k0-board 0.3.0 → 0.5.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 (82) hide show
  1. package/.claude/skills/k0-changelog/SKILL.md +2 -2
  2. package/.claude/skills/k0-discuss/SKILL.md +105 -0
  3. package/.claude/skills/k0-discuss/references/rounds.md +280 -0
  4. package/.claude/skills/k0-epic/SKILL.md +196 -0
  5. package/.claude/skills/k0-links/.claude-plugin/plugin.json +6 -0
  6. package/.claude/skills/k0-links/hooks/hooks.json +1 -0
  7. package/.claude/skills/k0-links/hooks/links.js +128 -0
  8. package/.claude/skills/k0-links/hooks/register.js +204 -0
  9. package/.claude/skills/k0-next/SKILL.md +82 -0
  10. package/.claude/skills/k0-order/SKILL.md +123 -0
  11. package/.claude/skills/k0-plan/SKILL.md +156 -0
  12. package/.claude/skills/k0-split/SKILL.md +169 -0
  13. package/.claude/skills/k0-story/SKILL.md +108 -0
  14. package/.claude/skills/k0-ultracode/SKILL.md +251 -0
  15. package/.claude/skills/k0-ultracode/references/agent-brief.md +71 -0
  16. package/.claude/skills/k0-ultracode/references/modes.md +49 -0
  17. package/.claude/skills/k0-verify/SKILL.md +219 -0
  18. package/.claude/skills/k0-whatsnew/SKILL.md +95 -0
  19. package/.claude/skills/k0-work/SKILL.md +212 -0
  20. package/CHANGELOG.md +426 -1
  21. package/README.md +1021 -119
  22. package/bin/k0-board.js +81 -11
  23. package/menubar/K0MenuBar.swift +35 -5
  24. package/package.json +13 -1
  25. package/platform/contract.js +37 -6
  26. package/platform/darwin/index.js +1 -0
  27. package/platform/darwin/shell.js +4 -1
  28. package/platform/darwin/terminal.js +230 -56
  29. package/platform/index.js +3 -1
  30. package/platform/linux/index.js +14 -0
  31. package/platform/linux/shell.js +10 -1
  32. package/platform/linux/tray.py +10 -10
  33. package/platform/shared/command.js +19 -3
  34. package/platform/shared/tmux.js +32 -14
  35. package/platform/win32/index.js +6 -2
  36. package/platform/win32/shell.js +4 -1
  37. package/platform/win32/terminal.js +24 -8
  38. package/platform/win32/tray.ps1 +13 -13
  39. package/server/backlog.js +618 -0
  40. package/server/changelog.js +13 -13
  41. package/server/db.js +1800 -146
  42. package/server/files.js +156 -26
  43. package/server/git.js +53 -14
  44. package/server/idle.js +15 -13
  45. package/server/index.js +1286 -189
  46. package/server/launcher.js +122 -14
  47. package/server/machine.js +10 -1
  48. package/server/mirror.js +1048 -0
  49. package/server/prices.js +59 -0
  50. package/server/projects.js +57 -12
  51. package/server/servers.js +22 -1
  52. package/server/sessions.js +5 -5
  53. package/server/settings.js +25 -2
  54. package/server/update.js +324 -0
  55. package/server/usage.js +642 -0
  56. package/server/watcher.js +67 -13
  57. package/server/worktree.js +600 -0
  58. package/server/writer.js +98 -26
  59. package/web/awake.js +62 -0
  60. package/web/base.css +4 -0
  61. package/web/board.css +404 -16
  62. package/web/board.js +1182 -152
  63. package/web/changelog.js +3 -3
  64. package/web/conf.js +118 -0
  65. package/web/files.css +206 -1
  66. package/web/files.html +10 -0
  67. package/web/files.js +533 -75
  68. package/web/fuzzy.js +73 -21
  69. package/web/index.html +109 -12
  70. package/web/json.js +145 -0
  71. package/web/list.css +536 -0
  72. package/web/list.js +1015 -0
  73. package/web/mentions.js +27 -9
  74. package/web/recency.js +10 -10
  75. package/web/units.js +1 -1
  76. package/web/usage.css +169 -0
  77. package/web/usage.html +78 -0
  78. package/web/usage.js +447 -0
  79. package/web/view.js +22 -3
  80. package/web/whatsnew.css +211 -0
  81. package/web/whatsnew.html +49 -0
  82. package/web/whatsnew.js +339 -0
@@ -0,0 +1,156 @@
1
+ ---
2
+ name: k0-plan
3
+ description: Plans one k0 story in plan mode, with the decisions already taken written into the plan as constraints the plan has to satisfy out loud, then stores the approved plan on the story and moves it to Planned. Use this skill when the user types "/k0-plan" or "/k0-plan K42", or says "plan this story", "let's plan K42", "make the plan before we start", "pianifica questa storia", "facciamo il piano di K42", "prepara il piano". Do not use it to discuss a story that has never been discussed (that is /k0-discuss), to break a story into tasks (/k0-split), or to write any code: this skill plans and never edits a file.
4
+ ---
5
+
6
+ # /k0-plan [key]
7
+
8
+ A plan that quietly contradicts what was already decided is the failure this whole feature
9
+ exists to prevent. So the plan carries the decisions in it, in writing, and every step says
10
+ which one it serves.
11
+
12
+ `[key]` is a story key such as `K42`. With no argument, the story is the one this session is
13
+ attached to.
14
+
15
+ ## 1. Find the story, and read it
16
+
17
+ ```bash
18
+ PORT="${K0_PORT:-4319}"
19
+ REPO="$(git rev-parse --path-format=absolute --git-common-dir 2>/dev/null)"; REPO="${REPO%/.git}"
20
+ [ -d "$REPO" ] || REPO="$(git rev-parse --show-toplevel 2>/dev/null)"
21
+ curl -sS --max-time 30 --get --data-urlencode "repo=$REPO" \
22
+ "http://127.0.0.1:$PORT/api/backlog" -o "$SCRATCH/k0-backlog.json"
23
+ ```
24
+
25
+ `127.0.0.1`, not `k0.localhost`: browsers resolve that name by themselves, `curl` does not.
26
+ `--get --data-urlencode`, not `?repo=$REPO`: a repository path with a space in it makes `curl`
27
+ refuse the address outright, and one with a `#` in it quietly sends half.
28
+ `$SCRATCH` is the session's scratch directory; nothing is written outside it. `REPO` is the
29
+ repository the stories are filed under — the main one, even when this session sits in a
30
+ subdirectory of it or inside a worktree, which is why it is not `$PWD`.
31
+
32
+ - `curl` cannot connect → the k0 server is not running. Say so (`k0-board start`, or the tray
33
+ icon → *Restart*) and **stop**.
34
+ - `{"enabled": false}` → say in one line that the k0 backlog is switched off and **stop**.
35
+ - `REPO` empty → this is not a git repository. Ask once which repository this belongs to and
36
+ take the path he gives.
37
+ - **A listing with no stories in it** → say that plainly. It means this repository has nothing
38
+ on the board, not that you failed to find the story; do not fall back to asking the user for a
39
+ key, a state or a plan the board would have given you.
40
+
41
+ With a key, take that story. With no key, take the story whose `session` is alive in this
42
+ repository; if more than one is, that is the only thing worth asking about — ask which.
43
+
44
+ ```bash
45
+ curl -sS --max-time 30 "http://127.0.0.1:$PORT/api/backlog/story/$STORY_ID" -o "$SCRATCH/k0-story.json"
46
+ ```
47
+
48
+ `$STORY_ID` is the `id` of the story you just matched, not its key. That file holds the body, the
49
+ rounds, the decisions, the checks, any plan already stored and the log. Everything else — the
50
+ epic, the dependencies, what is blocked — is in the first call. Do not ask the user
51
+ for any of it, and do not work it out yourself.
52
+
53
+ - **No decisions at all** → the story was never discussed. Say so, offer `/k0-discuss`, and go on
54
+ only if the user tells you to plan it as it stands.
55
+ - **A plan already stored** → say it exists, in one line say what it plans, and ask whether to
56
+ replace it. A new plan overwrites the old one.
57
+ - **A dependency that is not Done** → say which, before planning. The user decides whether to
58
+ carry on.
59
+
60
+ ## 2. Plan mode
61
+
62
+ Enter plan mode and stay in it. Read the code, follow the story, ask what you must — nothing on
63
+ disk changes until the plan is approved, and this skill never changes anything on disk at all.
64
+
65
+ For questions, `AskUserQuestion`, and the rules that govern them are the ones in
66
+ `../k0-discuss/references/rounds.md` — how many rounds and how to say the count, when to stop,
67
+ how to ask, and what never to ask. The path is relative to the folder this skill was loaded from;
68
+ the two skills are siblings wherever k0 is installed. Read that file; it is not restated here,
69
+ and if you cannot find it, say so and **stop**. Planning is usually two or three rounds, not
70
+ eight: most of the unknowns were closed by the discussion.
71
+
72
+ **Keep the planning on tasks.** The task tools work in plan mode, so before the first question
73
+ create one task per phase — reading the story, the rounds of questions, writing the constraints
74
+ and the plan, storing it once approved (§4) — and move each one to `in_progress` when it starts
75
+ and `completed` when it is over. They are how somebody glancing at this terminal sees where the
76
+ planning has got to. If `TaskCreate` is not among your tools, say so in one line and carry on;
77
+ never call it again to see whether it has come back.
78
+
79
+ ## 3. The constraints go in the plan, in writing
80
+
81
+ The plan opens with two blocks, above anything technical:
82
+
83
+ ```markdown
84
+ ## What you get
85
+ <one or two sentences, in the user's language: what is different once this is done>
86
+
87
+ ## Constraints — already decided
88
+ - **D1** <the decision, word for word as it is recorded>
89
+ - **K7·D3** <one inherited from the epic, under the label the story shows it with>
90
+ ```
91
+
92
+ Then the plan itself. Rules that make it worth reading:
93
+
94
+ - **Every decision that is still standing appears.** Copy the sentence as recorded, in the
95
+ language it was written in; do not summarise it, do not translate it, do not tidy it up.
96
+ - **Use each decision's `label`, exactly as the story gives it.** The list is the effective set:
97
+ the story's own, labelled `D1`, `D2`, and its epic's, labelled `K7·D3` — decided before this
98
+ story existed and binding on every story under that epic. The epic's key in front is what says
99
+ so, and it matters because the story usually has a `D3` of its own that says something else. A
100
+ plan with two lines both called `D3` is a plan whose constraints cannot be checked, and
101
+ `/k0-verify` will name them the other way round.
102
+ - **Leave out the superseded ones.** A decision with `superseded_by` set lost; the one that beat
103
+ it is already in the list.
104
+ - **Every step of the plan names the decisions it serves** — by label, `(D2, K7·D3)` at the end of
105
+ the line. A step that serves none is either scaffolding or something nobody asked for; say which.
106
+ - **A decision the plan cannot satisfy stops the plan.** Do not plan around it and do not
107
+ reinterpret it. Put it in front of the user, say what it collides with, say which you think
108
+ should win and why, and wait — the collision rules are §4 of `rounds.md`.
109
+ - The rest of the plan is a plan: what gets touched, in what order, what could go wrong. Keep it
110
+ short enough to be read in one sitting.
111
+ - **Write the steps so each one can be a task.** `/k0-work` opens with one task per step of the
112
+ stored plan, so a step is one thing somebody could say is finished — not a paragraph holding
113
+ three.
114
+
115
+ Anything settled while planning is a **new decision**, written the moment it is settled, in the
116
+ user's language, one sentence about behaviour and not implementation (§5 of `rounds.md`):
117
+
118
+ ```bash
119
+ curl -sS --max-time 30 -X POST "http://127.0.0.1:$PORT/api/backlog/story/$STORY_ID/decision" \
120
+ -H 'content-type: application/json' -d @"$SCRATCH/k0-decision.json" # {"text": "…", "source": "plan"}
121
+ ```
122
+
123
+ ## 4. When the user approves it
124
+
125
+ Two calls, in this order:
126
+
127
+ ```bash
128
+ curl -sS --max-time 30 -X POST "http://127.0.0.1:$PORT/api/backlog/story/$STORY_ID/plan" \
129
+ -H 'content-type: application/json' -d @"$SCRATCH/k0-plan.json" # {"text": "<the whole plan>"}
130
+
131
+ curl -sS --max-time 30 -X PATCH "http://127.0.0.1:$PORT/api/backlog/story/$STORY_ID" \
132
+ -H 'content-type: application/json' -d '{"state": "Planned"}'
133
+ ```
134
+
135
+ Store the plan **as it was approved**, in the user's language, the constraints block included —
136
+ it is what `/k0-work` reads and what `/k0-verify` holds the finished work up against. Write the
137
+ JSON to a file under `$SCRATCH` and send it with `-d @file`: a plan pasted inline dies on its
138
+ first quote or newline.
139
+
140
+ Then one more call, **only if the story has no checklist yet**. Write one from the plan — a
141
+ handful of lines, each something the user could look at and tell whether it is true:
142
+
143
+ ```bash
144
+ curl -sS --max-time 30 -X POST "http://127.0.0.1:$PORT/api/backlog/story/$STORY_ID/check" \
145
+ -H 'content-type: application/json' -d @"$SCRATCH/k0-checks.json" # {"items": [{"text": "…"}]}
146
+ ```
147
+
148
+ **Leave a checklist that already exists alone.** This call replaces the whole list, so on a story
149
+ that already has one it does not add lines, it destroys the ones somebody wrote by hand. When
150
+ there is already a checklist, this third call does not happen at all.
151
+
152
+ ## 5. Close
153
+
154
+ Two lines: the story is `Planned`, and `/k0-work` is what does it. Do not start the work, do not
155
+ open a worktree, do not touch a file. That is the next skill's job, and the separation is the
156
+ point: a plan that begins implementing itself was never a plan.
@@ -0,0 +1,169 @@
1
+ ---
2
+ name: k0-split
3
+ description: Breaks a k0 story that will not close — too big, or open for weeks — into tasks that inherit the parent's decisions and context, so nothing has to be explained a second time. Reads what the story already holds, says plainly what it based the split on, proposes the tasks and creates them under the parent once the user agrees. Use this skill when the user types "/k0-split", or says "split K42", "this story is too big", "it has been open for weeks", "break it into pieces", "spezza K42", "questa storia è troppo grande", "dividila in task", "non si chiude mai". Do not use it to create unrelated stories (that is /k0-story), to discuss a story that is merely vague (/k0-discuss), or to decide what to work on next (/k0-next).
4
+ ---
5
+
6
+ # /k0-split [key]
7
+
8
+ A story that has been in `Working` for three weeks is not a story any more. This cuts it into
9
+ tasks that live under it, each one small enough to finish, and each one carrying the decisions
10
+ that already apply to it — so the first thing a task does is not re-explain the story.
11
+
12
+ `[key]` is `K42`, or nothing — with nothing, work out which story from what the user just said.
13
+
14
+ ## Procedure
15
+
16
+ 1. **Find the story, and check the feature is on.**
17
+
18
+ ```bash
19
+ PORT="${K0_PORT:-4319}"
20
+ REPO="$(git rev-parse --path-format=absolute --git-common-dir 2>/dev/null)"; REPO="${REPO%/.git}"
21
+ [ -d "$REPO" ] || REPO="$(git rev-parse --show-toplevel 2>/dev/null)"
22
+ curl -sS --max-time 30 --get --data-urlencode "repo=$REPO" \
23
+ "http://127.0.0.1:$PORT/api/backlog" -o "$SCRATCH/k0-backlog.json"
24
+ ```
25
+
26
+ `127.0.0.1`, not `k0.localhost`: `curl` does not resolve that name. `--get --data-urlencode`,
27
+ not `?repo=$REPO`: a repository path with a space in it makes `curl` refuse the address
28
+ outright, and one with a `#` in it quietly sends half. `$SCRATCH` is the session's
29
+ scratch directory; nothing is written outside it. `REPO` is the repository the stories are
30
+ filed under — the main one, even when this session sits in a subdirectory of it or inside a
31
+ worktree, which is why it is not `$PWD`.
32
+
33
+ - `curl` cannot connect → the server is not running. Say so (`k0-board start`, or the tray
34
+ icon → *Restart*) and **stop**.
35
+ - `{"enabled": false}` → say in one line that the backlog is switched off in k0's settings and
36
+ **stop**.
37
+ - `REPO` empty → this is not a git repository. Ask once which repository this belongs to.
38
+ - A listing with no stories in it → say so and stop; there is nothing here to split.
39
+
40
+ Match the key the user gave, or the title he described. If two stories match, ask which one.
41
+ A story that already has tasks can still be split further; a task itself cannot be split
42
+ again. If the user points at one, say so and offer its parent instead.
43
+
44
+ 2. **Read everything the story holds.**
45
+
46
+ ```bash
47
+ curl -sS --max-time 30 "http://127.0.0.1:$PORT/api/backlog/story/$STORY_ID" -o "$SCRATCH/k0-story.json"
48
+ ```
49
+
50
+ `$STORY_ID` is the `id` of the story you matched in step 1, not its key — which is why this
51
+ call comes after that one and not beside it. Rounds, decisions, plan, checks, log.
52
+
53
+ 3. **Say what you are splitting on, before you propose anything.** Four lines at most, and every
54
+ one of them a fact from the two files you just read — not an impression:
55
+
56
+ > K42 · Fix the invoicing API — `Working` since 12 August, 9 decisions, 2 of them superseded,
57
+ > a plan from 20 August, and a log whose last entry says the export is done and the retries
58
+ > are not.
59
+
60
+ If there are no decisions and no plan, say that too: *the split is based on the story's Why
61
+ and its log, nothing else has been recorded.* The user needs to know how thin the ground is
62
+ before he agrees to stand on it.
63
+
64
+ 4. **Propose the tasks.** Two to five. More than five and you are not splitting the story, you
65
+ are rewriting the epic — say that instead and stop. For each one:
66
+
67
+ - a title of a handful of words, in his language;
68
+ - one line saying what it finishes — a piece that can reach `Done` on its own;
69
+ - **the decisions it inherits, by label**: `D1, D4, D7`. A superseded decision is never
70
+ inherited; the one that superseded it is.
71
+
72
+ Only the story's **own** decisions are shared out this way — the ones whose `owner` is
73
+ `story`. The epic's, labelled `K7·D3`, go to every task automatically because every task
74
+ carries the parent's `epic_key`: do not list them here and do not divide them up. Say in one
75
+ line that they carry over, and leave them alone.
76
+
77
+ Every decision of the story's own that is still standing must land on at least one task. If one
78
+ lands on none, either you missed a task or the decision was about something already finished:
79
+ say which, out loud, rather than letting it fall on the floor.
80
+
81
+ 5. **Ask once.** `AskUserQuestion`, under the rules in §3 of
82
+ `../k0-discuss/references/rounds.md` — the path is relative to the folder this skill was
83
+ loaded from, and the two skills are siblings wherever k0 is installed. Read that file rather
84
+ than working from memory, and if you cannot find it, say so and **stop**. Ask whether the cut
85
+ is right, with the alternative cuts you considered as the other options. If the answer opens
86
+ genuine unknowns, run rounds on them the way that file describes — do not invent your own
87
+ rules. Usually one question is enough.
88
+
89
+ 6. **Create the tasks.** One `POST` each, `parent_key` set to the parent's key, `epic_key` and
90
+ `lang` copied from the parent:
91
+
92
+ ```bash
93
+ curl -sS --max-time 30 -X POST "http://127.0.0.1:$PORT/api/backlog/story" \
94
+ -H 'content-type: application/json' -d @"$SCRATCH/k0-task-1.json"
95
+ ```
96
+
97
+ `body` is the context the task inherits, in the user's language: why the parent exists,
98
+ condensed to what this task needs, and the sentence that says which slice it owns. It is
99
+ written so that somebody opening the task alone, six weeks from now, does not have to open
100
+ the parent to understand it.
101
+
102
+ Then copy each of the **parent's own** decisions that this task inherits onto it, **verbatim**,
103
+ one call each. Never an epic decision: the task already has those, through `epic_key`, as the
104
+ same rows the parent has. Copying one makes a second row saying the same sentence, and the day
105
+ the user reverses it on the epic only the epic's changes — `/k0-verify` goes on checking the
106
+ task against a rule he took back. A decision copied is a decision that forks.
107
+
108
+ ```bash
109
+ curl -sS --max-time 30 -X POST "http://127.0.0.1:$PORT/api/backlog/story/$TASK_ID/decision" \
110
+ -H 'content-type: application/json' -d @"$SCRATCH/k0-decision.json" \
111
+ -o "$SCRATCH/k0-new-decision.json"
112
+ ```
113
+
114
+ Copied verbatim means copied: same sentence, same language, same wording. Rewording an
115
+ inherited decision to fit the task is how a decision quietly changes meaning, and `/k0-verify`
116
+ would then be checking the work against something the user never said.
117
+
118
+ **Numbering starts again at 1 on the task, so write down where each one came from.** The
119
+ parent's `D4` may well be the task's `D2`, and the user approved a list that said `D1, D4, D7`.
120
+ Each `POST` answers with the new decision's `n`: put the correspondence at the end of the
121
+ task's `body`, one line, in his language —
122
+
123
+ > Decisions inherited from K42: D1 here is K42's D1, D2 is K42's D4, D3 is K42's D7.
124
+
125
+ — and repeat it in the parent's log in step 8. Without it, `/k0-verify` reports on `D1, D2, D3`
126
+ and the man reviewing his own decisions has nothing to tie them back to.
127
+
128
+ 7. **Order them if the order matters.** When one task genuinely cannot start before another
129
+ finishes, record it and say so in the same breath:
130
+
131
+ ```bash
132
+ curl -sS --max-time 30 -X POST "http://127.0.0.1:$PORT/api/backlog/dependency" \
133
+ -H 'content-type: application/json' -d '{"story_id": 91, "depends_on": 90}'
134
+ ```
135
+
136
+ A dependency is a note, not a lock: it marks the task and never stops anybody starting it.
137
+ Do not invent an order to look tidy — two tasks that could be done in either order get no
138
+ dependency.
139
+
140
+ 8. **Write the split into the parent's log**, one line, in his language, then say what you did.
141
+
142
+ ```bash
143
+ curl -sS --max-time 30 -X POST "http://127.0.0.1:$PORT/api/backlog/story/$STORY_ID/log" \
144
+ -H 'content-type: application/json' -d @"$SCRATCH/k0-log.json"
145
+ ```
146
+
147
+ The account is short: the keys and titles of the tasks that were born, and which of the
148
+ parent's decisions each one carries, by the parent's numbers. Then stop. Do not start working
149
+ on the first one.
150
+
151
+ ## Rules
152
+
153
+ - **The parent survives.** It is not deleted, its decisions are not moved, its state is not
154
+ changed, and its rounds stay where they are. It becomes the place the tasks came from, and it
155
+ closes when they are done — by the user pressing `Done`, as always.
156
+ - **A copied decision lives in two places, and both have to move together.** That is the cost of
157
+ the copy, and it is why only the parent's own decisions are ever copied: when one is later
158
+ reversed, the copy on the task is superseded too — §4 of `rounds.md` says how. An epic's
159
+ decision is never copied and so never has this problem: it is one row, reversed once.
160
+ - **Nothing is decided that was not decided.** A split redistributes what is already recorded.
161
+ If a task needs an answer nobody has given, it is an open question you name in step 4, not a
162
+ decision you write on the user's behalf.
163
+ - **Say what you based it on, always.** Step 3 is not a courtesy. A split proposed without
164
+ showing its ground is a guess wearing a plan's clothes, and the user has no way to tell.
165
+ - **Talk in the language the user speaks, and store what he says in that language.**
166
+ - **Never ask what the API can tell you** — the state, the age, the decisions, the plan, the log,
167
+ the epic, the dependencies are all in the two calls in steps 1 and 2. See §7 of `rounds.md`.
168
+ - **No files outside the scratch directory**, and never write into `.k0/` by hand: the server
169
+ mirrors the tasks there on its own.
@@ -0,0 +1,108 @@
1
+ ---
2
+ name: k0-story
3
+ description: Puts one story on the k0 board in a single move — the user says what he wants, it lands as a post-it with a key of its own, and a Claude Code session can start on it straight away. No questions, no rounds, no ceremony: this is the fast door. Use this skill when the user says "/k0-story", "add a story", "put this on the board", "new post-it", "note this down for later", "one more thing for the backlog", "and start it now", or in Italian "aggiungi una storia", "mettila sul board", "segnati questa cosa", "nuova storia e partiamo". Do not use it for something big enough to need breaking up — that is /k0-epic — and do not use it on a story that already exists: discussing it is /k0-discuss, planning it is /k0-plan, working it is /k0-work.
4
+ ---
5
+
6
+ # /k0-story [what it is]
7
+
8
+ One story, straight onto the board. The user has already said what he wants; your job is to
9
+ write it down well and get out of the way. **No rounds, no questions, no confirmation** unless
10
+ he asks for one or something is genuinely missing.
11
+
12
+ If he also says *and start it* — or anything like it — start the session in the same breath.
13
+
14
+ ## Before anything
15
+
16
+ ```bash
17
+ PORT="${K0_PORT:-4319}"
18
+ REPO="$(git rev-parse --path-format=absolute --git-common-dir 2>/dev/null)"; REPO="${REPO%/.git}"
19
+ [ -d "$REPO" ] || REPO="$(git rev-parse --show-toplevel 2>/dev/null)"
20
+ curl -sS --max-time 30 --get --data-urlencode "repo=$REPO" \
21
+ "http://127.0.0.1:$PORT/api/backlog" -o "$SCRATCH/k0-backlog.json"
22
+ node -e 'const b=JSON.parse(require("fs").readFileSync(process.argv[1],"utf8"));
23
+ console.log(JSON.stringify({enabled: b.enabled, epics: (b.epics||[]).map(e => ({key: e.key, title: e.title}))}))' \
24
+ "$SCRATCH/k0-backlog.json"
25
+ ```
26
+
27
+ `127.0.0.1`, not `k0.localhost`: browsers resolve that name by themselves, `curl` does not.
28
+ `--get --data-urlencode`, not `?repo=$REPO`: a repository path with a space in it makes `curl`
29
+ refuse the address outright, and one with a `#` in it quietly sends half.
30
+ `$SCRATCH` is the session's scratch directory; nothing is written outside it. `REPO` is the
31
+ repository the stories are filed under — the main one, even when this session sits in a
32
+ subdirectory of it or inside a worktree, which is why it is not `$PWD`.
33
+
34
+ - `curl` cannot connect → the k0 server is not running. Say so (`k0-board start`, or the tray
35
+ icon → *Restart*) and **stop**.
36
+ - `enabled` is `false` → say in one line that the backlog is switched off in k0's settings and
37
+ **stop**. Do not create anything and do not argue for turning it on.
38
+ - `REPO` empty → this is not a git repository. Ask once which repository the story belongs to
39
+ and take the path he gives. That is the only question this skill asks on its own.
40
+
41
+ **Read the two lines `node` prints, not the file.** The board's answer carries every story in the
42
+ repository with everything known about each one, and this skill needs exactly two things out of
43
+ it: whether the feature is on, and what the epics are called. On a board of a hundred stories,
44
+ reading all of that to write one post-it costs more than the post-it does. If the user named no
45
+ epic, even the list of epics is surplus — check `enabled` and move on.
46
+
47
+ If he did name one in passing — *"this one goes under invoicing"* — match it in that list and use
48
+ its `key`. Do not ask which epic: a story with no epic is perfectly normal and stands on its own all
49
+ the same.
50
+
51
+ ## Write it
52
+
53
+ - **`title`** — 2 to 6 words, 60 characters at most, the thing itself. Readable, not a slug.
54
+ - **`body`** — the *why*, in one or two sentences: what he wants and what it is for. **His
55
+ words, his language**, tidied but not translated and not padded. If he said one sentence, the
56
+ body is one sentence.
57
+ - **`lang`** — the language he spoke: `it`, `en`, and so on.
58
+ - **`prompt`** — only when the story is starting now: the instruction the session opens with.
59
+
60
+ Do not invent scope. If he described half a thing, the story is half a thing — a story is
61
+ allowed to be thin, and `/k0-discuss` exists for the rest.
62
+
63
+ ## Create it
64
+
65
+ ```bash
66
+ curl -sS --max-time 30 -X POST "http://127.0.0.1:$PORT/api/backlog/story" \
67
+ -H 'content-type: application/json' -d @"$SCRATCH/k0-story.json"
68
+ ```
69
+
70
+ with `{ "project_path": "…", "title": "…", "body": "…", "lang": "it", "epic_key": "K7" }` —
71
+ `project_path` is `REPO`, and `epic_key` only when there is one. Write the JSON to a file and
72
+ send it with `-d @file`: a body dictated by voice will have quotes and newlines in it and will
73
+ not survive being pasted inline.
74
+
75
+ The answer carries the `key` and the `id`. **Read them from there** — never work
76
+ them out yourself, and never ask.
77
+
78
+ ## Start it, if that is what he said
79
+
80
+ ```bash
81
+ curl -sS --max-time 30 -X POST "http://127.0.0.1:$PORT/api/backlog/story/$ID/start" \
82
+ -H 'content-type: application/json' -d '{"auto_send": true}'
83
+ ```
84
+
85
+ `prompt` is optional here: leave it out and the story's own prompt is used. Only start when he
86
+ asked. A story created and left on the board is the normal case.
87
+
88
+ ## Say one line
89
+
90
+ In his language, and one line is the whole report:
91
+
92
+ > **K42 · 1.12** — Fix the invoice export. On the board, in Backlog.
93
+
94
+ Add *and the session is running* when you started one. Nothing else: no summary of what you
95
+ understood, no list of what he might want next, no offer to discuss it.
96
+
97
+ ## Rules
98
+
99
+ - **Speed is the feature.** Two calls, one line back. If you find yourself asking a second
100
+ question, you are in the wrong skill.
101
+ - **Never ask for what the API just told you** — the key, the epic, the state.
102
+ - **Store what he said in the language he said it in.** The interface is English; his words are
103
+ his.
104
+ - **This skill only creates.** No `PATCH`, no `DELETE`, no touching stories that already exist.
105
+ - **Several stories in one breath** — *"add these three"* — is still this skill: one `POST` each,
106
+ then one line each. Do not turn it into a discussion.
107
+ - If he starts discussing instead of dictating, hand over to `/k0-discuss` on the story you have
108
+ just created rather than running rounds here.