k0-board 0.4.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 (73) 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 +361 -1
  21. package/README.md +931 -111
  22. package/bin/k0-board.js +79 -11
  23. package/menubar/K0MenuBar.swift +35 -5
  24. package/package.json +13 -1
  25. package/platform/contract.js +30 -5
  26. package/platform/darwin/terminal.js +230 -56
  27. package/platform/index.js +2 -1
  28. package/platform/linux/index.js +3 -0
  29. package/platform/linux/tray.py +10 -10
  30. package/platform/shared/command.js +19 -3
  31. package/platform/shared/tmux.js +32 -14
  32. package/platform/win32/index.js +5 -2
  33. package/platform/win32/terminal.js +24 -8
  34. package/platform/win32/tray.ps1 +13 -13
  35. package/server/backlog.js +618 -0
  36. package/server/changelog.js +13 -13
  37. package/server/db.js +1800 -146
  38. package/server/files.js +60 -21
  39. package/server/git.js +53 -14
  40. package/server/idle.js +15 -13
  41. package/server/index.js +1251 -186
  42. package/server/launcher.js +122 -14
  43. package/server/machine.js +10 -1
  44. package/server/mirror.js +1048 -0
  45. package/server/prices.js +59 -0
  46. package/server/projects.js +57 -12
  47. package/server/servers.js +22 -1
  48. package/server/sessions.js +5 -5
  49. package/server/settings.js +25 -2
  50. package/server/update.js +324 -0
  51. package/server/usage.js +642 -0
  52. package/server/watcher.js +67 -13
  53. package/server/worktree.js +600 -0
  54. package/server/writer.js +98 -26
  55. package/web/awake.js +62 -0
  56. package/web/base.css +4 -0
  57. package/web/board.css +396 -16
  58. package/web/board.js +1182 -152
  59. package/web/changelog.js +3 -3
  60. package/web/files.js +73 -16
  61. package/web/index.html +109 -12
  62. package/web/list.css +536 -0
  63. package/web/list.js +1015 -0
  64. package/web/mentions.js +27 -9
  65. package/web/recency.js +10 -10
  66. package/web/units.js +1 -1
  67. package/web/usage.css +169 -0
  68. package/web/usage.html +78 -0
  69. package/web/usage.js +447 -0
  70. package/web/view.js +22 -3
  71. package/web/whatsnew.css +211 -0
  72. package/web/whatsnew.html +49 -0
  73. package/web/whatsnew.js +339 -0
@@ -0,0 +1,95 @@
1
+ ---
2
+ name: k0-whatsnew
3
+ description: Writes the What's New page — what changed between the version of k0 somebody had and the one they are running now — from the CHANGELOG entries k0 hands over on standard input, in the language and at the level of detail they asked for. k0 calls it by itself when somebody opens the What's New page after a version jump. Use this skill when the user types "/k0-whatsnew", or asks "what changed in this version", "what's new since the version I had", "cosa è cambiato nell'ultima versione". Do not use it to look the facts up: they arrive on standard input already, and this skill never reads CHANGELOG.md, never runs git, and never calls the API.
4
+ ---
5
+
6
+ # /k0-whatsnew
7
+
8
+ You are handed, on standard input, the CHANGELOG entries between two versions of k0, plus the
9
+ language to write in and how technical to be. Write the page somebody reads once, after k0
10
+ told them it had moved on while they were not looking.
11
+
12
+ Your entire reply is the page. It is printed as it is, so there is no room for a preamble, no
13
+ "here is what changed", no closing offer of further help, and no code fence around the whole
14
+ thing. Markdown, starting at the first word that belongs to the page.
15
+
16
+ ## What arrives
17
+
18
+ ```json
19
+ {
20
+ "from": "0.3.1",
21
+ "to": "0.4.0",
22
+ "lang": "it",
23
+ "level": "normal",
24
+ "entries": [
25
+ {
26
+ "version": "0.4.0",
27
+ "date": "2026-09-02",
28
+ "sections": {
29
+ "Added": ["the file viewer opens the file the session touched last"],
30
+ "Fixed": ["the search underlines the letters in the name, and leaves the path alone"],
31
+ "Changed": ["…"]
32
+ }
33
+ }
34
+ ]
35
+ }
36
+ ```
37
+
38
+ `entries` are the versions between `from` and `to`, newest first, in the Keep a Changelog
39
+ shape the repository already uses. `lang` is a language tag — write everything in it. `level`
40
+ is one of `plain`, `normal`, `nerd`.
41
+
42
+ ## The three levels
43
+
44
+ The facts are the same at all three. What changes is who is being told.
45
+
46
+ - **`plain`** — for somebody who uses k0 and never thinks about how it is built. No file names,
47
+ no module names, no flags, no words of the trade beyond the ones on the buttons. Say what
48
+ they will notice: what is on the screen now that was not, what stopped getting in the way.
49
+ - **`normal`** — the default. Name the parts of k0 the way the interface names them: the board,
50
+ the post-it, the ChangeLog page, the tray icon. Still no paths, still no function names.
51
+ - **`nerd`** — for the person who would read the diff. Name the modules, the settings, the
52
+ flags, and say *why* a thing was done when the entry makes it clear. Never guess at a reason
53
+ the entries do not give.
54
+
55
+ ## The shape of the page
56
+
57
+ ```markdown
58
+ ## What is new in 0.4.0
59
+
60
+ <one paragraph, no heading above it — two or three sentences saying what is
61
+ different now, and one line on how far back this reaches when it is more than
62
+ one version>
63
+
64
+ ### The file viewer opens where you left off
65
+ <two or three sentences, or a couple of bullets>
66
+
67
+ ### The search stops wandering into the path
68
+ <…>
69
+ ```
70
+
71
+ **Group by what changed for the person, not by the section it came from.** `Added`, `Fixed` and
72
+ `Changed` are how the changelog is filed, not how anybody reads it: two lines from two different
73
+ sections about the same thing belong under one heading.
74
+
75
+ The headings say **what is different now**, not what was modified. Not "the search algorithm was
76
+ narrowed" but "the search stops wandering into the path". Drop a heading that has only one short
77
+ line under it and let the line live in the paragraph instead.
78
+
79
+ ## Rules
80
+
81
+ - **Write in `lang`.** All of it: the title, the headings, the paragraphs. Do not translate the
82
+ words of the trade — *commit*, *changelog*, *post-it*, *branch* are what these things are
83
+ called in every language, and they do not decline. Version numbers stay numerals.
84
+ - **Do not invent.** If an entry does not say what it did, say what it says and stop. A page
85
+ that guesses is worse than a page that is short.
86
+ - **Leave out what has nothing in it for the reader.** A version whose only entry is that
87
+ nothing visible changed gets half a line, or no line at all — not a heading of its own.
88
+ - **No emoji, no exclamation marks, no thanking anybody for updating.** Nothing is exciting;
89
+ things changed.
90
+ - **Never print commit hashes, version tags as links, or an upgrade command.** k0 already knows
91
+ how it got here, and the page is read after the fact, not before.
92
+ - **If `entries` is empty**, write one line saying nothing changed between the two versions and
93
+ stop. Do not pad it out.
94
+ - **Only what is in front of you.** No reading of files, no git, no API calls, no network. The
95
+ facts arrive on standard input and that is all there is.
@@ -0,0 +1,212 @@
1
+ ---
2
+ name: k0-work
3
+ description: Carries out a planned k0 story inside its own git worktree — opens the worktree through k0 from the branch you are on, does the work there, writes to the story's Log as it goes so a session that runs out of context hands over cleanly, then merges back into that same branch and destroys the worktree. Never pushes and never opens a pull request. Use this skill when the user types "/k0-work" or "/k0-work K42", or says "start the work", "do it", "let's build K42", "carry on with this story", "fai il lavoro", "inizia a lavorare su K42", "mettiti al lavoro", "riprendi la storia". Do not use it on a story with no stored plan (that is /k0-plan), to check the finished work against the decisions (/k0-verify), or to push, tag or release anything (/commit-push-deploy).
4
+ ---
5
+
6
+ # /k0-work [key]
7
+
8
+ The work of one story, from an empty worktree to a merge, with a Log that lets somebody else —
9
+ or this same session after a compaction — pick it up cold.
10
+
11
+ `[key]` is a story key such as `K42`. With no argument, the story is the one this session is
12
+ attached to.
13
+
14
+ ## 1. Find the story
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
+ ```
23
+
24
+ `127.0.0.1`, not `k0.localhost`: browsers resolve that name by themselves, `curl` does not.
25
+ `--get --data-urlencode`, not `?repo=$REPO`: a repository path with a space in it makes `curl`
26
+ refuse the address outright, and one with a `#` in it quietly sends half.
27
+ `$SCRATCH` is the session's scratch directory; nothing is written outside it. `REPO` is the
28
+ repository the stories are filed under — the main one, even when this session sits in a
29
+ subdirectory of it or inside a worktree, which is why it is not `$PWD`.
30
+
31
+ - `curl` cannot connect → the k0 server is not running. Say so (`k0-board start`, or the tray
32
+ icon → *Restart*) and **stop**.
33
+ - `{"enabled": false}` → say in one line that the k0 backlog is switched off and **stop**.
34
+ - `REPO` empty → this is not a git repository. Ask once which repository this belongs to and
35
+ take the path he gives.
36
+ - **A listing with no stories in it** → say that plainly and stop. An empty board is not a story
37
+ you failed to find, and it is never a reason to ask the user for the plan the board would have
38
+ handed you.
39
+
40
+ With a key, take that story; with none, the one whose `session` is alive here. If two could be
41
+ meant, ask once, showing both.
42
+
43
+ ## 2. Read it, and earn the right to start
44
+
45
+ ```bash
46
+ curl -sS --max-time 30 "http://127.0.0.1:$PORT/api/backlog/story/$STORY_ID" -o "$SCRATCH/k0-story.json"
47
+ ```
48
+
49
+ `$STORY_ID` is the `id` of the story you matched in step 1, not its key — the call needs the id,
50
+ which is why it could not go in the same block as the listing that gives it to you.
51
+
52
+ Then read the story file and obey what is in it:
53
+
54
+ - **No plan** → stop. Say the story has never been planned and point at `/k0-plan`. A worktree is
55
+ never opened before there is a plan: work that starts without one is work that gets thrown away.
56
+ - **No session** — `session` is `null` → start one, and say in one line that you did. A story
57
+ planned on the board and then picked up in a terminal the user opened himself has no session
58
+ row, and that is the ordinary case, not an error:
59
+
60
+ ```bash
61
+ curl -sS --max-time 30 -X POST "http://127.0.0.1:$PORT/api/backlog/story/$STORY_ID/start" \
62
+ -H 'content-type: application/json' -d '{}'
63
+ ```
64
+
65
+ The answer carries the story with its new `session`. Use the `session.id` from it in step 3.
66
+ Never open a worktree by hand and never invent a session id.
67
+ - **A Log with entries** → this is a handover, not a fresh start. Read it, say in one line where
68
+ you are picking up, and carry on from there. Never redo what the last session recorded as done.
69
+ - **The decisions that are still standing** are the constraints you work under. Keep that list in
70
+ front of you. **Leave out any decision with `superseded_by` set** — it was reversed, the one
71
+ that beat it is already in the list, and honouring a reversed rule is both wrong work and,
72
+ worse, a false alarm in step 3 that teaches the user to ignore the real ones.
73
+ - **Call each decision by its `label`, never by its number.** The list is the story's own
74
+ decisions *and* its epic's: an inherited one is labelled `K7·D3` and binds every story under
75
+ that epic, while the story may have a `D3` of its own saying something else entirely. Two
76
+ different sentences both called "D3" is how the wrong rule gets honoured and the right one
77
+ quietly dropped.
78
+ - The key, the epic, the dependencies, the checks and the session are all in those two
79
+ files. Do not ask the user for anything they already say.
80
+
81
+ The server sets the story to `Working` by itself when the session goes live. If the API still
82
+ shows something else, set it once and move on:
83
+
84
+ ```bash
85
+ curl -sS --max-time 30 -X PATCH "http://127.0.0.1:$PORT/api/backlog/story/$STORY_ID" \
86
+ -H 'content-type: application/json' -d '{"state": "Working"}'
87
+ ```
88
+
89
+ **Then turn the plan into tasks — every time, before the worktree.** One `TaskCreate` for each
90
+ step of the stored plan, in the plan's order: the subject is the step in a few words, the
91
+ description is the step in full with the labels of the decisions it serves. On a handover, only
92
+ the steps the Log does not record as done. The merge (§6) and the closing entry (§7) are tasks
93
+ too, the last two. From then on:
94
+
95
+ - exactly **one** task `in_progress` at a time, set with `TaskUpdate` when the step starts — not
96
+ after it is over;
97
+ - `completed` the moment that step is really done, never in a batch at the end;
98
+ - a step the plan did not foresee becomes a new task the moment you find it, and a step that turns
99
+ out to be unnecessary is deleted with one sentence saying why.
100
+
101
+ The tasks are for whoever is watching this terminal now; the Log is for whoever picks the story up
102
+ cold. Keep both — neither stands in for the other.
103
+
104
+ If `TaskCreate` is not among your tools, say so in one line — the session was not opened by k0, or
105
+ Claude Code is older than the commands; on newer models Claude Code only offers the task tools
106
+ when `CLAUDE_CODE_ENABLE_TODO_TOOLS=1` is in the environment — and carry on with the Log alone.
107
+ Never call it again to see whether it has come back.
108
+
109
+ ## 3. Open the worktree
110
+
111
+ ```bash
112
+ curl -sS --max-time 30 -X POST "http://127.0.0.1:$PORT/api/backlog/worktree" \
113
+ -H 'content-type: application/json' -d "{\"session\": $SESSION_ID, \"action\": \"open\"}"
114
+ ```
115
+
116
+ `$SESSION_ID` is `session.id` from the story you just fetched: the **row id, a number**. It is
117
+ not `session.session_id`, which is the Claude Code session's own long text id — the field is
118
+ called `session` and takes a number so the two cannot be confused.
119
+
120
+ The answer is `{"ok": true, "path": "…", "branch": "wt-K42", "base": "…"}`. **`path` is the
121
+ worktree**, and it is the only place you may write from here on; call it `$WORK`. If `ok` is
122
+ false, the answer says why in a sentence meant to be read out — say it and stop. Do not guess a
123
+ directory and do not fall back to the repository: that is the one thing this step exists to
124
+ prevent.
125
+
126
+ k0 branches **from the branch you are on** — not from `main`, not from `origin`. Do not check out
127
+ another branch first, do not `git pull`, do not `git fetch`. If the user is on a feature branch,
128
+ that is the branch this work belongs to, and the merge at the end goes back into that one.
129
+
130
+ From here every path you touch is absolute and under `$WORK`. Nothing is written in the base
131
+ repository — not a file, not a note, not a scratch script.
132
+
133
+ ## 4. Do the work, and write the Log as you go
134
+
135
+ Follow the plan. Where the plan turns out to be wrong, say so and adjust; where the change
136
+ contradicts a decision that is still standing, **stop and ask** before writing the code — that
137
+ collision is §4 of `../k0-discuss/references/rounds.md`, and the same file says how a decision is
138
+ written. The path is relative to the folder this skill was loaded from; the two skills are
139
+ siblings wherever k0 is installed, and if you cannot find the file, say so rather than inventing
140
+ the rule. Anything newly settled goes to the API the moment it is settled:
141
+
142
+ ```bash
143
+ curl -sS --max-time 30 -X POST "http://127.0.0.1:$PORT/api/backlog/story/$STORY_ID/decision" \
144
+ -H 'content-type: application/json' -d @"$SCRATCH/k0-decision.json" # {"text": "…", "source": "chat"}
145
+ ```
146
+
147
+ **Append to the Log after every meaningful step** — not at the end, not in one lump. The same
148
+ moment is when that step's task goes to `completed` and the next one to `in_progress`:
149
+
150
+ ```bash
151
+ curl -sS --max-time 30 -X POST "http://127.0.0.1:$PORT/api/backlog/story/$STORY_ID/log" \
152
+ -H 'content-type: application/json' -d @"$SCRATCH/k0-log.json"
153
+ ```
154
+
155
+ with `{"text": "…", "session_id": "<session.session_id>"}`. Write the JSON to a file under
156
+ `$SCRATCH` and send it with `-d @file`; pasted inline it dies on the first quote or newline.
157
+
158
+ A Log entry is two or three lines in the user's language and answers exactly two questions:
159
+ **what is now done**, and **what is left, and where it was left**. Names of files are welcome
160
+ here — this one is read by whoever continues, not by the user over a coffee. Write it as though
161
+ the session ends immediately after the call, because sometimes it does.
162
+
163
+ ## 5. Never run anything in the worktree
164
+
165
+ No tests, no build, no dev server, no `npm run` of any kind, inside `$WORK`. The reason is
166
+ concrete: the `.env` that came across with the worktree carries the **base repository's port**, so
167
+ a runner that finds a live server there reuses it — and that server is serving the base
168
+ repository's code. The run goes green against code you did not write, which is worse than no run
169
+ at all, because it is believed.
170
+
171
+ The tests belong on the base branch after the merge, where the server serves the merged code.
172
+ Whether they run there is the repository's business, not this skill's.
173
+
174
+ ## 6. Merge, and put the worktree away
175
+
176
+ ```bash
177
+ curl -sS --max-time 30 -X POST "http://127.0.0.1:$PORT/api/backlog/worktree" \
178
+ -H 'content-type: application/json' -d "{\"session\": $SESSION_ID, \"action\": \"merge\"}"
179
+ ```
180
+
181
+ The same `session` row id as in step 3. k0 commits whatever is pending in the worktree with a
182
+ message written from the diff — Conventional Commits, one line, English — merges it `--no-ff` into
183
+ the branch it came from, removes the worktree and deletes its branch.
184
+
185
+ The answer says `hooks: true` when a commit was made. That commit ran the repository's own
186
+ `pre-commit` hook, **inside the worktree** — so if that hook runs a test suite, the suite it ran
187
+ was the one next door, with the copied `.env`. Say so in one line when it happens: it is the same
188
+ trap as §5, arriving from the other direction, and the run that counts is the one after the merge.
189
+
190
+ **Never `git push`. Never a pull request.** Not with a flag, not because the user's branch tracks
191
+ a remote, not to be helpful. What leaves this machine leaves it through `/commit-push-deploy`, and
192
+ only when the user asks.
193
+
194
+ If the merge comes back with a conflict, **stop**. Say which files, leave the worktree standing,
195
+ and let the user decide. Do not guess a resolution and do not delete anything.
196
+
197
+ ## 7. Close — and say that nothing has been checked yet
198
+
199
+ A last Log entry saying the work is merged and what is in it. Then, to the user, in his language:
200
+
201
+ 1. one line: what is different now;
202
+ 2. one line that does not get softened — **no decision has been checked against the finished work
203
+ yet.** Read the story's `decisions` and say how many are standing and waiting. Pressing `Done`
204
+ now closes a story nobody counter-checked, and the discussion that produced those decisions was
205
+ then worth nothing.
206
+ 3. offer to run the counter-check now. If he says yes, follow `/k0-verify` on this story before
207
+ anything else. If he says no, leave it — but he has been told, and the story goes to the board
208
+ knowing it.
209
+
210
+ Do not set the story to `Review` — `/k0-verify` does that when it starts a run. Do not set it to
211
+ `Done` under any circumstances: `Done` is the button the user presses, and nothing else may press
212
+ it.