ai-projects 1.5.1 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +138 -10
- package/dist/index.d.ts +12 -0
- package/dist/index.js +96 -77
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,25 +1,153 @@
|
|
|
1
|
-
# AIP - AI Project Management CLI
|
|
1
|
+
# AIP - AI Project Management CLI 🤖
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**Built for AI agents. Polished by AI agents.**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
A command-line tool for managing AI agent projects, tasks, and agents with structured workflows, activity logging, and automation hooks.
|
|
6
6
|
|
|
7
|
+
## 📚 Help System
|
|
8
|
+
|
|
9
|
+
AIP has a comprehensive built-in help system for every level:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# 🚀 New here? Start with the quick guide
|
|
13
|
+
aip help quickstart
|
|
14
|
+
|
|
15
|
+
# 📋 Browse all commands by noun
|
|
16
|
+
aip help usage
|
|
17
|
+
|
|
18
|
+
# 🎯 Need commands for a specific noun?
|
|
19
|
+
aip help usage task # All task commands
|
|
20
|
+
aip help usage project # All project commands
|
|
21
|
+
aip help usage log # All logging commands
|
|
22
|
+
|
|
23
|
+
# 📖 Complete API reference (comprehensive!)
|
|
24
|
+
aip help api
|
|
25
|
+
|
|
26
|
+
# 🛠️ Project management skill documentation
|
|
27
|
+
aip help skill
|
|
28
|
+
|
|
29
|
+
# 🔗 Hook system documentation
|
|
30
|
+
aip help hooks
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## ✨ Features
|
|
34
|
+
|
|
35
|
+
- **Structured Projects**: YAML frontmatter + markdown body
|
|
36
|
+
- **Activity Logging**: TSV-based status tracking (date, time, type, action, text)
|
|
37
|
+
- **Automation Hooks**: Pre/post hooks for create, start, update, complete
|
|
38
|
+
- **Multi-line Support**: Heredoc syntax for complex content
|
|
39
|
+
- **Agent-Ready**: Designed for autonomous AI workflows
|
|
40
|
+
|
|
41
|
+
## 🚀 Quick Start
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# Create a project with multi-line body
|
|
45
|
+
aip project create "my-project" --description "..." --body "$(cat <<'EOF'
|
|
46
|
+
# Goals
|
|
47
|
+
- Build something amazing
|
|
48
|
+
- Solve real problems
|
|
49
|
+
|
|
50
|
+
## Success Criteria
|
|
51
|
+
- Tests passing
|
|
52
|
+
- Documentation complete
|
|
53
|
+
EOF
|
|
54
|
+
)"
|
|
55
|
+
|
|
56
|
+
# Create a task in the project
|
|
57
|
+
aip task create my-project "first-task" --description "Get started"
|
|
58
|
+
|
|
59
|
+
# Navigate and work
|
|
60
|
+
cd $(aip task path first-task)
|
|
61
|
+
|
|
62
|
+
# Log your progress
|
|
63
|
+
aip log append "API integration complete"
|
|
64
|
+
|
|
65
|
+
# View activity history
|
|
66
|
+
aip log read
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## 📁 Project Structure
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
$AIP_HOME/projects/{project}/
|
|
73
|
+
├── main.md # Goals + body (YAML frontmatter + markdown)
|
|
74
|
+
├── log.tsv # Activity log (tab-separated: date, time, type, slug, action, text)
|
|
75
|
+
├── hooks/ # Automation: pre|post-{create,start,update,complete}
|
|
76
|
+
├── outputs/ # Deliverables go here
|
|
77
|
+
├── inputs/ # External data (API responses, downloads)
|
|
78
|
+
├── scripts/ # Automation scripts
|
|
79
|
+
└── tasks/{task}/
|
|
80
|
+
├── main.md # Task definition + body
|
|
81
|
+
├── log.tsv # Task activity log
|
|
82
|
+
└── ... # Same substructure
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## 🔧 Key Commands
|
|
86
|
+
|
|
87
|
+
### Projects
|
|
88
|
+
```bash
|
|
89
|
+
aip project create "name" --description "..." --body "..."
|
|
90
|
+
aip project update --status done --body "$(cat final-report.md)"
|
|
91
|
+
aip project list
|
|
92
|
+
aip project path my-project # Get absolute path
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Tasks
|
|
96
|
+
```bash
|
|
97
|
+
aip task create my-project "task-name" --description "..."
|
|
98
|
+
aip task update --status in-progress
|
|
99
|
+
aip task list
|
|
100
|
+
aip task path task-name # Get absolute path
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Logging
|
|
104
|
+
```bash
|
|
105
|
+
aip log append "Completed the implementation"
|
|
106
|
+
aip log append --task my-task "Fixed the bug"
|
|
107
|
+
aip log read # View status history
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Utilities
|
|
7
111
|
```bash
|
|
8
|
-
|
|
112
|
+
aip task ingest # Output full context for AI agents
|
|
113
|
+
aip task start # Mark as in-progress
|
|
114
|
+
aip help quickstart # Get started guide
|
|
9
115
|
```
|
|
10
116
|
|
|
11
|
-
|
|
117
|
+
## 🤖 For AI Agents
|
|
12
118
|
|
|
13
|
-
|
|
119
|
+
If you're an AI agent working with AIP:
|
|
120
|
+
|
|
121
|
+
1. **Read** `$AIP_HOME/AGENTS.md` first
|
|
122
|
+
2. **Review** `main.md` for goals and context
|
|
123
|
+
3. **Check** `log.tsv` for activity history
|
|
124
|
+
4. **Work** and save outputs to `outputs/`
|
|
125
|
+
5. **Log** progress: `aip log append "message"`
|
|
126
|
+
6. **Complete**: Set status=done, summarize in project status
|
|
127
|
+
|
|
128
|
+
## 💡 Pro Tips
|
|
14
129
|
|
|
15
130
|
```bash
|
|
16
|
-
|
|
131
|
+
# Chain commands
|
|
132
|
+
cd $(aip task path my-task) && aip task start
|
|
133
|
+
|
|
134
|
+
# Use heredocs for complex body content
|
|
135
|
+
aip project update --body "$(cat <<'EOF'
|
|
136
|
+
# Updated Goals
|
|
137
|
+
...
|
|
138
|
+
EOF
|
|
139
|
+
)"
|
|
140
|
+
|
|
141
|
+
# Quick status check
|
|
142
|
+
aip log read | tail -5
|
|
17
143
|
```
|
|
18
144
|
|
|
19
|
-
##
|
|
145
|
+
## 🛠️ Development
|
|
146
|
+
|
|
147
|
+
This tool is **meant for AI agents** and will be **automatically polished by AI agents** based on their usage.
|
|
20
148
|
|
|
21
|
-
|
|
149
|
+
**Suggestions and PRs welcome!** 🎉
|
|
22
150
|
|
|
23
|
-
## License
|
|
151
|
+
## 📄 License
|
|
24
152
|
|
|
25
153
|
MIT
|
package/dist/index.d.ts
CHANGED
|
@@ -155,14 +155,17 @@ declare const commands: {
|
|
|
155
155
|
description: zod.ZodString;
|
|
156
156
|
status: zod.ZodDefault<zod.ZodString>;
|
|
157
157
|
assignee: zod.ZodOptional<zod.ZodString>;
|
|
158
|
+
body: zod.ZodOptional<zod.ZodString>;
|
|
158
159
|
}, "strip", zod.ZodTypeAny, {
|
|
159
160
|
status: string;
|
|
160
161
|
description: string;
|
|
161
162
|
assignee?: string | undefined;
|
|
163
|
+
body?: string | undefined;
|
|
162
164
|
}, {
|
|
163
165
|
description: string;
|
|
164
166
|
status?: string | undefined;
|
|
165
167
|
assignee?: string | undefined;
|
|
168
|
+
body?: string | undefined;
|
|
166
169
|
}>, zod.ZodObject<{
|
|
167
170
|
name: zod.ZodString;
|
|
168
171
|
}, "strip", zod.ZodTypeAny, {
|
|
@@ -198,16 +201,19 @@ declare const commands: {
|
|
|
198
201
|
description: zod.ZodOptional<zod.ZodString>;
|
|
199
202
|
status: zod.ZodOptional<zod.ZodString>;
|
|
200
203
|
assignee: zod.ZodOptional<zod.ZodString>;
|
|
204
|
+
body: zod.ZodOptional<zod.ZodString>;
|
|
201
205
|
}, "strip", zod.ZodTypeAny, {
|
|
202
206
|
status?: string | undefined;
|
|
203
207
|
description?: string | undefined;
|
|
204
208
|
name?: string | undefined;
|
|
205
209
|
assignee?: string | undefined;
|
|
210
|
+
body?: string | undefined;
|
|
206
211
|
}, {
|
|
207
212
|
status?: string | undefined;
|
|
208
213
|
description?: string | undefined;
|
|
209
214
|
name?: string | undefined;
|
|
210
215
|
assignee?: string | undefined;
|
|
216
|
+
body?: string | undefined;
|
|
211
217
|
}>, zod.ZodObject<{
|
|
212
218
|
project: zod.ZodOptional<zod.ZodString>;
|
|
213
219
|
}, "strip", zod.ZodTypeAny, {
|
|
@@ -230,14 +236,17 @@ declare const commands: {
|
|
|
230
236
|
description: zod.ZodOptional<zod.ZodString>;
|
|
231
237
|
assignee: zod.ZodOptional<zod.ZodString>;
|
|
232
238
|
status: zod.ZodDefault<zod.ZodString>;
|
|
239
|
+
body: zod.ZodOptional<zod.ZodString>;
|
|
233
240
|
}, "strip", zod.ZodTypeAny, {
|
|
234
241
|
status: string;
|
|
235
242
|
description?: string | undefined;
|
|
236
243
|
assignee?: string | undefined;
|
|
244
|
+
body?: string | undefined;
|
|
237
245
|
}, {
|
|
238
246
|
status?: string | undefined;
|
|
239
247
|
description?: string | undefined;
|
|
240
248
|
assignee?: string | undefined;
|
|
249
|
+
body?: string | undefined;
|
|
241
250
|
}>, zod.ZodObject<{
|
|
242
251
|
project: zod.ZodString;
|
|
243
252
|
name: zod.ZodString;
|
|
@@ -324,18 +333,21 @@ declare const commands: {
|
|
|
324
333
|
status: zod.ZodOptional<zod.ZodString>;
|
|
325
334
|
assignee: zod.ZodOptional<zod.ZodString>;
|
|
326
335
|
project: zod.ZodOptional<zod.ZodString>;
|
|
336
|
+
body: zod.ZodOptional<zod.ZodString>;
|
|
327
337
|
}, "strip", zod.ZodTypeAny, {
|
|
328
338
|
project?: string | undefined;
|
|
329
339
|
status?: string | undefined;
|
|
330
340
|
description?: string | undefined;
|
|
331
341
|
name?: string | undefined;
|
|
332
342
|
assignee?: string | undefined;
|
|
343
|
+
body?: string | undefined;
|
|
333
344
|
}, {
|
|
334
345
|
project?: string | undefined;
|
|
335
346
|
status?: string | undefined;
|
|
336
347
|
description?: string | undefined;
|
|
337
348
|
name?: string | undefined;
|
|
338
349
|
assignee?: string | undefined;
|
|
350
|
+
body?: string | undefined;
|
|
339
351
|
}>, zod.ZodObject<{
|
|
340
352
|
task: zod.ZodOptional<zod.ZodString>;
|
|
341
353
|
}, "strip", zod.ZodTypeAny, {
|
package/dist/index.js
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {z as z$1}from'zod';import {parser}from'zod-opts';import
|
|
2
|
+
import {z as z$1}from'zod';import {parser}from'zod-opts';import Ve from'dotenv';import We from'fs';import G from'path';import {fileURLToPath}from'url';import {spawn,exec}from'child_process';import z from'fs/promises';import w from'lodash';import Z from'moment';import {inspect}from'util';import vt from'yaml';var Ge=Object.defineProperty;var g=(t,e)=>()=>(t&&(e=t(t=0)),e);var Me=(t,e)=>{for(var o in e)Ge(t,o,{get:e[o],enumerable:true});};var S,W=g(()=>{S={name:"ai-projects",version:"1.6.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:all":"npm run build:map && tsup","build:check":"tsc --noEmit","build:watch":"npm run build:code -- --watch","build:clean":"rimraf dist/*","build:incr":"tsup --no-dts",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 dist/test.tsbuildinfo","test:types:bin":"tsc -p bin/tsconfig.json --incremental --tsBuildInfoFile dist/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:incr && npm run test:types:bin && npm run lint:fix","lint:full:silent":"npm run -s lint:full && echo LINT OK",map:"npm run build:map",link:"npm link",unlink:"npm unlink",prepare:'[ "$CI" != "true" ] && [ -d node_modules/husky ] && husky || true',prepack:"npm run test:full && npm run build:all","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 p(t){let{description:e,options:o=z$1.object({}),args:r,handler:n}=t,i=o.shape,a={};for(let[m,d]of Object.entries(i))a[m]={type:d};let l=parser().options(a);if(r){let m=r.shape,d=Object.entries(m).map(([f,b])=>({name:f,type:b}));d.length>0&&(l=l.args(d));}return e&&(l=l.description(e)),{description:e,options:o,args:r,parser:l,handler:n,cli:m=>n(l.parse(m))}}var k=g(()=>{});var c,P=g(()=>{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"]};});var qe,$t,U,Ye,A,M=g(()=>{P();qe=()=>{let t=fileURLToPath(import.meta.url),e=G.dirname(t),o=10;for(let r=0;r<o;r++)try{if(We.existsSync(G.join(e,"package.json")))return e;let n=G.dirname(e);if(n===e)break;e=n;}catch{break}return process.cwd()},$t=qe(),U=process.env.AIP_HOME;U||(Ve.config({path:G.join($t,".env"),quiet:true}),U=process.env.AIP_HOME);if(!U){U=process.cwd();let t=U.split(G.sep);for(let e of [c.dirs.PROJECTS,c.dirs.SKILLS,c.dirs.AGENTS]){let o=t.indexOf(e);if(o!==-1){U=t.slice(0,o).join(G.sep);break}}}Ye={ROOT:$t,AIP_HOME:U},A=Ye;});var y,s,j=g(()=>{M();y={REPO:fileURLToPath(import.meta.url.replace(/\/(dist|src)\/.*/,"/")),join:(...t)=>G.join(...t),onRepo:(...t)=>y.join(y.REPO,...t),joinHome:(...t)=>y.join(A.AIP_HOME,...t),async ensureDir(t){await z.mkdir(t,{recursive:true});},async write(t,e){await y.ensureDir(G.dirname(t)),await z.writeFile(t,e,"utf8");},async append(t,e){await y.ensureDir(G.dirname(t)),await z.appendFile(t,e,"utf8");},async read(t){return z.readFile(t,"utf8")},async readRepo(...t){return y.read(y.onRepo(...t))},async readMany(...t){return (await Promise.all(t.map(async o=>{if(await y.fileExists(o)){let r=await y.read(o);return `# ${o}
|
|
3
3
|
|
|
4
|
-
${r}`}return ""}))).filter(Boolean)},async logFiles(...t){let e=await
|
|
4
|
+
${r}`}return ""}))).filter(Boolean)},async logFiles(...t){let e=await y.readMany(...t);console.log(e.join(`
|
|
5
5
|
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
`));},dumpCommandMapLines(t,e){let o=e?
|
|
8
|
+
`));},dumpCommandMapLines(t,e){let o=e?w.pick(t,e):t,r=[];for(let[n,i]of y.entriesOf(o))r.push(`${n} {${Object.keys(i).join("|")}}`);return r},async fileExists(t){try{return await z.access(t),!0}catch{return false}},async listDir(t){try{return await z.readdir(t)}catch{return []}},spawn:spawn,cd(t){process.chdir(t);},async exec(t,e){return new Promise(o=>{exec(t,{encoding:"utf8",...e},(r,n,i)=>{let a=r?.code;o({stdout:n??"",stderr:i??"",code:r?typeof a=="number"?a:1:0});});})},noop:()=>{},omitByDeep:(t,e)=>w.isArray(t)?t.map(o=>y.omitByDeep(o,e)):w.isPlainObject(t)?w.mapValues(w.omitBy(t,e),o=>y.omitByDeep(o,e)):t,omitNilsDeep:t=>y.omitByDeep(t,w.isNil),omitUndefinedsDeep:t=>y.omitByDeep(t,w.isUndefined),cloneDeep:t=>w.cloneDeep(t),int:t=>Number.parseInt(t,10),keysOf:t=>Object.keys(t),entriesOf:t=>Object.entries(t),isKeyOf:(t,e)=>!w.isNil(t)&&t in e,typeOf:t=>typeof t,never:{},undef:t=>t??void 0,toNull:t=>t??null,same:t=>t,notNil:t=>{if(w.isNil(t))throw new Error(`Received unexpected ${t} value`);return t},randomInt:(t,e)=>Math.floor(Math.random()*(e-t+1))+t,promise:()=>{let t,e=new Promise((o,r)=>{t={resolve:o,reject:r};});return w.extend(e,t)},isPromise:t=>w.isObject(t)&&"catch"in t,delay:t=>{let e=w.isObject(t)?y.toMS(t):t;return new Promise(o=>setTimeout(o,e))},promiseMap:(t,e)=>Promise.all(t.map(e)),promiseEach:(t,e)=>Promise.all(t.map(e)).then(()=>{}),memoize:t=>w.memoize(t,y.memoizeKey),toMS:t=>Z.duration(t).asMilliseconds(),toSecs:t=>Z.duration(t).asSeconds(),inspect:(t,e)=>inspect(t,{colors:false,showHidden:false,depth:null,compact:true,breakLength:1/0,...e}),stringify(t,e,o){let r=new WeakSet;return JSON.stringify(t,(n,i)=>{if(w.isObject(i)){if(r.has(i))return "[Circular]";r.add(i);}return w.isFunction(e)?e(n,i):i},o)},dump:t=>y.oneLine(y.stringify(t)),compactWhitespace:t=>t.replace(/\\n/g,`
|
|
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)=>
|
|
13
|
-
${
|
|
12
|
+
`).replace(/ {2,}/g," ").trim(),oneLine:t=>t.replace(/\n/g,"\\n").replace(/\t/g,"\\t").replace(/ +/g," ").trim(),fuzzySearch:(t,e)=>w.includes(w.toLower(t||""),w.toLower(e||"")),elapsed:(t,e=Date.now())=>Z.duration(Z(e).diff(t||0)),iso:t=>Z.utc(t).toISOString(),isoDate:t=>y.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,"")},s=y;});var et,B,ft,q,Et=g(()=>{j();et=t=>{let e=t.trim();if(!e.startsWith("---"))return null;let o=e.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);return o?{frontmatter:vt.parse(o[1]),content:o[2].trim()}:null},B=async(t,e,o="")=>{let n=`---
|
|
13
|
+
${vt.stringify(e).trim()}
|
|
14
14
|
---
|
|
15
15
|
|
|
16
|
-
${o}`.trim();await
|
|
17
|
-
`);},
|
|
18
|
-
Expected at: ${o}`);console.log(e);}});});var _t,
|
|
19
|
-
Expected at: ${o}`);let i=[r,o];await
|
|
20
|
-
`,r.length>0||
|
|
16
|
+
${o}`.trim();await s.write(t,n+`
|
|
17
|
+
`);},ft=async(t,e)=>{let o=await s.read(t),r=et(o);if(!r)throw new Error(`No frontmatter found in ${t}`);let n={...r.frontmatter,...e};return await B(t,n,r.content),n},q=async t=>{let e=await s.read(t),o=et(e);if(!o)throw new Error(`No frontmatter found in ${t}`);return o.frontmatter};});var J,ot,At,Ot,oo,ro,u,x=g(()=>{P();M();Et();j();J=(a=>(a.BACKLOG="backlog",a.IN_PROGRESS="in-progress",a.ONGOING="ongoing",a.DONE="done",a.BLOCKED="blocked",a.TO_DO="to-do",a))(J||{}),ot=Object.values(J),At=["backlog","in-progress","ongoing"],Ot=[c.dirs.HOOKS,c.dirs.INPUTS,c.dirs.OUTPUTS,c.dirs.SCRIPTS],oo=[c.dirs.TASKS,...Ot],ro={getProjectDir(t){return s.joinHome(c.dirs.PROJECTS,t)},getTaskDir(t,e){return s.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 s.promiseEach(o,async n=>{(await this.listTasks(n)).includes(t)&&r.push(n);}),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 s.join(A.AIP_HOME,c.dirs.AGENTS,t)},async listProjects(){let t=s.join(A.AIP_HOME,c.dirs.PROJECTS),e=await s.listDir(t);return (await s.promiseMap(e,async r=>{let n=this.getProjectDir(r);return await s.fileExists(n)&&r!==c.dirs.AGENTS?r:null})).filter(r=>r!==null).sort()},async listTasks(t){let e=s.join(this.getProjectDir(t),c.dirs.TASKS);return await s.fileExists(e)?await s.listDir(e):[]},async listAgents(){let t=s.join(A.AIP_HOME,c.dirs.AGENTS);return await s.fileExists(t)?await s.listDir(t):[]},async createProject(t,e,o){let r=this.getProjectDir(t);return await s.ensureDir(r),await Promise.all(oo.map(n=>s.ensureDir(s.join(r,n)))),await B(s.join(r,c.files.MAIN),e,o),await s.write(s.join(r,c.files.LOG),""),r},async createTask(t,e,o,r){let n=this.getTaskDir(t,e);return await s.ensureDir(n),await Promise.all(Ot.map(i=>s.ensureDir(s.join(n,i)))),await B(s.join(n,c.files.MAIN),o,r),await s.write(s.join(n,c.files.LOG),""),n},async createAgent(t,e){let o=this.getAgentDir(t);return await s.ensureDir(o),await B(s.join(o,c.files.MAIN),e),o},async getProject(t){let e=s.join(this.getProjectDir(t),c.files.MAIN);return await s.fileExists(e)?await q(e):null},async getTask(t,e){let o=s.join(this.getTaskDir(t,e),c.files.MAIN);return await s.fileExists(o)?await q(o):null},async getAgent(t){let e=s.join(this.getAgentDir(t),c.files.MAIN);return await s.fileExists(e)?await q(e):null},async updateProject(t,e){let o=s.join(this.getProjectDir(t),c.files.MAIN);return await ft(o,e)},async updateBody(t,e){let o=await s.read(t),r=et(o);if(!r)throw new Error(`No frontmatter found in ${t}`);await B(t,r.frontmatter,e);},async updateTask(t,e,o){let r=s.join(this.getTaskDir(t,e),c.files.MAIN);if((await q(r))?.status==="ongoing")throw new Error("Cannot update ongoing task. Should be done by user or update manually");return await ft(r,o)},async ingestTask(t,e){let o=this.getTaskDir(t,e),r=this.getProjectDir(t),n=[s.join(r,c.files.MAIN),s.join(o,c.files.MAIN),s.join(o,c.files.LOG)];await s.logFiles(...n);},async ingestProject(t){let e=this.getProjectDir(t),o=await this.listTasks(t),r=[s.join(e,c.files.MAIN),s.join(e,c.files.LOG),...o.map(n=>s.join(this.getTaskDir(t,n),c.files.MAIN))];await s.logFiles(...r);},async ingestFiles(t){await s.logFiles(...t);}},u=ro;});var Dt,Ct=g(()=>{k();j();x();Dt=p({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=s.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 Nt,Rt=g(()=>{k();Nt=p({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 It,Lt=g(()=>{k();x();It=p({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,name:r.name||o,status:r.status,description:r.description});}if(e.length===0){console.log("No agents found");return}console.log("Agents:"),console.log("---");for(let o of e)console.log(`${o.slug.padEnd(20)} ${o.name?.padEnd(30)||""} ${o.status||""} ${o.description||""}`);}});});var Ft,Ut=g(()=>{P();k();M();j();Ft=p({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=s.join(A.AIP_HOME,c.dirs.AGENTS,t),o=s.join(e,c.files.MAIN);if(!await s.fileExists(o))throw new Error(`Agent not found: ${t}
|
|
18
|
+
Expected at: ${o}`);console.log(e);}});});var _t,Ht=g(()=>{P();k();M();j();_t=p({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=s.join(A.AIP_HOME,c.dirs.AGENTS,t),o=s.join(e,c.files.MAIN),r=s.join(e,"SOUL.md");if(!await s.fileExists(o))throw new Error(`Agent not found: ${t}
|
|
19
|
+
Expected at: ${o}`);let i=[r,o];await s.logFiles(...i);}});});var Kt,Gt,ao,Mt,zt=g(()=>{k();Kt=t=>{let e=t.shape,o=[];for(let[r,n]of Object.entries(e)){let i=n._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=Gt(i.innerType):i.typeName==="ZodDefault"&&(a=Gt(i.innerType),m=i.defaultValue()),i.description&&(l=i.description);let d=i.typeName!=="ZodOptional"&&i.typeName!=="ZodDefault";o.push({name:r,type:a,required:d,description:l,defaultValue:m});}return o},Gt=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"},ao=(t,e,o)=>{let r=Kt(o.options),n=o.args?Kt(o.args):[],i=o.description,a=`\`${t} ${e}\``;if(i&&(a+=`: ${i}`),a+=`
|
|
20
|
+
`,r.length>0||n.length>0){let m=[];for(let d of n){let f=d.required?`<${d.name}>`:`[${d.name}]`,b=d.description||"";d.defaultValue!==void 0&&(b+=b?` (default: ${d.defaultValue})`:`(default: ${d.defaultValue})`),m.push(`\xB7 ${f}${b?": "+b:""}`);}for(let d of r){let f=d.description||"";d.defaultValue!==void 0&&(f+=f?` (default: ${d.defaultValue})`:`(default: ${d.defaultValue})`),m.push(`\xB7 --${d.name}${f?": "+f:""}`);}a+=m.join(`
|
|
21
21
|
`)+`
|
|
22
22
|
`;}return a+=`
|
|
23
|
-
`,a},
|
|
23
|
+
`,a},Mt=p({description:"Print generated CLI reference from command schemas",options:z$1.object({}),handler:async()=>{let{default:t}=await Promise.resolve().then(()=>(rt(),yt)),e="Prepend `aip` to each command\n\n",o=Object.keys(t).sort();for(let r of o){let n=t[r],i=Object.keys(n).sort();for(let a of i){let l=n[a];e+=ao(r,a,l);}}console.log(e);}});});var po,Bt,Jt=g(()=>{k();po=`# AIP Hooks
|
|
24
24
|
|
|
25
25
|
Automated scripts that run before/after project/task actions.
|
|
26
26
|
|
|
@@ -62,7 +62,7 @@ Projects can include validation scripts and hooks to enforce folder semantics:
|
|
|
62
62
|
|
|
63
63
|
- **\`hooks/pre-complete.sh\`** \u2013 Runs before task completion
|
|
64
64
|
- Validates required files exist
|
|
65
|
-
- Checks
|
|
65
|
+
- Checks log.tsv has completion entry
|
|
66
66
|
- Runs structure validation (warning only)
|
|
67
67
|
- Exit 1 blocks completion
|
|
68
68
|
|
|
@@ -112,10 +112,10 @@ if (!content.includes('description:')) {
|
|
|
112
112
|
process.exit(1)
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
// Require
|
|
116
|
-
const
|
|
117
|
-
if (!existsSync(
|
|
118
|
-
console.error('\u274C
|
|
115
|
+
// Require log update
|
|
116
|
+
const logPath = join(taskDir, config.files.LOG)
|
|
117
|
+
if (!existsSync(logPath) || readFileSync(logPath, 'utf-8').length === 0) {
|
|
118
|
+
console.error('\u274C log.tsv is empty')
|
|
119
119
|
process.exit(1)
|
|
120
120
|
}
|
|
121
121
|
\`\`\`
|
|
@@ -183,7 +183,7 @@ DEBUG=1 aip task update --status done
|
|
|
183
183
|
- Require tests before completion
|
|
184
184
|
- Check outputs exist
|
|
185
185
|
- Validate frontmatter fields
|
|
186
|
-
- Ensure
|
|
186
|
+
- Ensure log.tsv updated
|
|
187
187
|
|
|
188
188
|
### Automation
|
|
189
189
|
- Backup before changes
|
|
@@ -200,26 +200,30 @@ 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
|
-
`,
|
|
203
|
+
`,Bt=p({description:"Hook types, env vars, and patterns",options:z$1.object({}),handler:async()=>{console.log(po);}});});var O,Vt,mo,Wt,Zt=g(()=>{P();k();W();O=Object.keys(S.bin)[0],{LOG:Vt}=c.files,mo=`# Quick Start
|
|
204
204
|
|
|
205
205
|
## New Task/Project
|
|
206
206
|
|
|
207
207
|
\`\`\`bash
|
|
208
208
|
# 1. Create project (if needed)
|
|
209
|
-
${
|
|
209
|
+
${O} project create "my-project" --description "What I'm building" --body $'# Goals
|
|
210
|
+
- Build X
|
|
211
|
+
- Solve Y'
|
|
210
212
|
|
|
211
|
-
# 2. Create task
|
|
212
|
-
${
|
|
213
|
+
# 2. Create task (heredoc works too)
|
|
214
|
+
${O} task create my-project "first-task" --description "Start here" --body "$(cat <<< '# Task Details
|
|
215
|
+
- Step 1
|
|
216
|
+
- Step 2')"
|
|
213
217
|
|
|
214
218
|
# 3. Navigate to task
|
|
215
|
-
cd $(${
|
|
219
|
+
cd $(${O} task path first-task)
|
|
216
220
|
|
|
217
221
|
# 4. Start working (implicit from PWD)
|
|
218
|
-
${
|
|
222
|
+
${O} task start
|
|
219
223
|
# \u2192 sets status to in-progress, reads all context to stdout
|
|
220
224
|
|
|
221
225
|
# 5. Work session
|
|
222
|
-
# Log progress: ${
|
|
226
|
+
# Log progress: ${O} log append "API integration complete"
|
|
223
227
|
# Save: outputs/ to deliver, inputs/ for data
|
|
224
228
|
\`\`\`
|
|
225
229
|
|
|
@@ -227,27 +231,27 @@ ${A} task start
|
|
|
227
231
|
|
|
228
232
|
\`\`\`bash
|
|
229
233
|
# Find your tasks (searches all projects)
|
|
230
|
-
${
|
|
234
|
+
${O} task list
|
|
231
235
|
|
|
232
236
|
# Navigate to task
|
|
233
|
-
cd $(${
|
|
237
|
+
cd $(${O} task path task-slug)
|
|
234
238
|
|
|
235
239
|
# All commands work implicitly from PWD:
|
|
236
|
-
${
|
|
240
|
+
${O} task start # Start working (sets status to in-progress, reads all context to stdout)
|
|
237
241
|
\`\`\`
|
|
238
242
|
|
|
239
243
|
## Completing
|
|
240
244
|
|
|
241
245
|
\`\`\`bash
|
|
242
246
|
# Mark done (implicit from PWD)
|
|
243
|
-
${
|
|
244
|
-
${
|
|
247
|
+
${O} task update --status done
|
|
248
|
+
${O} log append "if you want to log something extra"
|
|
245
249
|
\`\`\`
|
|
246
250
|
|
|
247
251
|
## Check current task
|
|
248
252
|
|
|
249
253
|
\`\`\`bash
|
|
250
|
-
${
|
|
254
|
+
${O} task current
|
|
251
255
|
\`\`\`
|
|
252
256
|
|
|
253
257
|
**Note:** All task commands accept an optional task slug, but use PWD if not provided. Navigate with \`cd\` first for smoother workflow.
|
|
@@ -256,20 +260,18 @@ ${A} task current
|
|
|
256
260
|
|
|
257
261
|
\`\`\`
|
|
258
262
|
$AIP_HOME/projects/slug/
|
|
259
|
-
\u251C\u2500\u2500 main.md #
|
|
260
|
-
\u251C\u2500\u2500
|
|
263
|
+
\u251C\u2500\u2500 main.md # Definition + body
|
|
264
|
+
\u251C\u2500\u2500 ${Vt} # Log (auto-appended, has key task updates too)
|
|
261
265
|
\u2514\u2500\u2500 tasks/task/
|
|
262
|
-
\u251C\u2500\u2500 main.md # Task definition
|
|
263
|
-
\u2514\u2500\u2500
|
|
266
|
+
\u251C\u2500\u2500 main.md # Task definition + body
|
|
267
|
+
\u2514\u2500\u2500 ${Vt} # Updates
|
|
264
268
|
\`\`\`
|
|
265
269
|
|
|
266
|
-
**
|
|
270
|
+
**Log format:** TSV with columns: date, time, entityType, slug, action, text
|
|
267
271
|
**Example:** \`2026-03-30<TAB>14:30:00<TAB>task<TAB>api-integration<TAB>log<TAB>API integration complete\`
|
|
268
272
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
Run \`${A} help usage\` for all commands.
|
|
272
|
-
`,Jt=p({description:"Quick start guide for new users",options:z$1.object({}),handler:async()=>{console.log(po);}});});var lo,mo,uo,fo,go,ko,ho,Vt,Zt,G,ht,qt,Yt=f(()=>{B();$();g();x();lo=Object.values(M).join("|"),{PROJECTS:mo,TASKS:uo,HOOKS:fo,INPUTS:go,OUTPUTS:ko,SCRIPTS:ho}=c.dirs,{MAIN:Vt,STATUS:Zt}=c.files,G=Object.keys(b.bin)[0],ht=`# AIP - Project Management Skill
|
|
273
|
+
Run \`${O} help usage\` for all commands.
|
|
274
|
+
`,Wt=p({description:"Quick start guide for new users",options:z$1.object({}),handler:async()=>{console.log(mo);}});});var uo,go,fo,ko,ho,yo,jo,Yt,jt,R,Tt,Qt,Xt=g(()=>{W();P();k();x();uo=Object.values(J).join("|"),{PROJECTS:go,TASKS:fo,HOOKS:ko,INPUTS:ho,OUTPUTS:yo,SCRIPTS:jo}=c.dirs,{MAIN:Yt,LOG:jt}=c.files,R=Object.keys(S.bin)[0],Tt=`# AIP - Project Management Skill
|
|
273
275
|
|
|
274
276
|
Automated project and task creation with proper structure, front-matter, and file organization.
|
|
275
277
|
|
|
@@ -279,25 +281,25 @@ Streamline creation of new projects and tasks with the correct directory structu
|
|
|
279
281
|
|
|
280
282
|
## Quick Start
|
|
281
283
|
|
|
282
|
-
- New user? Run: \`${
|
|
283
|
-
- All commands? Run: \`${
|
|
284
|
-
- Just for one noun? Run: \`${
|
|
285
|
-
- Need EVERYTHING (big)? Run: \`${
|
|
284
|
+
- New user? Run: \`${R} help quickstart\`
|
|
285
|
+
- All commands? Run: \`${R} help usage\`
|
|
286
|
+
- Just for one noun? Run: \`${R} help usage <noun>\` (e.g., \`${R} help usage task\`)
|
|
287
|
+
- Need EVERYTHING (big)? Run: \`${R} help api\` - Shows all commands with full option details
|
|
286
288
|
|
|
287
289
|
## File Structure Overview
|
|
288
290
|
|
|
289
291
|
\`\`\`
|
|
290
|
-
$AIP_HOME/${
|
|
291
|
-
\u251C\u2500\u2500 ${
|
|
292
|
-
\u251C\u2500\u2500 ${
|
|
293
|
-
\u251C\u2500\u2500 ${
|
|
294
|
-
\u251C\u2500\u2500 ${
|
|
295
|
-
\u251C\u2500\u2500 ${
|
|
296
|
-
\u251C\u2500\u2500 ${
|
|
297
|
-
\u2514\u2500\u2500 ${
|
|
292
|
+
$AIP_HOME/${go}/{project-slug}/
|
|
293
|
+
\u251C\u2500\u2500 ${Yt} # Goals + body (YAML frontmatter + markdown content)
|
|
294
|
+
\u251C\u2500\u2500 ${jt} # Chronological log (TSV: date, time, entityType, slug, action, text)
|
|
295
|
+
\u251C\u2500\u2500 ${ko}/ # pre|post-{create,start,update,complete}.*
|
|
296
|
+
\u251C\u2500\u2500 ${yo}/ # Deliverables
|
|
297
|
+
\u251C\u2500\u2500 ${ho}/ # External data
|
|
298
|
+
\u251C\u2500\u2500 ${jo}/ # Automation
|
|
299
|
+
\u2514\u2500\u2500 ${fo}/
|
|
298
300
|
\u2514\u2500\u2500 {task-slug}/
|
|
299
|
-
\u251C\u2500\u2500 ${
|
|
300
|
-
\u251C\u2500\u2500 ${
|
|
301
|
+
\u251C\u2500\u2500 ${Yt} # Task definition + body
|
|
302
|
+
\u251C\u2500\u2500 ${jt} # Activity log
|
|
301
303
|
\u2514\u2500\u2500 ... (same structure)
|
|
302
304
|
\`\`\`
|
|
303
305
|
|
|
@@ -308,11 +310,28 @@ $AIP_HOME/${mo}/{project-slug}/
|
|
|
308
310
|
name: Clear Title
|
|
309
311
|
description: One-line summary
|
|
310
312
|
assignee: agent-name
|
|
311
|
-
status: ${
|
|
313
|
+
status: ${uo}
|
|
312
314
|
created: YYYY-MM-DD
|
|
313
315
|
---
|
|
314
316
|
\`\`\`
|
|
315
317
|
|
|
318
|
+
## Body/Content
|
|
319
|
+
|
|
320
|
+
Markdown after frontmatter. Add via CLI:
|
|
321
|
+
|
|
322
|
+
\`\`\`bash
|
|
323
|
+
# Using heredoc (multi-line)
|
|
324
|
+
${R} project create "my-project" --description "..." --body "$(cat <<'EOF'
|
|
325
|
+
# Goals
|
|
326
|
+
- Build X
|
|
327
|
+
- Solve Y
|
|
328
|
+
EOF
|
|
329
|
+
)"
|
|
330
|
+
|
|
331
|
+
# Update/replace body
|
|
332
|
+
${R} project update --body "$(cat new-content.md)"
|
|
333
|
+
\`\`\`
|
|
334
|
+
|
|
316
335
|
## Best Practices
|
|
317
336
|
|
|
318
337
|
**DO:** Concise status entries, update every session, save deliverables to outputs/
|
|
@@ -322,25 +341,25 @@ created: YYYY-MM-DD
|
|
|
322
341
|
|
|
323
342
|
When working on a task:
|
|
324
343
|
1. Read \`main.md\` first (goals/context)
|
|
325
|
-
2. Review \`
|
|
344
|
+
2. Review \`${jt}\` (activity history)
|
|
326
345
|
3. Work and save outputs to \`outputs/\`
|
|
327
|
-
4. Log progress: \`${
|
|
346
|
+
4. Log progress: \`${R} log append "message"\`
|
|
328
347
|
5. On completion: set status=\`done\`, log summary
|
|
329
|
-
`,
|
|
348
|
+
`,Qt=p({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(S.bin)[0];if(t.mode==="md"){console.log(Tt);return}if(t.mode==="claude"){console.log(`---
|
|
330
349
|
name: ${e}
|
|
331
|
-
description: ${
|
|
332
|
-
---`),console.log(),console.log(
|
|
350
|
+
description: ${S.description}
|
|
351
|
+
---`),console.log(),console.log(Tt);return}if(t.mode==="hermes"){console.log(`---
|
|
333
352
|
name: ${e}
|
|
334
|
-
description: ${
|
|
335
|
-
version: ${
|
|
336
|
-
author: ${
|
|
337
|
-
license: ${
|
|
353
|
+
description: ${S.description}
|
|
354
|
+
version: ${S.version}
|
|
355
|
+
author: ${S.author}
|
|
356
|
+
license: ${S.license}
|
|
338
357
|
metadata:
|
|
339
358
|
hermes:
|
|
340
|
-
tags: [${
|
|
341
|
-
---`),console.log(),console.log(
|
|
342
|
-
`)),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
|
|
343
|
-
`)},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
|
|
359
|
+
tags: [${S.keywords.join(", ")}]
|
|
360
|
+
---`),console.log(),console.log(Tt);return}}});});var te,ee=g(()=>{W();k();j();te=p({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(()=>(rt(),yt)),o=`${S.name} ${S.version} -`,r=s.dumpCommandMapLines(e,t);if(!t)console.log(o,"Usage: aip <noun> <verb> [options]"),console.log(r.map(n=>`-> ${n}`).join(`
|
|
361
|
+
`)),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 n=r[0]??`${t} {?}`;console.log(o,`Usage: aip ${n} [options]`);}}});});var bt,To,h,D=g(()=>{P();j();bt=s.joinHome(c.dirs.PROJECTS),To={getProjectFromPwd(t=process.cwd()){let e=G.relative(bt,t);if(!e||e.startsWith(".."))return null;let o=e.split(G.sep).filter(Boolean);return o.length===0?null:o[0]},getTaskFromPwd(t=process.cwd()){let e=G.relative(bt,t);if(!e||e.startsWith(".."))return null;let o=e.split(G.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: ${bt}`);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(`
|
|
362
|
+
`)},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 n=s.joinHome(c.dirs.PROJECTS,r);return {targetDir:n,projectDir:n,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=s.joinHome(c.dirs.PROJECTS,o.project);return {targetDir:s.join(r,c.dirs.TASKS,o.task),projectDir:r,entityType:"task"}}if(o.task&&o.project){let r=s.joinHome(c.dirs.PROJECTS,o.project);return {targetDir:s.join(r,c.dirs.TASKS,o.task),projectDir:r,entityType:"task"}}if(o.project){let r=s.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=To;});var oe,re=g(()=>{k();j();D();P();oe=p({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,n=`.${r}`,{targetDir:i,entityType:a}=h.getTargetDir(o),l=s.join(i,c.dirs.HOOKS);await s.ensureDir(l);let m=s.join(l,`${t}${n}`);if(await s.fileExists(m))throw new Error(`Hook already exists: ${m}`);let f;if(r==="ts")f=`#!/usr/bin/env tsx
|
|
344
363
|
/** ${t} hook for ${a} */
|
|
345
364
|
|
|
346
365
|
import { env } from 'node:process'
|
|
@@ -353,7 +372,7 @@ if (env.TASK_SLUG) {
|
|
|
353
372
|
|
|
354
373
|
// Exit with non-zero to prevent action (for pre-hooks)
|
|
355
374
|
// process.exit(1)
|
|
356
|
-
`;else if(r==="js")
|
|
375
|
+
`;else if(r==="js")f=`#!/usr/bin/env node
|
|
357
376
|
/** ${t} hook for ${a} */
|
|
358
377
|
|
|
359
378
|
console.log('Running ${t} hook for ${a}')
|
|
@@ -364,7 +383,7 @@ if (process.env.TASK_SLUG) {
|
|
|
364
383
|
|
|
365
384
|
// Exit with non-zero to prevent action (for pre-hooks)
|
|
366
385
|
// process.exit(1)
|
|
367
|
-
`;else if(r==="sh")
|
|
386
|
+
`;else if(r==="sh")f=`#!/bin/bash
|
|
368
387
|
# ${t} hook for ${a}
|
|
369
388
|
|
|
370
389
|
echo "Running ${t} hook for ${a}"
|
|
@@ -375,7 +394,7 @@ fi
|
|
|
375
394
|
|
|
376
395
|
# Exit with non-zero to prevent action (for pre-hooks)
|
|
377
396
|
# exit 1
|
|
378
|
-
`;else if(r==="py")
|
|
397
|
+
`;else if(r==="py")f=`#!/usr/bin/env python3
|
|
379
398
|
"""${t} hook for ${a}"""
|
|
380
399
|
|
|
381
400
|
import os
|
|
@@ -387,13 +406,13 @@ if os.environ.get('TASK_SLUG'):
|
|
|
387
406
|
|
|
388
407
|
# Exit with non-zero to prevent action (for pre-hooks)
|
|
389
408
|
# sys.exit(1)
|
|
390
|
-
`;else throw new Error(`Unsupported language: ${r}`);await
|
|
391
|
-
`},async
|
|
392
|
-
Expected at: ${o}`);await
|
|
393
|
-
${d}:`),console.log("---");for(let
|
|
394
|
-
`).filter(m=>m.
|
|
395
|
-
=== Post-Mortem Analysis ===`),console.log(`Project: ${t}`),console.log(`Task: ${e}`),console.log(`Name: ${l}`),console.log(`Status: ${r?.status||"unknown"}`),console.log(`
|
|
409
|
+
`;else throw new Error(`Unsupported language: ${r}`);await s.write(m,f);let{chmod:b}=await import('fs/promises');await b(m,493),console.log(`Hook created: ${m}`);}});});var bo,$,V=g(()=>{P();j();bo={async findHooks(t,e){let o=s.join(t,c.dirs.HOOKS);if(!await s.fileExists(o))return [];let n=await s.listDir(o),i=`${e}.`;return n.filter(a=>a.startsWith(i)).map(a=>s.join(o,a))},async executeHook(t,e,o){if(!await s.fileExists(t))return true;let n=e.project?s.joinHome(c.dirs.PROJECTS,e.project):o,i=e.task?s.join(n,c.dirs.TASKS,e.task):"",a={...process.env,HOOK_TYPE:e.action,ENTITY_TYPE:e.entityType,TARGET_DIR:o,PROJECT_DIR:n,...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:G.dirname(t),shell:false});m.on("close",(d,f)=>{d===0?l(true):(console.error(`Hook ${G.basename(t)} failed (code=${d??f})`),l(false));}),m.on("error",d=>{console.error(`Failed to execute hook ${t}: ${d.message}`),l(false);});})},async runHooks(t,e,o){let r=await this.findHooks(t,e),n=e.startsWith("pre-");for(let i of r)if(!await this.executeHook(i,o,t)&&n)return false;return true},async runHooksForContext(t,e,o,r){return !(!await this.runHooks(t,o,r)||e&&!await this.runHooks(e,o,r))}},$=bo;});var ne,ie=g(()=>{k();V();D();P();ne=p({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),n={action:t,entityType:r,project:h.getProjectFromPwd()||void 0,task:h.getTaskFromPwd()||void 0};await $.runHooks(o,t,n)||(console.error(`Hook ${t} failed`),process.exit(1)),console.log(`Hook ${t} completed successfully`);}});});var Po,T,I=g(()=>{P();D();j();Po={formatEntry(t,e,o,r){let n=new Date,i=n.getFullYear(),a=String(n.getMonth()+1).padStart(2,"0"),l=String(n.getDate()).padStart(2,"0"),m=n.toLocaleTimeString("en-US",{hour12:false,hour:"2-digit",minute:"2-digit",second:"2-digit"});return `${`${i}-${a}-${l}`} ${m} ${t} ${e} ${o} ${r}
|
|
410
|
+
`},async append(t,e,o,r,n){let i=s.join(t,c.files.LOG),a=this.formatEntry(e,o,r,n);await s.append(i,a);},async read(t){let e=s.join(t,c.files.LOG);return await s.fileExists(e)?await s.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 n=s.joinHome(c.dirs.PROJECTS,r.project,c.dirs.TASKS,r.task);await this.append(n,"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 n=s.joinHome(c.dirs.PROJECTS,r);await this.append(n,"project",t,"log",o?`${o}: ${e}`:e);}},T=Po;});var ae,ce=g(()=>{P();D();k();j();I();ae=p({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(),n=t||r.project;if(!n)throw new Error("No project specified. Use --project or run from a project/task directory");let i=s.joinHome(c.dirs.PROJECTS,n);if(e||r.task){let a=e||r.task;if(!a)throw new Error("No task specified");let l=s.join(i,c.dirs.TASKS,a);await T.append(l,"task",a,"log",o),console.log(`Appended to task ${a} log.tsv`);}else await T.append(i,"project",n,"log",o),console.log(`Appended to project ${n} log.tsv`);}});});var pe,le=g(()=>{P();D();k();j();I();pe=p({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 n=s.joinHome(c.dirs.PROJECTS,r);if(e||o.task){let i=e||o.task;if(!i)throw new Error("No task specified");let a=s.join(n,c.dirs.TASKS,i),l=await T.read(a);console.log(l||`No log.tsv found for task ${i}`);}else {let i=await T.read(n);console.log(i||`No log.tsv found for project ${r}`);}}});});var me,de=g(()=>{k();V();j();x();I();me=p({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:n})=>{let i=s.slugify(t),a=u.getProjectDir(i);if(!await $.runHooks(a,"pre-create",{action:"pre-create",entityType:"project"}))throw new Error("Pre-create hook failed, aborting project creation");await u.createProject(i,{name:t,description:e,status:o,assignee:r,created:new Date().toISOString()},n),await T.append(a,"project",i,"created",`${t} > status is ${o}`),await $.runHooks(a,"post-create",{action:"post-create",entityType:"project"}),console.log(`Project created: ${i}`),console.log(` Path: ${a}`);}});});var ue,ge=g(()=>{k();D();ue=p({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 ke,he=g(()=>{k();x();ke=p({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 n=await u.getProject(r);n&&(t&&n.status!==t||o.push({slug:r,name:n.name||r,status:n.status,assignee:n.assignee}));}if(o.length===0){console.log("No projects found");return}console.log("Projects:"),console.log("---");for(let r of o)console.log(`${r.slug.padEnd(20)} ${r.name?.padEnd(30)||""} ${r.status||""} ${r.assignee||""}`);}});});var ye,je=g(()=>{k();x();ye=p({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 Te,we=g(()=>{P();D();k();V();j();x();I();Te=p({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:n,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=s.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 f={};if(e&&(f.name=e),o&&(f.description=o),r&&(f.status=r),n&&(f.assignee=n),Object.keys(f).length===0&&!i){console.log("No updates provided");return}if(Object.keys(f).length>0){await u.updateProject(a,f);let b=Object.entries(f).map(([C,E])=>`${C}=${E}`).join(", ");await T.append(l,"project",a,"updated",b);}i!==void 0&&(await u.updateBody(m,i),await T.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 be,Pe=g(()=>{P();k();M();j();be=p({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=s.join(A.AIP_HOME,c.dirs.SKILLS,t),o=s.join(e,c.files.SKILL);if(!await s.fileExists(o))throw new Error(`Skill not found: ${t}
|
|
411
|
+
Expected at: ${o}`);await s.logFiles(o);}});});var Se,xe=g(()=>{k();V();j();x();I();Se=p({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:n,body:i})=>{let a=s.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:n,created:new Date().toISOString()},i),await T.append(m,"task",a,"created",e),await T.append(l,"task",a,"created",`${a} > status is ${n}`),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 $e,ve=g(()=>{k();D();$e=p({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,Ae=g(()=>{D();k();x();Ee=p({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("Need task slug (or cd into task dir)");let{project:n}=await u.findTask(r,t);await u.ingestTask(n,r);}});});var Oe,De=g(()=>{k();x();Oe=p({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 or name, case-insensitive)")}),handler:async({project:t,statuses:e,assignee:o,all:r,search:n})=>{if(e&&e.length>0){for(let d of e)if(!ot.includes(d))throw new Error(`Invalid status: ${d}. Valid values: ${ot.join(", ")}`)}let i;e&&e.length>0?i=e:r?i=ot:i=At;let a=t?[t]:await u.listProjects(),l={};for(let d of a){let f=await u.listTasks(d),b=[];for(let C of f){let E=await u.getTask(d,C);if(E&&!(i.length>0&&!i.includes(E.status||""))&&!(o&&E.assignee!==o)){if(n){let v=n.toLowerCase(),dt=C.toLowerCase().includes(v),ut=(E.name||"").toLowerCase().includes(v);if(!dt&&!ut)continue}b.push({slug:C,name:E.name||C,status:E.status,assignee:E.assignee});}}b.length>0&&(l[d]=b.sort((C,E)=>C.slug.localeCompare(E.slug)));}let m=Object.keys(l).sort();if(m.length===0){console.log("No tasks found");return}for(let d of m){console.log(`
|
|
412
|
+
${d}:`),console.log("---");for(let f of l[d])console.log(`${f.slug.padEnd(20)} ${f.name?.padEnd(30)||""} ${f.status||""} ${f.assignee||""}`);}}});});var Ce,Ne=g(()=>{k();x();Ce=p({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),n=u.getTaskDir(o,r);console.log(n);}});});var pt,xt=g(()=>{P();D();k();V();j();x();I();pt=p({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)")}),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:n,assignee:i,body:a})=>{let l=h.getCurrentContext(),m=e??l.task;if(!m)throw new Error("No task specified (use --task or cd into task dir)");let{project:d}=await u.findTask(m,t),f=u.getTaskDir(d,m),b=u.getProjectDir(d),C=s.join(f,c.files.MAIN);if(!await $.runHooksForContext(b,f,"pre-update",{action:"pre-update",entityType:"task",project:d,task:m}))throw new Error("Pre-update hook failed, aborting update");let v={};if(o&&(v.name=o),r&&(v.description=r),n&&(v.status=n),i&&(v.assignee=i),Object.keys(v).length===0&&!a){console.log("No updates provided");return}if(Object.keys(v).length>0){await u.updateTask(d,m,v);let dt=Object.entries(v).map(([ut,Ke])=>`${ut}=${Ke}`).join(", ");await T.append(f,"task",m,"updated",dt);}a!==void 0&&(await u.updateBody(C,a),await T.append(f,"task",m,"updated",`body replaced (${a.length} chars)`)),v.status&&await T.append(b,"task",m,"updated",`status to ${v.status}`),await $.runHooksForContext(u.getProjectDir(d),f,"post-update",{action:"post-update",entityType:"task",project:d,task:m}),console.log(`Task ${m} updated`);}});});var Re,Ie=g(()=>{D();k();x();xt();Re=p({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(false).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(),n=e??r.task;if(!n)throw new Error("No task specified (use --task or cd into task dir)");let{project:i}=await u.findTask(n,t);(await u.getTask(i,n))?.status!=="in-progress"&&await pt.handler({project:i,task:n,status:"in-progress"}),o&&await u.ingestTask(i,n);}});});var Le,Fe=g(()=>{k();x();I();Le=p({description:"Post-mortem analysis for a completed task",options:z$1.object({}),args:z$1.object({project:z$1.string().describe("Project slug"),task:z$1.string().describe("Task slug")}),handler:async({project:t,task:e})=>{let o=u.getTaskDir(t,e),r=await u.getTask(t,e),i=(await T.read(o)).split(`
|
|
413
|
+
`).filter(m=>m.trim()).length,a=[],l=r?.name||e;i>5&&a.push("High log entry count - consider breaking into smaller tasks"),l.toLowerCase().includes("implement")&&a.push("Implementation task - check if similar patterns exist to reuse"),l.toLowerCase().includes("create")&&l.toLowerCase().includes("command")&&a.push("Command creation - check existing command patterns in src/commands/"),console.log(`
|
|
414
|
+
=== Post-Mortem Analysis ===`),console.log(`Project: ${t}`),console.log(`Task: ${e}`),console.log(`Name: ${l}`),console.log(`Status: ${r?.status||"unknown"}`),console.log(`Log entries: ${i}`),a.length>0?(console.log(`
|
|
396
415
|
Suggestions:`),a.forEach(m=>console.log(` - ${m}`))):console.log(`
|
|
397
416
|
No specific suggestions - task looks well-scoped`),console.log(`
|
|
398
417
|
=== End Post-Mortem ===
|
|
399
|
-
`);}});});var Ue,_e=
|
|
418
|
+
`);}});});var Ue,_e=g(()=>{k();j();Ue=p({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 s.logFiles(...t);}});});var yt={};Me(yt,{default:()=>K});var $o,K,rt=g(()=>{Ct();Rt();Lt();Ut();Ht();zt();Jt();Zt();Xt();ee();re();ie();ce();le();de();ge();he();je();we();Pe();xe();ve();Ae();De();Ne();Ie();xt();Fe();_e();$o={agent:{create:Dt,current:Nt,list:It,path:Ft,start:_t},help:{api:Mt,hooks:Bt,quickstart:Wt,skill:Qt,usage:te},hook:{create:oe,run:ne},log:{append:ae,read:pe},project:{create:me,current:ue,list:ke,path:ye,update:Te},skill:{read:be},task:{create:Se,current:$e,ingest:Ee,list:Oe,path:Ce,start:Re,update:pt},util:{postmortem:Le,read:Ue}},K=$o;});W();rt();j();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 He(t){let[e,o,...r]=t;(e==="--version"||e==="-v")&&(console.log(S.version),process.exit(0));try{(!e||!s.isKeyOf(e,K))&&(await K.help.usage.handler({}),process.exit(1));let n=K[e];(!o||!s.isKeyOf(o,n))&&(await K.help.usage.handler({name:e}),process.exit(1));let i=n[o];i||(console.error(`Error: unknown command '${e} ${o}'`),console.log("Run with --help for more information"),process.exit(1)),await i.handler(i.parser.name(`${e} ${o}`).parse(r));}catch(n){console.error("Error:",s.errorMessage(n)),process.exit(1);}}var Hi=He,Ki=K;s.isMain()&&He(process.argv.slice(2));export{Ki as commands,Hi as default};
|