kadence 0.3.2 → 0.4.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 +346 -0
- package/README.md +90 -11
- package/dist/chunks/board-YUJ6VL5O.js +12 -0
- package/dist/chunks/chunk-CDGGOWGY.js +10 -0
- package/dist/chunks/chunk-FKPFXIL4.js +224 -0
- package/dist/chunks/ui-BZTPZE22.js +7 -0
- package/dist/cli.js +247 -60
- package/package.json +1 -1
- package/dist/chunks/board-7RVHIQJQ.js +0 -12
- package/dist/chunks/chunk-EPFIY2MT.js +0 -199
- package/dist/chunks/ui-HHJ5TWYZ.js +0 -7
package/package.json
CHANGED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import v from"blessed";var c={border:"gray",borderFocus:"cyan",headerFg:"white",headerBg:"blue",selectedFg:"black",selectedBg:"cyan",dim:"gray",hint:"gray",warn:"yellow",danger:"red"},oe={backlog:"gray",todo:"white",in_progress:"blue",doing:"blue",blocked:"red",in_review:"magenta",review:"magenta",done:"green",shipped:"green"};function W(s){return oe[s]??"white"}var le={urgent:"\u203C",high:"\u2191",normal:" ",low:"\u2193"},ae={urgent:"red",high:"yellow",normal:"white",low:"gray"},ue={bug:"\u2716",story:"\u25C6",epic:"\u2B22",task:"\xB7"};function E(s,i){return`{${i}-fg}${s}{/}`}function H(s,i){let d=E(le[s.priority],ae[s.priority]),g=E(ue[s.type]??"\xB7","gray"),a=E(s.label,"cyan"),u=[];if(s.blockedBy.length>0&&u.push(E("\u2298","red")),s.comments.length>0&&u.push(E("\u{1F4AC}","gray")),s.due!==null){let $=s.due<new Date().toISOString().slice(0,10);u.push(E($?"\u23F0":"\u{1F4C5}",$?"red":"gray"))}let f=[s.assignee!==null?E(`@${s.assignee.split("@")[0]}`,"gray"):"",s.estimate!==null?E(String(s.estimate),"yellow"):"",u.join("")].filter($=>$.length>0).join(" "),I=`${D(d)}${D(g)} ${D(a)} `,B=f.length>0?` ${D(f)}`:"",P=Math.max(4,i-I.length-B.length),R=[...s.title],x=R.length>P?`${R.slice(0,P-1).join("")}\u2026`:s.title;return`${d}${g} ${a} ${x}${f.length>0?` ${f}`:""}`}function Y(s,i){return i?`{cyan-bg}{black-fg}${D(s)}{/}`:` ${s}`}function z(s,i,d,g=12){let a=`${s.padEnd(g)} ${i}`;return d?`{cyan-bg}{black-fg}\u25B8 ${a}{/}`:` ${a}`}function D(s){return s.replace(/\{[^}]*\}/g,"")}var J=["\u2190\u2192\u2191\u2193 move","enter details","[ ] shift","m status","a assign","c comment","e edit","n new","s sprint","/ filter","? help","q quit (Ctrl-C forces)"].join(" ");function V(s){let i=[],d=!1;function g(){d=!0,setImmediate(()=>{d=!1})}return{dispatch(a){if(d)return;let u=i[i.length-1];u!==void 0?u(a):s(a)},push(a){i.push(a),g();let u=!1;return()=>{if(u)return;u=!0;let f=i.lastIndexOf(a);f!==-1&&i.splice(f,1),g()}},isDialogOpen:()=>i.length>0,depth:()=>i.length}}function X(s){if(s.ch==="")return!1;let i=s.ch.charCodeAt(0);return i<32||i===127}var de=["up","down","pageup","pagedown","home","end"],Q=["escape","q"];function _(s){return de.includes(s.name)}function Z(s){return Q.includes(s.name)||Q.includes(s.ch)}function M(s,i,d){return d===0?0:(s+i+d)%d}var ee="cancelled";function me(s){let i=v.screen({smartCSR:!0,title:"kadence",fullUnicode:!0,mouse:!0}),{state:d}=s.reload(),g="",a=[],u=0,f=V(t=>se(t));function I(t=0){try{i.destroy()}catch{}process.exit(t)}process.on("SIGINT",()=>I(0)),process.on("SIGTERM",()=>I(0)),i.program.on("keypress",(t,n)=>{let r={ch:t??"",name:n?.name??""};(r.name==="C-c"||r.ch==="")&&I(0),!(X(r)&&r.name!=="enter"&&r.name!=="escape")&&f.dispatch(r)});let B=v.box({parent:i,top:0,height:1,width:"100%",tags:!0,style:{fg:c.headerFg,bg:c.headerBg}}),P=v.box({parent:i,bottom:0,height:1,width:"100%",tags:!0,content:` ${J}`,style:{fg:c.hint}}),R=v.box({parent:i,bottom:1,height:1,width:"100%",tags:!0,style:{fg:c.warn}});function x(t,n=c.warn){R.setContent(` ${t}`),R.style.fg=n,i.render()}function $(){let t=d.statuses.filter(r=>r!==ee),n=d.orphanStatuses.filter(r=>r!==ee);return[...t,...n]}function te(t){let n=g.toLowerCase();return d.tasks.filter(r=>r.status===t&&(n===""||r.title.toLowerCase().includes(n)||(r.assignee??"").toLowerCase().includes(n)||r.labels.some(e=>e.toLowerCase().includes(n))))}function N(){for(let r of a)r.box.destroy();a=[];let t=$(),n=Math.max(Math.floor(100/Math.max(t.length,1)),12);t.forEach((r,e)=>{let o=v.box({parent:i,top:1,left:`${e*n}%`,width:`${n}%`,bottom:2,label:` ${r} `,border:{type:"line"},style:{border:{fg:c.border},label:{fg:W(r)}}}),h=v.list({parent:o,top:0,left:0,right:0,bottom:0,keys:!1,mouse:!1,interactive:!1,tags:!0,scrollable:!0,style:{selected:{fg:c.selectedFg,bg:c.selectedBg},item:{fg:"white"}}});a.push({status:r,box:o,list:h,tasks:[],cursor:0})})}function p(t=!1){t&&(d=s.reload().state),a.length!==$().length&&N();let n=0,r=0;a.forEach((l,S)=>{l.tasks=te(l.status),n+=l.tasks.length,r+=l.tasks.reduce((C,T)=>C+(T.estimate??0),0);let K=l.box.width-4;l.cursor=Math.min(l.cursor,Math.max(0,l.tasks.length-1)),l.list.setItems(l.tasks.map((C,T)=>Y(H(C,K),S===u&&T===l.cursor)));let L=l.tasks.reduce((C,T)=>C+(T.estimate??0),0);l.box.setLabel(` ${l.status} (${l.tasks.length}${L>0?`, ${L}`:""}) `),l.box.style.border.fg=S===u?c.borderFocus:c.border});let e=d.sprints.find(l=>l.status==="active"),o=e===void 0?"no active sprint":e.name,h=g===""?"":` filter: "${g}"`;B.setContent(` kadence ${o} ${n} tasks, ${r} points${h}`),d.cycles.length>0&&x(`${d.cycles.length} dependency cycle(s) \u2014 see kadence task list`,c.danger),i.render()}function w(){let t=a[u];return t?.tasks[t.cursor]}function A(){a.forEach((t,n)=>{let r=t.box.width-4;t.list.setItems(t.tasks.map((e,o)=>Y(H(e,r),n===u&&o===t.cursor))),t.box.style.border.fg=n===u?c.borderFocus:c.border}),i.render()}function m(t){t!==null?x(t,c.warn):x(""),p(!0)}function k(t,n,r){let e=f.push(()=>{}),o=v.prompt({parent:i,top:"center",left:"center",width:"60%",height:7,border:{type:"line"},style:{border:{fg:c.borderFocus}},keys:!0,mouse:!0});o.input(t,n,(h,l)=>{o.destroy(),e(),i.render(),typeof l=="string"&&r(l.trim())})}function ne(t){let n=v.box({parent:i,top:"center",left:"center",width:"75%",height:"80%",border:{type:"line"},label:` ${t.label} `,style:{border:{fg:c.borderFocus}},tags:!0,keys:!0,mouse:!0}),r=[{key:"title",label:"title",value:()=>t.title,hint:"Title:"},{key:"description",label:"description",value:()=>(t.description??"\u2014").split(`
|
|
3
|
-
`)[0]??"\u2014",hint:"Description (one line here, e for $EDITOR):"},{key:"status",label:"status",value:()=>t.status,hint:`Status (${$().join(", ")}):`},{key:"type",label:"type",value:()=>t.type,hint:"Type (task, bug, story, epic):"},{key:"priority",label:"priority",value:()=>t.priority,hint:"Priority (low, normal, high, urgent):"},{key:"assignee",label:"assignee",value:()=>t.assignee??"\u2014",hint:'Assignee (or "none"):'},{key:"estimate",label:"estimate",value:()=>t.estimate===null?"\u2014":String(t.estimate),hint:"Estimate in points:"},{key:"due",label:"due",value:()=>t.due??"\u2014",hint:"Due date YYYY-MM-DD (empty clears):"},{key:"labels",label:"labels",value:()=>t.labels.length>0?t.labels.join(", "):"\u2014",hint:"Labels, comma separated:"}],e=v.list({parent:n,top:0,left:1,right:1,height:r.length,keys:!1,mouse:!1,interactive:!1,tags:!0,style:{selected:{fg:c.selectedFg,bg:c.selectedBg}}}),o=0,h=v.box({parent:n,top:r.length+1,left:1,right:1,bottom:0,tags:!0,scrollable:!0});function l(){e.setItems(r.map((y,O)=>z(y.label,y.value(),O===o)));let b=[t.blockedBy.length>0?`{red-fg}blocked by ${t.blockedBy.length} task(s){/}`:"",t.parent!==null?"{gray-fg}has a parent{/}":"",t.loggedHours>0?`{gray-fg}logged ${t.loggedHours.toFixed(1)}h{/}`:"","",t.description!==null&&t.description.includes(`
|
|
4
|
-
`)?`{gray-fg}${t.description.split(`
|
|
5
|
-
`).slice(1).join(`
|
|
6
|
-
`)}{/}`:"",t.comments.length>0?`{cyan-fg}comments (${t.comments.length}){/}`:"",...t.comments.map(y=>` {gray-fg}${y.author}:{/} ${y.text}`),"","{gray-fg}\u2191\u2193 field enter edit e description in $EDITOR esc close{/}","{gray-fg}description opens the editor, so it can hold paragraphs{/}"].filter(y=>y!=="");h.setContent(b.join(`
|
|
7
|
-
`)),i.render()}l();let S=f.push(b=>T(b)),K=()=>{S(),n.destroy(),p(!0)};function L(){d=s.reload().state;let b=d.tasks.find(y=>y.id===t.id);if(b===void 0){K();return}Object.assign(t,b),l()}function C(){let b=G(()=>s.edit(t.id));b!==null&&x(b),L()}function T(b){let{ch:y,name:O}=b;if(O==="up"||y==="k")return o=M(o,-1,r.length),l();if(O==="down"||y==="j")return o=M(o,1,r.length),l();if(Z(b))return K();if(y==="e")return C();if(O==="enter"){let j=r[o];if(j===void 0)return;if(j.key==="description")return C();k(j.hint,j.value()==="\u2014"?"":j.value(),ie=>{let U=s.setField(t.id,j.key,ie);U!==null&&x(U),L()})}}i.render()}function re(){let t=["{cyan-fg}Navigation{/}"," \u2190 \u2192 h l move between columns"," \u2191 \u2193 k j move between tasks"," enter task details"," / filter escape clears it"," r reload from the journal","","{cyan-fg}Task actions{/}"," [ ] move one column left or right"," m move to a named status"," a assign c comment"," e edit description in $EDITOR"," p priority t log time"," n new task d delete","","{cyan-fg}Sprint{/}"," s sprint menu: status, start, close, burndown"," S add the selected task to the active sprint","","{cyan-fg}Mouse{/}"," click select a card"," drag move a card to another column","","{gray-fg}press any key to close{/}"],n=v.box({parent:i,top:"center",left:"center",width:60,height:Math.min(t.length+2,30),border:{type:"line"},label:" Keys ",style:{border:{fg:c.borderFocus}},tags:!0,scrollable:!0,keys:!0,mouse:!0,content:t.join(`
|
|
8
|
-
`)}),r=f.push(e=>{_(e)||(r(),n.destroy(),p())});n.on("click",()=>{r(),n.destroy(),p()}),i.render()}function q(t,n,r){let e=r.length>0?`
|
|
9
|
-
|
|
10
|
-
{gray-fg}${r.map(l=>`${l.key} ${l.label}`).join(" ")} esc close{/}`:`
|
|
11
|
-
|
|
12
|
-
{gray-fg}press any key to close{/}`,o=v.box({parent:i,top:"center",left:"center",width:"80%",height:"70%",border:{type:"line"},label:` ${t} `,style:{border:{fg:c.borderFocus}},tags:!0,scrollable:!0,mouse:!0,content:n+e}),h=f.push(l=>{if(_(l))return;let S=r.find(K=>K.key===l.ch);h(),o.destroy(),S!==void 0?S.run():p()});i.render()}function se(t){let{ch:n,name:r}=t;if(r==="left"||n==="h")return u=Math.max(0,u-1),p();if(r==="right"||n==="l")return u=Math.min(a.length-1,u+1),p();if(r==="up"||n==="k"){let e=a[u];e!==void 0&&(e.cursor=M(e.cursor,-1,e.tasks.length),A());return}if(r==="down"||n==="j"){let e=a[u];e!==void 0&&(e.cursor=M(e.cursor,1,e.tasks.length),A());return}if(r==="enter"){let e=w();e!==void 0&&ne(e);return}if(n==="["||n==="]"){let e=w();if(e===void 0)return;let o=n==="]"?1:-1,h=a[u+o];return h===void 0?void 0:(m(s.move(e.id,h.status)),u+=o,p())}if(n==="m"){let e=w();return e===void 0?void 0:k(`Move ${e.label} to (${$().join(", ")}):`,"",o=>m(s.move(e.id,o)))}if(n==="a"){let e=w();return e===void 0?void 0:k(`Assign ${e.label} to (or "none"):`,e.assignee??"",o=>m(s.assign(e.id,o)))}if(n==="c"){let e=w();return e===void 0?void 0:k(`Comment on ${e.label}:`,"",o=>m(s.comment(e.id,o)))}if(n==="t"){let e=w();return e===void 0?void 0:k(`Log time on ${e.label} (2h, 90m, -30m):`,"",o=>m(s.logTime(e.id,o)))}if(n==="p"){let e=w();return e===void 0?void 0:k(`Priority for ${e.label} (low, normal, high, urgent):`,e.priority,o=>m(s.setPriority(e.id,o)))}if(n==="n")return k("New task title:","",e=>m(s.create(e)));if(n==="d"){let e=w();return e===void 0?void 0:k(`Delete ${e.label}? type "yes":`,"",o=>{o.toLowerCase()==="yes"?m(s.remove(e.id)):x("Not deleted.")})}if(n==="e"){let e=w();return e===void 0?void 0:m(G(()=>s.edit(e.id)))}if(n==="S"){let e=w();return e===void 0?void 0:m(s.addToSprint(e.id))}if(n==="s")return q("Sprint",s.sprintStatus(),[{key:"b",label:"burndown",run:()=>q("Burndown",s.burndown(),[])},{key:"n",label:"start next sprint",run:()=>m(s.sprintStart())},{key:"x",label:"close sprint",run:()=>m(s.sprintClose())}]);if(n==="/")return k("Filter (title, assignee or label):",g,e=>{g=e==="*"?"":e,p()});if(r==="escape"&&g!=="")return g="",x("Filter cleared."),p();if(n==="r")return x("Reloaded."),p(!0);if(n==="?")return re();(n==="q"||r==="C-c")&&I(0)}function G(t){let n=i;n.leave();let r=t();return n.enter(),r}let F=null;a.forEach(()=>{}),i.on("mousedown",t=>{if(f.isDialogOpen())return;let n=a.findIndex(h=>{let l=h.box.left;return t.x>=l&&t.x<l+h.box.width});if(n===-1)return;u=n;let r=a[n],e=t.y-r.box.top-1,o=r.tasks[e];o!==void 0&&(r.cursor=e,F={task:o,from:n}),p()}),i.on("mouseup",t=>{if(f.isDialogOpen()||F===null)return;let n=a.findIndex(r=>{let e=r.box.left;return t.x>=e&&t.x<e+r.box.width});n!==-1&&n!==F.from&&(m(s.move(F.task.id,a[n].status)),u=n,p()),F=null}),N(),p()}export{me as runBoardUi};
|
|
@@ -1,199 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
function re(e){return`<!-- generated by kadence ${e} \u2014 refresh with \`kadence init\` -->`}function Zt(e){return`${re(e)}
|
|
3
|
-
# kadence \u2014 for AI agents
|
|
4
|
-
|
|
5
|
-
This project's tasks live here as plain files. Read them directly, or through
|
|
6
|
-
the CLI. No server required.
|
|
7
|
-
|
|
8
|
-
## Commands
|
|
9
|
-
|
|
10
|
-
kadence board --json the whole board
|
|
11
|
-
kadence task list --json all tasks
|
|
12
|
-
kadence task show KAD-42 --json one task with its history
|
|
13
|
-
kadence task add "title" -d "..." --type bug --estimate 3
|
|
14
|
-
kadence task move KAD-42 in_progress
|
|
15
|
-
kadence task assign KAD-42 you@example.com
|
|
16
|
-
kadence sprint status --json current sprint progress
|
|
17
|
-
|
|
18
|
-
## JSON contract
|
|
19
|
-
|
|
20
|
-
Every \`--json\` response carries \`schema: "kadence/v1"\`. stdout holds JSON and
|
|
21
|
-
nothing else; warnings go to stderr. Exit codes: 0 success, 1 runtime error,
|
|
22
|
-
2 bad arguments.
|
|
23
|
-
|
|
24
|
-
The contract itself is machine-readable \u2014 read it instead of guessing:
|
|
25
|
-
|
|
26
|
-
kadence schema --json
|
|
27
|
-
|
|
28
|
-
It lists every command, the fields you can rely on, and every error code. It
|
|
29
|
-
works outside a repository, so you can read it before \`init\`.
|
|
30
|
-
|
|
31
|
-
## When something fails
|
|
32
|
-
|
|
33
|
-
A failed \`--json\` call carries \`error.code\` \u2014 branch on that, not on the
|
|
34
|
-
sentence. Where the valid set is knowable it also carries \`allowed\`:
|
|
35
|
-
|
|
36
|
-
{ "ok": false,
|
|
37
|
-
"error": { "code": "unknown_status", "received": "shipped",
|
|
38
|
-
"allowed": ["backlog", "in_progress", "done"],
|
|
39
|
-
"hint": "kadence board statuses --json" } }
|
|
40
|
-
|
|
41
|
-
Statuses are configured per project, so \`allowed\` is the only reliable source \u2014
|
|
42
|
-
never assume the defaults. Retrying an identical command never helps: there is no
|
|
43
|
-
network and no lock, so the same input always fails the same way.
|
|
44
|
-
|
|
45
|
-
## Working as an agent
|
|
46
|
-
|
|
47
|
-
Set \`KADENCE_SOURCE=agent\` so events record your authorship. Without it an
|
|
48
|
-
event is marked as human \u2014 we do not guess.
|
|
49
|
-
|
|
50
|
-
## Why to ask rather than read the files
|
|
51
|
-
|
|
52
|
-
You cannot find a task by its label in the journal. \`KAD-3\` is derived while
|
|
53
|
-
folding and is never stored in an event, so \`grep -r "KAD-3" .kadence/events/\`
|
|
54
|
-
returns nothing. Folding the journal yourself is the only alternative to asking.
|
|
55
|
-
|
|
56
|
-
Asking is also cheaper, and stays cheap: \`task show --json\` is about 950 bytes
|
|
57
|
-
whether the project holds ten tasks or a thousand, while the journal behind it
|
|
58
|
-
grows past 500 KB.
|
|
59
|
-
|
|
60
|
-
\`board --json\` is the exception: it returns every task in full, which on a large
|
|
61
|
-
project is a lot of description you did not ask for. Narrow it:
|
|
62
|
-
|
|
63
|
-
kadence board --json --fields label,status,assignee
|
|
64
|
-
kadence task list --json --fields id,label,status
|
|
65
|
-
|
|
66
|
-
\`kadence schema --json\` lists every selectable field.
|
|
67
|
-
|
|
68
|
-
## Recording why
|
|
69
|
-
|
|
70
|
-
The journal holds what happened. \`decision\` holds why, which the code and
|
|
71
|
-
\`git log\` never carry:
|
|
72
|
-
|
|
73
|
-
kadence decision add "Use ULIDs" --why "Clocks disagree between machines" \\
|
|
74
|
-
--rejected "Auto-increment: collides across branches" --task KAD-1
|
|
75
|
-
|
|
76
|
-
\`--why\` is required: without it the record is a changelog line. \`--rejected\` is
|
|
77
|
-
what stops the next agent proposing the thing that was already turned down.
|
|
78
|
-
|
|
79
|
-
When a decision stops being true, do not edit it \u2014 supersede it:
|
|
80
|
-
|
|
81
|
-
kadence decision add "Use signed tokens" --why "..." --supersedes DEC-1
|
|
82
|
-
|
|
83
|
-
One event writes both directions. \`decision list\` then returns only what is
|
|
84
|
-
still in force; pass \`--all\` when you need the history too. **Read the default,
|
|
85
|
-
not \`--all\`** \u2014 a reversed reason quoted as current is worse than no memory.
|
|
86
|
-
|
|
87
|
-
## Documents
|
|
88
|
-
|
|
89
|
-
\`kadence task doc KAD-1 docs/design.md\` links a document to a task, and
|
|
90
|
-
\`task show --json\` returns the links. kadence does not store the document: it
|
|
91
|
-
stays plain markdown in the repository. The link is the part git cannot express.
|
|
92
|
-
|
|
93
|
-
## What not to do
|
|
94
|
-
|
|
95
|
-
Do not hand-edit files under \`.kadence/events/\`: the journal is appended to,
|
|
96
|
-
never modified. To correct the state, add a new event through the CLI.
|
|
97
|
-
`}var se="<!-- kadence:begin -->",Z="<!-- kadence:end -->";function He(e){return`${se}
|
|
98
|
-
${re(e)}
|
|
99
|
-
## Project tasks \u2014 kadence
|
|
100
|
-
|
|
101
|
-
Tasks live in \`.kadence/\` as plain files. Read them directly or via the CLI:
|
|
102
|
-
|
|
103
|
-
kadence board --json the whole board
|
|
104
|
-
kadence task list --json all tasks
|
|
105
|
-
kadence task move KAD-1 done change state
|
|
106
|
-
|
|
107
|
-
kadence schema --json the contract: commands, fields, error codes
|
|
108
|
-
kadence decision list --json why the current choices were made
|
|
109
|
-
|
|
110
|
-
\`--json\` responses carry \`schema: "kadence/v1"\`; stdout is JSON only. A failure
|
|
111
|
-
carries \`error.code\` and, where knowable, \`allowed\`.
|
|
112
|
-
When acting as an agent, set \`KADENCE_SOURCE=agent\`.
|
|
113
|
-
|
|
114
|
-
Details: \`.kadence/README.md\`
|
|
115
|
-
${Z}`}function Vt(e,n){let r=He(n);if(e===null||e.trim().length===0)return`${r}
|
|
116
|
-
`;let t=e.indexOf(se),s=e.indexOf(Z);if(t!==-1&&s!==-1&&s>t){let o=e.slice(0,t),a=e.slice(s+Z.length);return`${o}${r}${a}`}let i=e.endsWith(`
|
|
117
|
-
`)?`
|
|
118
|
-
`:`
|
|
119
|
-
|
|
120
|
-
`;return`${e}${i}${r}
|
|
121
|
-
`}var F=["id","label","title","description","type","priority","status","labels","assignee","reporter","sprint","loggedHours","parent","blockedBy","due","comments","estimate","history"],ie=["not_a_repository","not_initialised","no_git_identity","task_not_found","sprint_not_found","decision_not_found","unknown_status","unknown_type","unknown_priority","unknown_field","invalid_argument","template_not_found","conflicting_state"],We={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.",decision_not_found:"No decision carries that ULID or DEC-N label.",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.",template_not_found:"No template carries that name.",conflicting_state:"The arguments were understood, but the current state does not allow it \u2014 a closed sprint, or one already started."};function zt(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:ie.map(n=>({code:n,meaning:We[n]})),shapes:{task:{required:["id","label","title","status","type","priority","estimate","assignee","blockedBy","loggedHours"],selectable:[...F],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"]},decision:{required:["id","label","title","why","rejected","docs","supersedes","supersededBy","source"],notes:{why:"The reason. Required when recording \u2014 a decision without one is a changelog line.",supersededBy:"Derived while folding from a later decision carrying `supersedes`. Both directions come from one write, so they cannot fall out of step.",docs:"Repository-relative paths. kadence does not store the documents, only the link.",source:'"human" or "agent", from KADENCE_SOURCE at the time of writing. Never guessed: without the variable an event counts as human.',listing:"`decision list` hides superseded decisions unless --all is passed: a reversed reason presented as current is worse than no memory."}},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:"decision add",summary:"Record why something was chosen, and what was turned down.",args:["title"],flags:["--why","--rejected","--task","--supersedes","--doc"],json:!0},{name:"decision list",summary:"Current decisions. Superseded ones need --all.",flags:["--all","--task"],json:!0},{name:"decision show",summary:"One decision in full.",args:["ref"],json:!0},{name:"task doc",summary:"Link a document to a task. The file stays plain markdown in the repo.",args:["ref","path"],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 G=["backlog","todo","in_progress","blocked","in_review","done","cancelled"],Qt="done",Ye="cancelled",N=["task","bug","story","epic"],A=["low","normal","high","urgent"];function ce(e){let n=[...e].sort((c,p)=>c.id<p.id?-1:c.id>p.id?1:0),r=new Map,t=new Map,s=new Map,i=new Map,o=null,a=[],d=[];for(let c of n){if(c.type==="decision.recorded"){let p=c.data??{},k=R=>typeof p[R]=="string"&&p[R].length>0?p[R]:null,$=k("title"),_=k("why");$!==null&&_!==null&&i.set(c.id,{id:c.id,label:"",title:$,why:_,rejected:k("rejected"),task:k("task"),docs:Array.isArray(p.docs)?p.docs.filter(R=>typeof R=="string"):[],supersedes:k("supersedes"),supersededBy:null,at:c.ts,by:c.actor,source:c.source});continue}if(c.type==="template.saved"){let p=typeof c.data?.name=="string"?c.data.name:null;p!==null&&s.set(p,{name:p,fields:c.data?.fields??{},author:c.actor});continue}if(c.type==="board.configured"){let p=c.data?.statuses;if(Array.isArray(p)){let k=p.filter($=>typeof $=="string"&&$.length>0);k.length>0&&(o=k)}continue}if(c.type==="template.deleted"){let p=typeof c.data?.name=="string"?c.data.name:null;p!==null&&s.delete(p);continue}oe(c,r,t,a,d)}let u=d.length>0,l=d;for(;l.length>0;){let c=[];for(let p of l)oe(p,r,t,a,c);if(c.length===l.length){l=c;break}l=c}if(u)for(let c of r.values())c.history.sort((p,k)=>p.id<k.id?-1:1);let f=[...r.values()].sort((c,p)=>c.id<p.id?-1:1);f.forEach((c,p)=>{c.label=`KAD-${p+1}`});let g=new Set(f.map(c=>c.id));for(let c of f)c.parent!==null&&!g.has(c.parent)&&(c.parent=null),c.blockedBy=c.blockedBy.filter(p=>g.has(p));let m=[...i.values()].sort((c,p)=>c.id<p.id?-1:1);m.forEach((c,p)=>{c.label=`DEC-${p+1}`});for(let c of m){if(c.supersedes===null)continue;let p=i.get(c.supersedes);p!==void 0&&(p.supersededBy=c.id)}for(let c of m)c.task!==null&&!g.has(c.task)&&(c.task=null);return{tasks:f,decisions:m,sprints:[...t.values()].sort((c,p)=>c.id<p.id?-1:1),statuses:o??[...G],orphanStatuses:[...new Set(f.map(c=>c.status).filter(c=>!(o??G).includes(c)))].sort(),templates:[...s.values()].sort((c,p)=>c.name.localeCompare(p.name)),cycles:Ge(f),pending:l,rejected:a}}function oe(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:w(i.description),type:ae(i.type),priority:de(i.priority),status:"backlog",labels:ue(i.labels),assignee:w(i.assignee),reporter:e.actor,sprint:null,parent:w(i.parent),blockedBy:[],due:w(i.due),comments:[],docs:[],estimate:typeof i.estimate=="number"?i.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 i.name=="string"?i.name:"(untitled)",description:w(i.description),startDate:w(i.startDate),endDate:w(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=w(i.description)),i.startDate!==void 0&&(a.startDate=w(i.startDate)),i.endDate!==void 0&&(a.endDate=w(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),V(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=Ye;break;case"task.reopened":o.status="in_progress";break;case"task.assigned":o.assignee=w(i.assignee);break;case"task.updated":typeof i.title=="string"&&(o.title=i.title),i.description!==void 0&&(o.description=w(i.description)),i.type!==void 0&&(o.type=ae(i.type)),i.priority!==void 0&&(o.priority=de(i.priority)),i.labels!==void 0&&(o.labels=ue(i.labels)),i.due!==void 0&&(o.due=w(i.due)),typeof i.estimate=="number"&&(o.estimate=i.estimate);break;case"task.parent_set":o.parent=w(i.parent);break;case"task.blocked_by_added":{let a=w(i.blocker);a!==null&&!o.blockedBy.includes(a)&&o.blockedBy.push(a);break}case"task.blocked_by_removed":{let a=w(i.blocker);a!==null&&(o.blockedBy=o.blockedBy.filter(d=>d!==a));break}case"task.doc_linked":{let a=w(i.path);a!==null&&!o.docs.includes(a)&&o.docs.push(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=w(i.text);a!==null&&o.comments.push({id:e.id,author:e.actor,ts:e.ts,text:a});break}default:break}return V(o,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 w(e){return typeof e=="string"&&e.length>0?e:null}function ae(e){return N.includes(e)?e:"task"}function de(e){return A.includes(e)?e:"normal"}function ue(e){return Array.isArray(e)?e.filter(n=>typeof n=="string"&&n.length>0):[]}function Ge(e){let n=new Map(e.map(i=>[i.id,i])),r=[],t=new Set,s=(i,o)=>{let a=new Map,d=(u,l)=>{let f=a.get(u);if(f==="done")return;if(f==="visiting"){let m=l.indexOf(u),c=l.slice(m),p=`${i}:${[...c].sort().join(",")}`;t.has(p)||(t.add(p),r.push({kind:i,path:[...c,u]}));return}a.set(u,"visiting");let g=n.get(u);if(g!==void 0)for(let m of o(g))d(m,[...l,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 le={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(i=>{if(s!==void 0&&s.length>0){let o=i.comments.some(a=>a.text.toLowerCase().includes(s));if(!pe(i.title,s)&&!pe(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 me(e,n){let r=[...e];switch(n){case"priority":return r.sort((t,s)=>le[t.priority]-le[s.priority]);case"due":return r.sort((t,s)=>fe(t.due,s.due,(i,o)=>i<o?-1:i>o?1:0));case"estimate":return r.sort((t,s)=>fe(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 fe(e,n,r){return e===null&&n===null?0:e===null?1:n===null?-1:r(e,n)}function he(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.
|
|
122
|
-
Create the first one:
|
|
123
|
-
kadence task add "title"`:`No tasks match ${n.join(" and ")}.
|
|
124
|
-
Try fewer filters:
|
|
125
|
-
kadence task list`}var q=["created","priority","due","estimate"];function ke(e){return q.includes(e)}import{isAbsolute as jt,join as Rt,relative as Nt}from"node:path";import{execFileSync as qe}from"node:child_process";function ye(e,n){try{return qe("git",n,{cwd:e,encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim()}catch{return null}}function be(e){let n=ye(e,["rev-parse","--show-toplevel"]);return n===null||n.length===0?null:n}function ve(e){let n=ye(e,["config","user.email"]);return n===null||n.length===0?null:n}import{mkdirSync as tt,readdirSync as nt,readFileSync as rt,renameSync as st,rmSync as an,writeFileSync as it}from"node:fs";import{join as O}from"node:path";var Ze=["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","task.doc_linked","template.saved","template.deleted","board.configured","sprint.created","sprint.started","sprint.updated","sprint.closed","sprint.cancelled","sprint.task_added","decision.recorded"],Ve=new Set(Ze),we=/^[0-9ABCDEFGHJKMNPQRSTVWXYZ]{26}$/,ze=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{1,3})?(Z|[+-]\d{2}:\d{2})$/;function Xe(e){return typeof e=="string"&&Ve.has(e)}function Qe(e){if(typeof e!="object"||e===null)return["event"];let n=e,r=[];if((typeof n.id!="string"||!we.test(n.id))&&r.push("id"),Xe(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"||!ze.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"),n.type==="decision.recorded"){let t=n.data??{};for(let s of["title","why"]){let i=t[s];(typeof i!="string"||i.trim().length===0)&&r.push(`data.${s}`)}}return r}function Se(e){let n=e.data?.description;if(typeof n!="string"||!n.includes(`
|
|
126
|
-
`))return JSON.stringify(e);let r={...e,data:{...e.data,description:n.split(`
|
|
127
|
-
`)}};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=et(n);let r=Qe(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 et(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(`
|
|
128
|
-
`)}}:e}var ot=.2;function M(e){return O(e,".kadence")}function U(e){return O(M(e),"events")}function at(e){return O(U(e),"archive")}function dt(e){return e.slice(0,7)}function E(e,n){let r=O(U(e),dt(n.ts));tt(r,{recursive:!0});let t=O(r,`${n.id}.json`),s=O(r,`.${n.id}.tmp`);it(s,`${Se(n)}
|
|
129
|
-
`,"utf8"),st(s,t)}function B(e){let n=U(e),r=[],t=[],s=new Set,i=0,o=X(at(e)),a=new Set(o);for(let u of X(n)){let l;try{l=rt(u,"utf8")}catch{t.push(u);continue}if(a.has(u)){let g;try{g=JSON.parse(l)}catch{t.push(u);continue}if(!Array.isArray(g)){t.push(u);continue}for(let m of g){let c=z(JSON.stringify(m));c.unknownType?i++:c.error!==null||c.event===null?t.push(u):s.has(c.event.id)||(s.add(c.event.id),r.push(c.event))}continue}let f=z(l);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,l)=>u.id<l.id?-1:u.id>l.id?1:0);let d=r.length+t.length;return{events:r,corrupted:t,unknownTypes:i,systemicCorruption:d>0&&t.length/d>ot}}function X(e){let n;try{n=nt(e,{withFileTypes:!0})}catch{return[]}let r=[];for(let t of n){let s=O(e,t.name);t.isDirectory()?r.push(...X(s)):t.name.endsWith(".json")&&r.push(s)}return r}import{randomFillSync as ut}from"node:crypto";var xe="0123456789ABCDEFGHJKMNPQRSTVWXYZ",ct=10,lt=16,$e=2**48-1;function pt(e){let n="",r=e;for(let t=ct-1;t>=0;t--)n=xe[r%32]+n,r=Math.floor(r/32);return n}function ft(e){let n="",r=0,t=0;for(let s of e){for(r=r<<8|s,t+=8;t>=5;)t-=5,n+=xe[r>>>t&31];r&=(1<<t)-1}return n.slice(0,lt)}function gt(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 mt(){let e=-1,n=new Uint8Array(10);return function(t=Date.now()){if(!Number.isInteger(t)||t<0||t>$e)throw new RangeError(`ULID: time out of range 0..${$e}: ${t}`);return t>e?(e=t,ut(n)):gt(n),pt(e)+ft(n)}}var x=mt();import{readFileSync as ht,writeFileSync as kt,renameSync as yt,readdirSync as bt,mkdirSync as vt}from"node:fs";import{join as Ee}from"node:path";var Te="kadence-snapshot/2";function Ce(e){return Ee(M(e),"state.json")}function _e(e,n){let r=wt(U(e)),t=St(e);if(t!==null&&t.version===Te&&t.lastEventId===r.lastEventId&&t.eventCount===r.count)return{state:t.state,fromCache:!0,incomingEvents:0};let s=B(e),i=ce(s.events),o=t===null||n===void 0?0:xt(s.events,t,n);return $t(e,{version:Te,lastEventId:r.lastEventId,eventCount:r.count,state:i}),{state:i,fromCache:!1,incomingEvents:o}}function wt(e){let n="",r=0,t=s=>{let i;try{i=bt(s,{withFileTypes:!0})}catch{return}for(let o of i)if(o.isDirectory())t(Ee(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 St(e){try{let n=JSON.parse(ht(Ce(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 $t(e,n){try{vt(M(e),{recursive:!0});let r=Ce(e),t=`${r}.tmp`;kt(t,JSON.stringify(n),"utf8"),yt(t,r)}catch{}}function xt(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 T={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}${T.reset}`:e}var Tt={done:T.green,in_progress:T.blue,blocked:T.yellow,cancelled:T.dim},Et=72;function je(e,n=Et){let r=[...e];return r.length<=n?e:`${r.slice(0,n-1).join("")}\u2026`}function Q(e){return[...e].length}function De(e,n){let r=n-Q(e);return r>0?e+" ".repeat(r):e}function Re(e,n){if(e.length===0)return`No tasks yet.
|
|
130
|
-
Create the first one:
|
|
131
|
-
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 i=D(De(s.label,r),T.bold,n),o=D(De(s.status,t),Tt[s.status]??T.dim,n),a=s.estimate===null?"":D(` (${s.estimate})`,T.dim,n);return`${i} ${o} ${je(s.title)}${a}`}).join(`
|
|
132
|
-
`)}function Ne(e){return e<=0?null:`Merged ${e} ${e===1?"change":"changes"} from another branch, no conflicts.`}var Ct={urgent:"!!",high:"!",normal:"",low:"v"},_t={bug:"BUG",story:"STORY",task:""};function Ae(e,n){let r=[D(e.label,T.bold,n)],t=Ct[e.priority];t!==""&&r.push(D(t,e.priority==="low"?T.dim:T.yellow,n));let s=_t[e.type]??"";s!==""&&r.push(D(s,T.dim,n)),r.push(je(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(D(`(${i.join(", ")})`,T.dim,n)),` ${r.join(" ")}`}function yn(e,n){if(Object.values(e).reduce((s,i)=>s+i.length,0)===0)return`No tasks yet.
|
|
133
|
-
Create the first one:
|
|
134
|
-
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(D(`${s} (${i.length}${a})`,T.bold,n),...i.map(d=>Ae(d,n)),"")}return t.join(`
|
|
135
|
-
`).trimEnd()}function Dt(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.
|
|
136
|
-
Create the first one:
|
|
137
|
-
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 l=" ".repeat(d),f=u.blockedBy.length>0?D(" [blocked]",T.yellow,n):"";s.push(`${l}${Ae(u,n).trimStart()}${f}`),o(u.id,d+1)}};return o(null,0),s.join(`
|
|
138
|
-
`)}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}${Dt(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(`
|
|
139
|
-
`))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(`
|
|
140
|
-
`)}import{existsSync as Ie}from"node:fs";var jn=G;function h(e,n,r,t={}){return{ok:!1,exitCode:e,message:r,error:{code:n,message:r,...t}}}function j(e){return h(1,"task_not_found",`No task ${e}.
|
|
141
|
-
kadence task list`,{received:e,hint:"kadence task list --json"})}function L(e,n,r,t){return h(2,e,`Unknown ${n} "${r}".
|
|
142
|
-
Available: ${t.join(", ")}`,{received:r,allowed:t})}function b(e,n){let r=be(e);if(r===null)return h(1,"not_a_repository",`kadence lives inside a git repository, and there is none here.
|
|
143
|
-
Create one and try again:
|
|
144
|
-
git init`,{hint:"git init"});if(!Ie(M(r)))return h(1,"not_initialised",`No .kadence/ found here.
|
|
145
|
-
Run:
|
|
146
|
-
npx kadence init`,{hint:"kadence init"});let t=ve(r);if(t===null)return h(1,"no_git_identity",`Git does not know who you are, so there is no author for the event.
|
|
147
|
-
Run:
|
|
148
|
-
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 v(e){return"root"in e}function Rn(e,n,r,t={}){let s=b(e,n);if(!v(s))return s;let i=r.trim();if(i.length===0)return h(2,"invalid_argument","A task needs a title.",{hint:"kadence task list --json"});if(t.type!==void 0&&!N.includes(t.type))return L("unknown_type","type",t.type,N);if(t.priority!==void 0&&!A.includes(t.priority))return L("unknown_priority","priority",t.priority,A);let o;if(t.parent!==void 0){let{state:l}=y(s.root,s.actor),f=C(l,t.parent);if(f===void 0)return{...j(t.parent)};o=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: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}:{}}};E(s.root,d);let u=t.estimate===void 0?`
|
|
149
|
-
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 y(e,n){let r=_e(e,n),t=B(e),s=[],i=Ne(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 C(e,n){let r=n.toUpperCase();return e.tasks.find(t=>t.id===r||t.label===r)}function Fe(e,n){return h(2,"unknown_status",`Unknown status "${e}".
|
|
150
|
-
Available: ${n.join(", ")}
|
|
151
|
-
kadence board config --statuses "todo,doing,done"`,{received:e,allowed:n,hint:"kadence board config --json"})}function Nn(e,n,r){let t=b(e,n);if(!v(t))return t;if(r.type!==void 0&&!N.includes(r.type))return L("unknown_type","type",r.type,N);if(r.priority!==void 0&&!A.includes(r.priority))return L("unknown_priority","priority",r.priority,A);let{fields:s,error:i}=At(r.fields);if(i!==null)return i;if(r.sort!==void 0&&!ke(r.sort))return{...h(2,"invalid_argument",`Unknown sort key "${r.sort}".
|
|
152
|
-
Available: ${q.join(", ")}`,{received:r.sort,allowed:q})};let{state:o,warnings:a}=y(t.root,t.actor);if(r.status!==void 0&&!o.statuses.includes(r.status))return Fe(r.status,o.statuses);let{sort:d,tree:u,...l}=r,f=ge(o.tasks,l),g=d===void 0?f:me(f,d);return g.length===0?{ok:!0,exitCode:0,warnings:a,message:he(l),data:{schema:"kadence/v1",ok:!0,tasks:[]}}:{ok:!0,exitCode:0,warnings:a,message:u===!0?Oe(g,ee(n,process.stdout.isTTY===!0)):Re(g,ee(n,process.stdout.isTTY===!0)),data:{schema:"kadence/v1",ok:!0,tasks:g.map(m=>Me(m,s)),cycles:o.cycles}}}function An(e,n,r,t){let s=b(e,n);if(!v(s))return s;let{state:i,warnings:o}=y(s.root,s.actor);if(!i.statuses.includes(t))return Fe(t,i.statuses);let{tasks:a,error:d}=P(i,r);if(d!==null)return d;let u=[],l=[],f="";for(let m of a){if(m.status===t){l.push(m);continue}let c=m.status;E(s.root,{id:x(),type:"task.moved",entity:m.id,actor:s.actor,ts:new Date().toISOString(),source:s.source,data:{from:c,to:t}}),u.push(m),a.length===1&&i.statuses.indexOf(t)-i.statuses.indexOf(c)>1&&(f=`
|
|
153
|
-
Moved straight from ${c} to ${t}, skipping the stages between.`)}if(u.length===0)return{ok:!0,exitCode:0,warnings:o,message:S("already there",l,`is already ${t}.`)};let g=l.length>0?`
|
|
154
|
-
${l.length} already ${t}.`:"";return{ok:!0,exitCode:0,warnings:o,message:`${S("moved",u,`${u[0].status} \u2192 ${t}`)}${f}${g}`,data:{schema:"kadence/v1",ok:!0,moved:u.map(m=>({id:m.id,label:m.label,to:t}))}}}function At(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:h(2,"invalid_argument","--fields needs at least one field name.",{allowed:F})};let r=n.find(t=>!F.includes(t));return r!==void 0?{fields:null,error:h(2,"unknown_field",`Unknown field "${r}".
|
|
155
|
-
Available: ${F.join(", ")}`,{received:r,allowed:F})}:{fields:n,error:null}}function Me(e,n=null){let r=Ot(e);return n===null?r:Object.fromEntries(n.map(t=>[t,r[t]]))}function Ot(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,docs:e.docs,estimate:e.estimate,history:e.history}}function On(e,n,r,t){let s=b(e,n);if(!v(s))return s;let{state:i,warnings:o}=y(s.root,s.actor),{tasks:a,error:d}=P(i,r);if(d!==null)return d;let u=t.trim().toLowerCase()==="none"?null:t.trim(),l=a.filter(f=>f.assignee!==u);if(l.length===0)return{ok:!0,exitCode:0,warnings:o,message:u===null?S("already unassigned",a,"is already unassigned."):S("already assigned",a,`is already assigned to ${u}.`)};for(let f of l)E(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:o,message:u===null?S("unassigned",l,"unassigned."):S("assigned",l,`\u2192 ${u}`),data:{schema:"kadence/v1",ok:!0,assigned:l.map(f=>({id:f.id,label:f.label,assignee:u}))}}}function Pn(e,n,r){let t=b(e,n);if(!v(t))return t;let{state:s,warnings:i}=y(t.root,t.actor),o=C(s,r);if(o===void 0)return j(r);let a=s.decisions.filter(d=>d.task===o.id&&d.supersededBy===null).map(d=>({id:d.id,label:d.label,title:d.title,why:d.why,rejected:d.rejected,docs:d.docs,source:d.source}));return{ok:!0,exitCode:0,warnings:i,message:Pe(o),data:{schema:"kadence/v1",ok:!0,task:{...Me(o),decisions:a}}}}function In(e,n,r,t){let s=b(e,n);if(!v(s))return s;if(t.type!==void 0&&!N.includes(t.type))return L("unknown_type","type",t.type,N);if(t.priority!==void 0&&!A.includes(t.priority))return L("unknown_priority","priority",t.priority,A);if(t.due!==void 0&&t.due!==""&&!Pt(t.due))return{...h(2,"invalid_argument",`Due date must be YYYY-MM-DD, got "${t.due}".
|
|
156
|
-
kadence task edit KAD-1 --due 2026-09-30`,{received:t.due})};let{state:i,warnings:o}=y(s.root,s.actor),{tasks:a,error:d}=P(i,r);if(d!==null)return d;if(t.title!==void 0&&a.length>1)return{...h(2,"invalid_argument","A title can only be set on one task at a time.")};let u=[],l=new Set;for(let g of a){let m={},c=[];if(t.title!==void 0&&t.title!==g.title&&(m.title=t.title,c.push("title")),t.description!==void 0&&t.description!==(g.description??"")&&(m.description=t.description,c.push("description")),t.type!==void 0&&t.type!==g.type&&(m.type=t.type,c.push("type")),t.priority!==void 0&&t.priority!==g.priority&&(m.priority=t.priority,c.push("priority")),t.due!==void 0&&t.due!==(g.due??"")&&(m.due=t.due,c.push("due")),t.estimate!==void 0&&t.estimate!==g.estimate&&(m.estimate=t.estimate,c.push("estimate")),t.labels!==void 0&&t.labels.join(",")!==g.labels.join(",")&&(m.labels=t.labels,c.push("labels")),c.length!==0){E(s.root,{id:x(),type:"task.updated",entity:g.id,actor:s.actor,ts:new Date().toISOString(),source:s.source,data:m}),u.push(g);for(let p of c)l.add(p)}}if(u.length===0)return{ok:!0,exitCode:0,warnings:o,message:S("unchanged",a,"nothing changed.")};let f=[...l].join(", ");return{ok:!0,exitCode:0,warnings:o,message:S("updated",u,`updated ${f}.`),data:{schema:"kadence/v1",ok:!0,updated:u.map(g=>({id:g.id,label:g.label})),changed:[...l]}}}function Pt(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 Fn(e,n,r){let t=b(e,n);if(!v(t))return t;let{state:s,warnings:i}=y(t.root,t.actor),{tasks:o,error:a}=P(s,r);if(a!==null)return a;let d=o.filter(u=>u.status!=="cancelled");if(d.length===0)return{ok:!0,exitCode:0,warnings:i,message:S("already cancelled",o,"is already cancelled.")};for(let u of d)E(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:i,message:`${S("cancelled",d,"cancelled.")}
|
|
157
|
-
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 Mn(e,n,r){let t=b(e,n);if(!v(t))return t;let{state:s,warnings:i}=y(t.root,t.actor),{tasks:o,error:a}=P(s,r);if(a!==null)return a;for(let u of o)E(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=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}
|
|
158
|
-
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 Bn(e,n,r,t){let s=b(e,n);if(!v(s))return s;let i=t.trim();if(i.length===0)return h(2,"invalid_argument","A link needs a path.",{hint:"kadence task doc KAD-1 docs/design.md"});let{state:o,warnings:a}=y(s.root,s.actor),d=C(o,r);if(d===void 0)return j(r);let u=jt(i)?Nt(s.root,i):i.replace(/^\.\//,""),l=!Ie(Rt(s.root,u));return E(s.root,{id:x(),type:"task.doc_linked",entity:d.id,actor:s.actor,ts:new Date().toISOString(),source:s.source,data:{path:u}}),{ok:!0,exitCode:0,warnings:[...a,...l?[`No file at ${u} \u2014 the link is recorded anyway; it may arrive later.`]:[]],message:`${u} linked to ${d.label}.`,data:{schema:"kadence/v1",ok:!0,task:{id:d.id,label:d.label},doc:u}}}function Ln(e,n,r,t){let s=b(e,n);if(!v(s))return s;let i=t.trim();if(i.length===0)return h(2,"invalid_argument","A comment needs text.",{received:r});let{state:o,warnings:a}=y(s.root,s.actor),d=C(o,r);return d===void 0?j(r):(E(s.root,{id:x(),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:h(2,"invalid_argument","No task given.")};let t=[],s=[];for(let o of r){let a=C(e,o);a===void 0?s.push(o):t.push(a)}return s.length>0?{tasks:[],error:h(1,"task_not_found",`No task ${s.join(", ")} \u2014 nothing was changed.
|
|
159
|
-
All ids must exist before a bulk change runs.
|
|
160
|
-
kadence task list`,{received:s.join(","),hint:"kadence task list --json"})}:{tasks:[...new Map(t.map(o=>[o.id,o])).values()],error:null}}function S(e,n,r){return n.length===1?`${n[0].label}: ${r}`:`${n.length} tasks ${e}: ${n.map(t=>t.label).join(", ")}`}function Kn(e,n,r,t){let s=b(e,n);if(!v(s))return s;let{state:i,warnings:o}=y(s.root,s.actor),{tasks:a,error:d}=P(i,r);if(d!==null)return d;let u=t.trim().toLowerCase()==="none",l=null;if(!u){let m=C(i,t);if(m===void 0)return j(t);if(a.some(c=>c.id===m.id))return h(2,"invalid_argument","A task cannot be its own parent.",{received:r});l=m.id}let f=a.filter(m=>m.parent!==l);if(f.length===0)return{ok:!0,exitCode:0,warnings:o,message:S("unchanged",a,"already there.")};for(let m of f)E(s.root,{id:x(),type:"task.parent_set",entity:m.id,actor:s.actor,ts:new Date().toISOString(),source:s.source,data:{parent:l}});let g=u?"detached":C(i,t).label;return{ok:!0,exitCode:0,warnings:[...o,...Be(s.root,s.actor)],message:u?S("detached",f,"detached from its parent."):S("moved",f,`\u2192 child of ${g}`),data:{schema:"kadence/v1",ok:!0,parent:l}}}function Jn(e,n,r,t,s){let i=b(e,n);if(!v(i))return i;let{state:o,warnings:a}=y(i.root,i.actor),{tasks:d,error:u}=P(o,r);if(u!==null)return u;let l=C(o,t);if(l===void 0)return j(t);if(d.some(g=>g.id===l.id))return h(2,"invalid_argument","A task cannot block itself.",{received:r});let f=d.filter(g=>s?g.blockedBy.includes(l.id):!g.blockedBy.includes(l.id));if(f.length===0)return{ok:!0,exitCode:0,warnings:a,message:S("unchanged",d,s?"was not blocked by it.":"is already blocked by it.")};for(let g of f)E(i.root,{id:x(),type:s?"task.blocked_by_removed":"task.blocked_by_added",entity:g.id,actor:i.actor,ts:new Date().toISOString(),source:i.source,data:{blocker:l.id}});return{ok:!0,exitCode:0,warnings:[...a,...Be(i.root,i.actor)],message:s?S("unblocked",f,`no longer blocked by ${l.label}.`):S("blocked",f,`blocked by ${l.label}.`),data:{schema:"kadence/v1",ok:!0,blocker:l.id}}}function Be(e,n){let{state:r}=y(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 It(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 Un(e,n,r,t){let s=b(e,n);if(!v(s))return s;let i=It(t);if(i===null)return{...h(2,"invalid_argument",`Cannot read "${t}" as a duration.
|
|
161
|
-
Use hours or minutes:
|
|
162
|
-
kadence task log KAD-1 2h
|
|
163
|
-
kadence task log KAD-1 90m
|
|
164
|
-
kadence task log KAD-1 -30m to correct a mistake`,{received:t})};let{state:o,warnings:a}=y(s.root,s.actor),d=C(o,r);if(d===void 0)return j(r);E(s.root,{id:x(),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),l=d.estimate===null?`
|
|
165
|
-
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.${l}`,data:{schema:"kadence/v1",ok:!0,task:{id:d.id,label:d.label,loggedHours:u}}}}import{spawnSync as Ft}from"node:child_process";import{mkdtempSync as Mt,readFileSync as Bt,rmSync as Lt,writeFileSync as Kt}from"node:fs";import{tmpdir as Jt}from"node:os";import{join as Le}from"node:path";var H="#";function Ut(e){return e.GIT_EDITOR??e.VISUAL??e.EDITOR??"vi"}function Zn(e,n,r){let t=Mt(Le(Jt(),"kadence-edit-")),s=Le(t,"KADENCE_EDITMSG.md"),i=["",`${H} ${r}`,`${H} Lines starting with '${H}' are ignored.`,`${H} Save an empty file to abort.`].join(`
|
|
166
|
-
`);try{Kt(s,`${n}${i}
|
|
167
|
-
`,"utf8");let o=Ut(e),a=Ft(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.
|
|
168
|
-
Set one explicitly:
|
|
169
|
-
export EDITOR=nano`};let u=Bt(s,"utf8").split(`
|
|
170
|
-
`).filter(l=>!l.startsWith(H)).join(`
|
|
171
|
-
`).trim();return{text:u.length===0?null:u,error:null}}catch(o){return{text:null,error:`Could not open an editor: ${o.message}`}}finally{Lt(t,{recursive:!0,force:!0})}}function Vn(e,n){return e.KADENCE_SOURCE==="agent"?!1:n}function te(e,n){let r=e.sprints.find(p=>p.id===n);if(r===void 0)return null;let t=e.tasks.filter(p=>p.sprint===n),s=t.filter(p=>p.status==="cancelled"),i=t.filter(p=>p.status!=="cancelled"),o=i.filter(p=>p.status==="done"),a=i.filter(p=>p.status!=="done"),d=W(i.map(p=>p.estimate??0)),u=W(o.map(p=>p.estimate??0)),l=o.filter(p=>p.estimate===null),f=o.map(Ht).filter(p=>p!==null),g=f.length>0?W(f):null,m=W(o.filter(p=>p.estimate!==null).map(p=>p.estimate)),c=g!==null&&m>0?g/m:null;return{id:r.id,name:r.name,status:r.status,committed:d,velocity:u,actualHours:g,hoursPerPoint:c,done:o,carriedOver:a,cancelled:s,unestimated:l,loggedHours:W(t.map(p=>p.loggedHours))}}function Ht(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 W(e){return e.reduce((n,r)=>n+r,0)}function Y(e){return new Date(e).toISOString().slice(0,10)}function Wt(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(Y(t));return r}function Ke(e,n,r,t=Y(Date.now())){let s=e.tasks.filter(k=>k.sprint===r.id&&k.status!=="cancelled"),i=new Map(s.map(k=>[k.id,k.estimate??0])),o=[...i.values()].reduce((k,$)=>k+$,0),a=n.filter(k=>i.has(k.entity));if(a.length===0)return null;let d=r.startDate??Y(a[0].ts),u=r.endDate??Y(a.at(-1).ts),l=r.status==="closed"||u<t?u:t;if(l<d)return null;let f=new Set,g=new Map;for(let k of a){let $=Y(k.ts);if($<d)continue;let _=k.type==="task.moved"?k.data?.to:void 0,R=i.get(k.entity)??0;_==="done"&&!f.has(k.entity)?(f.add(k.entity),g.set($,(g.get($)??0)+R)):_!==void 0&&_!=="done"&&f.has(k.entity)&&(f.delete(k.entity),g.set($,(g.get($)??0)-R))}let m=Wt(d,l),c=Math.max(m.length-1,1),p=o;return{sprintName:r.name,committed:o,finalRemaining:(r.status==="closed",null),days:m.map((k,$)=>{let _=g.get(k)??0;return p-=_,{date:k,remaining:Math.max(0,p),ideal:Math.max(0,o-o/c*$),completed:_}})}}function Je(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 l=0;l<n;l++)l===o&&l>=i?a.push("\u250A"):l<i?a.push(l===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(`
|
|
172
|
-
`)}function I(e){return e.sprints.find(n=>n.status==="active")}function Yt(e){return e.sprints.filter(n=>n.status==="planned")}function K(e,n){let r=n.trim().toLowerCase();return e.sprints.find(t=>t.name.toLowerCase()===r)}function J(e,n,r,t){E(e.root,{id:x(),type:n,entity:r,actor:e.actor,ts:new Date().toISOString(),source:e.source,data:t})}function or(e,n,r){let t=b(e,n);if(!v(t))return t;let s=r.trim();if(s.length===0)return h(2,"invalid_argument","A sprint needs a name.",{hint:"kadence sprint list --json"});let{state:i,warnings:o}=y(t.root,t.actor);if(K(i,s)!==void 0)return h(2,"invalid_argument",`Sprint "${s}" already exists.`,{received:s,hint:"kadence sprint list --json"});let a=I(i)!==void 0,d=x();return J(t,"sprint.created",d,{name:s}),a||J(t,"sprint.started",d,{}),{ok:!0,exitCode:0,warnings:o,message:a?`Sprint "${s}" planned.
|
|
173
|
-
|
|
174
|
-
kadence sprint add KAD-1 --sprint "${s}"
|
|
175
|
-
kadence sprint start "${s}"`:`Sprint "${s}" started.
|
|
176
|
-
|
|
177
|
-
kadence sprint add KAD-1
|
|
178
|
-
kadence sprint status`,data:{schema:"kadence/v1",ok:!0,sprint:{id:d,name:s,status:a?"planned":"active"}}}}function ar(e,n,r,t={}){let s=b(e,n);if(!v(s))return s;let{state:i,warnings:o}=y(s.root,s.actor),a=t.sprint===void 0?I(i):K(i,t.sprint);if(a===void 0)return t.sprint===void 0?{...h(1,"sprint_not_found",`No active sprint.
|
|
179
|
-
kadence sprint create "Sprint 1"`,{hint:"kadence sprint list --json"})}:h(1,"sprint_not_found",`No sprint named "${t.sprint}".
|
|
180
|
-
kadence sprint list`,{received:t.sprint,hint:"kadence sprint list --json"});if(a.status==="closed")return h(1,"conflicting_state",`Sprint "${a.name}" is closed \u2014 its velocity is not rewritten.`,{received:a.name});let d=C(i,r);if(d===void 0)return j(r);if(d.sprint===a.id)return{ok:!0,exitCode:0,warnings:o,message:`${d.label} is already in the sprint.`};J(s,"sprint.task_added",a.id,{task:d.id});let u=d.estimate===null?`
|
|
181
|
-
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 dr(e,n){let r=b(e,n);if(!v(r))return r;let{state:t,warnings:s}=y(r.root,r.actor),i=I(t);if(i===void 0)return{...h(1,"sprint_not_found",`No active sprint.
|
|
182
|
-
kadence sprint create "Sprint 1"`,{hint:"kadence sprint list --json"})};let o=te(t,i.id);J(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:Gt(o),data:{schema:"kadence/v1",ok:!0,report:Ue(o)}}}function ur(e,n){let r=b(e,n);if(!v(r))return r;let{state:t,warnings:s}=y(r.root,r.actor),i=I(t);if(i===void 0)return{ok:!0,exitCode:0,warnings:s,message:`No active sprint.
|
|
183
|
-
kadence sprint create "Sprint 1"`,data:{schema:"kadence/v1",ok:!0,sprint:null}};let o=te(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(`
|
|
184
|
-
`),data:{schema:"kadence/v1",ok:!0,report:Ue(o)}}}function Gt(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(`
|
|
185
|
-
`)}function ne(e){return e<1?`${Math.round(e*60)}m`:e<10?`${e.toFixed(1)}h`:`${Math.round(e)}h`}function Ue(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 cr(e,n,r){let t=b(e,n);if(!v(t))return t;let{state:s,warnings:i}=y(t.root,t.actor),o=I(s);if(o!==void 0)return{...h(1,"conflicting_state",`Sprint "${o.name}" is still active.
|
|
186
|
-
Close it so velocity can be computed:
|
|
187
|
-
kadence sprint close`,{received:o.name})};let a=Yt(s),d=r===void 0?a[0]:K(s,r);return d===void 0?{...h(1,"sprint_not_found",r===void 0?`No planned sprints.
|
|
188
|
-
kadence sprint create "Sprint 2"`:`No sprint named "${r}".
|
|
189
|
-
kadence sprint list`,{...r!==void 0?{received:r}:{},hint:"kadence sprint list --json"})}:d.status!=="planned"?h(1,"conflicting_state",`Sprint "${d.name}" is already ${d.status}.`,{received:d.name}):(J(t,"sprint.started",d.id,{}),{ok:!0,exitCode:0,warnings:i,message:`Sprint "${d.name}" started.
|
|
190
|
-
|
|
191
|
-
kadence sprint status`,data:{schema:"kadence/v1",ok:!0,sprint:{id:d.id,name:d.name}}})}function lr(e,n){let r=b(e,n);if(!v(r))return r;let{state:t,warnings:s}=y(r.root,r.actor);if(t.sprints.length===0)return{ok:!0,exitCode:0,warnings:s,message:`No sprints yet.
|
|
192
|
-
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,l)=>u+(l.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":" ",l=a.length===0?"":` ${a.length} tasks, ${d} points`;return`${u} ${o.name.padEnd(20)} ${o.status.padEnd(8)}${l}`}).join(`
|
|
193
|
-
`),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 qt(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 pr(e,n,r,t){let s=b(e,n);if(!v(s))return s;for(let[g,m]of[["--start",t.startDate],["--end",t.endDate]])if(m!==void 0&&m!==""&&!qt(m))return{...h(2,"invalid_argument",`${g} must be YYYY-MM-DD, got "${m}".
|
|
194
|
-
kadence sprint edit --start 2026-09-01`,{received:m})};let{state:i,warnings:o}=y(s.root,s.actor),a=r===void 0?I(i):K(i,r);if(a===void 0)return{...h(1,"sprint_not_found",r===void 0?`No active sprint.
|
|
195
|
-
kadence sprint list`:`No sprint named "${r}".
|
|
196
|
-
kadence sprint list`,{...r!==void 0?{received:r}:{},hint:"kadence sprint list --json"})};if(a.status==="closed")return{...h(1,"conflicting_state",`Sprint "${a.name}" is closed \u2014 its record is not rewritten.`,{received:a.name})};if(t.name!==void 0&&t.name!==a.name&&K(i,t.name)!==void 0)return h(2,"invalid_argument",`Sprint "${t.name}" already exists.`,{received:t.name});let d=t.startDate??a.startDate??"",u=t.endDate??a.endDate??"";if(d!==""&&u!==""&&u<d)return{...h(2,"invalid_argument",`The end date (${u}) is before the start date (${d}).`,{received:u})};let l={},f=[];return t.name!==void 0&&t.name!==a.name&&(l.name=t.name,f.push("name")),t.description!==void 0&&t.description!==(a.description??"")&&(l.description=t.description,f.push("description")),t.startDate!==void 0&&t.startDate!==(a.startDate??"")&&(l.startDate=t.startDate,f.push("start")),t.endDate!==void 0&&t.endDate!==(a.endDate??"")&&(l.endDate=t.endDate,f.push("end")),f.length===0?{ok:!0,exitCode:0,warnings:o,message:`"${a.name}": nothing changed.`}:(J(s,"sprint.updated",a.id,l),{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 fr(e,n,r){let t=b(e,n);if(!v(t))return t;let{state:s,warnings:i}=y(t.root,t.actor),o=r===void 0?I(s):K(s,r);if(o===void 0)return{...h(1,"sprint_not_found",r===void 0?`No active sprint.
|
|
197
|
-
kadence sprint list`:`No sprint named "${r}".
|
|
198
|
-
kadence sprint list`,{...r!==void 0?{received:r}:{},hint:"kadence sprint list --json"})};let a=Ke(s,B(t.root).events,o);return a===null?{ok:!0,exitCode:0,warnings:i,message:`"${o.name}" has no tasks yet.
|
|
199
|
-
kadence sprint add KAD-1`,data:{schema:"kadence/v1",ok:!0,burndown:null}}:{ok:!0,exitCode:0,warnings:i,message:Je(a),data:{schema:"kadence/v1",ok:!0,burndown:a}}}export{be as a,M as b,U as c,E as d,Zt as e,Vt as f,zt as g,x as h,Qt as i,Ye as j,N as k,A as l,ee as m,yn as n,q as o,jn as p,h as q,j as r,b as s,v as t,Rn as u,y as v,C as w,Nn as x,An as y,At as z,Me as A,On as B,Pn as C,In as D,Fn as E,Mn as F,Bn as G,Ln as H,Kn as I,Jn as J,Un as K,Zn as L,Vn as M,or as N,ar as O,dr as P,ur as Q,cr as R,lr as S,pr as T,fr as U};
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import{B as f,D as u,F as S,H as k,K as x,L as C,M as h,O as y,P as E,Q as A,R as N,U as F,s as b,t as T,u as c,v as l,y as d}from"./chunk-EPFIY2MT.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
|
-
For pipes and scripts use:
|
|
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
|
-
The plain board always works:
|
|
6
|
-
kadence board`}}return g.runBoardUi({reload:()=>l(a.root,a.actor),move:(t,o)=>s(d(r,e,t,o)),assign:(t,o)=>s(f(r,e,t,o)),create:t=>s(c(r,e,t,{})),remove:t=>s(S(r,e,t)),edit:t=>{if(!h(e,!0))return"No editor available.";let{state:o}=l(a.root,a.actor),m=o.tasks.find(i=>i.id===t);if(m===void 0)return"Task not found.";let n=C(e,m.description??"",`Editing the description of ${m.label}.`);return n.error!==null?n.error:n.text===null?"Aborted \u2014 nothing changed.":s(u(r,e,t,{description:n.text}))},comment:(t,o)=>s(k(r,e,t,o)),setField:(t,o,m)=>{let n=m.trim();if(o==="status")return s(d(r,e,t,n));if(o==="assignee")return s(f(r,e,t,n.length===0?"none":n));if(o==="estimate"){let i=Number(n);return!Number.isFinite(i)||i<0?"Estimate must be a positive number.":s(u(r,e,t,{estimate:i}))}if(o==="labels"){let i=n.split(",").map(p=>p.trim()).filter(p=>p.length>0);return s(u(r,e,t,{labels:i}))}return s(u(r,e,t,{[o]:n}))},logTime:(t,o)=>s(x(r,e,t,o)),setPriority:(t,o)=>s(u(r,e,t,{priority:o})),addToSprint:t=>s(y(r,e,t,{})),sprintStatus:()=>A(r,e).message,burndown:()=>F(r,e,void 0).message,sprintStart:()=>s(N(r,e,void 0)),sprintClose:()=>s(E(r,e))}),{ok:!0,exitCode:0,message:""}}function s(r){return r.message.split(`
|
|
7
|
-
`)[0]??""}export{$ as runUi};
|