kadence 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +86 -0
- package/README.md +19 -5
- package/dist/chunks/{board-6UNW5ISX.js → board-5SQP5RX6.js} +1 -1
- package/dist/chunks/chunk-CR5YON2J.js +10 -0
- package/dist/chunks/chunk-J7QEHKDW.js +248 -0
- package/dist/chunks/{ui-Q53SLKMA.js → ui-OTWFK76P.js} +2 -2
- package/dist/cli.js +142 -127
- package/package.json +1 -1
- package/dist/chunks/chunk-CDGGOWGY.js +0 -10
- package/dist/chunks/chunk-FCPGSN7D.js +0 -240
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,92 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.6.0] — 2026-09-23
|
|
6
|
+
|
|
7
|
+
**Documentation in the journal, and an honest answer when something goes
|
|
8
|
+
wrong.** Two halves of the same session. Documentation stops being a filename
|
|
9
|
+
someone has to know and becomes an entity an agent is handed — `DOC-N`, revised,
|
|
10
|
+
conflict-aware. And the three places where kadence told an agent something that
|
|
11
|
+
was not true — a claim it had already lost, a failure with no JSON, a flag
|
|
12
|
+
written twice — now answer straight. The second half came out of a contract
|
|
13
|
+
stress audit run against 0.5.0; the report is in
|
|
14
|
+
`docs/research/contract-stress-audit-2026-09.md`.
|
|
15
|
+
|
|
16
|
+
### ⚠️ Upgrading — everyone updates before anyone runs `compact`
|
|
17
|
+
|
|
18
|
+
`compact` in 0.5.0 and earlier archives the events it can parse and then removes
|
|
19
|
+
the whole month directory, which **deletes `doc.*` events written by 0.6.0**.
|
|
20
|
+
An older kadence reads the journal fine; it just must not compact it. From this
|
|
21
|
+
release on, `compact` leaves alone any month holding an event it cannot read.
|
|
22
|
+
If someone compacted with an old binary, `git status` shows the deleted event
|
|
23
|
+
files — restore them, do not re-run.
|
|
24
|
+
|
|
25
|
+
### Added — documentation is an entity
|
|
26
|
+
|
|
27
|
+
- **`kadence doc`** — `add`, `edit`, `show`, `list`, `link`. A document is
|
|
28
|
+
`DOC-N`, stored as `doc.written` revisions in the journal rather than as an
|
|
29
|
+
`.md` file beside it (ADR-014, superseding that part of ADR-010). Text comes
|
|
30
|
+
from `--body`, `--file` or `--stdin`; `--file` reads any path and keeps
|
|
31
|
+
nothing (DEC-15).
|
|
32
|
+
- **A revision names its parents.** Two people revising the same version leave a
|
|
33
|
+
conflict that is reported and settled by writing text — never a silent loss.
|
|
34
|
+
`doc edit` with no new text on a conflicted document is refused with
|
|
35
|
+
`conflicting_state`, because otherwise it would keep whichever version ULID
|
|
36
|
+
order happened to show and nobody would have read the other.
|
|
37
|
+
- **Agents reach documentation without a search term.** `task show --json`
|
|
38
|
+
carries `documentation[]` (label, title, bytes, `updatedAt`), `prime` names the
|
|
39
|
+
documentation of the work you hold, and `doc list --json` carries no bodies.
|
|
40
|
+
One body arrives only when you ask for it with `doc show`.
|
|
41
|
+
- **A body past 16 KiB is written with a warning, not refused.** Agents read long
|
|
42
|
+
inputs measurably worse; splitting is the author's call, not ours.
|
|
43
|
+
- **`KADENCE_ACTOR`** names the claimant (DEC-16). Without it, an agent in a
|
|
44
|
+
linked worktree claims as `email#<worktree>`. A person owns what their agents
|
|
45
|
+
hold; an agent owns only its own.
|
|
46
|
+
- **`task claim` reports what actually happened** — `claim: claimed |
|
|
47
|
+
already_yours | contested`, read back out of the journal after the write.
|
|
48
|
+
Additive to `kadence/v1`.
|
|
49
|
+
|
|
50
|
+
### Changed
|
|
51
|
+
|
|
52
|
+
- **`prime` puts contested claims first in *Yours*,** each carrying `claimedBy`
|
|
53
|
+
and `contestedBy`, so an agent holding a task it no longer owns sees that
|
|
54
|
+
before it starts working. When every claim is the person's own agents, it says
|
|
55
|
+
so instead: *N of your agents collided — keep one, release the rest.*
|
|
56
|
+
- **`task doc` stays** for linking files that already exist; new writing goes to
|
|
57
|
+
`kadence doc`.
|
|
58
|
+
- **A repeated single-value flag keeps its last value** (DEC-18). Only
|
|
59
|
+
`--label`, `--add-label`, `--remove-label`, `--rejected` and `--doc`
|
|
60
|
+
accumulate. `--title a --title b` had been storing both and reporting success.
|
|
61
|
+
|
|
62
|
+
### Fixed — the contract, where it was quiet
|
|
63
|
+
|
|
64
|
+
- **A parser failure answers in JSON.** An unknown flag, a missing value or an
|
|
65
|
+
extra argument is thrown by cac before any handler runs, and it used to reach
|
|
66
|
+
stderr as a bare sentence with nothing on stdout — the one failure `--json`
|
|
67
|
+
did not cover. It now goes through `failure()`: `invalid_argument` with
|
|
68
|
+
`received` and `allowed`, exit 2.
|
|
69
|
+
- **An unknown command no longer exits 0 with both streams empty,** and a bare
|
|
70
|
+
`kadence` prints help instead of nothing. An exception that is not a cac error
|
|
71
|
+
prints its stack and exits 1, rather than being mislabelled as usage.
|
|
72
|
+
- **`compact` no longer deletes events it cannot parse** along with their month
|
|
73
|
+
directory — see Upgrading.
|
|
74
|
+
- **`task doc` recorded a URL as the mangled path `https:/…`** and `task doc add`
|
|
75
|
+
created a directory named `https:` (KAD-33).
|
|
76
|
+
- **`--body -` was read as a missing value and `--body 007` became `7`.**
|
|
77
|
+
`--stdin` is its own flag now, and text flags are read raw from argv. Two text
|
|
78
|
+
sources at once are refused rather than one winning silently.
|
|
79
|
+
- **`doc link` returned a partial document;** it returns the full shape, pinned
|
|
80
|
+
in the schema contract.
|
|
81
|
+
|
|
82
|
+
### Measured
|
|
83
|
+
|
|
84
|
+
- `claim` re-reads the journal after writing: ~121 ms median at 400 events,
|
|
85
|
+
against ~105 ms for a plain read. An agent without `KADENCE_ACTOR` pays one
|
|
86
|
+
git spawn (~10 ms) in `ready`, `prime` and `claim` to detect a linked
|
|
87
|
+
worktree.
|
|
88
|
+
- `ready` and `prime` now sit at the edge of the 200 ms budget as this
|
|
89
|
+
repository's own journal grows. Recorded as a note, not yet as a fix.
|
|
90
|
+
|
|
5
91
|
## [0.5.0] — 2026-09-16
|
|
6
92
|
|
|
7
93
|
**The second author.** kadence was built for a team, and until now its first
|
package/README.md
CHANGED
|
@@ -292,9 +292,23 @@ no number, and `prime` shows the latest:
|
|
|
292
292
|
kadence note "The staging clock runs 40 s behind" --task KAD-1
|
|
293
293
|
```
|
|
294
294
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
295
|
+
**Documentation lives in the journal too.** How something works now, revised as
|
|
296
|
+
it changes — an entity, `DOC-N`, not a filename an agent has to guess:
|
|
297
|
+
|
|
298
|
+
```bash
|
|
299
|
+
kadence doc add "How auth works" --file notes/auth.md --task KAD-1
|
|
300
|
+
kadence doc show DOC-1 --json
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
A revision names the revisions it was written on top of, so two people editing
|
|
304
|
+
the same version leave a conflict that is reported and settled by writing text,
|
|
305
|
+
never a silent overwrite. Agents are handed it without searching: `task show`
|
|
306
|
+
carries `documentation[]` and `prime` names the documentation of the work you
|
|
307
|
+
hold — both without bodies, so the body arrives only when asked for.
|
|
308
|
+
|
|
309
|
+
A markdown file that already exists is still linked, not swallowed:
|
|
310
|
+
`kadence task doc add KAD-1 docs/design.md` records the link, which is the part
|
|
311
|
+
git cannot express.
|
|
298
312
|
|
|
299
313
|
Bulk works everywhere and is all or nothing: `kadence task move KAD-1,KAD-2 done`
|
|
300
314
|
either moves both or changes nothing. A typo does not leave half a board.
|
|
@@ -320,7 +334,7 @@ true.
|
|
|
320
334
|
|
|
321
335
|
**Verified.** The merge thesis, on real git branches. Performance and size, by
|
|
322
336
|
tests that fail if they regress. That the conflict problem exists in the wild —
|
|
323
|
-
measured, not assumed.
|
|
337
|
+
measured, not assumed. 1060 tests in the repository today, including an
|
|
324
338
|
end-to-end run through the installed binary.
|
|
325
339
|
|
|
326
340
|
**Not verified.** That teams and their AI agents actually lose enough context to want
|
|
@@ -374,7 +388,7 @@ revisit it: [docs/decisions/](docs/decisions/).
|
|
|
374
388
|
|
|
375
389
|
```bash
|
|
376
390
|
npm install
|
|
377
|
-
npm test #
|
|
391
|
+
npm test # 1060 tests; builds dist/cli.js first
|
|
378
392
|
npm run typecheck
|
|
379
393
|
npm run build # one 111 KB bundle, blessed kept external (82 KB at 0.4.1)
|
|
380
394
|
```
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{
|
|
2
|
+
import{q as G}from"./chunk-CR5YON2J.js";import S from"blessed";var c={border:"gray",borderFocus:"cyan",headerFg:"white",headerBg:"blue",selectedFg:"black",selectedBg:"cyan",dim:"gray",hint:"gray",warn:"yellow",danger:"red"},he={backlog:"gray",todo:"white",in_progress:"blue",doing:"blue",blocked:"red",in_review:"magenta",review:"magenta",done:"green",shipped:"green"};function ne(n){return he[n]??"white"}var pe={urgent:"\u203C",high:"\u2191",normal:" ",low:"\u2193"},me={urgent:"red",high:"yellow",normal:"white",low:"gray"},ye={bug:"\u2716",story:"\u25C6",epic:"\u2B22",task:"\xB7"};function k(n,s){return`{${s}-fg}${n}{/}`}function W(n,s){let d=k(pe[n.priority],me[n.priority]),p=k(ye[n.type]??"\xB7","gray"),h=k(n.label,"cyan"),g=[];n.blockedBy.length>0&&g.push(k("\u2298","red")),n.contestedBy.length>0?g.push(k("\u2691","magenta")):n.claimedBy!==null&&g.push(k("\u2713","green"));let E=n.criteria.filter(O=>!O.checked).length;if(E>0?g.push(k(`${n.criteria.length-E}/${n.criteria.length}`,"yellow")):n.criteria.length>0&&g.push(k("\u2611","green")),n.comments.length>0&&g.push(k("\u{1F4AC}","gray")),n.due!==null){let O=n.due<new Date().toISOString().slice(0,10);g.push(k(O?"\u23F0":"\u{1F4C5}",O?"red":"gray"))}let C=[n.assignee!==null?k(`@${n.assignee.split("@")[0]}`,"gray"):"",n.estimate!==null?k(String(n.estimate),"yellow"):"",g.join("")].filter(O=>O.length>0).join(" "),m=`${Y(d)}${Y(p)} ${Y(h)} `,b=C.length>0?` ${Y(C)}`:"",T=Math.max(4,s-m.length-b.length),F=[...n.title],q=F.length>T?`${F.slice(0,T-1).join("")}\u2026`:n.title;return`${d}${p} ${h} ${q}${C.length>0?` ${C}`:""}`}function z(n,s){return s?`{cyan-bg}{black-fg}${Y(n)}{/}`:` ${n}`}function J(n,s,d,p=12){let h=`${n.padEnd(p)} ${s}`;return d?`{cyan-bg}{black-fg}\u25B8 ${h}{/}`:` ${h}`}function Y(n){return n.replace(/\{[^}]*\}/g,"")}var re=["\u2190\u2192\u2191\u2193 move","enter details","[ ] shift","m status","a assign","c comment","e edit","n new","s sprint","/ filter","R ready","b branch","M milestone","C claim","? help","q quit (Ctrl-C forces)"].join(" ");function se(n){let s=[],d=!1;function p(){d=!0,setImmediate(()=>{d=!1})}return{dispatch(h){if(d)return;let g=s[s.length-1];g!==void 0?g(h):n(h)},push(h){s.push(h),p();let g=!1;return()=>{if(g)return;g=!0;let E=s.lastIndexOf(h);E!==-1&&s.splice(E,1),p()}},isDialogOpen:()=>s.length>0,depth:()=>s.length}}function oe(n){if(n.ch==="")return!1;let s=n.ch.charCodeAt(0);return s<32||s===127}var be=["up","down","pageup","pagedown","home","end"],ie=["escape","q"];function Q(n){return be.includes(n.name)}function le(n){return ie.includes(n.name)||ie.includes(n.ch)}function _(n,s,d){return d===0?0:(n+s+d)%d}var ae="cancelled",we="done";function ve(n){let s=[`${n.open} open`,`${n.ready} ready`,`${n.decisions} ${n.decisions===1?"decision":"decisions"} in force`,...n.points===null?[]:[`${n.points} points`]];return`kadence ${n.sprint===null?"":`${n.sprint} `}${s.join(" \xB7 ")}${n.filterNote}`}function Ie(n){let s=S.screen({smartCSR:!0,title:"kadence",fullUnicode:!0,mouse:!0}),{state:d}=n.reload(),p=n.branchEventIds(),h="",g=!1,E=!1,C="",m=[],b=0,T=se(t=>ge(t));function F(t=0){try{s.destroy()}catch{}process.exit(t)}process.on("SIGINT",()=>F(0)),process.on("SIGTERM",()=>F(0)),s.program.on("keypress",(t,r)=>{let i={ch:t??"",name:r?.name??""};(i.name==="C-c"||i.ch==="")&&F(0),!(oe(i)&&i.name!=="enter"&&i.name!=="escape")&&T.dispatch(i)});let q=S.box({parent:s,top:0,height:1,width:"100%",tags:!0,style:{fg:c.headerFg,bg:c.headerBg}}),O=S.box({parent:s,bottom:0,height:1,width:"100%",tags:!0,content:` ${re}`,style:{fg:c.hint}}),V=S.box({parent:s,bottom:1,height:1,width:"100%",tags:!0,style:{fg:c.warn}});function w(t,r=c.warn){V.setContent(` ${t}`),V.style.fg=r,s.render()}function A(){let t=d.statuses.filter(i=>i!==ae),r=d.orphanStatuses.filter(i=>i!==ae);return[...t,...r]}function de(t){let r=h.toLowerCase(),i=g?new Set(G(d.tasks,{viewer:n.actor,statuses:d.statuses,started:d.started}).map(a=>a.id)):null,e=E&&!("reason"in p)?p:null,o=e===null?null:a=>e.ids.has(a.id)||a.history.some(l=>e.ids.has(l.id)),u=C===""?null:d.milestones.find(a=>a.label===C)?.id??null;return d.tasks.filter(a=>a.status===t&&(i===null||i.has(a.id))&&(o===null||o(a))&&(u===null||a.milestone===u)&&(r===""||a.title.toLowerCase().includes(r)||(a.assignee??"").toLowerCase().includes(r)||a.labels.some(l=>l.toLowerCase().includes(r))))}function X(){for(let i of m)i.box.destroy();m=[];let t=A(),r=Math.max(Math.floor(100/Math.max(t.length,1)),12);t.forEach((i,e)=>{let o=S.box({parent:s,top:1,left:`${e*r}%`,width:`${r}%`,bottom:2,label:` ${i} `,border:{type:"line"},style:{border:{fg:c.border},label:{fg:ne(i)}}}),u=S.list({parent:o,top:0,left:0,right:0,bottom:0,keys:!1,mouse:!1,interactive:!1,tags:!0,scrollable:!0,style:{selected:{fg:c.selectedFg,bg:c.selectedBg},item:{fg:"white"}}});m.push({status:i,box:o,list:u,tasks:[],cursor:0})})}function y(t=!1){t&&(d=n.reload().state,p=n.branchEventIds()),m.length!==A().length&&X();let r=0,i=0,e=!1;m.forEach((l,N)=>{l.tasks=de(l.status),l.status!==we&&(r+=l.tasks.length,i+=l.tasks.reduce((R,M)=>R+(M.estimate??0),0)),l.tasks.some(R=>R.estimate!==null)&&(e=!0);let U=l.box.width-4;l.cursor=Math.min(l.cursor,Math.max(0,l.tasks.length-1)),l.list.setItems(l.tasks.map((R,M)=>z(W(R,U),N===b&&M===l.cursor)));let L=l.tasks.reduce((R,M)=>R+(M.estimate??0),0);l.box.setLabel(` ${l.status} (${l.tasks.length}${L>0?`, ${L}`:""}) `),l.box.style.border.fg=N===b?c.borderFocus:c.border});let o=d.sprints.find(l=>l.status==="active"),u=(h===""?"":` filter: "${h}"`)+(g?" ready only":"")+(E&&!("reason"in p)?` branch: ${p.name}`:"")+(C===""?"":` milestone: ${C}`),a=G(d.tasks,{viewer:n.actor,statuses:d.statuses,started:d.started}).length;q.setContent(` ${ve({sprint:o===void 0?null:o.name,open:r,ready:a,decisions:d.decisions.filter(l=>l.supersededBy===null).length,points:e?i:null,filterNote:u})}`),d.cycles.length>0&&w(`${d.cycles.length} dependency cycle(s) \u2014 see kadence task list`,c.danger),s.render()}function I(){let t=m[b];return t?.tasks[t.cursor]}function Z(){m.forEach((t,r)=>{let i=t.box.width-4;t.list.setItems(t.tasks.map((e,o)=>z(W(e,i),r===b&&o===t.cursor))),t.box.style.border.fg=r===b?c.borderFocus:c.border}),s.render()}function x(t){t!==null?w(t,c.warn):w(""),y(!0)}function K(t,r,i){let e=T.push(()=>{}),o=S.prompt({parent:s,top:"center",left:"center",width:"60%",height:7,border:{type:"line"},style:{border:{fg:c.borderFocus}},keys:!0,mouse:!0});o.input(t,r,(u,a)=>{o.destroy(),e(),s.render(),typeof a=="string"&&i(a.trim())})}function ue(t){let r=S.box({parent:s,top:"center",left:"center",width:"75%",height:"80%",border:{type:"line"},label:` ${t.label} `,style:{border:{fg:c.borderFocus}},tags:!0,keys:!0,mouse:!0}),i=[{key:"title",label:"title",value:()=>t.title,hint:"Title:"},{key:"description",label:"description",value:()=>(t.description??"\u2014").split(`
|
|
3
3
|
`)[0]??"\u2014",hint:"Description (one line here, e for $EDITOR):"},{key:"status",label:"status",value:()=>t.status,hint:`Status (${A().join(", ")}):`},{key:"type",label:"type",value:()=>t.type,hint:"Type (task, bug, story, epic):"},{key:"priority",label:"priority",value:()=>t.priority,hint:"Priority (low, normal, high, urgent):"},{key:"assignee",label:"assignee",value:()=>t.assignee??"\u2014",hint:'Assignee (or "none"):'},{key:"estimate",label:"estimate",value:()=>t.estimate===null?"\u2014":String(t.estimate),hint:"Estimate in points:"},{key:"due",label:"due",value:()=>t.due??"\u2014",hint:"Due date YYYY-MM-DD (empty clears):"},{key:"labels",label:"labels",value:()=>t.labels.length>0?t.labels.join(", "):"\u2014",hint:"Labels, comma separated:"}],e=()=>[...i.map((v,f)=>({kind:"field",index:f})),...t.criteria.map(v=>({kind:"criterion",n:v.n}))],o=S.list({parent:r,top:0,left:1,right:1,height:i.length+t.criteria.length,keys:!1,mouse:!1,interactive:!1,tags:!0,style:{selected:{fg:c.selectedFg,bg:c.selectedBg}}}),u=0,a=S.box({parent:r,top:i.length+t.criteria.length+1,left:1,right:1,bottom:0,tags:!0,scrollable:!0});function l(){o.setItems(e().map((f,B)=>f.kind==="field"?J(i[f.index].label,i[f.index].value(),B===u):J(` ${f.n}.`,`[${t.criteria.find($=>$.n===f.n)?.checked===!0?"x":" "}] ${t.criteria.find($=>$.n===f.n)?.text??""}`,B===u)));let v=[t.blockedBy.length>0?`{red-fg}blocked by ${t.blockedBy.length} task(s){/}`:"",t.parent!==null?"{gray-fg}has a parent{/}":"",t.loggedHours>0?`{gray-fg}logged ${t.loggedHours.toFixed(1)}h{/}`:"","",t.description!==null&&t.description.includes(`
|
|
4
4
|
`)?`{gray-fg}${t.description.split(`
|
|
5
5
|
`).slice(1).join(`
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
var F=["backlog","todo","in_progress","blocked","in_review","done","cancelled"],x="done",S="cancelled",$="in_progress",Y="backlog",ot=["task","bug","story","epic"],at=["low","normal","high","urgent"];function lt(t){let e=m(t.data?.title),s=t.data?.body,u=t.data?.parents;return e===null||typeof s!="string"||s.trim().length===0||!Array.isArray(u)?null:{title:e,body:s,parents:u.filter(l=>typeof l=="string")}}function dt(t,e,s){let u=[];for(let[l,a]of t){let r=a.filter((c,h)=>a.findIndex(k=>k.id===c.id)===h).map(c=>({e:c,r:lt(c)})).filter(c=>c.r!==null);if(r.length===0)continue;let d=new Set(r.flatMap(c=>c.r.parents)),i=r.filter(c=>!d.has(c.e.id));i.length===0&&(i=[r[r.length-1]]);let f=i[i.length-1],y=r[0];u.push({id:l,label:"",title:f.r.title,body:f.r.body,tasks:(e.get(l)??[]).filter(c=>s.has(c)),revision:f.e.id,revisions:r.length,conflicts:i.slice(0,-1).map(c=>({revision:c.e.id,title:c.r.title,body:c.r.body,at:c.e.ts,by:c.e.actor,source:c.e.source})),createdAt:y.e.ts,createdBy:y.e.actor,updatedAt:f.e.ts,updatedBy:f.e.actor,source:f.e.source})}return u.sort((l,a)=>l.id<a.id?-1:1),u.forEach((l,a)=>{l.label=`DOC-${a+1}`}),u}function L(t,e){for(let s=t.length-1;s>=0;s--)if(t[s].id<e)return t[s].started;return $}function wt(t){let e=[...t].sort((n,o)=>n.id<o.id?-1:n.id>o.id?1:0),s=new Map,u=new Map,l=new Map,a=new Map,p=new Map,r=[],d=new Map,i=new Map,f=null,y=[],c={started:$,changes:[]},h=[],k=[];for(let n of e)n.type==="task.created"?z(s,n):n.type==="sprint.created"?G(u,n):n.type==="milestone.created"&&J(l,n);for(let n of e){if(n.type==="decision.recorded"){let o=n.data??{},g=A=>typeof o[A]=="string"&&o[A].length>0?o[A]:null,b=g("title"),v=g("why");b!==null&&v!==null&&p.set(n.id,{id:n.id,label:"",title:b,why:v,rejected:g("rejected"),task:g("task"),docs:Array.isArray(o.docs)?o.docs.filter(A=>typeof A=="string"):[],supersedes:g("supersedes"),supersededBy:null,at:n.ts,by:n.actor,source:n.source});continue}if(n.type==="note.recorded"){let o=m(n.data?.text);o!==null&&r.push({id:n.id,text:o,task:m(n.data?.task),at:n.ts,by:n.actor,source:n.source});continue}if(n.type==="doc.written"){let o=d.get(n.entity)??[];o.push(n),d.set(n.entity,o);continue}if(n.type==="doc.linked"){let o=m(n.data?.task);if(o!==null){let g=i.get(n.entity)??[];g.includes(o)||g.push(o),i.set(n.entity,g)}continue}if(n.type==="template.saved"){let o=typeof n.data?.name=="string"?n.data.name:null;o!==null&&a.set(o,{name:o,fields:n.data?.fields??{},author:n.actor});continue}if(n.type==="board.configured"){let o=n.data?.statuses;if(Array.isArray(o)){let v=o.filter(A=>typeof A=="string"&&A.length>0);v.length>0&&(f=v)}let g=n.data?.dod;Array.isArray(g)&&(y=g.filter(v=>typeof v=="string"&&v.length>0));let b=m(n.data?.started);b!==null&&(c.started=b,c.changes.push({id:n.id,started:b}));continue}if(n.type==="template.deleted"){let o=typeof n.data?.name=="string"?n.data.name:null;o!==null&&a.delete(o);continue}ut(n,s,u,l,h,k,c)}let w=k,T=[...s.values()].sort((n,o)=>n.id<o.id?-1:1);T.forEach((n,o)=>{n.label=`KAD-${o+1}`,ft(n),n.criteria.sort((g,b)=>g.id<b.id?-1:1),n.criteria.forEach((g,b)=>{g.n=b+1}),ct(n)});let M=new Set(T.map(n=>n.id));for(let n of T)n.parent!==null&&!M.has(n.parent)&&(n.parent=null),n.blockedBy=n.blockedBy.filter(o=>M.has(o));let B=[...p.values()].sort((n,o)=>n.id<o.id?-1:1);B.forEach((n,o)=>{n.label=`DEC-${o+1}`});for(let n of B){if(n.supersedes===null)continue;let o=p.get(n.supersedes);o!==void 0&&(o.supersededBy=n.id)}let C=[...l.values()].sort((n,o)=>n.id<o.id?-1:1);C.forEach((n,o)=>{n.label=`MS-${o+1}`});let R=new Map;for(let n of T){if(n.milestone===null||!l.has(n.milestone))continue;let o=R.get(n.milestone)??[];o.push(n.id),R.set(n.milestone,o)}for(let n of C){n.taskIds=R.get(n.id)??[];let o=n.taskIds.map(g=>s.get(g)).filter(g=>g!==void 0);n.totalTasks=o.length,n.doneTasks=o.filter(g=>g.status===x).length,n.totalPoints=o.reduce((g,b)=>g+(b.estimate??0),0),n.donePoints=o.filter(g=>g.status===x).reduce((g,b)=>g+(b.estimate??0),0)}for(let n of B)n.task!==null&&!M.has(n.task)&&(n.task=null);for(let n of r)n.task!==null&&!M.has(n.task)&&(n.task=null);let K=dt(d,i,M);return{tasks:T,decisions:B,documents:K,milestones:C,notes:r,sprints:[...u.values()].sort((n,o)=>n.id<o.id?-1:1),statuses:f??[...F],dod:y,started:c.started,startedChanges:[...c.changes],orphanStatuses:[...new Set(T.map(n=>n.status).filter(n=>!(f??F).includes(n)))].sort(),templates:[...a.values()].sort((n,o)=>n.name.localeCompare(o.name)),cycles:pt(T),pending:w,rejected:h}}function z(t,e){if(t.has(e.entity))return;let s=e.data??{};t.set(e.entity,{id:e.entity,label:"",title:typeof s.title=="string"?s.title:"(untitled)",description:m(s.description),type:Q(s.type),priority:V(s.priority),status:Y,labels:X(s.labels),assignee:m(s.assignee),reporter:e.actor,sprint:null,milestone:null,parent:m(s.parent),blockedBy:[],due:m(s.due),claimedBy:null,claimedAt:null,claimedEventId:null,contestedBy:[],criteria:[],comments:[],docs:[],estimate:typeof s.estimate=="number"?s.estimate:null,loggedHours:0,createdAt:e.ts,updatedAt:e.ts,history:[]})}function G(t,e){if(t.has(e.entity))return;let s=e.data??{};t.set(e.entity,{id:e.entity,name:typeof s.name=="string"?s.name:"(untitled)",description:m(s.description),startDate:m(s.startDate),endDate:m(s.endDate),status:"planned",closedBy:null,taskIds:[]})}function J(t,e){if(t.has(e.entity))return;let s=e.data??{};t.set(e.entity,{id:e.entity,label:"",name:typeof s.name=="string"?s.name:"(untitled)",due:m(s.due),status:"open",closedBy:null,taskIds:[],donePoints:0,totalPoints:0,doneTasks:0,totalTasks:0})}function ut(t,e,s,u,l,a,p){let r=t.data??{};if(t.type==="milestone.created")return J(u,t),!0;if(t.type==="milestone.task_added"){let i=m(r.task);if(i===null)return!0;let f=e.get(i);return f===void 0?(a.push(t),!1):(f.milestone=t.entity,!0)}if(t.type==="milestone.closed"){let i=u.get(t.entity);return i===void 0?(a.push(t),!1):(i.closedBy===null?(i.status="closed",i.closedBy=t.id):l.push(t),!0)}if(t.type==="task.created")return z(e,t),H(e.get(t.entity),t),!0;if(t.type==="sprint.created")return G(s,t),!0;if(t.type.startsWith("sprint.")){let i=s.get(t.entity);if(i===void 0)return a.push(t),!1;if(t.type==="sprint.started")return i.status==="planned"&&(i.status="active"),!0;if(t.type==="sprint.updated")return i.status==="closed"?(l.push(t),!0):(typeof r.name=="string"&&(i.name=r.name),r.description!==void 0&&(i.description=m(r.description)),r.startDate!==void 0&&(i.startDate=m(r.startDate)),r.endDate!==void 0&&(i.endDate=m(r.endDate)),!0);if(t.type==="sprint.closed")return i.closedBy===null?(i.status="closed",i.closedBy=t.id):l.push(t),!0;if(t.type==="sprint.cancelled")return i.status==="planned"?i.status="cancelled":l.push(t),!0;if(t.type==="sprint.task_added"){if(i.status==="closed")return l.push(t),!0;let f=typeof r.task=="string"?r.task:null;if(f===null)return!0;let y=e.get(f);return y===void 0?(a.push(t),!1):(y.sprint=i.id,i.taskIds.includes(f)||i.taskIds.push(f),H(y,t),!0)}return!0}let d=e.get(t.entity);if(d===void 0)return a.push(t),!1;if(t.type==="task.deleted")return e.delete(t.entity),!0;switch(t.type){case"task.moved":{let i=r.to;typeof i=="string"&&i.length>0&&(d.status=i);break}case"task.cancelled":d.status=S;break;case"task.reopened":d.status=L(p.changes,t.id);break;case"task.assigned":d.assignee=m(r.assignee);break;case"task.updated":typeof r.title=="string"&&(d.title=r.title),r.description!==void 0&&(d.description=m(r.description)),r.type!==void 0&&(d.type=Q(r.type)),r.priority!==void 0&&(d.priority=V(r.priority)),r.labels!==void 0&&(d.labels=X(r.labels)),r.due!==void 0&&(d.due=m(r.due)),typeof r.estimate=="number"&&(d.estimate=r.estimate);break;case"task.parent_set":d.parent=m(r.parent);break;case"task.blocked_by_added":{let i=m(r.blocker);i!==null&&!d.blockedBy.includes(i)&&d.blockedBy.push(i);break}case"task.blocked_by_removed":{let i=m(r.blocker);i!==null&&(d.blockedBy=d.blockedBy.filter(f=>f!==i));break}case"task.label_added":{let i=m(r.label);i!==null&&!d.labels.includes(i)&&d.labels.push(i);break}case"task.label_removed":{let i=m(r.label);i!==null&&(d.labels=d.labels.filter(f=>f!==i));break}case"task.criterion_added":{let i=m(r.text);i!==null&&d.criteria.push({id:t.id,n:0,text:i,checked:!1,checkedBy:null});break}case"task.criterion_checked":case"task.criterion_unchecked":break;case"task.doc_linked":{let i=m(r.path);i!==null&&!d.docs.includes(i)&&d.docs.push(i);break}case"task.time_logged":{let i=r.hours;typeof i=="number"&&Number.isFinite(i)&&(d.loggedHours=Math.max(0,d.loggedHours+i));break}case"task.commented":{let i=m(r.text);i!==null&&d.comments.push({id:t.id,author:t.actor,ts:t.ts,text:i,source:t.source});break}default:break}return H(d,t),!0}function ct(t){let e=new Map(t.criteria.map(s=>[s.id,s]));for(let s of t.criteria)s.checked=!1,s.checkedBy=null;for(let s of t.history){if(s.type!=="task.criterion_checked"&&s.type!=="task.criterion_unchecked")continue;let u=m(s.data.criterion),l=u===null?void 0:e.get(u);if(l===void 0)continue;let a=s.type==="task.criterion_checked";l.checked=a,l.checkedBy=a?s.actor:null}}function ft(t){let e=null,s=null,u=null,l=[],a=()=>{e=null,s=null,u=null,l=[]};for(let p of t.history)if(p.type==="task.claimed"){let r=m(p.data.by)??p.actor;e===null?(e=r,s=p.ts,u=p.id):r!==e&&!l.includes(r)&&l.push(r)}else if(p.type==="task.released"){let r=m(p.data.by)??p.actor;e===r?a():l=l.filter(d=>d!==r)}else(p.type==="task.cancelled"||p.type==="task.moved"&&p.data.to===x)&&a();t.claimedBy=e,t.claimedAt=s,t.claimedEventId=u,t.contestedBy=l}function H(t,e){t.history.push({id:e.id,type:e.type,actor:e.actor,ts:e.ts,source:e.source,data:e.data??{}}),e.ts>t.updatedAt&&(t.updatedAt=e.ts)}function m(t){return typeof t=="string"&&t.length>0?t:null}function Q(t){return ot.includes(t)?t:"task"}function V(t){return at.includes(t)?t:"normal"}function X(t){return Array.isArray(t)?t.filter(e=>typeof e=="string"&&e.length>0):[]}function pt(t){let e=new Map(t.map(a=>[a.id,a])),s=[],u=new Set,l=(a,p)=>{let r=new Map,d=(i,f)=>{let y=r.get(i);if(y==="done")return;if(y==="visiting"){let h=f.indexOf(i),k=f.slice(h),w=`${a}:${[...k].sort().join(",")}`;u.has(w)||(u.add(w),s.push({kind:a,path:[...k,i]}));return}r.set(i,"visiting");let c=e.get(i);if(c!==void 0)for(let h of p(c))d(h,[...f,i]);r.set(i,"done")};for(let i of t)d(i.id,[])};return l("parent",a=>a.parent===null?[]:[a.parent]),l("blocking",a=>a.blockedBy),s}var D=864e5;function P(t){return new Date(t).toISOString().slice(0,10)}function E(t){return Date.parse(`${t}T00:00:00.000Z`)}function gt(t){let e=new Date(E(t)),s=(e.getUTCDay()+6)%7;return P(e.getTime()-s*D)}function et(t,e){let s=P(t.getTime());return{from:P(E(s)-(e-1)*D),to:s,days:e}}function tt(t,e){let s=t.slice(0,10);return s>=e.from&&s<=e.to}function N(t,e){if(t.length===0)return 0;let s=Math.max(1,Math.ceil(e*t.length));return t[s-1]}var I=t=>Math.round(t*10)/10;function q(t){if(t.length===0)return null;let e=[...t].sort((s,u)=>s-u);return{shown:{n:e.length,p50:I(N(e,.5)),p85:I(N(e,.85)),p95:I(N(e,.95))},rawP85:N(e,.85)}}function j(t,e){let s=t.indexOf(e);return s===-1?null:new Set(t.slice(0,s))}function Z(t,e,s=[],u=[]){let l=j(s,e),a=r=>r===x||r===S?!1:l===null?r===e:r===e||!l.has(r);return t.history.find(r=>r.type==="task.reopened"?a(L(u,r.id)):r.type==="task.moved"&&typeof r.data.to=="string"&&a(r.data.to))?.ts??null}function yt(t,e){if(e.status===x||e.status===S)return!1;let s=j(t.statuses,t.started);return s===null?e.status===t.started:s.has(e.status)?!1:Z(e,t.started,t.statuses,t.startedChanges)!==null}function _(t){if(t.status!==x)return null;for(let e=t.history.length-1;e>=0;e--){let s=t.history[e];if(s.type==="task.moved"&&s.data.to===x)return s.ts}return null}function ht(t){if(t.status!==S)return null;for(let e=t.history.length-1;e>=0;e--){let s=t.history[e];if(s.type==="task.cancelled"||s.type==="task.moved"&&s.data.to===S)return s.ts}return null}function O(t,e){return Math.max(0,(Date.parse(e)-Date.parse(t))/D)}function mt(t,e,s,u){let l=_(t)??ht(t),a=l===null?u:Date.parse(l),p=[],r=new Map;for(let h of t.history){let k=typeof h.data.blocker=="string"?h.data.blocker:null;if(k!==null){if(h.type==="task.blocked_by_added")r.has(k)||r.set(k,Date.parse(h.ts));else if(h.type==="task.blocked_by_removed"){let w=r.get(k);w!==void 0&&(p.push([w,Math.min(Date.parse(h.ts),a)]),r.delete(k))}}}for(let[h,k]of r){let w=Math.min(e.get(h)??u,a);p.push([k,Math.max(k,w)])}let d=E(s.from),i=E(s.to)+D,f=p.map(([h,k])=>[Math.max(h,d),Math.min(k,i)]).filter(([h,k])=>k>h).sort((h,k)=>h[0]-k[0]),y=0,c=null;for(let[h,k]of f)c===null||h>c[1]?(c!==null&&(y+=c[1]-c[0]),c=[h,k]):k>c[1]&&(c[1]=k);return c!==null&&(y+=c[1]-c[0]),y/D}function St(t,e=new Date,s=30){let u=et(e,s),l=e.getTime(),a=[],p=t.tasks.filter(n=>n.status!==S),r=p.filter(n=>{let o=_(n);return o!==null&&tt(o,u)}),d=[],i=[],f=[];for(let n of r){let o=_(n),g=Z(n,t.started,t.statuses,t.startedChanges);i.push(O(n.createdAt,o)),g!==null&&(d.push(O(g,o)),f.push(O(n.createdAt,g)))}let y=q(d),c=y?.shown??null,h=p.filter(n=>yt(t,n)),k=h.map(n=>{let o=O(Z(n,t.started,t.statuses,t.startedChanges),e.toISOString());return{label:n.label,title:n.title,status:n.status,ageDays:I(o),overP85:y!==null&&o>y.rawP85}}).sort((n,o)=>o.ageDays-n.ageDays),w=new Map,T=n=>{let o=gt(n),g=w.get(o);return g===void 0&&(g={week:o,finished:0,created:0},w.set(o,g)),g};for(let n=E(u.from);n<=E(u.to);n+=D)T(P(n));for(let n of r)T(_(n).slice(0,10)).finished+=1;for(let n of p)tt(n.createdAt,u)&&(T(n.createdAt.slice(0,10)).created+=1);let M=[...w.values()].sort((n,o)=>n.week<o.week?-1:1),B=new Map;for(let n of t.tasks){let o=_(n);o!==null&&B.set(n.id,Date.parse(o))}let C=0,R=0;for(let n of p){let o=mt(n,B,u,l);o>0&&(C+=1,R+=o)}t.tasks.length===0?a.push("No tasks yet."):(h.length===0&&r.length===0&&a.push(`Nothing has crossed "${t.started}" yet. If work starts in another column, say so: kadence board config --started <status>`),r.length===0?a.push(`Nothing finished between ${u.from} and ${u.to}; cycle time needs finished work.`):d.length===0&&a.push(`${r.length} item(s) finished without ever entering "${t.started}", so there is no cycle time to measure.`),t.statuses.includes(t.started)||a.push(`"${t.started}" is not one of the board's columns; set one with kadence board config --started.`));let K=c===null?null:`${c.n<10?`From ${c.n} finished items (a small sample): `:""}85% of finished items took ${c.p85} calendar days or less.`;return{window:u,started:t.started,unit:"calendar days",wip:h.length,finished:r.length,perWeek:M,cycleTime:c,leadTime:q(i)?.shown??null,responseTime:q(f)?.shown??null,sle:K,aging:k,blocked:{tasks:C,days:I(R)},notes:a}}function vt(t,e=new Date,s=30){let u=et(e,s),l=[...t.statuses];for(let d of t.tasks)l.includes(d.status)||l.push(d.status);let a=Y;!l.includes(a)&&t.tasks.length>0&&l.unshift(a);let p=t.tasks.map(d=>{let i=[];for(let f of d.history)f.type==="task.moved"&&typeof f.data.to=="string"?i.push({at:Date.parse(f.ts),status:f.data.to}):f.type==="task.cancelled"?i.push({at:Date.parse(f.ts),status:S}):f.type==="task.reopened"&&i.push({at:Date.parse(f.ts),status:L(t.startedChanges,f.id)});return{createdAt:Date.parse(d.createdAt),changes:i,next:0,status:a}}),r=[];for(let d=E(u.from);d<=E(u.to);d+=D){let i=d+D,f={};for(let y of l)f[y]=0;for(let y of p){for(;y.next<y.changes.length&&y.changes[y.next].at<i;)y.status=y.changes[y.next].status,y.next+=1;y.createdAt>=i||(f[y.status]=(f[y.status]??0)+1)}r.push({date:P(d),counts:f})}return{window:u,statuses:l,days:r}}var W={urgent:0,high:1,normal:2,low:3};function nt(t,e){return t!==null&&t.toLowerCase().includes(e)}function Mt(t,e,s=new Date){let u=s.toISOString().slice(0,10),l=e.search?.toLowerCase();return t.filter(a=>{if(l!==void 0&&l.length>0){let p=a.comments.some(r=>r.text.toLowerCase().includes(l));if(!nt(a.title,l)&&!nt(a.description,l)&&!p)return!1}if(e.status!==void 0&&a.status!==e.status||e.type!==void 0&&a.type!==e.type||e.priority!==void 0&&a.priority!==e.priority)return!1;if(e.assignee!==void 0){let p=e.assignee.toLowerCase(),r=(a.assignee??"").toLowerCase();if(p==="none"?r!=="":r!==p)return!1}if(e.label!==void 0){let p=e.label.toLowerCase();if(!a.labels.some(r=>r.toLowerCase()===p))return!1}return!(e.sprint!==void 0&&a.sprint!==e.sprint||e.overdue===!0&&(a.due===null||a.due>=u)||e.dueBefore!==void 0&&(a.due===null||a.due>=e.dueBefore))})}function Bt(t,e){let s=[...t];switch(e){case"priority":return s.sort((u,l)=>W[u.priority]-W[l.priority]);case"due":return s.sort((u,l)=>st(u.due,l.due,(a,p)=>a<p?-1:a>p?1:0));case"estimate":return s.sort((u,l)=>st(u.estimate,l.estimate,(a,p)=>p-a));default:return s.sort((u,l)=>u.id<l.id?-1:u.id>l.id?1:0)}}function st(t,e,s){return t===null&&e===null?0:t===null?1:e===null?-1:s(t,e)}function Ct(t){let e=[];return t.search!==void 0&&e.push(`search="${t.search}"`),t.status!==void 0&&e.push(`status=${t.status}`),t.type!==void 0&&e.push(`type=${t.type}`),t.priority!==void 0&&e.push(`priority=${t.priority}`),t.assignee!==void 0&&e.push(`assignee=${t.assignee}`),t.label!==void 0&&e.push(`label=${t.label}`),t.overdue===!0&&e.push("overdue"),t.dueBefore!==void 0&&e.push(`due before ${t.dueBefore}`),e.length===0?`No tasks yet.
|
|
3
|
+
Create the first one:
|
|
4
|
+
kadence task add "title"`:`No tasks match ${e.join(" and ")}.
|
|
5
|
+
Try fewer filters:
|
|
6
|
+
kadence task list`}function rt(t,e){return t===null||e===null?!1:t===e?!0:!e.includes("#")&&t.startsWith(`${e}#`)}function kt(t){let e=t.indexOf("#");return e===-1?t:t.slice(0,e)}function it(t){return j(t.statuses??F,t.started??$)}function U(t){return t.status===x||t.status===S}function Rt(t,e={}){let s=e.viewer??null,u=new Set(t.filter(U).map(r=>r.id)),l=e.assignee==="me"?s===null?null:kt(s):e.assignee??null,a=it(e);return t.filter(r=>{if(U(r)||a!==null&&!a.has(r.status)||r.blockedBy.some(d=>!u.has(d))||r.claimedBy!==null&&!rt(r.claimedBy,s)&&r.contestedBy.length===0)return!1;if(l!==null){if(l==="none")return r.assignee===null;if(r.assignee!==l)return!1}return!0}).sort((r,d)=>W[r.priority]-W[d.priority]||(r.id<d.id?-1:1))}function _t(t,e,s,u={}){if(t.length===0)return`No tasks yet.
|
|
7
|
+
Create the first one:
|
|
8
|
+
kadence task add "title"`;let l=t.filter(c=>!U(c));if(l.length===0)return"Nothing ready: every task is done or cancelled.";let a=new Set(t.filter(U).map(c=>c.id)),p=it(u),r=p===null?0:l.filter(c=>!p.has(c.status)).length,d=l.filter(c=>c.blockedBy.some(h=>!a.has(h))).length,i=l.filter(c=>c.claimedBy!==null&&!rt(c.claimedBy,e)&&c.contestedBy.length===0).length,f=[];return r>0&&f.push(`${r} already started`),d>0&&f.push(`${d} blocked`),i>0&&f.push(`${i} claimed by someone else`),s!==void 0&&f.push(`filtered to assignee=${s}`),`Nothing ready${f.length>0?` (${f.join(", ")})`:""}.
|
|
9
|
+
See the whole board:
|
|
10
|
+
kadence task list`}var bt=["created","priority","due","estimate"];function It(t){return bt.includes(t)}export{F as a,x as b,S as c,ot as d,at as e,wt as f,Z as g,yt as h,_ as i,St as j,vt as k,Mt as l,Bt as m,Ct as n,rt as o,U as p,Rt as q,_t as r,bt as s,It as t};
|