kadence 0.1.4 → 0.2.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,71 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.2.1] — 2026-09-08
4
+
5
+ > Numbered 0.2.1 because 0.2.0 cannot be published under this name: a different
6
+ > package called `kadence` used that version on 2026-02-05, before this one
7
+ > claimed the name, and npm never allows a version number to be reused. Nothing
8
+ > was released as 0.2.0 — this is the first release of the 0.2 line.
9
+
10
+ The agent contract, made real. `schema: "kadence/v1"` used to be a version
11
+ string that nothing checked; now the contract is published, the failures are
12
+ machine-readable, and the responses can be narrowed to what an agent actually
13
+ reads. Reasoning in [ADR-009](docs/decisions/009-the-agent-contract.md),
14
+ measurements in [Probe C](docs/research/probe-c-agent-cost.md).
15
+
16
+ ### Added
17
+
18
+ - `kadence schema --json` — the machine-readable contract behind
19
+ `schema: "kadence/v1"`: every command, the fields you can rely on, and every
20
+ error code. It works outside a repository, because an agent asks what the tool
21
+ does before it has a project to ask about.
22
+ - Failed `--json` calls now carry `error.code` from a closed list, plus
23
+ `received`, `allowed` and `hint` where each is knowable. `allowed` matters
24
+ most for statuses: they are configured per project, so an agent cannot learn
25
+ the valid set from documentation. There is deliberately no `retryable` field —
26
+ with no network and no lock, the same input always fails the same way.
27
+ - `--fields` on `board --json` and `task list --json`, so an agent can ask for
28
+ the columns it reads instead of every description. On a 200-task board that is
29
+ 130,799 bytes down to 11,015. An unknown name fails with `unknown_field` and
30
+ the list of what exists.
31
+
32
+ ### Changed
33
+
34
+ - **`init` now writes the kadence section into `CLAUDE.md` as well as
35
+ `AGENTS.md`.** Claude Code does not read `AGENTS.md`, so a repository carrying
36
+ only the latter was invisible to the largest agent audience — the README's
37
+ promise that "the AI agent finds it on its own" was not true for them. Text a
38
+ human wrote in either file is left untouched, and a repeat `init` does not
39
+ duplicate the section. If you do not want the file, delete it; nothing else
40
+ depends on it.
41
+
42
+ ### Fixed
43
+
44
+ - **Any `--json` response larger than the pipe buffer was truncated
45
+ mid-string.** `process.exit()` does not wait for an asynchronous write to
46
+ drain, and writing to a pipe — how every agent reads us — is asynchronous,
47
+ while writing to a file is not. A 200-task board produced 131,072 bytes and a
48
+ parse error; the same command redirected to a file was valid. Output is now
49
+ written synchronously.
50
+
51
+ ### Note on the roadmap
52
+
53
+ `kadence context <task>` will not be built. `task show --json` already returns
54
+ the whole history of one piece of work in 948 bytes, and that number does not
55
+ grow with the project — the only thing left to add was a format nobody has
56
+ asked for.
57
+
58
+ ## [0.1.5] — 2026-09-03
59
+
60
+ ### Changed
61
+
62
+ - README rewritten to lead with the number the product exists for — what a
63
+ story point actually costs — instead of a feature list. Claims now carry
64
+ their evidence inline: the merge thesis links to the 8,396-commit study and
65
+ to the integration test that proves it, and the performance table says these
66
+ are tests that fail the build.
67
+ - Repository URLs follow the rename to `bogutskiandriy/kadence`.
68
+
3
69
  ## [0.1.4] — 2026-09-03
4
70
 
5
71
  ### Fixed
package/README.md CHANGED
@@ -1,236 +1,262 @@
1
1
  # kadence
2
2
 
3
- **Your team plans sprints on gut feel. kadence counts what it actually delivers — from a journal that lives in your repository.**
4
-
5
- Tasks, sprints and velocity as plain files inside your git repo. No server, no
6
- account, no network. Works offline, and works for AI agents because the data is
7
- just files they can read.
3
+ **Your team and your AI agents work from the same context — it lives in your repo and remembers what the code cannot.**
8
4
 
9
5
  ```bash
10
6
  npm install -g kadence
11
-
12
7
  kadence init
13
- kadence task add "Fix login" -d "Broken since 2.3" --type bug --estimate 3
14
- kadence ui # interactive board, or `kadence board` for a plain list
15
8
  ```
16
9
 
17
- > **v0.1.0.** The architecture is measured and covered by 383 tests. The product
18
- > bet — that teams want sprint analytics in their repo — has not been validated
19
- > with users yet. See [Honest status](#honest-status).
10
+ No server. No account. No network. Tasks, their whole history and the time they
11
+ took are files next to your code, and they move with your branches.
20
12
 
21
- ## Why another tracker
13
+ ---
22
14
 
23
- There are good file-based trackers already:
24
- [git-bug](https://github.com/git-bug/git-bug),
25
- [Backlog.md](https://github.com/MrLesk/Backlog.md),
26
- [git-issues](https://steviee.github.io/git-issues/). kadence differs in two ways.
15
+ ## The context your code cannot hold
27
16
 
28
- **1. It never conflicts on merge.** The others store a task as a *mutable* file,
29
- so two branches touching one task collide. kadence stores an append-only journal
30
- of events: one file per event, never rewritten.
17
+ Your code says **what** exists. `git log` says **when** it changed. Neither says
18
+ what was tried and abandoned, why a task is blocked, or what the team agreed on
19
+ Tuesday.
31
20
 
32
- We measured this rather than assumed it. Across **8,396 merge commits from 130
33
- public repositories** using file-based trackers, conflicts in task files occur
34
- in 15% of repositories — and **89% of them are `CONFLICT (content)`**, exactly
35
- the type this design eliminates. Full data:
36
- [probe-a-results.md](docs/research/probe-a-results.md).
21
+ That gap costs a human a few minutes. It costs an AI agent the entire session:
22
+ every new one starts from scratch, re-reads the same files and asks the same
23
+ questions you answered yesterday.
37
24
 
38
- **2. It computes velocity.** None of the three tracks sprints, velocity, or how
39
- estimates compare with reality. kadence derives all of it from the journal, so
40
- the numbers cannot be forgotten or faked — they are a product of the work.
25
+ kadence keeps that missing layer as an append-only journal — one file per event,
26
+ committed with the code:
41
27
 
28
+ ```bash
29
+ $ kadence task show KAD-1 --json
42
30
  ```
43
- Sprint "Sprint 12" closed.
44
31
 
45
- Velocity: 10 of 10 points
46
- Actual: 16h — 1.6h per point
32
+ ```json
33
+ {
34
+ "schema": "kadence/v1",
35
+ "label": "KAD-1",
36
+ "title": "Fix login",
37
+ "status": "in_review",
38
+ "loggedHours": 4.5,
39
+ "blockedBy": ["KAD-7"],
40
+ "comments": [
41
+ { "at": "2026-09-02T09:14:00Z", "by": "ana",
42
+ "text": "Session cookie is fine — the redirect drops it." }
43
+ ],
44
+ "history": [
45
+ { "at": "2026-09-01T10:02:00Z", "by": "ana", "type": "task.created" },
46
+ { "at": "2026-09-01T14:40:00Z", "by": "ana", "type": "task.moved", "to": "in_progress" },
47
+ { "at": "2026-09-02T09:20:00Z", "by": "agent","type": "task.blocked_by_added" }
48
+ ]
49
+ }
47
50
  ```
48
51
 
49
- That last number is the point of the whole tool: what a story point actually
50
- costs your team.
52
+ That is the whole state of a piece of work, in one call, with no server to ask
53
+ and no context to rebuild. A human reads it in `kadence task show`. An AI agent
54
+ reads the same thing as JSON.
51
55
 
52
- ## Install
56
+ **And it stays one call.** That answer is 948 bytes whether the project holds ten
57
+ tasks or a thousand — while the journal behind it grows from 5 KB to 528 KB. The
58
+ cost of asking does not grow with the history that makes the answer worth having.
59
+ [Measured](docs/research/probe-c-agent-cost.md).
53
60
 
54
- Requires Node 20 or newer, and a git repository.
61
+ ## Why events and not files
55
62
 
56
- Install it once, so the command stays available:
63
+ Every other tool that keeps work in a repository keeps **state**: a task file, a
64
+ row in a database, the current spec. State has three failure modes, and all
65
+ three are why kadence stores **events** instead.
57
66
 
58
- ```bash
59
- npm install -g kadence
60
- kadence init
61
- ```
67
+ **It drifts.** A spec written on Monday and edited by an agent on Thursday no
68
+ longer says what actually happened. An event cannot drift — it records that
69
+ something occurred, not what is currently true.
62
70
 
63
- Or run it without installing — but note that `npx` fetches the package for that
64
- one command and leaves nothing behind, so every later call needs `npx` too:
71
+ **It conflicts.** Two people editing one task on two branches is a merge
72
+ conflict in every file-based tracker. Here it is not, by construction: the
73
+ journal is append-only, one file per event.
65
74
 
66
- ```bash
67
- npx kadence init
68
- npx kadence board
69
- ```
75
+ **It forgets.** Rewriting a task file destroys the previous version. The journal
76
+ keeps every step, so «how did we get here» has an answer.
70
77
 
71
- `init` creates `.kadence/`, adds the derived cache to `.gitignore`, and writes a
72
- short guide for AI agents. It does **not** commit anything — that call is yours.
78
+ State is still there when you want it — it is folded from the journal on read,
79
+ which is why the board can never drift from reality.
73
80
 
74
- ## Commands
81
+ ---
75
82
 
76
- ```
77
- kadence init set up kadence in this repository
78
- kadence ui interactive kanban board
79
-
80
- kadence task add "<title>" create a task
81
- -d, --description <text> full description
82
- --type task|bug|story|epic type; an epic is simply a parent task
83
- --priority low|normal|high|urgent
84
- -a, --assignee <who> assignee
85
- --label <name> label; repeat for several
86
- --due <date> deadline, YYYY-MM-DD
87
- --parent <task> make it a subtask
88
- --template <name> pre-fill from a saved template
89
- --estimate <points> estimate, always last
90
- kadence task list list tasks
91
- --search <text> title, description and comments
92
- --status|--type|--priority|--assignee|--label
93
- --overdue --due-before <date>
94
- --sort created|priority|due|estimate
95
- --tree show parent/child structure
96
- kadence task show KAD-1 full detail and history
97
- kadence task edit KAD-1 opens $EDITOR; or pass field flags
98
- kadence task move KAD-1 done change state
99
- kadence task assign KAD-1 <who> assign; "none" unassigns
100
- kadence task comment KAD-1 "text" comment
101
- kadence task log KAD-1 2h log time; 90m, -30m to correct
102
- kadence task parent KAD-2 KAD-1 nest under a parent
103
- kadence task block KAD-2 KAD-1 KAD-2 waits for KAD-1
104
- kadence task cancel KAD-1 keeps it in history
105
- kadence task delete KAD-1 drops it from the board
106
-
107
- kadence board plain board, one column per status
108
- -a, --assignee me only your tasks
109
- --sprint only the active sprint
110
- kadence board config show or change the columns
111
- --statuses "todo,doing,done" your own workflow
112
-
113
- kadence sprint create "Sprint 1" first starts now, later ones are planned
114
- kadence sprint add KAD-1 [--sprint "Sprint 2"]
115
- kadence sprint start ["Sprint 2"] start the next planned sprint
116
- kadence sprint close close and report velocity
117
- kadence sprint status progress of the active sprint
118
- kadence sprint burndown chart rebuilt from the journal
119
- kadence sprint list every sprint
120
-
121
- kadence template save bug --type bug --priority high
122
- kadence template list | delete <name>
123
- ```
83
+ ## Why the merge claim holds
84
+
85
+ We measured it before building on it.
86
+
87
+ Across **8,396 merge commits in 130 public repositories** using file-based
88
+ trackers, conflicts in task files hit **15% of repositories** — and **89% are
89
+ `CONFLICT (content)`**, the exact type an append-only journal removes.
124
90
 
125
- Most commands accept several tasks at once — `kadence task move KAD-1,KAD-2 done`
126
- — and apply **all or nothing**: if one id does not exist, nothing changes.
91
+ Then the other direction: three people editing one task on three branches,
92
+ merged in every order. Zero conflicts, every author preserved, identical final
93
+ state. That is an [integration test](test/integration/merge.test.ts), not a
94
+ claim.
127
95
 
128
- Add `--json` to any command for a stable machine-readable shape.
96
+ Full data: [probe-a-results.md](docs/research/probe-a-results.md).
129
97
 
130
- ## The interactive board
98
+ ---
99
+
100
+ ## In practice
101
+
102
+ ```bash
103
+ kadence init
104
+
105
+ kadence sprint create "Sprint 14"
106
+ kadence task add "Fix login" -d "Broken since 2.3" --type bug --priority high --estimate 3
107
+ kadence task comment KAD-1 "Session cookie is fine — the redirect drops it."
108
+ kadence task move KAD-1 done
109
+ kadence sprint close
110
+ ```
111
+
112
+ **The board, when you want to look at it:**
131
113
 
132
114
  ```
133
- kadence ui
115
+ $ kadence ui
116
+
117
+ kadence Sprint 14 9 tasks, 28 points
118
+ +- backlog (2) -------++- in_progress (1) --++- in_review (1) ----++- done (3) ---------+
119
+ | ^# KAD-1 Auth epic || . KAD-4 Tokens @dev||!! KAD-7 Crash [] || v KAD-2 Export |
120
+ | * KAD-3 Login form || || || v KAD-5 Docs |
121
+ +---------------------++--------------------++--------------------++--------------------+
122
+ arrows move enter details m status a assign e edit s sprint / filter q quit
134
123
  ```
135
124
 
136
- Columns side by side, mouse and keyboard:
125
+ Keyboard, mouse, drag between columns, every field editable in place. It calls
126
+ the same commands the CLI does, so the two can never disagree.
127
+
128
+ **And because the journal has the timestamps, the cost comes out of it for free:**
137
129
 
138
130
  ```
139
- ←→ column ↑↓ task enter details [ ] shift a card
140
- m status a assign c comment e edit in $EDITOR
141
- p priority t log time n new d delete
142
- s sprint menu (status, burndown, start, close) S add to sprint
143
- / filter ? help q quit
131
+ $ kadence sprint close
132
+
133
+ Sprint "Sprint 14" closed.
134
+
135
+ Velocity: 23 of 28 points
136
+ Actual: 37h — 1.6h per point
137
+
138
+ Carried over (2):
139
+ · KAD-12 Auth refactor
144
140
  ```
145
141
 
146
- Enter opens a card where every field is editable in place. Dragging a card with
147
- the mouse moves it between columns. Each action runs the same command the CLI
148
- does, so the board can never disagree with the terminal.
142
+ Nobody fills in a form. Nobody can forget to update it. The number is derived
143
+ from state changes the team already made.
149
144
 
150
- The board loads its UI layer lazily — `kadence task add` never pays for it.
145
+ ---
151
146
 
152
- ## For AI agents
147
+ ## For agents
153
148
 
154
- Tasks are files. An agent reads them directly, or through the CLI — no MCP
155
- server, no token, no network:
149
+ Files first. Every command speaks `--json`, every response carries
150
+ `schema: "kadence/v1"`, stdout is JSON and nothing else, warnings go to stderr.
156
151
 
157
152
  ```bash
158
153
  kadence board --json
159
- kadence task list --json --status in_progress --sort priority
160
- kadence task show KAD-1 --json
161
- kadence sprint status --json
154
+ kadence task show KAD-1 --json # full history and comments
162
155
  KADENCE_SOURCE=agent kadence task move KAD-1 in_progress
163
156
  ```
164
157
 
165
- Every `--json` response carries `schema: "kadence/v1"`. stdout holds JSON and
166
- nothing else; warnings go to stderr. Exit codes: `0` success, `1` runtime error,
167
- `2` bad arguments.
158
+ `init` writes that guide into both `AGENTS.md` and `CLAUDE.md` — the first is the
159
+ cross-tool convention, the second is what Claude Code actually reads. Whatever a
160
+ human wrote in either is left alone. No MCP server to run, no token to issue, no
161
+ network call to make.
168
162
 
169
- `init` writes `.kadence/README.md` and a section in `AGENTS.md` so your agent
170
- finds this on its own.
171
-
172
- ## How it works
163
+ The contract is not a promise you have to take on trust:
173
164
 
165
+ ```bash
166
+ kadence schema --json # every command, every field, every error code
174
167
  ```
175
- .kadence/
176
- ├── state.json derived cache — gitignored, safe to delete
177
- └── events/
178
- ├── archive/ compacted history, one file per month
179
- └── 2026-09/ recent events, one file each
168
+
169
+ A failure carries `error.code` and, where the valid set is knowable, `allowed` —
170
+ which matters most for statuses, because they are configured per project and no
171
+ documentation can tell an agent what yours are.
172
+
173
+ An MCP wrapper stays on the roadmap as an **optional package**: it costs about
174
+ 700 tokens a session over the CLI path — [we measured it](docs/research/probe-c-agent-cost.md),
175
+ and it is not the saving the industry benchmarks suggest — but it would be a
176
+ second way to say the same thing, and it would not work for agents that have no
177
+ MCP client at all.
178
+
179
+ Ask for only what you need — a board of a thousand tasks is 803 KB in full, and
180
+ a tenth of that with the fields an agent actually reads:
181
+
182
+ ```bash
183
+ kadence board --json --fields label,status,assignee
180
184
  ```
181
185
 
182
- Every command appends one event. State is folded from the journal on read, so
183
- the board can never drift from reality. Two branches writing at once produce two
184
- different files, and git merges them without a conflict by construction.
186
+ Bulk works everywhere and is all or nothing: `kadence task move KAD-1,KAD-2 done`
187
+ either moves both or changes nothing. A typo does not leave half a board.
188
+
189
+ ---
185
190
 
186
- Measured on 10,000 events:
191
+ ## What it costs you
187
192
 
188
193
  | | |
189
194
  |---|---|
190
- | Cold start with compacted archive | 28 ms |
191
- | Warm start (cache) | 7 ms |
192
- | Journal on disk | 1.9 MB (39 MB without compaction) |
193
- | Bundle | 30 KB, zero runtime deps in the fast path |
195
+ | Install | 29 KB, one runtime dependency |
196
+ | Startup | 80 ms |
197
+ | 10,000 events | 28 ms cold, 7 ms warm |
198
+ | Journal on disk | 1.9 MB |
199
+ | One task, as an agent reads it | 948 bytes — the same at 10 tasks or 1,000 |
200
+
201
+ These are tests. They fail the build on regression, which is why they are still
202
+ true.
194
203
 
195
- These are enforced by tests that fail on regression.
204
+ ---
196
205
 
197
206
  ## Honest status
198
207
 
199
- What is verified:
208
+ **Verified.** The merge thesis, on real git branches. Performance and size, by
209
+ tests that fail if they regress. That the conflict problem exists in the wild —
210
+ measured, not assumed. 428 tests, including an end-to-end run through the
211
+ installed binary.
200
212
 
201
- - The merge thesis, on real git branches: three people editing one task produce
202
- zero conflicts, and every intent is preserved with its author.
203
- - Performance and size guardrails, by tests that fail if they regress.
204
- - The conflict problem exists in the wild — measured, not assumed.
213
+ **Not verified.** That teams and their AI agents actually lose enough context to want
214
+ this. The bet rests on reasoning and on the industry naming the problem out
215
+ loud — not on our own users. That research is
216
+ [designed](docs/research/interview-script.md) and not yet run.
205
217
 
206
- What is not:
218
+ **On the roadmap, not shipped.** `kadence decision` (record why, as its own event
219
+ type) and the optional MCP package — the latter kept as a response to someone who
220
+ cannot use the CLI, not as an inevitability.
207
221
 
208
- - **Whether teams want this.** The velocity bet rests on reasoning, not on user
209
- interviews. That research is designed but not yet run
210
- ([interview script](docs/research/interview-script.md)).
211
- - Conflicts are real but **rare** — roughly one merge in two hundred. That is
212
- why the headline message is analytics, not conflict-freedom.
222
+ `kadence context <task>` was dropped: we measured what `task show --json` already
223
+ returns and it is the whole history of one piece of work, 948 bytes, constant.
224
+ The only thing left to add was a different format, and nobody has asked for one.
213
225
 
214
- The full reasoning, including what would prove this product wrong, lives in
215
- [docs/](docs/README.md).
226
+ **Known limits.** Conflicts are real but rare: roughly one merge in two hundred.
227
+ Terminal interaction is covered by manual testing; only the key router is
228
+ unit-tested.
216
229
 
217
- ## Development
230
+ ---
231
+
232
+ ## How it works
233
+
234
+ ```
235
+ .kadence/
236
+ |- state.json derived cache - gitignored, safe to delete
237
+ `- events/
238
+ |- archive/ compacted history, one file per month
239
+ `- 2026-09/ recent events, one file each
240
+ ```
241
+
242
+ Every command appends one event. State is folded from the journal on read, so
243
+ the board cannot drift from reality. Two branches writing at once produce two
244
+ different files, and git merges them without a conflict by construction.
245
+
246
+ Design decisions, each recording what was measured and what would make us
247
+ revisit it: [docs/decisions/](docs/decisions/).
248
+
249
+ ## Contributing
218
250
 
219
251
  ```bash
220
252
  npm install
221
- npm test # 363 tests
222
- npm run build # single 40 KB bundle
223
- npm run typecheck
253
+ npm test # 428 tests
254
+ npm run build # 29 KB bundle
224
255
  ```
225
256
 
226
- The core has **zero runtime dependencies** — ULID and validation are
227
- hand-rolled, because a general-purpose validator cost 15% of the startup budget
228
- for a seven-field object ([ADR-003](docs/decisions/003-zero-runtime-deps-in-core.md)).
229
- The CLI layer uses `cac` and nothing else.
230
-
231
- Architecture decisions are in [docs/decisions/](docs/decisions/); each one
232
- records what was measured and what would make us revisit it.
257
+ `CLAUDE.md` documents the invariants, the boundaries, and the decisions that
258
+ look arbitrary without their reasoning. Read it before changing the core.
233
259
 
234
- ## License
260
+ ## Licence
235
261
 
236
262
  MIT