kadence 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.1.2] — 2026-09-03
4
+
5
+ ### Documentation
6
+
7
+ - The README opened with `npx kadence init` and said nothing more, so the
8
+ obvious next step — `kadence board` — failed with "command not found". `npx`
9
+ fetches a package for one command and leaves nothing installed. Global
10
+ install is now the first instruction, with the npx path shown as the
11
+ alternative it is.
12
+
13
+ ## [0.1.1] — 2026-09-03
14
+
15
+ ### Fixed
16
+
17
+ - `kadence --version` reported `0.1.0-dev` while the published package was
18
+ `0.1.0`. The CLI carried its own copy of the version string; it is now
19
+ injected from package.json at build time, with a test that fails if the two
20
+ ever diverge again.
21
+
3
22
  ## [0.1.0] — 2026-09-03
4
23
 
5
24
  First release. Tasks, sprints and velocity as plain files inside a git
package/README.md CHANGED
@@ -7,9 +7,11 @@ account, no network. Works offline, and works for AI agents because the data is
7
7
  just files they can read.
8
8
 
9
9
  ```bash
10
- npx kadence init
11
- npx kadence task add "Fix login" -d "Broken since 2.3" --type bug --estimate 3
12
- npx kadence ui # interactive board, or `kadence board` for a plain list
10
+ npm install -g kadence
11
+
12
+ kadence init
13
+ kadence task add "Fix login" -d "Broken since 2.3" --type bug --estimate 3
14
+ kadence ui # interactive board, or `kadence board` for a plain list
13
15
  ```
14
16
 
15
17
  > **v0.1.0.** The architecture is measured and covered by 383 tests. The product
@@ -51,13 +53,23 @@ costs your team.
51
53
 
52
54
  Requires Node 20 or newer, and a git repository.
53
55
 
56
+ Install it once, so the command stays available:
57
+
58
+ ```bash
59
+ npm install -g kadence
60
+ kadence init
61
+ ```
62
+
63
+ Or run it without installing — but note that `npx` fetches the package for that
64
+ one command and leaves nothing behind, so every later call needs `npx` too:
65
+
54
66
  ```bash
55
67
  npx kadence init
68
+ npx kadence board
56
69
  ```
57
70
 
58
- No global install needed. `init` creates `.kadence/`, adds the derived cache to
59
- `.gitignore`, and writes a short guide for AI agents. It does **not** commit
60
- anything — that call is yours.
71
+ `init` creates `.kadence/`, adds the derived cache to `.gitignore`, and writes a
72
+ short guide for AI agents. It does **not** commit anything — that call is yours.
61
73
 
62
74
  ## Commands
63
75
 
package/dist/cli.js CHANGED
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
- import{A as se,B as ae,C as T,D as ie,E as re,F as oe,G as de,H as ce,I as le,J as ue,K as me,L as fe,M as pe,a as F,b as U,c as $,d as A,e as g,f as E,g as q,h as W,i as P,j as Y,k as G,l as V,m as S,n as k,o as b,p as J,q as y,r as H,s as z,t as Q,u as X,v as O,w as Z,x as ee,y as te,z as ne}from"./chunks/chunk-BUHXYOZ4.js";function K(n){return n==null?[]:Array.isArray(n)?n:[n]}function _e(n,t,s,e){var a,i=n[t],r=~e.string.indexOf(t)?s==null||s===!0?"":String(s):typeof s=="boolean"?s:~e.boolean.indexOf(t)?s==="false"?!1:s==="true"||(n._.push((a=+s,a*0===0?a:s)),!!s):(a=+s,a*0===0?a:s);n[t]=i==null?r:Array.isArray(i)?i.concat(r):[i,r]}function Be(n,t){n=n||[],t=t||{};var s,e,a,i,r,d={_:[]},o=0,l=0,u=0,m=n.length;let p=t.alias!==void 0,D=t.unknown!==void 0,M=t.default!==void 0;if(t.alias=t.alias||{},t.string=K(t.string),t.boolean=K(t.boolean),p)for(s in t.alias)for(e=t.alias[s]=K(t.alias[s]),o=0;o<e.length;o++)(t.alias[e[o]]=e.concat(s)).splice(o,1);for(o=t.boolean.length;o-- >0;)for(e=t.alias[t.boolean[o]]||[],l=e.length;l-- >0;)t.boolean.push(e[l]);for(o=t.string.length;o-- >0;)for(e=t.alias[t.string[o]]||[],l=e.length;l-- >0;)t.string.push(e[l]);if(M){for(s in t.default)if(i=typeof t.default[s],e=t.alias[s]=t.alias[s]||[],t[i]!==void 0)for(t[i].push(s),o=0;o<e.length;o++)t[i].push(e[o])}let L=D?Object.keys(t.alias):[];for(o=0;o<m;o++){if(a=n[o],a==="--"){d._=d._.concat(n.slice(++o));break}for(l=0;l<a.length&&a.charCodeAt(l)===45;l++);if(l===0)d._.push(a);else if(a.substring(l,l+3)==="no-"){if(i=a.substring(l+3),D&&!~L.indexOf(i))return t.unknown(a);d[i]=!1}else{for(u=l+1;u<a.length&&a.charCodeAt(u)!==61;u++);for(i=a.substring(l,u),r=a.substring(++u)||o+1===m||(""+n[o+1]).charCodeAt(0)===45||n[++o],e=l===2?[i]:i,u=0;u<e.length;u++){if(i=e[u],D&&!~L.indexOf(i))return t.unknown("-".repeat(l)+i);_e(d,i,u+1<e.length||r,t)}}}if(M)for(s in t.default)d[s]===void 0&&(d[s]=t.default[s]);if(p)for(s in d)for(e=t.alias[s]||[];e.length>0;)d[e.shift()]=d[s];return d}function ke(n){return n.replace(/[<[].+/,"").trim()}function Me(n){let t=/<([^>]+)>/g,s=/\[([^\]]+)\]/g,e=[],a=d=>{let o=!1,l=d[1];return l.startsWith("...")&&(l=l.slice(3),o=!0),{required:d[0].startsWith("<"),value:l,variadic:o}},i;for(;i=t.exec(n);)e.push(a(i));let r;for(;r=s.exec(n);)e.push(a(r));return e}function Le(n){let t={alias:{},boolean:[]};for(let[s,e]of n.entries())e.names.length>1&&(t.alias[e.names[0]]=e.names.slice(1)),e.isBoolean&&(e.negated&&n.some((a,i)=>i!==s&&a.names.some(r=>e.names.includes(r))&&typeof a.required=="boolean")||t.boolean.push(e.names[0]));return t}function he(n){return n.sort((t,s)=>t.length>s.length?-1:1)[0]}function ge(n,t){return n.length>=t?n:`${n}${" ".repeat(t-n.length)}`}function Fe(n){return n.replaceAll(/([a-z])-([a-z])/g,(t,s,e)=>s+e.toUpperCase())}function Ue(n,t,s){let e=n;for(let a=0;a<t.length;a++){let i=t[a];if(a===t.length-1){e[i]=s;return}if(e[i]==null){let r=+t[a+1]>-1;e[i]=r?[]:{}}e=e[i]}}function qe(n,t){for(let s of Object.keys(t)){let e=t[s];e.shouldTransform&&(n[s]=[n[s]].flat(),typeof e.transformFunction=="function"&&(n[s]=n[s].map(e.transformFunction)))}}function We(n){let t=/([^\\/]+)$/.exec(n);return t?t[1]:""}function be(n){return n.split(".").map((t,s)=>s===0?Fe(t):t).join(".")}var x=class extends Error{constructor(n){super(n),this.name="CACError",typeof Error.captureStackTrace!="function"&&(this.stack=new Error(n).stack)}},Pe=class{rawName;description;name;names;isBoolean;required;config;negated;constructor(n,t,s){this.rawName=n,this.description=t,this.config=Object.assign({},s),n=n.replaceAll(".*",""),this.negated=!1,this.names=ke(n).split(",").map(e=>{let a=e.trim().replace(/^-{1,2}/,"");return a.startsWith("no-")&&(this.negated=!0,a=a.replace(/^no-/,"")),be(a)}).sort((e,a)=>e.length>a.length?1:-1),this.name=this.names.at(-1),this.negated&&this.config.default==null&&(this.config.default=!0),n.includes("<")?this.required=!0:n.includes("[")?this.required=!1:this.isBoolean=!0}},j,w;if(typeof process<"u"){let n;typeof Deno<"u"&&typeof Deno.version?.deno=="string"?n="deno":typeof Bun<"u"&&typeof Bun.version=="string"?n="bun":n="node",w=`${process.platform}-${process.arch} ${n}-${process.version}`,j=process.argv}else typeof navigator>"u"?w="unknown":w=`${navigator.platform} ${navigator.userAgent}`;var ye=class{rawName;description;config;cli;options;aliasNames;name;args;commandAction;usageText;versionNumber;examples;helpCallback;globalCommand;constructor(n,t,s={},e){this.rawName=n,this.description=t,this.config=s,this.cli=e,this.options=[],this.aliasNames=[],this.name=ke(n),this.args=Me(n),this.examples=[]}usage(n){return this.usageText=n,this}allowUnknownOptions(){return this.config.allowUnknownOptions=!0,this}ignoreOptionDefaultValue(){return this.config.ignoreOptionDefaultValue=!0,this}version(n,t="-v, --version"){return this.versionNumber=n,this.option(t,"Display version number"),this}example(n){return this.examples.push(n),this}option(n,t,s){let e=new Pe(n,t,s);return this.options.push(e),this}alias(n){return this.aliasNames.push(n),this}action(n){return this.commandAction=n,this}isMatched(n){return this.name===n||this.aliasNames.includes(n)}get isDefaultCommand(){return this.name===""||this.aliasNames.includes("!")}get isGlobalCommand(){return this instanceof ve}hasOption(n){return n=n.split(".")[0],this.options.find(t=>t.names.includes(n))}outputHelp(){let{name:n,commands:t}=this.cli,{versionNumber:s,options:e,helpCallback:a}=this.cli.globalCommand,i=[{body:`${n}${s?`/${s}`:""}`}];if(i.push({title:"Usage",body:` $ ${n} ${this.usageText||this.rawName}`}),(this.isGlobalCommand||this.isDefaultCommand)&&t.length>0){let d=he(t.map(o=>o.rawName));i.push({title:"Commands",body:t.map(o=>` ${ge(o.rawName,d.length)} ${o.description}`).join(`
2
+ import{A as se,B as ae,C as T,D as ie,E as re,F as oe,G as de,H as ce,I as le,J as ue,K as me,L as fe,M as pe,a as F,b as U,c as $,d as A,e as g,f as E,g as q,h as W,i as P,j as Y,k as G,l as V,m as S,n as k,o as b,p as J,q as y,r as H,s as z,t as Q,u as X,v as O,w as Z,x as ee,y as te,z as ne}from"./chunks/chunk-BUHXYOZ4.js";function K(n){return n==null?[]:Array.isArray(n)?n:[n]}function Ie(n,t,s,e){var a,i=n[t],r=~e.string.indexOf(t)?s==null||s===!0?"":String(s):typeof s=="boolean"?s:~e.boolean.indexOf(t)?s==="false"?!1:s==="true"||(n._.push((a=+s,a*0===0?a:s)),!!s):(a=+s,a*0===0?a:s);n[t]=i==null?r:Array.isArray(i)?i.concat(r):[i,r]}function Be(n,t){n=n||[],t=t||{};var s,e,a,i,r,d={_:[]},o=0,l=0,u=0,m=n.length;let p=t.alias!==void 0,D=t.unknown!==void 0,M=t.default!==void 0;if(t.alias=t.alias||{},t.string=K(t.string),t.boolean=K(t.boolean),p)for(s in t.alias)for(e=t.alias[s]=K(t.alias[s]),o=0;o<e.length;o++)(t.alias[e[o]]=e.concat(s)).splice(o,1);for(o=t.boolean.length;o-- >0;)for(e=t.alias[t.boolean[o]]||[],l=e.length;l-- >0;)t.boolean.push(e[l]);for(o=t.string.length;o-- >0;)for(e=t.alias[t.string[o]]||[],l=e.length;l-- >0;)t.string.push(e[l]);if(M){for(s in t.default)if(i=typeof t.default[s],e=t.alias[s]=t.alias[s]||[],t[i]!==void 0)for(t[i].push(s),o=0;o<e.length;o++)t[i].push(e[o])}let L=D?Object.keys(t.alias):[];for(o=0;o<m;o++){if(a=n[o],a==="--"){d._=d._.concat(n.slice(++o));break}for(l=0;l<a.length&&a.charCodeAt(l)===45;l++);if(l===0)d._.push(a);else if(a.substring(l,l+3)==="no-"){if(i=a.substring(l+3),D&&!~L.indexOf(i))return t.unknown(a);d[i]=!1}else{for(u=l+1;u<a.length&&a.charCodeAt(u)!==61;u++);for(i=a.substring(l,u),r=a.substring(++u)||o+1===m||(""+n[o+1]).charCodeAt(0)===45||n[++o],e=l===2?[i]:i,u=0;u<e.length;u++){if(i=e[u],D&&!~L.indexOf(i))return t.unknown("-".repeat(l)+i);Ie(d,i,u+1<e.length||r,t)}}}if(M)for(s in t.default)d[s]===void 0&&(d[s]=t.default[s]);if(p)for(s in d)for(e=t.alias[s]||[];e.length>0;)d[e.shift()]=d[s];return d}function ke(n){return n.replace(/[<[].+/,"").trim()}function Me(n){let t=/<([^>]+)>/g,s=/\[([^\]]+)\]/g,e=[],a=d=>{let o=!1,l=d[1];return l.startsWith("...")&&(l=l.slice(3),o=!0),{required:d[0].startsWith("<"),value:l,variadic:o}},i;for(;i=t.exec(n);)e.push(a(i));let r;for(;r=s.exec(n);)e.push(a(r));return e}function Le(n){let t={alias:{},boolean:[]};for(let[s,e]of n.entries())e.names.length>1&&(t.alias[e.names[0]]=e.names.slice(1)),e.isBoolean&&(e.negated&&n.some((a,i)=>i!==s&&a.names.some(r=>e.names.includes(r))&&typeof a.required=="boolean")||t.boolean.push(e.names[0]));return t}function he(n){return n.sort((t,s)=>t.length>s.length?-1:1)[0]}function ge(n,t){return n.length>=t?n:`${n}${" ".repeat(t-n.length)}`}function Fe(n){return n.replaceAll(/([a-z])-([a-z])/g,(t,s,e)=>s+e.toUpperCase())}function Ue(n,t,s){let e=n;for(let a=0;a<t.length;a++){let i=t[a];if(a===t.length-1){e[i]=s;return}if(e[i]==null){let r=+t[a+1]>-1;e[i]=r?[]:{}}e=e[i]}}function qe(n,t){for(let s of Object.keys(t)){let e=t[s];e.shouldTransform&&(n[s]=[n[s]].flat(),typeof e.transformFunction=="function"&&(n[s]=n[s].map(e.transformFunction)))}}function We(n){let t=/([^\\/]+)$/.exec(n);return t?t[1]:""}function be(n){return n.split(".").map((t,s)=>s===0?Fe(t):t).join(".")}var x=class extends Error{constructor(n){super(n),this.name="CACError",typeof Error.captureStackTrace!="function"&&(this.stack=new Error(n).stack)}},Pe=class{rawName;description;name;names;isBoolean;required;config;negated;constructor(n,t,s){this.rawName=n,this.description=t,this.config=Object.assign({},s),n=n.replaceAll(".*",""),this.negated=!1,this.names=ke(n).split(",").map(e=>{let a=e.trim().replace(/^-{1,2}/,"");return a.startsWith("no-")&&(this.negated=!0,a=a.replace(/^no-/,"")),be(a)}).sort((e,a)=>e.length>a.length?1:-1),this.name=this.names.at(-1),this.negated&&this.config.default==null&&(this.config.default=!0),n.includes("<")?this.required=!0:n.includes("[")?this.required=!1:this.isBoolean=!0}},N,w;if(typeof process<"u"){let n;typeof Deno<"u"&&typeof Deno.version?.deno=="string"?n="deno":typeof Bun<"u"&&typeof Bun.version=="string"?n="bun":n="node",w=`${process.platform}-${process.arch} ${n}-${process.version}`,N=process.argv}else typeof navigator>"u"?w="unknown":w=`${navigator.platform} ${navigator.userAgent}`;var ye=class{rawName;description;config;cli;options;aliasNames;name;args;commandAction;usageText;versionNumber;examples;helpCallback;globalCommand;constructor(n,t,s={},e){this.rawName=n,this.description=t,this.config=s,this.cli=e,this.options=[],this.aliasNames=[],this.name=ke(n),this.args=Me(n),this.examples=[]}usage(n){return this.usageText=n,this}allowUnknownOptions(){return this.config.allowUnknownOptions=!0,this}ignoreOptionDefaultValue(){return this.config.ignoreOptionDefaultValue=!0,this}version(n,t="-v, --version"){return this.versionNumber=n,this.option(t,"Display version number"),this}example(n){return this.examples.push(n),this}option(n,t,s){let e=new Pe(n,t,s);return this.options.push(e),this}alias(n){return this.aliasNames.push(n),this}action(n){return this.commandAction=n,this}isMatched(n){return this.name===n||this.aliasNames.includes(n)}get isDefaultCommand(){return this.name===""||this.aliasNames.includes("!")}get isGlobalCommand(){return this instanceof ve}hasOption(n){return n=n.split(".")[0],this.options.find(t=>t.names.includes(n))}outputHelp(){let{name:n,commands:t}=this.cli,{versionNumber:s,options:e,helpCallback:a}=this.cli.globalCommand,i=[{body:`${n}${s?`/${s}`:""}`}];if(i.push({title:"Usage",body:` $ ${n} ${this.usageText||this.rawName}`}),(this.isGlobalCommand||this.isDefaultCommand)&&t.length>0){let d=he(t.map(o=>o.rawName));i.push({title:"Commands",body:t.map(o=>` ${ge(o.rawName,d.length)} ${o.description}`).join(`
3
3
  `)},{title:"For more info, run any command with the `--help` flag",body:t.map(o=>` $ ${n}${o.name===""?"":` ${o.name}`} --help`).join(`
4
4
  `)})}let r=this.isGlobalCommand?e:[...this.options,...e||[]];if(!this.isGlobalCommand&&!this.isDefaultCommand&&(r=r.filter(d=>d.name!=="version")),r.length>0){let d=he(r.map(o=>o.rawName));i.push({title:"Options",body:r.map(o=>` ${ge(o.rawName,d.length)} ${o.description} ${o.config.default===void 0?"":`(default: ${o.config.default})`}`).join(`
5
5
  `)})}this.examples.length>0&&i.push({title:"Examples",body:this.examples.map(d=>typeof d=="function"?d(n):d).join(`
6
6
  `)}),a&&(i=a(i)||i),console.info(i.map(d=>d.title?`${d.title}:
7
7
  ${d.body}`:d.body).join(`
8
8
 
9
- `))}outputVersion(){let{name:n}=this.cli,{versionNumber:t}=this.cli.globalCommand;t&&console.info(`${n}/${t} ${w}`)}checkRequiredArgs(){let n=this.args.filter(t=>t.required).length;if(this.cli.args.length<n)throw new x(`missing required args for command \`${this.rawName}\``)}checkUnknownOptions(){let{options:n,globalCommand:t}=this.cli;if(!this.config.allowUnknownOptions){for(let s of Object.keys(n))if(s!=="--"&&!this.hasOption(s)&&!t.hasOption(s))throw new x(`Unknown option \`${s.length>1?`--${s}`:`-${s}`}\``)}}checkOptionValue(){let{options:n,globalCommand:t}=this.cli,s=[...t.options,...this.options];for(let e of s){let a=n[e.name.split(".")[0]];if(e.required){let i=s.some(r=>r.negated&&r.names.includes(e.name));if(a===!0||a===!1&&!i)throw new x(`option \`${e.rawName}\` value is missing`)}}}checkUnusedArgs(){let n=this.args.some(t=>t.variadic)?1/0:this.args.length;if(n<this.cli.args.length)throw new x(`Unused args: ${this.cli.args.slice(n).map(t=>`\`${t}\``).join(", ")}`)}},ve=class extends ye{constructor(n){super("@@global@@","",{},n)}},Ye=class extends EventTarget{name;commands;globalCommand;matchedCommand;matchedCommandName;rawArgs;args;options;showHelpOnExit;showVersionOnExit;constructor(n=""){super(),this.name=n,this.commands=[],this.rawArgs=[],this.args=[],this.options={},this.globalCommand=new ve(this),this.globalCommand.usage("<command> [options]")}usage(n){return this.globalCommand.usage(n),this}command(n,t,s){let e=new ye(n,t||"",s,this);return e.globalCommand=this.globalCommand,this.commands.push(e),e}option(n,t,s){return this.globalCommand.option(n,t,s),this}help(n){return this.globalCommand.option("-h, --help","Display this message"),this.globalCommand.helpCallback=n,this.showHelpOnExit=!0,this}version(n,t="-v, --version"){return this.globalCommand.version(n,t),this.showVersionOnExit=!0,this}example(n){return this.globalCommand.example(n),this}outputHelp(){this.matchedCommand?this.matchedCommand.outputHelp():this.globalCommand.outputHelp()}outputVersion(){this.globalCommand.outputVersion()}setParsedInfo({args:n,options:t},s,e){return this.args=n,this.options=t,s&&(this.matchedCommand=s),e&&(this.matchedCommandName=e),this}unsetMatchedCommand(){this.matchedCommand=void 0,this.matchedCommandName=void 0}parse(n,{run:t=!0}={}){if(!n){if(!j)throw new Error("No argv provided and runtime process argv is not available.");n=j}this.rawArgs=n,this.name||(this.name=n[1]?We(n[1]):"cli");let s=!0;for(let a of this.commands){let i=this.mri(n.slice(2),a),r=i.args[0];if(a.isMatched(r)){s=!1;let d={...i,args:i.args.slice(1)};this.setParsedInfo(d,a,r),this.dispatchEvent(new CustomEvent(`command:${r}`,{detail:a}))}}if(s){for(let a of this.commands)if(a.isDefaultCommand){s=!1;let i=this.mri(n.slice(2),a);this.setParsedInfo(i,a),this.dispatchEvent(new CustomEvent("command:!",{detail:a}))}}if(s){let a=this.mri(n.slice(2));this.setParsedInfo(a)}this.options.help&&this.showHelpOnExit&&(this.outputHelp(),t=!1,this.unsetMatchedCommand()),this.options.version&&this.showVersionOnExit&&this.matchedCommandName==null&&(this.outputVersion(),t=!1,this.unsetMatchedCommand());let e={args:this.args,options:this.options};return t&&this.runMatchedCommand(),!this.matchedCommand&&this.args[0]&&this.dispatchEvent(new CustomEvent("command:*",{detail:this.args[0]})),e}mri(n,t){let s=[...this.globalCommand.options,...t?t.options:[]],e=Le(s),a=[],i=n.indexOf("--");i!==-1&&(a=n.slice(i+1),n=n.slice(0,i));let r=Be(n,e);r=Object.keys(r).reduce((m,p)=>({...m,[be(p)]:r[p]}),{_:[]});let d=r._,o={"--":a},l=t&&t.config.ignoreOptionDefaultValue?t.config.ignoreOptionDefaultValue:this.globalCommand.config.ignoreOptionDefaultValue,u=Object.create(null);for(let m of s){if(!l&&m.config.default!==void 0)for(let p of m.names)o[p]=m.config.default;Array.isArray(m.config.type)&&u[m.name]===void 0&&(u[m.name]=Object.create(null),u[m.name].shouldTransform=!0,u[m.name].transformFunction=m.config.type[0])}for(let m of Object.keys(r))m!=="_"&&(Ue(o,m.split("."),r[m]),qe(o,u));return{args:d,options:o}}runMatchedCommand(){let{args:n,options:t,matchedCommand:s}=this;if(!s||!s.commandAction)return;s.checkUnknownOptions(),s.checkOptionValue(),s.checkRequiredArgs(),s.checkUnusedArgs();let e=[];return s.args.forEach((a,i)=>{a.variadic?e.push(n.slice(i)):e.push(n[i])}),e.push(t),s.commandAction.apply(this,e)}},Ae=(n="")=>new Ye(n);import{existsSync as C,mkdirSync as Ge,readFileSync as $e,writeFileSync as I}from"node:fs";import{join as _}from"node:path";var xe=`# kadence \u2014 for AI agents
9
+ `))}outputVersion(){let{name:n}=this.cli,{versionNumber:t}=this.cli.globalCommand;t&&console.info(`${n}/${t} ${w}`)}checkRequiredArgs(){let n=this.args.filter(t=>t.required).length;if(this.cli.args.length<n)throw new x(`missing required args for command \`${this.rawName}\``)}checkUnknownOptions(){let{options:n,globalCommand:t}=this.cli;if(!this.config.allowUnknownOptions){for(let s of Object.keys(n))if(s!=="--"&&!this.hasOption(s)&&!t.hasOption(s))throw new x(`Unknown option \`${s.length>1?`--${s}`:`-${s}`}\``)}}checkOptionValue(){let{options:n,globalCommand:t}=this.cli,s=[...t.options,...this.options];for(let e of s){let a=n[e.name.split(".")[0]];if(e.required){let i=s.some(r=>r.negated&&r.names.includes(e.name));if(a===!0||a===!1&&!i)throw new x(`option \`${e.rawName}\` value is missing`)}}}checkUnusedArgs(){let n=this.args.some(t=>t.variadic)?1/0:this.args.length;if(n<this.cli.args.length)throw new x(`Unused args: ${this.cli.args.slice(n).map(t=>`\`${t}\``).join(", ")}`)}},ve=class extends ye{constructor(n){super("@@global@@","",{},n)}},Ye=class extends EventTarget{name;commands;globalCommand;matchedCommand;matchedCommandName;rawArgs;args;options;showHelpOnExit;showVersionOnExit;constructor(n=""){super(),this.name=n,this.commands=[],this.rawArgs=[],this.args=[],this.options={},this.globalCommand=new ve(this),this.globalCommand.usage("<command> [options]")}usage(n){return this.globalCommand.usage(n),this}command(n,t,s){let e=new ye(n,t||"",s,this);return e.globalCommand=this.globalCommand,this.commands.push(e),e}option(n,t,s){return this.globalCommand.option(n,t,s),this}help(n){return this.globalCommand.option("-h, --help","Display this message"),this.globalCommand.helpCallback=n,this.showHelpOnExit=!0,this}version(n,t="-v, --version"){return this.globalCommand.version(n,t),this.showVersionOnExit=!0,this}example(n){return this.globalCommand.example(n),this}outputHelp(){this.matchedCommand?this.matchedCommand.outputHelp():this.globalCommand.outputHelp()}outputVersion(){this.globalCommand.outputVersion()}setParsedInfo({args:n,options:t},s,e){return this.args=n,this.options=t,s&&(this.matchedCommand=s),e&&(this.matchedCommandName=e),this}unsetMatchedCommand(){this.matchedCommand=void 0,this.matchedCommandName=void 0}parse(n,{run:t=!0}={}){if(!n){if(!N)throw new Error("No argv provided and runtime process argv is not available.");n=N}this.rawArgs=n,this.name||(this.name=n[1]?We(n[1]):"cli");let s=!0;for(let a of this.commands){let i=this.mri(n.slice(2),a),r=i.args[0];if(a.isMatched(r)){s=!1;let d={...i,args:i.args.slice(1)};this.setParsedInfo(d,a,r),this.dispatchEvent(new CustomEvent(`command:${r}`,{detail:a}))}}if(s){for(let a of this.commands)if(a.isDefaultCommand){s=!1;let i=this.mri(n.slice(2),a);this.setParsedInfo(i,a),this.dispatchEvent(new CustomEvent("command:!",{detail:a}))}}if(s){let a=this.mri(n.slice(2));this.setParsedInfo(a)}this.options.help&&this.showHelpOnExit&&(this.outputHelp(),t=!1,this.unsetMatchedCommand()),this.options.version&&this.showVersionOnExit&&this.matchedCommandName==null&&(this.outputVersion(),t=!1,this.unsetMatchedCommand());let e={args:this.args,options:this.options};return t&&this.runMatchedCommand(),!this.matchedCommand&&this.args[0]&&this.dispatchEvent(new CustomEvent("command:*",{detail:this.args[0]})),e}mri(n,t){let s=[...this.globalCommand.options,...t?t.options:[]],e=Le(s),a=[],i=n.indexOf("--");i!==-1&&(a=n.slice(i+1),n=n.slice(0,i));let r=Be(n,e);r=Object.keys(r).reduce((m,p)=>({...m,[be(p)]:r[p]}),{_:[]});let d=r._,o={"--":a},l=t&&t.config.ignoreOptionDefaultValue?t.config.ignoreOptionDefaultValue:this.globalCommand.config.ignoreOptionDefaultValue,u=Object.create(null);for(let m of s){if(!l&&m.config.default!==void 0)for(let p of m.names)o[p]=m.config.default;Array.isArray(m.config.type)&&u[m.name]===void 0&&(u[m.name]=Object.create(null),u[m.name].shouldTransform=!0,u[m.name].transformFunction=m.config.type[0])}for(let m of Object.keys(r))m!=="_"&&(Ue(o,m.split("."),r[m]),qe(o,u));return{args:d,options:o}}runMatchedCommand(){let{args:n,options:t,matchedCommand:s}=this;if(!s||!s.commandAction)return;s.checkUnknownOptions(),s.checkOptionValue(),s.checkRequiredArgs(),s.checkUnusedArgs();let e=[];return s.args.forEach((a,i)=>{a.variadic?e.push(n.slice(i)):e.push(n[i])}),e.push(t),s.commandAction.apply(this,e)}},Ae=(n="")=>new Ye(n);import{existsSync as C,mkdirSync as Ge,readFileSync as $e,writeFileSync as _}from"node:fs";import{join as I}from"node:path";var xe=`# kadence \u2014 for AI agents
10
10
 
11
11
  This project's tasks live here as plain files. Read them directly, or through
12
12
  the CLI. No server required.
@@ -36,7 +36,7 @@ event is marked as human \u2014 we do not guess.
36
36
 
37
37
  Do not hand-edit files under \`.kadence/events/\`: the journal is appended to,
38
38
  never modified. To correct the state, add a new event through the CLI.
39
- `,we="<!-- kadence:begin -->",R="<!-- kadence:end -->",N=`${we}
39
+ `,we="<!-- kadence:begin -->",R="<!-- kadence:end -->",j=`${we}
40
40
  ## Project tasks \u2014 kadence
41
41
 
42
42
  Tasks live in \`.kadence/\` as plain files. Read them directly or via the CLI:
@@ -49,23 +49,23 @@ Tasks live in \`.kadence/\` as plain files. Read them directly or via the CLI:
49
49
  When acting as an agent, set \`KADENCE_SOURCE=agent\`.
50
50
 
51
51
  Details: \`.kadence/README.md\`
52
- ${R}`;function Ce(n){if(n===null||n.trim().length===0)return`${N}
53
- `;let t=n.indexOf(we),s=n.indexOf(R);if(t!==-1&&s!==-1&&s>t){let a=n.slice(0,t),i=n.slice(s+R.length);return`${a}${N}${i}`}let e=n.endsWith(`
52
+ ${R}`;function Ce(n){if(n===null||n.trim().length===0)return`${j}
53
+ `;let t=n.indexOf(we),s=n.indexOf(R);if(t!==-1&&s!==-1&&s>t){let a=n.slice(0,t),i=n.slice(s+R.length);return`${a}${j}${i}`}let e=n.endsWith(`
54
54
  `)?`
55
55
  `:`
56
56
 
57
- `;return`${n}${e}${N}
57
+ `;return`${n}${e}${j}
58
58
  `}var De=".kadence/state.json";function Ee(n){let t=F(n);if(t===null)return{ok:!1,alreadyInitialized:!1,root:null,message:`kadence lives inside a git repository, and there is none here.
59
59
  Create one and try again:
60
- git init`};let s=C($(t));Ge($(t),{recursive:!0}),Ve(t);let e=_(U(t),"README.md");return C(e)||I(e,xe,"utf8"),Je(t),{ok:!0,alreadyInitialized:s,root:t,message:s?"kadence is already initialised.":`kadence is ready.
60
+ git init`};let s=C($(t));Ge($(t),{recursive:!0}),Ve(t);let e=I(U(t),"README.md");return C(e)||_(e,xe,"utf8"),Je(t),{ok:!0,alreadyInitialized:s,root:t,message:s?"kadence is already initialised.":`kadence is ready.
61
61
 
62
62
  kadence task add "first task"
63
63
  kadence board
64
64
 
65
- Files were created but not committed \u2014 that call is yours.`}}function Ve(n){let t=_(n,".gitignore"),s="";if(C(t)&&(s=$e(t,"utf8")),s.includes(De))return;let e=s.length>0&&!s.endsWith(`
65
+ Files were created but not committed \u2014 that call is yours.`}}function Ve(n){let t=I(n,".gitignore"),s="";if(C(t)&&(s=$e(t,"utf8")),s.includes(De))return;let e=s.length>0&&!s.endsWith(`
66
66
  `)?`
67
- `:"";I(t,`${s}${e}${De}
68
- `,"utf8")}function Je(n){let t=_(n,"AGENTS.md"),s=C(t)?$e(t,"utf8"):null,e=Ce(s);e!==s&&I(t,e,"utf8")}var B="cancelled";function Se(n,t,s){let e=k(n,t);if(!b(e))return e;let{state:a,warnings:i}=y(e.root,e.actor),r=a.tasks.filter(u=>u.status!==B);if(s.assignee!==void 0){let u=s.assignee.toLowerCase(),m=u==="me"?e.actor.toLowerCase():u;r=r.filter(p=>(p.assignee??"").toLowerCase()===m)}if(s.sprint==="active"){let u=a.sprints.find(m=>m.status==="active"||m.status==="planned");r=u===void 0?[]:r.filter(m=>m.sprint===u.id)}let d={};for(let u of a.statuses)u!==B&&(d[u]=r.filter(m=>m.status===u));let o=a.orphanStatuses.filter(u=>u!==B);for(let u of o)d[u]=r.filter(m=>m.status===u);let l=o.length>0?[`Statuses not in the board configuration: ${o.join(", ")}.
67
+ `:"";_(t,`${s}${e}${De}
68
+ `,"utf8")}function Je(n){let t=I(n,"AGENTS.md"),s=C(t)?$e(t,"utf8"):null,e=Ce(s);e!==s&&_(t,e,"utf8")}var B="cancelled";function Se(n,t,s){let e=k(n,t);if(!b(e))return e;let{state:a,warnings:i}=y(e.root,e.actor),r=a.tasks.filter(u=>u.status!==B);if(s.assignee!==void 0){let u=s.assignee.toLowerCase(),m=u==="me"?e.actor.toLowerCase():u;r=r.filter(p=>(p.assignee??"").toLowerCase()===m)}if(s.sprint==="active"){let u=a.sprints.find(m=>m.status==="active"||m.status==="planned");r=u===void 0?[]:r.filter(m=>m.sprint===u.id)}let d={};for(let u of a.statuses)u!==B&&(d[u]=r.filter(m=>m.status===u));let o=a.orphanStatuses.filter(u=>u!==B);for(let u of o)d[u]=r.filter(m=>m.status===u);let l=o.length>0?[`Statuses not in the board configuration: ${o.join(", ")}.
69
69
  Tasks there are still shown. Add the column or move them:
70
70
  kadence board config --statuses "..."`]:[];return{ok:!0,exitCode:0,warnings:[...i,...l],message:G(d,Y(t,process.stdout.isTTY===!0)),data:{schema:"kadence/v1",ok:!0,columns:Object.fromEntries(Object.entries(d).map(([u,m])=>[u,m.map(Q)]))}}}function Oe(n,t,s){let e=k(n,t);if(!b(e))return e;let{state:a,warnings:i}=y(e.root,e.actor);if(s===void 0)return{ok:!0,exitCode:0,warnings:i,message:`Board columns: ${a.statuses.join(", ")}
71
71
 
@@ -75,8 +75,8 @@ ${d.length} task(s) remain in removed columns: ${[...new Set(d.map(l=>l.status))
75
75
  kadence template save bug --type bug --priority high --label triage`}:(A(a.root,{id:g(),type:"template.saved",entity:g(),actor:a.actor,ts:new Date().toISOString(),source:a.source,data:{name:i,fields:r}}),{ok:!0,exitCode:0,message:`Template "${i}" saved: ${Object.keys(r).join(", ")}.
76
76
  kadence task add "title" --template ${i}`,data:{schema:"kadence/v1",ok:!0,template:{name:i,fields:r}}})}function Ke(n,t){let s=k(n,t);if(!b(s))return s;let{state:e,warnings:a}=y(s.root,s.actor);return e.templates.length===0?{ok:!0,exitCode:0,warnings:a,message:`No templates yet.
77
77
  kadence template save bug --type bug --priority high`,data:{schema:"kadence/v1",ok:!0,templates:[]}}:{ok:!0,exitCode:0,warnings:a,message:e.templates.map(i=>{let r=Object.entries(i.fields).map(([d,o])=>`${d}=${Array.isArray(o)?o.join("/"):String(o)}`).join(" ");return` ${i.name.padEnd(14)} ${r}`}).join(`
78
- `),data:{schema:"kadence/v1",ok:!0,templates:e.templates}}}function je(n,t,s){let e=k(n,t);if(!b(e))return e;let{state:a,warnings:i}=y(e.root,e.actor);return a.templates.some(r=>r.name===s)?(A(e.root,{id:g(),type:"template.deleted",entity:g(),actor:e.actor,ts:new Date().toISOString(),source:e.source,data:{name:s}}),{ok:!0,exitCode:0,warnings:i,message:`Template "${s}" deleted.`}):{ok:!1,exitCode:1,message:`No template "${s}".
79
- kadence template list`}}function Ne(n,t,s){let e=k(n,t);if(!b(e))return{error:e};let{state:a}=y(e.root,e.actor),i=a.templates.find(r=>r.name===s);if(i===void 0){let r=a.templates.map(d=>d.name).join(", ");return{error:{ok:!1,exitCode:1,message:`No template "${s}".`+(r.length>0?`
78
+ `),data:{schema:"kadence/v1",ok:!0,templates:e.templates}}}function Ne(n,t,s){let e=k(n,t);if(!b(e))return e;let{state:a,warnings:i}=y(e.root,e.actor);return a.templates.some(r=>r.name===s)?(A(e.root,{id:g(),type:"template.deleted",entity:g(),actor:e.actor,ts:new Date().toISOString(),source:e.source,data:{name:s}}),{ok:!0,exitCode:0,warnings:i,message:`Template "${s}" deleted.`}):{ok:!1,exitCode:1,message:`No template "${s}".
79
+ kadence template list`}}function je(n,t,s){let e=k(n,t);if(!b(e))return{error:e};let{state:a}=y(e.root,e.actor),i=a.templates.find(r=>r.name===s);if(i===void 0){let r=a.templates.map(d=>d.name).join(", ");return{error:{ok:!1,exitCode:1,message:`No template "${s}".`+(r.length>0?`
80
80
  Available: ${r}`:`
81
81
  kadence template save ...`)}}}return{fields:i.fields}}var h=Ae("kadence");function c(n,t){for(let s of n.warnings??[])process.stderr.write(`${s}
82
82
  `);if(t){let s=n.data??{schema:"kadence/v1",ok:n.ok,...n.ok?{}:{error:{message:n.message}}};process.stdout.write(`${JSON.stringify(s)}
@@ -94,7 +94,7 @@ Pass the text directly:
94
94
  kadence task cancel KAD-1
95
95
  kadence task delete KAD-1`),a),n){case"add":{t===void 0&&c(f(`A title is required:
96
96
  kadence task add "Fix login"`),a);let r=e.estimate===void 0?void 0:Number(e.estimate);r!==void 0&&(!Number.isFinite(r)||r<0)&&c(f(`Estimate must be a positive number, got "${e.estimate}".
97
- kadence task add "Fix login" --estimate 3`),a);let d={};if(e.template!==void 0){let l=Ne(i,process.env,e.template);"error"in l?c(l.error,a):d=l.fields}let o=e.label===void 0?void 0:Array.isArray(e.label)?e.label:[e.label];c(J(i,process.env,t,{...d,...e.description!==void 0?{description:e.description}:{},...e.type!==void 0?{type:e.type}:{},...e.priority!==void 0?{priority:e.priority}:{},...e.assignee!==void 0?{assignee:e.assignee}:{},...o!==void 0?{labels:o}:{},...e.due!==void 0?{due:e.due}:{},...e.parent!==void 0?{parent:e.parent}:{},...r!==void 0?{estimate:r}:{}}),a);break}case"log":(t===void 0||s===void 0)&&c(f(`A task and a duration are required:
97
+ kadence task add "Fix login" --estimate 3`),a);let d={};if(e.template!==void 0){let l=je(i,process.env,e.template);"error"in l?c(l.error,a):d=l.fields}let o=e.label===void 0?void 0:Array.isArray(e.label)?e.label:[e.label];c(J(i,process.env,t,{...d,...e.description!==void 0?{description:e.description}:{},...e.type!==void 0?{type:e.type}:{},...e.priority!==void 0?{priority:e.priority}:{},...e.assignee!==void 0?{assignee:e.assignee}:{},...o!==void 0?{labels:o}:{},...e.due!==void 0?{due:e.due}:{},...e.parent!==void 0?{parent:e.parent}:{},...r!==void 0?{estimate:r}:{}}),a);break}case"log":(t===void 0||s===void 0)&&c(f(`A task and a duration are required:
98
98
  kadence task log KAD-1 2h
99
99
  kadence task log KAD-1 90m`),a),c(T(i,process.env,t,s),a);break;case"parent":(t===void 0||s===void 0)&&c(f(`A task and a parent are required:
100
100
  kadence task parent KAD-2 KAD-1
@@ -128,8 +128,8 @@ Available: config
128
128
  Available: create, add, edit, start, close, status, list, burndown
129
129
  kadence sprint --help`),e)}});h.command("template [action] [name]","Task templates: save | list | delete").option("-d, --description <text>","Default description").option("--type <type>","Default type").option("--priority <level>","Default priority").option("-a, --assignee <who>","Default assignee").option("--label <name>","Default label; repeat for several").option("--estimate <points>","Default estimate").option("--json","Machine-readable output for agents").example(" kadence template save bug --type bug --priority high --label triage").example(" kadence template list").action((n,t,s)=>{let e=s.json===!0,a=process.cwd();switch(n){case"save":{t===void 0&&c(f(`A template name is required:
130
130
  kadence template save bug --type bug`),e);let i=s.label===void 0?void 0:Array.isArray(s.label)?s.label:[s.label];c(Te(a,process.env,t,{...s.description!==void 0?{description:s.description}:{},...s.type!==void 0?{type:s.type}:{},...s.priority!==void 0?{priority:s.priority}:{},...s.assignee!==void 0?{assignee:s.assignee}:{},...i!==void 0?{labels:i}:{},...s.estimate!==void 0?{estimate:Number(s.estimate)}:{}}),e);break}case"list":case void 0:c(Ke(a,process.env),e);break;case"delete":t===void 0&&c(f(`Which template?
131
- kadence template delete bug`),e),c(je(a,process.env,t),e);break;default:c(f(`Unknown action "${n}".
132
- Available: save, list, delete`),e)}});h.command("ui","Interactive kanban board").alias("board:ui").example(" kadence ui").action(async()=>{let{runUi:n}=await import("./chunks/ui-WFLRVGUH.js"),t=await n(process.cwd(),process.env);t.ok||c(t,!1)});h.help();h.version("0.1.0-dev");var v=process.argv;if(v[2]==="task"&&v[3]==="log"&&v[4]!==void 0&&v[5]!==void 0){let n=T(process.cwd(),process.env,v[4],v[5]),t=v.includes("--json");c(n,t)}var Ie=process.argv.findIndex((n,t)=>n.startsWith("-")&&/^-\d+(\.\d+)?$/.test(n)&&process.argv[t-1]==="--estimate");Ie!==-1&&(process.stderr.write(`Estimate must be a positive number, got "${process.argv[Ie]}".
131
+ kadence template delete bug`),e),c(Ne(a,process.env,t),e);break;default:c(f(`Unknown action "${n}".
132
+ Available: save, list, delete`),e)}});h.command("ui","Interactive kanban board").alias("board:ui").example(" kadence ui").action(async()=>{let{runUi:n}=await import("./chunks/ui-WFLRVGUH.js"),t=await n(process.cwd(),process.env);t.ok||c(t,!1)});h.help();h.version("0.1.2");var v=process.argv;if(v[2]==="task"&&v[3]==="log"&&v[4]!==void 0&&v[5]!==void 0){let n=T(process.cwd(),process.env,v[4],v[5]),t=v.includes("--json");c(n,t)}var _e=process.argv.findIndex((n,t)=>n.startsWith("-")&&/^-\d+(\.\d+)?$/.test(n)&&process.argv[t-1]==="--estimate");_e!==-1&&(process.stderr.write(`Estimate must be a positive number, got "${process.argv[_e]}".
133
133
  kadence task add "Fix login" --estimate 3
134
134
  `),process.exit(2));try{h.parse()}catch(n){process.stderr.write(`${n.message}
135
135
  `),process.exit(2)}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kadence",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Tasks, sprints and velocity as plain files inside your git repository",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -26,7 +26,8 @@
26
26
  "dependencies": {
27
27
  "@types/blessed": "^0.1.27",
28
28
  "blessed": "^0.1.81",
29
- "cac": "^7.0.0"
29
+ "cac": "^7.0.0",
30
+ "kadence": "^0.1.1"
30
31
  },
31
32
  "devDependencies": {
32
33
  "@types/node": "^22.0.0",