ai-projects 2.0.0 → 2.1.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.
Files changed (2) hide show
  1. package/dist/index.js +30 -30
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import {z as z$1}from'zod';import {parser}from'zod-opts';import'dotenv';import it from'path';import {spawn,exec}from'child_process';import G from'fs/promises';import b from'lodash';import V from'moment';import {fileURLToPath}from'url';import {inspect}from'util';import Et from'yaml';import ut from'fs';var ze=Object.defineProperty;var f=(t,e)=>()=>(t&&(e=t(t=0)),e);var Be=(t,e)=>{for(var o in e)ze(t,o,{get:e[o],enumerable:true});};var x,J=f(()=>{x={name:"ai-projects",version:"2.0.0",type:"module",description:"Useful CLI for AI agents to create and manage projects, tasks, skills and agents",main:"dist/index.js",types:"dist/index.d.ts",bin:{aip:"dist/index.js"},files:["dist/**/*","README.md","LICENSE"],scripts:{build:"npm run build:map && npm run build:code","build:map":"tsx bin/map-commands.ts","build:code":"tsup --no-dts","build:full":"npm run build:map && tsup","build:check":"tsc --noEmit","build:watch":"npm run build:code -- --watch","build:clean":"rimraf dist/*",start:"dist/index.js",dev:'npm run build:watch -- --onSuccess "dist/index.js"',cli:"npm run build && npm start --",ts:"tsx",vitest:"VITE_CJS_IGNORE_WARNING=true vitest",test:"npm run test:types && npm run test:unit","test:unit":"npm run vitest -- run","test:types:test":"tsc -p tsconfig.test.json --incremental --tsBuildInfoFile test.tsbuildinfo","test:types:bin":"tsc -p bin/tsconfig.json --incremental --tsBuildInfoFile bin.tsbuildinfo","test:types":"npm run test:types:test && npm run test:types:bin","test:full":"npm run lint:full && npm run test",eslint:"eslint --cache",lint:"npm run eslint -- '{src,bin}/**/*.ts'","lint:fix":"npm run lint -- --fix","lint:full":"npm run build:check && npm run test:types:bin && npm run lint:fix","lint:full:silent":"npm run -s lint:full && echo LINT OK",prepare:'[ "$CI" != "true" ] && [ -d node_modules/husky ] && husky || true',prepack:"npm run test:full && npm run build:full","publish:dry":"npm pack --dry-run","version:patch":"npm version patch","version:minor":"npm version minor","version:major":"npm version major","agent:stop":"npm run -s lint:full:silent"},keywords:["ai","aip","project","task","kanban","cli","agent","automation"],author:"Ariel Flesler <aflesler@gmail.com>",license:"MIT",repository:{type:"git",url:"git+https://github.com/flesler/ai-projects.git"},homepage:"https://github.com/flesler/ai-projects#readme",bugs:{url:"https://github.com/flesler/ai-projects/issues"},engines:{node:">=20.0.0"},dependencies:{dotenv:"^17.3.1",lodash:"^4.17.21",moment:"^2.30.1",tslib:"^2.8.1",yaml:"^2.8.0",zod:"^3.25.76","zod-opts":"^1.0.0"},devDependencies:{"@eslint/js":"^10.0.1","@stylistic/eslint-plugin":"^5.7.0","@types/dotenv":"^8.2.3","@types/eslint":"^9.6.1","@types/lodash":"^4.17.23","@types/moment":"^2.13.0","@types/node":"^25.0.9","@types/source-map-support":"^0.5.10","@typescript-eslint/eslint-plugin":"^8.53.0","@typescript-eslint/parser":"^8.53.0",eslint:"^10.0.3","eslint-plugin-import-x":"^4.16.2","eslint-plugin-unused-imports":"^4.4.1","fast-glob":"^3.3.3",husky:"^9.1.7",rimraf:"^6.0.1","source-map-support":"^0.5.21",tsup:"^8.5.1",tsx:"^4.20.3","types-package-json":"^2.0.39",typescript:"^5.8.3",vitest:"^4.0.17"}};});function d(t){let{description:e,options:o=z$1.object({}),args:r,handler:s}=t,i=o.shape,a={};for(let[m,l]of Object.entries(i))a[m]={type:l};let p=parser().options(a);if(r){let m=r.shape,l=Object.entries(m).map(([g,y])=>({name:g,type:y}));l.length>0&&(p=p.args(l));}return e&&(p=p.description(e)),{description:e,options:o,args:r,parser:p,handler:s,cli:m=>s(p.parse(m))}}var k=f(()=>{});var c,P=f(()=>{c={dirs:{PROJECTS:"projects",SKILLS:"skills",AGENTS:"agents",TASKS:"tasks",INPUTS:"inputs",OUTPUTS:"outputs",HOOKS:"hooks",SCRIPTS:"scripts"},files:{MAIN:"main.md",LOG:"log.tsv",SKILL:"SKILL.md"},hookTypes:["pre-create","post-create","pre-complete","post-complete","pre-start","post-start","pre-update","post-update"],languages:["ts","js","sh","py"],targets:["project","task"]};});function Ze(t){return t.startsWith("~")?it.join(process.env.HOME??"",t.slice(1)):t}var W,qe,S,L=f(()=>{P();W=process.env.AIP_HOME?Ze(process.env.AIP_HOME):void 0;if(!W){W=process.cwd();let t=W.split(it.sep);for(let e of [c.dirs.PROJECTS,c.dirs.SKILLS,c.dirs.AGENTS]){let o=t.indexOf(e);if(o!==-1){W=t.slice(0,o).join(it.sep);break}}}qe={AIP_HOME:W,ERROR_LOG:process.env.AIP_ERROR_LOG},S=qe;});var T,n,j=f(()=>{L();T={REPO:fileURLToPath(import.meta.url.replace(/\/(dist|src)\/.*/,"/")),join:(...t)=>it.join(...t),onRepo:(...t)=>T.join(T.REPO,...t),joinHome:(...t)=>T.join(S.AIP_HOME,...t),async ensureDir(t){await G.mkdir(t,{recursive:true});},async write(t,e){await T.ensureDir(it.dirname(t)),await G.writeFile(t,e,"utf8");},async append(t,e){await T.ensureDir(it.dirname(t)),await G.appendFile(t,e,"utf8");},async read(t){return G.readFile(t,"utf8")},async readRepo(...t){return T.read(T.onRepo(...t))},async readMany(...t){return (await Promise.all(t.map(async o=>{let r=await T.fileExists(o)?await T.read(o):"ERROR: File not found";return `# ${o}
2
+ import {z as z$1}from'zod';import {parser}from'zod-opts';import'dotenv';import it from'path';import {spawn,exec}from'child_process';import G from'fs/promises';import b from'lodash';import V from'moment';import {fileURLToPath}from'url';import {inspect}from'util';import Dt from'yaml';import ut from'fs';var We=Object.defineProperty;var f=(t,e)=>()=>(t&&(e=t(t=0)),e);var Ve=(t,e)=>{for(var o in e)We(t,o,{get:e[o],enumerable:true});};var x,J=f(()=>{x={name:"ai-projects",version:"2.1.0",type:"module",description:"Useful CLI for AI agents to create and manage projects, tasks, skills and agents",main:"dist/index.js",types:"dist/index.d.ts",bin:{aip:"dist/index.js"},files:["dist/**/*","README.md","LICENSE"],scripts:{build:"npm run build:map && npm run build:code","build:map":"tsx bin/map-commands.ts","build:code":"tsup --no-dts","build:full":"npm run build:map && tsup","build:check":"tsc --noEmit","build:watch":"npm run build:code -- --watch","build:clean":"rimraf dist/*",start:"dist/index.js",dev:'npm run build:watch -- --onSuccess "dist/index.js"',cli:"npm run build && npm start --",ts:"tsx",vitest:"VITE_CJS_IGNORE_WARNING=true vitest",test:"npm run test:types && npm run test:unit","test:unit":"npm run vitest -- run","test:types:test":"tsc -p tsconfig.test.json --incremental --tsBuildInfoFile test.tsbuildinfo","test:types:bin":"tsc -p bin/tsconfig.json --incremental --tsBuildInfoFile bin.tsbuildinfo","test:types":"npm run test:types:test && npm run test:types:bin","test:full":"npm run lint:full && npm run test",eslint:"eslint --cache",lint:"npm run eslint -- '{src,bin}/**/*.ts'","lint:fix":"npm run lint -- --fix","lint:full":"npm run build:check && npm run test:types:bin && npm run lint:fix","lint:full:silent":"npm run -s lint:full && echo LINT OK",prepare:'[ "$CI" != "true" ] && [ -d node_modules/husky ] && husky || true',prepack:"npm run test:full && npm run build:full","publish:dry":"npm pack --dry-run","version:patch":"npm version patch","version:minor":"npm version minor","version:major":"npm version major","agent:stop":"npm run -s lint:full:silent"},keywords:["ai","aip","project","task","kanban","cli","agent","automation"],author:"Ariel Flesler <aflesler@gmail.com>",license:"MIT",repository:{type:"git",url:"git+https://github.com/flesler/ai-projects.git"},homepage:"https://github.com/flesler/ai-projects#readme",bugs:{url:"https://github.com/flesler/ai-projects/issues"},engines:{node:">=20.0.0"},dependencies:{dotenv:"^17.3.1",lodash:"^4.17.21",moment:"^2.30.1",tslib:"^2.8.1",yaml:"^2.8.0",zod:"^3.25.76","zod-opts":"^1.0.0"},devDependencies:{"@eslint/js":"^10.0.1","@stylistic/eslint-plugin":"^5.7.0","@types/dotenv":"^8.2.3","@types/eslint":"^9.6.1","@types/lodash":"^4.17.23","@types/moment":"^2.13.0","@types/node":"^25.0.9","@types/source-map-support":"^0.5.10","@typescript-eslint/eslint-plugin":"^8.53.0","@typescript-eslint/parser":"^8.53.0",eslint:"^10.0.3","eslint-plugin-import-x":"^4.16.2","eslint-plugin-unused-imports":"^4.4.1","fast-glob":"^3.3.3",husky:"^9.1.7",rimraf:"^6.0.1","source-map-support":"^0.5.21",tsup:"^8.5.1",tsx:"^4.20.3","types-package-json":"^2.0.39",typescript:"^5.8.3",vitest:"^4.0.17"}};});function d(t){let{description:e,options:o=z$1.object({}),args:r,handler:s}=t,i=o.shape,a={};for(let[m,p]of Object.entries(i))a[m]={type:p};let l=parser().options(a);if(r){let m=r.shape,p=Object.entries(m).map(([g,y])=>({name:g,type:y}));p.length>0&&(l=l.args(p));}return e&&(l=l.description(e)),{description:e,options:o,args:r,parser:l,handler:s,cli:m=>s(l.parse(m))}}var k=f(()=>{});var c,P=f(()=>{c={dirs:{PROJECTS:"projects",SKILLS:"skills",AGENTS:"agents",TASKS:"tasks",INPUTS:"inputs",OUTPUTS:"outputs",HOOKS:"hooks",SCRIPTS:"scripts"},files:{MAIN:"main.md",LOG:"log.tsv",SKILL:"SKILL.md"},hookTypes:["pre-create","post-create","pre-complete","post-complete","pre-start","post-start","pre-update","post-update"],languages:["ts","js","sh","py"],targets:["project","task"]};});function Qe(t){return t.startsWith("~")?it.join(process.env.HOME??"",t.slice(1)):t}var W,Xe,S,_=f(()=>{P();W=process.env.AIP_HOME?Qe(process.env.AIP_HOME):void 0;if(!W){W=process.cwd();let t=W.split(it.sep);for(let e of [c.dirs.PROJECTS,c.dirs.SKILLS,c.dirs.AGENTS]){let o=t.indexOf(e);if(o!==-1){W=t.slice(0,o).join(it.sep);break}}}Xe={AIP_HOME:W,ERROR_LOG:process.env.AIP_ERROR_LOG},S=Xe;});var T,n,j=f(()=>{_();T={REPO:fileURLToPath(import.meta.url.replace(/\/(dist|src)\/.*/,"/")),join:(...t)=>it.join(...t),onRepo:(...t)=>T.join(T.REPO,...t),joinHome:(...t)=>T.join(S.AIP_HOME,...t),async ensureDir(t){await G.mkdir(t,{recursive:true});},async write(t,e){await T.ensureDir(it.dirname(t)),await G.writeFile(t,e,"utf8");},async append(t,e){await T.ensureDir(it.dirname(t)),await G.appendFile(t,e,"utf8");},async read(t){return G.readFile(t,"utf8")},async readRepo(...t){return T.read(T.onRepo(...t))},async readMany(...t){return (await Promise.all(t.map(async o=>{let r=await T.fileExists(o)?await T.read(o):"ERROR: File not found";return `# ${o}
3
3
 
4
4
  ${r}`}))).filter(Boolean)},async logFiles(...t){let e=await T.readMany(...t);console.log(e.join(`
5
5
 
@@ -9,18 +9,18 @@ ${r}`}))).filter(Boolean)},async logFiles(...t){let e=await T.readMany(...t);con
9
9
  `).replace(/\r/g,"").replace(/[ \t]*\n[ \t]*/g,`
10
10
  `).replace(/\n{3,}/g,`
11
11
 
12
- `).replace(/ {2,}/g," ").trim(),oneLine:t=>t.replace(/\n/g,"\\n").replace(/\t/g,"\\t").replace(/ +/g," ").trim(),fuzzySearch:(t,e)=>b.includes(b.toLower(t||""),b.toLower(e||"")),elapsed:(t,e=Date.now())=>V.duration(V(e).diff(t||0)),iso:t=>V.utc(t).toISOString(),isoDate:t=>T.iso(t).slice(0,10),memoizeKey:(...t)=>t.join(""),exit:(t=0)=>{process.exit(t);},set:(t,e,o)=>(t[e]=o,t),run:async t=>{try{await t(),process.exit(0);}catch(e){console.error(e),process.exit(1);}},isMain:()=>{let t=process.argv[1]||"";return t.includes("/index.")||t.endsWith("/bin/aip")},errorMessage:t=>t instanceof Error?t.message:String(t),slugify:t=>t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,""),matchesSearch:(t,e)=>{let o=e?.toLowerCase().split(/\s+/).filter(Boolean);if(!o?.length)return true;let r=t.toLowerCase();return o.every(s=>r.includes(s))}},n=T;});var eo,rt,oo,Ot=f(()=>{j();eo=" ",rt=class{filename;context;constructor(t){this.filename=t;}log=(t,e,...o)=>{this.filename&&!this.context&&(this.context=`<${oo(this.filename)}>`),this.context&&o.unshift(this.context);let[r,s]=new Date().toISOString().split(/[T.]/);o.unshift(e,r,s);let i=o.map(this.stringify).map(this.sanitize).join(eo);return t?console.error(i):console.log(i),i};stringify=t=>{if(!t)return "-";if(b.isNumber(t))return `${t}`;if(b.isError(t))return n.oneLine(t.message||"");if(b.isFunction(t))return n.oneLine(t.toString());if(b.isObject(t)||b.isArray(t))try{return n.dump(t)}catch(e){return `Failed to stringify: ${e.message}`}return b.toString(t)};sanitize=t=>t.replace(/ {2,}/g," ");debug=(...t)=>{this.log(false,"[DEBUG]",...t);};info=(...t)=>{this.log(false,"[INFO]",...t);};warn=(...t)=>{this.log(true,"[WARN]",...t);};error=(...t)=>{this.log(true,"[ERROR]",...t);}},oo=t=>{let e=t.split(it.sep),[o,r,...s]=e.reverse();if(!s.length)return t;let i=it.basename(o,".js").replace(".ts","");if(i==="index")return r;let a=e.indexOf("commands");if(a!==-1&&a<e.length-1){let p=e.slice(a+1);if(p.length>=2){let[m,l]=p;return `<${m}/${l.replace(".js","").replace(".ts","")}>`}}return i};});var ro,st,M,kt,Z,Dt=f(()=>{j();Ot();ro=new rt,st=t=>{let e=t.trim();if(!e.startsWith("---"))return null;let o=e.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);return o?{frontmatter:Et.parse(o[1]),content:o[2].trim()}:null},M=async(t,e,o="")=>{let s=`---
13
- ${Et.stringify(e).trim()}
12
+ `).replace(/ {2,}/g," ").trim(),oneLine:t=>t.replace(/\n/g,"\\n").replace(/\t/g,"\\t").replace(/ +/g," ").trim(),fuzzySearch:(t,e)=>b.includes(b.toLower(t||""),b.toLower(e||"")),elapsed:(t,e=Date.now())=>V.duration(V(e).diff(t||0)),iso:t=>V.utc(t).toISOString(),isoDate:t=>T.iso(t).slice(0,10),memoizeKey:(...t)=>t.join(""),exit:(t=0)=>{process.exit(t);},set:(t,e,o)=>(t[e]=o,t),run:async t=>{try{await t(),process.exit(0);}catch(e){console.error(e),process.exit(1);}},isMain:()=>{let t=process.argv[1]||"";return t.includes("/index.")||t.endsWith("/bin/aip")},errorMessage:t=>t instanceof Error?t.message:String(t),slugify:t=>t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,""),matchesSearch:(t,e)=>{let o=e?.toLowerCase().split(/\s+/).filter(Boolean);if(!o?.length)return true;let r=t.toLowerCase();return o.every(s=>r.includes(s))}},n=T;});var so,rt,no,Ot=f(()=>{j();so=" ",rt=class{filename;context;constructor(t){this.filename=t;}log=(t,e,...o)=>{this.filename&&!this.context&&(this.context=`<${no(this.filename)}>`),this.context&&o.unshift(this.context);let[r,s]=new Date().toISOString().split(/[T.]/);o.unshift(e,r,s);let i=o.map(this.stringify).map(this.sanitize).join(so);return t?console.error(i):console.log(i),i};stringify=t=>{if(!t)return "-";if(b.isNumber(t))return `${t}`;if(b.isError(t))return n.oneLine(t.message||"");if(b.isFunction(t))return n.oneLine(t.toString());if(b.isObject(t)||b.isArray(t))try{return n.dump(t)}catch(e){return `Failed to stringify: ${e.message}`}return b.toString(t)};sanitize=t=>t.replace(/ {2,}/g," ");debug=(...t)=>{this.log(false,"[DEBUG]",...t);};info=(...t)=>{this.log(false,"[INFO]",...t);};warn=(...t)=>{this.log(true,"[WARN]",...t);};error=(...t)=>{this.log(true,"[ERROR]",...t);}},no=t=>{let e=t.split(it.sep),[o,r,...s]=e.reverse();if(!s.length)return t;let i=it.basename(o,".js").replace(".ts","");if(i==="index")return r;let a=e.indexOf("commands");if(a!==-1&&a<e.length-1){let l=e.slice(a+1);if(l.length>=2){let[m,p]=l;return `<${m}/${p.replace(".js","").replace(".ts","")}>`}}return i};});var io,st,M,kt,Z,Rt=f(()=>{j();Ot();io=new rt,st=t=>{let e=t.trim();if(!e.startsWith("---"))return null;let o=e.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);return o?{frontmatter:Dt.parse(o[1]),content:o[2].trim()}:null},M=async(t,e,o="")=>{let s=`---
13
+ ${Dt.stringify(e).trim()}
14
14
  ---
15
15
 
16
16
  ${o}`.trim();await n.write(t,s+`
17
- `);},kt=async(t,e)=>{let o=await n.read(t),r=st(o);if(!r)throw new Error(`No frontmatter found in ${t}`);let s={...r.frontmatter,...e};return await M(t,s,r.content),s},Z=async t=>{if(!await n.fileExists(t))return null;let o=await n.read(t),r=st(o);return r?r.frontmatter:(ro.warn(`No frontmatter found in ${t}`),null)};});var z,nt,Rt,Ct,so,no,u,v=f(()=>{P();L();Dt();j();z=(a=>(a.BACKLOG="backlog",a.IN_PROGRESS="in-progress",a.ONGOING="ongoing",a.DONE="done",a.BLOCKED="blocked",a.TO_DO="to-do",a))(z||{}),nt=Object.values(z),Rt=["backlog","in-progress","ongoing"],Ct=[c.dirs.HOOKS,c.dirs.INPUTS,c.dirs.OUTPUTS,c.dirs.SCRIPTS],so=[c.dirs.TASKS,...Ct],no={getProjectDir(t){return n.joinHome(c.dirs.PROJECTS,t)},getTaskDir(t,e){return n.join(this.getProjectDir(t),c.dirs.TASKS,e)},async findTask(t,e){if(e)return {project:e,task:t};let o=await this.listProjects(),r=[];if(await n.promiseEach(o,async s=>{(await this.listTasks(s)).includes(t)&&r.push(s);}),r.length===0)throw new Error(`Task '${t}' not found. Use --project to specify the project.`);if(r.length>1)throw new Error(`Task '${t}' found in multiple projects: ${r.join(", ")}. Use --project to specify which one.`);return {project:r[0],task:t}},getAgentDir(t){return n.join(S.AIP_HOME,c.dirs.AGENTS,t)},async listProjects(){let t=n.join(S.AIP_HOME,c.dirs.PROJECTS),e=await n.listDir(t);return (await n.promiseMap(e,async r=>{let s=this.getProjectDir(r);return await n.fileExists(s)&&r!==c.dirs.AGENTS?r:null})).filter(r=>r!==null).sort()},async listTasks(t){let e=n.join(this.getProjectDir(t),c.dirs.TASKS);return await n.fileExists(e)?await n.listDir(e):[]},async listAgents(){let t=n.join(S.AIP_HOME,c.dirs.AGENTS);return await n.fileExists(t)?await n.listDir(t):[]},async createProject(t,e,o){let r=this.getProjectDir(t);return await n.ensureDir(r),await Promise.all(so.map(s=>n.ensureDir(n.join(r,s)))),await M(n.join(r,c.files.MAIN),e,o),await n.write(n.join(r,c.files.LOG),""),r},async createTask(t,e,o,r){let s=this.getTaskDir(t,e);return await n.ensureDir(s),await Promise.all(Ct.map(i=>n.ensureDir(n.join(s,i)))),await M(n.join(s,c.files.MAIN),o,r),await n.write(n.join(s,c.files.LOG),""),s},async createAgent(t,e){let o=this.getAgentDir(t);return await n.ensureDir(o),await M(n.join(o,c.files.MAIN),e),o},async getProject(t){let e=n.join(this.getProjectDir(t),c.files.MAIN);return await Z(e)},async getTask(t,e){let o=n.join(this.getTaskDir(t,e),c.files.MAIN);return await Z(o)},async getAgent(t){let e=n.join(this.getAgentDir(t),c.files.MAIN);return await Z(e)},async updateProject(t,e){let o=n.join(this.getProjectDir(t),c.files.MAIN);return await kt(o,e)},async updateBody(t,e){let o=await n.read(t),r=st(o);if(!r)throw new Error(`No frontmatter found in ${t}`);await M(t,r.frontmatter,e);},async updateTask(t,e,o){let r=n.join(this.getTaskDir(t,e),c.files.MAIN);if((await Z(r))?.status==="ongoing")throw new Error("Cannot update ongoing task. Should be done by user or update manually");return await kt(r,o)},async ingestTask(t,e){let o=this.getTaskDir(t,e),r=this.getProjectDir(t),s=[n.join(r,c.files.MAIN),n.join(o,c.files.MAIN),n.join(o,c.files.LOG)];await n.logFiles(...s);},async ingestProject(t){let e=this.getProjectDir(t),o=await this.listTasks(t),r=[n.join(e,c.files.MAIN),n.join(e,c.files.LOG),...o.map(s=>n.join(this.getTaskDir(t,s),c.files.MAIN))];await n.logFiles(...r);},async ingestFiles(t){await n.logFiles(...t);}},u=no;});var Nt,It=f(()=>{k();j();v();Nt=d({options:z$1.object({description:z$1.string().describe("Agent description"),status:z$1.string().default("active").describe("Initial status")}),args:z$1.object({name:z$1.string().describe("Agent name")}),handler:async({name:t,description:e,status:o})=>{let r=n.slugify(t);await u.createAgent(r,{name:t,description:e,status:o,created:new Date().toISOString()}),console.log(`Agent created: ${r}`),console.log(` Path: ${u.getAgentDir(r)}`);}});});var _t,Lt=f(()=>{k();_t=d({options:z$1.object({}),handler:async()=>{let t=process.env.CURRENT_AGENT;t||(console.error("CURRENT_AGENT not set"),process.exit(1)),console.log(t);}});});var Ft,Ut=f(()=>{k();v();Ft=d({options:z$1.object({}),handler:async()=>{let t=await u.listAgents(),e=[];for(let o of t){let r=await u.getAgent(o);r&&e.push({slug:o,description:r.description});}if(e.length===0)return console.log("No agents found");console.log("Agents:");for(let o of e)console.log(`- ${o.slug}: ${o.description||""}`);}});});var Ht,Gt=f(()=>{P();k();L();j();Ht=d({description:"Output agent directory path (for cd)",options:z$1.object({}),args:z$1.object({name:z$1.string().describe("Agent name (directory name)")}),handler:async({name:t})=>{let e=n.join(S.AIP_HOME,c.dirs.AGENTS,t),o=n.join(e,c.files.MAIN);if(!await n.fileExists(o))throw new Error(`Agent not found: ${t}
18
- Expected at: ${o}`);console.log(e);}});});var Kt,Mt=f(()=>{P();k();L();j();Kt=d({description:"Start an agent: read SOUL.md and AGENTS.md content",options:z$1.object({}),args:z$1.object({name:z$1.string().describe("Agent name (directory name)")}),handler:async({name:t})=>{let e=n.join(S.AIP_HOME,c.dirs.AGENTS,t),o=n.join(e,c.files.MAIN),r=n.join(e,"SOUL.md");if(!await n.fileExists(o))throw new Error(`Agent not found: ${t}
19
- Expected at: ${o}`);let i=[r,o];await n.logFiles(...i);}});});var zt,Bt,po,Jt,Wt=f(()=>{k();zt=t=>{let e=t.shape,o=[];for(let[r,s]of Object.entries(e)){let i=s._def,a="unknown",p,m;i.typeName==="ZodString"?a="string":i.typeName==="ZodNumber"?a="number":i.typeName==="ZodBoolean"?a="boolean":i.typeName==="ZodEnum"?a=`enum: ${i.values.join(" | ")}`:i.typeName==="ZodOptional"?a=Bt(i.innerType):i.typeName==="ZodDefault"&&(a=Bt(i.innerType),m=i.defaultValue()),i.description&&(p=i.description);let l=i.typeName!=="ZodOptional"&&i.typeName!=="ZodDefault";o.push({name:r,type:a,required:l,description:p,defaultValue:m});}return o},Bt=t=>{let e=t._def;return e.typeName==="ZodString"?"string":e.typeName==="ZodNumber"?"number":e.typeName==="ZodBoolean"?"boolean":e.typeName==="ZodEnum"?`enum: ${e.values.join(" | ")}`:"unknown"},po=(t,e,o)=>{let r=zt(o.options),s=o.args?zt(o.args):[],i=o.description,a=`\`${t} ${e}\``;if(i&&(a+=`: ${i}`),a+=`
20
- `,r.length>0||s.length>0){let m=[];for(let l of s){let g=l.required?`<${l.name}>`:`[${l.name}]`,y=l.description||"";l.defaultValue!==void 0&&(y+=y?` (default: ${l.defaultValue})`:`(default: ${l.defaultValue})`),m.push(`\xB7 ${g}${y?": "+y:""}`);}for(let l of r){let g=l.description||"";l.defaultValue!==void 0&&(g+=g?` (default: ${l.defaultValue})`:`(default: ${l.defaultValue})`),m.push(`\xB7 --${l.name}${g?": "+g:""}`);}a+=m.join(`
17
+ `);},kt=async(t,e)=>{let o=await n.read(t),r=st(o);if(!r)throw new Error(`No frontmatter found in ${t}`);let s={...r.frontmatter,...e};return await M(t,s,r.content),s},Z=async t=>{if(!await n.fileExists(t))return null;let o=await n.read(t),r=st(o);return r?r.frontmatter:(io.warn(`No frontmatter found in ${t}`),null)};});var z,nt,Ct,Nt,ao,co,u,v=f(()=>{P();_();Rt();j();z=(a=>(a.BACKLOG="backlog",a.IN_PROGRESS="in-progress",a.ONGOING="ongoing",a.DONE="done",a.BLOCKED="blocked",a.TO_DO="to-do",a))(z||{}),nt=Object.values(z),Ct=["backlog","in-progress","ongoing"],Nt=[c.dirs.HOOKS,c.dirs.INPUTS,c.dirs.OUTPUTS,c.dirs.SCRIPTS],ao=[c.dirs.TASKS,...Nt],co={getProjectDir(t){return n.joinHome(c.dirs.PROJECTS,t)},getTaskDir(t,e){return n.join(this.getProjectDir(t),c.dirs.TASKS,e)},async findTask(t,e){if(e)return {project:e,task:t};let o=await this.listProjects(),r=[];if(await n.promiseEach(o,async s=>{(await this.listTasks(s)).includes(t)&&r.push(s);}),r.length===0)throw new Error(`Task '${t}' not found. Use --project to specify the project.`);if(r.length>1)throw new Error(`Task '${t}' found in multiple projects: ${r.join(", ")}. Use --project to specify which one.`);return {project:r[0],task:t}},getAgentDir(t){return n.join(S.AIP_HOME,c.dirs.AGENTS,t)},async listProjects(){let t=n.join(S.AIP_HOME,c.dirs.PROJECTS),e=await n.listDir(t);return (await n.promiseMap(e,async r=>{let s=this.getProjectDir(r);return await n.fileExists(s)&&r!==c.dirs.AGENTS?r:null})).filter(r=>r!==null).sort()},async listTasks(t){let e=n.join(this.getProjectDir(t),c.dirs.TASKS);return await n.fileExists(e)?await n.listDir(e):[]},async listAgents(){let t=n.join(S.AIP_HOME,c.dirs.AGENTS);return await n.fileExists(t)?await n.listDir(t):[]},async createProject(t,e,o){let r=this.getProjectDir(t);return await n.ensureDir(r),await Promise.all(ao.map(s=>n.ensureDir(n.join(r,s)))),await M(n.join(r,c.files.MAIN),e,o),await n.write(n.join(r,c.files.LOG),""),r},async createTask(t,e,o,r){let s=this.getTaskDir(t,e);return await n.ensureDir(s),await Promise.all(Nt.map(i=>n.ensureDir(n.join(s,i)))),await M(n.join(s,c.files.MAIN),o,r),await n.write(n.join(s,c.files.LOG),""),s},async createAgent(t,e){let o=this.getAgentDir(t);return await n.ensureDir(o),await M(n.join(o,c.files.MAIN),e),o},async getProject(t){let e=n.join(this.getProjectDir(t),c.files.MAIN);return await Z(e)},async getTask(t,e){let o=n.join(this.getTaskDir(t,e),c.files.MAIN);return await Z(o)},async getAgent(t){let e=n.join(this.getAgentDir(t),c.files.MAIN);return await Z(e)},async updateProject(t,e){let o=n.join(this.getProjectDir(t),c.files.MAIN);return await kt(o,e)},async updateBody(t,e){let o=await n.read(t),r=st(o);if(!r)throw new Error(`No frontmatter found in ${t}`);await M(t,r.frontmatter,e);},async updateTask(t,e,o){let r=n.join(this.getTaskDir(t,e),c.files.MAIN);if((await Z(r))?.status==="ongoing")throw new Error("Cannot update ongoing task. Should be done by user or update manually");return await kt(r,o)},async ingestTask(t,e){let o=this.getTaskDir(t,e),r=this.getProjectDir(t),s=[n.join(r,c.files.MAIN),n.join(o,c.files.MAIN),n.join(o,c.files.LOG)];await n.logFiles(...s);},async ingestProject(t){let e=this.getProjectDir(t),o=await this.listTasks(t),r=[n.join(e,c.files.MAIN),n.join(e,c.files.LOG),...o.map(s=>n.join(this.getTaskDir(t,s),c.files.MAIN))];await n.logFiles(...r);},async ingestFiles(t){await n.logFiles(...t);}},u=co;});var It,Lt=f(()=>{k();j();v();It=d({options:z$1.object({description:z$1.string().describe("Agent description"),status:z$1.string().default("active").describe("Initial status")}),args:z$1.object({name:z$1.string().describe("Agent name")}),handler:async({name:t,description:e,status:o})=>{let r=n.slugify(t);await u.createAgent(r,{name:t,description:e,status:o,created:new Date().toISOString()}),console.log(`Agent created: ${r}`),console.log(` Path: ${u.getAgentDir(r)}`);}});});var _t,Ft=f(()=>{k();_t=d({options:z$1.object({}),handler:async()=>{let t=process.env.CURRENT_AGENT;t||(console.error("CURRENT_AGENT not set"),process.exit(1)),console.log(t);}});});var Ut,Ht=f(()=>{k();v();Ut=d({options:z$1.object({}),handler:async()=>{let t=await u.listAgents(),e=[];for(let o of t){let r=await u.getAgent(o);r&&e.push({slug:o,description:r.description});}if(e.length===0)return console.log("No agents found");console.log("Agents:");for(let o of e)console.log(`- ${o.slug}: ${o.description||""}`);}});});var Gt,Kt=f(()=>{P();k();_();j();Gt=d({description:"Output agent directory path (for cd)",options:z$1.object({}),args:z$1.object({name:z$1.string().describe("Agent name (directory name)")}),handler:async({name:t})=>{let e=n.join(S.AIP_HOME,c.dirs.AGENTS,t),o=n.join(e,c.files.MAIN);if(!await n.fileExists(o))throw new Error(`Agent not found: ${t}
18
+ Expected at: ${o}`);console.log(e);}});});var Mt,zt=f(()=>{P();k();_();j();Mt=d({description:"Start an agent: read SOUL.md and AGENTS.md content",options:z$1.object({}),args:z$1.object({name:z$1.string().describe("Agent name (directory name)")}),handler:async({name:t})=>{let e=n.join(S.AIP_HOME,c.dirs.AGENTS,t),o=n.join(e,c.files.MAIN),r=n.join(e,"SOUL.md");if(!await n.fileExists(o))throw new Error(`Agent not found: ${t}
19
+ Expected at: ${o}`);let i=[r,o];await n.logFiles(...i);}});});var Bt,Jt,uo,Wt,Vt=f(()=>{k();Bt=t=>{let e=t.shape,o=[];for(let[r,s]of Object.entries(e)){let i=s._def,a="unknown",l,m;i.typeName==="ZodString"?a="string":i.typeName==="ZodNumber"?a="number":i.typeName==="ZodBoolean"?a="boolean":i.typeName==="ZodEnum"?a=`enum: ${i.values.join(" | ")}`:i.typeName==="ZodOptional"?a=Jt(i.innerType):i.typeName==="ZodDefault"&&(a=Jt(i.innerType),m=i.defaultValue()),i.description&&(l=i.description);let p=i.typeName!=="ZodOptional"&&i.typeName!=="ZodDefault";o.push({name:r,type:a,required:p,description:l,defaultValue:m});}return o},Jt=t=>{let e=t._def;return e.typeName==="ZodString"?"string":e.typeName==="ZodNumber"?"number":e.typeName==="ZodBoolean"?"boolean":e.typeName==="ZodEnum"?`enum: ${e.values.join(" | ")}`:"unknown"},uo=(t,e,o)=>{let r=Bt(o.options),s=o.args?Bt(o.args):[],i=o.description,a=`\`${t} ${e}\``;if(i&&(a+=`: ${i}`),a+=`
20
+ `,r.length>0||s.length>0){let m=[];for(let p of s){let g=p.required?`<${p.name}>`:`[${p.name}]`,y=p.description||"";p.defaultValue!==void 0&&(y+=y?` (default: ${p.defaultValue})`:`(default: ${p.defaultValue})`),m.push(`\xB7 ${g}${y?": "+y:""}`);}for(let p of r){let g=p.description||"";p.defaultValue!==void 0&&(g+=g?` (default: ${p.defaultValue})`:`(default: ${p.defaultValue})`),m.push(`\xB7 --${p.name}${g?": "+g:""}`);}a+=m.join(`
21
21
  `)+`
22
22
  `;}return a+=`
23
- `,a},Jt=d({description:"Print generated CLI reference from command schemas",options:z$1.object({}),handler:async()=>{let{default:t}=await Promise.resolve().then(()=>(Y(),jt)),e="Prepend `aip` to each command\n\n",o=Object.keys(t).sort();for(let r of o){let s=t[r],i=Object.keys(s).sort();for(let a of i){let p=s[a];e+=po(r,a,p);}}console.log(e);}});});var mo,Vt,Zt=f(()=>{k();mo=`# AIP Hooks
23
+ `,a},Wt=d({description:"Print generated CLI reference from command schemas",options:z$1.object({}),handler:async()=>{let{default:t}=await Promise.resolve().then(()=>(Y(),jt)),e="Prepend `aip` to each command\n\n",o=Object.keys(t).sort();for(let r of o){let s=t[r],i=Object.keys(s).sort();for(let a of i){let l=s[a];e+=uo(r,a,l);}}console.log(e);}});});var go,Zt,qt=f(()=>{k();go=`# AIP Hooks
24
24
 
25
25
  Automated scripts that run before/after project/task actions.
26
26
 
@@ -200,7 +200,7 @@ DEBUG=1 aip task update --status done
200
200
  ---
201
201
 
202
202
  *Hooks automate workflow enforcement. Pre-hooks guard quality, post-hooks handle cleanup.*
203
- `,Vt=d({description:"Hook types, env vars, and patterns",options:z$1.object({}),handler:async()=>{console.log(mo);}});});var A,qt,fo,Yt,Qt=f(()=>{J();P();k();A=Object.keys(x.bin)[0],{LOG:qt}=c.files,fo=`# Quick Start
203
+ `,Zt=d({description:"Hook types, env vars, and patterns",options:z$1.object({}),handler:async()=>{console.log(go);}});});var A,Yt,ho,Qt,Xt=f(()=>{J();P();k();A=Object.keys(x.bin)[0],{LOG:Yt}=c.files,ho=`# Quick Start
204
204
 
205
205
  ## New Task/Project
206
206
 
@@ -261,10 +261,10 @@ ${A} task current
261
261
 
262
262
  $AIP_HOME/projects/slug/
263
263
  \u251C\u2500\u2500 main.md # Definition + body
264
- \u251C\u2500\u2500 ${qt} # Log (auto-appended, has key task updates too)
264
+ \u251C\u2500\u2500 ${Yt} # Log (auto-appended, has key task updates too)
265
265
  \u2514\u2500\u2500 tasks/task/
266
266
  \u251C\u2500\u2500 main.md # Task definition + body
267
- \u2514\u2500\u2500 ${qt} # Updates
267
+ \u2514\u2500\u2500 ${Yt} # Updates
268
268
 
269
269
  **Log format:** TSV with columns: date, time, entityType, slug, action, text
270
270
  **Example:** \`2026-03-30<TAB>14:30:00<TAB>task<TAB>api-integration<TAB>log<TAB>API integration complete\`
@@ -281,7 +281,7 @@ ${A} <noun> --help
281
281
  # All parameters and --options for a command
282
282
  ${A} <noun> <verb> --help
283
283
  \`\`\`
284
- `,Yt=d({description:"Quick start guide for new users",options:z$1.object({}),handler:async()=>{console.log(fo);}});});var go,ko,ho,yo,jo,To,bo,te,Tt,Q,bt,ee,oe=f(()=>{J();P();k();v();go=Object.values(z).join("|"),{PROJECTS:ko,TASKS:ho,HOOKS:yo,INPUTS:jo,OUTPUTS:To,SCRIPTS:bo}=c.dirs,{MAIN:te,LOG:Tt}=c.files,Q=Object.keys(x.bin)[0],bt=`# AIP - Project Management Skill
284
+ `,Qt=d({description:"Quick start guide for new users",options:z$1.object({}),handler:async()=>{console.log(ho);}});});var yo,jo,To,bo,wo,Po,So,ee,Tt,Q,bt,oe,re=f(()=>{J();P();k();v();yo=Object.values(z).join("|"),{PROJECTS:jo,TASKS:To,HOOKS:bo,INPUTS:wo,OUTPUTS:Po,SCRIPTS:So}=c.dirs,{MAIN:ee,LOG:Tt}=c.files,Q=Object.keys(x.bin)[0],bt=`# AIP - Project Management Skill
285
285
 
286
286
  Automated project and task creation with proper structure, front-matter, and file organization.
287
287
 
@@ -299,16 +299,16 @@ Streamline creation of new projects and tasks with the correct directory structu
299
299
  ## File Structure Overview
300
300
 
301
301
  \`\`\`
302
- $AIP_HOME/${ko}/{project-slug}/
303
- \u251C\u2500\u2500 ${te} # Goals + body (YAML frontmatter + markdown content)
302
+ $AIP_HOME/${jo}/{project-slug}/
303
+ \u251C\u2500\u2500 ${ee} # Goals + body (YAML frontmatter + markdown content)
304
304
  \u251C\u2500\u2500 ${Tt} # Chronological log (TSV: date, time, entityType, slug, action, text)
305
- \u251C\u2500\u2500 ${yo}/ # pre|post-{create,start,update,complete}.*
306
- \u251C\u2500\u2500 ${jo}/ # Intermediate/raw data (e.g. API responses, downloads)
307
- \u251C\u2500\u2500 ${To}/ # Deliverables (e.g. reports, leads, etc.)
308
- \u251C\u2500\u2500 ${bo}/ # Automation
309
- \u2514\u2500\u2500 ${ho}/
305
+ \u251C\u2500\u2500 ${bo}/ # pre|post-{create,start,update,complete}.*
306
+ \u251C\u2500\u2500 ${wo}/ # Intermediate/raw data (e.g. API responses, downloads)
307
+ \u251C\u2500\u2500 ${Po}/ # Deliverables (e.g. reports, leads, etc.)
308
+ \u251C\u2500\u2500 ${So}/ # Automation
309
+ \u2514\u2500\u2500 ${To}/
310
310
  \u2514\u2500\u2500 {task-slug}/
311
- \u251C\u2500\u2500 ${te} # Task definition + body
311
+ \u251C\u2500\u2500 ${ee} # Task definition + body
312
312
  \u251C\u2500\u2500 ${Tt} # Activity log
313
313
  \u2514\u2500\u2500 ... (same structure)
314
314
  \`\`\`
@@ -320,7 +320,7 @@ $AIP_HOME/${ko}/{project-slug}/
320
320
  name: Clear Title
321
321
  description: One-line summary
322
322
  assignee: agent-name
323
- status: ${go}
323
+ status: ${yo}
324
324
  created: YYYY-MM-DD
325
325
  ---
326
326
  \`\`\`
@@ -337,7 +337,7 @@ Markdown content after frontmatter. See \`aip help quickstart\` for examples of
337
337
  ## For Agents
338
338
 
339
339
  Typical workflow: read \`main.md\` for context, check \`${Tt}\` for history, work, and log progress with \`aip log append\`.
340
- `,ee=d({description:"Project management skill for creating and managing projects/tasks",options:z$1.object({mode:z$1.enum(["md","claude","hermes"]).default("md").describe("Output format: md (no header), claude (name+description), hermes (full frontmatter)")}),handler:async t=>{let e=Object.keys(x.bin)[0];if(t.mode==="md"){console.log(bt);return}if(t.mode==="claude"){console.log(`---
340
+ `,oe=d({description:"Project management skill for creating and managing projects/tasks",options:z$1.object({mode:z$1.enum(["md","claude","hermes"]).default("md").describe("Output format: md (no header), claude (name+description), hermes (full frontmatter)")}),handler:async t=>{let e=Object.keys(x.bin)[0];if(t.mode==="md"){console.log(bt);return}if(t.mode==="claude"){console.log(`---
341
341
  name: ${e}
342
342
  description: ${x.description}
343
343
  ---`),console.log(),console.log(bt);return}if(t.mode==="hermes"){console.log(`---
@@ -349,9 +349,9 @@ license: ${x.license}
349
349
  metadata:
350
350
  hermes:
351
351
  tags: [${x.keywords.join(", ")}]
352
- ---`),console.log(),console.log(bt);return}}});});var re,se=f(()=>{J();k();j();re=d({description:"Print compact CLI usage (all nouns, or one noun if name is given)",options:z$1.object({}),args:z$1.object({name:z$1.string().optional().describe("Noun (e.g. task) to list verbs for")}),handler:async({name:t})=>{let{default:e}=await Promise.resolve().then(()=>(Y(),jt)),o=`${x.name} ${x.version} -`,r=n.dumpCommandMapLines(e,t);if(!t)console.log(o,"Usage: aip <noun> <verb> [options]"),console.log(r.map(s=>`-> ${s}`).join(`
353
- `)),console.log(),console.log("Run `aip help quickstart` for a quick start guide"),console.log("Run `aip help skill` for a broader overview");else {let s=r[0]??`${t} {?}`;console.log(o,`Usage: aip ${s} [options]`);}}});});var Pt,Po,h,D=f(()=>{P();j();Pt=ut.realpathSync(n.joinHome(c.dirs.PROJECTS)),Po={getProjectFromPwd(t=process.cwd()){let e=it.relative(Pt,t);if(!e||e.startsWith(".."))return null;let o=e.split(it.sep).filter(Boolean);return o.length===0?null:o[0]},getTaskFromPwd(t=process.cwd()){let e=it.relative(Pt,t);if(!e||e.startsWith(".."))return null;let o=e.split(it.sep).filter(Boolean);return o.length<3||o[1]!==c.dirs.TASKS?null:o[2]},getCurrentContext(t=process.cwd()){return {project:this.getProjectFromPwd(t),task:this.getTaskFromPwd(t)}},requireProject(t=process.cwd()){let e=this.getProjectFromPwd(t);if(!e)throw new Error(`Not in a project directory. PWD: ${t}, projects: ${Pt}`);return e},requireTask(t=process.cwd()){let e=this.getCurrentContext(t);if(!e.project||!e.task)throw new Error(`Not in a task directory. PWD: ${t}`);return {project:e.project,task:e.task}},exportContext(t=process.cwd()){let e=this.getCurrentContext(t),o=[];return e.project&&o.push(`export CURRENT_PROJECT="${e.project}"`),e.task&&o.push(`export CURRENT_TASK="${e.task}"`),process.env.CURRENT_AGENT&&o.push(`export CURRENT_AGENT="${process.env.CURRENT_AGENT}"`),o.join(`
354
- `)},getTargetDir(t,e=process.cwd()){let o=this.getCurrentContext(e);if(t==="project"){let r=this.getProjectFromPwd(e);if(!r)throw new Error("Not in a project directory. Use --project flag or cd into a project.");let s=n.joinHome(c.dirs.PROJECTS,r);return {targetDir:s,projectDir:s,entityType:"project"}}if(t==="task"){if(!o.project||!o.task)throw new Error("Not in a task directory. Use --project and --task flags or cd into a task.");let r=n.joinHome(c.dirs.PROJECTS,o.project);return {targetDir:n.join(r,c.dirs.TASKS,o.task),projectDir:r,entityType:"task"}}if(o.task&&o.project){let r=n.joinHome(c.dirs.PROJECTS,o.project);return {targetDir:n.join(r,c.dirs.TASKS,o.task),projectDir:r,entityType:"task"}}if(o.project){let r=n.joinHome(c.dirs.PROJECTS,o.project);return {targetDir:r,projectDir:r,entityType:"project"}}throw new Error("Not in a project or task directory. Specify --target flag.")}},h=Po;});var ne,ie=f(()=>{k();j();D();P();ne=d({options:z$1.object({lang:z$1.enum(c.languages).default("ts").describe("Language"),target:z$1.enum(c.targets).default("project").describe("Target level")}),args:z$1.object({type:z$1.enum(c.hookTypes).describe("Hook type (e.g., pre-create, post-complete)")}),handler:async({type:t,lang:e,target:o})=>{let r=e,s=`.${r}`,{targetDir:i,entityType:a}=h.getTargetDir(o),p=n.join(i,c.dirs.HOOKS);await n.ensureDir(p);let m=n.join(p,`${t}${s}`);if(await n.fileExists(m))throw new Error(`Hook already exists: ${m}`);let g;if(r==="ts")g=`#!/usr/bin/env tsx
352
+ ---`),console.log(),console.log(bt);return}}});});var se,ne=f(()=>{J();k();j();se=d({description:"Print compact CLI usage (all nouns, or one noun if name is given)",options:z$1.object({}),args:z$1.object({name:z$1.string().optional().describe("Noun (e.g. task) to list verbs for")}),handler:async({name:t})=>{let{default:e}=await Promise.resolve().then(()=>(Y(),jt)),o=`${x.name} ${x.version} -`,r=n.dumpCommandMapLines(e,t);if(!t)console.log(o,"Usage: aip <noun> <verb> [options]"),console.log(r.map(s=>`-> ${s}`).join(`
353
+ `)),console.log(),console.log("Run `aip help quickstart` for a quick start guide"),console.log("Run `aip help skill` for a broader overview");else {let s=r[0]??`${t} {?}`;console.log(o,`Usage: aip ${s} [options]`);}}});});var Pt,vo,h,D=f(()=>{P();j();Pt=ut.realpathSync(n.joinHome(c.dirs.PROJECTS)),vo={getProjectFromPwd(t=process.cwd()){let e=it.relative(Pt,t);if(!e||e.startsWith(".."))return null;let o=e.split(it.sep).filter(Boolean);return o.length===0?null:o[0]},getTaskFromPwd(t=process.cwd()){let e=it.relative(Pt,t);if(!e||e.startsWith(".."))return null;let o=e.split(it.sep).filter(Boolean);return o.length<3||o[1]!==c.dirs.TASKS?null:o[2]},getCurrentContext(t=process.cwd()){return {project:this.getProjectFromPwd(t),task:this.getTaskFromPwd(t)}},requireProject(t=process.cwd()){let e=this.getProjectFromPwd(t);if(!e)throw new Error(`Not in a project directory. PWD: ${t}, projects: ${Pt}`);return e},requireTask(t=process.cwd()){let e=this.getCurrentContext(t);if(!e.project||!e.task)throw new Error(`Not in a task directory. PWD: ${t}`);return {project:e.project,task:e.task}},exportContext(t=process.cwd()){let e=this.getCurrentContext(t),o=[];return e.project&&o.push(`export CURRENT_PROJECT="${e.project}"`),e.task&&o.push(`export CURRENT_TASK="${e.task}"`),process.env.CURRENT_AGENT&&o.push(`export CURRENT_AGENT="${process.env.CURRENT_AGENT}"`),o.join(`
354
+ `)},getTargetDir(t,e=process.cwd()){let o=this.getCurrentContext(e);if(t==="project"){let r=this.getProjectFromPwd(e);if(!r)throw new Error("Not in a project directory. Use --project flag or cd into a project.");let s=n.joinHome(c.dirs.PROJECTS,r);return {targetDir:s,projectDir:s,entityType:"project"}}if(t==="task"){if(!o.project||!o.task)throw new Error("Not in a task directory. Use --project and --task flags or cd into a task.");let r=n.joinHome(c.dirs.PROJECTS,o.project);return {targetDir:n.join(r,c.dirs.TASKS,o.task),projectDir:r,entityType:"task"}}if(o.task&&o.project){let r=n.joinHome(c.dirs.PROJECTS,o.project);return {targetDir:n.join(r,c.dirs.TASKS,o.task),projectDir:r,entityType:"task"}}if(o.project){let r=n.joinHome(c.dirs.PROJECTS,o.project);return {targetDir:r,projectDir:r,entityType:"project"}}throw new Error("Not in a project or task directory. Specify --target flag.")}},h=vo;});var ie,ae=f(()=>{k();j();D();P();ie=d({options:z$1.object({lang:z$1.enum(c.languages).default("ts").describe("Language"),target:z$1.enum(c.targets).default("project").describe("Target level")}),args:z$1.object({type:z$1.enum(c.hookTypes).describe("Hook type (e.g., pre-create, post-complete)")}),handler:async({type:t,lang:e,target:o})=>{let r=e,s=`.${r}`,{targetDir:i,entityType:a}=h.getTargetDir(o),l=n.join(i,c.dirs.HOOKS);await n.ensureDir(l);let m=n.join(l,`${t}${s}`);if(await n.fileExists(m))throw new Error(`Hook already exists: ${m}`);let g;if(r==="ts")g=`#!/usr/bin/env tsx
355
355
  /** ${t} hook for ${a} */
356
356
 
357
357
  import { env } from 'node:process'
@@ -398,8 +398,8 @@ if os.environ.get('TASK_SLUG'):
398
398
 
399
399
  # Exit with non-zero to prevent action (for pre-hooks)
400
400
  # sys.exit(1)
401
- `;else throw new Error(`Unsupported language: ${r}`);await n.write(m,g);let{chmod:y}=await import('fs/promises');await y(m,493),console.log(`Hook created: ${m}`);}});});var vo,$,B=f(()=>{P();j();vo={async findHooks(t,e){let o=n.join(t,c.dirs.HOOKS);if(!await n.fileExists(o))return [];let s=await n.listDir(o),i=`${e}.`;return s.filter(a=>a.startsWith(i)).map(a=>n.join(o,a))},async executeHook(t,e,o){if(!await n.fileExists(t))return true;let s=e.project?n.joinHome(c.dirs.PROJECTS,e.project):o,i=e.task?n.join(s,c.dirs.TASKS,e.task):"",a={...process.env,HOOK_TYPE:e.action,ENTITY_TYPE:e.entityType,TARGET_DIR:o,PROJECT_DIR:s,...e.project?{PROJECT_SLUG:e.project}:{},...e.task?{TASK_SLUG:e.task,TASK_DIR:i}:{}};return new Promise(p=>{let m=spawn(t,[],{stdio:"inherit",env:a,cwd:o,shell:false});m.on("close",(l,g)=>{l===0?p(true):(console.error(`Hook ${it.basename(t)} failed (code=${l??g})`),p(false));}),m.on("error",l=>{console.error(`Failed to execute hook ${t}: ${l.message}`),p(false);});})},async runHooks(t,e,o){let r=await this.findHooks(t,e),s=e.startsWith("pre-");for(let i of r)if(!await this.executeHook(i,o,t)&&s)return false;return true},async runHooksForContext(t,e,o,r){return !(!await this.runHooks(t,o,r)||e&&!await this.runHooks(e,o,r))}},$=vo;});var ae,ce=f(()=>{k();B();D();P();ae=d({options:z$1.object({target:z$1.enum(c.targets).optional().describe("Target level")}),args:z$1.object({type:z$1.enum(c.hookTypes).describe("Hook type to run")}),handler:async({type:t,target:e})=>{let{targetDir:o,entityType:r}=h.getTargetDir(e),s={action:t,entityType:r,project:h.getProjectFromPwd()||void 0,task:h.getTaskFromPwd()||void 0};await $.runHooks(o,t,s)||(console.error(`Hook ${t} failed`),process.exit(1)),console.log(`Hook ${t} completed successfully`);}});});var Ao,w,F=f(()=>{P();D();j();Ao={formatEntry(t,e,o,r){let s=new Date,i=s.getFullYear(),a=String(s.getMonth()+1).padStart(2,"0"),p=String(s.getDate()).padStart(2,"0"),m=s.toLocaleTimeString("en-US",{hour12:false,hour:"2-digit",minute:"2-digit",second:"2-digit"});return `${`${i}-${a}-${p}`} ${m} ${t} ${e} ${o} ${r}
402
- `},async append(t,e,o,r,s){let i=n.join(t,c.files.LOG),a=this.formatEntry(e,o,r,s);await n.append(i,a);},async read(t){let e=n.join(t,c.files.LOG);return await n.fileExists(e)?await n.read(e):""},async task(t,e,o){let r=h.getCurrentContext();if(!r.project||!r.task)throw new Error("Not in a task directory");let s=n.joinHome(c.dirs.PROJECTS,r.project,c.dirs.TASKS,r.task);await this.append(s,"task",t,"log",o?`${o}: ${e}`:e);},async project(t,e,o){let r=h.getProjectFromPwd();if(!r)throw new Error("Not in a project directory");let s=n.joinHome(c.dirs.PROJECTS,r);await this.append(s,"project",t,"log",o?`${o}: ${e}`:e);}},w=Ao;});var pe,le=f(()=>{P();D();k();j();F();pe=d({description:"Append a custom entry to log.tsv",options:z$1.object({project:z$1.string().optional().describe("Project slug (uses current project from $PWD if not provided)"),task:z$1.string().optional().describe("Task slug (uses current task from $PWD if not provided)")}),args:z$1.object({text:z$1.string().describe("Text to append")}),handler:async({project:t,task:e,text:o})=>{let r=h.getCurrentContext(),s=t||r.project;if(!s)throw new Error("No project specified. Use --project or run from a project/task directory");let i=n.joinHome(c.dirs.PROJECTS,s);if(e||r.task){let a=e||r.task;if(!a)throw new Error("No task specified");let p=n.join(i,c.dirs.TASKS,a);await w.append(p,"task",a,"log",o),console.log(`Appended to task ${a} log.tsv`);}else await w.append(i,"project",s,"log",o),console.log(`Appended to project ${s} log.tsv`);}});});var de,me=f(()=>{P();D();k();j();F();de=d({description:"Read log.tsv history",options:z$1.object({project:z$1.string().optional().describe("Project slug (uses current project from $PWD if not provided)"),task:z$1.string().optional().describe("Task slug (uses current task from $PWD if not provided)")}),args:z$1.object({}),handler:async({project:t,task:e})=>{let o=h.getCurrentContext(),r=t||o.project;if(!r)throw new Error("No project specified. Use --project or run from a project/task directory");let s=n.joinHome(c.dirs.PROJECTS,r);if(e||o.task){let i=e||o.task;if(!i)throw new Error("No task specified");let a=n.join(s,c.dirs.TASKS,i),p=await w.read(a);console.log(p||`No log.tsv found for task ${i}`);}else {let i=await w.read(s);console.log(i||`No log.tsv found for project ${r}`);}}});});var ue,fe=f(()=>{k();j();F();v();ue=d({description:"Create a new project with name, description, optional status, assignee and body",options:z$1.object({description:z$1.string().describe("Project description"),status:z$1.string().default("active").describe("Initial status"),assignee:z$1.string().optional().describe("Assignee agent slug"),body:z$1.string().optional().describe("Initial body/content (markdown)")}),args:z$1.object({name:z$1.string().describe("Project name")}),handler:async({name:t,description:e,status:o,assignee:r,body:s})=>{let i=n.slugify(t),a=u.getProjectDir(i);await u.createProject(i,{name:t,description:e,status:o,assignee:r,created:new Date().toISOString()},s),await w.append(a,"project",i,"created",`${t} > status is ${o}`),console.log(`Project created: ${i}. Path: ${a}`);}});});var ge,ke=f(()=>{k();D();ge=d({options:z$1.object({}),handler:async()=>{let t=h.getProjectFromPwd();t||(console.error("Not in a project directory"),process.exit(1)),console.log(t);}});});var ye,je=f(()=>{k();v();ye=d({description:"List all projects, optionally filtered by status",options:z$1.object({status:z$1.string().optional().describe("Filter by status")}),handler:async({status:t})=>{let e=await u.listProjects(),o=[];for(let r of e){let s=await u.getProject(r);s&&(t&&s.status!==t||o.push({slug:r,status:s.status,assignee:s.assignee}));}if(o.length===0)return console.log("No projects found");console.log("Projects:");for(let r of o)console.log(`- ${r.slug}: ${r.status||""} ${r.assignee||""}`);}});});var Te,be=f(()=>{k();v();Te=d({description:"Output project directory path (for cd)",options:z$1.object({}),args:z$1.object({name:z$1.string().describe("Project name (slug)")}),handler:async({name:t})=>{let e=u.getProjectDir(t);console.log(e);}});});var we,Pe=f(()=>{P();D();k();B();j();v();F();we=d({description:"Update project properties: name, description, status, assignee, or replace body",options:z$1.object({name:z$1.string().optional().describe("New name"),description:z$1.string().optional().describe("New description"),status:z$1.string().optional().describe("New status"),assignee:z$1.string().optional().describe("New assignee"),body:z$1.string().optional().describe("Replace entire body/content (markdown)")}),args:z$1.object({project:z$1.string().optional().describe("Project slug (defaults to current project from $PWD)")}),handler:async({project:t,name:e,description:o,status:r,assignee:s,body:i})=>{let a=t||h.getProjectFromPwd();if(!a)throw new Error("No project specified and not in a project directory");let p=u.getProjectDir(a),m=n.join(p,c.files.MAIN);if(!await $.runHooks(p,"pre-update",{action:"pre-update",entityType:"project"}))throw new Error("Pre-update hook failed, aborting update");let g={};if(e&&(g.name=e),o&&(g.description=o),r&&(g.status=r),s&&(g.assignee=s),Object.keys(g).length===0&&!i){console.log("No updates provided");return}if(Object.keys(g).length>0){await u.updateProject(a,g);let y=Object.entries(g).map(([O,E])=>`${O}=${E}`).join(", ");await w.append(p,"project",a,"updated",y);}i!==void 0&&(await u.updateBody(m,i),await w.append(p,"project",a,"updated",`body replaced (${i.length} chars)`)),await $.runHooks(p,"post-update",{action:"post-update",entityType:"project"}),console.log(`Project ${a} updated`);}});});var Se,xe=f(()=>{P();k();L();j();Se=d({description:"Read a skill's SKILL.md file into the console for agent context",options:z$1.object({}),args:z$1.object({name:z$1.string().describe("Skill name (directory name)")}),handler:async({name:t})=>{let e=n.join(S.AIP_HOME,c.dirs.SKILLS,t),o=n.join(e,c.files.SKILL);if(!await n.fileExists(o))throw new Error(`Skill not found: ${t}
403
- Expected at: ${o}`);await n.logFiles(o);}});});var ve,Ae=f(()=>{k();B();j();v();F();ve=d({description:"Create a new task with assignee, initial status and optional body",options:z$1.object({description:z$1.string().optional().describe("Task description"),assignee:z$1.string().optional().describe("Assignee agent slug"),status:z$1.string().default("backlog").describe("Initial status"),body:z$1.string().optional().describe("Initial body/content (markdown)")}),args:z$1.object({project:z$1.string().describe("Project slug"),name:z$1.string().describe("Task name")}),handler:async({project:t,name:e,description:o,assignee:r,status:s,body:i})=>{let a=n.slugify(e),p=u.getProjectDir(t),m=u.getTaskDir(t,a);if(!await $.runHooksForContext(p,m,"pre-create",{action:"pre-create",entityType:"task",project:t}))throw new Error("Pre-create hook failed, aborting task creation");await u.createTask(t,a,{name:e,description:o,assignee:r,status:s,created:new Date().toISOString()},i),await w.append(m,"task",a,"created",e),await w.append(p,"task",a,"created",`${a} > status is ${s}`),await $.runHooksForContext(p,m,"post-create",{action:"post-create",entityType:"task",project:t}),console.log(`Task created: ${a}`),console.log(` Project: ${t}`),console.log(` Path: ${m}`);}});});var $e,Oe=f(()=>{k();D();$e=d({description:"Get the current task slug from PWD",options:z$1.object({}),handler:async()=>{let t=h.getTaskFromPwd();t||(console.error("Not in a task directory"),process.exit(1)),console.log(t);}});});var Ee,De=f(()=>{D();k();v();Ee=d({description:"Output full task context (main.md, log.tsv) for ingestion by agents",options:z$1.object({project:z$1.string().optional().describe("Project slug (searches all projects if not provided)")}),args:z$1.object({task:z$1.string().optional().describe("Task slug (default: from $PWD)")}),handler:async({project:t,task:e})=>{let o=h.getCurrentContext(),r=e??o.task;if(!r)throw new Error("No task specified or inferred. cd into task dir before: `cd $(aip task path my-task) && aip task ingest`");let{project:s}=await u.findTask(r,t);await u.ingestTask(s,r);}});});var Re,Ce=f(()=>{k();j();v();Re=d({description:"List tasks, optionally filtered by project, status, assignee, or search query",options:z$1.object({project:z$1.string().optional().describe("Project slug (searches all projects if not provided)"),statuses:z$1.array(z$1.string()).default([]).describe("Filter by statuses (multiple allowed)"),assignee:z$1.string().optional().describe("Filter by assignee"),all:z$1.boolean().default(false).describe("Include all tasks (including done/blocked)"),search:z$1.string().optional().describe("Search query (matches task slug, case-insensitive, multi-part AND, any order)")}),handler:async({project:t,statuses:e,assignee:o,all:r,search:s})=>{if(e&&e.length>0){for(let l of e)if(!nt.includes(l))throw new Error(`Invalid status: ${l}. Valid values: ${nt.join(", ")}`)}let i;e&&e.length>0?i=e:r?i=nt:i=Rt;let a=t?[t]:await u.listProjects(),p={};await n.promiseEach(a,async l=>{let g=await u.listTasks(l),y=[];await n.promiseEach(g,async O=>{let E=await u.getTask(l,O);E&&(i.length>0&&!i.includes(E.status||"")||o&&E.assignee!==o||n.matchesSearch(O,s)&&y.push({slug:O,description:E.description}));}),y.length>0&&(p[l]=y.sort((O,E)=>O.slug.localeCompare(E.slug)));});let m=Object.keys(p).sort();if(m.length===0)return console.log("No tasks found");for(let l of m){console.log(`${l}:`);for(let g of p[l])console.log(`- ${g.slug}: ${g.description||""}`);}}});});var Ne,Ie=f(()=>{k();v();Ne=d({description:"Output task directory path (for cd)",options:z$1.object({project:z$1.string().optional().describe("Project slug (searches all projects if not provided)")}),args:z$1.object({task:z$1.string().describe("Task slug")}),handler:async({project:t,task:e})=>{let{project:o,task:r}=await u.findTask(e,t),s=u.getTaskDir(o,r);console.log(s);}});});var dt,vt=f(()=>{P();D();k();B();j();F();v();dt=d({description:"Update task properties: name, description, status, assignee, or replace body",options:z$1.object({name:z$1.string().optional().describe("New name"),description:z$1.string().optional().describe("New description"),status:z$1.string().optional().describe("New status"),assignee:z$1.string().optional().describe("New assignee"),project:z$1.string().optional().describe("Project slug (searches all projects if not provided)"),body:z$1.string().optional().describe("Replace entire body/content (markdown)"),log:z$1.string().optional().describe("Log message to include in log.tsv")}),args:z$1.object({task:z$1.string().optional().describe("Task slug (default: from $PWD)")}),handler:async({project:t,task:e,name:o,description:r,status:s,assignee:i,body:a,log:p})=>{let m=h.getCurrentContext(),l=e??m.task;if(!l)throw new Error("No task specified or inferred. Provide it or cd into task dir before: `cd $(aip task path my-task)`");let{project:g}=await u.findTask(l,t),y=u.getTaskDir(g,l),O=u.getProjectDir(g),E=n.join(y,c.files.MAIN);if(!await $.runHooksForContext(O,y,"pre-update",{action:"pre-update",entityType:"task",project:g,task:l}))throw new Error("Pre-update hook failed, aborting update");let R={};if(o&&(R.name=o),r&&(R.description=r),s&&(R.status=s),i&&(R.assignee=i),Object.keys(R).length===0&&!a&&!p){console.log("No updates provided");return}if(Object.keys(R).length>0){await u.updateTask(g,l,R);let At=Object.entries(R).map(([Ke,Me])=>`${Ke}=${Me}`).join(", ");p&&(At+=` | ${p}`),await w.append(y,"task",l,"updated",At);}else p&&await w.append(y,"task",l,"log",p);a!==void 0&&(await u.updateBody(E,a),await w.append(y,"task",l,"updated",`body replaced (${a.length} chars)`)),R.status&&await w.append(O,"task",l,"updated",`status to ${R.status}`),await $.runHooksForContext(u.getProjectDir(g),y,"post-update",{action:"post-update",entityType:"task",project:g,task:l}),console.log(`Task ${l} updated`);}});});var _e,Le=f(()=>{D();k();B();v();vt();_e=d({description:"Start a task: set status to in-progress, optionally print context",options:z$1.object({project:z$1.string().optional().describe("Project slug (searches all projects if not provided)"),ingest:z$1.boolean().default(true).describe("Also output context for this task")}),args:z$1.object({task:z$1.string().optional().describe("Task slug (default: from $PWD)")}),handler:async({project:t,task:e,ingest:o})=>{let r=h.getCurrentContext(),s=e??r.task;if(!s)throw new Error("No task specified or inferred. cd into task dir before: `cd $(aip task path my-task) && aip task ingest`");let{project:i}=await u.findTask(s,t),a=u.getProjectDir(i),p=u.getTaskDir(i,s);if(!await $.runHooksForContext(a,p,"pre-start",{action:"pre-start",entityType:"task",project:i,task:s}))throw new Error("Pre-start hook failed, aborting task start");let l=await u.getTask(i,s);l?.status!=="in-progress"&&l?.status!=="ongoing"&&await dt.handler({project:i,task:s,status:"in-progress"}),o&&await u.ingestTask(i,s),await $.runHooksForContext(a,p,"post-start",{action:"post-start",entityType:"task",project:i,task:s});}});});var Fe,Ue=f(()=>{k();j();Fe=d({description:"Read one or more files into the console",options:z$1.object({}),args:z$1.object({paths:z$1.array(z$1.string()).describe("File paths to read")}),handler:async({paths:t})=>{await n.logFiles(...t);}});});var jt={};Be(jt,{default:()=>N});var Eo,N,Y=f(()=>{It();Lt();Ut();Gt();Mt();Wt();Zt();Qt();oe();se();ie();ce();le();me();fe();ke();je();be();Pe();xe();Ae();Oe();De();Ce();Ie();Le();vt();Ue();Eo={agent:{create:Nt,current:_t,list:Ft,path:Ht,start:Kt},help:{api:Jt,hooks:Vt,quickstart:Yt,skill:ee,usage:re},hook:{create:ne,run:ae},log:{append:pe,read:de},project:{create:ue,current:ge,list:ye,path:Te,update:we},skill:{read:Se},task:{create:ve,current:$e,ingest:Ee,list:Re,path:Ne,start:_e,update:dt},util:{read:Fe}},N=Eo;});J();Y();j();var Do={task:{complete:{noun:"task",verb:"update",prependArgs:["--status","done"]},done:{noun:"task",verb:"update",prependArgs:["--status","done"]},stop:{noun:"task",verb:"update",prependArgs:["--status","done"]},log:{noun:"log",verb:"append"},show:{noun:"task",verb:"ingest"},status:{noun:"task",verb:"current"}},project:{stop:{noun:"project",verb:"update",prependArgs:["--status","done"]},done:{noun:"project",verb:"update",prependArgs:["--status","done"]}}},Ro={task:{update:{summary:"log",message:"log"}}};function Co(t,e,o){let r=Do[t]?.[e];return r?{noun:r.noun,verb:r.verb,args:[...r.prependArgs||[],...o]}:{noun:t,verb:e,args:o}}function No(t,e,o){let r=Ro[t]?.[e];return r?o.map(s=>{if(s.startsWith("--")){let i=s.slice(2);if(i in r)return `--${r[i]}`}return s}):o}function Io(t){let e=[];for(let o of t){let r=o.indexOf("=");r>0&&!o.startsWith("-")?e.push(`--${o.slice(0,r)}`,o.slice(r+1)):e.push(o);}return e}function He(t){let[e="",o="",...r]=t,s=Co(e,o,r),i=Io(s.args),a=No(s.noun,s.verb,i);return [s.noun,s.verb,...a]}Y();L();j();var Lo="date time noun verb extra_args error";function ot(t,e){if(!S.ERROR_LOG)return;let r=new Date().toISOString(),[s,i]=r.split("T"),a=i.replace(/\.\d+Z$/,""),p="",m="";n.isKeyOf(t[0],N)&&(p=t[0],n.isKeyOf(t[1],N[p])&&(m=t[1]));let l=(p?1:0)+(m?1:0),g=t.slice(l).join(" "),y=[s,a,p,m,g,n.errorMessage(e)].map(Fo).join(" "),O=it.dirname(S.ERROR_LOG);ut.existsSync(O)||ut.mkdirSync(O,{recursive:true});let E=ut.existsSync(S.ERROR_LOG);ut.appendFileSync(S.ERROR_LOG,(E?"":Lo+`
404
- `)+y+`
405
- `);}function Fo(t){return (t||"-").replace(/\\/g,"\\\\").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\r/g,"")}process.on("unhandledRejection",t=>{console.error("Unhandled Rejection:",t),process.exit(1);});process.on("uncaughtException",t=>{console.error("Unhandled Exception:",t),process.exit(1);});async function Ge(t){let[e,o,...r]=He(t);(e==="--version"||e==="-v")&&(console.log(x.version),process.exit(0));try{let s=!e||e==="--help"||e==="-h";(s||!n.isKeyOf(e,N))&&(await N.help.usage.handler({}),s||ot(t,`Unknown command: ${e}`),process.exit(1));let i=N[e];s=!o||o==="--help"||o==="-h",(s||!n.isKeyOf(o,i))&&(s||ot(t,`Unknown command: ${e} ${o}`),await N.help.usage.handler({name:e}),process.exit(1));let a=i[o];a.parser._internalHandler(m=>{m.type==="error"&&ot(t,m.error||"parse error");});let p=Uo(r,a.args);await a.handler(a.parser.name(`${e} ${o}`).parse(p));}catch(s){console.error("Error:",n.errorMessage(s)),ot(t,s),process.exit(1);}}var la=Ge,da=N;n.isMain()&&Ge(process.argv.slice(2));function Uo(t,e){if(!e)return t;let o=new Set(Object.keys(e.shape)),r=[],s=0;for(;s<t.length;){if(t[s].startsWith("--")){let i=t[s].slice(2);if(o.has(i)&&s+1<t.length&&!t[s+1].startsWith("--")){r.push(t[s+1]),s+=2;continue}}r.push(t[s]),s++;}return r}export{da as commands,la as default};
401
+ `;else throw new Error(`Unsupported language: ${r}`);await n.write(m,g);let{chmod:y}=await import('fs/promises');await y(m,493),console.log(`Hook created: ${m}`);}});});var Eo,$,B=f(()=>{P();j();Eo={async findHooks(t,e){let o=n.join(t,c.dirs.HOOKS);if(!await n.fileExists(o))return [];let s=await n.listDir(o),i=`${e}.`;return s.filter(a=>a.startsWith(i)).map(a=>n.join(o,a))},async executeHook(t,e,o){if(!await n.fileExists(t))return true;let s=e.project?n.joinHome(c.dirs.PROJECTS,e.project):o,i=e.task?n.join(s,c.dirs.TASKS,e.task):"",a={...process.env,HOOK_TYPE:e.action,ENTITY_TYPE:e.entityType,TARGET_DIR:o,PROJECT_DIR:s,...e.project?{PROJECT_SLUG:e.project}:{},...e.task?{TASK_SLUG:e.task,TASK_DIR:i}:{}};return new Promise(l=>{let m=spawn(t,[],{stdio:"inherit",env:a,cwd:o,shell:false});m.on("close",(p,g)=>{p===0?l(true):(console.error(`Hook ${it.basename(t)} failed (code=${p??g})`),l(false));}),m.on("error",p=>{console.error(`Failed to execute hook ${t}: ${p.message}`),l(false);});})},async runHooks(t,e,o){let r=await this.findHooks(t,e),s=e.startsWith("pre-");for(let i of r)if(!await this.executeHook(i,o,t)&&s)return false;return true},async runHooksForContext(t,e,o,r){return !(!await this.runHooks(t,o,r)||e&&!await this.runHooks(e,o,r))}},$=Eo;});var ce,pe=f(()=>{k();B();D();P();ce=d({options:z$1.object({target:z$1.enum(c.targets).optional().describe("Target level")}),args:z$1.object({type:z$1.enum(c.hookTypes).describe("Hook type to run")}),handler:async({type:t,target:e})=>{let{targetDir:o,entityType:r}=h.getTargetDir(e),s={action:t,entityType:r,project:h.getProjectFromPwd()||void 0,task:h.getTaskFromPwd()||void 0};await $.runHooks(o,t,s)||(console.error(`Hook ${t} failed`),process.exit(1)),console.log(`Hook ${t} completed successfully`);}});});var Oo,w,F=f(()=>{P();D();j();Oo={formatEntry(t,e,o,r){let s=new Date,i=s.getFullYear(),a=String(s.getMonth()+1).padStart(2,"0"),l=String(s.getDate()).padStart(2,"0"),m=s.toLocaleTimeString("en-US",{hour12:false,hour:"2-digit",minute:"2-digit",second:"2-digit"});return `${`${i}-${a}-${l}`} ${m} ${t} ${e} ${o} ${r}
402
+ `},async append(t,e,o,r,s){let i=n.join(t,c.files.LOG),a=this.formatEntry(e,o,r,s);await n.append(i,a);},async read(t){let e=n.join(t,c.files.LOG);return await n.fileExists(e)?await n.read(e):""},async task(t,e,o){let r=h.getCurrentContext();if(!r.project||!r.task)throw new Error("Not in a task directory");let s=n.joinHome(c.dirs.PROJECTS,r.project,c.dirs.TASKS,r.task);await this.append(s,"task",t,"log",o?`${o}: ${e}`:e);},async project(t,e,o){let r=h.getProjectFromPwd();if(!r)throw new Error("Not in a project directory");let s=n.joinHome(c.dirs.PROJECTS,r);await this.append(s,"project",t,"log",o?`${o}: ${e}`:e);}},w=Oo;});var le,de=f(()=>{P();D();k();j();F();le=d({description:"Append a custom entry to log.tsv",options:z$1.object({project:z$1.string().optional().describe("Project slug (uses current project from $PWD if not provided)"),task:z$1.string().optional().describe("Task slug (uses current task from $PWD if not provided)")}),args:z$1.object({text:z$1.string().describe("Text to append")}),handler:async({project:t,task:e,text:o})=>{let r=h.getCurrentContext(),s=t||r.project;if(!s)throw new Error("No project specified. Use --project or run from a project/task directory");let i=n.joinHome(c.dirs.PROJECTS,s);if(e||r.task){let a=e||r.task;if(!a)throw new Error("No task specified");let l=n.join(i,c.dirs.TASKS,a);await w.append(l,"task",a,"log",o),console.log(`Appended to task ${a} log.tsv`);}else await w.append(i,"project",s,"log",o),console.log(`Appended to project ${s} log.tsv`);}});});var me,ue=f(()=>{P();D();k();j();F();me=d({description:"Read log.tsv history",options:z$1.object({project:z$1.string().optional().describe("Project slug (uses current project from $PWD if not provided)"),task:z$1.string().optional().describe("Task slug (uses current task from $PWD if not provided)")}),args:z$1.object({}),handler:async({project:t,task:e})=>{let o=h.getCurrentContext(),r=t||o.project;if(!r)throw new Error("No project specified. Use --project or run from a project/task directory");let s=n.joinHome(c.dirs.PROJECTS,r);if(e||o.task){let i=e||o.task;if(!i)throw new Error("No task specified");let a=n.join(s,c.dirs.TASKS,i),l=await w.read(a);console.log(l||`No log.tsv found for task ${i}`);}else {let i=await w.read(s);console.log(i||`No log.tsv found for project ${r}`);}}});});var fe,ge=f(()=>{k();j();F();v();fe=d({description:"Create a new project with name, description, optional status, assignee and body",options:z$1.object({description:z$1.string().describe("Project description"),status:z$1.string().default("active").describe("Initial status"),assignee:z$1.string().optional().describe("Assignee agent slug"),body:z$1.string().optional().describe("Initial body/content (markdown)")}),args:z$1.object({name:z$1.string().describe("Project name")}),handler:async({name:t,description:e,status:o,assignee:r,body:s})=>{let i=n.slugify(t),a=u.getProjectDir(i);await u.createProject(i,{name:t,description:e,status:o,assignee:r,created:new Date().toISOString()},s),await w.append(a,"project",i,"created",`${t} > status is ${o}`),console.log(`Project created: ${i}. Path: ${a}`);}});});var ke,he=f(()=>{k();D();ke=d({options:z$1.object({}),handler:async()=>{let t=h.getProjectFromPwd();t||(console.error("Not in a project directory"),process.exit(1)),console.log(t);}});});var je,Te=f(()=>{k();v();je=d({description:"List all projects, optionally filtered by status",options:z$1.object({status:z$1.string().optional().describe("Filter by status")}),handler:async({status:t})=>{let e=await u.listProjects(),o=[];for(let r of e){let s=await u.getProject(r);s&&(t&&s.status!==t||o.push({slug:r,status:s.status,assignee:s.assignee}));}if(o.length===0)return console.log("No projects found");console.log("Projects:");for(let r of o)console.log(`- ${r.slug}: ${r.status||""} ${r.assignee||""}`);}});});var be,we=f(()=>{k();v();be=d({description:"Output project directory path (for cd)",options:z$1.object({}),args:z$1.object({name:z$1.string().describe("Project name (slug)")}),handler:async({name:t})=>{let e=u.getProjectDir(t);console.log(e);}});});var Pe,Se=f(()=>{P();D();k();B();j();v();F();Pe=d({description:"Update project properties: name, description, status, assignee, or replace body",options:z$1.object({name:z$1.string().optional().describe("New name"),description:z$1.string().optional().describe("New description"),status:z$1.string().optional().describe("New status"),assignee:z$1.string().optional().describe("New assignee"),body:z$1.string().optional().describe("Replace entire body/content (markdown)")}),args:z$1.object({project:z$1.string().optional().describe("Project slug (defaults to current project from $PWD)")}),handler:async({project:t,name:e,description:o,status:r,assignee:s,body:i})=>{let a=t||h.getProjectFromPwd();if(!a)throw new Error("No project specified and not in a project directory");let l=u.getProjectDir(a),m=n.join(l,c.files.MAIN);if(!await $.runHooks(l,"pre-update",{action:"pre-update",entityType:"project"}))throw new Error("Pre-update hook failed, aborting update");let g={};if(e&&(g.name=e),o&&(g.description=o),r&&(g.status=r),s&&(g.assignee=s),Object.keys(g).length===0&&!i){console.log("No updates provided");return}if(Object.keys(g).length>0){await u.updateProject(a,g);let y=Object.entries(g).map(([O,E])=>`${O}=${E}`).join(", ");await w.append(l,"project",a,"updated",y);}i!==void 0&&(await u.updateBody(m,i),await w.append(l,"project",a,"updated",`body replaced (${i.length} chars)`)),await $.runHooks(l,"post-update",{action:"post-update",entityType:"project"}),console.log(`Project ${a} updated`);}});});var xe,ve=f(()=>{P();k();_();j();xe=d({description:"Read a skill's SKILL.md file into the console for agent context",options:z$1.object({}),args:z$1.object({name:z$1.string().describe("Skill name (directory name)")}),handler:async({name:t})=>{let e=n.join(S.AIP_HOME,c.dirs.SKILLS,t),o=n.join(e,c.files.SKILL);if(!await n.fileExists(o))throw new Error(`Skill not found: ${t}
403
+ Expected at: ${o}`);await n.logFiles(o);}});});var Ae,$e=f(()=>{k();B();j();v();F();Ae=d({description:"Create a new task with assignee, initial status and optional body",options:z$1.object({description:z$1.string().optional().describe("Task description"),assignee:z$1.string().optional().describe("Assignee agent slug"),status:z$1.string().default("backlog").describe("Initial status"),body:z$1.string().optional().describe("Initial body/content (markdown)")}),args:z$1.object({project:z$1.string().describe("Project slug"),name:z$1.string().describe("Task name")}),handler:async({project:t,name:e,description:o,assignee:r,status:s,body:i})=>{let a=n.slugify(e),l=u.getProjectDir(t),m=u.getTaskDir(t,a);if(!await $.runHooksForContext(l,m,"pre-create",{action:"pre-create",entityType:"task",project:t}))throw new Error("Pre-create hook failed, aborting task creation");await u.createTask(t,a,{name:e,description:o,assignee:r,status:s,created:new Date().toISOString()},i),await w.append(m,"task",a,"created",e),await w.append(l,"task",a,"created",`${a} > status is ${s}`),await $.runHooksForContext(l,m,"post-create",{action:"post-create",entityType:"task",project:t}),console.log(`Task created: ${a}`),console.log(` Project: ${t}`),console.log(` Path: ${m}`);}});});var Ee,Oe=f(()=>{k();D();Ee=d({description:"Get the current task slug from PWD",options:z$1.object({}),handler:async()=>{let t=h.getTaskFromPwd();t||(console.error("Not in a task directory"),process.exit(1)),console.log(t);}});});var De,Re=f(()=>{D();k();v();De=d({description:"Output full task context (main.md, log.tsv) for ingestion by agents",options:z$1.object({project:z$1.string().optional().describe("Project slug (searches all projects if not provided)")}),args:z$1.object({task:z$1.string().optional().describe("Task slug (default: from $PWD)")}),handler:async({project:t,task:e})=>{let o=h.getCurrentContext(),r=e??o.task;if(!r)throw new Error("No task specified or inferred. cd into task dir before: `cd $(aip task path my-task) && aip task ingest`");let{project:s}=await u.findTask(r,t);await u.ingestTask(s,r);}});});var Ce,Ne=f(()=>{k();j();v();Ce=d({description:"List tasks, optionally filtered by project, status, assignee, or search query",options:z$1.object({project:z$1.string().optional().describe("Project slug (searches all projects if not provided)"),statuses:z$1.array(z$1.string()).default([]).describe("Filter by statuses (multiple allowed)"),assignee:z$1.string().optional().describe("Filter by assignee"),all:z$1.boolean().default(false).describe("Include all tasks (including done/blocked)"),search:z$1.string().optional().describe("Search query (matches task slug, case-insensitive, multi-part AND, any order)")}),handler:async({project:t,statuses:e,assignee:o,all:r,search:s})=>{if(e&&e.length>0){for(let p of e)if(!nt.includes(p))throw new Error(`Invalid status: ${p}. Valid values: ${nt.join(", ")}`)}let i;e&&e.length>0?i=e:r?i=nt:i=Ct;let a=t?[t]:await u.listProjects(),l={};await n.promiseEach(a,async p=>{let g=await u.listTasks(p),y=[];await n.promiseEach(g,async O=>{let E=await u.getTask(p,O);E&&(i.length>0&&!i.includes(E.status||"")||o&&E.assignee!==o||n.matchesSearch(O,s)&&y.push({slug:O,description:E.description}));}),y.length>0&&(l[p]=y.sort((O,E)=>O.slug.localeCompare(E.slug)));});let m=Object.keys(l).sort();if(m.length===0)return console.log("No tasks found");for(let p of m){console.log(`${p}:`);for(let g of l[p])console.log(`- ${g.slug}: ${g.description||""}`);}}});});var Ie,Le=f(()=>{k();v();Ie=d({description:"Output task directory path (for cd)",options:z$1.object({project:z$1.string().optional().describe("Project slug (searches all projects if not provided)")}),args:z$1.object({task:z$1.string().describe("Task slug")}),handler:async({project:t,task:e})=>{let{project:o,task:r}=await u.findTask(e,t),s=u.getTaskDir(o,r);console.log(s);}});});var dt,vt=f(()=>{P();D();k();B();j();F();v();dt=d({description:"Update task properties: name, description, status, assignee, or replace body",options:z$1.object({name:z$1.string().optional().describe("New name"),description:z$1.string().optional().describe("New description"),status:z$1.string().optional().describe("New status"),assignee:z$1.string().optional().describe("New assignee"),project:z$1.string().optional().describe("Project slug (searches all projects if not provided)"),body:z$1.string().optional().describe("Replace entire body/content (markdown)"),log:z$1.string().optional().describe("Log message to include in log.tsv")}),args:z$1.object({task:z$1.string().optional().describe("Task slug (default: from $PWD)")}),handler:async({project:t,task:e,name:o,description:r,status:s,assignee:i,body:a,log:l})=>{let m=h.getCurrentContext(),p=e??m.task;if(!p)throw new Error("No task specified or inferred. Provide it or cd into task dir before: `cd $(aip task path my-task)`");let{project:g}=await u.findTask(p,t),y=u.getTaskDir(g,p),O=u.getProjectDir(g),E=n.join(y,c.files.MAIN);if(!await $.runHooksForContext(O,y,"pre-update",{action:"pre-update",entityType:"task",project:g,task:p}))throw new Error("Pre-update hook failed, aborting update");let C={};if(o&&(C.name=o),r&&(C.description=r),s&&(C.status=s),i&&(C.assignee=i),Object.keys(C).length===0&&!a&&!l){console.log("No updates provided");return}if(Object.keys(C).length>0){await u.updateTask(g,p,C);let $t=Object.entries(C).map(([Be,Je])=>`${Be}=${Je}`).join(", ");l&&($t+=` | ${l}`),await w.append(y,"task",p,"updated",$t);}else l&&await w.append(y,"task",p,"log",l);a!==void 0&&(await u.updateBody(E,a),await w.append(y,"task",p,"updated",`body replaced (${a.length} chars)`)),C.status&&await w.append(O,"task",p,"updated",`status to ${C.status}`),await $.runHooksForContext(u.getProjectDir(g),y,"post-update",{action:"post-update",entityType:"task",project:g,task:p}),console.log(`Task ${p} updated`);}});});var _e,Fe=f(()=>{D();k();B();v();vt();_e=d({description:"Start a task: set status to in-progress, optionally print context",options:z$1.object({project:z$1.string().optional().describe("Project slug (searches all projects if not provided)"),ingest:z$1.boolean().default(true).describe("Also output context for this task")}),args:z$1.object({task:z$1.string().optional().describe("Task slug (default: from $PWD)")}),handler:async({project:t,task:e,ingest:o})=>{let r=h.getCurrentContext(),s=e??r.task;if(!s)throw new Error("No task specified or inferred. cd into task dir before: `cd $(aip task path my-task) && aip task ingest`");let{project:i}=await u.findTask(s,t),a=u.getProjectDir(i),l=u.getTaskDir(i,s);if(!await $.runHooksForContext(a,l,"pre-start",{action:"pre-start",entityType:"task",project:i,task:s}))throw new Error("Pre-start hook failed, aborting task start");let p=await u.getTask(i,s);p?.status!=="in-progress"&&p?.status!=="ongoing"&&await dt.handler({project:i,task:s,status:"in-progress"}),o&&await u.ingestTask(i,s),await $.runHooksForContext(a,l,"post-start",{action:"post-start",entityType:"task",project:i,task:s});}});});var Ue,He=f(()=>{k();j();Ue=d({description:"Read one or more files into the console",options:z$1.object({}),args:z$1.object({paths:z$1.array(z$1.string()).describe("File paths to read")}),handler:async({paths:t})=>{await n.logFiles(...t);}});});var jt={};Ve(jt,{default:()=>R});var Co,R,Y=f(()=>{Lt();Ft();Ht();Kt();zt();Vt();qt();Xt();re();ne();ae();pe();de();ue();ge();he();Te();we();Se();ve();$e();Oe();Re();Ne();Le();Fe();vt();He();Co={agent:{create:It,current:_t,list:Ut,path:Gt,start:Mt},help:{api:Wt,hooks:Zt,quickstart:Qt,skill:oe,usage:se},hook:{create:ie,run:ce},log:{append:le,read:me},project:{create:fe,current:ke,list:je,path:be,update:Pe},skill:{read:xe},task:{create:Ae,current:Ee,ingest:De,list:Ce,path:Ie,start:_e,update:dt},util:{read:Ue}},R=Co;});J();Y();j();Y();_();j();var Io="type date time noun verb extra_args error";function Ge(t,e,o){if(!S.ERROR_LOG)return;let s=new Date().toISOString(),[i,a]=s.split("T"),l=a.replace(/\.\d+Z$/,""),m="",p="";n.isKeyOf(e[0],R)&&(m=e[0],n.isKeyOf(e[1],R[m])&&(p=e[1]));let g=(m?1:0)+(p?1:0),y=e.slice(g).join(" "),O=[t,i,l,m,p,y,o].map(Lo).join(" "),E=it.dirname(S.ERROR_LOG);ut.existsSync(E)||ut.mkdirSync(E,{recursive:true});let At=ut.existsSync(S.ERROR_LOG);ut.appendFileSync(S.ERROR_LOG,(At?"":Io+`
404
+ `)+O+`
405
+ `);}function ot(t,e){Ge("error",t,n.errorMessage(e));}function Ke(t,e){Ge("alias",t,e);}function Lo(t){return (t||"-").replace(/\\/g,"\\\\").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\r/g,"")}var _o={task:{complete:{noun:"task",verb:"update",prependArgs:["--status","done"]},done:{noun:"task",verb:"update",prependArgs:["--status","done"]},stop:{noun:"task",verb:"update",prependArgs:["--status","done"]},log:{noun:"log",verb:"append"},show:{noun:"task",verb:"ingest"},status:{noun:"task",verb:"current"}},project:{stop:{noun:"project",verb:"update",prependArgs:["--status","done"]},done:{noun:"project",verb:"update",prependArgs:["--status","done"]}}},Fo={task:{update:{summary:"log",message:"log"}}};function Uo(t,e,o){let r=_o[t]?.[e];if(r){let s=`${t} ${e} ${o.join(" ")}`.trim();return Ke([t,e,...o],s),{noun:r.noun,verb:r.verb,args:[...r.prependArgs||[],...o]}}return {noun:t,verb:e,args:o}}function Ho(t,e,o){let r=Fo[t]?.[e];return r?o.map(s=>{if(s.startsWith("--")){let i=s.slice(2);if(i in r)return `--${r[i]}`}return s}):o}function Go(t){let e=[];for(let o of t){let r=o.indexOf("=");r>0&&!o.startsWith("-")?e.push(`--${o.slice(0,r)}`,o.slice(r+1)):e.push(o);}return e}function Me(t){let[e="",o="",...r]=t,s=Uo(e,o,r),i=Go(s.args),a=Ho(s.noun,s.verb,i);return [s.noun,s.verb,...a]}process.on("unhandledRejection",t=>{console.error("Unhandled Rejection:",t),process.exit(1);});process.on("uncaughtException",t=>{console.error("Unhandled Exception:",t),process.exit(1);});async function ze(t){let[e,o,...r]=Me(t);(e==="--version"||e==="-v")&&(console.log(x.version),process.exit(0));try{let s=!e||e==="--help"||e==="-h";(s||!n.isKeyOf(e,R))&&(await R.help.usage.handler({}),s||ot(t,`Unknown command: ${e}`),process.exit(1));let i=R[e];s=!o||o==="--help"||o==="-h",(s||!n.isKeyOf(o,i))&&(s||ot(t,`Unknown command: ${e} ${o}`),await R.help.usage.handler({name:e}),process.exit(1));let a=i[o],l=!1;a.parser._internalHandler(p=>{p.type==="error"&&(l=!0,ot(t,p.error||"parse error"));}),l&&(await R.help.usage.handler({name:e}),process.exit(1));let m=Ko(r,a.args);await a.handler(a.parser.name(`${e} ${o}`).parse(m));}catch(s){console.error("Error:",n.errorMessage(s)),ot(t,s),process.exit(1);}}var ua=ze,fa=R;n.isMain()&&ze(process.argv.slice(2));function Ko(t,e){if(!e)return t;let o=new Set(Object.keys(e.shape)),r=[],s=0;for(;s<t.length;){if(t[s].startsWith("--")){let i=t[s].slice(2);if(o.has(i)&&s+1<t.length&&!t[s+1].startsWith("--")){r.push(t[s+1]),s+=2;continue}}r.push(t[s]),s++;}return r}export{fa as commands,ua as default};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-projects",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "type": "module",
5
5
  "description": "Useful CLI for AI agents to create and manage projects, tasks, skills and agents",
6
6
  "main": "dist/index.js",