nikos 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +84 -9
- package/dist/commands/verify.js +7 -3
- package/docs/quickstart.md +153 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,13 +8,21 @@
|
|
|
8
8
|
spec-driven development for AI coding agents
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
AI coding agents are quick to say "done". nikOS makes them prove it. Your
|
|
12
|
+
story map, plans and acceptance criteria live in your repo as plain files,
|
|
13
|
+
each criterion is a Cucumber scenario that runs as a test, and a story can't
|
|
14
|
+
be marked done until its scenarios pass. Your agent follows a named playbook
|
|
15
|
+
for each request instead of improvising, and every decision is written down
|
|
16
|
+
where the next person (or agent) can find it.
|
|
14
17
|
|
|
15
|
-
> Early work in progress.
|
|
18
|
+
> Early work in progress. Open source, MIT licensed.
|
|
16
19
|
|
|
17
|
-
##
|
|
20
|
+
## Try it in 10 minutes
|
|
21
|
+
|
|
22
|
+
[docs/quickstart.md](docs/quickstart.md) takes an empty repo to one passing
|
|
23
|
+
scenario, with every command and the output you should see.
|
|
24
|
+
|
|
25
|
+
## Install in your agent tool
|
|
18
26
|
|
|
19
27
|
| Tool | Command |
|
|
20
28
|
| --- | --- |
|
|
@@ -23,11 +31,78 @@ until its scenarios pass.
|
|
|
23
31
|
| Cursor | Add `https://github.com/nikovijay/NikOS` as a plugin marketplace |
|
|
24
32
|
|
|
25
33
|
Then ask your agent to plan or build a story: the `nikos-mode` skill takes it
|
|
26
|
-
from there.
|
|
34
|
+
from there. The skills run the `nikos` command through `npx`, so there's
|
|
35
|
+
nothing else to install. More in [docs/install.md](docs/install.md).
|
|
36
|
+
|
|
37
|
+
## The loop
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npx -y nikos init # create intent/ with a starter story
|
|
41
|
+
# write the story's scenarios in intent/features/
|
|
42
|
+
npx -y nikos verify setup # add a Cucumber runner for your stack
|
|
43
|
+
npx -y nikos verify TC-1 # run the story: it fails until it's built
|
|
44
|
+
# build it, then
|
|
45
|
+
npx -y nikos state set TC-1 done # refused unless its scenarios pass
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
With an agent, you only write the request ("add a story for X and build
|
|
49
|
+
it"); the playbooks run these steps and stop at each point that needs you.
|
|
50
|
+
|
|
51
|
+
## What lives in your repo
|
|
52
|
+
|
|
53
|
+
```text
|
|
54
|
+
intent/
|
|
55
|
+
├── constitution.md who it's for, the problem, what proves it works
|
|
56
|
+
├── storymap.yaml activities, releases, and the order to build stories in
|
|
57
|
+
├── state.yaml each story's status: todo, in_progress, needs_rework, done
|
|
58
|
+
├── decisions.md why things are the way they are, append-only
|
|
59
|
+
├── features/ one .feature file per story; its scenarios are the criteria
|
|
60
|
+
│ └── <activity>/<story>.feature
|
|
61
|
+
├── plans/ how each story will be built, versioned: <story>.v<N>.md
|
|
62
|
+
└── bets/ time-boxed bets and the stories that test them
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Every file is plain text you can read, review and diff. The full format:
|
|
66
|
+
[docs/format.md](docs/format.md). A worked example:
|
|
67
|
+
[examples/hello-todo](examples/hello-todo/intent).
|
|
68
|
+
|
|
69
|
+
## Commands
|
|
70
|
+
|
|
71
|
+
| Command | What it does |
|
|
72
|
+
| --- | --- |
|
|
73
|
+
| `nikos init` | Create `intent/` in this repo |
|
|
74
|
+
| `nikos validate` | Check `intent/` is well formed |
|
|
75
|
+
| `nikos clear <id>` | Check a story is ready to build |
|
|
76
|
+
| `nikos plan new <id>` | Start the next version of a story's plan |
|
|
77
|
+
| `nikos verify setup` | Add a Cucumber runner for this repo's stack |
|
|
78
|
+
| `nikos verify [id]` | Run a story's scenarios, or all of them |
|
|
79
|
+
| `nikos state set <id> <status>` | Move a story; done only if its scenarios pass |
|
|
80
|
+
| `nikos next` | Print the next story to build |
|
|
81
|
+
| `nikos show <id>` | Summarise a story: feature, status, plan, bets, decisions |
|
|
82
|
+
| `nikos decide "<title>"` | Append a decision to `decisions.md` |
|
|
83
|
+
| `nikos decisions "<q>"` | Quote the decisions about a topic or story |
|
|
84
|
+
| `nikos bet new <id>` | Write a time-boxed bet card linked to its stories |
|
|
85
|
+
|
|
86
|
+
## Working with a team: intentdocs
|
|
87
|
+
|
|
88
|
+
When you want a visual story map, reviews and a team around the same specs,
|
|
89
|
+
[intentdocs](https://www.intentdocs.com) reads the same `intent/` folder:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
npx intentdocs push # upload intent/ and link this repo
|
|
93
|
+
npx intentdocs pull # bring web edits back, shown as diffs first
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
The repo stays the source of truth for specs and plans; intentdocs runs the
|
|
97
|
+
build and acceptance steps. What maps to what:
|
|
98
|
+
[docs/intentdocs-mapping.md](docs/intentdocs-mapping.md).
|
|
99
|
+
|
|
100
|
+
## Links
|
|
27
101
|
|
|
28
102
|
- Home: https://nikos.tools
|
|
29
|
-
-
|
|
30
|
-
-
|
|
31
|
-
-
|
|
103
|
+
- Quickstart: [docs/quickstart.md](docs/quickstart.md)
|
|
104
|
+
- Install: [docs/install.md](docs/install.md)
|
|
105
|
+
- Format: [docs/format.md](docs/format.md)
|
|
106
|
+
- Writing stories as features: [docs/gherkin.md](docs/gherkin.md)
|
|
32
107
|
|
|
33
108
|
MIT licensed.
|
package/dist/commands/verify.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { copyFileSync, existsSync, mkdirSync } from "node:fs";
|
|
1
|
+
import { copyFileSync, existsSync, mkdirSync, readFileSync } from "node:fs";
|
|
2
2
|
import { dirname, join, relative } from "node:path";
|
|
3
3
|
import { spawnSync } from "node:child_process";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
@@ -12,6 +12,8 @@ const INSTALL = {
|
|
|
12
12
|
ts: "npm install --save-dev @cucumber/cucumber@^12 tsx",
|
|
13
13
|
python: "pip install behave",
|
|
14
14
|
};
|
|
15
|
+
/** A step only the untouched example story has. */
|
|
16
|
+
const EXAMPLE_STEP = "When I do the one thing this product is for";
|
|
15
17
|
const CONFIG = { js: "cucumber.mjs", ts: "cucumber.mjs", python: "behave.ini" };
|
|
16
18
|
function stackOrThrow(root) {
|
|
17
19
|
const stack = detectStack(root);
|
|
@@ -25,8 +27,10 @@ export function setupVerify(root) {
|
|
|
25
27
|
const src = join(templateDir, stack === "python" ? "python" : stack);
|
|
26
28
|
const created = [];
|
|
27
29
|
const skipped = [];
|
|
28
|
-
// Step stubs are for the example story `nikos init` creates; skip them once
|
|
29
|
-
|
|
30
|
+
// Step stubs are for the example story `nikos init` creates; skip them once
|
|
31
|
+
// it's gone or rewritten into a real story, whose steps they wouldn't match.
|
|
32
|
+
const example = join(root, "intent/features/getting-started/first-story.feature");
|
|
33
|
+
const hasExample = existsSync(example) && readFileSync(example, "utf8").includes(EXAMPLE_STEP);
|
|
30
34
|
for (const file of walk(src)) {
|
|
31
35
|
const rel = relative(src, file);
|
|
32
36
|
if (!hasExample && /first[-_]story/.test(rel))
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# Quickstart: your first passing scenario in 10 minutes
|
|
2
|
+
|
|
3
|
+
You'll make a tiny tip calculator in an empty repo and finish with one story
|
|
4
|
+
whose acceptance criterion runs as a test and passes. You need Node 20 or
|
|
5
|
+
later and npm. Nothing is installed globally: every `nikos` command runs
|
|
6
|
+
through `npx`.
|
|
7
|
+
|
|
8
|
+
## 1. Make a repo (1 minute)
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
mkdir tip-calculator && cd tip-calculator
|
|
12
|
+
git init
|
|
13
|
+
npm init -y
|
|
14
|
+
npm pkg set type=module
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## 2. Create the intent/ folder (1 minute)
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npx -y nikos init --name "Tip Calculator" --key TC
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
You should see:
|
|
24
|
+
|
|
25
|
+
```text
|
|
26
|
+
Created intent/ (6 files)
|
|
27
|
+
✓ intent/ is valid — 1 story, 1 release
|
|
28
|
+
|
|
29
|
+
Next: fill in intent/constitution.md, then write your first story in intent/features/.
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
`intent/` now holds your story map, a state file, a decision log and one
|
|
33
|
+
starter story, TC-1. [docs/format.md](format.md) explains each file.
|
|
34
|
+
|
|
35
|
+
## 3. Write the story (2 minutes)
|
|
36
|
+
|
|
37
|
+
Replace the starter story with a real one. Save this as
|
|
38
|
+
**`intent/features/getting-started/first-story.feature`**:
|
|
39
|
+
|
|
40
|
+
```gherkin
|
|
41
|
+
@TC-1 @release-1 @must @activity-getting-started
|
|
42
|
+
Feature: Add a tip to the bill
|
|
43
|
+
|
|
44
|
+
As a diner
|
|
45
|
+
I want to add a tip to my bill
|
|
46
|
+
So that I know what to pay
|
|
47
|
+
|
|
48
|
+
@AC1 @must
|
|
49
|
+
Scenario: AC1 — A 20% tip on a 50 bill
|
|
50
|
+
Given a bill of 50
|
|
51
|
+
When I add a 20% tip
|
|
52
|
+
Then the total is 60.00
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
The scenario is the acceptance criterion: TC-1 isn't done until it passes.
|
|
56
|
+
Check the folder is still well formed, and start the story:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
npx -y nikos validate
|
|
60
|
+
npx -y nikos state set TC-1 in_progress
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
```text
|
|
64
|
+
✓ intent/ is valid — 1 story, 1 release
|
|
65
|
+
TC-1: todo → in_progress
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## 4. Set up the runner (2 minutes)
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
npx -y nikos verify setup
|
|
72
|
+
npm install --save-dev @cucumber/cucumber@^12
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
`verify setup` notices this is a JavaScript repo and adds `cucumber.mjs`,
|
|
76
|
+
which runs every story in `intent/` as a test. Now run TC-1:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
npx -y nikos verify TC-1
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
It fails, and says why: none of the three steps has any code behind it yet.
|
|
83
|
+
|
|
84
|
+
```text
|
|
85
|
+
1 scenario (1 undefined)
|
|
86
|
+
3 steps (3 undefined)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## 5. Make it pass (3 minutes)
|
|
90
|
+
|
|
91
|
+
Write the code. Save this as **`tip.js`**:
|
|
92
|
+
|
|
93
|
+
```js
|
|
94
|
+
export function totalWithTip(bill, percent) {
|
|
95
|
+
return (bill * (1 + percent / 100)).toFixed(2);
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Connect each step to the code. Save this as **`test/steps/tip.steps.mjs`**:
|
|
100
|
+
|
|
101
|
+
```js
|
|
102
|
+
import { Given, When, Then } from "@cucumber/cucumber";
|
|
103
|
+
import assert from "node:assert/strict";
|
|
104
|
+
import { totalWithTip } from "../../tip.js";
|
|
105
|
+
|
|
106
|
+
Given("a bill of {int}", function (bill) {
|
|
107
|
+
this.bill = bill;
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
When("I add a {int}% tip", function (percent) {
|
|
111
|
+
this.total = totalWithTip(this.bill, percent);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
Then("the total is {float}", function (expected) {
|
|
115
|
+
assert.equal(this.total, expected.toFixed(2));
|
|
116
|
+
});
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Run it again:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
npx -y nikos verify TC-1
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
```text
|
|
126
|
+
1 scenario (1 passed)
|
|
127
|
+
3 steps (3 passed)
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## 6. Call it done (1 minute)
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
npx -y nikos state set TC-1 done
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
```text
|
|
137
|
+
TC-1: in_progress → done
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
`state set … done` runs the scenarios first and refuses if any fail, so a
|
|
141
|
+
story can't be marked done on the agent's word alone.
|
|
142
|
+
|
|
143
|
+
That's the whole loop: write the story, run it, make it pass, mark it done.
|
|
144
|
+
|
|
145
|
+
## Next: let your agent do it
|
|
146
|
+
|
|
147
|
+
Install nikOS in your agent tool ([docs/install.md](install.md)), then ask:
|
|
148
|
+
|
|
149
|
+
> Add a story for splitting the bill between people, and build it.
|
|
150
|
+
|
|
151
|
+
The `nikos-mode` skill picks the right playbook: it writes the story,
|
|
152
|
+
checks it, plans it, builds it, and stops at "done" only when the new
|
|
153
|
+
scenario passes.
|
package/package.json
CHANGED