nikos 0.0.6 → 0.1.0

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.
Files changed (39) hide show
  1. package/README.md +5 -4
  2. package/dist/cli.js +21 -5
  3. package/dist/commands/map.js +272 -0
  4. package/dist/commands/release.js +170 -0
  5. package/dist/commands/show.js +7 -7
  6. package/dist/commands/step.js +59 -0
  7. package/dist/commands/story.js +9 -3
  8. package/dist/commands/validate.js +46 -31
  9. package/dist/commands/video.js +116 -0
  10. package/dist/lib/bets.js +25 -0
  11. package/dist/lib/frontmatter.js +8 -0
  12. package/dist/lib/project.js +37 -0
  13. package/dist/lint/gherkin.js +2 -2
  14. package/dist/planning/bets.js +73 -0
  15. package/dist/planning/cli.js +152 -0
  16. package/dist/planning/delivery.js +20 -0
  17. package/dist/planning/krs.js +73 -0
  18. package/dist/planning/model.js +164 -0
  19. package/dist/planning/server.js +336 -0
  20. package/dist/planning/ui.js +452 -0
  21. package/dist/planning/upstream.js +175 -0
  22. package/docs/format.md +50 -55
  23. package/docs/gherkin.md +2 -1
  24. package/docs/install.md +26 -5
  25. package/docs/planning.md +124 -0
  26. package/package.json +2 -1
  27. package/schemas/planning/bet.schema.json +42 -0
  28. package/schemas/planning/kr.schema.json +35 -0
  29. package/schemas/planning/plan.schema.json +28 -0
  30. package/schemas/storymap.schema.json +94 -11
  31. package/skills/nikos-mode/playbooks/idea-to-blueprint.md +1 -1
  32. package/skills/nikos-mode/playbooks/index.md +2 -1
  33. package/skills/nikos-mode/playbooks/planning.md +11 -0
  34. package/skills/nikos-mode/playbooks/video.md +14 -0
  35. package/skills/nikos-mode/principles/index.md +0 -2
  36. package/dist/commands/bet.js +0 -97
  37. package/docs/intentdocs-mapping.md +0 -117
  38. package/schemas/bet.schema.json +0 -23
  39. package/skills/nikos-mode/playbooks/bet.md +0 -14
package/docs/format.md CHANGED
@@ -19,8 +19,6 @@ intent/
19
19
  state.yaml status, blockers and the run queue
20
20
  outreach/ optional, drafts from the validate playbook
21
21
  <date>-<channel>.md
22
- bets/ optional, time-boxed bets (see Bets)
23
- <bet-id>.md
24
22
  ```
25
23
 
26
24
  Two rules hold across every file:
@@ -79,8 +77,8 @@ five vision sections come first, in order, and aren't empty.
79
77
 
80
78
  ## storymap.yaml
81
79
 
82
- **Purpose:** the shape of the product: activities (columns), releases (rows)
83
- and the order stories should be built in. It is an index; the stories
80
+ **Purpose:** the shape of the product: activities and their steps (columns),
81
+ releases (rows) and the order stories should be built in. It is an index; the stories
84
82
  themselves live in feature files.
85
83
 
86
84
  **Path:** `intent/storymap.yaml`
@@ -94,9 +92,15 @@ key: HT # story id prefix: HT-1, HT-2 …
94
92
  activities:
95
93
  - id: tasks # slug, matches the features/<activity>/ folder
96
94
  title: Manage tasks
95
+ steps: # optional: the steps a person takes in this activity
96
+ - id: capture # slug, unique across the map; a story tags it @step-capture
97
+ title: Capture a task
98
+ - id: focus
99
+ title: Focus on today
97
100
  releases:
98
101
  - number: 1
99
102
  title: MVP
103
+ goal: Capture tasks and see only today's top three. # optional, one line
100
104
  stories: [HT-1, HT-2] # build order within the release
101
105
  - number: 2
102
106
  title: Enhancements
@@ -108,10 +112,48 @@ Rules:
108
112
  - Every story id appears in exactly one release.
109
113
  - Every story id has exactly one feature file and one `state.yaml` entry.
110
114
  - Release numbers start at 1 and have no gaps.
115
+ - Step ids are unique across the map. A story's `@step-<id>` must name a step
116
+ of its own activity. A story with no step sits under the activity's first
117
+ step on the map.
118
+ - A story's `@release-N` tag should match the release that lists it;
119
+ `nikos validate` warns when they differ.
111
120
 
112
- Add a story with `nikos story add "<title>" --activity <id>`. It takes the
113
- next free id, adds it to the last release (or `--release <n>`), gives it a
114
- `todo` entry in `state.yaml` and writes a starter feature file to fill in.
121
+ ### Bet links (optional)
122
+
123
+ A release can name the bets it delivers, and a single story can override its
124
+ release's list. The bets themselves live outside `intent/`, in `planning/`
125
+ (the Planning pack, see [planning.md](planning.md)).
126
+
127
+ ```yaml
128
+ releases:
129
+ - number: 1
130
+ title: MVP
131
+ bets: [fewer-missed-tasks] # a bet in planning/bets/
132
+ stories: [HT-1, HT-2]
133
+ story_bets:
134
+ HT-2: [acme/company-plan#focus-mode] # this story serves another repo's bet
135
+ ```
136
+
137
+ - A bet id must have a `planning/bets/<id>.md` in the same repo.
138
+ - `owner/repo#id` names another repo's bet. `nikos validate` checks its form
139
+ only and never fetches it.
140
+ - A story's `story_bets` entry replaces its release's `bets` for that story.
141
+
142
+ Add a story with `nikos story add "<title>" --activity <id> [--step <id>]`.
143
+ It takes the next free id, adds it to the last release (or `--release <n>`),
144
+ gives it a `todo` entry in `state.yaml` and writes a starter feature file to
145
+ fill in.
146
+
147
+ The map's shape has commands too, so nobody has to hand-edit the YAML. Each
148
+ keeps comments and leaves the rest of the file as it was:
149
+
150
+ | Command | What it does |
151
+ | --- | --- |
152
+ | `nikos step add "<title>" --activity <id>` | Add a step under an activity (`--id` to choose its id) |
153
+ | `nikos release add "<title>" [--goal "<goal>"]` | Add the next numbered release, with no stories yet |
154
+ | `nikos release rename <n> ["<title>"] [--goal "<goal>"]` | Change a release's title or goal (`--goal ""` removes it) |
155
+ | `nikos release move <story-id> <n>` | Move a story to the end of another release and retag its feature |
156
+ | `nikos release reorder <n> <position>` | Move a release, renumber them all from 1 and retag every moved story |
115
157
 
116
158
  ---
117
159
 
@@ -129,7 +171,7 @@ story; each acceptance criterion is a `Scenario` (or `Scenario Outline`)
129
171
  titled with its label. Full rules are in [gherkin.md](gherkin.md).
130
172
 
131
173
  ```gherkin
132
- @HT-1 @release-1 @must @activity-tasks
174
+ @HT-1 @release-1 @must @activity-tasks @step-capture
133
175
  Feature: Add a task
134
176
 
135
177
  As a busy person
@@ -172,8 +214,6 @@ summary: One to three plain sentences on the approach.
172
214
  Notes for the agent.
173
215
  ```
174
216
 
175
- These fields match intentdocs plans one to one (see the mapping doc).
176
-
177
217
  Start a new version with `nikos plan new <story-id>`. It writes the next
178
218
  `v<N>` from a template, sets `supersedes`, and refuses to overwrite an
179
219
  existing file.
@@ -250,51 +290,6 @@ founder sends it, never the agent.
250
290
 
251
291
  ---
252
292
 
253
- ## bets/&lt;bet-id&gt;.md (optional)
254
-
255
- **Purpose:** a time-boxed bet that a set of stories will move a measure.
256
-
257
- **Path:** `intent/bets/<bet-id>.md`, where `<bet-id>` is lowercase words
258
- joined by hyphens.
259
-
260
- **Format:** Markdown with YAML front matter, then free-form notes. Create one
261
- with `nikos bet new`; the bet playbook frames and closes it.
262
-
263
- ```markdown
264
- ---
265
- id: faster-reorder
266
- hypothesis: We believe drag to reorder will make people plan their day in the app because they reorder on paper today.
267
- key_result: Share of daily users who reorder at least once
268
- expected_uplift: from 10% to 30%
269
- time_box: 2026-12-01
270
- blockers: []
271
- stories: [HT-3]
272
- status: open
273
- ---
274
-
275
- ## Why we think so
276
- The evidence behind the hypothesis.
277
-
278
- ## Outcome
279
- Filled in when the time box ends.
280
- ```
281
-
282
- | Field | Required | Meaning |
283
- | --- | --- | --- |
284
- | `id` | yes | Matches the file name |
285
- | `hypothesis` | yes | What you believe and why |
286
- | `key_result` | yes | The one measure that says whether it worked |
287
- | `expected_uplift` | yes | How far you expect it to move, from what to what |
288
- | `time_box` | yes | End date, `YYYY-MM-DD` |
289
- | `blockers` | yes | What stands in the way; `[]` if nothing |
290
- | `stories` | yes | At least one story id; each must be in `storymap.yaml` |
291
- | `status` | yes | `open \| won \| lost \| killed` |
292
-
293
- `nikos validate` checks every field against `schemas/bet.schema.json`, that
294
- the id matches the file name, and that every linked story exists.
295
-
296
- ---
297
-
298
293
  ## Versioning this format
299
294
 
300
295
  `format_version` in `storymap.yaml` and `state.yaml` is the version of this
package/docs/gherkin.md CHANGED
@@ -8,7 +8,7 @@ and the test: each acceptance criterion is a scenario that Cucumber can run.
8
8
  ## The shape of a story
9
9
 
10
10
  ```gherkin
11
- @HT-1 @release-1 @must @activity-tasks @effort-S
11
+ @HT-1 @release-1 @must @activity-tasks @step-capture @effort-S
12
12
  Feature: Add a task
13
13
 
14
14
  As a busy person
@@ -54,6 +54,7 @@ criterion's priority).
54
54
  | `@release-N` | release the story is in | yes |
55
55
  | `@must` / `@should` / `@could` | story priority | yes |
56
56
  | `@activity-<id>` | activity, matching the folder name | no |
57
+ | `@step-<id>` | step within that activity, from `storymap.yaml` | no |
57
58
  | `@effort-XS` … `@effort-XL` | size estimate | no |
58
59
 
59
60
  Anything else is a warning, so you notice typos.
package/docs/install.md CHANGED
@@ -50,6 +50,21 @@ then Add Marketplace, then Import from Repo), and install nikOS from it.
50
50
  To try it without a marketplace, copy the repo to
51
51
  `~/.cursor/plugins/local/nikos` and run "Developer: Reload Window".
52
52
 
53
+ ## Packs
54
+
55
+ Packs are extra tools that install on their own, next to nikOS or without it.
56
+ Each lives in `tools/<pack>/` with its own manifests and skills, and both
57
+ marketplaces list it.
58
+
59
+ | Pack | Folder | Claude Code |
60
+ | --- | --- | --- |
61
+ | Video | `tools/video/` | `/plugin install nikos-video@nikos` |
62
+ | Planning | `tools/planning/` | `/plugin install nikos-planning@nikos` |
63
+
64
+ In Codex and Cursor, install the pack from the same marketplace as nikOS.
65
+ nikOS's router hands requests to an installed pack's skill, and gives the
66
+ install command when the pack is missing.
67
+
53
68
  ## The command-line tool
54
69
 
55
70
  The skills run the `nikos` command. When it isn't installed, they run it
@@ -58,14 +73,20 @@ it anyway: `npm install -g nikos`.
58
73
 
59
74
  ## Formats checked
60
75
 
61
- Plugin formats change often. These were read on 2026-11-04 (no page showed a
62
- version):
76
+ Plugin formats change often. These were read on 2026-11-04, and the display
77
+ name fields again on 2026-11-05 (no page showed a version):
63
78
 
64
79
  - Claude Code: https://code.claude.com/docs/en/plugins-reference and
65
80
  https://code.claude.com/docs/en/plugins/marketplace-reference. Checked with
66
- `claude plugin validate .` on Claude Code 2.1.318.
67
- - Cursor: https://cursor.com/docs/reference/plugins
68
- - Codex: https://developers.openai.com/plugins/build/plugins
81
+ `claude plugin validate .` on Claude Code 2.1.318. `displayName` is the
82
+ name shown in the UI. A marketplace entry's `displayName` wins over the
83
+ plugin's. The marketplace `name` stays the install id (`nikos@nikos`).
84
+ - Cursor: https://cursor.com/docs/reference/plugins. That page does not list
85
+ `displayName`. `.cursor-plugin/plugin.json` still sets it so a listing can
86
+ show nikOS, and `name` stays the kebab-case id.
87
+ - Codex: https://developers.openai.com/plugins/build/plugins. The plugin
88
+ title is `interface.displayName` in `.codex-plugin/plugin.json`. The
89
+ marketplace title is the same field on `.agents/plugins/marketplace.json`.
69
90
 
70
91
  All three find skills as `skills/<name>/SKILL.md` at the plugin root.
71
92
  `test/install.test.ts` checks the manifests agree with each other and with
@@ -0,0 +1,124 @@
1
+ # The planning/ format
2
+
3
+ The Planning pack keeps objectives, key results and bets in a `planning/`
4
+ folder at the repo root, next to `intent/`. Planning sets direction; the
5
+ story map in `intent/` handles delivery. Everything is plain text and only
6
+ changes when you (or your agent, with your yes) change it.
7
+
8
+ ```
9
+ planning/
10
+ plan.yaml period, level, pillars and objectives
11
+ krs/<kr-id>.yaml key results and their check-ins
12
+ bets/<bet-id>.md bet cards
13
+ upstream.yaml optional: plans in other repos this one works toward
14
+ upstream.lock written by `nikos planning sync`
15
+ views/<name>.html optional: custom dashboard views
16
+ ```
17
+
18
+ `nikos planning validate` checks every file against `schemas/planning/`.
19
+
20
+ ## plan.yaml
21
+
22
+ **Purpose:** the planning context: the period, the level being planned
23
+ (company, department, group or team), its strategic pillars and objectives.
24
+
25
+ ```yaml
26
+ period: Q1 2027
27
+ level: team
28
+ pillars: [Retention]
29
+ objectives:
30
+ - id: keep-plants-alive
31
+ title: People keep their plants alive
32
+ aligns_to: acme/company-plan#plants-alive # optional
33
+ ```
34
+
35
+ ## krs/&lt;kr-id&gt;.yaml
36
+
37
+ **Purpose:** one key result, with dated check-ins that are only ever added to.
38
+
39
+ ```yaml
40
+ id: reminders-acted-on
41
+ title: Reminders acted on the same day
42
+ objective: keep-plants-alive
43
+ owner: Reminders team
44
+ unit: "%"
45
+ baseline: 41
46
+ target: 60
47
+ original_target: 60 # kept when the target is revised
48
+ by: 2027-03-31
49
+ aligns_to: acme/company-plan#kr-2 # optional, another repo's key result
50
+ stale_after_days: 14 # optional, default 14
51
+ checkins:
52
+ - date: 2027-01-20
53
+ value: 44
54
+ note: First week of the new reminder time.
55
+ evidence: https://analytics.example.com/reminders
56
+ ```
57
+
58
+ Add one with `nikos planning kr new`, check in with `nikos planning checkin`,
59
+ and revise a target with `nikos planning kr target` (the original stays).
60
+
61
+ ## bets/&lt;bet-id&gt;.md
62
+
63
+ **Purpose:** a bet: what we believe, the key results it should move, when we
64
+ review it, and every review decision since.
65
+
66
+ ```markdown
67
+ ---
68
+ id: reminders-that-stick
69
+ owner: Reminders team
70
+ team: Reminders
71
+ hypothesis: We believe reminders at each plant's real watering time get acted on the same day.
72
+ krs:
73
+ primary: reminders-acted-on
74
+ also: [acme/company-plan#kr-2]
75
+ starts: 2027-01-06
76
+ review_on: 2027-02-14
77
+ deadline: 2027-03-31 # optional: only a hard deadline
78
+ confidence: medium # low | medium | high
79
+ dependencies: [Push notifications (Platform team)]
80
+ outcome: open # open | awaiting evidence | won | lost | stopped
81
+ reviews:
82
+ - date: 2027-02-17
83
+ decision: continue # continue | change | stop | complete
84
+ reason: 55% against 60%. Keep going; review again 3 Mar.
85
+ ---
86
+
87
+ ## Why we think so
88
+ 41% of reminders are acted on the same day; most misses arrive at night.
89
+ ```
90
+
91
+ - A bet card has no `stories` field. The story map names the bets each
92
+ release delivers (`bets:` on a release, `story_bets:` for one story; see
93
+ [format.md](format.md)).
94
+ - `krs` may be empty for maintenance or risk-reduction work.
95
+ - Delivery (Shipped, Building, Not started) is worked out from the stories
96
+ that deliver the bet. The outcome only changes at a review: stop sets
97
+ `stopped`; complete sets `won` or `lost` from the key result evidence.
98
+
99
+ Write one with `nikos planning bet new`; review it with
100
+ `nikos planning bet review`.
101
+
102
+ ## upstream.yaml and upstream.lock
103
+
104
+ **Purpose:** the plans in other repos this one works toward, read without
105
+ ever writing to them.
106
+
107
+ ```yaml
108
+ - repo: acme/company-plan
109
+ ref: main
110
+ # url: https://git.example.com/acme/company-plan.git (optional; defaults to GitHub)
111
+ ```
112
+
113
+ `nikos planning sync` clones each into `.nikos/upstream/<owner>/<repo>/`
114
+ (gitignored; sync adds it to `.gitignore`) and writes the commit it read to
115
+ `upstream.lock`. A repo it can't reach is reported as unresolved and planning
116
+ carries on. `nikos planning sync --check` says whether an upstream has moved
117
+ past its locked commit. This repo only stores references like
118
+ `owner/repo#id`, never upstream content.
119
+
120
+ ## views/&lt;name&gt;.html
121
+
122
+ **Purpose:** a custom dashboard view, served by `nikos planning serve` at
123
+ `/views/<name>`. It reads and writes only through the view contract in the
124
+ pack's dashboard playbook.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nikos",
3
- "version": "0.0.6",
3
+ "version": "0.1.0",
4
4
  "description": "Spec-driven development for AI coding agents: story maps, Gherkin acceptance criteria and a done gate for Claude Code, Codex and Cursor",
5
5
  "license": "MIT",
6
6
  "author": "Niko Vijay",
@@ -24,6 +24,7 @@
24
24
  "docs"
25
25
  ],
26
26
  "scripts": {
27
+ "prebuild": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
27
28
  "build": "tsc -p tsconfig.json",
28
29
  "prepublishOnly": "npm run build && npm test",
29
30
  "test": "vitest run",
@@ -0,0 +1,42 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://nikos.tools/schemas/planning/bet.schema.json",
4
+ "title": "nikOS Planning bet card front matter",
5
+ "type": "object",
6
+ "required": ["id", "owner", "hypothesis", "krs", "review_on", "confidence", "dependencies", "outcome", "reviews"],
7
+ "additionalProperties": false,
8
+ "properties": {
9
+ "id": { "type": "string", "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$" },
10
+ "owner": { "type": "string", "minLength": 1 },
11
+ "team": { "type": "string", "minLength": 1 },
12
+ "hypothesis": { "type": "string", "minLength": 1 },
13
+ "krs": {
14
+ "type": "object",
15
+ "additionalProperties": false,
16
+ "properties": {
17
+ "primary": { "type": "string", "minLength": 1 },
18
+ "also": { "type": "array", "uniqueItems": true, "items": { "type": "string", "minLength": 1 } }
19
+ }
20
+ },
21
+ "starts": { "type": "string", "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$" },
22
+ "review_on": { "type": "string", "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$" },
23
+ "deadline": { "type": "string", "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$" },
24
+ "confidence": { "enum": ["low", "medium", "high"] },
25
+ "dependencies": { "type": "array", "items": { "type": "string", "minLength": 1 } },
26
+ "outcome": { "enum": ["open", "awaiting evidence", "won", "lost", "stopped"] },
27
+ "reviews": {
28
+ "type": "array",
29
+ "items": {
30
+ "type": "object",
31
+ "required": ["date", "decision", "reason"],
32
+ "additionalProperties": false,
33
+ "properties": {
34
+ "date": { "type": "string", "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$" },
35
+ "decision": { "enum": ["continue", "change", "stop", "complete"] },
36
+ "reason": { "type": "string", "minLength": 1 },
37
+ "outcome": { "enum": ["won", "lost", "stopped"] }
38
+ }
39
+ }
40
+ }
41
+ }
42
+ }
@@ -0,0 +1,35 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://nikos.tools/schemas/planning/kr.schema.json",
4
+ "title": "nikOS Planning key result",
5
+ "type": "object",
6
+ "required": ["id", "title", "owner", "baseline", "target", "original_target", "by", "checkins"],
7
+ "additionalProperties": false,
8
+ "properties": {
9
+ "id": { "type": "string", "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$" },
10
+ "title": { "type": "string", "minLength": 1 },
11
+ "objective": { "type": "string", "minLength": 1 },
12
+ "owner": { "type": "string", "minLength": 1 },
13
+ "unit": { "type": "string" },
14
+ "baseline": { "type": "number" },
15
+ "target": { "type": "number" },
16
+ "original_target": { "type": "number" },
17
+ "by": { "type": "string", "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$" },
18
+ "aligns_to": { "type": "string", "pattern": "^[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+#[a-z0-9]+(-[a-z0-9]+)*$" },
19
+ "stale_after_days": { "type": "integer", "minimum": 1 },
20
+ "checkins": {
21
+ "type": "array",
22
+ "items": {
23
+ "type": "object",
24
+ "required": ["date", "value"],
25
+ "additionalProperties": false,
26
+ "properties": {
27
+ "date": { "type": "string", "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$" },
28
+ "value": { "type": "number" },
29
+ "note": { "type": "string" },
30
+ "evidence": { "type": "string" }
31
+ }
32
+ }
33
+ }
34
+ }
35
+ }
@@ -0,0 +1,28 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://nikos.tools/schemas/planning/plan.schema.json",
4
+ "title": "nikOS Planning context",
5
+ "type": "object",
6
+ "required": ["period", "level", "pillars"],
7
+ "additionalProperties": false,
8
+ "properties": {
9
+ "name": { "type": "string", "minLength": 1 },
10
+ "period": { "type": "string", "minLength": 1 },
11
+ "level": { "enum": ["company", "department", "group", "team"] },
12
+ "pillars": { "type": "array", "items": { "type": "string", "minLength": 1 } },
13
+ "objectives": {
14
+ "type": "array",
15
+ "items": {
16
+ "type": "object",
17
+ "required": ["id", "title"],
18
+ "additionalProperties": false,
19
+ "properties": {
20
+ "id": { "type": "string", "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$" },
21
+ "title": { "type": "string", "minLength": 1 },
22
+ "owner": { "type": "string" },
23
+ "aligns_to": { "type": "string" }
24
+ }
25
+ }
26
+ }
27
+ }
28
+ }
@@ -3,22 +3,66 @@
3
3
  "$id": "https://nikos.tools/schemas/storymap.schema.json",
4
4
  "title": "nikOS story map",
5
5
  "type": "object",
6
- "required": ["format_version", "project", "key", "activities", "releases"],
6
+ "required": [
7
+ "format_version",
8
+ "project",
9
+ "key",
10
+ "activities",
11
+ "releases"
12
+ ],
7
13
  "additionalProperties": false,
8
14
  "properties": {
9
- "format_version": { "const": 1 },
10
- "project": { "type": "string", "pattern": "^[a-z0-9][a-z0-9-]*$" },
11
- "key": { "type": "string", "pattern": "^[A-Z][A-Z0-9]{0,9}$" },
15
+ "format_version": {
16
+ "const": 1
17
+ },
18
+ "project": {
19
+ "type": "string",
20
+ "pattern": "^[a-z0-9][a-z0-9-]*$"
21
+ },
22
+ "key": {
23
+ "type": "string",
24
+ "pattern": "^[A-Z][A-Z0-9]{0,9}$"
25
+ },
12
26
  "activities": {
13
27
  "type": "array",
14
28
  "minItems": 1,
15
29
  "items": {
16
30
  "type": "object",
17
- "required": ["id", "title"],
31
+ "required": [
32
+ "id",
33
+ "title"
34
+ ],
18
35
  "additionalProperties": false,
19
36
  "properties": {
20
- "id": { "type": "string", "pattern": "^[a-z0-9][a-z0-9-]*$" },
21
- "title": { "type": "string", "minLength": 1 }
37
+ "id": {
38
+ "type": "string",
39
+ "pattern": "^[a-z0-9][a-z0-9-]*$"
40
+ },
41
+ "title": {
42
+ "type": "string",
43
+ "minLength": 1
44
+ },
45
+ "steps": {
46
+ "type": "array",
47
+ "items": {
48
+ "type": "object",
49
+ "required": [
50
+ "id",
51
+ "title"
52
+ ],
53
+ "additionalProperties": false,
54
+ "properties": {
55
+ "id": {
56
+ "type": "string",
57
+ "pattern": "^[a-z0-9][a-z0-9-]*$"
58
+ },
59
+ "title": {
60
+ "type": "string",
61
+ "minLength": 1
62
+ }
63
+ }
64
+ }
65
+ }
22
66
  }
23
67
  }
24
68
  },
@@ -27,17 +71,56 @@
27
71
  "minItems": 1,
28
72
  "items": {
29
73
  "type": "object",
30
- "required": ["number", "title", "stories"],
74
+ "required": [
75
+ "number",
76
+ "title",
77
+ "stories"
78
+ ],
31
79
  "additionalProperties": false,
32
80
  "properties": {
33
- "number": { "type": "integer", "minimum": 1 },
34
- "title": { "type": "string", "minLength": 1 },
81
+ "number": {
82
+ "type": "integer",
83
+ "minimum": 1
84
+ },
85
+ "title": {
86
+ "type": "string",
87
+ "minLength": 1
88
+ },
89
+ "goal": {
90
+ "type": "string",
91
+ "minLength": 1
92
+ },
35
93
  "stories": {
36
94
  "type": "array",
37
- "items": { "type": "string", "pattern": "^[A-Z][A-Z0-9]{0,9}-[0-9]+$" }
95
+ "items": {
96
+ "type": "string",
97
+ "pattern": "^[A-Z][A-Z0-9]{0,9}-[0-9]+$"
98
+ }
99
+ },
100
+ "bets": {
101
+ "type": "array",
102
+ "items": {
103
+ "type": "string",
104
+ "minLength": 1
105
+ },
106
+ "uniqueItems": true
38
107
  }
39
108
  }
40
109
  }
110
+ },
111
+ "story_bets": {
112
+ "type": "object",
113
+ "propertyNames": {
114
+ "pattern": "^[A-Z][A-Z0-9]{0,9}-[0-9]+$"
115
+ },
116
+ "additionalProperties": {
117
+ "type": "array",
118
+ "items": {
119
+ "type": "string",
120
+ "minLength": 1
121
+ },
122
+ "uniqueItems": true
123
+ }
41
124
  }
42
125
  }
43
126
  }
@@ -8,7 +8,7 @@ decides; you ask, propose and write it down.
8
8
  2. If the repo has no `intent/` folder, run `nikos init --name "<product name>"`, then put the one-sentence idea in the `idea:` line at the top of `intent/constitution.md`.
9
9
  3. Ask the five vision questions one at a time (Users, Problem, Switch, First, Proof), wait for each answer, and write it into its section of `intent/constitution.md`. If an answer contradicts the idea or an earlier answer, point it out and ask which one wins.
10
10
  4. Write a `## Jobs to be done` section ("When …, I want to …, so I can …") and a `## Founding hypothesis` section ("We believe <users> will <behaviour> because <reason>. We'll know we're right when <the Proof measure>."), then confirm both with the person.
11
- 5. Propose activities and releases, with the First answer as release 1, and write them into `intent/storymap.yaml` once the person agrees.
11
+ 5. Propose activities, the steps a person takes in each, and releases with a one-line goal, with the First answer as release 1. Once the person agrees, write them into `intent/storymap.yaml` (`nikos step add` and `nikos release add` do this without hand-editing).
12
12
  6. Write each story as `intent/features/<activity>/<story-slug>.feature`: tag it with its id, release and priority, put "As a … / I want … / So that …" under `Feature:`, and make each acceptance criterion a Scenario tagged and titled with its label (`@AC1`). Add each story to `intent/state.yaml` as `todo`, and remove the example story and its `getting-started` activity that `nikos init` created.
13
13
  7. Check every story with the clear skill. For each failed check, propose the fix to the person and change the spec only once they agree.
14
14
  8. Record every choice you made on the person's behalf (anything their answers didn't settle) with `nikos decide "<title>" --why "<why>" --category product`.
@@ -6,8 +6,9 @@ first match. Packs add rows here as they ship new playbooks.
6
6
  | Playbook | File | Use when |
7
7
  | --- | --- | --- |
8
8
  | idea-to-blueprint | `idea-to-blueprint.md` | The person has a new product idea, or wants to start a project from scratch and there is no story map yet. |
9
+ | video | `video.md` | The person asks for a video: an explainer, product tour, demo, launch or social clip, or to edit or re-render one. Needs the Video pack. |
9
10
  | validate | `validate.md` | The person wants to test or validate an idea with real people, or draft outreach, a post or a demo script for it. |
10
- | bet | `bet.md` | The person wants to frame work as a bet, set a key result or time box for some stories, or close a bet and call its outcome. |
11
+ | planning | `planning.md` | The person wants to plan a period, set OKRs or key results, frame or review a bet, check in on key results, or see a planning dashboard. Needs the Planning pack. |
11
12
  | build-a-story | `build-a-story.md` | The person asks to build, do or pick up the next story, or a story by its id. |
12
13
  | answer | `answer.md` | The person asks a question about the product, a story, a plan or a decision, and nothing in the repo needs to change. |
13
14
  | change | `change.md` | The person asks to add, fix, change or remove something in the repo: code, tests, docs or specs. |
@@ -0,0 +1,11 @@
1
+ # planning
2
+
3
+ Plan a period, frame or review a bet, check in on key results or open the
4
+ planning dashboard. The work is done by the `nikos-planning` skill, which
5
+ ships in the Planning pack, not in nikOS itself. This playbook checks the
6
+ pack is there and hands over to it.
7
+
8
+ 1. Check the Planning pack is installed: the `nikos-planning` skill is in your skills list. If it isn't, tell the person to install it (Claude Code: `/plugin install nikos-planning@nikos`; Codex and Cursor: install `nikos-planning` from the nikOS marketplace), say planning can't run until they do, and stop.
9
+ 2. Hand over to the `nikos-planning` skill: say which of its playbooks matches the request, and run every step of it in order.
10
+ 3. Bets are linked from the story map, not the other way round: when a release or story delivers a bet, it's named in `intent/storymap.yaml` (`bets:` on the release, or `story_bets:`), and `nikos validate` checks the link.
11
+ 4. Report every step with its evidence or its skip reason.
@@ -0,0 +1,14 @@
1
+ # video
2
+
3
+ Make a short product explainer video from a brief. The work is done by the
4
+ `product-tour-video` skill, which ships in the Video pack, not in nikOS
5
+ itself. This playbook checks the pack is there, pins down the brief, and
6
+ hands over to that skill's workflow.
7
+
8
+ 1. Check the Video pack is installed: the `product-tour-video` skill is in your skills list. If it isn't, tell the person to install it (Claude Code: `/plugin install nikos-video@nikos`; Codex and Cursor: install `nikos-video` from the nikOS marketplace), say the video can't be made until they do, and stop.
9
+ 2. Write the brief down before anything else. If the repo has an `intent/` folder with done stories, run `nikos video --out marketing/<name>`: it drafts `brief.md` and `storyboard.js` from `intent/constitution.md` and the stories marked done, one beat per activity, and leaves out everything not built yet. Otherwise write the product, who the video is for, its length, where it will live, the story it tells in one line, and what's in or out. Ask for anything missing.
10
+ 3. Make it with the `product-tour-video` skill. From a drafted storyboard, render its storyboard template (the skill's "From a nikOS story map" section). For a tour of the product's real screens, follow the skill's workflow, every step in its order: find out what's real, storyboard for sign-off, the style test, the full build, the contact sheet, the score, then render and mix.
11
+ 4. STOP at the storyboard (the beats in `brief.md`, or the skill's storyboard table) and, for a screen tour, again at the style test, and wait for the person's yes each time. A yes to one isn't a yes to the other.
12
+ 5. Check the encoded `final.mp4`: extract a few frames with ffmpeg and look at them, and give its length and size.
13
+ 6. Deliver `final.mp4` with the brief it was made from. Commit the video's sources only; the rendered files stay ignored.
14
+ 7. Report every step with its evidence or its skip reason.