kadence 0.1.5 → 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,60 @@
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
+
3
58
  ## [0.1.5] — 2026-09-03
4
59
 
5
60
  ### Changed
package/README.md CHANGED
@@ -1,48 +1,82 @@
1
1
  # kadence
2
2
 
3
- **Sprint tracking that lives in your git repo — and tells you what a story point actually costs.**
3
+ **Your team and your AI agents work from the same context — it lives in your repo and remembers what the code cannot.**
4
4
 
5
5
  ```bash
6
6
  npm install -g kadence
7
7
  kadence init
8
8
  ```
9
9
 
10
- No server. No account. No network. Your tasks are files next to your code, and
11
- they move with your branches.
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.
12
12
 
13
13
  ---
14
14
 
15
- ## The number nobody has
15
+ ## The context your code cannot hold
16
16
 
17
- Every team estimates in points. Almost none can say what a point costs them.
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.
18
20
 
19
- ```
20
- $ kadence sprint close
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.
21
24
 
22
- Sprint "Sprint 14" closed.
25
+ kadence keeps that missing layer as an append-only journal — one file per event,
26
+ committed with the code:
23
27
 
24
- Velocity: 23 of 28 points
25
- Actual: 37h — 1.6h per point
28
+ ```bash
29
+ $ kadence task show KAD-1 --json
30
+ ```
26
31
 
27
- Carried over (2):
28
- · KAD-12 Auth refactor
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
+ }
29
50
  ```
30
51
 
31
- `1.6h per point` is derived from the journal — every state change your team
32
- already made, timestamped. Nobody fills in a form. Nobody can forget to update
33
- it. Next sprint you plan against a measured number instead of a feeling.
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.
55
+
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).
34
60
 
35
- ## Three things a browser tab cannot do
61
+ ## Why events and not files
36
62
 
37
- **Your board is in the commit.** `git checkout` a release from three months ago
38
- and the tasks are exactly as they were that day. Not roughly — the same files.
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.
39
66
 
40
- **Merges do not fight you.** Two people editing one task on two branches is a
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.
70
+
71
+ **It conflicts.** Two people editing one task on two branches is a merge
41
72
  conflict in every file-based tracker. Here it is not, by construction: the
42
73
  journal is append-only, one file per event.
43
74
 
44
- **Agents read it without a bridge.** No MCP server, no token, no network. It is
45
- files, plus `--json` on every command.
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.
77
+
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.
46
80
 
47
81
  ---
48
82
 
@@ -70,7 +104,7 @@ kadence init
70
104
 
71
105
  kadence sprint create "Sprint 14"
72
106
  kadence task add "Fix login" -d "Broken since 2.3" --type bug --priority high --estimate 3
73
- kadence sprint add KAD-1
107
+ kadence task comment KAD-1 "Session cookie is fine — the redirect drops it."
74
108
  kadence task move KAD-1 done
75
109
  kadence sprint close
76
110
  ```
@@ -91,39 +125,66 @@ $ kadence ui
91
125
  Keyboard, mouse, drag between columns, every field editable in place. It calls
92
126
  the same commands the CLI does, so the two can never disagree.
93
127
 
94
- **For an agent:**
128
+ **And because the journal has the timestamps, the cost comes out of it for free:**
129
+
130
+ ```
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
140
+ ```
141
+
142
+ Nobody fills in a form. Nobody can forget to update it. The number is derived
143
+ from state changes the team already made.
144
+
145
+ ---
146
+
147
+ ## For agents
148
+
149
+ Files first. Every command speaks `--json`, every response carries
150
+ `schema: "kadence/v1"`, stdout is JSON and nothing else, warnings go to stderr.
95
151
 
96
152
  ```bash
97
153
  kadence board --json
154
+ kadence task show KAD-1 --json # full history and comments
98
155
  KADENCE_SOURCE=agent kadence task move KAD-1 in_progress
99
156
  ```
100
157
 
101
- Every response carries `schema: "kadence/v1"`. stdout is JSON and nothing else;
102
- warnings go to stderr. `init` writes a guide the agent finds on its own.
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.
103
162
 
104
- ---
105
-
106
- ## Commands
163
+ The contract is not a promise you have to take on trust:
107
164
 
165
+ ```bash
166
+ kadence schema --json # every command, every field, every error code
108
167
  ```
109
- kadence init set up in this repository
110
- kadence ui interactive board
111
-
112
- kadence task add "<title>" -d --type --priority -a --label --due
113
- --parent --template --estimate
114
- kadence task list --search --status --assignee --overdue
115
- --sort --tree
116
- kadence task show KAD-1 detail, comments and history
117
- kadence task edit KAD-1 opens $EDITOR, or pass field flags
118
- kadence task move KAD-1 done also: assign, comment, log, parent, block,
119
- cancel, delete
120
- kadence board plain columns; `board config` sets your own
121
- kadence sprint create|add|start|close|status|burndown|list
122
- kadence template save|list|delete
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
123
184
  ```
124
185
 
125
- Bulk works everywhere: `kadence task move KAD-1,KAD-2 done` — **all or
126
- nothing**, so a typo changes nothing rather than half your board.
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.
127
188
 
128
189
  ---
129
190
 
@@ -131,10 +192,11 @@ nothing**, so a typo changes nothing rather than half your board.
131
192
 
132
193
  | | |
133
194
  |---|---|
134
- | Install | 32 KB, one runtime dependency |
195
+ | Install | 29 KB, one runtime dependency |
135
196
  | Startup | 80 ms |
136
197
  | 10,000 events | 28 ms cold, 7 ms warm |
137
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 |
138
200
 
139
201
  These are tests. They fail the build on regression, which is why they are still
140
202
  true.
@@ -145,16 +207,25 @@ true.
145
207
 
146
208
  **Verified.** The merge thesis, on real git branches. Performance and size, by
147
209
  tests that fail if they regress. That the conflict problem exists in the wild —
148
- measured, not assumed. 390 tests, including an end-to-end run through the
210
+ measured, not assumed. 428 tests, including an end-to-end run through the
149
211
  installed binary.
150
212
 
151
- **Not verified.** Whether teams want this. The velocity bet rests on reasoning,
152
- not on user interviews — that research is
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
153
216
  [designed](docs/research/interview-script.md) and not yet run.
154
217
 
155
- **Known limits.** Conflicts are real but rare: roughly one merge in two
156
- hundred. That is why the headline is analytics, not conflict-freedom. Terminal
157
- interaction is covered by manual testing; only the key router is unit-tested.
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.
221
+
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.
225
+
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.
158
229
 
159
230
  ---
160
231
 
@@ -179,8 +250,8 @@ revisit it: [docs/decisions/](docs/decisions/).
179
250
 
180
251
  ```bash
181
252
  npm install
182
- npm test # 390 tests
183
- npm run build # 32 KB bundle
253
+ npm test # 428 tests
254
+ npm run build # 29 KB bundle
184
255
  ```
185
256
 
186
257
  `CLAUDE.md` documents the invariants, the boundaries, and the decisions that
@@ -0,0 +1,172 @@
1
+ #!/usr/bin/env node
2
+ var Wt=`# kadence \u2014 for AI agents
3
+
4
+ This project's tasks live here as plain files. Read them directly, or through
5
+ the CLI. No server required.
6
+
7
+ ## Commands
8
+
9
+ kadence board --json the whole board
10
+ kadence task list --json all tasks
11
+ kadence task show KAD-42 --json one task with its history
12
+ kadence task add "title" -d "..." --type bug --estimate 3
13
+ kadence task move KAD-42 in_progress
14
+ kadence task assign KAD-42 you@example.com
15
+ kadence sprint status --json current sprint progress
16
+
17
+ ## JSON contract
18
+
19
+ Every \`--json\` response carries \`schema: "kadence/v1"\`. stdout holds JSON and
20
+ nothing else; warnings go to stderr. Exit codes: 0 success, 1 runtime error,
21
+ 2 bad arguments.
22
+
23
+ The contract itself is machine-readable \u2014 read it instead of guessing:
24
+
25
+ kadence schema --json
26
+
27
+ It lists every command, the fields you can rely on, and every error code. It
28
+ works outside a repository, so you can read it before \`init\`.
29
+
30
+ ## When something fails
31
+
32
+ A failed \`--json\` call carries \`error.code\` \u2014 branch on that, not on the
33
+ sentence. Where the valid set is knowable it also carries \`allowed\`:
34
+
35
+ { "ok": false,
36
+ "error": { "code": "unknown_status", "received": "shipped",
37
+ "allowed": ["backlog", "in_progress", "done"],
38
+ "hint": "kadence board statuses --json" } }
39
+
40
+ Statuses are configured per project, so \`allowed\` is the only reliable source \u2014
41
+ never assume the defaults. Retrying an identical command never helps: there is no
42
+ network and no lock, so the same input always fails the same way.
43
+
44
+ ## Working as an agent
45
+
46
+ Set \`KADENCE_SOURCE=agent\` so events record your authorship. Without it an
47
+ event is marked as human \u2014 we do not guess.
48
+
49
+ ## Why to ask rather than read the files
50
+
51
+ You cannot find a task by its label in the journal. \`KAD-3\` is derived while
52
+ folding and is never stored in an event, so \`grep -r "KAD-3" .kadence/events/\`
53
+ returns nothing. Folding the journal yourself is the only alternative to asking.
54
+
55
+ Asking is also cheaper, and stays cheap: \`task show --json\` is about 950 bytes
56
+ whether the project holds ten tasks or a thousand, while the journal behind it
57
+ grows past 500 KB.
58
+
59
+ \`board --json\` is the exception: it returns every task in full, which on a large
60
+ project is a lot of description you did not ask for. Narrow it:
61
+
62
+ kadence board --json --fields label,status,assignee
63
+ kadence task list --json --fields id,label,status
64
+
65
+ \`kadence schema --json\` lists every selectable field.
66
+
67
+ ## What not to do
68
+
69
+ Do not hand-edit files under \`.kadence/events/\`: the journal is appended to,
70
+ never modified. To correct the state, add a new event through the CLI.
71
+ `,se="<!-- kadence:begin -->",Z="<!-- kadence:end -->",G=`${se}
72
+ ## Project tasks \u2014 kadence
73
+
74
+ Tasks live in \`.kadence/\` as plain files. Read them directly or via the CLI:
75
+
76
+ kadence board --json the whole board
77
+ kadence task list --json all tasks
78
+ kadence task move KAD-1 done change state
79
+
80
+ kadence schema --json the contract: commands, fields, error codes
81
+
82
+ \`--json\` responses carry \`schema: "kadence/v1"\`; stdout is JSON only. A failure
83
+ carries \`error.code\` and, where knowable, \`allowed\`.
84
+ When acting as an agent, set \`KADENCE_SOURCE=agent\`.
85
+
86
+ Details: \`.kadence/README.md\`
87
+ ${Z}`;function Yt(e){if(e===null||e.trim().length===0)return`${G}
88
+ `;let n=e.indexOf(se),r=e.indexOf(Z);if(n!==-1&&r!==-1&&r>n){let s=e.slice(0,n),o=e.slice(r+Z.length);return`${s}${G}${o}`}let t=e.endsWith(`
89
+ `)?`
90
+ `:`
91
+
92
+ `;return`${e}${t}${G}
93
+ `}var I=["id","label","title","description","type","priority","status","labels","assignee","reporter","sprint","loggedHours","parent","blockedBy","due","comments","estimate","history"],oe=["not_a_repository","not_initialised","no_git_identity","task_not_found","sprint_not_found","unknown_status","unknown_type","unknown_priority","unknown_field","invalid_argument"],Ue={not_a_repository:"There is no git repository here. kadence stores its journal inside one.",not_initialised:"The repository has no .kadence/ folder yet. Run `kadence init`.",no_git_identity:"Git has no user.email, so an event would have no author.",task_not_found:"No task carries that ULID or KAD-N label. Nothing was changed.",sprint_not_found:"No sprint carries that name or id.",unknown_status:"The status is not one of this project\u2019s columns. They are configurable, so read `allowed`.",unknown_type:"The task type is not one of the four kadence defines.",unknown_priority:"The priority is not one of the four kadence defines.",unknown_field:"A name given to --fields is not a task field. Read `allowed`.",invalid_argument:"An argument was missing or malformed; the command did nothing."};function Gt(e){return{version:"kadence/v1",tool:{name:"kadence",version:e},stability:"Additive only: fields and error codes may be added, never renamed or removed within kadence/v1.",exitCodes:{0:"success",1:"runtime error \u2014 the command understood you and could not comply",2:"bad arguments \u2014 nothing was attempted"},output:{stdout:"With --json, JSON and nothing else.",stderr:"Warnings and human messages, never part of the contract."},env:{KADENCE_SOURCE:'Set to "agent" so events record agent authorship. Without it an event counts as human \u2014 we do not guess.',NO_COLOR:"Any value disables colour."},errors:oe.map(n=>({code:n,meaning:Ue[n]})),shapes:{task:{required:["id","label","title","status","type","priority","estimate","assignee","blockedBy","loggedHours"],selectable:[...I],notes:{id:"ULID. The identity of the task; KAD-N is a label derived while folding and is never stored.",history:"Present in `task show` only \u2014 the events that produced this state.",required:"What a full response carries. With --fields you get exactly what you asked for and nothing else."}},board:{required:["schema","ok","columns"]},error:{required:["code","message"],optional:["received","allowed","hint"],notes:{allowed:"Present when the valid set is knowable \u2014 statuses are project-configurable.",retryable:"Deliberately absent: no network, no lock, so a retry always fails identically."}}},commands:[{name:"schema",summary:"This contract. Works outside a repository."},{name:"init",summary:"Create .kadence/ and the agent instruction files."},{name:"board",summary:"The whole board, grouped by column. Every task in full \u2014 pass --fields on a large project.",flags:["--json","--fields"],json:!0},{name:"task list",summary:"All tasks, filterable.",flags:["--json","--fields"],json:!0},{name:"task show",summary:"One task with its comments and full history.",args:["ref"],json:!0},{name:"task add",summary:"Create a task.",args:["title"],json:!0},{name:"task move",summary:"Change status. Accepts several refs, all or nothing.",args:["refs","status"],json:!0},{name:"task assign",summary:"Assign or unassign.",args:["refs","who"],json:!0},{name:"task comment",summary:"Append a comment.",args:["ref","text"],json:!0},{name:"task edit",summary:"Change fields.",args:["refs"],json:!0},{name:"task log",summary:"Log hours.",args:["refs","hours"],json:!0},{name:"task block",summary:"Record a blocker.",args:["ref","blocker"],json:!0},{name:"sprint status",summary:"Current sprint progress.",json:!0},{name:"sprint create",summary:"Start a sprint.",args:["name"],json:!0},{name:"sprint close",summary:"Close it and report velocity.",json:!0}]}}var Y=["backlog","todo","in_progress","blocked","in_review","done","cancelled"],Vt="done",He="cancelled",R=["task","bug","story","epic"],j=["low","normal","high","urgent"];function le(e){let n=[...e].sort((l,p)=>l.id<p.id?-1:l.id>p.id?1:0),r=new Map,t=new Map,s=new Map,o=null,i=[],a=[];for(let l of n){if(l.type==="template.saved"){let p=typeof l.data?.name=="string"?l.data.name:null;p!==null&&s.set(p,{name:p,fields:l.data?.fields??{},author:l.actor});continue}if(l.type==="board.configured"){let p=l.data?.statuses;if(Array.isArray(p)){let m=p.filter(g=>typeof g=="string"&&g.length>0);m.length>0&&(o=m)}continue}if(l.type==="template.deleted"){let p=typeof l.data?.name=="string"?l.data.name:null;p!==null&&s.delete(p);continue}ie(l,r,t,i,a)}let d=a.length>0,u=a;for(;u.length>0;){let l=[];for(let p of u)ie(p,r,t,i,l);if(l.length===u.length){u=l;break}u=l}if(d)for(let l of r.values())l.history.sort((p,m)=>p.id<m.id?-1:1);let c=[...r.values()].sort((l,p)=>l.id<p.id?-1:1);c.forEach((l,p)=>{l.label=`KAD-${p+1}`});let f=new Set(c.map(l=>l.id));for(let l of c)l.parent!==null&&!f.has(l.parent)&&(l.parent=null),l.blockedBy=l.blockedBy.filter(p=>f.has(p));return{tasks:c,sprints:[...t.values()].sort((l,p)=>l.id<p.id?-1:1),statuses:o??[...Y],orphanStatuses:[...new Set(c.map(l=>l.status).filter(l=>!(o??Y).includes(l)))].sort(),templates:[...s.values()].sort((l,p)=>l.name.localeCompare(p.name)),cycles:We(c),pending:u,rejected:i}}function ie(e,n,r,t,s){let o=e.data??{};if(e.type==="task.created")return n.has(e.entity)||n.set(e.entity,{id:e.entity,label:"",title:typeof o.title=="string"?o.title:"(untitled)",description:v(o.description),type:ae(o.type),priority:de(o.priority),status:"backlog",labels:ue(o.labels),assignee:v(o.assignee),reporter:e.actor,sprint:null,parent:v(o.parent),blockedBy:[],due:v(o.due),comments:[],estimate:typeof o.estimate=="number"?o.estimate:null,loggedHours:0,createdAt:e.ts,updatedAt:e.ts,history:[]}),V(n.get(e.entity),e),!0;if(e.type==="sprint.created")return r.has(e.entity)||r.set(e.entity,{id:e.entity,name:typeof o.name=="string"?o.name:"(untitled)",description:v(o.description),startDate:v(o.startDate),endDate:v(o.endDate),status:"planned",closedBy:null,taskIds:[]}),!0;if(e.type.startsWith("sprint.")){let a=r.get(e.entity);if(a===void 0)return s.push(e),!1;if(e.type==="sprint.started")return a.status==="planned"&&(a.status="active"),!0;if(e.type==="sprint.updated")return a.status==="closed"?(t.push(e),!0):(typeof o.name=="string"&&(a.name=o.name),o.description!==void 0&&(a.description=v(o.description)),o.startDate!==void 0&&(a.startDate=v(o.startDate)),o.endDate!==void 0&&(a.endDate=v(o.endDate)),!0);if(e.type==="sprint.closed")return a.closedBy===null?(a.status="closed",a.closedBy=e.id):t.push(e),!0;if(e.type==="sprint.cancelled")return a.status==="planned"?a.status="cancelled":t.push(e),!0;if(e.type==="sprint.task_added"){if(a.status==="closed")return t.push(e),!0;let d=typeof o.task=="string"?o.task:null;if(d===null)return!0;let u=n.get(d);return u===void 0?(s.push(e),!1):(u.sprint=a.id,a.taskIds.includes(d)||a.taskIds.push(d),V(u,e),!0)}return!0}let i=n.get(e.entity);if(i===void 0)return s.push(e),!1;if(e.type==="task.deleted")return n.delete(e.entity),!0;switch(e.type){case"task.moved":{let a=o.to;typeof a=="string"&&a.length>0&&(i.status=a);break}case"task.cancelled":i.status=He;break;case"task.reopened":i.status="in_progress";break;case"task.assigned":i.assignee=v(o.assignee);break;case"task.updated":typeof o.title=="string"&&(i.title=o.title),o.description!==void 0&&(i.description=v(o.description)),o.type!==void 0&&(i.type=ae(o.type)),o.priority!==void 0&&(i.priority=de(o.priority)),o.labels!==void 0&&(i.labels=ue(o.labels)),o.due!==void 0&&(i.due=v(o.due)),typeof o.estimate=="number"&&(i.estimate=o.estimate);break;case"task.parent_set":i.parent=v(o.parent);break;case"task.blocked_by_added":{let a=v(o.blocker);a!==null&&!i.blockedBy.includes(a)&&i.blockedBy.push(a);break}case"task.blocked_by_removed":{let a=v(o.blocker);a!==null&&(i.blockedBy=i.blockedBy.filter(d=>d!==a));break}case"task.time_logged":{let a=o.hours;typeof a=="number"&&Number.isFinite(a)&&(i.loggedHours=Math.max(0,i.loggedHours+a));break}case"task.commented":{let a=v(o.text);a!==null&&i.comments.push({id:e.id,author:e.actor,ts:e.ts,text:a});break}default:break}return V(i,e),!0}function V(e,n){e.history.push({id:n.id,type:n.type,actor:n.actor,ts:n.ts,data:n.data??{}}),n.ts>e.updatedAt&&(e.updatedAt=n.ts)}function v(e){return typeof e=="string"&&e.length>0?e:null}function ae(e){return R.includes(e)?e:"task"}function de(e){return j.includes(e)?e:"normal"}function ue(e){return Array.isArray(e)?e.filter(n=>typeof n=="string"&&n.length>0):[]}function We(e){let n=new Map(e.map(o=>[o.id,o])),r=[],t=new Set,s=(o,i)=>{let a=new Map,d=(u,c)=>{let f=a.get(u);if(f==="done")return;if(f==="visiting"){let p=c.indexOf(u),m=c.slice(p),g=`${o}:${[...m].sort().join(",")}`;t.has(g)||(t.add(g),r.push({kind:o,path:[...m,u]}));return}a.set(u,"visiting");let l=n.get(u);if(l!==void 0)for(let p of i(l))d(p,[...c,u]);a.set(u,"done")};for(let u of e)d(u.id,[])};return s("parent",o=>o.parent===null?[]:[o.parent]),s("blocking",o=>o.blockedBy),r}var ce={urgent:0,high:1,normal:2,low:3};function pe(e,n){return e!==null&&e.toLowerCase().includes(n)}function ge(e,n,r=new Date){let t=r.toISOString().slice(0,10),s=n.search?.toLowerCase();return e.filter(o=>{if(s!==void 0&&s.length>0){let i=o.comments.some(a=>a.text.toLowerCase().includes(s));if(!pe(o.title,s)&&!pe(o.description,s)&&!i)return!1}if(n.status!==void 0&&o.status!==n.status||n.type!==void 0&&o.type!==n.type||n.priority!==void 0&&o.priority!==n.priority)return!1;if(n.assignee!==void 0){let i=n.assignee.toLowerCase(),a=(o.assignee??"").toLowerCase();if(i==="none"?a!=="":a!==i)return!1}if(n.label!==void 0){let i=n.label.toLowerCase();if(!o.labels.some(a=>a.toLowerCase()===i))return!1}return!(n.sprint!==void 0&&o.sprint!==n.sprint||n.overdue===!0&&(o.due===null||o.due>=t)||n.dueBefore!==void 0&&(o.due===null||o.due>=n.dueBefore))})}function me(e,n){let r=[...e];switch(n){case"priority":return r.sort((t,s)=>ce[t.priority]-ce[s.priority]);case"due":return r.sort((t,s)=>fe(t.due,s.due,(o,i)=>o<i?-1:o>i?1:0));case"estimate":return r.sort((t,s)=>fe(t.estimate,s.estimate,(o,i)=>i-o));default:return r.sort((t,s)=>t.id<s.id?-1:t.id>s.id?1:0)}}function fe(e,n,r){return e===null&&n===null?0:e===null?1:n===null?-1:r(e,n)}function ke(e){let n=[];return e.search!==void 0&&n.push(`search="${e.search}"`),e.status!==void 0&&n.push(`status=${e.status}`),e.type!==void 0&&n.push(`type=${e.type}`),e.priority!==void 0&&n.push(`priority=${e.priority}`),e.assignee!==void 0&&n.push(`assignee=${e.assignee}`),e.label!==void 0&&n.push(`label=${e.label}`),e.overdue===!0&&n.push("overdue"),e.dueBefore!==void 0&&n.push(`due before ${e.dueBefore}`),n.length===0?`No tasks yet.
94
+ Create the first one:
95
+ kadence task add "title"`:`No tasks match ${n.join(" and ")}.
96
+ Try fewer filters:
97
+ kadence task list`}var q=["created","priority","due","estimate"];function ye(e){return q.includes(e)}import{execFileSync as Ye}from"node:child_process";function he(e,n){try{return Ye("git",n,{cwd:e,encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim()}catch{return null}}function be(e){let n=he(e,["rev-parse","--show-toplevel"]);return n===null||n.length===0?null:n}function ve(e){let n=he(e,["config","user.email"]);return n===null||n.length===0?null:n}import{mkdirSync as Qe,readdirSync as et,readFileSync as tt,renameSync as nt,rmSync as nn,writeFileSync as rt}from"node:fs";import{join as _}from"node:path";var Ge=["task.created","task.moved","task.assigned","task.commented","task.updated","task.cancelled","task.reopened","task.deleted","task.parent_set","task.blocked_by_added","task.blocked_by_removed","task.time_logged","template.saved","template.deleted","board.configured","sprint.created","sprint.started","sprint.updated","sprint.closed","sprint.cancelled","sprint.task_added"],Ze=new Set(Ge),we=/^[0-9ABCDEFGHJKMNPQRSTVWXYZ]{26}$/,Ve=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{1,3})?(Z|[+-]\d{2}:\d{2})$/;function qe(e){return typeof e=="string"&&Ze.has(e)}function ze(e){if(typeof e!="object"||e===null)return["event"];let n=e,r=[];return(typeof n.id!="string"||!we.test(n.id))&&r.push("id"),qe(n.type)||r.push("type"),(typeof n.entity!="string"||!we.test(n.entity))&&r.push("entity"),(typeof n.actor!="string"||n.actor.length===0)&&r.push("actor"),(typeof n.ts!="string"||!Ve.test(n.ts)||Number.isNaN(Date.parse(n.ts)))&&r.push("ts"),n.source!=="human"&&n.source!=="agent"&&r.push("source"),n.data!==void 0&&(typeof n.data!="object"||n.data===null)&&r.push("data"),r}function Se(e){let n=e.data?.description;if(typeof n!="string"||!n.includes(`
98
+ `))return JSON.stringify(e);let r={...e,data:{...e.data,description:n.split(`
99
+ `)}};return JSON.stringify(r,null,2)}function z(e){let n;try{n=JSON.parse(e)}catch(t){return{event:null,error:`unreadable JSON: ${t.message}`,unknownType:!1}}n=Xe(n);let r=ze(n);return r.length===1&&r[0]==="type"?{event:null,error:null,unknownType:!0}:r.length>0?{event:null,error:`invalid fields: ${r.join(", ")}`,unknownType:!1}:{event:n,error:null,unknownType:!1}}function Xe(e){if(typeof e!="object"||e===null)return e;let n=e,r=n.data;if(typeof r!="object"||r===null)return e;let t=r.description;return Array.isArray(t)?{...n,data:{...r,description:t.filter(s=>typeof s=="string").join(`
100
+ `)}}:e}var st=.2;function F(e){return _(e,".kadence")}function J(e){return _(F(e),"events")}function ot(e){return _(J(e),"archive")}function it(e){return e.slice(0,7)}function T(e,n){let r=_(J(e),it(n.ts));Qe(r,{recursive:!0});let t=_(r,`${n.id}.json`),s=_(r,`.${n.id}.tmp`);rt(s,`${Se(n)}
101
+ `,"utf8"),nt(s,t)}function M(e){let n=J(e),r=[],t=[],s=new Set,o=0,i=X(ot(e)),a=new Set(i);for(let u of X(n)){let c;try{c=tt(u,"utf8")}catch{t.push(u);continue}if(a.has(u)){let l;try{l=JSON.parse(c)}catch{t.push(u);continue}if(!Array.isArray(l)){t.push(u);continue}for(let p of l){let m=z(JSON.stringify(p));m.unknownType?o++:m.error!==null||m.event===null?t.push(u):s.has(m.event.id)||(s.add(m.event.id),r.push(m.event))}continue}let f=z(c);if(f.unknownType){o++;continue}if(f.error!==null||f.event===null){t.push(u);continue}s.has(f.event.id)||(s.add(f.event.id),r.push(f.event))}r.sort((u,c)=>u.id<c.id?-1:u.id>c.id?1:0);let d=r.length+t.length;return{events:r,corrupted:t,unknownTypes:o,systemicCorruption:d>0&&t.length/d>st}}function X(e){let n;try{n=et(e,{withFileTypes:!0})}catch{return[]}let r=[];for(let t of n){let s=_(e,t.name);t.isDirectory()?r.push(...X(s)):t.name.endsWith(".json")&&r.push(s)}return r}import{randomFillSync as at}from"node:crypto";var Te="0123456789ABCDEFGHJKMNPQRSTVWXYZ",dt=10,ut=16,xe=2**48-1;function lt(e){let n="",r=e;for(let t=dt-1;t>=0;t--)n=Te[r%32]+n,r=Math.floor(r/32);return n}function ct(e){let n="",r=0,t=0;for(let s of e){for(r=r<<8|s,t+=8;t>=5;)t-=5,n+=Te[r>>>t&31];r&=(1<<t)-1}return n.slice(0,ut)}function pt(e){for(let n=e.length-1;n>=0;n--){let r=e[n];if(r<255){e[n]=r+1;return}e[n]=0}throw new Error("ULID: random space exhausted within a single millisecond")}function ft(){let e=-1,n=new Uint8Array(10);return function(t=Date.now()){if(!Number.isInteger(t)||t<0||t>xe)throw new RangeError(`ULID: time out of range 0..${xe}: ${t}`);return t>e?(e=t,at(n)):pt(n),lt(e)+ct(n)}}var x=ft();import{readFileSync as gt,writeFileSync as mt,renameSync as kt,readdirSync as yt,mkdirSync as ht}from"node:fs";import{join as Ce}from"node:path";var $e="kadence-snapshot/1";function Ee(e){return Ce(F(e),"state.json")}function De(e,n){let r=bt(J(e)),t=vt(e);if(t!==null&&t.version===$e&&t.lastEventId===r.lastEventId&&t.eventCount===r.count)return{state:t.state,fromCache:!0,incomingEvents:0};let s=M(e),o=le(s.events),i=t===null||n===void 0?0:St(s.events,t,n);return wt(e,{version:$e,lastEventId:r.lastEventId,eventCount:r.count,state:o}),{state:o,fromCache:!1,incomingEvents:i}}function bt(e){let n="",r=0,t=s=>{let o;try{o=yt(s,{withFileTypes:!0})}catch{return}for(let i of o)if(i.isDirectory())t(Ce(s,i.name));else if(i.name.endsWith(".json")){r++;let a=i.name.slice(0,-5);a>n&&(n=a)}};return t(e),{lastEventId:n,count:r}}function vt(e){try{let n=JSON.parse(gt(Ee(e),"utf8"));if(typeof n!="object"||n===null)return null;let r=n;return typeof r.version!="string"||typeof r.lastEventId!="string"||typeof r.eventCount!="number"||typeof r.state!="object"?null:r}catch{return null}}function wt(e,n){try{ht(F(e),{recursive:!0});let r=Ee(e),t=`${r}.tmp`;mt(t,JSON.stringify(n),"utf8"),kt(t,r)}catch{}}function St(e,n,r){let t=0,s=0;for(let i of e)i.id<=n.lastEventId?t++:i.actor!==r&&s++;let o=Math.max(0,t-n.eventCount);return s+o}var S={dim:"\x1B[2m",bold:"\x1B[1m",green:"\x1B[32m",yellow:"\x1B[33m",blue:"\x1B[34m",reset:"\x1B[0m"};function ee(e,n){return e.NO_COLOR!==void 0?!1:n}function D(e,n,r){return r?`${n}${e}${S.reset}`:e}var xt={done:S.green,in_progress:S.blue,blocked:S.yellow,cancelled:S.dim},Tt=72;function je(e,n=Tt){let r=[...e];return r.length<=n?e:`${r.slice(0,n-1).join("")}\u2026`}function Q(e){return[...e].length}function Re(e,n){let r=n-Q(e);return r>0?e+" ".repeat(r):e}function _e(e,n){if(e.length===0)return`No tasks yet.
102
+ Create the first one:
103
+ kadence task add "title"`;let r=Math.max(...e.map(s=>Q(s.label)),2),t=Math.max(...e.map(s=>Q(s.status)),6);return e.map(s=>{let o=D(Re(s.label,r),S.bold,n),i=D(Re(s.status,t),xt[s.status]??S.dim,n),a=s.estimate===null?"":D(` (${s.estimate})`,S.dim,n);return`${o} ${i} ${je(s.title)}${a}`}).join(`
104
+ `)}function Ne(e){return e<=0?null:`Merged ${e} ${e===1?"change":"changes"} from another branch, no conflicts.`}var $t={urgent:"!!",high:"!",normal:"",low:"v"},Ct={bug:"BUG",story:"STORY",task:""};function Ae(e,n){let r=[D(e.label,S.bold,n)],t=$t[e.priority];t!==""&&r.push(D(t,e.priority==="low"?S.dim:S.yellow,n));let s=Ct[e.type]??"";s!==""&&r.push(D(s,S.dim,n)),r.push(je(e.title));let o=[];return e.assignee!==null&&o.push(`@${e.assignee.split("@")[0]}`),e.estimate!==null&&o.push(`${e.estimate}`),o.length>0&&r.push(D(`(${o.join(", ")})`,S.dim,n)),` ${r.join(" ")}`}function gn(e,n){if(Object.values(e).reduce((s,o)=>s+o.length,0)===0)return`No tasks yet.
105
+ Create the first one:
106
+ kadence task add "title"`;let t=[];for(let[s,o]of Object.entries(e)){if(o.length===0)continue;let i=o.reduce((d,u)=>d+(u.estimate??0),0),a=i>0?` \u2014 ${i}`:"";t.push(D(`${s} (${o.length}${a})`,S.bold,n),...o.map(d=>Ae(d,n)),"")}return t.join(`
107
+ `).trimEnd()}function Et(e,n=new Date){let r=Date.parse(`${e}T00:00:00.000Z`),t=Date.parse(`${n.toISOString().slice(0,10)}T00:00:00.000Z`);if(Number.isNaN(r))return"";let s=Math.round((r-t)/864e5);return s<0?` (overdue by ${-s} day${s===-1?"":"s"})`:s===0?" (today)":s===1?" (tomorrow)":s<=7?` (in ${s} days)`:""}function Oe(e,n){if(e.length===0)return`No tasks yet.
108
+ Create the first one:
109
+ kadence task add "title"`;let r=new Set(e.map(a=>a.id)),t=new Map;for(let a of e){let d=a.parent!==null&&r.has(a.parent)?a.parent:null,u=t.get(d)??[];u.push(a),t.set(d,u)}let s=[],o=new Set,i=(a,d)=>{if(!(d>10))for(let u of t.get(a)??[]){if(o.has(u.id))continue;o.add(u.id);let c=" ".repeat(d),f=u.blockedBy.length>0?D(" [blocked]",S.yellow,n):"";s.push(`${c}${Ae(u,n).trimStart()}${f}`),i(u.id,d+1)}};return i(null,0),s.join(`
110
+ `)}function Pe(e){let n=[`${e.label} ${e.title}`,""];if(e.description!==null&&n.push(e.description,""),n.push(` Status: ${e.status}`),n.push(` Type: ${e.type}`),n.push(` Priority: ${e.priority}`),e.labels.length>0&&n.push(` Labels: ${e.labels.join(", ")}`),e.parent!==null&&n.push(` Parent: ${e.parent}`),e.blockedBy.length>0&&n.push(` Blocked by: ${e.blockedBy.length} task(s)`),n.push(` Assignee: ${e.assignee??"\u2014"}`),n.push(` Reporter: ${e.reporter}`),e.due!==null&&n.push(` Due: ${e.due}${Et(e.due)}`),n.push(` Estimate: ${e.estimate??"\u2014"}`),e.comments.length>0){n.push("",` Comments (${e.comments.length}):`);for(let r of e.comments){n.push(` ${r.author} \xB7 ${r.ts.slice(0,10)}`);for(let t of r.text.split(`
111
+ `))n.push(` ${t}`)}}if(e.history.length>0){n.push("",` History (${e.history.length}):`);for(let r of e.history){let t=r.type==="task.moved"?` \u2192 ${String(r.data.to)}`:"";n.push(` ${r.ts.slice(0,16).replace("T"," ")} ${r.actor} ${r.type}${t}`)}}return n.join(`
112
+ `)}import{existsSync as Dt}from"node:fs";var $n=Y;function $(e,n,r,t={}){return{ok:!1,exitCode:e,message:r,error:{code:n,message:r,...t}}}function N(e){return $(1,"task_not_found",`No task ${e}.
113
+ kadence task list`,{received:e,hint:"kadence task list --json"})}function L(e,n,r,t){return $(2,e,`Unknown ${n} "${r}".
114
+ Available: ${t.join(", ")}`,{received:r,allowed:t})}function h(e,n){let r=be(e);if(r===null)return $(1,"not_a_repository",`kadence lives inside a git repository, and there is none here.
115
+ Create one and try again:
116
+ git init`,{hint:"git init"});if(!Dt(F(r)))return $(1,"not_initialised",`No .kadence/ found here.
117
+ Run:
118
+ npx kadence init`,{hint:"kadence init"});let t=ve(r);if(t===null)return $(1,"no_git_identity",`Git does not know who you are, so there is no author for the event.
119
+ Run:
120
+ git config user.email you@example.com`,{hint:"git config user.email you@example.com"});let s=n.KADENCE_SOURCE==="agent"?"agent":"human";return{root:r,actor:t,source:s}}function b(e){return"root"in e}function Cn(e,n,r,t={}){let s=h(e,n);if(!b(s))return s;let o=r.trim();if(o.length===0)return{ok:!1,exitCode:2,message:"A task needs a title."};if(t.type!==void 0&&!R.includes(t.type))return L("unknown_type","type",t.type,R);if(t.priority!==void 0&&!j.includes(t.priority))return L("unknown_priority","priority",t.priority,j);let i;if(t.parent!==void 0){let{state:c}=k(s.root,s.actor),f=C(c,t.parent);if(f===void 0)return{ok:!1,exitCode:1,message:`No parent task ${t.parent}.
121
+ kadence task list`};i=f.id}let a=x(),d={id:a,type:"task.created",entity:a,actor:s.actor,ts:new Date().toISOString(),source:s.source,data:{title:o,...t.description!==void 0?{description:t.description}:{},...t.type!==void 0?{type:t.type}:{},...t.priority!==void 0?{priority:t.priority}:{},...t.assignee!==void 0?{assignee:t.assignee}:{},...t.labels!==void 0&&t.labels.length>0?{labels:t.labels}:{},...t.due!==void 0?{due:t.due}:{},...i!==void 0?{parent:i}:{},...t.estimate!==void 0?{estimate:t.estimate}:{}}};T(s.root,d);let u=t.estimate===void 0?`
122
+ Without an estimate this task will not count towards velocity. Add --estimate.`:"";return{ok:!0,exitCode:0,message:`Created: ${o}${u}`,data:{schema:"kadence/v1",ok:!0,task:{id:a,title:o}}}}function k(e,n){let r=De(e,n),t=M(e),s=[],o=Ne(r.incomingEvents);return o!==null&&s.push(o),t.systemicCorruption?s.push(`The journal is badly damaged: ${t.corrupted.length} of ${t.corrupted.length+t.events.length} events are unreadable. Try: git checkout .kadence/`):t.corrupted.length>0&&s.push(`Skipped ${t.corrupted.length} corrupted event(s).`),t.unknownTypes>0&&s.push(`Skipped ${t.unknownTypes} event(s) from a newer format. Update kadence.`),{state:r.state,warnings:s}}function C(e,n){let r=n.toUpperCase();return e.tasks.find(t=>t.id===r||t.label===r)}function Ie(e,n){return $(2,"unknown_status",`Unknown status "${e}".
123
+ Available: ${n.join(", ")}
124
+ kadence board config --statuses "todo,doing,done"`,{received:e,allowed:n,hint:"kadence board statuses --json"})}function En(e,n,r){let t=h(e,n);if(!b(t))return t;if(r.type!==void 0&&!R.includes(r.type))return L("unknown_type","type",r.type,R);if(r.priority!==void 0&&!j.includes(r.priority))return L("unknown_priority","priority",r.priority,j);let{fields:s,error:o}=Rt(r.fields);if(o!==null)return o;if(r.sort!==void 0&&!ye(r.sort))return{ok:!1,exitCode:2,message:`Unknown sort key "${r.sort}".
125
+ Available: ${q.join(", ")}`};let{state:i,warnings:a}=k(t.root,t.actor);if(r.status!==void 0&&!i.statuses.includes(r.status))return Ie(r.status,i.statuses);let{sort:d,tree:u,...c}=r,f=ge(i.tasks,c),l=d===void 0?f:me(f,d);return l.length===0?{ok:!0,exitCode:0,warnings:a,message:ke(c),data:{schema:"kadence/v1",ok:!0,tasks:[]}}:{ok:!0,exitCode:0,warnings:a,message:u===!0?Oe(l,ee(n,process.stdout.isTTY===!0)):_e(l,ee(n,process.stdout.isTTY===!0)),data:{schema:"kadence/v1",ok:!0,tasks:l.map(p=>Fe(p,s)),cycles:i.cycles}}}function Dn(e,n,r,t){let s=h(e,n);if(!b(s))return s;let{state:o,warnings:i}=k(s.root,s.actor);if(!o.statuses.includes(t))return Ie(t,o.statuses);let{tasks:a,error:d}=A(o,r);if(d!==null)return d;let u=[],c=[],f="";for(let p of a){if(p.status===t){c.push(p);continue}let m=p.status;T(s.root,{id:x(),type:"task.moved",entity:p.id,actor:s.actor,ts:new Date().toISOString(),source:s.source,data:{from:m,to:t}}),u.push(p),a.length===1&&o.statuses.indexOf(t)-o.statuses.indexOf(m)>1&&(f=`
126
+ Moved straight from ${m} to ${t}, skipping the stages between.`)}if(u.length===0)return{ok:!0,exitCode:0,warnings:i,message:w("already there",c,`is already ${t}.`)};let l=c.length>0?`
127
+ ${c.length} already ${t}.`:"";return{ok:!0,exitCode:0,warnings:i,message:`${w("moved",u,`${u[0].status} \u2192 ${t}`)}${f}${l}`,data:{schema:"kadence/v1",ok:!0,moved:u.map(p=>({id:p.id,label:p.label,to:t}))}}}function Rt(e){if(e===void 0)return{fields:null,error:null};let n=e.split(",").map(t=>t.trim()).filter(t=>t.length>0);if(n.length===0)return{fields:null,error:$(2,"invalid_argument","--fields needs at least one field name.",{allowed:I})};let r=n.find(t=>!I.includes(t));return r!==void 0?{fields:null,error:$(2,"unknown_field",`Unknown field "${r}".
128
+ Available: ${I.join(", ")}`,{received:r,allowed:I})}:{fields:n,error:null}}function Fe(e,n=null){let r=jt(e);return n===null?r:Object.fromEntries(n.map(t=>[t,r[t]]))}function jt(e){return{id:e.id,label:e.label,title:e.title,description:e.description,type:e.type,priority:e.priority,status:e.status,labels:e.labels,assignee:e.assignee,reporter:e.reporter,sprint:e.sprint,loggedHours:e.loggedHours,parent:e.parent,blockedBy:e.blockedBy,due:e.due,comments:e.comments,estimate:e.estimate,history:e.history}}function Rn(e,n,r,t){let s=h(e,n);if(!b(s))return s;let{state:o,warnings:i}=k(s.root,s.actor),{tasks:a,error:d}=A(o,r);if(d!==null)return d;let u=t.trim().toLowerCase()==="none"?null:t.trim(),c=a.filter(f=>f.assignee!==u);if(c.length===0)return{ok:!0,exitCode:0,warnings:i,message:u===null?w("already unassigned",a,"is already unassigned."):w("already assigned",a,`is already assigned to ${u}.`)};for(let f of c)T(s.root,{id:x(),type:"task.assigned",entity:f.id,actor:s.actor,ts:new Date().toISOString(),source:s.source,data:{assignee:u}});return{ok:!0,exitCode:0,warnings:i,message:u===null?w("unassigned",c,"unassigned."):w("assigned",c,`\u2192 ${u}`),data:{schema:"kadence/v1",ok:!0,assigned:c.map(f=>({id:f.id,label:f.label,assignee:u}))}}}function jn(e,n,r){let t=h(e,n);if(!b(t))return t;let{state:s,warnings:o}=k(t.root,t.actor),i=C(s,r);return i===void 0?N(r):{ok:!0,exitCode:0,warnings:o,message:Pe(i),data:{schema:"kadence/v1",ok:!0,task:Fe(i)}}}function _n(e,n,r,t){let s=h(e,n);if(!b(s))return s;if(t.type!==void 0&&!R.includes(t.type))return L("unknown_type","type",t.type,R);if(t.priority!==void 0&&!j.includes(t.priority))return L("unknown_priority","priority",t.priority,j);if(t.due!==void 0&&t.due!==""&&!_t(t.due))return{ok:!1,exitCode:2,message:`Due date must be YYYY-MM-DD, got "${t.due}".
129
+ kadence task edit KAD-1 --due 2026-09-30`};let{state:o,warnings:i}=k(s.root,s.actor),{tasks:a,error:d}=A(o,r);if(d!==null)return d;if(t.title!==void 0&&a.length>1)return{ok:!1,exitCode:2,message:"A title can only be set on one task at a time."};let u=[],c=new Set;for(let l of a){let p={},m=[];if(t.title!==void 0&&t.title!==l.title&&(p.title=t.title,m.push("title")),t.description!==void 0&&t.description!==(l.description??"")&&(p.description=t.description,m.push("description")),t.type!==void 0&&t.type!==l.type&&(p.type=t.type,m.push("type")),t.priority!==void 0&&t.priority!==l.priority&&(p.priority=t.priority,m.push("priority")),t.due!==void 0&&t.due!==(l.due??"")&&(p.due=t.due,m.push("due")),t.estimate!==void 0&&t.estimate!==l.estimate&&(p.estimate=t.estimate,m.push("estimate")),t.labels!==void 0&&t.labels.join(",")!==l.labels.join(",")&&(p.labels=t.labels,m.push("labels")),m.length!==0){T(s.root,{id:x(),type:"task.updated",entity:l.id,actor:s.actor,ts:new Date().toISOString(),source:s.source,data:p}),u.push(l);for(let g of m)c.add(g)}}if(u.length===0)return{ok:!0,exitCode:0,warnings:i,message:w("unchanged",a,"nothing changed.")};let f=[...c].join(", ");return{ok:!0,exitCode:0,warnings:i,message:w("updated",u,`updated ${f}.`),data:{schema:"kadence/v1",ok:!0,updated:u.map(l=>({id:l.id,label:l.label})),changed:[...c]}}}function _t(e){if(!/^\d{4}-\d{2}-\d{2}$/.test(e))return!1;let n=new Date(`${e}T00:00:00.000Z`);return!Number.isNaN(n.getTime())&&n.toISOString().slice(0,10)===e}function Nn(e,n,r){let t=h(e,n);if(!b(t))return t;let{state:s,warnings:o}=k(t.root,t.actor),{tasks:i,error:a}=A(s,r);if(a!==null)return a;let d=i.filter(u=>u.status!=="cancelled");if(d.length===0)return{ok:!0,exitCode:0,warnings:o,message:w("already cancelled",i,"is already cancelled.")};for(let u of d)T(t.root,{id:x(),type:"task.cancelled",entity:u.id,actor:t.actor,ts:new Date().toISOString(),source:t.source,data:{}});return{ok:!0,exitCode:0,warnings:o,message:`${w("cancelled",d,"cancelled.")}
130
+ Cancelled work stays in history and does not count as missed.`,data:{schema:"kadence/v1",ok:!0,cancelled:d.map(u=>({id:u.id,label:u.label}))}}}function An(e,n,r){let t=h(e,n);if(!b(t))return t;let{state:s,warnings:o}=k(t.root,t.actor),{tasks:i,error:a}=A(s,r);if(a!==null)return a;for(let u of i)T(t.root,{id:x(),type:"task.deleted",entity:u.id,actor:t.actor,ts:new Date().toISOString(),source:t.source,data:{title:u.title}});let d=i.length===1?`${i[0].label} deleted: "${i[0].title}".`:`${i.length} tasks deleted: ${i.map(u=>u.label).join(", ")}.`;return{ok:!0,exitCode:0,warnings:o,message:`${d}
131
+ The events stay in the journal \u2014 history is never rewritten.`,data:{schema:"kadence/v1",ok:!0,deleted:i.map(u=>({id:u.id,label:u.label}))}}}function On(e,n,r,t){let s=h(e,n);if(!b(s))return s;let o=t.trim();if(o.length===0)return{ok:!1,exitCode:2,message:"A comment needs text."};let{state:i,warnings:a}=k(s.root,s.actor),d=C(i,r);return d===void 0?N(r):(T(s.root,{id:x(),type:"task.commented",entity:d.id,actor:s.actor,ts:new Date().toISOString(),source:s.source,data:{text:o}}),{ok:!0,exitCode:0,warnings:a,message:`Comment added to ${d.label}.`,data:{schema:"kadence/v1",ok:!0,task:{id:d.id,label:d.label}}})}function A(e,n){let r=n.split(",").map(i=>i.trim()).filter(i=>i.length>0);if(r.length===0)return{tasks:[],error:$(2,"invalid_argument","No task given.")};let t=[],s=[];for(let i of r){let a=C(e,i);a===void 0?s.push(i):t.push(a)}return s.length>0?{tasks:[],error:$(1,"task_not_found",`No task ${s.join(", ")} \u2014 nothing was changed.
132
+ All ids must exist before a bulk change runs.
133
+ kadence task list`,{received:s.join(","),hint:"kadence task list --json"})}:{tasks:[...new Map(t.map(i=>[i.id,i])).values()],error:null}}function w(e,n,r){return n.length===1?`${n[0].label}: ${r}`:`${n.length} tasks ${e}: ${n.map(t=>t.label).join(", ")}`}function Pn(e,n,r,t){let s=h(e,n);if(!b(s))return s;let{state:o,warnings:i}=k(s.root,s.actor),{tasks:a,error:d}=A(o,r);if(d!==null)return d;let u=t.trim().toLowerCase()==="none",c=null;if(!u){let p=C(o,t);if(p===void 0)return N(t);if(a.some(m=>m.id===p.id))return{ok:!1,exitCode:2,message:"A task cannot be its own parent."};c=p.id}let f=a.filter(p=>p.parent!==c);if(f.length===0)return{ok:!0,exitCode:0,warnings:i,message:w("unchanged",a,"already there.")};for(let p of f)T(s.root,{id:x(),type:"task.parent_set",entity:p.id,actor:s.actor,ts:new Date().toISOString(),source:s.source,data:{parent:c}});let l=u?"detached":C(o,t).label;return{ok:!0,exitCode:0,warnings:[...i,...Me(s.root,s.actor)],message:u?w("detached",f,"detached from its parent."):w("moved",f,`\u2192 child of ${l}`),data:{schema:"kadence/v1",ok:!0,parent:c}}}function In(e,n,r,t,s){let o=h(e,n);if(!b(o))return o;let{state:i,warnings:a}=k(o.root,o.actor),{tasks:d,error:u}=A(i,r);if(u!==null)return u;let c=C(i,t);if(c===void 0)return N(t);if(d.some(l=>l.id===c.id))return{ok:!1,exitCode:2,message:"A task cannot block itself."};let f=d.filter(l=>s?l.blockedBy.includes(c.id):!l.blockedBy.includes(c.id));if(f.length===0)return{ok:!0,exitCode:0,warnings:a,message:w("unchanged",d,s?"was not blocked by it.":"is already blocked by it.")};for(let l of f)T(o.root,{id:x(),type:s?"task.blocked_by_removed":"task.blocked_by_added",entity:l.id,actor:o.actor,ts:new Date().toISOString(),source:o.source,data:{blocker:c.id}});return{ok:!0,exitCode:0,warnings:[...a,...Me(o.root,o.actor)],message:s?w("unblocked",f,`no longer blocked by ${c.label}.`):w("blocked",f,`blocked by ${c.label}.`),data:{schema:"kadence/v1",ok:!0,blocker:c.id}}}function Me(e,n){let{state:r}=k(e,n),t=new Map(r.tasks.map(s=>[s.id,s.label]));return r.cycles.map(s=>{let o=s.path.map(i=>t.get(i)??i).join(" \u2192 ");return`Dependency cycle (${s.kind}): ${o}. Both edges were kept \u2014 resolve it when you can.`})}function Nt(e){let n=/^(-?\d+(?:\.\d+)?)\s*(h|hours?|m|min|minutes?)?$/i.exec(e.trim());if(n===null)return null;let r=Number(n[1]);return!Number.isFinite(r)||r===0?null:(n[2]??"h").toLowerCase().startsWith("m")?r/60:r}function Fn(e,n,r,t){let s=h(e,n);if(!b(s))return s;let o=Nt(t);if(o===null)return{ok:!1,exitCode:2,message:`Cannot read "${t}" as a duration.
134
+ Use hours or minutes:
135
+ kadence task log KAD-1 2h
136
+ kadence task log KAD-1 90m
137
+ kadence task log KAD-1 -30m to correct a mistake`};let{state:i,warnings:a}=k(s.root,s.actor),d=C(i,r);if(d===void 0)return N(r);T(s.root,{id:x(),type:"task.time_logged",entity:d.id,actor:s.actor,ts:new Date().toISOString(),source:s.source,data:{hours:o}});let u=Math.max(0,d.loggedHours+o),c=d.estimate===null?`
138
+ No estimate on this task, so there is nothing to compare against.`:"";return{ok:!0,exitCode:0,warnings:a,message:`${d.label}: ${u.toFixed(1)}h logged in total.${c}`,data:{schema:"kadence/v1",ok:!0,task:{id:d.id,label:d.label,loggedHours:u}}}}import{spawnSync as At}from"node:child_process";import{mkdtempSync as Ot,readFileSync as Pt,rmSync as It,writeFileSync as Ft}from"node:fs";import{tmpdir as Mt}from"node:os";import{join as Le}from"node:path";var U="#";function Lt(e){return e.GIT_EDITOR??e.VISUAL??e.EDITOR??"vi"}function Un(e,n,r){let t=Ot(Le(Mt(),"kadence-edit-")),s=Le(t,"KADENCE_EDITMSG.md"),o=["",`${U} ${r}`,`${U} Lines starting with '${U}' are ignored.`,`${U} Save an empty file to abort.`].join(`
139
+ `);try{Ft(s,`${n}${o}
140
+ `,"utf8");let i=Lt(e),a=At(i,[s],{stdio:"inherit",shell:!0});if(a.error!==void 0||a.status!==null&&a.status!==0)return{text:null,error:`Editor "${i}" exited without saving.
141
+ Set one explicitly:
142
+ export EDITOR=nano`};let u=Pt(s,"utf8").split(`
143
+ `).filter(c=>!c.startsWith(U)).join(`
144
+ `).trim();return{text:u.length===0?null:u,error:null}}catch(i){return{text:null,error:`Could not open an editor: ${i.message}`}}finally{It(t,{recursive:!0,force:!0})}}function Hn(e,n){return e.KADENCE_SOURCE==="agent"?!1:n}function te(e,n){let r=e.sprints.find(g=>g.id===n);if(r===void 0)return null;let t=e.tasks.filter(g=>g.sprint===n),s=t.filter(g=>g.status==="cancelled"),o=t.filter(g=>g.status!=="cancelled"),i=o.filter(g=>g.status==="done"),a=o.filter(g=>g.status!=="done"),d=H(o.map(g=>g.estimate??0)),u=H(i.map(g=>g.estimate??0)),c=i.filter(g=>g.estimate===null),f=i.map(Bt).filter(g=>g!==null),l=f.length>0?H(f):null,p=H(i.filter(g=>g.estimate!==null).map(g=>g.estimate)),m=l!==null&&p>0?l/p:null;return{id:r.id,name:r.name,status:r.status,committed:d,velocity:u,actualHours:l,hoursPerPoint:m,done:i,carriedOver:a,cancelled:s,unestimated:c,loggedHours:H(t.map(g=>g.loggedHours))}}function Bt(e){let n=e.history.find(s=>s.type==="task.moved"&&s.data.to==="in_progress"),r=[...e.history].reverse().find(s=>s.type==="task.moved"&&s.data.to==="done");if(n===void 0||r===void 0)return null;let t=Date.parse(r.ts)-Date.parse(n.ts);return t>0?t/36e5:null}function H(e){return e.reduce((n,r)=>n+r,0)}function W(e){return new Date(e).toISOString().slice(0,10)}function Kt(e,n){let r=[];for(let t=Date.parse(`${e}T00:00:00.000Z`);t<=Date.parse(`${n}T00:00:00.000Z`);t+=864e5)r.push(W(t));return r}function Be(e,n,r,t=W(Date.now())){let s=e.tasks.filter(y=>y.sprint===r.id&&y.status!=="cancelled"),o=new Map(s.map(y=>[y.id,y.estimate??0])),i=[...o.values()].reduce((y,E)=>y+E,0),a=n.filter(y=>o.has(y.entity));if(a.length===0)return null;let d=r.startDate??W(a[0].ts),u=r.endDate??W(a.at(-1).ts),c=r.status==="closed"||u<t?u:t;if(c<d)return null;let f=new Set,l=new Map;for(let y of a){let E=W(y.ts);if(E<d)continue;let P=y.type==="task.moved"?y.data?.to:void 0,re=o.get(y.entity)??0;P==="done"&&!f.has(y.entity)?(f.add(y.entity),l.set(E,(l.get(E)??0)+re)):P!==void 0&&P!=="done"&&f.has(y.entity)&&(f.delete(y.entity),l.set(E,(l.get(E)??0)-re))}let p=Kt(d,c),m=Math.max(p.length-1,1),g=i;return{sprintName:r.name,committed:i,finalRemaining:(r.status==="closed",null),days:p.map((y,E)=>{let P=l.get(y)??0;return g-=P,{date:y,remaining:Math.max(0,g),ideal:Math.max(0,i-i/m*E),completed:P}})}}function Ke(e,n=40){if(e.committed===0)return`"${e.sprintName}": nothing to burn down \u2014 no estimated tasks.`;let r=[`"${e.sprintName}" \u2014 ${e.committed} points committed`,""];for(let s of e.days){let o=Math.round(s.remaining/e.committed*n),i=Math.round(s.ideal/e.committed*n),a=[];for(let c=0;c<n;c++)c===i&&c>=o?a.push("\u250A"):c<o?a.push(c===i?"\u2503":"\u2588"):a.push(" ");let d=s.remaining-s.ideal,u=Math.abs(d)<.5?"":d>0?` +${d.toFixed(0)}`:` ${d.toFixed(0)}`;r.push(`${s.date.slice(5)} ${a.join("")} ${String(s.remaining).padStart(3)}${u}`)}let t=e.days.at(-1);return t!==void 0&&(r.push(""),r.push(t.remaining===0?" All committed work is done.":` ${t.remaining} of ${e.committed} points remain.`+(t.remaining>t.ideal?" Behind the ideal line.":" On or ahead of the line."))),r.join(`
145
+ `)}function O(e){return e.sprints.find(n=>n.status==="active")}function Jt(e){return e.sprints.filter(n=>n.status==="planned")}function B(e,n){let r=n.trim().toLowerCase();return e.sprints.find(t=>t.name.toLowerCase()===r)}function K(e,n,r,t){T(e.root,{id:x(),type:n,entity:r,actor:e.actor,ts:new Date().toISOString(),source:e.source,data:t})}function er(e,n,r){let t=h(e,n);if(!b(t))return t;let s=r.trim();if(s.length===0)return{ok:!1,exitCode:2,message:"A sprint needs a name."};let{state:o,warnings:i}=k(t.root,t.actor);if(B(o,s)!==void 0)return{ok:!1,exitCode:2,message:`Sprint "${s}" already exists.`};let a=O(o)!==void 0,d=x();return K(t,"sprint.created",d,{name:s}),a||K(t,"sprint.started",d,{}),{ok:!0,exitCode:0,warnings:i,message:a?`Sprint "${s}" planned.
146
+
147
+ kadence sprint add KAD-1 --sprint "${s}"
148
+ kadence sprint start "${s}"`:`Sprint "${s}" started.
149
+
150
+ kadence sprint add KAD-1
151
+ kadence sprint status`,data:{schema:"kadence/v1",ok:!0,sprint:{id:d,name:s,status:a?"planned":"active"}}}}function tr(e,n,r,t={}){let s=h(e,n);if(!b(s))return s;let{state:o,warnings:i}=k(s.root,s.actor),a=t.sprint===void 0?O(o):B(o,t.sprint);if(a===void 0)return t.sprint===void 0?{ok:!1,exitCode:1,message:`No active sprint.
152
+ kadence sprint create "Sprint 1"`}:{ok:!1,exitCode:1,message:`No sprint named "${t.sprint}".
153
+ kadence sprint list`};if(a.status==="closed")return{ok:!1,exitCode:1,message:`Sprint "${a.name}" is closed \u2014 its velocity is not rewritten.`};let d=C(o,r);if(d===void 0)return N(r);if(d.sprint===a.id)return{ok:!0,exitCode:0,warnings:i,message:`${d.label} is already in the sprint.`};K(s,"sprint.task_added",a.id,{task:d.id});let u=d.estimate===null?`
154
+ Without an estimate this task will not count towards velocity.`:"";return{ok:!0,exitCode:0,warnings:i,message:`${d.label} \u2192 "${a.name}"${u}`,data:{schema:"kadence/v1",ok:!0,task:{id:d.id,label:d.label},sprint:a.id}}}function nr(e,n){let r=h(e,n);if(!b(r))return r;let{state:t,warnings:s}=k(r.root,r.actor),o=O(t);if(o===void 0)return{ok:!1,exitCode:1,message:`No active sprint.
155
+ kadence sprint create "Sprint 1"`};let i=te(t,o.id);K(r,"sprint.closed",o.id,{velocity:i.velocity});let a=[...s];return i.unestimated.length>0&&a.push(`${i.unestimated.length} completed task(s) without an estimate were left out of velocity: `+i.unestimated.map(d=>d.label).join(", ")),{ok:!0,exitCode:0,warnings:a,message:Ut(i),data:{schema:"kadence/v1",ok:!0,report:Je(i)}}}function rr(e,n){let r=h(e,n);if(!b(r))return r;let{state:t,warnings:s}=k(r.root,r.actor),o=O(t);if(o===void 0)return{ok:!0,exitCode:0,warnings:s,message:`No active sprint.
156
+ kadence sprint create "Sprint 1"`,data:{schema:"kadence/v1",ok:!0,sprint:null}};let i=te(t,o.id),a=[`"${i.name}" \u2014 ${i.velocity} of ${i.committed} points`,"",...i.done.map(d=>` \u2713 ${d.label} ${d.title}`),...i.carriedOver.map(d=>` \xB7 ${d.label} ${d.title} (${d.status})`)];return{ok:!0,exitCode:0,warnings:s,message:a.join(`
157
+ `),data:{schema:"kadence/v1",ok:!0,report:Je(i)}}}function Ut(e){let n=[`Sprint "${e.name}" closed.`,""];if(n.push(` Velocity: ${e.velocity} of ${e.committed} points`),e.hoursPerPoint!==null&&e.actualHours!==null&&e.actualHours>=1/60&&n.push(` Actual: ${ne(e.actualHours)} \u2014 ${ne(e.hoursPerPoint)} per point`),e.loggedHours>0&&n.push(` Logged: ${ne(e.loggedHours)} entered by hand`),e.carriedOver.length>0){n.push("",` Carried over (${e.carriedOver.length}):`);for(let r of e.carriedOver)n.push(` \xB7 ${r.label} ${r.title}`)}return e.cancelled.length>0&&n.push("",` Cancelled (${e.cancelled.length}) \u2014 not counted towards velocity`),n.join(`
158
+ `)}function ne(e){return e<1?`${Math.round(e*60)}m`:e<10?`${e.toFixed(1)}h`:`${Math.round(e)}h`}function Je(e){return{id:e.id,name:e.name,status:e.status,velocity:e.velocity,committed:e.committed,actualHours:e.actualHours,hoursPerPoint:e.hoursPerPoint,done:e.done.map(n=>n.label),carriedOver:e.carriedOver.map(n=>n.label),cancelled:e.cancelled.map(n=>n.label),unestimated:e.unestimated.map(n=>n.label),loggedHours:e.loggedHours}}function sr(e,n,r){let t=h(e,n);if(!b(t))return t;let{state:s,warnings:o}=k(t.root,t.actor),i=O(s);if(i!==void 0)return{ok:!1,exitCode:1,message:`Sprint "${i.name}" is still active.
159
+ Close it so velocity can be computed:
160
+ kadence sprint close`};let a=Jt(s),d=r===void 0?a[0]:B(s,r);return d===void 0?{ok:!1,exitCode:1,message:r===void 0?`No planned sprints.
161
+ kadence sprint create "Sprint 2"`:`No sprint named "${r}".
162
+ kadence sprint list`}:d.status!=="planned"?{ok:!1,exitCode:1,message:`Sprint "${d.name}" is already ${d.status}.`}:(K(t,"sprint.started",d.id,{}),{ok:!0,exitCode:0,warnings:o,message:`Sprint "${d.name}" started.
163
+
164
+ kadence sprint status`,data:{schema:"kadence/v1",ok:!0,sprint:{id:d.id,name:d.name}}})}function or(e,n){let r=h(e,n);if(!b(r))return r;let{state:t,warnings:s}=k(r.root,r.actor);if(t.sprints.length===0)return{ok:!0,exitCode:0,warnings:s,message:`No sprints yet.
165
+ kadence sprint create "Sprint 1"`,data:{schema:"kadence/v1",ok:!0,sprints:[]}};let o=t.sprints.map(i=>{let a=t.tasks.filter(u=>u.sprint===i.id),d=a.reduce((u,c)=>u+(c.estimate??0),0);return{sprint:i,tasks:a,points:d}});return{ok:!0,exitCode:0,warnings:s,message:o.map(({sprint:i,tasks:a,points:d})=>{let u=i.status==="active"?"\u2192":" ",c=a.length===0?"":` ${a.length} tasks, ${d} points`;return`${u} ${i.name.padEnd(20)} ${i.status.padEnd(8)}${c}`}).join(`
166
+ `),data:{schema:"kadence/v1",ok:!0,sprints:o.map(({sprint:i,tasks:a,points:d})=>({id:i.id,name:i.name,status:i.status,taskIds:i.taskIds,taskCount:a.length,points:d}))}}}function Ht(e){if(!/^\d{4}-\d{2}-\d{2}$/.test(e))return!1;let n=new Date(`${e}T00:00:00.000Z`);return!Number.isNaN(n.getTime())&&n.toISOString().slice(0,10)===e}function ir(e,n,r,t){let s=h(e,n);if(!b(s))return s;for(let[l,p]of[["--start",t.startDate],["--end",t.endDate]])if(p!==void 0&&p!==""&&!Ht(p))return{ok:!1,exitCode:2,message:`${l} must be YYYY-MM-DD, got "${p}".
167
+ kadence sprint edit --start 2026-09-01`};let{state:o,warnings:i}=k(s.root,s.actor),a=r===void 0?O(o):B(o,r);if(a===void 0)return{ok:!1,exitCode:1,message:r===void 0?`No active sprint.
168
+ kadence sprint list`:`No sprint named "${r}".
169
+ kadence sprint list`};if(a.status==="closed")return{ok:!1,exitCode:1,message:`Sprint "${a.name}" is closed \u2014 its record is not rewritten.`};if(t.name!==void 0&&t.name!==a.name&&B(o,t.name)!==void 0)return{ok:!1,exitCode:2,message:`Sprint "${t.name}" already exists.`};let d=t.startDate??a.startDate??"",u=t.endDate??a.endDate??"";if(d!==""&&u!==""&&u<d)return{ok:!1,exitCode:2,message:`The end date (${u}) is before the start date (${d}).`};let c={},f=[];return t.name!==void 0&&t.name!==a.name&&(c.name=t.name,f.push("name")),t.description!==void 0&&t.description!==(a.description??"")&&(c.description=t.description,f.push("description")),t.startDate!==void 0&&t.startDate!==(a.startDate??"")&&(c.startDate=t.startDate,f.push("start")),t.endDate!==void 0&&t.endDate!==(a.endDate??"")&&(c.endDate=t.endDate,f.push("end")),f.length===0?{ok:!0,exitCode:0,warnings:i,message:`"${a.name}": nothing changed.`}:(K(s,"sprint.updated",a.id,c),{ok:!0,exitCode:0,warnings:i,message:`"${a.name}": updated ${f.join(", ")}.`,data:{schema:"kadence/v1",ok:!0,sprint:{id:a.id,changed:f}}})}function ar(e,n,r){let t=h(e,n);if(!b(t))return t;let{state:s,warnings:o}=k(t.root,t.actor),i=r===void 0?O(s):B(s,r);if(i===void 0)return{ok:!1,exitCode:1,message:r===void 0?`No active sprint.
170
+ kadence sprint list`:`No sprint named "${r}".
171
+ kadence sprint list`};let a=Be(s,M(t.root).events,i);return a===null?{ok:!0,exitCode:0,warnings:o,message:`"${i.name}" has no tasks yet.
172
+ kadence sprint add KAD-1`,data:{schema:"kadence/v1",ok:!0,burndown:null}}:{ok:!0,exitCode:0,warnings:o,message:Ke(a),data:{schema:"kadence/v1",ok:!0,burndown:a}}}export{be as a,F as b,J as c,T as d,Wt as e,Yt as f,Gt as g,x as h,Vt as i,He as j,R as k,j as l,ee as m,gn as n,q as o,$n as p,h as q,b as r,Cn as s,k as t,En as u,Dn as v,Rt as w,Fe as x,Rn as y,jn as z,_n as A,Nn as B,An as C,On as D,Pn as E,In as F,Fn as G,Un as H,Hn as I,er as J,tr as K,nr as L,rr as M,sr as N,or as O,ir as P,ar as Q};
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{C as x,D as C,E as h,G as y,H as E,I as A,J as N,M as F,n as b,o as T,p as c,q as l,s as d,u as f,w as u,y as S,z as k}from"./chunk-BUHXYOZ4.js";async function $(r,e){let a=b(r,e);if(!T(a))return a;if(process.stdout.isTTY!==!0)return{ok:!1,exitCode:1,message:`The interactive board needs a terminal.
2
+ import{A as u,C as S,D as k,G as x,H as C,I as h,K as y,L as E,M as A,N,Q as F,q as b,r as T,s as c,t as l,v as d,y as f}from"./chunk-JA73FCAN.js";async function $(r,e){let a=b(r,e);if(!T(a))return a;if(process.stdout.isTTY!==!0)return{ok:!1,exitCode:1,message:`The interactive board needs a terminal.
3
3
  For pipes and scripts use:
4
4
  kadence board --json`};let g;try{g=await import("./board-7RVHIQJQ.js")}catch(t){return{ok:!1,exitCode:1,message:`The interactive board could not start: ${t.message}
5
5
  The plain board always works:
package/dist/cli.js CHANGED
@@ -1,89 +1,44 @@
1
1
  #!/usr/bin/env node
2
- import{A as se,B as ae,C as T,D as ie,E as re,F as oe,G as de,H as ce,I as le,J as ue,K as me,L as fe,M as pe,a as F,b as U,c as $,d as A,e as g,f as E,g as q,h as W,i as P,j as Y,k as G,l as V,m as S,n as k,o as b,p as J,q as y,r as H,s as z,t as Q,u as X,v as O,w as Z,x as ee,y as te,z as ne}from"./chunks/chunk-BUHXYOZ4.js";function K(n){return n==null?[]:Array.isArray(n)?n:[n]}function Ie(n,t,s,e){var a,i=n[t],r=~e.string.indexOf(t)?s==null||s===!0?"":String(s):typeof s=="boolean"?s:~e.boolean.indexOf(t)?s==="false"?!1:s==="true"||(n._.push((a=+s,a*0===0?a:s)),!!s):(a=+s,a*0===0?a:s);n[t]=i==null?r:Array.isArray(i)?i.concat(r):[i,r]}function Be(n,t){n=n||[],t=t||{};var s,e,a,i,r,d={_:[]},o=0,l=0,u=0,m=n.length;let p=t.alias!==void 0,D=t.unknown!==void 0,M=t.default!==void 0;if(t.alias=t.alias||{},t.string=K(t.string),t.boolean=K(t.boolean),p)for(s in t.alias)for(e=t.alias[s]=K(t.alias[s]),o=0;o<e.length;o++)(t.alias[e[o]]=e.concat(s)).splice(o,1);for(o=t.boolean.length;o-- >0;)for(e=t.alias[t.boolean[o]]||[],l=e.length;l-- >0;)t.boolean.push(e[l]);for(o=t.string.length;o-- >0;)for(e=t.alias[t.string[o]]||[],l=e.length;l-- >0;)t.string.push(e[l]);if(M){for(s in t.default)if(i=typeof t.default[s],e=t.alias[s]=t.alias[s]||[],t[i]!==void 0)for(t[i].push(s),o=0;o<e.length;o++)t[i].push(e[o])}let L=D?Object.keys(t.alias):[];for(o=0;o<m;o++){if(a=n[o],a==="--"){d._=d._.concat(n.slice(++o));break}for(l=0;l<a.length&&a.charCodeAt(l)===45;l++);if(l===0)d._.push(a);else if(a.substring(l,l+3)==="no-"){if(i=a.substring(l+3),D&&!~L.indexOf(i))return t.unknown(a);d[i]=!1}else{for(u=l+1;u<a.length&&a.charCodeAt(u)!==61;u++);for(i=a.substring(l,u),r=a.substring(++u)||o+1===m||(""+n[o+1]).charCodeAt(0)===45||n[++o],e=l===2?[i]:i,u=0;u<e.length;u++){if(i=e[u],D&&!~L.indexOf(i))return t.unknown("-".repeat(l)+i);Ie(d,i,u+1<e.length||r,t)}}}if(M)for(s in t.default)d[s]===void 0&&(d[s]=t.default[s]);if(p)for(s in d)for(e=t.alias[s]||[];e.length>0;)d[e.shift()]=d[s];return d}function ke(n){return n.replace(/[<[].+/,"").trim()}function Me(n){let t=/<([^>]+)>/g,s=/\[([^\]]+)\]/g,e=[],a=d=>{let o=!1,l=d[1];return l.startsWith("...")&&(l=l.slice(3),o=!0),{required:d[0].startsWith("<"),value:l,variadic:o}},i;for(;i=t.exec(n);)e.push(a(i));let r;for(;r=s.exec(n);)e.push(a(r));return e}function Le(n){let t={alias:{},boolean:[]};for(let[s,e]of n.entries())e.names.length>1&&(t.alias[e.names[0]]=e.names.slice(1)),e.isBoolean&&(e.negated&&n.some((a,i)=>i!==s&&a.names.some(r=>e.names.includes(r))&&typeof a.required=="boolean")||t.boolean.push(e.names[0]));return t}function he(n){return n.sort((t,s)=>t.length>s.length?-1:1)[0]}function ge(n,t){return n.length>=t?n:`${n}${" ".repeat(t-n.length)}`}function Fe(n){return n.replaceAll(/([a-z])-([a-z])/g,(t,s,e)=>s+e.toUpperCase())}function Ue(n,t,s){let e=n;for(let a=0;a<t.length;a++){let i=t[a];if(a===t.length-1){e[i]=s;return}if(e[i]==null){let r=+t[a+1]>-1;e[i]=r?[]:{}}e=e[i]}}function qe(n,t){for(let s of Object.keys(t)){let e=t[s];e.shouldTransform&&(n[s]=[n[s]].flat(),typeof e.transformFunction=="function"&&(n[s]=n[s].map(e.transformFunction)))}}function We(n){let t=/([^\\/]+)$/.exec(n);return t?t[1]:""}function be(n){return n.split(".").map((t,s)=>s===0?Fe(t):t).join(".")}var x=class extends Error{constructor(n){super(n),this.name="CACError",typeof Error.captureStackTrace!="function"&&(this.stack=new Error(n).stack)}},Pe=class{rawName;description;name;names;isBoolean;required;config;negated;constructor(n,t,s){this.rawName=n,this.description=t,this.config=Object.assign({},s),n=n.replaceAll(".*",""),this.negated=!1,this.names=ke(n).split(",").map(e=>{let a=e.trim().replace(/^-{1,2}/,"");return a.startsWith("no-")&&(this.negated=!0,a=a.replace(/^no-/,"")),be(a)}).sort((e,a)=>e.length>a.length?1:-1),this.name=this.names.at(-1),this.negated&&this.config.default==null&&(this.config.default=!0),n.includes("<")?this.required=!0:n.includes("[")?this.required=!1:this.isBoolean=!0}},N,w;if(typeof process<"u"){let n;typeof Deno<"u"&&typeof Deno.version?.deno=="string"?n="deno":typeof Bun<"u"&&typeof Bun.version=="string"?n="bun":n="node",w=`${process.platform}-${process.arch} ${n}-${process.version}`,N=process.argv}else typeof navigator>"u"?w="unknown":w=`${navigator.platform} ${navigator.userAgent}`;var ye=class{rawName;description;config;cli;options;aliasNames;name;args;commandAction;usageText;versionNumber;examples;helpCallback;globalCommand;constructor(n,t,s={},e){this.rawName=n,this.description=t,this.config=s,this.cli=e,this.options=[],this.aliasNames=[],this.name=ke(n),this.args=Me(n),this.examples=[]}usage(n){return this.usageText=n,this}allowUnknownOptions(){return this.config.allowUnknownOptions=!0,this}ignoreOptionDefaultValue(){return this.config.ignoreOptionDefaultValue=!0,this}version(n,t="-v, --version"){return this.versionNumber=n,this.option(t,"Display version number"),this}example(n){return this.examples.push(n),this}option(n,t,s){let e=new Pe(n,t,s);return this.options.push(e),this}alias(n){return this.aliasNames.push(n),this}action(n){return this.commandAction=n,this}isMatched(n){return this.name===n||this.aliasNames.includes(n)}get isDefaultCommand(){return this.name===""||this.aliasNames.includes("!")}get isGlobalCommand(){return this instanceof ve}hasOption(n){return n=n.split(".")[0],this.options.find(t=>t.names.includes(n))}outputHelp(){let{name:n,commands:t}=this.cli,{versionNumber:s,options:e,helpCallback:a}=this.cli.globalCommand,i=[{body:`${n}${s?`/${s}`:""}`}];if(i.push({title:"Usage",body:` $ ${n} ${this.usageText||this.rawName}`}),(this.isGlobalCommand||this.isDefaultCommand)&&t.length>0){let d=he(t.map(o=>o.rawName));i.push({title:"Commands",body:t.map(o=>` ${ge(o.rawName,d.length)} ${o.description}`).join(`
2
+ import{A as ne,B as se,C as ie,D as ae,E as re,F as oe,G as K,H as de,I as ce,J as le,K as ue,L as me,M as fe,N as pe,O as he,P as ge,Q as ke,a as F,b as L,c as E,d as C,e as U,f as q,g as Y,h as b,i as O,j as P,k as V,l as W,m as G,n as J,o as H,p as T,q as y,r as x,s as z,t as v,u as Q,v as X,w as Z,x as ee,y as te,z as j}from"./chunks/chunk-JA73FCAN.js";function N(n){return n==null?[]:Array.isArray(n)?n:[n]}function Ie(n,t,s,e){var i,a=n[t],r=~e.string.indexOf(t)?s==null||s===!0?"":String(s):typeof s=="boolean"?s:~e.boolean.indexOf(t)?s==="false"?!1:s==="true"||(n._.push((i=+s,i*0===0?i:s)),!!s):(i=+s,i*0===0?i:s);n[t]=a==null?r:Array.isArray(a)?a.concat(r):[a,r]}function Be(n,t){n=n||[],t=t||{};var s,e,i,a,r,d={_:[]},o=0,l=0,u=0,m=n.length;let k=t.alias!==void 0,p=t.unknown!==void 0,h=t.default!==void 0;if(t.alias=t.alias||{},t.string=N(t.string),t.boolean=N(t.boolean),k)for(s in t.alias)for(e=t.alias[s]=N(t.alias[s]),o=0;o<e.length;o++)(t.alias[e[o]]=e.concat(s)).splice(o,1);for(o=t.boolean.length;o-- >0;)for(e=t.alias[t.boolean[o]]||[],l=e.length;l-- >0;)t.boolean.push(e[l]);for(o=t.string.length;o-- >0;)for(e=t.alias[t.string[o]]||[],l=e.length;l-- >0;)t.string.push(e[l]);if(h){for(s in t.default)if(a=typeof t.default[s],e=t.alias[s]=t.alias[s]||[],t[a]!==void 0)for(t[a].push(s),o=0;o<e.length;o++)t[a].push(e[o])}let w=p?Object.keys(t.alias):[];for(o=0;o<m;o++){if(i=n[o],i==="--"){d._=d._.concat(n.slice(++o));break}for(l=0;l<i.length&&i.charCodeAt(l)===45;l++);if(l===0)d._.push(i);else if(i.substring(l,l+3)==="no-"){if(a=i.substring(l+3),p&&!~w.indexOf(a))return t.unknown(i);d[a]=!1}else{for(u=l+1;u<i.length&&i.charCodeAt(u)!==61;u++);for(a=i.substring(l,u),r=i.substring(++u)||o+1===m||(""+n[o+1]).charCodeAt(0)===45||n[++o],e=l===2?[a]:a,u=0;u<e.length;u++){if(a=e[u],p&&!~w.indexOf(a))return t.unknown("-".repeat(l)+a);Ie(d,a,u+1<e.length||r,t)}}}if(h)for(s in t.default)d[s]===void 0&&(d[s]=t.default[s]);if(k)for(s in d)for(e=t.alias[s]||[];e.length>0;)d[e.shift()]=d[s];return d}function xe(n){return n.replace(/[<[].+/,"").trim()}function Me(n){let t=/<([^>]+)>/g,s=/\[([^\]]+)\]/g,e=[],i=d=>{let o=!1,l=d[1];return l.startsWith("...")&&(l=l.slice(3),o=!0),{required:d[0].startsWith("<"),value:l,variadic:o}},a;for(;a=t.exec(n);)e.push(i(a));let r;for(;r=s.exec(n);)e.push(i(r));return e}function Fe(n){let t={alias:{},boolean:[]};for(let[s,e]of n.entries())e.names.length>1&&(t.alias[e.names[0]]=e.names.slice(1)),e.isBoolean&&(e.negated&&n.some((i,a)=>a!==s&&i.names.some(r=>e.names.includes(r))&&typeof i.required=="boolean")||t.boolean.push(e.names[0]));return t}function be(n){return n.sort((t,s)=>t.length>s.length?-1:1)[0]}function ye(n,t){return n.length>=t?n:`${n}${" ".repeat(t-n.length)}`}function Le(n){return n.replaceAll(/([a-z])-([a-z])/g,(t,s,e)=>s+e.toUpperCase())}function Ue(n,t,s){let e=n;for(let i=0;i<t.length;i++){let a=t[i];if(i===t.length-1){e[a]=s;return}if(e[a]==null){let r=+t[i+1]>-1;e[a]=r?[]:{}}e=e[a]}}function qe(n,t){for(let s of Object.keys(t)){let e=t[s];e.shouldTransform&&(n[s]=[n[s]].flat(),typeof e.transformFunction=="function"&&(n[s]=n[s].map(e.transformFunction)))}}function Ye(n){let t=/([^\\/]+)$/.exec(n);return t?t[1]:""}function ve(n){return n.split(".").map((t,s)=>s===0?Le(t):t).join(".")}var D=class extends Error{constructor(n){super(n),this.name="CACError",typeof Error.captureStackTrace!="function"&&(this.stack=new Error(n).stack)}},Pe=class{rawName;description;name;names;isBoolean;required;config;negated;constructor(n,t,s){this.rawName=n,this.description=t,this.config=Object.assign({},s),n=n.replaceAll(".*",""),this.negated=!1,this.names=xe(n).split(",").map(e=>{let i=e.trim().replace(/^-{1,2}/,"");return i.startsWith("no-")&&(this.negated=!0,i=i.replace(/^no-/,"")),ve(i)}).sort((e,i)=>e.length>i.length?1:-1),this.name=this.names.at(-1),this.negated&&this.config.default==null&&(this.config.default=!0),n.includes("<")?this.required=!0:n.includes("[")?this.required=!1:this.isBoolean=!0}},R,$;if(typeof process<"u"){let n;typeof Deno<"u"&&typeof Deno.version?.deno=="string"?n="deno":typeof Bun<"u"&&typeof Bun.version=="string"?n="bun":n="node",$=`${process.platform}-${process.arch} ${n}-${process.version}`,R=process.argv}else typeof navigator>"u"?$="unknown":$=`${navigator.platform} ${navigator.userAgent}`;var Ae=class{rawName;description;config;cli;options;aliasNames;name;args;commandAction;usageText;versionNumber;examples;helpCallback;globalCommand;constructor(n,t,s={},e){this.rawName=n,this.description=t,this.config=s,this.cli=e,this.options=[],this.aliasNames=[],this.name=xe(n),this.args=Me(n),this.examples=[]}usage(n){return this.usageText=n,this}allowUnknownOptions(){return this.config.allowUnknownOptions=!0,this}ignoreOptionDefaultValue(){return this.config.ignoreOptionDefaultValue=!0,this}version(n,t="-v, --version"){return this.versionNumber=n,this.option(t,"Display version number"),this}example(n){return this.examples.push(n),this}option(n,t,s){let e=new Pe(n,t,s);return this.options.push(e),this}alias(n){return this.aliasNames.push(n),this}action(n){return this.commandAction=n,this}isMatched(n){return this.name===n||this.aliasNames.includes(n)}get isDefaultCommand(){return this.name===""||this.aliasNames.includes("!")}get isGlobalCommand(){return this instanceof we}hasOption(n){return n=n.split(".")[0],this.options.find(t=>t.names.includes(n))}outputHelp(){let{name:n,commands:t}=this.cli,{versionNumber:s,options:e,helpCallback:i}=this.cli.globalCommand,a=[{body:`${n}${s?`/${s}`:""}`}];if(a.push({title:"Usage",body:` $ ${n} ${this.usageText||this.rawName}`}),(this.isGlobalCommand||this.isDefaultCommand)&&t.length>0){let d=be(t.map(o=>o.rawName));a.push({title:"Commands",body:t.map(o=>` ${ye(o.rawName,d.length)} ${o.description}`).join(`
3
3
  `)},{title:"For more info, run any command with the `--help` flag",body:t.map(o=>` $ ${n}${o.name===""?"":` ${o.name}`} --help`).join(`
4
- `)})}let r=this.isGlobalCommand?e:[...this.options,...e||[]];if(!this.isGlobalCommand&&!this.isDefaultCommand&&(r=r.filter(d=>d.name!=="version")),r.length>0){let d=he(r.map(o=>o.rawName));i.push({title:"Options",body:r.map(o=>` ${ge(o.rawName,d.length)} ${o.description} ${o.config.default===void 0?"":`(default: ${o.config.default})`}`).join(`
5
- `)})}this.examples.length>0&&i.push({title:"Examples",body:this.examples.map(d=>typeof d=="function"?d(n):d).join(`
6
- `)}),a&&(i=a(i)||i),console.info(i.map(d=>d.title?`${d.title}:
4
+ `)})}let r=this.isGlobalCommand?e:[...this.options,...e||[]];if(!this.isGlobalCommand&&!this.isDefaultCommand&&(r=r.filter(d=>d.name!=="version")),r.length>0){let d=be(r.map(o=>o.rawName));a.push({title:"Options",body:r.map(o=>` ${ye(o.rawName,d.length)} ${o.description} ${o.config.default===void 0?"":`(default: ${o.config.default})`}`).join(`
5
+ `)})}this.examples.length>0&&a.push({title:"Examples",body:this.examples.map(d=>typeof d=="function"?d(n):d).join(`
6
+ `)}),i&&(a=i(a)||a),console.info(a.map(d=>d.title?`${d.title}:
7
7
  ${d.body}`:d.body).join(`
8
8
 
9
- `))}outputVersion(){let{name:n}=this.cli,{versionNumber:t}=this.cli.globalCommand;t&&console.info(`${n}/${t} ${w}`)}checkRequiredArgs(){let n=this.args.filter(t=>t.required).length;if(this.cli.args.length<n)throw new x(`missing required args for command \`${this.rawName}\``)}checkUnknownOptions(){let{options:n,globalCommand:t}=this.cli;if(!this.config.allowUnknownOptions){for(let s of Object.keys(n))if(s!=="--"&&!this.hasOption(s)&&!t.hasOption(s))throw new x(`Unknown option \`${s.length>1?`--${s}`:`-${s}`}\``)}}checkOptionValue(){let{options:n,globalCommand:t}=this.cli,s=[...t.options,...this.options];for(let e of s){let a=n[e.name.split(".")[0]];if(e.required){let i=s.some(r=>r.negated&&r.names.includes(e.name));if(a===!0||a===!1&&!i)throw new x(`option \`${e.rawName}\` value is missing`)}}}checkUnusedArgs(){let n=this.args.some(t=>t.variadic)?1/0:this.args.length;if(n<this.cli.args.length)throw new x(`Unused args: ${this.cli.args.slice(n).map(t=>`\`${t}\``).join(", ")}`)}},ve=class extends ye{constructor(n){super("@@global@@","",{},n)}},Ye=class extends EventTarget{name;commands;globalCommand;matchedCommand;matchedCommandName;rawArgs;args;options;showHelpOnExit;showVersionOnExit;constructor(n=""){super(),this.name=n,this.commands=[],this.rawArgs=[],this.args=[],this.options={},this.globalCommand=new ve(this),this.globalCommand.usage("<command> [options]")}usage(n){return this.globalCommand.usage(n),this}command(n,t,s){let e=new ye(n,t||"",s,this);return e.globalCommand=this.globalCommand,this.commands.push(e),e}option(n,t,s){return this.globalCommand.option(n,t,s),this}help(n){return this.globalCommand.option("-h, --help","Display this message"),this.globalCommand.helpCallback=n,this.showHelpOnExit=!0,this}version(n,t="-v, --version"){return this.globalCommand.version(n,t),this.showVersionOnExit=!0,this}example(n){return this.globalCommand.example(n),this}outputHelp(){this.matchedCommand?this.matchedCommand.outputHelp():this.globalCommand.outputHelp()}outputVersion(){this.globalCommand.outputVersion()}setParsedInfo({args:n,options:t},s,e){return this.args=n,this.options=t,s&&(this.matchedCommand=s),e&&(this.matchedCommandName=e),this}unsetMatchedCommand(){this.matchedCommand=void 0,this.matchedCommandName=void 0}parse(n,{run:t=!0}={}){if(!n){if(!N)throw new Error("No argv provided and runtime process argv is not available.");n=N}this.rawArgs=n,this.name||(this.name=n[1]?We(n[1]):"cli");let s=!0;for(let a of this.commands){let i=this.mri(n.slice(2),a),r=i.args[0];if(a.isMatched(r)){s=!1;let d={...i,args:i.args.slice(1)};this.setParsedInfo(d,a,r),this.dispatchEvent(new CustomEvent(`command:${r}`,{detail:a}))}}if(s){for(let a of this.commands)if(a.isDefaultCommand){s=!1;let i=this.mri(n.slice(2),a);this.setParsedInfo(i,a),this.dispatchEvent(new CustomEvent("command:!",{detail:a}))}}if(s){let a=this.mri(n.slice(2));this.setParsedInfo(a)}this.options.help&&this.showHelpOnExit&&(this.outputHelp(),t=!1,this.unsetMatchedCommand()),this.options.version&&this.showVersionOnExit&&this.matchedCommandName==null&&(this.outputVersion(),t=!1,this.unsetMatchedCommand());let e={args:this.args,options:this.options};return t&&this.runMatchedCommand(),!this.matchedCommand&&this.args[0]&&this.dispatchEvent(new CustomEvent("command:*",{detail:this.args[0]})),e}mri(n,t){let s=[...this.globalCommand.options,...t?t.options:[]],e=Le(s),a=[],i=n.indexOf("--");i!==-1&&(a=n.slice(i+1),n=n.slice(0,i));let r=Be(n,e);r=Object.keys(r).reduce((m,p)=>({...m,[be(p)]:r[p]}),{_:[]});let d=r._,o={"--":a},l=t&&t.config.ignoreOptionDefaultValue?t.config.ignoreOptionDefaultValue:this.globalCommand.config.ignoreOptionDefaultValue,u=Object.create(null);for(let m of s){if(!l&&m.config.default!==void 0)for(let p of m.names)o[p]=m.config.default;Array.isArray(m.config.type)&&u[m.name]===void 0&&(u[m.name]=Object.create(null),u[m.name].shouldTransform=!0,u[m.name].transformFunction=m.config.type[0])}for(let m of Object.keys(r))m!=="_"&&(Ue(o,m.split("."),r[m]),qe(o,u));return{args:d,options:o}}runMatchedCommand(){let{args:n,options:t,matchedCommand:s}=this;if(!s||!s.commandAction)return;s.checkUnknownOptions(),s.checkOptionValue(),s.checkRequiredArgs(),s.checkUnusedArgs();let e=[];return s.args.forEach((a,i)=>{a.variadic?e.push(n.slice(i)):e.push(n[i])}),e.push(t),s.commandAction.apply(this,e)}},Ae=(n="")=>new Ye(n);import{existsSync as C,mkdirSync as Ge,readFileSync as $e,writeFileSync as _}from"node:fs";import{join as I}from"node:path";var xe=`# kadence \u2014 for AI agents
10
-
11
- This project's tasks live here as plain files. Read them directly, or through
12
- the CLI. No server required.
13
-
14
- ## Commands
15
-
16
- kadence board --json the whole board
17
- kadence task list --json all tasks
18
- kadence task show KAD-42 --json one task with its history
19
- kadence task add "title" -d "..." --type bug --estimate 3
20
- kadence task move KAD-42 in_progress
21
- kadence task assign KAD-42 you@example.com
22
- kadence sprint status --json current sprint progress
23
-
24
- ## JSON contract
25
-
26
- Every \`--json\` response carries \`schema: "kadence/v1"\`. stdout holds JSON and
27
- nothing else; warnings go to stderr. Exit codes: 0 success, 1 runtime error,
28
- 2 bad arguments.
29
-
30
- ## Working as an agent
31
-
32
- Set \`KADENCE_SOURCE=agent\` so events record your authorship. Without it an
33
- event is marked as human \u2014 we do not guess.
34
-
35
- ## What not to do
36
-
37
- Do not hand-edit files under \`.kadence/events/\`: the journal is appended to,
38
- never modified. To correct the state, add a new event through the CLI.
39
- `,we="<!-- kadence:begin -->",R="<!-- kadence:end -->",j=`${we}
40
- ## Project tasks \u2014 kadence
41
-
42
- Tasks live in \`.kadence/\` as plain files. Read them directly or via the CLI:
43
-
44
- kadence board --json the whole board
45
- kadence task list --json all tasks
46
- kadence task move KAD-1 done change state
47
-
48
- \`--json\` responses carry \`schema: "kadence/v1"\`; stdout is JSON only.
49
- When acting as an agent, set \`KADENCE_SOURCE=agent\`.
50
-
51
- Details: \`.kadence/README.md\`
52
- ${R}`;function Ce(n){if(n===null||n.trim().length===0)return`${j}
53
- `;let t=n.indexOf(we),s=n.indexOf(R);if(t!==-1&&s!==-1&&s>t){let a=n.slice(0,t),i=n.slice(s+R.length);return`${a}${j}${i}`}let e=n.endsWith(`
54
- `)?`
55
- `:`
56
-
57
- `;return`${n}${e}${j}
58
- `}var De=".kadence/state.json";function Ee(n){let t=F(n);if(t===null)return{ok:!1,alreadyInitialized:!1,root:null,message:`kadence lives inside a git repository, and there is none here.
9
+ `))}outputVersion(){let{name:n}=this.cli,{versionNumber:t}=this.cli.globalCommand;t&&console.info(`${n}/${t} ${$}`)}checkRequiredArgs(){let n=this.args.filter(t=>t.required).length;if(this.cli.args.length<n)throw new D(`missing required args for command \`${this.rawName}\``)}checkUnknownOptions(){let{options:n,globalCommand:t}=this.cli;if(!this.config.allowUnknownOptions){for(let s of Object.keys(n))if(s!=="--"&&!this.hasOption(s)&&!t.hasOption(s))throw new D(`Unknown option \`${s.length>1?`--${s}`:`-${s}`}\``)}}checkOptionValue(){let{options:n,globalCommand:t}=this.cli,s=[...t.options,...this.options];for(let e of s){let i=n[e.name.split(".")[0]];if(e.required){let a=s.some(r=>r.negated&&r.names.includes(e.name));if(i===!0||i===!1&&!a)throw new D(`option \`${e.rawName}\` value is missing`)}}}checkUnusedArgs(){let n=this.args.some(t=>t.variadic)?1/0:this.args.length;if(n<this.cli.args.length)throw new D(`Unused args: ${this.cli.args.slice(n).map(t=>`\`${t}\``).join(", ")}`)}},we=class extends Ae{constructor(n){super("@@global@@","",{},n)}},Ve=class extends EventTarget{name;commands;globalCommand;matchedCommand;matchedCommandName;rawArgs;args;options;showHelpOnExit;showVersionOnExit;constructor(n=""){super(),this.name=n,this.commands=[],this.rawArgs=[],this.args=[],this.options={},this.globalCommand=new we(this),this.globalCommand.usage("<command> [options]")}usage(n){return this.globalCommand.usage(n),this}command(n,t,s){let e=new Ae(n,t||"",s,this);return e.globalCommand=this.globalCommand,this.commands.push(e),e}option(n,t,s){return this.globalCommand.option(n,t,s),this}help(n){return this.globalCommand.option("-h, --help","Display this message"),this.globalCommand.helpCallback=n,this.showHelpOnExit=!0,this}version(n,t="-v, --version"){return this.globalCommand.version(n,t),this.showVersionOnExit=!0,this}example(n){return this.globalCommand.example(n),this}outputHelp(){this.matchedCommand?this.matchedCommand.outputHelp():this.globalCommand.outputHelp()}outputVersion(){this.globalCommand.outputVersion()}setParsedInfo({args:n,options:t},s,e){return this.args=n,this.options=t,s&&(this.matchedCommand=s),e&&(this.matchedCommandName=e),this}unsetMatchedCommand(){this.matchedCommand=void 0,this.matchedCommandName=void 0}parse(n,{run:t=!0}={}){if(!n){if(!R)throw new Error("No argv provided and runtime process argv is not available.");n=R}this.rawArgs=n,this.name||(this.name=n[1]?Ye(n[1]):"cli");let s=!0;for(let i of this.commands){let a=this.mri(n.slice(2),i),r=a.args[0];if(i.isMatched(r)){s=!1;let d={...a,args:a.args.slice(1)};this.setParsedInfo(d,i,r),this.dispatchEvent(new CustomEvent(`command:${r}`,{detail:i}))}}if(s){for(let i of this.commands)if(i.isDefaultCommand){s=!1;let a=this.mri(n.slice(2),i);this.setParsedInfo(a,i),this.dispatchEvent(new CustomEvent("command:!",{detail:i}))}}if(s){let i=this.mri(n.slice(2));this.setParsedInfo(i)}this.options.help&&this.showHelpOnExit&&(this.outputHelp(),t=!1,this.unsetMatchedCommand()),this.options.version&&this.showVersionOnExit&&this.matchedCommandName==null&&(this.outputVersion(),t=!1,this.unsetMatchedCommand());let e={args:this.args,options:this.options};return t&&this.runMatchedCommand(),!this.matchedCommand&&this.args[0]&&this.dispatchEvent(new CustomEvent("command:*",{detail:this.args[0]})),e}mri(n,t){let s=[...this.globalCommand.options,...t?t.options:[]],e=Fe(s),i=[],a=n.indexOf("--");a!==-1&&(i=n.slice(a+1),n=n.slice(0,a));let r=Be(n,e);r=Object.keys(r).reduce((m,k)=>({...m,[ve(k)]:r[k]}),{_:[]});let d=r._,o={"--":i},l=t&&t.config.ignoreOptionDefaultValue?t.config.ignoreOptionDefaultValue:this.globalCommand.config.ignoreOptionDefaultValue,u=Object.create(null);for(let m of s){if(!l&&m.config.default!==void 0)for(let k of m.names)o[k]=m.config.default;Array.isArray(m.config.type)&&u[m.name]===void 0&&(u[m.name]=Object.create(null),u[m.name].shouldTransform=!0,u[m.name].transformFunction=m.config.type[0])}for(let m of Object.keys(r))m!=="_"&&(Ue(o,m.split("."),r[m]),qe(o,u));return{args:d,options:o}}runMatchedCommand(){let{args:n,options:t,matchedCommand:s}=this;if(!s||!s.commandAction)return;s.checkUnknownOptions(),s.checkOptionValue(),s.checkRequiredArgs(),s.checkUnusedArgs();let e=[];return s.args.forEach((i,a)=>{i.variadic?e.push(n.slice(a)):e.push(n[a])}),e.push(t),s.commandAction.apply(this,e)}},Ce=(n="")=>new Ve(n);import{existsSync as S,mkdirSync as We,readFileSync as $e,writeFileSync as _}from"node:fs";import{join as I}from"node:path";var De=".kadence/state.json",Ge=["AGENTS.md","CLAUDE.md"];function Se(n){let t=F(n);if(t===null)return{ok:!1,alreadyInitialized:!1,root:null,message:`kadence lives inside a git repository, and there is none here.
59
10
  Create one and try again:
60
- git init`};let s=C($(t));Ge($(t),{recursive:!0}),Ve(t);let e=I(U(t),"README.md");return C(e)||_(e,xe,"utf8"),Je(t),{ok:!0,alreadyInitialized:s,root:t,message:s?"kadence is already initialised.":`kadence is ready.
11
+ git init`};let s=S(E(t));We(E(t),{recursive:!0}),Je(t);let e=I(L(t),"README.md");S(e)||_(e,U,"utf8");for(let i of Ge)He(t,i);return{ok:!0,alreadyInitialized:s,root:t,message:s?"kadence is already initialised.":`kadence is ready.
61
12
 
62
13
  kadence task add "first task"
63
14
  kadence board
64
15
 
65
- Files were created but not committed \u2014 that call is yours.`}}function Ve(n){let t=I(n,".gitignore"),s="";if(C(t)&&(s=$e(t,"utf8")),s.includes(De))return;let e=s.length>0&&!s.endsWith(`
16
+ Files were created but not committed \u2014 that call is yours.`}}function Je(n){let t=I(n,".gitignore"),s="";if(S(t)&&(s=$e(t,"utf8")),s.includes(De))return;let e=s.length>0&&!s.endsWith(`
66
17
  `)?`
67
18
  `:"";_(t,`${s}${e}${De}
68
- `,"utf8")}function Je(n){let t=I(n,"AGENTS.md"),s=C(t)?$e(t,"utf8"):null,e=Ce(s);e!==s&&_(t,e,"utf8")}var B="cancelled";function Se(n,t,s){let e=k(n,t);if(!b(e))return e;let{state:a,warnings:i}=y(e.root,e.actor),r=a.tasks.filter(u=>u.status!==B);if(s.assignee!==void 0){let u=s.assignee.toLowerCase(),m=u==="me"?e.actor.toLowerCase():u;r=r.filter(p=>(p.assignee??"").toLowerCase()===m)}if(s.sprint==="active"){let u=a.sprints.find(m=>m.status==="active"||m.status==="planned");r=u===void 0?[]:r.filter(m=>m.sprint===u.id)}let d={};for(let u of a.statuses)u!==B&&(d[u]=r.filter(m=>m.status===u));let o=a.orphanStatuses.filter(u=>u!==B);for(let u of o)d[u]=r.filter(m=>m.status===u);let l=o.length>0?[`Statuses not in the board configuration: ${o.join(", ")}.
19
+ `,"utf8")}function He(n,t){let s=I(n,t),e=S(s)?$e(s,"utf8"):null,i=q(e);i!==e&&_(s,i,"utf8")}import{writeSync as Qe}from"node:fs";var B="cancelled";function Ee(n,t,s,e){let i=y(n,t);if(!x(i))return i;let{fields:a,error:r}=Z(e);if(r!==null)return r;let{state:d,warnings:o}=v(i.root,i.actor),l=d.tasks.filter(p=>p.status!==B);if(s.assignee!==void 0){let p=s.assignee.toLowerCase(),h=p==="me"?i.actor.toLowerCase():p;l=l.filter(w=>(w.assignee??"").toLowerCase()===h)}if(s.sprint==="active"){let p=d.sprints.find(h=>h.status==="active"||h.status==="planned");l=p===void 0?[]:l.filter(h=>h.sprint===p.id)}let u={};for(let p of d.statuses)p!==B&&(u[p]=l.filter(h=>h.status===p));let m=d.orphanStatuses.filter(p=>p!==B);for(let p of m)u[p]=l.filter(h=>h.status===p);let k=m.length>0?[`Statuses not in the board configuration: ${m.join(", ")}.
69
20
  Tasks there are still shown. Add the column or move them:
70
- kadence board config --statuses "..."`]:[];return{ok:!0,exitCode:0,warnings:[...i,...l],message:G(d,Y(t,process.stdout.isTTY===!0)),data:{schema:"kadence/v1",ok:!0,columns:Object.fromEntries(Object.entries(d).map(([u,m])=>[u,m.map(Q)]))}}}function Oe(n,t,s){let e=k(n,t);if(!b(e))return e;let{state:a,warnings:i}=y(e.root,e.actor);if(s===void 0)return{ok:!0,exitCode:0,warnings:i,message:`Board columns: ${a.statuses.join(", ")}
21
+ kadence board config --statuses "..."`]:[];return{ok:!0,exitCode:0,warnings:[...o,...k],message:J(u,G(t,process.stdout.isTTY===!0)),data:{schema:"kadence/v1",ok:!0,columns:Object.fromEntries(Object.entries(u).map(([p,h])=>[p,h.map(w=>ee(w,a))]))}}}function Oe(n,t,s){let e=y(n,t);if(!x(e))return e;let{state:i,warnings:a}=v(e.root,e.actor);if(s===void 0)return{ok:!0,exitCode:0,warnings:a,message:`Board columns: ${i.statuses.join(", ")}
71
22
 
72
23
  Change them with:
73
- kadence board config --statuses "todo,doing,review,done"`,data:{schema:"kadence/v1",ok:!0,statuses:a.statuses}};let r=s.split(",").map(l=>l.trim().toLowerCase().replace(/\s+/g,"_")).filter(l=>l.length>0);if(r.length===0)return{ok:!1,exitCode:2,message:"At least one status is required."};if(new Set(r).size!==r.length)return{ok:!1,exitCode:2,message:"The same status is listed twice."};if(!r.includes(E))return{ok:!1,exitCode:2,message:`The list must include "${E}" \u2014 velocity and burndown are computed from it.`};let d=a.tasks.filter(l=>!r.includes(l.status)&&l.status!==q);A(e.root,{id:g(),type:"board.configured",entity:g(),actor:e.actor,ts:new Date().toISOString(),source:e.source,data:{statuses:r}});let o=d.length>0?`
74
- ${d.length} task(s) remain in removed columns: ${[...new Set(d.map(l=>l.status))].join(", ")}. They are still listed.`:"";return{ok:!0,exitCode:0,warnings:i,message:`Board columns: ${r.join(", ")}${o}`,data:{schema:"kadence/v1",ok:!0,statuses:r}}}var He=["description","type","priority","estimate","labels","assignee"];function Te(n,t,s,e){let a=k(n,t);if(!b(a))return a;let i=s.trim();if(i.length===0)return{ok:!1,exitCode:2,message:"A template needs a name."};let r={};for(let d of He)e[d]!==void 0&&(r[d]=e[d]);return Object.keys(r).length===0?{ok:!1,exitCode:2,message:`A template needs at least one field.
75
- kadence template save bug --type bug --priority high --label triage`}:(A(a.root,{id:g(),type:"template.saved",entity:g(),actor:a.actor,ts:new Date().toISOString(),source:a.source,data:{name:i,fields:r}}),{ok:!0,exitCode:0,message:`Template "${i}" saved: ${Object.keys(r).join(", ")}.
76
- kadence task add "title" --template ${i}`,data:{schema:"kadence/v1",ok:!0,template:{name:i,fields:r}}})}function Ke(n,t){let s=k(n,t);if(!b(s))return s;let{state:e,warnings:a}=y(s.root,s.actor);return e.templates.length===0?{ok:!0,exitCode:0,warnings:a,message:`No templates yet.
77
- kadence template save bug --type bug --priority high`,data:{schema:"kadence/v1",ok:!0,templates:[]}}:{ok:!0,exitCode:0,warnings:a,message:e.templates.map(i=>{let r=Object.entries(i.fields).map(([d,o])=>`${d}=${Array.isArray(o)?o.join("/"):String(o)}`).join(" ");return` ${i.name.padEnd(14)} ${r}`}).join(`
78
- `),data:{schema:"kadence/v1",ok:!0,templates:e.templates}}}function Ne(n,t,s){let e=k(n,t);if(!b(e))return e;let{state:a,warnings:i}=y(e.root,e.actor);return a.templates.some(r=>r.name===s)?(A(e.root,{id:g(),type:"template.deleted",entity:g(),actor:e.actor,ts:new Date().toISOString(),source:e.source,data:{name:s}}),{ok:!0,exitCode:0,warnings:i,message:`Template "${s}" deleted.`}):{ok:!1,exitCode:1,message:`No template "${s}".
79
- kadence template list`}}function je(n,t,s){let e=k(n,t);if(!b(e))return{error:e};let{state:a}=y(e.root,e.actor),i=a.templates.find(r=>r.name===s);if(i===void 0){let r=a.templates.map(d=>d.name).join(", ");return{error:{ok:!1,exitCode:1,message:`No template "${s}".`+(r.length>0?`
24
+ kadence board config --statuses "todo,doing,review,done"`,data:{schema:"kadence/v1",ok:!0,statuses:i.statuses}};let r=s.split(",").map(l=>l.trim().toLowerCase().replace(/\s+/g,"_")).filter(l=>l.length>0);if(r.length===0)return{ok:!1,exitCode:2,message:"At least one status is required."};if(new Set(r).size!==r.length)return{ok:!1,exitCode:2,message:"The same status is listed twice."};if(!r.includes(O))return{ok:!1,exitCode:2,message:`The list must include "${O}" \u2014 velocity and burndown are computed from it.`};let d=i.tasks.filter(l=>!r.includes(l.status)&&l.status!==P);C(e.root,{id:b(),type:"board.configured",entity:b(),actor:e.actor,ts:new Date().toISOString(),source:e.source,data:{statuses:r}});let o=d.length>0?`
25
+ ${d.length} task(s) remain in removed columns: ${[...new Set(d.map(l=>l.status))].join(", ")}. They are still listed.`:"";return{ok:!0,exitCode:0,warnings:a,message:`Board columns: ${r.join(", ")}${o}`,data:{schema:"kadence/v1",ok:!0,statuses:r}}}var ze=["description","type","priority","estimate","labels","assignee"];function Te(n,t,s,e){let i=y(n,t);if(!x(i))return i;let a=s.trim();if(a.length===0)return{ok:!1,exitCode:2,message:"A template needs a name."};let r={};for(let d of ze)e[d]!==void 0&&(r[d]=e[d]);return Object.keys(r).length===0?{ok:!1,exitCode:2,message:`A template needs at least one field.
26
+ kadence template save bug --type bug --priority high --label triage`}:(C(i.root,{id:b(),type:"template.saved",entity:b(),actor:i.actor,ts:new Date().toISOString(),source:i.source,data:{name:a,fields:r}}),{ok:!0,exitCode:0,message:`Template "${a}" saved: ${Object.keys(r).join(", ")}.
27
+ kadence task add "title" --template ${a}`,data:{schema:"kadence/v1",ok:!0,template:{name:a,fields:r}}})}function je(n,t){let s=y(n,t);if(!x(s))return s;let{state:e,warnings:i}=v(s.root,s.actor);return e.templates.length===0?{ok:!0,exitCode:0,warnings:i,message:`No templates yet.
28
+ kadence template save bug --type bug --priority high`,data:{schema:"kadence/v1",ok:!0,templates:[]}}:{ok:!0,exitCode:0,warnings:i,message:e.templates.map(a=>{let r=Object.entries(a.fields).map(([d,o])=>`${d}=${Array.isArray(o)?o.join("/"):String(o)}`).join(" ");return` ${a.name.padEnd(14)} ${r}`}).join(`
29
+ `),data:{schema:"kadence/v1",ok:!0,templates:e.templates}}}function Ke(n,t,s){let e=y(n,t);if(!x(e))return e;let{state:i,warnings:a}=v(e.root,e.actor);return i.templates.some(r=>r.name===s)?(C(e.root,{id:b(),type:"template.deleted",entity:b(),actor:e.actor,ts:new Date().toISOString(),source:e.source,data:{name:s}}),{ok:!0,exitCode:0,warnings:a,message:`Template "${s}" deleted.`}):{ok:!1,exitCode:1,message:`No template "${s}".
30
+ kadence template list`}}function Ne(n,t,s){let e=y(n,t);if(!x(e))return{error:e};let{state:i}=v(e.root,e.actor),a=i.templates.find(r=>r.name===s);if(a===void 0){let r=i.templates.map(d=>d.name).join(", ");return{error:{ok:!1,exitCode:1,message:`No template "${s}".`+(r.length>0?`
80
31
  Available: ${r}`:`
81
- kadence template save ...`)}}}return{fields:i.fields}}var h=Ae("kadence");function c(n,t){for(let s of n.warnings??[])process.stderr.write(`${s}
82
- `);if(t){let s=n.data??{schema:"kadence/v1",ok:n.ok,...n.ok?{}:{error:{message:n.message}}};process.stdout.write(`${JSON.stringify(s)}
83
- `)}else(n.ok?process.stdout:process.stderr).write(`${n.message}
84
- `);process.exit(n.exitCode)}function Re(n,t,s,e){if(n!==void 0)return n;re(process.env,process.stdout.isTTY===!0)||c(f(`No terminal available for an editor.
32
+ kadence template save ...`)}}}return{fields:a.fields}}function M(n,t){let s=Buffer.from(t,"utf8"),e=0;for(;e<s.length;)try{e+=Qe(n,s,e,s.length-e)}catch(i){if(i.code!=="EAGAIN")throw i}}var g=Ce("kadence");function c(n,t){for(let s of n.warnings??[])M(2,`${s}
33
+ `);if(t){let s=n.data??{schema:"kadence/v1",ok:n.ok,...n.ok?{}:{error:n.error??{message:n.message}}};M(1,`${JSON.stringify(s)}
34
+ `)}else M(n.ok?1:2,`${n.message}
35
+ `);process.exit(n.exitCode)}function Re(n,t,s,e){if(n!==void 0)return n;ce(process.env,process.stdout.isTTY===!0)||c(f(`No terminal available for an editor.
85
36
  Pass the text directly:
86
- --description "..."`),e);let a=ie(process.env,t,s);return a.error!==null&&c({ok:!1,exitCode:1,message:a.error},e),a.text===null&&c({ok:!0,exitCode:0,message:"Aborted \u2014 nothing changed."},e),a.text}function f(n){return{ok:!1,exitCode:2,message:n}}h.command("init","Set up kadence in this repository").example(" kadence init").action(()=>{let n=Ee(process.cwd());c({ok:n.ok,message:n.message,exitCode:n.ok?0:1},!1)});h.command("task [action] [arg] [value]","Tasks: add | list | show | move | assign").option("--title <text>","New title (for edit)").option("-d, --description <text>","Full description; use quotes for multiple lines").option("--type <type>",`Type: ${W.join(" | ")}`).option("--priority <level>",`Priority: ${P.join(" | ")}`).option("-a, --assignee <who>","Assignee, e.g. dev@example.com").option("--label <name>","Label; repeat the flag for several").option("--estimate <points>","Estimate in points, a positive number").option("--due <date>","Due date, YYYY-MM-DD; empty string clears it").option("--status <status>",`Filter by status: ${S.join(" | ")}`).option("--search <text>","Search title, description and comments").option("--overdue","Only tasks past their due date").option("--due-before <date>","Only tasks due before YYYY-MM-DD").option("--sort <key>",`Sort by: ${V.join(" | ")}`).option("--tree","Show parent/child structure").option("--parent <task>",'Parent task, e.g. KAD-1 (use "none" to detach)').option("--template <name>","Pre-fill fields from a saved template").option("--json","Machine-readable output for agents").example(' kadence task add "Fix login" -d "Broken since 2.3" --type bug --priority high --estimate 3').example(" kadence task list --status in_progress --sort priority").example(" kadence task list --search cookie --overdue").example(" kadence task list --assignee me --label auth").example(" kadence task list --tree").example(" kadence task move KAD-1,KAD-2,KAD-3 done bulk: all or nothing").example(' kadence task add "Login form" --parent KAD-1 KAD-1 can be an epic').example(" kadence task parent KAD-2 KAD-1").example(" kadence task block KAD-2 KAD-1 KAD-2 waits for KAD-1").example(" kadence task unblock KAD-2 KAD-1").example(" kadence task log KAD-1 2h also 90m, or -30m to correct").example(' kadence task add "Crash on save" --template bug').example(" kadence task show KAD-1").example(" kadence task move KAD-1 done").example(" kadence task edit KAD-1 --priority urgent --due 2026-09-30").example(" kadence task edit KAD-1 opens $EDITOR for the description").example(' kadence task comment KAD-1 "Needs review"').example(' kadence task assign KAD-1 dev@example.com (use "none" to unassign)').example(" kadence task cancel KAD-1 keeps it in history").example(" kadence task delete KAD-1 drops it from the board").action((n,t,s,e)=>{let a=e.json===!0,i=process.cwd();switch(n===void 0&&c(f(`Which action?
37
+ --description "..."`),e);let i=de(process.env,t,s);return i.error!==null&&c({ok:!1,exitCode:1,message:i.error},e),i.text===null&&c({ok:!0,exitCode:0,message:"Aborted \u2014 nothing changed."},e),i.text}function f(n){return{ok:!1,exitCode:2,message:n}}function Xe(n){let t=n.commands,s=n.errors;return`kadence/v1 \u2014 ${t.length} commands, ${s.length} error codes.
38
+ ${n.stability}
39
+
40
+ The machine-readable form is what agents read:
41
+ kadence schema --json`}g.command("schema","The machine-readable --json contract, for agents").option("--json","Machine-readable output for agents").example(" kadence schema --json").action(n=>{let t=n.json===!0,s=Y("0.2.1");c({ok:!0,exitCode:0,message:Xe(s),data:{schema:"kadence/v1",ok:!0,contract:s}},t)});g.command("init","Set up kadence in this repository").example(" kadence init").action(()=>{let n=Se(process.cwd());c({ok:n.ok,message:n.message,exitCode:n.ok?0:1},!1)});g.command("task [action] [arg] [value]","Tasks: add | list | show | move | assign").option("--title <text>","New title (for edit)").option("-d, --description <text>","Full description; use quotes for multiple lines").option("--type <type>",`Type: ${V.join(" | ")}`).option("--priority <level>",`Priority: ${W.join(" | ")}`).option("-a, --assignee <who>","Assignee, e.g. dev@example.com").option("--label <name>","Label; repeat the flag for several").option("--estimate <points>","Estimate in points, a positive number").option("--due <date>","Due date, YYYY-MM-DD; empty string clears it").option("--status <status>",`Filter by status: ${T.join(" | ")}`).option("--search <text>","Search title, description and comments").option("--overdue","Only tasks past their due date").option("--due-before <date>","Only tasks due before YYYY-MM-DD").option("--sort <key>",`Sort by: ${H.join(" | ")}`).option("--tree","Show parent/child structure").option("--parent <task>",'Parent task, e.g. KAD-1 (use "none" to detach)').option("--template <name>","Pre-fill fields from a saved template").option("--fields <list>","JSON only: comma-separated task fields to return").option("--json","Machine-readable output for agents").example(' kadence task add "Fix login" -d "Broken since 2.3" --type bug --priority high --estimate 3').example(" kadence task list --status in_progress --sort priority").example(" kadence task list --search cookie --overdue").example(" kadence task list --assignee me --label auth").example(" kadence task list --tree").example(" kadence task list --json --fields id,label,status").example(" kadence task move KAD-1,KAD-2,KAD-3 done bulk: all or nothing").example(' kadence task add "Login form" --parent KAD-1 KAD-1 can be an epic').example(" kadence task parent KAD-2 KAD-1").example(" kadence task block KAD-2 KAD-1 KAD-2 waits for KAD-1").example(" kadence task unblock KAD-2 KAD-1").example(" kadence task log KAD-1 2h also 90m, or -30m to correct").example(' kadence task add "Crash on save" --template bug').example(" kadence task show KAD-1").example(" kadence task move KAD-1 done").example(" kadence task edit KAD-1 --priority urgent --due 2026-09-30").example(" kadence task edit KAD-1 opens $EDITOR for the description").example(' kadence task comment KAD-1 "Needs review"').example(' kadence task assign KAD-1 dev@example.com (use "none" to unassign)').example(" kadence task cancel KAD-1 keeps it in history").example(" kadence task delete KAD-1 drops it from the board").action((n,t,s,e)=>{let i=e.json===!0,a=process.cwd();switch(n===void 0&&c(f(`Which action?
87
42
  kadence task add "Fix login"
88
43
  kadence task list
89
44
  kadence task show KAD-1
@@ -92,29 +47,29 @@ Pass the text directly:
92
47
  kadence task assign KAD-1 dev@example.com
93
48
  kadence task comment KAD-1 "text"
94
49
  kadence task cancel KAD-1
95
- kadence task delete KAD-1`),a),n){case"add":{t===void 0&&c(f(`A title is required:
96
- kadence task add "Fix login"`),a);let r=e.estimate===void 0?void 0:Number(e.estimate);r!==void 0&&(!Number.isFinite(r)||r<0)&&c(f(`Estimate must be a positive number, got "${e.estimate}".
97
- kadence task add "Fix login" --estimate 3`),a);let d={};if(e.template!==void 0){let l=je(i,process.env,e.template);"error"in l?c(l.error,a):d=l.fields}let o=e.label===void 0?void 0:Array.isArray(e.label)?e.label:[e.label];c(J(i,process.env,t,{...d,...e.description!==void 0?{description:e.description}:{},...e.type!==void 0?{type:e.type}:{},...e.priority!==void 0?{priority:e.priority}:{},...e.assignee!==void 0?{assignee:e.assignee}:{},...o!==void 0?{labels:o}:{},...e.due!==void 0?{due:e.due}:{},...e.parent!==void 0?{parent:e.parent}:{},...r!==void 0?{estimate:r}:{}}),a);break}case"log":(t===void 0||s===void 0)&&c(f(`A task and a duration are required:
50
+ kadence task delete KAD-1`),i),n){case"add":{t===void 0&&c(f(`A title is required:
51
+ kadence task add "Fix login"`),i);let r=e.estimate===void 0?void 0:Number(e.estimate);r!==void 0&&(!Number.isFinite(r)||r<0)&&c(f(`Estimate must be a positive number, got "${e.estimate}".
52
+ kadence task add "Fix login" --estimate 3`),i);let d={};if(e.template!==void 0){let l=Ne(a,process.env,e.template);"error"in l?c(l.error,i):d=l.fields}let o=e.label===void 0?void 0:Array.isArray(e.label)?e.label:[e.label];c(z(a,process.env,t,{...d,...e.description!==void 0?{description:e.description}:{},...e.type!==void 0?{type:e.type}:{},...e.priority!==void 0?{priority:e.priority}:{},...e.assignee!==void 0?{assignee:e.assignee}:{},...o!==void 0?{labels:o}:{},...e.due!==void 0?{due:e.due}:{},...e.parent!==void 0?{parent:e.parent}:{},...r!==void 0?{estimate:r}:{}}),i);break}case"log":(t===void 0||s===void 0)&&c(f(`A task and a duration are required:
98
53
  kadence task log KAD-1 2h
99
- kadence task log KAD-1 90m`),a),c(T(i,process.env,t,s),a);break;case"parent":(t===void 0||s===void 0)&&c(f(`A task and a parent are required:
54
+ kadence task log KAD-1 90m`),i),c(K(a,process.env,t,s),i);break;case"parent":(t===void 0||s===void 0)&&c(f(`A task and a parent are required:
100
55
  kadence task parent KAD-2 KAD-1
101
- kadence task parent KAD-2 none to detach`),a),c(se(i,process.env,t,s),a);break;case"block":case"unblock":(t===void 0||s===void 0)&&c(f(`A task and a blocker are required:
56
+ kadence task parent KAD-2 none to detach`),i),c(re(a,process.env,t,s),i);break;case"block":case"unblock":(t===void 0||s===void 0)&&c(f(`A task and a blocker are required:
102
57
  kadence task block KAD-2 KAD-1 KAD-2 waits for KAD-1
103
- kadence task unblock KAD-2 KAD-1`),a),c(ae(i,process.env,t,s,n==="unblock"),a);break;case"edit":{t===void 0&&c(f(`Which task?
104
- kadence task edit KAD-1 --priority high`),a);let r=e.estimate===void 0?void 0:Number(e.estimate);r!==void 0&&(!Number.isFinite(r)||r<0)&&c(f(`Estimate must be a positive number, got "${e.estimate}".`),a);let d=e.label===void 0?void 0:Array.isArray(e.label)?e.label:[e.label],o=e.title!==void 0||e.description!==void 0||e.type!==void 0||e.priority!==void 0||e.due!==void 0||r!==void 0||d!==void 0||s!==void 0,l=e.description;if(!o){let u=O(i,process.env,t);u.ok||c(u,a);let m=u.data.task??{description:null};l=Re(void 0,m.description??"",`Editing the description of ${t}.`,a)}c(Z(i,process.env,t,{...e.title!==void 0?{title:e.title}:s!==void 0?{title:s}:{},...l!==void 0?{description:l}:{},...e.type!==void 0?{type:e.type}:{},...e.priority!==void 0?{priority:e.priority}:{},...e.due!==void 0?{due:e.due}:{},...r!==void 0?{estimate:r}:{},...d!==void 0?{labels:d}:{}}),a);break}case"comment":{t===void 0&&c(f(`Which task?
105
- kadence task comment KAD-1 "text"`),a);let r=Re(s,"",`Comment on ${t}.`,a);c(ne(i,process.env,t,r??""),a);break}case"cancel":t===void 0&&c(f(`Which task?
106
- kadence task cancel KAD-1`),a),c(ee(i,process.env,t),a);break;case"delete":t===void 0&&c(f(`Which task?
107
- kadence task delete KAD-1`),a),c(te(i,process.env,t),a);break;case"list":c(H(i,process.env,{...e.status!==void 0?{status:e.status}:{},...e.search!==void 0?{search:e.search}:{},...e.type!==void 0?{type:e.type}:{},...e.priority!==void 0?{priority:e.priority}:{},...e.assignee!==void 0?{assignee:e.assignee}:{},...e.label!==void 0?{label:Array.isArray(e.label)?e.label.at(-1):e.label}:{},...e.overdue===!0?{overdue:!0}:{},...e.dueBefore!==void 0?{dueBefore:e.dueBefore}:{},...e.sort!==void 0?{sort:e.sort}:{},...e.tree===!0?{tree:!0}:{}}),a);break;case"show":t===void 0&&c(f(`Which task?
108
- kadence task show KAD-1`),a),c(O(i,process.env,t),a);break;case"move":(t===void 0||s===void 0)&&c(f(`A task and a target status are required:
58
+ kadence task unblock KAD-2 KAD-1`),i),c(oe(a,process.env,t,s,n==="unblock"),i);break;case"edit":{t===void 0&&c(f(`Which task?
59
+ kadence task edit KAD-1 --priority high`),i);let r=e.estimate===void 0?void 0:Number(e.estimate);r!==void 0&&(!Number.isFinite(r)||r<0)&&c(f(`Estimate must be a positive number, got "${e.estimate}".`),i);let d=e.label===void 0?void 0:Array.isArray(e.label)?e.label:[e.label],o=e.title!==void 0||e.description!==void 0||e.type!==void 0||e.priority!==void 0||e.due!==void 0||r!==void 0||d!==void 0||s!==void 0,l=e.description;if(!o){let u=j(a,process.env,t);u.ok||c(u,i);let m=u.data.task??{description:null};l=Re(void 0,m.description??"",`Editing the description of ${t}.`,i)}c(ne(a,process.env,t,{...e.title!==void 0?{title:e.title}:s!==void 0?{title:s}:{},...l!==void 0?{description:l}:{},...e.type!==void 0?{type:e.type}:{},...e.priority!==void 0?{priority:e.priority}:{},...e.due!==void 0?{due:e.due}:{},...r!==void 0?{estimate:r}:{},...d!==void 0?{labels:d}:{}}),i);break}case"comment":{t===void 0&&c(f(`Which task?
60
+ kadence task comment KAD-1 "text"`),i);let r=Re(s,"",`Comment on ${t}.`,i);c(ae(a,process.env,t,r??""),i);break}case"cancel":t===void 0&&c(f(`Which task?
61
+ kadence task cancel KAD-1`),i),c(se(a,process.env,t),i);break;case"delete":t===void 0&&c(f(`Which task?
62
+ kadence task delete KAD-1`),i),c(ie(a,process.env,t),i);break;case"list":c(Q(a,process.env,{...e.status!==void 0?{status:e.status}:{},...e.search!==void 0?{search:e.search}:{},...e.type!==void 0?{type:e.type}:{},...e.priority!==void 0?{priority:e.priority}:{},...e.assignee!==void 0?{assignee:e.assignee}:{},...e.label!==void 0?{label:Array.isArray(e.label)?e.label.at(-1):e.label}:{},...e.overdue===!0?{overdue:!0}:{},...e.dueBefore!==void 0?{dueBefore:e.dueBefore}:{},...e.sort!==void 0?{sort:e.sort}:{},...e.tree===!0?{tree:!0}:{},...i&&e.fields!==void 0?{fields:e.fields}:{}}),i);break;case"show":t===void 0&&c(f(`Which task?
63
+ kadence task show KAD-1`),i),c(j(a,process.env,t),i);break;case"move":(t===void 0||s===void 0)&&c(f(`A task and a target status are required:
109
64
  kadence task move KAD-1 done
110
- Statuses: ${S.join(", ")}`),a),c(z(i,process.env,t,s),a);break;case"assign":(t===void 0||s===void 0)&&c(f(`A task and an assignee are required:
65
+ Statuses: ${T.join(", ")}`),i),c(X(a,process.env,t,s),i);break;case"assign":(t===void 0||s===void 0)&&c(f(`A task and an assignee are required:
111
66
  kadence task assign KAD-1 dev@example.com
112
- kadence task assign KAD-1 none to unassign`),a),c(X(i,process.env,t,s),a);break;default:c(f(`Unknown action "${n}".
67
+ kadence task assign KAD-1 none to unassign`),i),c(te(a,process.env,t,s),i);break;default:c(f(`Unknown action "${n}".
113
68
  Available: add, list, show, edit, move, assign, comment, log,
114
69
  parent, block, unblock, cancel, delete
115
- kadence task --help`),a)}});h.command("board [action]",'Kanban board in the terminal; "config" edits the columns').option("--statuses <list>",'Comma-separated columns, e.g. "todo,doing,done"').option("-a, --assignee <who>",`Only this person's tasks; "me" means you`).option("--sprint","Only tasks in the active sprint").option("--json","Machine-readable output for agents").example(" kadence board").example(" kadence board --assignee me --sprint").example(" kadence board config").example(' kadence board config --statuses "todo,doing,review,done"').action((n,t)=>{n==="config"&&c(Oe(process.cwd(),process.env,t.statuses),t.json===!0),n!==void 0&&c(f(`Unknown action "${n}".
70
+ kadence task --help`),i)}});g.command("board [action]",'Kanban board in the terminal; "config" edits the columns').option("--fields <list>","JSON only: comma-separated task fields to return").option("--statuses <list>",'Comma-separated columns, e.g. "todo,doing,done"').option("-a, --assignee <who>",`Only this person's tasks; "me" means you`).option("--sprint","Only tasks in the active sprint").option("--json","Machine-readable output for agents").example(" kadence board").example(" kadence board --assignee me --sprint").example(" kadence board --json --fields label,status,assignee").example(" kadence board config").example(' kadence board config --statuses "todo,doing,review,done"').action((n,t)=>{n==="config"&&c(Oe(process.cwd(),process.env,t.statuses),t.json===!0),n!==void 0&&c(f(`Unknown action "${n}".
116
71
  Available: config
117
- kadence board --help`),t.json===!0),c(Se(process.cwd(),process.env,{...t.assignee!==void 0?{assignee:t.assignee}:{},...t.sprint===!0?{sprint:"active"}:{}}),t.json===!0)});h.command("sprint [action] [name]","Sprints: create | add | edit | start | close | status | list | burndown").option("--sprint <name>","Which sprint to add to; defaults to the active one").option("--name <name>","New name (for edit)").option("-d, --description <text>","Sprint description (for edit)").option("--start <date>","Start date, YYYY-MM-DD").option("--end <date>","End date, YYYY-MM-DD").option("--json","Machine-readable output for agents").example(' kadence sprint create "Sprint 1" first one starts right away').example(' kadence sprint create "Sprint 2" later ones are planned').example(' kadence sprint add KAD-1 --sprint "Sprint 2"').example(" kadence sprint start starts the next planned sprint").example(" kadence sprint edit --start 2026-09-01 --end 2026-09-14").example(' kadence sprint edit "Sprint 2" --name "Sprint 2: auth"').example(" kadence sprint burndown chart from the journal, any day").example(" kadence sprint close closes the active one, reports velocity").action((n,t,s)=>{let e=s.json===!0,a=process.cwd();switch(n===void 0&&c(f(`Which action?
72
+ kadence board --help`),t.json===!0),c(Ee(process.cwd(),process.env,{...t.assignee!==void 0?{assignee:t.assignee}:{},...t.sprint===!0?{sprint:"active"}:{}},t.json===!0?t.fields:void 0),t.json===!0)});g.command("sprint [action] [name]","Sprints: create | add | edit | start | close | status | list | burndown").option("--sprint <name>","Which sprint to add to; defaults to the active one").option("--name <name>","New name (for edit)").option("-d, --description <text>","Sprint description (for edit)").option("--start <date>","Start date, YYYY-MM-DD").option("--end <date>","End date, YYYY-MM-DD").option("--json","Machine-readable output for agents").example(' kadence sprint create "Sprint 1" first one starts right away').example(' kadence sprint create "Sprint 2" later ones are planned').example(' kadence sprint add KAD-1 --sprint "Sprint 2"').example(" kadence sprint start starts the next planned sprint").example(" kadence sprint edit --start 2026-09-01 --end 2026-09-14").example(' kadence sprint edit "Sprint 2" --name "Sprint 2: auth"').example(" kadence sprint burndown chart from the journal, any day").example(" kadence sprint close closes the active one, reports velocity").action((n,t,s)=>{let e=s.json===!0,i=process.cwd();switch(n===void 0&&c(f(`Which action?
118
73
  kadence sprint create "Sprint 1"
119
74
  kadence sprint add KAD-1
120
75
  kadence sprint edit --start 2026-09-01
@@ -122,14 +77,14 @@ Available: config
122
77
  kadence sprint close
123
78
  kadence sprint status
124
79
  kadence sprint list`),e),n){case"create":t===void 0&&c(f(`A sprint name is required:
125
- kadence sprint create "Sprint 1"`),e),c(oe(a,process.env,t),e);break;case"add":t===void 0&&c(f(`Which task?
80
+ kadence sprint create "Sprint 1"`),e),c(le(i,process.env,t),e);break;case"add":t===void 0&&c(f(`Which task?
126
81
  kadence sprint add KAD-1
127
- kadence sprint add KAD-1 --sprint "Sprint 2"`),e),c(de(a,process.env,t,s.sprint===void 0?{}:{sprint:s.sprint}),e);break;case"edit":c(fe(a,process.env,t,{...s.name!==void 0?{name:s.name}:{},...s.description!==void 0?{description:s.description}:{},...s.start!==void 0?{startDate:s.start}:{},...s.end!==void 0?{endDate:s.end}:{}}),e);break;case"start":c(ue(a,process.env,t),e);break;case"close":c(ce(a,process.env),e);break;case"status":c(le(a,process.env),e);break;case"list":c(me(a,process.env),e);break;case"burndown":c(pe(a,process.env,t),e);break;default:c(f(`Unknown action "${n}".
82
+ kadence sprint add KAD-1 --sprint "Sprint 2"`),e),c(ue(i,process.env,t,s.sprint===void 0?{}:{sprint:s.sprint}),e);break;case"edit":c(ge(i,process.env,t,{...s.name!==void 0?{name:s.name}:{},...s.description!==void 0?{description:s.description}:{},...s.start!==void 0?{startDate:s.start}:{},...s.end!==void 0?{endDate:s.end}:{}}),e);break;case"start":c(pe(i,process.env,t),e);break;case"close":c(me(i,process.env),e);break;case"status":c(fe(i,process.env),e);break;case"list":c(he(i,process.env),e);break;case"burndown":c(ke(i,process.env,t),e);break;default:c(f(`Unknown action "${n}".
128
83
  Available: create, add, edit, start, close, status, list, burndown
129
- kadence sprint --help`),e)}});h.command("template [action] [name]","Task templates: save | list | delete").option("-d, --description <text>","Default description").option("--type <type>","Default type").option("--priority <level>","Default priority").option("-a, --assignee <who>","Default assignee").option("--label <name>","Default label; repeat for several").option("--estimate <points>","Default estimate").option("--json","Machine-readable output for agents").example(" kadence template save bug --type bug --priority high --label triage").example(" kadence template list").action((n,t,s)=>{let e=s.json===!0,a=process.cwd();switch(n){case"save":{t===void 0&&c(f(`A template name is required:
130
- kadence template save bug --type bug`),e);let i=s.label===void 0?void 0:Array.isArray(s.label)?s.label:[s.label];c(Te(a,process.env,t,{...s.description!==void 0?{description:s.description}:{},...s.type!==void 0?{type:s.type}:{},...s.priority!==void 0?{priority:s.priority}:{},...s.assignee!==void 0?{assignee:s.assignee}:{},...i!==void 0?{labels:i}:{},...s.estimate!==void 0?{estimate:Number(s.estimate)}:{}}),e);break}case"list":case void 0:c(Ke(a,process.env),e);break;case"delete":t===void 0&&c(f(`Which template?
131
- kadence template delete bug`),e),c(Ne(a,process.env,t),e);break;default:c(f(`Unknown action "${n}".
132
- Available: save, list, delete`),e)}});h.command("ui","Interactive kanban board").alias("board:ui").example(" kadence ui").action(async()=>{let{runUi:n}=await import("./chunks/ui-WFLRVGUH.js"),t=await n(process.cwd(),process.env);t.ok||c(t,!1)});h.help();h.version("0.1.5");var v=process.argv;if(v[2]==="task"&&v[3]==="log"&&v[4]!==void 0&&v[5]!==void 0){let n=T(process.cwd(),process.env,v[4],v[5]),t=v.includes("--json");c(n,t)}var _e=process.argv.findIndex((n,t)=>n.startsWith("-")&&/^-\d+(\.\d+)?$/.test(n)&&process.argv[t-1]==="--estimate");_e!==-1&&(process.stderr.write(`Estimate must be a positive number, got "${process.argv[_e]}".
84
+ kadence sprint --help`),e)}});g.command("template [action] [name]","Task templates: save | list | delete").option("-d, --description <text>","Default description").option("--type <type>","Default type").option("--priority <level>","Default priority").option("-a, --assignee <who>","Default assignee").option("--label <name>","Default label; repeat for several").option("--estimate <points>","Default estimate").option("--json","Machine-readable output for agents").example(" kadence template save bug --type bug --priority high --label triage").example(" kadence template list").action((n,t,s)=>{let e=s.json===!0,i=process.cwd();switch(n){case"save":{t===void 0&&c(f(`A template name is required:
85
+ kadence template save bug --type bug`),e);let a=s.label===void 0?void 0:Array.isArray(s.label)?s.label:[s.label];c(Te(i,process.env,t,{...s.description!==void 0?{description:s.description}:{},...s.type!==void 0?{type:s.type}:{},...s.priority!==void 0?{priority:s.priority}:{},...s.assignee!==void 0?{assignee:s.assignee}:{},...a!==void 0?{labels:a}:{},...s.estimate!==void 0?{estimate:Number(s.estimate)}:{}}),e);break}case"list":case void 0:c(je(i,process.env),e);break;case"delete":t===void 0&&c(f(`Which template?
86
+ kadence template delete bug`),e),c(Ke(i,process.env,t),e);break;default:c(f(`Unknown action "${n}".
87
+ Available: save, list, delete`),e)}});g.command("ui","Interactive kanban board").alias("board:ui").example(" kadence ui").action(async()=>{let{runUi:n}=await import("./chunks/ui-ILZI767Q.js"),t=await n(process.cwd(),process.env);t.ok||c(t,!1)});g.help();g.version("0.2.1");var A=process.argv;if(A[2]==="task"&&A[3]==="log"&&A[4]!==void 0&&A[5]!==void 0){let n=K(process.cwd(),process.env,A[4],A[5]),t=A.includes("--json");c(n,t)}var _e=process.argv.findIndex((n,t)=>n.startsWith("-")&&/^-\d+(\.\d+)?$/.test(n)&&process.argv[t-1]==="--estimate");_e!==-1&&(process.stderr.write(`Estimate must be a positive number, got "${process.argv[_e]}".
133
88
  kadence task add "Fix login" --estimate 3
134
- `),process.exit(2));try{h.parse()}catch(n){process.stderr.write(`${n.message}
89
+ `),process.exit(2));try{g.parse()}catch(n){process.stderr.write(`${n.message}
135
90
  `),process.exit(2)}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "kadence",
3
- "version": "0.1.5",
4
- "description": "Tasks, sprints and velocity as plain files inside your git repository",
3
+ "version": "0.2.1",
4
+ "description": "Your team and your AI agents work from the same context: tasks, their full history and time as plain files in your git repository",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "engines": {
@@ -44,6 +44,7 @@
44
44
  "tui",
45
45
  "project-management",
46
46
  "ai-agents",
47
+ "shared-context",
47
48
  "event-sourcing",
48
49
  "offline"
49
50
  ],
@@ -1,90 +0,0 @@
1
- #!/usr/bin/env node
2
- var U=["backlog","todo","in_progress","blocked","in_review","done","cancelled"],Ot="done",Ie="cancelled",D=["task","bug","story","epic"],R=["low","normal","high","urgent"];function ne(e){let n=[...e].sort((l,p)=>l.id<p.id?-1:l.id>p.id?1:0),r=new Map,t=new Map,s=new Map,i=null,o=[],a=[];for(let l of n){if(l.type==="template.saved"){let p=typeof l.data?.name=="string"?l.data.name:null;p!==null&&s.set(p,{name:p,fields:l.data?.fields??{},author:l.actor});continue}if(l.type==="board.configured"){let p=l.data?.statuses;if(Array.isArray(p)){let m=p.filter(g=>typeof g=="string"&&g.length>0);m.length>0&&(i=m)}continue}if(l.type==="template.deleted"){let p=typeof l.data?.name=="string"?l.data.name:null;p!==null&&s.delete(p);continue}q(l,r,t,o,a)}let d=a.length>0,u=a;for(;u.length>0;){let l=[];for(let p of u)q(p,r,t,o,l);if(l.length===u.length){u=l;break}u=l}if(d)for(let l of r.values())l.history.sort((p,m)=>p.id<m.id?-1:1);let c=[...r.values()].sort((l,p)=>l.id<p.id?-1:1);c.forEach((l,p)=>{l.label=`KAD-${p+1}`});let f=new Set(c.map(l=>l.id));for(let l of c)l.parent!==null&&!f.has(l.parent)&&(l.parent=null),l.blockedBy=l.blockedBy.filter(p=>f.has(p));return{tasks:c,sprints:[...t.values()].sort((l,p)=>l.id<p.id?-1:1),statuses:i??[...U],orphanStatuses:[...new Set(c.map(l=>l.status).filter(l=>!(i??U).includes(l)))].sort(),templates:[...s.values()].sort((l,p)=>l.name.localeCompare(p.name)),cycles:_e(c),pending:u,rejected:o}}function q(e,n,r,t,s){let i=e.data??{};if(e.type==="task.created")return n.has(e.entity)||n.set(e.entity,{id:e.entity,label:"",title:typeof i.title=="string"?i.title:"(untitled)",description:x(i.description),type:Q(i.type),priority:ee(i.priority),status:"backlog",labels:te(i.labels),assignee:x(i.assignee),reporter:e.actor,sprint:null,parent:x(i.parent),blockedBy:[],due:x(i.due),comments:[],estimate:typeof i.estimate=="number"?i.estimate:null,loggedHours:0,createdAt:e.ts,updatedAt:e.ts,history:[]}),K(n.get(e.entity),e),!0;if(e.type==="sprint.created")return r.has(e.entity)||r.set(e.entity,{id:e.entity,name:typeof i.name=="string"?i.name:"(untitled)",description:x(i.description),startDate:x(i.startDate),endDate:x(i.endDate),status:"planned",closedBy:null,taskIds:[]}),!0;if(e.type.startsWith("sprint.")){let a=r.get(e.entity);if(a===void 0)return s.push(e),!1;if(e.type==="sprint.started")return a.status==="planned"&&(a.status="active"),!0;if(e.type==="sprint.updated")return a.status==="closed"?(t.push(e),!0):(typeof i.name=="string"&&(a.name=i.name),i.description!==void 0&&(a.description=x(i.description)),i.startDate!==void 0&&(a.startDate=x(i.startDate)),i.endDate!==void 0&&(a.endDate=x(i.endDate)),!0);if(e.type==="sprint.closed")return a.closedBy===null?(a.status="closed",a.closedBy=e.id):t.push(e),!0;if(e.type==="sprint.cancelled")return a.status==="planned"?a.status="cancelled":t.push(e),!0;if(e.type==="sprint.task_added"){if(a.status==="closed")return t.push(e),!0;let d=typeof i.task=="string"?i.task:null;if(d===null)return!0;let u=n.get(d);return u===void 0?(s.push(e),!1):(u.sprint=a.id,a.taskIds.includes(d)||a.taskIds.push(d),K(u,e),!0)}return!0}let o=n.get(e.entity);if(o===void 0)return s.push(e),!1;if(e.type==="task.deleted")return n.delete(e.entity),!0;switch(e.type){case"task.moved":{let a=i.to;typeof a=="string"&&a.length>0&&(o.status=a);break}case"task.cancelled":o.status=Ie;break;case"task.reopened":o.status="in_progress";break;case"task.assigned":o.assignee=x(i.assignee);break;case"task.updated":typeof i.title=="string"&&(o.title=i.title),i.description!==void 0&&(o.description=x(i.description)),i.type!==void 0&&(o.type=Q(i.type)),i.priority!==void 0&&(o.priority=ee(i.priority)),i.labels!==void 0&&(o.labels=te(i.labels)),i.due!==void 0&&(o.due=x(i.due)),typeof i.estimate=="number"&&(o.estimate=i.estimate);break;case"task.parent_set":o.parent=x(i.parent);break;case"task.blocked_by_added":{let a=x(i.blocker);a!==null&&!o.blockedBy.includes(a)&&o.blockedBy.push(a);break}case"task.blocked_by_removed":{let a=x(i.blocker);a!==null&&(o.blockedBy=o.blockedBy.filter(d=>d!==a));break}case"task.time_logged":{let a=i.hours;typeof a=="number"&&Number.isFinite(a)&&(o.loggedHours=Math.max(0,o.loggedHours+a));break}case"task.commented":{let a=x(i.text);a!==null&&o.comments.push({id:e.id,author:e.actor,ts:e.ts,text:a});break}default:break}return K(o,e),!0}function K(e,n){e.history.push({id:n.id,type:n.type,actor:n.actor,ts:n.ts,data:n.data??{}}),n.ts>e.updatedAt&&(e.updatedAt=n.ts)}function x(e){return typeof e=="string"&&e.length>0?e:null}function Q(e){return D.includes(e)?e:"task"}function ee(e){return R.includes(e)?e:"normal"}function te(e){return Array.isArray(e)?e.filter(n=>typeof n=="string"&&n.length>0):[]}function _e(e){let n=new Map(e.map(i=>[i.id,i])),r=[],t=new Set,s=(i,o)=>{let a=new Map,d=(u,c)=>{let f=a.get(u);if(f==="done")return;if(f==="visiting"){let p=c.indexOf(u),m=c.slice(p),g=`${i}:${[...m].sort().join(",")}`;t.has(g)||(t.add(g),r.push({kind:i,path:[...m,u]}));return}a.set(u,"visiting");let l=n.get(u);if(l!==void 0)for(let p of o(l))d(p,[...c,u]);a.set(u,"done")};for(let u of e)d(u.id,[])};return s("parent",i=>i.parent===null?[]:[i.parent]),s("blocking",i=>i.blockedBy),r}var re={urgent:0,high:1,normal:2,low:3};function se(e,n){return e!==null&&e.toLowerCase().includes(n)}function oe(e,n,r=new Date){let t=r.toISOString().slice(0,10),s=n.search?.toLowerCase();return e.filter(i=>{if(s!==void 0&&s.length>0){let o=i.comments.some(a=>a.text.toLowerCase().includes(s));if(!se(i.title,s)&&!se(i.description,s)&&!o)return!1}if(n.status!==void 0&&i.status!==n.status||n.type!==void 0&&i.type!==n.type||n.priority!==void 0&&i.priority!==n.priority)return!1;if(n.assignee!==void 0){let o=n.assignee.toLowerCase(),a=(i.assignee??"").toLowerCase();if(o==="none"?a!=="":a!==o)return!1}if(n.label!==void 0){let o=n.label.toLowerCase();if(!i.labels.some(a=>a.toLowerCase()===o))return!1}return!(n.sprint!==void 0&&i.sprint!==n.sprint||n.overdue===!0&&(i.due===null||i.due>=t)||n.dueBefore!==void 0&&(i.due===null||i.due>=n.dueBefore))})}function ae(e,n){let r=[...e];switch(n){case"priority":return r.sort((t,s)=>re[t.priority]-re[s.priority]);case"due":return r.sort((t,s)=>ie(t.due,s.due,(i,o)=>i<o?-1:i>o?1:0));case"estimate":return r.sort((t,s)=>ie(t.estimate,s.estimate,(i,o)=>o-i));default:return r.sort((t,s)=>t.id<s.id?-1:t.id>s.id?1:0)}}function ie(e,n,r){return e===null&&n===null?0:e===null?1:n===null?-1:r(e,n)}function de(e){let n=[];return e.search!==void 0&&n.push(`search="${e.search}"`),e.status!==void 0&&n.push(`status=${e.status}`),e.type!==void 0&&n.push(`type=${e.type}`),e.priority!==void 0&&n.push(`priority=${e.priority}`),e.assignee!==void 0&&n.push(`assignee=${e.assignee}`),e.label!==void 0&&n.push(`label=${e.label}`),e.overdue===!0&&n.push("overdue"),e.dueBefore!==void 0&&n.push(`due before ${e.dueBefore}`),n.length===0?`No tasks yet.
3
- Create the first one:
4
- kadence task add "title"`:`No tasks match ${n.join(" and ")}.
5
- Try fewer filters:
6
- kadence task list`}var H=["created","priority","due","estimate"];function ue(e){return H.includes(e)}import{execFileSync as Fe}from"node:child_process";function le(e,n){try{return Fe("git",n,{cwd:e,encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim()}catch{return null}}function ce(e){let n=le(e,["rev-parse","--show-toplevel"]);return n===null||n.length===0?null:n}function pe(e){let n=le(e,["config","user.email"]);return n===null||n.length===0?null:n}import{mkdirSync as He,readdirSync as Ye,readFileSync as We,renameSync as Ge,rmSync as Jt,writeFileSync as Ze}from"node:fs";import{join as N}from"node:path";var Me=["task.created","task.moved","task.assigned","task.commented","task.updated","task.cancelled","task.reopened","task.deleted","task.parent_set","task.blocked_by_added","task.blocked_by_removed","task.time_logged","template.saved","template.deleted","board.configured","sprint.created","sprint.started","sprint.updated","sprint.closed","sprint.cancelled","sprint.task_added"],Be=new Set(Me),fe=/^[0-9ABCDEFGHJKMNPQRSTVWXYZ]{26}$/,Le=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{1,3})?(Z|[+-]\d{2}:\d{2})$/;function Je(e){return typeof e=="string"&&Be.has(e)}function Ue(e){if(typeof e!="object"||e===null)return["event"];let n=e,r=[];return(typeof n.id!="string"||!fe.test(n.id))&&r.push("id"),Je(n.type)||r.push("type"),(typeof n.entity!="string"||!fe.test(n.entity))&&r.push("entity"),(typeof n.actor!="string"||n.actor.length===0)&&r.push("actor"),(typeof n.ts!="string"||!Le.test(n.ts)||Number.isNaN(Date.parse(n.ts)))&&r.push("ts"),n.source!=="human"&&n.source!=="agent"&&r.push("source"),n.data!==void 0&&(typeof n.data!="object"||n.data===null)&&r.push("data"),r}function ge(e){let n=e.data?.description;if(typeof n!="string"||!n.includes(`
7
- `))return JSON.stringify(e);let r={...e,data:{...e.data,description:n.split(`
8
- `)}};return JSON.stringify(r,null,2)}function Y(e){let n;try{n=JSON.parse(e)}catch(t){return{event:null,error:`unreadable JSON: ${t.message}`,unknownType:!1}}n=Ke(n);let r=Ue(n);return r.length===1&&r[0]==="type"?{event:null,error:null,unknownType:!0}:r.length>0?{event:null,error:`invalid fields: ${r.join(", ")}`,unknownType:!1}:{event:n,error:null,unknownType:!1}}function Ke(e){if(typeof e!="object"||e===null)return e;let n=e,r=n.data;if(typeof r!="object"||r===null)return e;let t=r.description;return Array.isArray(t)?{...n,data:{...r,description:t.filter(s=>typeof s=="string").join(`
9
- `)}}:e}var Ve=.2;function O(e){return N(e,".kadence")}function M(e){return N(O(e),"events")}function ze(e){return N(M(e),"archive")}function Xe(e){return e.slice(0,7)}function w(e,n){let r=N(M(e),Xe(n.ts));He(r,{recursive:!0});let t=N(r,`${n.id}.json`),s=N(r,`.${n.id}.tmp`);Ze(s,`${ge(n)}
10
- `,"utf8"),Ge(s,t)}function I(e){let n=M(e),r=[],t=[],s=new Set,i=0,o=W(ze(e)),a=new Set(o);for(let u of W(n)){let c;try{c=We(u,"utf8")}catch{t.push(u);continue}if(a.has(u)){let l;try{l=JSON.parse(c)}catch{t.push(u);continue}if(!Array.isArray(l)){t.push(u);continue}for(let p of l){let m=Y(JSON.stringify(p));m.unknownType?i++:m.error!==null||m.event===null?t.push(u):s.has(m.event.id)||(s.add(m.event.id),r.push(m.event))}continue}let f=Y(c);if(f.unknownType){i++;continue}if(f.error!==null||f.event===null){t.push(u);continue}s.has(f.event.id)||(s.add(f.event.id),r.push(f.event))}r.sort((u,c)=>u.id<c.id?-1:u.id>c.id?1:0);let d=r.length+t.length;return{events:r,corrupted:t,unknownTypes:i,systemicCorruption:d>0&&t.length/d>Ve}}function W(e){let n;try{n=Ye(e,{withFileTypes:!0})}catch{return[]}let r=[];for(let t of n){let s=N(e,t.name);t.isDirectory()?r.push(...W(s)):t.name.endsWith(".json")&&r.push(s)}return r}import{randomFillSync as qe}from"node:crypto";var ke="0123456789ABCDEFGHJKMNPQRSTVWXYZ",Qe=10,et=16,me=2**48-1;function tt(e){let n="",r=e;for(let t=Qe-1;t>=0;t--)n=ke[r%32]+n,r=Math.floor(r/32);return n}function nt(e){let n="",r=0,t=0;for(let s of e){for(r=r<<8|s,t+=8;t>=5;)t-=5,n+=ke[r>>>t&31];r&=(1<<t)-1}return n.slice(0,et)}function rt(e){for(let n=e.length-1;n>=0;n--){let r=e[n];if(r<255){e[n]=r+1;return}e[n]=0}throw new Error("ULID: random space exhausted within a single millisecond")}function st(){let e=-1,n=new Uint8Array(10);return function(t=Date.now()){if(!Number.isInteger(t)||t<0||t>me)throw new RangeError(`ULID: time out of range 0..${me}: ${t}`);return t>e?(e=t,qe(n)):rt(n),tt(e)+nt(n)}}var $=st();import{readFileSync as it,writeFileSync as ot,renameSync as at,readdirSync as dt,mkdirSync as ut}from"node:fs";import{join as he}from"node:path";var ye="kadence-snapshot/1";function be(e){return he(O(e),"state.json")}function xe(e,n){let r=lt(M(e)),t=ct(e);if(t!==null&&t.version===ye&&t.lastEventId===r.lastEventId&&t.eventCount===r.count)return{state:t.state,fromCache:!0,incomingEvents:0};let s=I(e),i=ne(s.events),o=t===null||n===void 0?0:ft(s.events,t,n);return pt(e,{version:ye,lastEventId:r.lastEventId,eventCount:r.count,state:i}),{state:i,fromCache:!1,incomingEvents:o}}function lt(e){let n="",r=0,t=s=>{let i;try{i=dt(s,{withFileTypes:!0})}catch{return}for(let o of i)if(o.isDirectory())t(he(s,o.name));else if(o.name.endsWith(".json")){r++;let a=o.name.slice(0,-5);a>n&&(n=a)}};return t(e),{lastEventId:n,count:r}}function ct(e){try{let n=JSON.parse(it(be(e),"utf8"));if(typeof n!="object"||n===null)return null;let r=n;return typeof r.version!="string"||typeof r.lastEventId!="string"||typeof r.eventCount!="number"||typeof r.state!="object"?null:r}catch{return null}}function pt(e,n){try{ut(O(e),{recursive:!0});let r=be(e),t=`${r}.tmp`;ot(t,JSON.stringify(n),"utf8"),at(t,r)}catch{}}function ft(e,n,r){let t=0,s=0;for(let o of e)o.id<=n.lastEventId?t++:o.actor!==r&&s++;let i=Math.max(0,t-n.eventCount);return s+i}var S={dim:"\x1B[2m",bold:"\x1B[1m",green:"\x1B[32m",yellow:"\x1B[33m",blue:"\x1B[34m",reset:"\x1B[0m"};function Z(e,n){return e.NO_COLOR!==void 0?!1:n}function E(e,n,r){return r?`${n}${e}${S.reset}`:e}var gt={done:S.green,in_progress:S.blue,blocked:S.yellow,cancelled:S.dim},mt=72;function Se(e,n=mt){let r=[...e];return r.length<=n?e:`${r.slice(0,n-1).join("")}\u2026`}function G(e){return[...e].length}function ve(e,n){let r=n-G(e);return r>0?e+" ".repeat(r):e}function $e(e,n){if(e.length===0)return`No tasks yet.
11
- Create the first one:
12
- kadence task add "title"`;let r=Math.max(...e.map(s=>G(s.label)),2),t=Math.max(...e.map(s=>G(s.status)),6);return e.map(s=>{let i=E(ve(s.label,r),S.bold,n),o=E(ve(s.status,t),gt[s.status]??S.dim,n),a=s.estimate===null?"":E(` (${s.estimate})`,S.dim,n);return`${i} ${o} ${Se(s.title)}${a}`}).join(`
13
- `)}function we(e){return e<=0?null:`Merged ${e} ${e===1?"change":"changes"} from another branch, no conflicts.`}var kt={urgent:"!!",high:"!",normal:"",low:"v"},yt={bug:"BUG",story:"STORY",task:""};function Te(e,n){let r=[E(e.label,S.bold,n)],t=kt[e.priority];t!==""&&r.push(E(t,e.priority==="low"?S.dim:S.yellow,n));let s=yt[e.type]??"";s!==""&&r.push(E(s,S.dim,n)),r.push(Se(e.title));let i=[];return e.assignee!==null&&i.push(`@${e.assignee.split("@")[0]}`),e.estimate!==null&&i.push(`${e.estimate}`),i.length>0&&r.push(E(`(${i.join(", ")})`,S.dim,n)),` ${r.join(" ")}`}function qt(e,n){if(Object.values(e).reduce((s,i)=>s+i.length,0)===0)return`No tasks yet.
14
- Create the first one:
15
- kadence task add "title"`;let t=[];for(let[s,i]of Object.entries(e)){if(i.length===0)continue;let o=i.reduce((d,u)=>d+(u.estimate??0),0),a=o>0?` \u2014 ${o}`:"";t.push(E(`${s} (${i.length}${a})`,S.bold,n),...i.map(d=>Te(d,n)),"")}return t.join(`
16
- `).trimEnd()}function ht(e,n=new Date){let r=Date.parse(`${e}T00:00:00.000Z`),t=Date.parse(`${n.toISOString().slice(0,10)}T00:00:00.000Z`);if(Number.isNaN(r))return"";let s=Math.round((r-t)/864e5);return s<0?` (overdue by ${-s} day${s===-1?"":"s"})`:s===0?" (today)":s===1?" (tomorrow)":s<=7?` (in ${s} days)`:""}function Ce(e,n){if(e.length===0)return`No tasks yet.
17
- Create the first one:
18
- kadence task add "title"`;let r=new Set(e.map(a=>a.id)),t=new Map;for(let a of e){let d=a.parent!==null&&r.has(a.parent)?a.parent:null,u=t.get(d)??[];u.push(a),t.set(d,u)}let s=[],i=new Set,o=(a,d)=>{if(!(d>10))for(let u of t.get(a)??[]){if(i.has(u.id))continue;i.add(u.id);let c=" ".repeat(d),f=u.blockedBy.length>0?E(" [blocked]",S.yellow,n):"";s.push(`${c}${Te(u,n).trimStart()}${f}`),o(u.id,d+1)}};return o(null,0),s.join(`
19
- `)}function Ee(e){let n=[`${e.label} ${e.title}`,""];if(e.description!==null&&n.push(e.description,""),n.push(` Status: ${e.status}`),n.push(` Type: ${e.type}`),n.push(` Priority: ${e.priority}`),e.labels.length>0&&n.push(` Labels: ${e.labels.join(", ")}`),e.parent!==null&&n.push(` Parent: ${e.parent}`),e.blockedBy.length>0&&n.push(` Blocked by: ${e.blockedBy.length} task(s)`),n.push(` Assignee: ${e.assignee??"\u2014"}`),n.push(` Reporter: ${e.reporter}`),e.due!==null&&n.push(` Due: ${e.due}${ht(e.due)}`),n.push(` Estimate: ${e.estimate??"\u2014"}`),e.comments.length>0){n.push("",` Comments (${e.comments.length}):`);for(let r of e.comments){n.push(` ${r.author} \xB7 ${r.ts.slice(0,10)}`);for(let t of r.text.split(`
20
- `))n.push(` ${t}`)}}if(e.history.length>0){n.push("",` History (${e.history.length}):`);for(let r of e.history){let t=r.type==="task.moved"?` \u2192 ${String(r.data.to)}`:"";n.push(` ${r.ts.slice(0,16).replace("T"," ")} ${r.actor} ${r.type}${t}`)}}return n.join(`
21
- `)}import{existsSync as bt}from"node:fs";var un=U;function h(e,n){let r=ce(e);if(r===null)return{ok:!1,exitCode:1,message:`kadence lives inside a git repository, and there is none here.
22
- Create one and try again:
23
- git init`};if(!bt(O(r)))return{ok:!1,exitCode:1,message:`No .kadence/ found here.
24
- Run:
25
- npx kadence init`};let t=pe(r);if(t===null)return{ok:!1,exitCode:1,message:`Git does not know who you are, so there is no author for the event.
26
- Run:
27
- git config user.email you@example.com`};let s=n.KADENCE_SOURCE==="agent"?"agent":"human";return{root:r,actor:t,source:s}}function b(e){return"root"in e}function ln(e,n,r,t={}){let s=h(e,n);if(!b(s))return s;let i=r.trim();if(i.length===0)return{ok:!1,exitCode:2,message:"A task needs a title."};if(t.type!==void 0&&!D.includes(t.type))return{ok:!1,exitCode:2,message:`Unknown type "${t.type}".
28
- Available: ${D.join(", ")}`};if(t.priority!==void 0&&!R.includes(t.priority))return{ok:!1,exitCode:2,message:`Unknown priority "${t.priority}".
29
- Available: ${R.join(", ")}`};let o;if(t.parent!==void 0){let{state:c}=k(s.root,s.actor),f=T(c,t.parent);if(f===void 0)return{ok:!1,exitCode:1,message:`No parent task ${t.parent}.
30
- kadence task list`};o=f.id}let a=$(),d={id:a,type:"task.created",entity:a,actor:s.actor,ts:new Date().toISOString(),source:s.source,data:{title:i,...t.description!==void 0?{description:t.description}:{},...t.type!==void 0?{type:t.type}:{},...t.priority!==void 0?{priority:t.priority}:{},...t.assignee!==void 0?{assignee:t.assignee}:{},...t.labels!==void 0&&t.labels.length>0?{labels:t.labels}:{},...t.due!==void 0?{due:t.due}:{},...o!==void 0?{parent:o}:{},...t.estimate!==void 0?{estimate:t.estimate}:{}}};w(s.root,d);let u=t.estimate===void 0?`
31
- Without an estimate this task will not count towards velocity. Add --estimate.`:"";return{ok:!0,exitCode:0,message:`Created: ${i}${u}`,data:{schema:"kadence/v1",ok:!0,task:{id:a,title:i}}}}function k(e,n){let r=xe(e,n),t=I(e),s=[],i=we(r.incomingEvents);return i!==null&&s.push(i),t.systemicCorruption?s.push(`The journal is badly damaged: ${t.corrupted.length} of ${t.corrupted.length+t.events.length} events are unreadable. Try: git checkout .kadence/`):t.corrupted.length>0&&s.push(`Skipped ${t.corrupted.length} corrupted event(s).`),t.unknownTypes>0&&s.push(`Skipped ${t.unknownTypes} event(s) from a newer format. Update kadence.`),{state:r.state,warnings:s}}function T(e,n){let r=n.toUpperCase();return e.tasks.find(t=>t.id===r||t.label===r)}function De(e,n){return{ok:!1,exitCode:2,message:`Unknown status "${e}".
32
- Available: ${n.join(", ")}
33
- kadence board config --statuses "todo,doing,done"`}}function cn(e,n,r){let t=h(e,n);if(!b(t))return t;if(r.type!==void 0&&!D.includes(r.type))return{ok:!1,exitCode:2,message:`Unknown type "${r.type}".
34
- Available: ${D.join(", ")}`};if(r.priority!==void 0&&!R.includes(r.priority))return{ok:!1,exitCode:2,message:`Unknown priority "${r.priority}".
35
- Available: ${R.join(", ")}`};if(r.sort!==void 0&&!ue(r.sort))return{ok:!1,exitCode:2,message:`Unknown sort key "${r.sort}".
36
- Available: ${H.join(", ")}`};let{state:s,warnings:i}=k(t.root,t.actor);if(r.status!==void 0&&!s.statuses.includes(r.status))return De(r.status,s.statuses);let{sort:o,tree:a,...d}=r,u=oe(s.tasks,d),c=o===void 0?u:ae(u,o);return c.length===0?{ok:!0,exitCode:0,warnings:i,message:de(d),data:{schema:"kadence/v1",ok:!0,tasks:[]}}:{ok:!0,exitCode:0,warnings:i,message:a===!0?Ce(c,Z(n,process.stdout.isTTY===!0)):$e(c,Z(n,process.stdout.isTTY===!0)),data:{schema:"kadence/v1",ok:!0,tasks:c.map(Re),cycles:s.cycles}}}function pn(e,n,r,t){let s=h(e,n);if(!b(s))return s;let{state:i,warnings:o}=k(s.root,s.actor);if(!i.statuses.includes(t))return De(t,i.statuses);let{tasks:a,error:d}=P(i,r);if(d!==null)return{ok:!1,exitCode:1,message:d};let u=[],c=[],f="";for(let p of a){if(p.status===t){c.push(p);continue}let m=p.status;w(s.root,{id:$(),type:"task.moved",entity:p.id,actor:s.actor,ts:new Date().toISOString(),source:s.source,data:{from:m,to:t}}),u.push(p),a.length===1&&i.statuses.indexOf(t)-i.statuses.indexOf(m)>1&&(f=`
37
- Moved straight from ${m} to ${t}, skipping the stages between.`)}if(u.length===0)return{ok:!0,exitCode:0,warnings:o,message:v("already there",c,`is already ${t}.`)};let l=c.length>0?`
38
- ${c.length} already ${t}.`:"";return{ok:!0,exitCode:0,warnings:o,message:`${v("moved",u,`${u[0].status} \u2192 ${t}`)}${f}${l}`,data:{schema:"kadence/v1",ok:!0,moved:u.map(p=>({id:p.id,label:p.label,to:t}))}}}function Re(e){return{id:e.id,label:e.label,title:e.title,description:e.description,type:e.type,priority:e.priority,status:e.status,labels:e.labels,assignee:e.assignee,reporter:e.reporter,sprint:e.sprint,loggedHours:e.loggedHours,parent:e.parent,blockedBy:e.blockedBy,due:e.due,comments:e.comments,estimate:e.estimate,history:e.history}}function fn(e,n,r,t){let s=h(e,n);if(!b(s))return s;let{state:i,warnings:o}=k(s.root,s.actor),{tasks:a,error:d}=P(i,r);if(d!==null)return{ok:!1,exitCode:1,message:d};let u=t.trim().toLowerCase()==="none"?null:t.trim(),c=a.filter(f=>f.assignee!==u);if(c.length===0)return{ok:!0,exitCode:0,warnings:o,message:u===null?v("already unassigned",a,"is already unassigned."):v("already assigned",a,`is already assigned to ${u}.`)};for(let f of c)w(s.root,{id:$(),type:"task.assigned",entity:f.id,actor:s.actor,ts:new Date().toISOString(),source:s.source,data:{assignee:u}});return{ok:!0,exitCode:0,warnings:o,message:u===null?v("unassigned",c,"unassigned."):v("assigned",c,`\u2192 ${u}`),data:{schema:"kadence/v1",ok:!0,assigned:c.map(f=>({id:f.id,label:f.label,assignee:u}))}}}function gn(e,n,r){let t=h(e,n);if(!b(t))return t;let{state:s,warnings:i}=k(t.root,t.actor),o=T(s,r);return o===void 0?{ok:!1,exitCode:1,message:`No task ${r}.
39
- kadence task list`}:{ok:!0,exitCode:0,warnings:i,message:Ee(o),data:{schema:"kadence/v1",ok:!0,task:Re(o)}}}function mn(e,n,r,t){let s=h(e,n);if(!b(s))return s;if(t.type!==void 0&&!D.includes(t.type))return{ok:!1,exitCode:2,message:`Unknown type "${t.type}".
40
- Available: ${D.join(", ")}`};if(t.priority!==void 0&&!R.includes(t.priority))return{ok:!1,exitCode:2,message:`Unknown priority "${t.priority}".
41
- Available: ${R.join(", ")}`};if(t.due!==void 0&&t.due!==""&&!xt(t.due))return{ok:!1,exitCode:2,message:`Due date must be YYYY-MM-DD, got "${t.due}".
42
- kadence task edit KAD-1 --due 2026-09-30`};let{state:i,warnings:o}=k(s.root,s.actor),{tasks:a,error:d}=P(i,r);if(d!==null)return{ok:!1,exitCode:1,message:d};if(t.title!==void 0&&a.length>1)return{ok:!1,exitCode:2,message:"A title can only be set on one task at a time."};let u=[],c=new Set;for(let l of a){let p={},m=[];if(t.title!==void 0&&t.title!==l.title&&(p.title=t.title,m.push("title")),t.description!==void 0&&t.description!==(l.description??"")&&(p.description=t.description,m.push("description")),t.type!==void 0&&t.type!==l.type&&(p.type=t.type,m.push("type")),t.priority!==void 0&&t.priority!==l.priority&&(p.priority=t.priority,m.push("priority")),t.due!==void 0&&t.due!==(l.due??"")&&(p.due=t.due,m.push("due")),t.estimate!==void 0&&t.estimate!==l.estimate&&(p.estimate=t.estimate,m.push("estimate")),t.labels!==void 0&&t.labels.join(",")!==l.labels.join(",")&&(p.labels=t.labels,m.push("labels")),m.length!==0){w(s.root,{id:$(),type:"task.updated",entity:l.id,actor:s.actor,ts:new Date().toISOString(),source:s.source,data:p}),u.push(l);for(let g of m)c.add(g)}}if(u.length===0)return{ok:!0,exitCode:0,warnings:o,message:v("unchanged",a,"nothing changed.")};let f=[...c].join(", ");return{ok:!0,exitCode:0,warnings:o,message:v("updated",u,`updated ${f}.`),data:{schema:"kadence/v1",ok:!0,updated:u.map(l=>({id:l.id,label:l.label})),changed:[...c]}}}function xt(e){if(!/^\d{4}-\d{2}-\d{2}$/.test(e))return!1;let n=new Date(`${e}T00:00:00.000Z`);return!Number.isNaN(n.getTime())&&n.toISOString().slice(0,10)===e}function kn(e,n,r){let t=h(e,n);if(!b(t))return t;let{state:s,warnings:i}=k(t.root,t.actor),{tasks:o,error:a}=P(s,r);if(a!==null)return{ok:!1,exitCode:1,message:a};let d=o.filter(u=>u.status!=="cancelled");if(d.length===0)return{ok:!0,exitCode:0,warnings:i,message:v("already cancelled",o,"is already cancelled.")};for(let u of d)w(t.root,{id:$(),type:"task.cancelled",entity:u.id,actor:t.actor,ts:new Date().toISOString(),source:t.source,data:{}});return{ok:!0,exitCode:0,warnings:i,message:`${v("cancelled",d,"cancelled.")}
43
- Cancelled work stays in history and does not count as missed.`,data:{schema:"kadence/v1",ok:!0,cancelled:d.map(u=>({id:u.id,label:u.label}))}}}function yn(e,n,r){let t=h(e,n);if(!b(t))return t;let{state:s,warnings:i}=k(t.root,t.actor),{tasks:o,error:a}=P(s,r);if(a!==null)return{ok:!1,exitCode:1,message:a};for(let u of o)w(t.root,{id:$(),type:"task.deleted",entity:u.id,actor:t.actor,ts:new Date().toISOString(),source:t.source,data:{title:u.title}});let d=o.length===1?`${o[0].label} deleted: "${o[0].title}".`:`${o.length} tasks deleted: ${o.map(u=>u.label).join(", ")}.`;return{ok:!0,exitCode:0,warnings:i,message:`${d}
44
- The events stay in the journal \u2014 history is never rewritten.`,data:{schema:"kadence/v1",ok:!0,deleted:o.map(u=>({id:u.id,label:u.label}))}}}function hn(e,n,r,t){let s=h(e,n);if(!b(s))return s;let i=t.trim();if(i.length===0)return{ok:!1,exitCode:2,message:"A comment needs text."};let{state:o,warnings:a}=k(s.root,s.actor),d=T(o,r);return d===void 0?{ok:!1,exitCode:1,message:`No task ${r}.
45
- kadence task list`}:(w(s.root,{id:$(),type:"task.commented",entity:d.id,actor:s.actor,ts:new Date().toISOString(),source:s.source,data:{text:i}}),{ok:!0,exitCode:0,warnings:a,message:`Comment added to ${d.label}.`,data:{schema:"kadence/v1",ok:!0,task:{id:d.id,label:d.label}}})}function P(e,n){let r=n.split(",").map(o=>o.trim()).filter(o=>o.length>0);if(r.length===0)return{tasks:[],error:"No task given."};let t=[],s=[];for(let o of r){let a=T(e,o);a===void 0?s.push(o):t.push(a)}return s.length>0?{tasks:[],error:`No task ${s.join(", ")} \u2014 nothing was changed.
46
- All ids must exist before a bulk change runs.
47
- kadence task list`}:{tasks:[...new Map(t.map(o=>[o.id,o])).values()],error:null}}function v(e,n,r){return n.length===1?`${n[0].label}: ${r}`:`${n.length} tasks ${e}: ${n.map(t=>t.label).join(", ")}`}function bn(e,n,r,t){let s=h(e,n);if(!b(s))return s;let{state:i,warnings:o}=k(s.root,s.actor),{tasks:a,error:d}=P(i,r);if(d!==null)return{ok:!1,exitCode:1,message:d};let u=t.trim().toLowerCase()==="none",c=null;if(!u){let p=T(i,t);if(p===void 0)return{ok:!1,exitCode:1,message:`No task ${t}.
48
- kadence task list`};if(a.some(m=>m.id===p.id))return{ok:!1,exitCode:2,message:"A task cannot be its own parent."};c=p.id}let f=a.filter(p=>p.parent!==c);if(f.length===0)return{ok:!0,exitCode:0,warnings:o,message:v("unchanged",a,"already there.")};for(let p of f)w(s.root,{id:$(),type:"task.parent_set",entity:p.id,actor:s.actor,ts:new Date().toISOString(),source:s.source,data:{parent:c}});let l=u?"detached":T(i,t).label;return{ok:!0,exitCode:0,warnings:[...o,...Ne(s.root,s.actor)],message:u?v("detached",f,"detached from its parent."):v("moved",f,`\u2192 child of ${l}`),data:{schema:"kadence/v1",ok:!0,parent:c}}}function xn(e,n,r,t,s){let i=h(e,n);if(!b(i))return i;let{state:o,warnings:a}=k(i.root,i.actor),{tasks:d,error:u}=P(o,r);if(u!==null)return{ok:!1,exitCode:1,message:u};let c=T(o,t);if(c===void 0)return{ok:!1,exitCode:1,message:`No task ${t}.
49
- kadence task list`};if(d.some(l=>l.id===c.id))return{ok:!1,exitCode:2,message:"A task cannot block itself."};let f=d.filter(l=>s?l.blockedBy.includes(c.id):!l.blockedBy.includes(c.id));if(f.length===0)return{ok:!0,exitCode:0,warnings:a,message:v("unchanged",d,s?"was not blocked by it.":"is already blocked by it.")};for(let l of f)w(i.root,{id:$(),type:s?"task.blocked_by_removed":"task.blocked_by_added",entity:l.id,actor:i.actor,ts:new Date().toISOString(),source:i.source,data:{blocker:c.id}});return{ok:!0,exitCode:0,warnings:[...a,...Ne(i.root,i.actor)],message:s?v("unblocked",f,`no longer blocked by ${c.label}.`):v("blocked",f,`blocked by ${c.label}.`),data:{schema:"kadence/v1",ok:!0,blocker:c.id}}}function Ne(e,n){let{state:r}=k(e,n),t=new Map(r.tasks.map(s=>[s.id,s.label]));return r.cycles.map(s=>{let i=s.path.map(o=>t.get(o)??o).join(" \u2192 ");return`Dependency cycle (${s.kind}): ${i}. Both edges were kept \u2014 resolve it when you can.`})}function vt(e){let n=/^(-?\d+(?:\.\d+)?)\s*(h|hours?|m|min|minutes?)?$/i.exec(e.trim());if(n===null)return null;let r=Number(n[1]);return!Number.isFinite(r)||r===0?null:(n[2]??"h").toLowerCase().startsWith("m")?r/60:r}function vn(e,n,r,t){let s=h(e,n);if(!b(s))return s;let i=vt(t);if(i===null)return{ok:!1,exitCode:2,message:`Cannot read "${t}" as a duration.
50
- Use hours or minutes:
51
- kadence task log KAD-1 2h
52
- kadence task log KAD-1 90m
53
- kadence task log KAD-1 -30m to correct a mistake`};let{state:o,warnings:a}=k(s.root,s.actor),d=T(o,r);if(d===void 0)return{ok:!1,exitCode:1,message:`No task ${r}.
54
- kadence task list`};w(s.root,{id:$(),type:"task.time_logged",entity:d.id,actor:s.actor,ts:new Date().toISOString(),source:s.source,data:{hours:i}});let u=Math.max(0,d.loggedHours+i),c=d.estimate===null?`
55
- No estimate on this task, so there is nothing to compare against.`:"";return{ok:!0,exitCode:0,warnings:a,message:`${d.label}: ${u.toFixed(1)}h logged in total.${c}`,data:{schema:"kadence/v1",ok:!0,task:{id:d.id,label:d.label,loggedHours:u}}}}import{spawnSync as St}from"node:child_process";import{mkdtempSync as $t,readFileSync as wt,rmSync as Tt,writeFileSync as Ct}from"node:fs";import{tmpdir as Et}from"node:os";import{join as Pe}from"node:path";var B="#";function Dt(e){return e.GIT_EDITOR??e.VISUAL??e.EDITOR??"vi"}function En(e,n,r){let t=$t(Pe(Et(),"kadence-edit-")),s=Pe(t,"KADENCE_EDITMSG.md"),i=["",`${B} ${r}`,`${B} Lines starting with '${B}' are ignored.`,`${B} Save an empty file to abort.`].join(`
56
- `);try{Ct(s,`${n}${i}
57
- `,"utf8");let o=Dt(e),a=St(o,[s],{stdio:"inherit",shell:!0});if(a.error!==void 0||a.status!==null&&a.status!==0)return{text:null,error:`Editor "${o}" exited without saving.
58
- Set one explicitly:
59
- export EDITOR=nano`};let u=wt(s,"utf8").split(`
60
- `).filter(c=>!c.startsWith(B)).join(`
61
- `).trim();return{text:u.length===0?null:u,error:null}}catch(o){return{text:null,error:`Could not open an editor: ${o.message}`}}finally{Tt(t,{recursive:!0,force:!0})}}function Dn(e,n){return e.KADENCE_SOURCE==="agent"?!1:n}function V(e,n){let r=e.sprints.find(g=>g.id===n);if(r===void 0)return null;let t=e.tasks.filter(g=>g.sprint===n),s=t.filter(g=>g.status==="cancelled"),i=t.filter(g=>g.status!=="cancelled"),o=i.filter(g=>g.status==="done"),a=i.filter(g=>g.status!=="done"),d=L(i.map(g=>g.estimate??0)),u=L(o.map(g=>g.estimate??0)),c=o.filter(g=>g.estimate===null),f=o.map(Rt).filter(g=>g!==null),l=f.length>0?L(f):null,p=L(o.filter(g=>g.estimate!==null).map(g=>g.estimate)),m=l!==null&&p>0?l/p:null;return{id:r.id,name:r.name,status:r.status,committed:d,velocity:u,actualHours:l,hoursPerPoint:m,done:o,carriedOver:a,cancelled:s,unestimated:c,loggedHours:L(t.map(g=>g.loggedHours))}}function Rt(e){let n=e.history.find(s=>s.type==="task.moved"&&s.data.to==="in_progress"),r=[...e.history].reverse().find(s=>s.type==="task.moved"&&s.data.to==="done");if(n===void 0||r===void 0)return null;let t=Date.parse(r.ts)-Date.parse(n.ts);return t>0?t/36e5:null}function L(e){return e.reduce((n,r)=>n+r,0)}function J(e){return new Date(e).toISOString().slice(0,10)}function Nt(e,n){let r=[];for(let t=Date.parse(`${e}T00:00:00.000Z`);t<=Date.parse(`${n}T00:00:00.000Z`);t+=864e5)r.push(J(t));return r}function je(e,n,r,t=J(Date.now())){let s=e.tasks.filter(y=>y.sprint===r.id&&y.status!=="cancelled"),i=new Map(s.map(y=>[y.id,y.estimate??0])),o=[...i.values()].reduce((y,C)=>y+C,0),a=n.filter(y=>i.has(y.entity));if(a.length===0)return null;let d=r.startDate??J(a[0].ts),u=r.endDate??J(a.at(-1).ts),c=r.status==="closed"||u<t?u:t;if(c<d)return null;let f=new Set,l=new Map;for(let y of a){let C=J(y.ts);if(C<d)continue;let A=y.type==="task.moved"?y.data?.to:void 0,X=i.get(y.entity)??0;A==="done"&&!f.has(y.entity)?(f.add(y.entity),l.set(C,(l.get(C)??0)+X)):A!==void 0&&A!=="done"&&f.has(y.entity)&&(f.delete(y.entity),l.set(C,(l.get(C)??0)-X))}let p=Nt(d,c),m=Math.max(p.length-1,1),g=o;return{sprintName:r.name,committed:o,finalRemaining:(r.status==="closed",null),days:p.map((y,C)=>{let A=l.get(y)??0;return g-=A,{date:y,remaining:Math.max(0,g),ideal:Math.max(0,o-o/m*C),completed:A}})}}function Ae(e,n=40){if(e.committed===0)return`"${e.sprintName}": nothing to burn down \u2014 no estimated tasks.`;let r=[`"${e.sprintName}" \u2014 ${e.committed} points committed`,""];for(let s of e.days){let i=Math.round(s.remaining/e.committed*n),o=Math.round(s.ideal/e.committed*n),a=[];for(let c=0;c<n;c++)c===o&&c>=i?a.push("\u250A"):c<i?a.push(c===o?"\u2503":"\u2588"):a.push(" ");let d=s.remaining-s.ideal,u=Math.abs(d)<.5?"":d>0?` +${d.toFixed(0)}`:` ${d.toFixed(0)}`;r.push(`${s.date.slice(5)} ${a.join("")} ${String(s.remaining).padStart(3)}${u}`)}let t=e.days.at(-1);return t!==void 0&&(r.push(""),r.push(t.remaining===0?" All committed work is done.":` ${t.remaining} of ${e.committed} points remain.`+(t.remaining>t.ideal?" Behind the ideal line.":" On or ahead of the line."))),r.join(`
62
- `)}function j(e){return e.sprints.find(n=>n.status==="active")}function Pt(e){return e.sprints.filter(n=>n.status==="planned")}function _(e,n){let r=n.trim().toLowerCase();return e.sprints.find(t=>t.name.toLowerCase()===r)}function F(e,n,r,t){w(e.root,{id:$(),type:n,entity:r,actor:e.actor,ts:new Date().toISOString(),source:e.source,data:t})}function Mn(e,n,r){let t=h(e,n);if(!b(t))return t;let s=r.trim();if(s.length===0)return{ok:!1,exitCode:2,message:"A sprint needs a name."};let{state:i,warnings:o}=k(t.root,t.actor);if(_(i,s)!==void 0)return{ok:!1,exitCode:2,message:`Sprint "${s}" already exists.`};let a=j(i)!==void 0,d=$();return F(t,"sprint.created",d,{name:s}),a||F(t,"sprint.started",d,{}),{ok:!0,exitCode:0,warnings:o,message:a?`Sprint "${s}" planned.
63
-
64
- kadence sprint add KAD-1 --sprint "${s}"
65
- kadence sprint start "${s}"`:`Sprint "${s}" started.
66
-
67
- kadence sprint add KAD-1
68
- kadence sprint status`,data:{schema:"kadence/v1",ok:!0,sprint:{id:d,name:s,status:a?"planned":"active"}}}}function Bn(e,n,r,t={}){let s=h(e,n);if(!b(s))return s;let{state:i,warnings:o}=k(s.root,s.actor),a=t.sprint===void 0?j(i):_(i,t.sprint);if(a===void 0)return t.sprint===void 0?{ok:!1,exitCode:1,message:`No active sprint.
69
- kadence sprint create "Sprint 1"`}:{ok:!1,exitCode:1,message:`No sprint named "${t.sprint}".
70
- kadence sprint list`};if(a.status==="closed")return{ok:!1,exitCode:1,message:`Sprint "${a.name}" is closed \u2014 its velocity is not rewritten.`};let d=T(i,r);if(d===void 0)return{ok:!1,exitCode:1,message:`No task ${r}.
71
- kadence task list`};if(d.sprint===a.id)return{ok:!0,exitCode:0,warnings:o,message:`${d.label} is already in the sprint.`};F(s,"sprint.task_added",a.id,{task:d.id});let u=d.estimate===null?`
72
- Without an estimate this task will not count towards velocity.`:"";return{ok:!0,exitCode:0,warnings:o,message:`${d.label} \u2192 "${a.name}"${u}`,data:{schema:"kadence/v1",ok:!0,task:{id:d.id,label:d.label},sprint:a.id}}}function Ln(e,n){let r=h(e,n);if(!b(r))return r;let{state:t,warnings:s}=k(r.root,r.actor),i=j(t);if(i===void 0)return{ok:!1,exitCode:1,message:`No active sprint.
73
- kadence sprint create "Sprint 1"`};let o=V(t,i.id);F(r,"sprint.closed",i.id,{velocity:o.velocity});let a=[...s];return o.unestimated.length>0&&a.push(`${o.unestimated.length} completed task(s) without an estimate were left out of velocity: `+o.unestimated.map(d=>d.label).join(", ")),{ok:!0,exitCode:0,warnings:a,message:jt(o),data:{schema:"kadence/v1",ok:!0,report:Oe(o)}}}function Jn(e,n){let r=h(e,n);if(!b(r))return r;let{state:t,warnings:s}=k(r.root,r.actor),i=j(t);if(i===void 0)return{ok:!0,exitCode:0,warnings:s,message:`No active sprint.
74
- kadence sprint create "Sprint 1"`,data:{schema:"kadence/v1",ok:!0,sprint:null}};let o=V(t,i.id),a=[`"${o.name}" \u2014 ${o.velocity} of ${o.committed} points`,"",...o.done.map(d=>` \u2713 ${d.label} ${d.title}`),...o.carriedOver.map(d=>` \xB7 ${d.label} ${d.title} (${d.status})`)];return{ok:!0,exitCode:0,warnings:s,message:a.join(`
75
- `),data:{schema:"kadence/v1",ok:!0,report:Oe(o)}}}function jt(e){let n=[`Sprint "${e.name}" closed.`,""];if(n.push(` Velocity: ${e.velocity} of ${e.committed} points`),e.hoursPerPoint!==null&&e.actualHours!==null&&e.actualHours>=1/60&&n.push(` Actual: ${z(e.actualHours)} \u2014 ${z(e.hoursPerPoint)} per point`),e.loggedHours>0&&n.push(` Logged: ${z(e.loggedHours)} entered by hand`),e.carriedOver.length>0){n.push("",` Carried over (${e.carriedOver.length}):`);for(let r of e.carriedOver)n.push(` \xB7 ${r.label} ${r.title}`)}return e.cancelled.length>0&&n.push("",` Cancelled (${e.cancelled.length}) \u2014 not counted towards velocity`),n.join(`
76
- `)}function z(e){return e<1?`${Math.round(e*60)}m`:e<10?`${e.toFixed(1)}h`:`${Math.round(e)}h`}function Oe(e){return{id:e.id,name:e.name,status:e.status,velocity:e.velocity,committed:e.committed,actualHours:e.actualHours,hoursPerPoint:e.hoursPerPoint,done:e.done.map(n=>n.label),carriedOver:e.carriedOver.map(n=>n.label),cancelled:e.cancelled.map(n=>n.label),unestimated:e.unestimated.map(n=>n.label),loggedHours:e.loggedHours}}function Un(e,n,r){let t=h(e,n);if(!b(t))return t;let{state:s,warnings:i}=k(t.root,t.actor),o=j(s);if(o!==void 0)return{ok:!1,exitCode:1,message:`Sprint "${o.name}" is still active.
77
- Close it so velocity can be computed:
78
- kadence sprint close`};let a=Pt(s),d=r===void 0?a[0]:_(s,r);return d===void 0?{ok:!1,exitCode:1,message:r===void 0?`No planned sprints.
79
- kadence sprint create "Sprint 2"`:`No sprint named "${r}".
80
- kadence sprint list`}:d.status!=="planned"?{ok:!1,exitCode:1,message:`Sprint "${d.name}" is already ${d.status}.`}:(F(t,"sprint.started",d.id,{}),{ok:!0,exitCode:0,warnings:i,message:`Sprint "${d.name}" started.
81
-
82
- kadence sprint status`,data:{schema:"kadence/v1",ok:!0,sprint:{id:d.id,name:d.name}}})}function Kn(e,n){let r=h(e,n);if(!b(r))return r;let{state:t,warnings:s}=k(r.root,r.actor);if(t.sprints.length===0)return{ok:!0,exitCode:0,warnings:s,message:`No sprints yet.
83
- kadence sprint create "Sprint 1"`,data:{schema:"kadence/v1",ok:!0,sprints:[]}};let i=t.sprints.map(o=>{let a=t.tasks.filter(u=>u.sprint===o.id),d=a.reduce((u,c)=>u+(c.estimate??0),0);return{sprint:o,tasks:a,points:d}});return{ok:!0,exitCode:0,warnings:s,message:i.map(({sprint:o,tasks:a,points:d})=>{let u=o.status==="active"?"\u2192":" ",c=a.length===0?"":` ${a.length} tasks, ${d} points`;return`${u} ${o.name.padEnd(20)} ${o.status.padEnd(8)}${c}`}).join(`
84
- `),data:{schema:"kadence/v1",ok:!0,sprints:i.map(({sprint:o,tasks:a,points:d})=>({id:o.id,name:o.name,status:o.status,taskIds:o.taskIds,taskCount:a.length,points:d}))}}}function At(e){if(!/^\d{4}-\d{2}-\d{2}$/.test(e))return!1;let n=new Date(`${e}T00:00:00.000Z`);return!Number.isNaN(n.getTime())&&n.toISOString().slice(0,10)===e}function Hn(e,n,r,t){let s=h(e,n);if(!b(s))return s;for(let[l,p]of[["--start",t.startDate],["--end",t.endDate]])if(p!==void 0&&p!==""&&!At(p))return{ok:!1,exitCode:2,message:`${l} must be YYYY-MM-DD, got "${p}".
85
- kadence sprint edit --start 2026-09-01`};let{state:i,warnings:o}=k(s.root,s.actor),a=r===void 0?j(i):_(i,r);if(a===void 0)return{ok:!1,exitCode:1,message:r===void 0?`No active sprint.
86
- kadence sprint list`:`No sprint named "${r}".
87
- kadence sprint list`};if(a.status==="closed")return{ok:!1,exitCode:1,message:`Sprint "${a.name}" is closed \u2014 its record is not rewritten.`};if(t.name!==void 0&&t.name!==a.name&&_(i,t.name)!==void 0)return{ok:!1,exitCode:2,message:`Sprint "${t.name}" already exists.`};let d=t.startDate??a.startDate??"",u=t.endDate??a.endDate??"";if(d!==""&&u!==""&&u<d)return{ok:!1,exitCode:2,message:`The end date (${u}) is before the start date (${d}).`};let c={},f=[];return t.name!==void 0&&t.name!==a.name&&(c.name=t.name,f.push("name")),t.description!==void 0&&t.description!==(a.description??"")&&(c.description=t.description,f.push("description")),t.startDate!==void 0&&t.startDate!==(a.startDate??"")&&(c.startDate=t.startDate,f.push("start")),t.endDate!==void 0&&t.endDate!==(a.endDate??"")&&(c.endDate=t.endDate,f.push("end")),f.length===0?{ok:!0,exitCode:0,warnings:o,message:`"${a.name}": nothing changed.`}:(F(s,"sprint.updated",a.id,c),{ok:!0,exitCode:0,warnings:o,message:`"${a.name}": updated ${f.join(", ")}.`,data:{schema:"kadence/v1",ok:!0,sprint:{id:a.id,changed:f}}})}function Yn(e,n,r){let t=h(e,n);if(!b(t))return t;let{state:s,warnings:i}=k(t.root,t.actor),o=r===void 0?j(s):_(s,r);if(o===void 0)return{ok:!1,exitCode:1,message:r===void 0?`No active sprint.
88
- kadence sprint list`:`No sprint named "${r}".
89
- kadence sprint list`};let a=je(s,I(t.root).events,o);return a===null?{ok:!0,exitCode:0,warnings:i,message:`"${o.name}" has no tasks yet.
90
- kadence sprint add KAD-1`,data:{schema:"kadence/v1",ok:!0,burndown:null}}:{ok:!0,exitCode:0,warnings:i,message:Ae(a),data:{schema:"kadence/v1",ok:!0,burndown:a}}}export{ce as a,O as b,M as c,w as d,$ as e,Ot as f,Ie as g,D as h,R as i,Z as j,qt as k,H as l,un as m,h as n,b as o,ln as p,k as q,cn as r,pn as s,Re as t,fn as u,gn as v,mn as w,kn as x,yn as y,hn as z,bn as A,xn as B,vn as C,En as D,Dn as E,Mn as F,Bn as G,Ln as H,Jn as I,Un as J,Kn as K,Hn as L,Yn as M};