kadence 0.6.0 → 0.8.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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,178 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.8.0] — 2026-09-30
6
+
7
+ **The journal is searched before the agent starts guessing.** Agents told to
8
+ use `kadence search` did not: in natural runs on this repository 1 in 10
9
+ reached for it, and 0 in 10 after the instruction files said "before grep".
10
+ Every one opened with grep over the whole tree. So `kadence init` now installs
11
+ a UserPromptSubmit hook that searches the journal for each prompt and puts up
12
+ to three records next to it — by default, next to the `prime` hook.
13
+
14
+ ### ⚠️ `init` now writes `.claude/settings.json`
15
+
16
+ It used to only with `--hooks`. It now installs both hooks unless you pass
17
+ `--no-hooks`, creates the file when there is none, keeps every hook that was
18
+ already there, says what it added, and never rewrites a file it cannot parse.
19
+ `--hooks` is still accepted.
20
+
21
+ Measured on the same ten questions, same prompt, Sonnet agents:
22
+
23
+ | | without the hook | with it |
24
+ |---|---|---|
25
+ | Used the journal | 1 / 10 | 9 / 10 (6 as the first step) |
26
+ | Right answer | 9 / 10 | 10 / 10 |
27
+ | Context added, median | ~10.9k tokens | ~7.9k tokens |
28
+ | Time, median | 44 s | 25 s |
29
+ | Answered from files a clone does not have | 1 | 0 |
30
+
31
+ One repository, ten questions, one model. The hook's output was placed in the
32
+ prompt by hand, because subagents do not fire hooks, so this measures what the
33
+ records do once they arrive, not the hook firing in a live session. A signal,
34
+ not a benchmark.
35
+
36
+ ### Added
37
+
38
+ - `kadence hook prompt` — run by the hook, not by hand. Reads the
39
+ UserPromptSubmit payload on stdin and prints up to three records (1 KB at
40
+ most), or nothing. A passage is quoted only when its record holds the whole
41
+ question; a note is given whole, since there is no command to open one.
42
+ Always exits 0: exit 2 from this hook erases the prompt.
43
+ - A record is shown once per session: what a session has seen is kept in the
44
+ system temp directory, keyed by session and repository — never in
45
+ `.kadence/`. The lines are offered on a condition ("if this is about why or
46
+ how something was decided"), not as an order. On ten ordinary code tasks
47
+ the hook added ~180 tokens and sent no agent into the journal; same answers,
48
+ same time.
49
+ - `init` installs it next to the SessionStart hook. The command is
50
+ silent where kadence is missing and swallows an older kadence's exit 2, so a
51
+ teammate who has not upgraded does not lose every prompt they type.
52
+
53
+ ### Changed
54
+
55
+ - **`task list --search` runs on the search engine.** It was a substring over
56
+ title, description and comments — a second idea of what "matches" means.
57
+ Now it matches words the way `kadence search` does, reads acceptance
58
+ criteria too, returns every matching task rather than the top five, and
59
+ lists the most relevant first unless `--sort` is given. A fragment no longer
60
+ matches: `--search coo` does not find `cookie`. The flag and the `--json`
61
+ fields are unchanged. The TUI `/` filter stays a substring, since it filters
62
+ as a person types.
63
+ - The instruction section and `.kadence/README.md` list the ways to look
64
+ something up cheapest first, with what each costs in tokens — from the
65
+ prompt hook's ~90 to `board --json`'s ~51,000, with grep at ~11,000.
66
+ - `prime` names `kadence search` first under "Go deeper", with when to use it.
67
+ - The instruction section in `AGENTS.md` / `CLAUDE.md` and `.kadence/README.md`
68
+ say when to search — before grep or a list. On their own these changed
69
+ nothing measurable; they stay because they cost one line.
70
+
71
+ ### Fixed
72
+
73
+ - `search` missed the last word of every sentence. A full stop stayed inside
74
+ the token, so "release steps." was indexed as `steps.` and a search for
75
+ "steps" never found it. Golden-set recall@3 0.64 → 0.68.
76
+
77
+ ## [0.7.0] — 2026-09-25
78
+
79
+ **One question over everything written down — and three fixes that had to come
80
+ first.** `kadence search` answers "what do we know about X" across tasks,
81
+ decisions, notes and documents at once. Getting there meant admitting that the
82
+ commands an agent already calls were returning answers it could not use: one
83
+ that could be forged by a note, one that read the whole journal twice on every
84
+ call, and one that returned four thousand tasks into a window that truncates at
85
+ twenty-five thousand tokens.
86
+
87
+ ### ⚠️ Upgrading — three defaults changed
88
+
89
+ Nothing was renamed or removed from `kadence schema --json`, so `kadence/v1`
90
+ stands. What a caller gets **by default** changed in three places, and a script
91
+ that assumed otherwise needs one flag:
92
+
93
+ | Was | Is | To get the old answer |
94
+ |---|---|---|
95
+ | `task list --json` carried `history` | it does not | `--fields id,label,history` |
96
+ | list commands returned everything | one page of 100 | `--limit 0` |
97
+ | `prime --json` carried full note text | capped at 2000 characters | `kadence note list --json` |
98
+
99
+ `history` was never promised there — the schema has always placed it in
100
+ `task show` — but it was emitted, and Hyrum's Law says somebody depended on it.
101
+ It is 61% of that response at 4000 tasks, which put the command past the point
102
+ where an agent's tool output is silently cut in half.
103
+
104
+ ### Added — `kadence search`
105
+
106
+ - **One query, every kind of record.** Tasks with their descriptions,
107
+ acceptance criteria and comments; decisions with their reason and the
108
+ alternative they rejected; notes; documents cut at their headings. Most of
109
+ that was unreachable by any command before this: `task list --search` covered
110
+ 24% of the journal's prose and only tasks.
111
+ - **Lexical, not semantic, and measured rather than assumed.** BM25,
112
+ hand-rolled, no dependency, over the folded projection — so labels exist
113
+ (I7), a superseded decision does not answer as though it were current, and
114
+ search cannot disagree with `task show`. An embedding model is 200 MB and
115
+ seconds of cold start against a 200 ms budget and a promise to work offline;
116
+ on a vocabulary of `ULID`, `KAD-N` and `FlowEvent` it is also the weaker
117
+ method. 26 ms a query over 829 units; 158 ms end to end (DEC-26).
118
+ - **A hit is something you can cite.** The ULID, never the derived label; the
119
+ lines a document section came from; and a quoted span whose offsets land on
120
+ the quoted text, so an agent quotes the journal instead of paraphrasing it.
121
+ - **`coverage` — how much of the question a record actually holds**, 0 to 1,
122
+ weighted by how rare each word is. Where the first hit is right this is 1.00
123
+ at the median; where it is wrong, 0.62. Below 0.7 the human output says the
124
+ passage answers part of the question. The obvious signal — the gap to the
125
+ second hit — was measured and does not work: 0.10 against 0.08 (DEC-30).
126
+ - **An empty answer, said plainly.** Below the coverage floor the result is
127
+ nothing, and the message says the journal has no answer. A model handed
128
+ passages that merely look relevant fabricates more than one handed none, so
129
+ this is a feature and not a cop-out. Nine of ten questions about things this
130
+ journal has never discussed get silence.
131
+ - **Quality is held by a test, not by hope.** `test/search-relevance.test.ts`
132
+ runs 25 real questions against the repository's own journal and fails below
133
+ recall@3 of 0.64. Three ranking ideas were measured this release and two were
134
+ removed for making it worse (DEC-27, DEC-28).
135
+
136
+ ### Fixed — `prime` could be forged, and repainted your terminal
137
+
138
+ - **A note carrying newlines rendered as sections of its own**, and the
139
+ cheapest section to forge is the `Go deeper:` block `prime` ends with. The
140
+ length was capped; the shape was not. An escape sequence went further and
141
+ cleared the screen — `prime` runs from the `SessionStart` hook without being
142
+ asked.
143
+ - **`prime --json` was unbounded.** One 200 KB note made the session preamble
144
+ 200,728 bytes. Free text is now capped at 2000 characters with `bytes`
145
+ alongside, the signal `documentation` already gave (DEC-21).
146
+
147
+ ### Fixed — a warm command read the whole journal anyway
148
+
149
+ - **`loadState` called `readAll` on every command**, purely to count corrupted
150
+ and unknown events for a warning, after the snapshot had already answered.
151
+ A warm call read all 10,103 files; a cold one read every event twice.
152
+ 345 ms to 201 ms end to end at 10k events; 204 ms to 5 ms in process.
153
+ - **The fingerprint counts bytes as well as names**, so a file rewritten in
154
+ place invalidates the cache. That also means `git checkout .kadence/` — the
155
+ remedy the corruption warning itself recommends — finally invalidates the
156
+ cache it needed to, which it never did (DEC-22).
157
+ - Every performance guardrail measured `loadOrBuild`; the CLI calls
158
+ `loadState`. The bug lived in the gap between them. Both are measured now.
159
+
160
+ ### Fixed — list commands returned the whole board
161
+
162
+ - **One page of 100, with the real total and the offset beside it.**
163
+ `task list --json` was 1.3M tokens at 4000 tasks against the 25k at which an
164
+ agent's tool output is cut — silently, so the agent answers on a fraction
165
+ while believing it saw everything. Now 50 KB. `--limit 0` returns everything;
166
+ `--offset` walks (DEC-24).
167
+ - 100 rather than 200 because this repository's own tasks run 1100 bytes each,
168
+ where the ceiling is 93.
169
+
170
+ ### Changed
171
+
172
+ - Documentation moved into the journal: 65 documents, `DOC-2` through `DOC-66`,
173
+ as `doc.written` events. `docs/` stays on disk as the working draft and links
174
+ are rewritten to `DOC-N` on publication (DEC-25). The npm package is
175
+ unaffected — `.kadence/` is not in `files`.
176
+
5
177
  ## [0.6.0] — 2026-09-23
6
178
 
7
179
  **Documentation in the journal, and an honest answer when something goes
@@ -318,7 +490,7 @@ command was renamed, and `--json` responses gain keys rather than losing them.
318
490
  - **`kadence task claim` / `task release`** — take a task, or give it back.
319
491
  `claim` with no argument takes the top of `ready`, which is one step instead
320
492
  of two. There is **no lock**, and the message says so: two machines can each
321
- claim before either pushes. See [ADR-011](docs/decisions/011-claims-as-events.md).
493
+ claim before either pushes. See ADR-011.
322
494
  - **`kadence note "text" [--task KAD-1]`** and `note list` — something learned
323
495
  that was never a choice. Deliberately not a decision: no `--why`, no
324
496
  `supersedes`, no number. The help says when to reach for `decision add`
@@ -354,7 +526,7 @@ command was renamed, and `--json` responses gain keys rather than losing them.
354
526
  events fold differently depending on where they were written. A detached HEAD
355
527
  and an unknown base both fail by name rather than reporting no work.
356
528
  The measurement that justified the flag, including what would make it wrong,
357
- is in [branch-context-2026-09.md](docs/research/branch-context-2026-09.md).
529
+ is in branch-context-2026-09.md.
358
530
  - **Acceptance criteria** — `task ac add|check|uncheck|list`. The number is a
359
531
  position in the folded list, assigned like `KAD-N` and never stored, so two
360
532
  branches can each add a criterion and merge without renumbering. Moving a task
@@ -395,7 +567,7 @@ command was renamed, and `--json` responses gain keys rather than losing them.
395
567
 
396
568
  What the neighbours call reports is, here, a fold over timestamps the journal
397
569
  already carries. The reasoning, the sources and the verdict per report are in
398
- [reports-discovery-2026-09.md](docs/research/reports-discovery-2026-09.md).
570
+ reports-discovery-2026-09.md.
399
571
  Velocity and cycle time stay out of the headline; they are a consequence, served
400
572
  to the person who asks.
401
573
 
@@ -426,7 +598,7 @@ to the person who asks.
426
598
 
427
599
  Each of these was a standing "no". Each is now tried in the shape that survives
428
600
  the three constraints, and each has a kill condition written before the code, in
429
- [feature-adoption-2026-09.md](docs/product/feature-adoption-2026-09.md).
601
+ feature-adoption-2026-09.md.
430
602
 
431
603
  - **`kadence board export --html`** — the board, the sprint, the burndown,
432
604
  milestones and decisions in force, as **one self-contained file**. No script
@@ -444,7 +616,7 @@ the three constraints, and each has a kill condition written before the code, in
444
616
  trusts. A marker in the issue body makes a second publish an edit rather than
445
617
  a duplicate, and the issue itself says that edits made there are overwritten.
446
618
  Nothing is ever read back. See
447
- [ADR-012](docs/decisions/012-network-only-in-packages.md), written before the
619
+ ADR-012, written before the
448
620
  code. Every test runs against a recorded `gh`, never the real one.
449
621
  - **`kadence task doc add KAD-1 docs/design.md`** — creates the file from a
450
622
  four-line template and records the link in one call. It never overwrites: a
@@ -475,7 +647,7 @@ the three constraints, and each has a kill condition written before the code, in
475
647
  adding different labels merged without a conflict and one label vanished with
476
648
  no warning. Not a merge failure — a fold storing *state* in an event, the
477
649
  exact mistake the product exists to avoid. Reasoning in
478
- [ADR-013](docs/decisions/013-labels-as-deltas.md).
650
+ ADR-013.
479
651
  - **`labels` in `ready --json`**, the seventh field, and in the guaranteed set.
480
652
 
481
653
  Source for this slice: a tech lead's feedback of 2026-09-10 — drift comes not
@@ -662,7 +834,7 @@ is additive within `kadence/v1`, which the contract permits at any version.
662
834
  The journal held what happened. It now holds **why** — and the reasoning cannot
663
835
  quietly go stale, because superseding a decision is one event rather than two
664
836
  edits somebody has to remember to make. Reasoning in
665
- [ADR-010](docs/decisions/010-decisions-as-events.md).
837
+ ADR-010.
666
838
 
667
839
  ### Added
668
840
 
@@ -687,7 +859,7 @@ edits somebody has to remember to make. Reasoning in
687
859
  explains this task, and that is the only thing recorded. A missing file is a
688
860
  warning, not a refusal — it may arrive in a later commit.
689
861
 
690
- Measured before building ([Probe D](docs/research/probe-d-docs-linkage.md)):
862
+ Measured before building (Probe D):
691
863
  across five real questions, grep finds the answering document every time and
692
864
  buries it among 10–35 candidates. The link saves the sifting, not the search.
693
865
 
@@ -758,8 +930,8 @@ published package rather than the source.
758
930
  The agent contract, made real. `schema: "kadence/v1"` used to be a version
759
931
  string that nothing checked; now the contract is published, the failures are
760
932
  machine-readable, and the responses can be narrowed to what an agent actually
761
- reads. Reasoning in [ADR-009](docs/decisions/009-the-agent-contract.md),
762
- measurements in [Probe C](docs/research/probe-c-agent-cost.md).
933
+ reads. Reasoning in ADR-009,
934
+ measurements in Probe C.
763
935
 
764
936
  ### Added
765
937
 
@@ -830,7 +1002,7 @@ asked for.
830
1002
  - Developer tooling (`.claude/`, `.serena/`) is no longer committed: 381 files
831
1003
  and 3.8 MB of it, against 94 files of actual product. What belongs in git and
832
1004
  what does not is written down in
833
- [ADR-007](docs/decisions/007-what-goes-into-git.md), and `.gitignore` now
1005
+ ADR-007, and `.gitignore` now
834
1006
  also covers `.env`, coverage output and editor leftovers.
835
1007
 
836
1008
  ## [0.1.3] — 2026-09-03
package/README.md CHANGED
@@ -56,7 +56,7 @@ reads the same thing as JSON.
56
56
  **And it stays one call.** That answer stays under a kilobyte whether the project
57
57
  holds ten tasks or a thousand — while the journal behind it grows from 5 KB to
58
58
  528 KB. The cost of asking does not grow with the history that makes the answer
59
- worth having. [Measured](docs/research/probe-c-agent-cost.md) at 948 bytes in
59
+ worth having. Measured at 948 bytes in
60
60
  0.2; 982 bytes at 0.4, after claims and acceptance criteria joined every record.
61
61
 
62
62
  ## Why events and not files
@@ -102,7 +102,9 @@ merged in every order. Zero conflicts, every author preserved, identical final
102
102
  state. That is an [integration test](test/integration/merge.test.ts), not a
103
103
  claim.
104
104
 
105
- Full data: [probe-a-results.md](docs/research/probe-a-results.md).
105
+ The measurement itself is a working paper and is not published (see
106
+ `.gitignore`); the mechanism it measures is proved here by
107
+ `test/integration/merge.test.ts`.
106
108
 
107
109
  ---
108
110
 
@@ -111,8 +113,8 @@ Full data: [probe-a-results.md](docs/research/probe-a-results.md).
111
113
  **The first ten minutes, for the person who owns `CLAUDE.md`:**
112
114
 
113
115
  ```bash
114
- kadence init --hooks # .kadence/, a short section in AGENTS.md and CLAUDE.md,
115
- # and a Claude Code hook that runs `kadence prime` at session start
116
+ kadence init # .kadence/, a short section in AGENTS.md and CLAUDE.md, and two
117
+ # Claude Code hooks: prime at session start, a journal search per prompt
116
118
  kadence task add "Fix login" --type bug --priority high
117
119
  kadence decision add "Keep sessions in Redis" \
118
120
  --why "Revocation must be instant" --rejected "JWT: cannot revoke before expiry"
@@ -187,7 +189,7 @@ kadence task list --branch
187
189
 
188
190
  Nothing is stored for that: which tasks belong to a branch lives in git's
189
191
  history and is read when you ask. It narrows the answer between three and
190
- twenty times, [measured](docs/research/branch-context-2026-09.md) on real board
192
+ twenty times, measured on real board
191
193
  sizes.
192
194
 
193
195
  ### Also in the box
@@ -198,8 +200,8 @@ columns, reports folded from the same journal (`report flow`, `cfd`,
198
200
  `attention`; burndown, velocity and workload are in the repository and not yet
199
201
  on npm), a self-contained HTML or Markdown export, `compact` for long journals,
200
202
  and shell completion. None of it is required, and none of it is the point —
201
- it is what the journal happens to know. Commands and caveats:
202
- [docs/reports.md](docs/reports.md), and `--help` on each command.
203
+ it is what the journal happens to know. `--help` on each command is the
204
+ reference, and `kadence doc list` is what the journal knows about itself.
203
205
 
204
206
  ### Removing kadence
205
207
 
@@ -209,7 +211,7 @@ Everything `init` touched, so you can undo it by hand:
209
211
  |---|---|
210
212
  | The journal | `.kadence/` — yours to keep or delete; kadence never deletes it |
211
213
  | The agent section | between `<!-- kadence:begin -->` and `<!-- kadence:end -->` in `AGENTS.md` and `CLAUDE.md` |
212
- | The hook (only with `--hooks`) | the `SessionStart` entry that runs `kadence prime` in `.claude/settings.json` |
214
+ | The hooks (unless `--no-hooks`) | the `SessionStart` entry that runs `kadence prime` and the `UserPromptSubmit` entry that runs `kadence hook prompt`, in `.claude/settings.json` |
213
215
  | The cache entry | the `.kadence/state.json` line in `.gitignore` |
214
216
 
215
217
  Then `npm uninstall -g kadence`. Nothing lives outside the repository and your
@@ -230,9 +232,12 @@ kadence ready --json # seven fields per task, not the whole record
230
232
  ```
231
233
 
232
234
  `prime` is held to forty lines and three kilobytes by a test, because it is paid
233
- for on every turn that follows. `kadence init --hooks` will add it as a
234
- `SessionStart` hook — only with the flag, because `.claude/settings.json` is
235
- yours.
235
+ for on every turn that follows. `kadence init` adds it as a `SessionStart` hook,
236
+ and adds a `UserPromptSubmit` hook that searches the journal for each prompt
237
+ and puts up to three records next to it. Both are on by default because agents
238
+ do not reach for search on their own (1 in 10 measured); `--no-hooks` leaves
239
+ `.claude/settings.json` alone. The journal is searched in the words it is
240
+ written in: a prompt in another language finds nothing.
236
241
 
237
242
  ```bash
238
243
  kadence board --json
@@ -257,7 +262,7 @@ documentation can tell an agent what yours are.
257
262
 
258
263
  There is no MCP wrapper, and one gets built only as an **optional package**, when
259
264
  someone who cannot run a CLI asks for it: it costs about 700 tokens a session
260
- over the CLI path — [we measured it](docs/research/probe-c-agent-cost.md), and it
265
+ over the CLI path — we measured it, and it
261
266
  is not the saving the industry benchmarks suggest — it would be a second way to
262
267
  say the same thing, and it would not work for agents that have no MCP client at
263
268
  all.
@@ -319,8 +324,8 @@ either moves both or changes nothing. A typo does not leave half a board.
319
324
 
320
325
  | | |
321
326
  |---|---|
322
- | Install | 76 KB packed — 233 KB of kadence, plus 1.8 MB of blessed |
323
- | Startup | 65 ms |
327
+ | Install | 114 KB packed — 344 KB of kadence, plus 1.8 MB of blessed |
328
+ | Startup | 70 ms (`--version`, 0.8.0, one laptop) |
324
329
  | 10,000 events | 21 ms cold with a compacted archive, 12 ms warm — 199 ms cold if every event is still a separate file |
325
330
  | Journal on disk | under 5 MB |
326
331
  | One task, as an agent reads it | 982 bytes, or 304 with `--summary` — the same however long the task has been worked on |
@@ -334,24 +339,20 @@ true.
334
339
 
335
340
  **Verified.** The merge thesis, on real git branches. Performance and size, by
336
341
  tests that fail if they regress. That the conflict problem exists in the wild —
337
- measured, not assumed. 1060 tests in the repository today, including an
342
+ measured, not assumed. 1,188 tests in the repository today, including an
338
343
  end-to-end run through the installed binary.
339
344
 
340
345
  **Not verified.** That teams and their AI agents actually lose enough context to want
341
346
  this. The bet rests on reasoning and on the industry naming the problem out
342
347
  loud — not on our own users. That research, Probe B, is
343
- [designed](docs/research/interview-script.md) and not yet run: as of
344
- 2026-09-16, [zero conversations](docs/research/probe-b-results.md) and no
345
- external users. [The strategy](docs/product/strategy.md) says what happens next
346
- and on which dates.
348
+ designed and not yet run: as of
349
+ 2026-09-30, zero conversations and no external users. What happens next, and
350
+ on which dates, is recorded in this repository's own journal — `kadence
351
+ decision list` and `kadence note list`.
347
352
 
348
353
  **Not built, on purpose.** An MCP package — only if someone who cannot run a CLI
349
354
  asks for it, not as an inevitability.
350
355
 
351
- **In the repository, not yet released.** `report burndown`, `report velocity`,
352
- `report workload`, `report --list` and `report <name> --html`. `npm install`
353
- gives you 0.4.1 without them.
354
-
355
356
  `kadence context <task>` was dropped: we measured what `task show --json` already
356
357
  returns and it is the whole history of one piece of work, under a kilobyte,
357
358
  constant.
@@ -382,15 +383,18 @@ branches writing at once produce two different files, and git merges them
382
383
  without a conflict by construction.
383
384
 
384
385
  Design decisions, each recording what was measured and what would make us
385
- revisit it: [docs/decisions/](docs/decisions/).
386
+ revisit it, are in the journal that ships with this repository — `kadence
387
+ decision list`, or `kadence decision show DEC-3` for one in full. The longer
388
+ write-ups behind them are working papers and are kept out of git on purpose;
389
+ the decision, its reason and the alternatives that lost are in the events.
386
390
 
387
391
  ## Contributing
388
392
 
389
393
  ```bash
390
394
  npm install
391
- npm test # 1060 tests; builds dist/cli.js first
395
+ npm test # 1,188 tests; builds dist/cli.js first
392
396
  npm run typecheck
393
- npm run build # one 111 KB bundle, blessed kept external (82 KB at 0.4.1)
397
+ npm run build # dist/cli.js 135 KB, blessed kept external (82 KB at 0.4.1)
394
398
  ```
395
399
 
396
400
  `CLAUDE.md` documents the invariants, the boundaries, and the decisions that
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{q as G}from"./chunk-CR5YON2J.js";import S from"blessed";var c={border:"gray",borderFocus:"cyan",headerFg:"white",headerBg:"blue",selectedFg:"black",selectedBg:"cyan",dim:"gray",hint:"gray",warn:"yellow",danger:"red"},he={backlog:"gray",todo:"white",in_progress:"blue",doing:"blue",blocked:"red",in_review:"magenta",review:"magenta",done:"green",shipped:"green"};function ne(n){return he[n]??"white"}var pe={urgent:"\u203C",high:"\u2191",normal:" ",low:"\u2193"},me={urgent:"red",high:"yellow",normal:"white",low:"gray"},ye={bug:"\u2716",story:"\u25C6",epic:"\u2B22",task:"\xB7"};function k(n,s){return`{${s}-fg}${n}{/}`}function W(n,s){let d=k(pe[n.priority],me[n.priority]),p=k(ye[n.type]??"\xB7","gray"),h=k(n.label,"cyan"),g=[];n.blockedBy.length>0&&g.push(k("\u2298","red")),n.contestedBy.length>0?g.push(k("\u2691","magenta")):n.claimedBy!==null&&g.push(k("\u2713","green"));let E=n.criteria.filter(O=>!O.checked).length;if(E>0?g.push(k(`${n.criteria.length-E}/${n.criteria.length}`,"yellow")):n.criteria.length>0&&g.push(k("\u2611","green")),n.comments.length>0&&g.push(k("\u{1F4AC}","gray")),n.due!==null){let O=n.due<new Date().toISOString().slice(0,10);g.push(k(O?"\u23F0":"\u{1F4C5}",O?"red":"gray"))}let C=[n.assignee!==null?k(`@${n.assignee.split("@")[0]}`,"gray"):"",n.estimate!==null?k(String(n.estimate),"yellow"):"",g.join("")].filter(O=>O.length>0).join(" "),m=`${Y(d)}${Y(p)} ${Y(h)} `,b=C.length>0?` ${Y(C)}`:"",T=Math.max(4,s-m.length-b.length),F=[...n.title],q=F.length>T?`${F.slice(0,T-1).join("")}\u2026`:n.title;return`${d}${p} ${h} ${q}${C.length>0?` ${C}`:""}`}function z(n,s){return s?`{cyan-bg}{black-fg}${Y(n)}{/}`:` ${n}`}function J(n,s,d,p=12){let h=`${n.padEnd(p)} ${s}`;return d?`{cyan-bg}{black-fg}\u25B8 ${h}{/}`:` ${h}`}function Y(n){return n.replace(/\{[^}]*\}/g,"")}var re=["\u2190\u2192\u2191\u2193 move","enter details","[ ] shift","m status","a assign","c comment","e edit","n new","s sprint","/ filter","R ready","b branch","M milestone","C claim","? help","q quit (Ctrl-C forces)"].join(" ");function se(n){let s=[],d=!1;function p(){d=!0,setImmediate(()=>{d=!1})}return{dispatch(h){if(d)return;let g=s[s.length-1];g!==void 0?g(h):n(h)},push(h){s.push(h),p();let g=!1;return()=>{if(g)return;g=!0;let E=s.lastIndexOf(h);E!==-1&&s.splice(E,1),p()}},isDialogOpen:()=>s.length>0,depth:()=>s.length}}function oe(n){if(n.ch==="")return!1;let s=n.ch.charCodeAt(0);return s<32||s===127}var be=["up","down","pageup","pagedown","home","end"],ie=["escape","q"];function Q(n){return be.includes(n.name)}function le(n){return ie.includes(n.name)||ie.includes(n.ch)}function _(n,s,d){return d===0?0:(n+s+d)%d}var ae="cancelled",we="done";function ve(n){let s=[`${n.open} open`,`${n.ready} ready`,`${n.decisions} ${n.decisions===1?"decision":"decisions"} in force`,...n.points===null?[]:[`${n.points} points`]];return`kadence ${n.sprint===null?"":`${n.sprint} `}${s.join(" \xB7 ")}${n.filterNote}`}function Ie(n){let s=S.screen({smartCSR:!0,title:"kadence",fullUnicode:!0,mouse:!0}),{state:d}=n.reload(),p=n.branchEventIds(),h="",g=!1,E=!1,C="",m=[],b=0,T=se(t=>ge(t));function F(t=0){try{s.destroy()}catch{}process.exit(t)}process.on("SIGINT",()=>F(0)),process.on("SIGTERM",()=>F(0)),s.program.on("keypress",(t,r)=>{let i={ch:t??"",name:r?.name??""};(i.name==="C-c"||i.ch==="")&&F(0),!(oe(i)&&i.name!=="enter"&&i.name!=="escape")&&T.dispatch(i)});let q=S.box({parent:s,top:0,height:1,width:"100%",tags:!0,style:{fg:c.headerFg,bg:c.headerBg}}),O=S.box({parent:s,bottom:0,height:1,width:"100%",tags:!0,content:` ${re}`,style:{fg:c.hint}}),V=S.box({parent:s,bottom:1,height:1,width:"100%",tags:!0,style:{fg:c.warn}});function w(t,r=c.warn){V.setContent(` ${t}`),V.style.fg=r,s.render()}function A(){let t=d.statuses.filter(i=>i!==ae),r=d.orphanStatuses.filter(i=>i!==ae);return[...t,...r]}function de(t){let r=h.toLowerCase(),i=g?new Set(G(d.tasks,{viewer:n.actor,statuses:d.statuses,started:d.started}).map(a=>a.id)):null,e=E&&!("reason"in p)?p:null,o=e===null?null:a=>e.ids.has(a.id)||a.history.some(l=>e.ids.has(l.id)),u=C===""?null:d.milestones.find(a=>a.label===C)?.id??null;return d.tasks.filter(a=>a.status===t&&(i===null||i.has(a.id))&&(o===null||o(a))&&(u===null||a.milestone===u)&&(r===""||a.title.toLowerCase().includes(r)||(a.assignee??"").toLowerCase().includes(r)||a.labels.some(l=>l.toLowerCase().includes(r))))}function X(){for(let i of m)i.box.destroy();m=[];let t=A(),r=Math.max(Math.floor(100/Math.max(t.length,1)),12);t.forEach((i,e)=>{let o=S.box({parent:s,top:1,left:`${e*r}%`,width:`${r}%`,bottom:2,label:` ${i} `,border:{type:"line"},style:{border:{fg:c.border},label:{fg:ne(i)}}}),u=S.list({parent:o,top:0,left:0,right:0,bottom:0,keys:!1,mouse:!1,interactive:!1,tags:!0,scrollable:!0,style:{selected:{fg:c.selectedFg,bg:c.selectedBg},item:{fg:"white"}}});m.push({status:i,box:o,list:u,tasks:[],cursor:0})})}function y(t=!1){t&&(d=n.reload().state,p=n.branchEventIds()),m.length!==A().length&&X();let r=0,i=0,e=!1;m.forEach((l,N)=>{l.tasks=de(l.status),l.status!==we&&(r+=l.tasks.length,i+=l.tasks.reduce((R,M)=>R+(M.estimate??0),0)),l.tasks.some(R=>R.estimate!==null)&&(e=!0);let U=l.box.width-4;l.cursor=Math.min(l.cursor,Math.max(0,l.tasks.length-1)),l.list.setItems(l.tasks.map((R,M)=>z(W(R,U),N===b&&M===l.cursor)));let L=l.tasks.reduce((R,M)=>R+(M.estimate??0),0);l.box.setLabel(` ${l.status} (${l.tasks.length}${L>0?`, ${L}`:""}) `),l.box.style.border.fg=N===b?c.borderFocus:c.border});let o=d.sprints.find(l=>l.status==="active"),u=(h===""?"":` filter: "${h}"`)+(g?" ready only":"")+(E&&!("reason"in p)?` branch: ${p.name}`:"")+(C===""?"":` milestone: ${C}`),a=G(d.tasks,{viewer:n.actor,statuses:d.statuses,started:d.started}).length;q.setContent(` ${ve({sprint:o===void 0?null:o.name,open:r,ready:a,decisions:d.decisions.filter(l=>l.supersededBy===null).length,points:e?i:null,filterNote:u})}`),d.cycles.length>0&&w(`${d.cycles.length} dependency cycle(s) \u2014 see kadence task list`,c.danger),s.render()}function I(){let t=m[b];return t?.tasks[t.cursor]}function Z(){m.forEach((t,r)=>{let i=t.box.width-4;t.list.setItems(t.tasks.map((e,o)=>z(W(e,i),r===b&&o===t.cursor))),t.box.style.border.fg=r===b?c.borderFocus:c.border}),s.render()}function x(t){t!==null?w(t,c.warn):w(""),y(!0)}function K(t,r,i){let e=T.push(()=>{}),o=S.prompt({parent:s,top:"center",left:"center",width:"60%",height:7,border:{type:"line"},style:{border:{fg:c.borderFocus}},keys:!0,mouse:!0});o.input(t,r,(u,a)=>{o.destroy(),e(),s.render(),typeof a=="string"&&i(a.trim())})}function ue(t){let r=S.box({parent:s,top:"center",left:"center",width:"75%",height:"80%",border:{type:"line"},label:` ${t.label} `,style:{border:{fg:c.borderFocus}},tags:!0,keys:!0,mouse:!0}),i=[{key:"title",label:"title",value:()=>t.title,hint:"Title:"},{key:"description",label:"description",value:()=>(t.description??"\u2014").split(`
2
+ import{s as G}from"./chunk-IP426V3B.js";import S from"blessed";var c={border:"gray",borderFocus:"cyan",headerFg:"white",headerBg:"blue",selectedFg:"black",selectedBg:"cyan",dim:"gray",hint:"gray",warn:"yellow",danger:"red"},he={backlog:"gray",todo:"white",in_progress:"blue",doing:"blue",blocked:"red",in_review:"magenta",review:"magenta",done:"green",shipped:"green"};function ne(n){return he[n]??"white"}var pe={urgent:"\u203C",high:"\u2191",normal:" ",low:"\u2193"},me={urgent:"red",high:"yellow",normal:"white",low:"gray"},ye={bug:"\u2716",story:"\u25C6",epic:"\u2B22",task:"\xB7"};function k(n,s){return`{${s}-fg}${n}{/}`}function W(n,s){let d=k(pe[n.priority],me[n.priority]),p=k(ye[n.type]??"\xB7","gray"),h=k(n.label,"cyan"),g=[];n.blockedBy.length>0&&g.push(k("\u2298","red")),n.contestedBy.length>0?g.push(k("\u2691","magenta")):n.claimedBy!==null&&g.push(k("\u2713","green"));let E=n.criteria.filter(O=>!O.checked).length;if(E>0?g.push(k(`${n.criteria.length-E}/${n.criteria.length}`,"yellow")):n.criteria.length>0&&g.push(k("\u2611","green")),n.comments.length>0&&g.push(k("\u{1F4AC}","gray")),n.due!==null){let O=n.due<new Date().toISOString().slice(0,10);g.push(k(O?"\u23F0":"\u{1F4C5}",O?"red":"gray"))}let C=[n.assignee!==null?k(`@${n.assignee.split("@")[0]}`,"gray"):"",n.estimate!==null?k(String(n.estimate),"yellow"):"",g.join("")].filter(O=>O.length>0).join(" "),m=`${Y(d)}${Y(p)} ${Y(h)} `,b=C.length>0?` ${Y(C)}`:"",T=Math.max(4,s-m.length-b.length),F=[...n.title],q=F.length>T?`${F.slice(0,T-1).join("")}\u2026`:n.title;return`${d}${p} ${h} ${q}${C.length>0?` ${C}`:""}`}function z(n,s){return s?`{cyan-bg}{black-fg}${Y(n)}{/}`:` ${n}`}function J(n,s,d,p=12){let h=`${n.padEnd(p)} ${s}`;return d?`{cyan-bg}{black-fg}\u25B8 ${h}{/}`:` ${h}`}function Y(n){return n.replace(/\{[^}]*\}/g,"")}var re=["\u2190\u2192\u2191\u2193 move","enter details","[ ] shift","m status","a assign","c comment","e edit","n new","s sprint","/ filter","R ready","b branch","M milestone","C claim","? help","q quit (Ctrl-C forces)"].join(" ");function se(n){let s=[],d=!1;function p(){d=!0,setImmediate(()=>{d=!1})}return{dispatch(h){if(d)return;let g=s[s.length-1];g!==void 0?g(h):n(h)},push(h){s.push(h),p();let g=!1;return()=>{if(g)return;g=!0;let E=s.lastIndexOf(h);E!==-1&&s.splice(E,1),p()}},isDialogOpen:()=>s.length>0,depth:()=>s.length}}function oe(n){if(n.ch==="")return!1;let s=n.ch.charCodeAt(0);return s<32||s===127}var be=["up","down","pageup","pagedown","home","end"],ie=["escape","q"];function Q(n){return be.includes(n.name)}function le(n){return ie.includes(n.name)||ie.includes(n.ch)}function _(n,s,d){return d===0?0:(n+s+d)%d}var ae="cancelled",we="done";function ve(n){let s=[`${n.open} open`,`${n.ready} ready`,`${n.decisions} ${n.decisions===1?"decision":"decisions"} in force`,...n.points===null?[]:[`${n.points} points`]];return`kadence ${n.sprint===null?"":`${n.sprint} `}${s.join(" \xB7 ")}${n.filterNote}`}function Ie(n){let s=S.screen({smartCSR:!0,title:"kadence",fullUnicode:!0,mouse:!0}),{state:d}=n.reload(),p=n.branchEventIds(),h="",g=!1,E=!1,C="",m=[],b=0,T=se(t=>ge(t));function F(t=0){try{s.destroy()}catch{}process.exit(t)}process.on("SIGINT",()=>F(0)),process.on("SIGTERM",()=>F(0)),s.program.on("keypress",(t,r)=>{let i={ch:t??"",name:r?.name??""};(i.name==="C-c"||i.ch==="")&&F(0),!(oe(i)&&i.name!=="enter"&&i.name!=="escape")&&T.dispatch(i)});let q=S.box({parent:s,top:0,height:1,width:"100%",tags:!0,style:{fg:c.headerFg,bg:c.headerBg}}),O=S.box({parent:s,bottom:0,height:1,width:"100%",tags:!0,content:` ${re}`,style:{fg:c.hint}}),V=S.box({parent:s,bottom:1,height:1,width:"100%",tags:!0,style:{fg:c.warn}});function w(t,r=c.warn){V.setContent(` ${t}`),V.style.fg=r,s.render()}function A(){let t=d.statuses.filter(i=>i!==ae),r=d.orphanStatuses.filter(i=>i!==ae);return[...t,...r]}function de(t){let r=h.toLowerCase(),i=g?new Set(G(d.tasks,{viewer:n.actor,statuses:d.statuses,started:d.started}).map(a=>a.id)):null,e=E&&!("reason"in p)?p:null,o=e===null?null:a=>e.ids.has(a.id)||a.history.some(l=>e.ids.has(l.id)),u=C===""?null:d.milestones.find(a=>a.label===C)?.id??null;return d.tasks.filter(a=>a.status===t&&(i===null||i.has(a.id))&&(o===null||o(a))&&(u===null||a.milestone===u)&&(r===""||a.title.toLowerCase().includes(r)||(a.assignee??"").toLowerCase().includes(r)||a.labels.some(l=>l.toLowerCase().includes(r))))}function X(){for(let i of m)i.box.destroy();m=[];let t=A(),r=Math.max(Math.floor(100/Math.max(t.length,1)),12);t.forEach((i,e)=>{let o=S.box({parent:s,top:1,left:`${e*r}%`,width:`${r}%`,bottom:2,label:` ${i} `,border:{type:"line"},style:{border:{fg:c.border},label:{fg:ne(i)}}}),u=S.list({parent:o,top:0,left:0,right:0,bottom:0,keys:!1,mouse:!1,interactive:!1,tags:!0,scrollable:!0,style:{selected:{fg:c.selectedFg,bg:c.selectedBg},item:{fg:"white"}}});m.push({status:i,box:o,list:u,tasks:[],cursor:0})})}function y(t=!1){t&&(d=n.reload().state,p=n.branchEventIds()),m.length!==A().length&&X();let r=0,i=0,e=!1;m.forEach((l,N)=>{l.tasks=de(l.status),l.status!==we&&(r+=l.tasks.length,i+=l.tasks.reduce((R,M)=>R+(M.estimate??0),0)),l.tasks.some(R=>R.estimate!==null)&&(e=!0);let U=l.box.width-4;l.cursor=Math.min(l.cursor,Math.max(0,l.tasks.length-1)),l.list.setItems(l.tasks.map((R,M)=>z(W(R,U),N===b&&M===l.cursor)));let L=l.tasks.reduce((R,M)=>R+(M.estimate??0),0);l.box.setLabel(` ${l.status} (${l.tasks.length}${L>0?`, ${L}`:""}) `),l.box.style.border.fg=N===b?c.borderFocus:c.border});let o=d.sprints.find(l=>l.status==="active"),u=(h===""?"":` filter: "${h}"`)+(g?" ready only":"")+(E&&!("reason"in p)?` branch: ${p.name}`:"")+(C===""?"":` milestone: ${C}`),a=G(d.tasks,{viewer:n.actor,statuses:d.statuses,started:d.started}).length;q.setContent(` ${ve({sprint:o===void 0?null:o.name,open:r,ready:a,decisions:d.decisions.filter(l=>l.supersededBy===null).length,points:e?i:null,filterNote:u})}`),d.cycles.length>0&&w(`${d.cycles.length} dependency cycle(s) \u2014 see kadence task list`,c.danger),s.render()}function I(){let t=m[b];return t?.tasks[t.cursor]}function Z(){m.forEach((t,r)=>{let i=t.box.width-4;t.list.setItems(t.tasks.map((e,o)=>z(W(e,i),r===b&&o===t.cursor))),t.box.style.border.fg=r===b?c.borderFocus:c.border}),s.render()}function x(t){t!==null?w(t,c.warn):w(""),y(!0)}function K(t,r,i){let e=T.push(()=>{}),o=S.prompt({parent:s,top:"center",left:"center",width:"60%",height:7,border:{type:"line"},style:{border:{fg:c.borderFocus}},keys:!0,mouse:!0});o.input(t,r,(u,a)=>{o.destroy(),e(),s.render(),typeof a=="string"&&i(a.trim())})}function ue(t){let r=S.box({parent:s,top:"center",left:"center",width:"75%",height:"80%",border:{type:"line"},label:` ${t.label} `,style:{border:{fg:c.borderFocus}},tags:!0,keys:!0,mouse:!0}),i=[{key:"title",label:"title",value:()=>t.title,hint:"Title:"},{key:"description",label:"description",value:()=>(t.description??"\u2014").split(`
3
3
  `)[0]??"\u2014",hint:"Description (one line here, e for $EDITOR):"},{key:"status",label:"status",value:()=>t.status,hint:`Status (${A().join(", ")}):`},{key:"type",label:"type",value:()=>t.type,hint:"Type (task, bug, story, epic):"},{key:"priority",label:"priority",value:()=>t.priority,hint:"Priority (low, normal, high, urgent):"},{key:"assignee",label:"assignee",value:()=>t.assignee??"\u2014",hint:'Assignee (or "none"):'},{key:"estimate",label:"estimate",value:()=>t.estimate===null?"\u2014":String(t.estimate),hint:"Estimate in points:"},{key:"due",label:"due",value:()=>t.due??"\u2014",hint:"Due date YYYY-MM-DD (empty clears):"},{key:"labels",label:"labels",value:()=>t.labels.length>0?t.labels.join(", "):"\u2014",hint:"Labels, comma separated:"}],e=()=>[...i.map((v,f)=>({kind:"field",index:f})),...t.criteria.map(v=>({kind:"criterion",n:v.n}))],o=S.list({parent:r,top:0,left:1,right:1,height:i.length+t.criteria.length,keys:!1,mouse:!1,interactive:!1,tags:!0,style:{selected:{fg:c.selectedFg,bg:c.selectedBg}}}),u=0,a=S.box({parent:r,top:i.length+t.criteria.length+1,left:1,right:1,bottom:0,tags:!0,scrollable:!0});function l(){o.setItems(e().map((f,B)=>f.kind==="field"?J(i[f.index].label,i[f.index].value(),B===u):J(` ${f.n}.`,`[${t.criteria.find($=>$.n===f.n)?.checked===!0?"x":" "}] ${t.criteria.find($=>$.n===f.n)?.text??""}`,B===u)));let v=[t.blockedBy.length>0?`{red-fg}blocked by ${t.blockedBy.length} task(s){/}`:"",t.parent!==null?"{gray-fg}has a parent{/}":"",t.loggedHours>0?`{gray-fg}logged ${t.loggedHours.toFixed(1)}h{/}`:"","",t.description!==null&&t.description.includes(`
4
4
  `)?`{gray-fg}${t.description.split(`
5
5
  `).slice(1).join(`