pi-gsd 2.0.4 → 2.0.6
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/.gsd/harnesses/pi/get-shit-done/workflows/add-phase.md +1 -1
- package/.gsd/harnesses/pi/get-shit-done/workflows/add-tests.md +1 -1
- package/.gsd/harnesses/pi/get-shit-done/workflows/add-todo.md +1 -1
- package/.gsd/harnesses/pi/get-shit-done/workflows/audit-milestone.md +1 -1
- package/.gsd/harnesses/pi/get-shit-done/workflows/autonomous.md +6 -6
- package/.gsd/harnesses/pi/get-shit-done/workflows/check-todos.md +1 -1
- package/.gsd/harnesses/pi/get-shit-done/workflows/complete-milestone.md +2 -2
- package/.gsd/harnesses/pi/get-shit-done/workflows/discuss-phase-assumptions.md +1 -1
- package/.gsd/harnesses/pi/get-shit-done/workflows/discuss-phase.md +1 -1
- package/.gsd/harnesses/pi/get-shit-done/workflows/do.md +1 -1
- package/.gsd/harnesses/pi/get-shit-done/workflows/execute-milestone.md +38 -38
- package/.gsd/harnesses/pi/get-shit-done/workflows/execute-plan.md +1 -1
- package/.gsd/harnesses/pi/get-shit-done/workflows/insert-phase.md +1 -1
- package/.gsd/harnesses/pi/get-shit-done/workflows/list-workspaces.md +1 -1
- package/.gsd/harnesses/pi/get-shit-done/workflows/manager.md +2 -2
- package/.gsd/harnesses/pi/get-shit-done/workflows/map-codebase.md +1 -1
- package/.gsd/harnesses/pi/get-shit-done/workflows/milestone-summary.md +1 -1
- package/.gsd/harnesses/pi/get-shit-done/workflows/new-milestone.md +1 -1
- package/.gsd/harnesses/pi/get-shit-done/workflows/new-project.md +1 -1
- package/.gsd/harnesses/pi/get-shit-done/workflows/new-workspace.md +1 -1
- package/.gsd/harnesses/pi/get-shit-done/workflows/pause-work.md +1 -1
- package/.gsd/harnesses/pi/get-shit-done/workflows/plan-milestone.md +8 -8
- package/.gsd/harnesses/pi/get-shit-done/workflows/progress.md +1 -1
- package/.gsd/harnesses/pi/get-shit-done/workflows/quick.md +1 -1
- package/.gsd/harnesses/pi/get-shit-done/workflows/remove-phase.md +1 -1
- package/.gsd/harnesses/pi/get-shit-done/workflows/remove-workspace.md +1 -1
- package/.gsd/harnesses/pi/get-shit-done/workflows/research-phase.md +1 -1
- package/.gsd/harnesses/pi/get-shit-done/workflows/resume-project.md +1 -1
- package/.gsd/harnesses/pi/get-shit-done/workflows/review.md +1 -1
- package/.gsd/harnesses/pi/get-shit-done/workflows/settings.md +1 -1
- package/.gsd/harnesses/pi/get-shit-done/workflows/ship.md +1 -1
- package/.gsd/harnesses/pi/get-shit-done/workflows/ui-phase.md +1 -1
- package/.gsd/harnesses/pi/get-shit-done/workflows/ui-review.md +1 -1
- package/.gsd/harnesses/pi/get-shit-done/workflows/validate-phase.md +1 -1
- package/.gsd/harnesses/pi/get-shit-done/workflows/verify-phase.md +1 -1
- package/.gsd/harnesses/pi/get-shit-done/workflows/verify-work.md +1 -1
- package/README.md +60 -60
- package/dist/pi-gsd-hooks.js +4 -4
- package/dist/pi-gsd-tools.js +2 -2
- package/package.json +1 -1
- package/prompts/gsd-discuss-phase.md +1 -1
- package/prompts/gsd-execute-phase.md +1 -1
- package/prompts/gsd-plan-phase.md +1 -1
- package/prompts/gsd-quick.md +1 -1
- package/prompts/gsd-verify-work.md +1 -1
- package/scripts/postinstall.js +323 -323
|
@@ -105,7 +105,7 @@ Then verify each level against the actual codebase.
|
|
|
105
105
|
<step name="load_context" priority="first">
|
|
106
106
|
Load phase operation context:
|
|
107
107
|
|
|
108
|
-
<!-- Context pre-injected above via WXP
|
|
108
|
+
<!-- Context pre-injected above via WXP - variables available via <gsd-paste name="..."> -->
|
|
109
109
|
|
|
110
110
|
Extract from init JSON: `phase_dir`, `phase_number`, `phase_name`, `has_plans`, `plan_count`.
|
|
111
111
|
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
<step name="initialize" priority="first">
|
|
91
91
|
If $ARGUMENTS contains a phase number, load context:
|
|
92
92
|
|
|
93
|
-
<!-- Context pre-injected above via WXP
|
|
93
|
+
<!-- Context pre-injected above via WXP - variables available via <gsd-paste name="..."> -->
|
|
94
94
|
|
|
95
95
|
Parse JSON for: `planner_model`, `checker_model`, `commit_docs`, `phase_found`, `phase_dir`, `phase_number`, `phase_name`, `has_verification`, `uat_path`.
|
|
96
96
|
</step>
|
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
[](https://www.npmjs.com/package/pi-gsd)
|
|
6
6
|
[](LICENSE)
|
|
7
7
|
|
|
8
|
-
GSD is a structured software-delivery framework for AI coding agents. It wraps any AI coding session with a six-step phase lifecycle, slash commands, specialised subagents, background hooks, and model profiles
|
|
8
|
+
GSD is a structured software-delivery framework for AI coding agents. It wraps any AI coding session with a six-step phase lifecycle, slash commands, specialised subagents, background hooks, and model profiles - all backed by a git-committed `.planning/` directory that survives context resets.
|
|
9
9
|
|
|
10
10
|
---
|
|
11
11
|
|
|
@@ -27,12 +27,12 @@ Then start your first project:
|
|
|
27
27
|
|
|
28
28
|
## What You Get
|
|
29
29
|
|
|
30
|
-
| Artifact | Count | Description
|
|
31
|
-
|
|
32
|
-
| Skills | 57 | `/gsd-*` slash commands loaded automatically
|
|
33
|
-
| CLI binary | 1 | `pi-gsd-tools`
|
|
34
|
-
| WXP engine | 1 | Pre-processor that eliminates LLM bash round-trips
|
|
35
|
-
| Workflow files | 58 | Fully WXP-converted; 49 with active data injection
|
|
30
|
+
| Artifact | Count | Description |
|
|
31
|
+
| -------------- | ----: | --------------------------------------------------- |
|
|
32
|
+
| Skills | 57 | `/gsd-*` slash commands loaded automatically |
|
|
33
|
+
| CLI binary | 1 | `pi-gsd-tools` - state, scaffolding, model routing |
|
|
34
|
+
| WXP engine | 1 | Pre-processor that eliminates LLM bash round-trips |
|
|
35
|
+
| Workflow files | 58 | Fully WXP-converted; 49 with active data injection |
|
|
36
36
|
| Hooks | 1 | TypeScript extension: context monitor, WXP pipeline |
|
|
37
37
|
|
|
38
38
|
---
|
|
@@ -49,13 +49,13 @@ Then start your first project:
|
|
|
49
49
|
└─► (next phase or /gsd-complete-milestone)
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
-
All project state lives in `.planning/`
|
|
52
|
+
All project state lives in `.planning/` - committed to git, survives `/clear` and context resets.
|
|
53
53
|
|
|
54
54
|
---
|
|
55
55
|
|
|
56
|
-
## WXP
|
|
56
|
+
## WXP - Workflow XML Preprocessor
|
|
57
57
|
|
|
58
|
-
v2.0 introduces WXP: an XML preprocessing engine that runs in the pi extension's `context` event, **before the LLM sees the message**. Workflow files embed XML directives that execute shell commands, evaluate conditions, iterate arrays, and inject the results
|
|
58
|
+
v2.0 introduces WXP: an XML preprocessing engine that runs in the pi extension's `context` event, **before the LLM sees the message**. Workflow files embed XML directives that execute shell commands, evaluate conditions, iterate arrays, and inject the results - so the LLM receives clean, data-rich context with zero bash tool calls for setup.
|
|
59
59
|
|
|
60
60
|
### What it replaces
|
|
61
61
|
|
|
@@ -102,21 +102,21 @@ Phase init data: <gsd-paste name="init" />
|
|
|
102
102
|
|
|
103
103
|
### WXP element reference
|
|
104
104
|
|
|
105
|
-
| Element
|
|
106
|
-
|
|
107
|
-
| `<gsd-arguments>`
|
|
108
|
-
| `<gsd-execute>`
|
|
109
|
-
| `<shell command="...">`
|
|
110
|
-
| `<if><condition>...<then>...<else>`
|
|
111
|
-
| `<for-each var="..." item="...">`
|
|
112
|
-
| `<json-parse src="..." path="$.key" out="...">` | Extract a scalar or array from a JSON variable
|
|
113
|
-
| `<string-op op="split">`
|
|
114
|
-
| `<read-file path="..." out="...">`
|
|
115
|
-
| `<write-file path="..." src="...">`
|
|
116
|
-
| `<display msg="..." level="info">`
|
|
117
|
-
| `<gsd-paste name="...">`
|
|
118
|
-
| `<gsd-include path="..." include-arguments>`
|
|
119
|
-
| `<gsd-version v="..." do-not-update>`
|
|
105
|
+
| Element | Purpose |
|
|
106
|
+
| ----------------------------------------------- | ----------------------------------------------------------------------------------------- |
|
|
107
|
+
| `<gsd-arguments>` | Parse `$ARGUMENTS` into typed named variables (two-pass: flags first, then positionals) |
|
|
108
|
+
| `<gsd-execute>` | Container for executable operations; removed from document after execution |
|
|
109
|
+
| `<shell command="...">` | Run an allowlisted command via `execFileSync`; `<args>/<outs>/<suppress-errors>` children |
|
|
110
|
+
| `<if><condition>...<then>...<else>` | Conditional execution with full condition expression support |
|
|
111
|
+
| `<for-each var="..." item="...">` | Iterate an array variable; optional `<where>` filter and `<sort-by>` |
|
|
112
|
+
| `<json-parse src="..." path="$.key" out="...">` | Extract a scalar or array from a JSON variable |
|
|
113
|
+
| `<string-op op="split">` | Split a variable on a delimiter; `<args>/<outs>` children |
|
|
114
|
+
| `<read-file path="..." out="...">` | Read any accessible file into a variable |
|
|
115
|
+
| `<write-file path="..." src="...">` | Create a new file from a variable (create-only, never overwrites) |
|
|
116
|
+
| `<display msg="..." level="info">` | Emit `ctx.ui.notify()` with `{varname}` interpolation; LLM never sees it |
|
|
117
|
+
| `<gsd-paste name="...">` | Inline-replace with a variable's value; undefined variable aborts processing |
|
|
118
|
+
| `<gsd-include path="..." include-arguments>` | Inject a trusted file; `include-arguments` pipes `$ARGUMENTS` into the include |
|
|
119
|
+
| `<gsd-version v="..." do-not-update>` | Version tag; `do-not-update` prevents harness auto-overwrite |
|
|
120
120
|
|
|
121
121
|
### Condition operators
|
|
122
122
|
|
|
@@ -155,18 +155,18 @@ pi-gsd-tools state json --output toon # toon renderer
|
|
|
155
155
|
pi-gsd-tools state json --pick phase # extract a field (JSONPath)
|
|
156
156
|
```
|
|
157
157
|
|
|
158
|
-
All commands are typed oclif classes
|
|
158
|
+
All commands are typed oclif classes - run `pi-gsd-tools --help` or `pi-gsd-tools <command> --help` for the full reference.
|
|
159
159
|
|
|
160
160
|
---
|
|
161
161
|
|
|
162
162
|
## Model Profiles
|
|
163
163
|
|
|
164
|
-
| Profile | Description
|
|
165
|
-
|
|
166
|
-
| `quality` | Maximum reasoning
|
|
167
|
-
| `balanced` | Default
|
|
168
|
-
| `budget` | Cheapest available model per agent
|
|
169
|
-
| `inherit` | Use the session's current model everywhere
|
|
164
|
+
| Profile | Description |
|
|
165
|
+
| ---------- | ---------------------------------------------------- |
|
|
166
|
+
| `quality` | Maximum reasoning - Opus/Pro for all decision agents |
|
|
167
|
+
| `balanced` | Default - Sonnet/Flash tier |
|
|
168
|
+
| `budget` | Cheapest available model per agent |
|
|
169
|
+
| `inherit` | Use the session's current model everywhere |
|
|
170
170
|
|
|
171
171
|
Switch: `/gsd-set-profile <profile>`
|
|
172
172
|
|
|
@@ -174,36 +174,36 @@ Switch: `/gsd-set-profile <profile>`
|
|
|
174
174
|
|
|
175
175
|
## v2.0 vs v1.x
|
|
176
176
|
|
|
177
|
-
|
|
|
178
|
-
|
|
179
|
-
| WXP preprocessing engine
|
|
180
|
-
| Zero LLM bash calls for setup
|
|
181
|
-
| `<for-each>` + `<json-parse>` loops
|
|
182
|
-
| `<display>` deterministic notifications
|
|
183
|
-
| `<read-file>` / `<write-file>`
|
|
184
|
-
| `<and>` / `<or>` condition nesting
|
|
185
|
-
| Typed oclif CLI (was commander.js)
|
|
186
|
-
| Zero `any` in codebase
|
|
187
|
-
| `YamlValue` recursive frontmatter types
|
|
188
|
-
| Copy-on-first-run harness (was symlinks) |
|
|
189
|
-
| Correct `_auto_chain_active` lifecycle
|
|
190
|
-
| 116 vitest tests
|
|
177
|
+
| | v1.x | v2.0 |
|
|
178
|
+
| ---------------------------------------- | :---: | :---: |
|
|
179
|
+
| WXP preprocessing engine | ❌ | ✅ |
|
|
180
|
+
| Zero LLM bash calls for setup | ❌ | ✅ |
|
|
181
|
+
| `<for-each>` + `<json-parse>` loops | ❌ | ✅ |
|
|
182
|
+
| `<display>` deterministic notifications | ❌ | ✅ |
|
|
183
|
+
| `<read-file>` / `<write-file>` | ❌ | ✅ |
|
|
184
|
+
| `<and>` / `<or>` condition nesting | ❌ | ✅ |
|
|
185
|
+
| Typed oclif CLI (was commander.js) | ❌ | ✅ |
|
|
186
|
+
| Zero `any` in codebase | ❌ | ✅ |
|
|
187
|
+
| `YamlValue` recursive frontmatter types | ❌ | ✅ |
|
|
188
|
+
| Copy-on-first-run harness (was symlinks) | ❌ | ✅ |
|
|
189
|
+
| Correct `_auto_chain_active` lifecycle | ❌ | ✅ |
|
|
190
|
+
| 116 vitest tests | ❌ | ✅ |
|
|
191
191
|
|
|
192
192
|
## v1.x vs GSD v1.30.0
|
|
193
193
|
|
|
194
|
-
|
|
|
195
|
-
|
|
196
|
-
|
|
|
197
|
-
|
|
|
198
|
-
|
|
|
199
|
-
|
|
|
200
|
-
|
|
|
201
|
-
|
|
|
202
|
-
|
|
|
203
|
-
|
|
|
204
|
-
| `<gsd-include>` context injection |
|
|
205
|
-
|
|
|
206
|
-
|
|
|
194
|
+
| Feature | gsd v1.30 | pi-gsd |
|
|
195
|
+
| --------------------------------: | :-------: | :----: |
|
|
196
|
+
| `.planning/` data format | ✔️ | ✔️ |
|
|
197
|
+
| Workstreams | ✔️ | ✔️ |
|
|
198
|
+
| 4 model profiles | ✔️ | ✔️ |
|
|
199
|
+
| 18 subagents | ✔️ | ✔️ |
|
|
200
|
+
| 57 GSD skills | ✔️ | ✔️ |
|
|
201
|
+
| pi harness (`.pi/`) | ❌ | ✔️ |
|
|
202
|
+
| Background hooks | ❌ | ✔️ |
|
|
203
|
+
| Instant commands (no LLM) | ❌ | ✔️ |
|
|
204
|
+
| `<gsd-include>` context injection | ❌ | ✔️ |
|
|
205
|
+
| TypeScript source | ❌ | ✔️ |
|
|
206
|
+
| Runtime validation (Zod) | ❌ | ✔️ |
|
|
207
207
|
|
|
208
208
|
---
|
|
209
209
|
|
|
@@ -222,4 +222,4 @@ node scripts/validate-model-profiles.cjs
|
|
|
222
222
|
|
|
223
223
|
## License
|
|
224
224
|
|
|
225
|
-
MIT
|
|
225
|
+
MIT - unofficial port. Original GSD by [Get Shit Done](https://github.com/gsd-build/get-shit-done).
|
package/dist/pi-gsd-hooks.js
CHANGED
|
@@ -935,7 +935,7 @@ function pi_gsd_hooks_default(pi) {
|
|
|
935
935
|
return null;
|
|
936
936
|
}
|
|
937
937
|
if (parts.length > 1 && parts.some((p) => p.trim().startsWith("lines:"))) {
|
|
938
|
-
errors.push("lines: cannot be chained
|
|
938
|
+
errors.push("lines: cannot be chained - use it alone: " + selectExpr);
|
|
939
939
|
return null;
|
|
940
940
|
}
|
|
941
941
|
for (const part of parts) {
|
|
@@ -1420,13 +1420,13 @@ Run: pi-gsd-tools harness update [y|n|pick|diff]`,
|
|
|
1420
1420
|
let reason;
|
|
1421
1421
|
if (next.plans === 0) {
|
|
1422
1422
|
action = `/gsd-discuss-phase ${n}`;
|
|
1423
|
-
reason = `Phase ${n} has no plans yet
|
|
1423
|
+
reason = `Phase ${n} has no plans yet - start with discussion`;
|
|
1424
1424
|
} else if (next.summaries < next.plans) {
|
|
1425
1425
|
action = `/gsd-execute-phase ${n}`;
|
|
1426
|
-
reason = `Phase ${n}: ${next.summaries}/${next.plans} plans done
|
|
1426
|
+
reason = `Phase ${n}: ${next.summaries}/${next.plans} plans done - continue execution`;
|
|
1427
1427
|
} else {
|
|
1428
1428
|
action = `/gsd-verify-work ${n}`;
|
|
1429
|
-
reason = `Phase ${n}: all plans done
|
|
1429
|
+
reason = `Phase ${n}: all plans done - verify UAT`;
|
|
1430
1430
|
}
|
|
1431
1431
|
ctx.ui.notify(
|
|
1432
1432
|
[
|
package/dist/pi-gsd-tools.js
CHANGED
|
@@ -221,7 +221,7 @@ ${S||"- (none recorded)"}
|
|
|
221
221
|
${_}`),"utf-8");else{let C=k.match(/^(#{1,3}\s+[^\n]*\n\n?)/);C?B.default.writeFileSync(a,Ee(C[1]+_+k.slice(C[1].length)),"utf-8"):B.default.writeFileSync(a,Ee(_+k),"utf-8")}}else B.default.writeFileSync(a,Ee(`# Milestones
|
|
222
222
|
|
|
223
223
|
${_}`),"utf-8");if(B.default.existsSync(o)){let k=B.default.readFileSync(o,"utf-8");k=ye(k,"Status",null,`${e} milestone complete`),k=ye(k,"Last Activity","Last activity",d),k=ye(k,"Last Activity Description",null,`${e} milestone completed and archived`),oe(o,k,t)}let P=!1;if(n.archivePhases)try{let k=ke.default.join(c,`${e}-phases`);B.default.mkdirSync(k,{recursive:!0});let C=B.default.readdirSync(l,{withFileTypes:!0}).filter($=>$.isDirectory()).map($=>$.name),L=0;for(let $ of C)m($)&&(B.default.renameSync(ke.default.join(l,$),ke.default.join(k,$)),L++);P=L>0}catch{}y({version:e,name:u,date:d,phases:p,plans:f,tasks:g,accomplishments:h,archived:{roadmap:B.default.existsSync(ke.default.join(c,`${e}-ROADMAP.md`)),requirements:B.default.existsSync(ke.default.join(c,`${e}-REQUIREMENTS.md`)),audit:B.default.existsSync(ke.default.join(c,`${e}-MILESTONE-AUDIT.md`)),phases:P},milestones_updated:!0,state_updated:B.default.existsSync(o)},r)}var B,ke,Wn=N(()=>{"use strict";B=W(require("fs")),ke=W(require("path"));ge();Ue();Fe()});var Vt,qn,Ln,Rr=N(()=>{"use strict";Vt=require("@oclif/core");$e();qn=class t extends w{static description="Complete the current milestone";static args={version:Vt.Args.string({required:!1})};static flags={...w.baseFlags,name:Vt.Flags.string({description:"Milestone name"}),"archive-phases":Vt.Flags.boolean({description:"Archive phases",default:!1})};async run(){let{flags:e,args:n}=await this.parse(t),{cwd:r,raw:s}=this.resolveContext(e),{cmdMilestoneComplete:i}=await Promise.resolve().then(()=>(Wn(),Nn));i(r,n.version??"",{name:e.name??null,archivePhases:e["archive-phases"]},s)}},Ln=class t extends w{static description="Mark requirements as complete";static flags={...w.baseFlags};static strict=!1;async run(){let{flags:e,argv:n}=await this.parse(t),{cwd:r,raw:s}=this.resolveContext(e),{cmdRequirementsMarkComplete:i}=await Promise.resolve().then(()=>(Wn(),Nn));i(r,n,s)}}});var v,Er,Xc,Zc,Kc,Qc,Vo,el,zo,Go,Bo,Un,Fr=N(()=>{"use strict";v=require("zod"),Er=v.z.object({milestone:v.z.string().optional(),milestone_name:v.z.string().optional(),current_phase:v.z.string().optional(),current_phase_name:v.z.string().optional(),current_plan:v.z.string().optional(),total_phases:v.z.coerce.number().int().nonnegative().optional(),total_plans_in_phase:v.z.coerce.number().int().nonnegative().optional(),status:v.z.string().optional(),progress:v.z.string().optional(),last_activity:v.z.string().optional(),paused_at:v.z.string().optional(),stopped_at:v.z.string().optional()}).passthrough(),Xc=v.z.object({found:v.z.literal(!0),phase_number:v.z.string(),phase_name:v.z.string(),goal:v.z.string().nullable(),success_criteria:v.z.array(v.z.string()).default([]),section:v.z.string().optional()}).passthrough(),Zc=v.z.object({phase:v.z.union([v.z.string(),v.z.number()]),plan:v.z.union([v.z.string(),v.z.number()]),type:v.z.string(),wave:v.z.union([v.z.string(),v.z.number()]),depends_on:v.z.union([v.z.string(),v.z.array(v.z.string())]),files_modified:v.z.union([v.z.string(),v.z.array(v.z.string())]),autonomous:v.z.union([v.z.boolean(),v.z.string()]),must_haves:v.z.union([v.z.string(),v.z.array(v.z.string())])}).passthrough(),Kc=v.z.object({phase:v.z.union([v.z.string(),v.z.number()]),plan:v.z.union([v.z.string(),v.z.number()]),subsystem:v.z.string(),tags:v.z.union([v.z.string(),v.z.array(v.z.string())]),duration:v.z.string(),completed:v.z.string()}).passthrough(),Qc=v.z.object({phase:v.z.union([v.z.string(),v.z.number()]),verified:v.z.union([v.z.boolean(),v.z.string()]),status:v.z.string(),score:v.z.union([v.z.number(),v.z.string()])}).passthrough(),Vo=v.z.object({test:v.z.number().int().positive().optional(),name:v.z.string(),expected:v.z.string().optional(),result:v.z.string(),category:v.z.string(),reason:v.z.string().optional(),blocked_by:v.z.string().optional()}).passthrough(),el=v.z.object({phase:v.z.string(),phase_dir:v.z.string(),file:v.z.string(),file_path:v.z.string(),type:v.z.literal("uat"),status:v.z.string(),items:v.z.array(Vo)}).passthrough(),zo=v.z.object({branching_strategy:v.z.enum(["none","phase","milestone","workstream"]).default("none"),phase_branch_template:v.z.string().default("gsd/phase-{phase}-{slug}"),milestone_branch_template:v.z.string().default("gsd/{milestone}-{slug}"),quick_branch_template:v.z.string().nullable().default(null)}).passthrough(),Go=v.z.object({research:v.z.boolean().default(!0),plan_check:v.z.boolean().default(!0),verifier:v.z.boolean().default(!0),nyquist_validation:v.z.boolean().default(!0),auto_advance:v.z.boolean().default(!1),node_repair:v.z.boolean().default(!0),node_repair_budget:v.z.number().int().nonnegative().default(2),auto_retry_audit:v.z.boolean().default(!0),auto_retry_audit_budget:v.z.number().int().nonnegative().default(1),auto_retry_tech_debt:v.z.boolean().default(!0),auto_retry_tech_debt_budget:v.z.number().int().nonnegative().default(1),ui_phase:v.z.boolean().default(!0),ui_safety_gate:v.z.boolean().default(!0),text_mode:v.z.boolean().default(!1),research_before_questions:v.z.boolean().default(!1),discuss_mode:v.z.string().default("discuss"),skip_discuss:v.z.boolean().default(!1),_auto_chain_active:v.z.boolean().default(!1)}).passthrough(),Bo=v.z.object({context_warnings:v.z.boolean().default(!0),workflow_guard:v.z.boolean().default(!1)}).passthrough(),Un=v.z.object({model_profile:v.z.enum(["quality","balanced","budget","inherit"]).default("balanced"),commit_docs:v.z.boolean().default(!0),parallelization:v.z.boolean().default(!0),search_gitignored:v.z.boolean().default(!1),brave_search:v.z.boolean().default(!1),firecrawl:v.z.boolean().default(!1),exa_search:v.z.boolean().default(!1),git:zo.default({}),workflow:Go.default({}),hooks:Bo.default({}),agent_skills:v.z.record(v.z.string(),v.z.unknown()).default({})}).passthrough()});var jt={};he(jt,{cmdValidateAgents:()=>sa,cmdValidateConsistency:()=>ta,cmdValidateHealth:()=>na,cmdVerifyArtifacts:()=>Qo,cmdVerifyCommits:()=>Ko,cmdVerifyKeyLinks:()=>ea,cmdVerifyPhaseCompleteness:()=>Xo,cmdVerifyPlanStructure:()=>Ho,cmdVerifyReferences:()=>Zo,cmdVerifySummary:()=>Yo});function Jo(t,e){let n=t;for(let r of e){if(n==null||typeof n!="object")return;n=n[r]}return n}function Yo(t,e,n,r){e||b("summary-path required");let s=K.default.join(t,e),i=n||2;if(!Q.default.existsSync(s)){y({passed:!1,checks:{summary_exists:!1,files_created:{checked:0,found:0,missing:[]},commits_exist:!1,self_check:"not_found"},errors:["SUMMARY.md not found"]},r,"failed");return}let o=Q.default.readFileSync(s,"utf-8"),a=[],c=new Set;for(let g of[/`([^`]+\.[a-zA-Z]+)`/g,/(?:Created|Modified|Added|Updated|Edited):\s*`?([^\s`]+\.[a-zA-Z]+)`?/gi]){let h;for(;(h=g.exec(o))!==null;)h[1]&&!h[1].startsWith("http")&&h[1].includes("/")&&c.add(h[1])}let l=Array.from(c).slice(0,i),d=l.filter(g=>!Q.default.existsSync(K.default.join(t,g))),u=o.match(/\b[0-9a-f]{7,40}\b/g)||[],m=!1;for(let g of u.slice(0,3))if(ae(t,["cat-file","-t",g]).stdout==="commit"){m=!0;break}let p="not_found";if(/##\s*(?:Self[- ]?Check|Verification|Quality Check)/i.test(o)){let g=o.slice(o.search(/##\s*(?:Self[- ]?Check|Verification|Quality Check)/i));/(?:fail|✗|❌|incomplete|blocked)/i.test(g)?p="failed":/(?:all\s+)?(?:pass|✓|✅|complete|succeeded)/i.test(g)&&(p="passed")}d.length>0&&a.push("Missing files: "+d.join(", ")),!m&&u.length>0&&a.push("Referenced commit hashes not found in git history"),p==="failed"&&a.push("Self-check section indicates failure");let f=d.length===0&&p!=="failed";y({passed:f,checks:{summary_exists:!0,files_created:{checked:l.length,found:l.length-d.length,missing:d},commits_exist:m,self_check:p},errors:a},r,f?"passed":"failed")}function Ho(t,e,n){e||b("file path required");let r=K.default.isAbsolute(e)?e:K.default.join(t,e),s=Oe(r);if(!s){y({error:"File not found",path:e},n);return}let i=ie(s),o=[],a=[];for(let m of["phase","plan","type","wave","depends_on","files_modified","autonomous","must_haves"])i[m]===void 0&&o.push(`Missing required frontmatter field: ${m}`);let c=/<task[^>]*>([\s\S]*?)<\/task>/g,l=[],d;for(;(d=c.exec(s))!==null;){let m=d[1],p=m.match(/<name>([\s\S]*?)<\/name>/),f=p?p[1].trim():"unnamed",g=/<files>/.test(m),h=/<action>/.test(m),x=/<verify>/.test(m),S=/<done>/.test(m);p||o.push("Task missing <name> element"),h||o.push(`Task '${f}' missing <action>`),x||a.push(`Task '${f}' missing <verify>`),S||a.push(`Task '${f}' missing <done>`),g||a.push(`Task '${f}' missing <files>`),l.push({name:f,hasFiles:g,hasAction:h,hasVerify:x,hasDone:S})}l.length===0&&a.push("No <task> elements found"),i.wave&&parseInt(String(i.wave))>1&&(!i.depends_on||Array.isArray(i.depends_on)&&i.depends_on.length===0)&&a.push("Wave > 1 but depends_on is empty"),/<task\s+type=["']?checkpoint/.test(s)&&i.autonomous!=="false"&&i.autonomous!==!1&&o.push("Has checkpoint tasks but autonomous is not false"),y({valid:o.length===0,errors:o,warnings:a,task_count:l.length,tasks:l,frontmatter_fields:Object.keys(i)},n,o.length===0?"valid":"invalid")}function Xo(t,e,n){e||b("phase required");let r=fe(t,e);if(!r?.found){y({error:"Phase not found",phase:e},n);return}let s=K.default.join(t,r.directory),i=[],o=[],a;try{a=Q.default.readdirSync(s)}catch{y({error:"Cannot read phase directory"},n);return}let c=a.filter(f=>f.match(/-PLAN\.md$/i)),l=a.filter(f=>f.match(/-SUMMARY\.md$/i)),d=new Set(c.map(f=>f.replace(/-PLAN\.md$/i,""))),u=new Set(l.map(f=>f.replace(/-SUMMARY\.md$/i,""))),m=[...d].filter(f=>!u.has(f)),p=[...u].filter(f=>!d.has(f));m.length>0&&i.push(`Plans without summaries: ${m.join(", ")}`),p.length>0&&o.push(`Summaries without plans: ${p.join(", ")}`),y({complete:i.length===0,phase:r.phase_number,plan_count:c.length,summary_count:l.length,incomplete_plans:m,orphan_summaries:p,errors:i,warnings:o},n,i.length===0?"complete":"incomplete")}function Zo(t,e,n){e||b("file path required");let r=K.default.isAbsolute(e)?e:K.default.join(t,e),s=Oe(r);if(!s){y({error:"File not found",path:e},n);return}let i=[],o=[];for(let a of s.match(/@([^\s\n,)]+\/[^\s\n,)]+)/g)||[]){let c=a.slice(1),l=c.startsWith("~/")?K.default.join(process.env.HOME??"",c.slice(2)):K.default.join(t,c);(Q.default.existsSync(l)?i:o).push(c)}for(let a of s.match(/`([^`]+\/[^`]+\.[a-zA-Z]{1,10})`/g)||[]){let c=a.slice(1,-1);c.startsWith("http")||c.includes("${")||c.includes("{{")||i.includes(c)||o.includes(c)||(Q.default.existsSync(K.default.join(t,c))?i:o).push(c)}y({valid:o.length===0,found:i.length,missing:o,total:i.length+o.length},n,o.length===0?"valid":"invalid")}function Ko(t,e,n){(!e||e.length===0)&&b("At least one commit hash required");let r=[],s=[];for(let i of e)(ae(t,["cat-file","-t",i]).stdout.trim()==="commit"?r:s).push(i);y({all_valid:s.length===0,valid:r,invalid:s,total:e.length},n,s.length===0?"valid":"invalid")}function Qo(t,e,n){e||b("plan file path required");let r=K.default.isAbsolute(e)?e:K.default.join(t,e),s=Oe(r);if(!s){y({error:"File not found",path:e},n);return}let i=an(s,"artifacts");if(i.length===0){y({error:"No must_haves.artifacts found in frontmatter",path:e},n);return}let o=[];for(let c of i){if(typeof c=="string")continue;let l=c;if(!l.path)continue;let d=K.default.join(t,l.path),u=Q.default.existsSync(d),m={path:l.path,exists:u,issues:[],passed:!1};if(u){let p=Oe(d)??"",f=p.split(`
|
|
224
|
-
`).length;if(l.min_lines&&f<l.min_lines&&m.issues.push(`Only ${f} lines, need ${l.min_lines}`),l.contains&&!p.includes(l.contains)&&m.issues.push(`Missing pattern: ${l.contains}`),l.exports){let g=Array.isArray(l.exports)?l.exports:[l.exports];for(let h of g)p.includes(h)||m.issues.push(`Missing export: ${h}`)}m.passed=m.issues.length===0}else m.issues.push("File not found");o.push(m)}let a=o.filter(c=>c.passed).length;y({all_passed:a===o.length,passed:a,total:o.length,artifacts:o},n,a===o.length?"valid":"invalid")}function ea(t,e,n){e||b("plan file path required");let r=K.default.isAbsolute(e)?e:K.default.join(t,e),s=Oe(r);if(!s){y({error:"File not found",path:e},n);return}let i=an(s,"key_links");if(i.length===0){y({error:"No must_haves.key_links found in frontmatter",path:e},n);return}let o=[];for(let c of i){if(typeof c=="string")continue;let l=c,d={from:l.from??"",to:l.to??"",via:l.via||"",verified:!1,detail:""},u=Oe(K.default.join(t,l.from||""));if(!u)d.detail="Source file not found";else if(l.pattern)try{let m=new RegExp(l.pattern);if(m.test(u))d.verified=!0,d.detail="Pattern found in source";else{let p=Oe(K.default.join(t,l.to||""));p&&m.test(p)?(d.verified=!0,d.detail="Pattern found in target"):d.detail=`Pattern "${l.pattern}" not found in source or target`}}catch{d.detail=`Invalid regex pattern: ${l.pattern}`}else u.includes(l.to||"")?(d.verified=!0,d.detail="Target referenced in source"):d.detail="Target not referenced in source";o.push(d)}let a=o.filter(c=>c.verified).length;y({all_verified:a===o.length,verified:a,total:o.length,links:o},n,a===o.length?"valid":"invalid")}function ta(t,e){let n=K.default.join(T(t),"ROADMAP.md"),r=K.default.join(T(t),"phases"),s=[],i=[];if(!Q.default.existsSync(n)){s.push("ROADMAP.md not found"),y({passed:!1,errors:s,warnings:i},e,"failed");return}let o=ve(Q.default.readFileSync(n,"utf-8"),t),a=new Set,c=/#{2,4}\s*Phase\s+(\d+[A-Z]?(?:\.\d+)*)\s*:/gi,l;for(;(l=c.exec(o))!==null;)a.add(l[1]);let d=new Set;try{Q.default.readdirSync(r,{withFileTypes:!0}).filter(p=>p.isDirectory()).map(p=>p.name).forEach(p=>{let f=p.match(/^(\d+[A-Z]?(?:\.\d+)*)/i);f&&d.add(f[1])})}catch{}for(let p of a)!d.has(p)&&!d.has(de(p))&&i.push(`Phase ${p} in ROADMAP.md but no directory on disk`);for(let p of d){let f=String(parseInt(p,10));!a.has(p)&&!a.has(f)&&i.push(`Phase ${p} exists on disk but not in ROADMAP.md`)}if(X(t).phase_naming!=="custom"){let p=[...d].filter(f=>!f.includes(".")).map(f=>parseInt(f,10)).sort((f,g)=>f-g);for(let f=1;f<p.length;f++)p[f]!==p[f-1]+1&&i.push(`Gap in phase numbering: ${p[f-1]} \u2192 ${p[f]}`)}let m=s.length===0;y({passed:m,errors:s,warnings:i,warning_count:i.length},e,m?"passed":"failed")}function na(t,e,n){let r=K.default.resolve(t);if(r===Mr.default.homedir()){y({status:"error",errors:[{code:"E010",message:"CWD is home directory - health check would read the wrong .planning/ directory.",fix:"cd into your project directory and retry"}],warnings:[],info:[{code:"I010",message:`Resolved CWD: ${r}`}],repairable_count:0},n);return}let s=T(t),i=Z(t),o=K.default.join(i,"PROJECT.md"),a=K.default.join(s,"ROADMAP.md"),c=K.default.join(s,"STATE.md"),l=K.default.join(i,"config.json"),d=K.default.join(s,"phases"),u=[],m=[],p=[],f=[],g=(S,_,P,k,C=!1,L)=>{let $={code:_,message:P,fix:k,repairable:C,...L};S==="error"?u.push($):S==="warning"?m.push($):p.push($)};if(!Q.default.existsSync(s)){g("error","E001",".planning/ directory not found","Run /gsd-new-project to initialize"),y({status:"broken",errors:u,warnings:m,info:p,repairable_count:0},n);return}if(!Q.default.existsSync(o))g("error","E002","PROJECT.md not found","Run /gsd-new-project to create");else{let S=Q.default.readFileSync(o,"utf-8");for(let _ of["## What This Is","## Core Value","## Requirements"])S.includes(_)||g("warning","W001",`PROJECT.md missing section: ${_}`,"Add section manually")}if(Q.default.existsSync(a)||g("error","E003","ROADMAP.md not found","Run /gsd-new-milestone to create roadmap"),!Q.default.existsSync(c))g("error","E004","STATE.md not found","Run /gsd-health --repair to regenerate",!0),f.push("regenerateState");else try{let S=Q.default.readFileSync(c,"utf-8"),_=ie(S),P=Er.safeParse(_);if(!P.success){for(let k of P.error.issues){let C=k.path.join(".")||"(root)";g("warning","W011",`STATE.md frontmatter: field "${C}"
|
|
224
|
+
`).length;if(l.min_lines&&f<l.min_lines&&m.issues.push(`Only ${f} lines, need ${l.min_lines}`),l.contains&&!p.includes(l.contains)&&m.issues.push(`Missing pattern: ${l.contains}`),l.exports){let g=Array.isArray(l.exports)?l.exports:[l.exports];for(let h of g)p.includes(h)||m.issues.push(`Missing export: ${h}`)}m.passed=m.issues.length===0}else m.issues.push("File not found");o.push(m)}let a=o.filter(c=>c.passed).length;y({all_passed:a===o.length,passed:a,total:o.length,artifacts:o},n,a===o.length?"valid":"invalid")}function ea(t,e,n){e||b("plan file path required");let r=K.default.isAbsolute(e)?e:K.default.join(t,e),s=Oe(r);if(!s){y({error:"File not found",path:e},n);return}let i=an(s,"key_links");if(i.length===0){y({error:"No must_haves.key_links found in frontmatter",path:e},n);return}let o=[];for(let c of i){if(typeof c=="string")continue;let l=c,d={from:l.from??"",to:l.to??"",via:l.via||"",verified:!1,detail:""},u=Oe(K.default.join(t,l.from||""));if(!u)d.detail="Source file not found";else if(l.pattern)try{let m=new RegExp(l.pattern);if(m.test(u))d.verified=!0,d.detail="Pattern found in source";else{let p=Oe(K.default.join(t,l.to||""));p&&m.test(p)?(d.verified=!0,d.detail="Pattern found in target"):d.detail=`Pattern "${l.pattern}" not found in source or target`}}catch{d.detail=`Invalid regex pattern: ${l.pattern}`}else u.includes(l.to||"")?(d.verified=!0,d.detail="Target referenced in source"):d.detail="Target not referenced in source";o.push(d)}let a=o.filter(c=>c.verified).length;y({all_verified:a===o.length,verified:a,total:o.length,links:o},n,a===o.length?"valid":"invalid")}function ta(t,e){let n=K.default.join(T(t),"ROADMAP.md"),r=K.default.join(T(t),"phases"),s=[],i=[];if(!Q.default.existsSync(n)){s.push("ROADMAP.md not found"),y({passed:!1,errors:s,warnings:i},e,"failed");return}let o=ve(Q.default.readFileSync(n,"utf-8"),t),a=new Set,c=/#{2,4}\s*Phase\s+(\d+[A-Z]?(?:\.\d+)*)\s*:/gi,l;for(;(l=c.exec(o))!==null;)a.add(l[1]);let d=new Set;try{Q.default.readdirSync(r,{withFileTypes:!0}).filter(p=>p.isDirectory()).map(p=>p.name).forEach(p=>{let f=p.match(/^(\d+[A-Z]?(?:\.\d+)*)/i);f&&d.add(f[1])})}catch{}for(let p of a)!d.has(p)&&!d.has(de(p))&&i.push(`Phase ${p} in ROADMAP.md but no directory on disk`);for(let p of d){let f=String(parseInt(p,10));!a.has(p)&&!a.has(f)&&i.push(`Phase ${p} exists on disk but not in ROADMAP.md`)}if(X(t).phase_naming!=="custom"){let p=[...d].filter(f=>!f.includes(".")).map(f=>parseInt(f,10)).sort((f,g)=>f-g);for(let f=1;f<p.length;f++)p[f]!==p[f-1]+1&&i.push(`Gap in phase numbering: ${p[f-1]} \u2192 ${p[f]}`)}let m=s.length===0;y({passed:m,errors:s,warnings:i,warning_count:i.length},e,m?"passed":"failed")}function na(t,e,n){let r=K.default.resolve(t);if(r===Mr.default.homedir()){y({status:"error",errors:[{code:"E010",message:"CWD is home directory - health check would read the wrong .planning/ directory.",fix:"cd into your project directory and retry"}],warnings:[],info:[{code:"I010",message:`Resolved CWD: ${r}`}],repairable_count:0},n);return}let s=T(t),i=Z(t),o=K.default.join(i,"PROJECT.md"),a=K.default.join(s,"ROADMAP.md"),c=K.default.join(s,"STATE.md"),l=K.default.join(i,"config.json"),d=K.default.join(s,"phases"),u=[],m=[],p=[],f=[],g=(S,_,P,k,C=!1,L)=>{let $={code:_,message:P,fix:k,repairable:C,...L};S==="error"?u.push($):S==="warning"?m.push($):p.push($)};if(!Q.default.existsSync(s)){g("error","E001",".planning/ directory not found","Run /gsd-new-project to initialize"),y({status:"broken",errors:u,warnings:m,info:p,repairable_count:0},n);return}if(!Q.default.existsSync(o))g("error","E002","PROJECT.md not found","Run /gsd-new-project to create");else{let S=Q.default.readFileSync(o,"utf-8");for(let _ of["## What This Is","## Core Value","## Requirements"])S.includes(_)||g("warning","W001",`PROJECT.md missing section: ${_}`,"Add section manually")}if(Q.default.existsSync(a)||g("error","E003","ROADMAP.md not found","Run /gsd-new-milestone to create roadmap"),!Q.default.existsSync(c))g("error","E004","STATE.md not found","Run /gsd-health --repair to regenerate",!0),f.push("regenerateState");else try{let S=Q.default.readFileSync(c,"utf-8"),_=ie(S),P=Er.safeParse(_);if(!P.success){for(let k of P.error.issues){let C=k.path.join(".")||"(root)";g("warning","W011",`STATE.md frontmatter: field "${C}" - ${k.message}`,"Check STATE.md frontmatter manually or run /gsd-health --repair to regenerate",!0)}f.includes("regenerateState")||f.push("regenerateState")}}catch{}if(!Q.default.existsSync(l))g("warning","W003","config.json not found","Run /gsd-health --repair to create with defaults",!0),f.push("createConfig");else try{let S=JSON.parse(Q.default.readFileSync(l,"utf-8")),_=Un.safeParse(S);if(!_.success){for(let P of _.error.issues){let k=P.path.join(".")||"(root)",C=Jo(S,P.path);g("warning","W005",`config.json: field "${k}" - ${P.message}`,"Run pi-gsd-tools validate health --repair to fix using schema defaults",!0,{field:k,expected:P.message,actual:C})}f.includes("fixSchemaDefaults")||f.push("fixSchemaDefaults")}}catch(S){g("error","E005",`config.json: JSON parse error - ${S.message}`,"Run pi-gsd-tools validate health --repair to reset to defaults",!0),f.push("resetConfig")}try{let S=_t();S.agents_installed||g("warning","W010",S.installed_agents.length===0?`No GSD agents found in ${S.agents_dir}`:`Missing ${S.missing_agents.length} GSD agents: ${S.missing_agents.join(", ")}`,"Run the GSD installer: pi install npm:pi-gsd")}catch{}let h=[];if(e.repair&&f.length>0)for(let S of f)try{if(S==="createConfig"||S==="resetConfig"){let _=Un.parse({});Q.default.writeFileSync(l,JSON.stringify(_,null,2),"utf-8"),h.push({action:S,success:!0,path:"config.json"})}else if(S==="fixSchemaDefaults"&&Q.default.existsSync(l)){let _=JSON.parse(Q.default.readFileSync(l,"utf-8")),P=Un.parse(_);Q.default.writeFileSync(l,JSON.stringify(P,null,2),"utf-8"),h.push({action:S,success:!0,path:"config.json"})}else if(S==="regenerateState"){if(Q.default.existsSync(c)){let P=new Date().toISOString().replace(/[:.]/g,"-").slice(0,19),k=`${c}.bak-${P}`;Q.default.copyFileSync(c,k),h.push({action:"backupState",success:!0,path:k})}let _=re(t);oe(c,`# Session State
|
|
225
225
|
|
|
226
226
|
## Project Reference
|
|
227
227
|
|
|
@@ -337,7 +337,7 @@ ${p}
|
|
|
337
337
|
`,h=Bt.default.join(t,s.directory,f);if(as.default.existsSync(h)){y({error:"File already exists",path:G(Bt.default.relative(t,h))},r);return}as.default.writeFileSync(h,Ee(g),"utf-8");let x=G(Bt.default.relative(t,h));y({created:!0,path:x,template:e},r,x)}var as,Bt,Js=N(()=>{"use strict";as=W(require("fs")),Bt=W(require("path"));ge();Ue()});var Je,cs,ls,Lr=N(()=>{"use strict";Je=require("@oclif/core");$e();cs=class t extends w{static description="Select a workflow template";static args={type:Je.Args.string({required:!0})};static flags={...w.baseFlags};async run(){let{flags:e,args:n}=await this.parse(t),{cwd:r,raw:s}=this.resolveContext(e),{cmdTemplateSelect:i}=await Promise.resolve().then(()=>(Js(),Bs));i(r,n.type,s)}},ls=class t extends w{static description="Fill a template with values";static args={type:Je.Args.string({required:!0})};static flags={...w.baseFlags,phase:Je.Flags.string(),plan:Je.Flags.string(),name:Je.Flags.string(),type:Je.Flags.string({char:"t"}),wave:Je.Flags.string(),fields:Je.Flags.string({description:"JSON fields"})};async run(){let{flags:e,args:n}=await this.parse(t),{cwd:r,raw:s}=this.resolveContext(e),{cmdTemplateFill:i}=await Promise.resolve().then(()=>(Js(),Bs)),o={};if(e.fields)try{o=JSON.parse(e.fields)}catch{}i(r,n.type,{phase:e.phase??void 0,plan:e.plan??void 0,name:e.name??void 0,type:e.type??void 0,wave:e.wave??void 0,...o},s)}}});var Et,ds,us,ms,ps,fs,Ur=N(()=>{"use strict";Et=require("@oclif/core");$e();ds=class t extends w{static description="Show project progress";static args={format:Et.Args.string({default:"json"})};static flags={...w.baseFlags};async run(){let{flags:e,args:n}=await this.parse(t),{cwd:r,raw:s}=this.resolveContext(e),{cmdProgressRender:i}=await Promise.resolve().then(()=>(Se(),xe));i(r,n.format,s)}},us=class t extends w{static description="Show project statistics";static args={format:Et.Args.string({default:"json"})};static flags={...w.baseFlags};async run(){let{flags:e,args:n}=await this.parse(t),{cwd:r,raw:s}=this.resolveContext(e),{cmdStats:i}=await Promise.resolve().then(()=>(Se(),xe));i(r,n.format,s)}},ms=class t extends w{static description="Mark a todo as complete";static args={id:Et.Args.string({required:!0})};static flags={...w.baseFlags};async run(){let{flags:e,args:n}=await this.parse(t),{cwd:r,raw:s}=this.resolveContext(e),{cmdTodoComplete:i}=await Promise.resolve().then(()=>(Se(),xe));i(r,n.id,s)}},ps=class t extends w{static description="Match todos to phase";static args={phase:Et.Args.string({required:!0})};static flags={...w.baseFlags};async run(){let{flags:e,args:n}=await this.parse(t),{cwd:r,raw:s}=this.resolveContext(e),{cmdTodoMatchPhase:i}=await Promise.resolve().then(()=>(Se(),xe));i(r,n.phase,s)}},fs=class t extends w{static description="Extract fields from summary files";static args={phase:Et.Args.string({required:!0})};static flags={...w.baseFlags,fields:w.baseFlags.pick};async run(){let{flags:e,args:n}=await this.parse(t),{cwd:r,raw:s}=this.resolveContext(e),{cmdSummaryExtract:i}=await Promise.resolve().then(()=>(Se(),xe)),o=e.fields?e.fields.split(","):null;i(r,n.phase,o,s)}}});function ft(t){let e=[],n=/^```[^\n]*\n[\s\S]*?^```/gm,r;for(;(r=n.exec(t))!==null;)e.push([r.index,r.index+r[0].length]);return e}function gt(t,e){return e.some(([n,r])=>t>=n&&t<r)}function Ia(t){let e={},n=/([a-zA-Z0-9_:-]+)(?:=(?:"([^"]*)"|'([^']*)'|([^\s/>]*)))?/g,r;for(;(r=n.exec(t))!==null;){let s=r[1],i=r[2]??r[3]??r[4]??"";e[s]=i}return e}function Vr(t,e){if(t[e]!=="<")return null;let n=/^<([a-zA-Z0-9_:-]+)((?:\s+[a-zA-Z0-9_:-]+(?:=(?:"[^"]*"|'[^']*'|[^\s/>]*))?)*)?\s*(\/??>)/,r=t.slice(e),s=n.exec(r);if(!s)return null;let i=s[1],o=(s[2]??"").trim(),a=s[3],c=Ia(o);if(a==="/>")return{node:{tag:i,attrs:c,children:[],selfClosing:!0},end:e+s[0].length};let l=e+s[0].length,d=[],u=`</${i}>`;for(;l<t.length;){let m=t.indexOf("<",l);if(m===-1)break;if(t.startsWith(u,m))return{node:{tag:i,attrs:c,children:d,selfClosing:!1},end:m+u.length};if(t.startsWith("<!--",m)){let f=t.indexOf("-->",m+4);l=f!==-1?f+3:t.length;continue}let p=Vr(t,m);p?(d.push(p.node),l=p.end):l=m+1}return{node:{tag:i,attrs:c,children:d,selfClosing:!1},end:l}}function Jt(t){let e=ft(t),n=[],r=/<(gsd-[a-zA-Z0-9_-]+)/g,s;for(;(s=r.exec(t))!==null;){let i=s.index;if(gt(i,e))continue;let o=s[1];if(!Ta.has(o))continue;let a=Vr(t,i);a&&(n.push({node:a.node,start:i,end:a.end}),r.lastIndex=a.end)}return n}function gs(t,e,n,r){return t.slice(0,e)+r+t.slice(n)}var Ta,Ys=N(()=>{"use strict";Ta=new Set(["gsd-execute","gsd-arguments","gsd-paste","gsd-include","gsd-version"])});function zr(){let t=new Map,e=new Map,n=r=>{let s=t.get(r)?.value;if(s!==void 0)return s;let i=r.indexOf(".");if(i===-1)return;let o=r.slice(0,i),a=r.slice(i+1),c=t.get(o)?.value;if(c!==void 0)try{let l=JSON.parse(c);for(let d of a.split(".")){if(l===null||typeof l!="object")return;l=l[d]}return l==null?void 0:String(l)}catch{return}};return{set(r,s,i){let o=t.get(r);o?.owner&&i&&o.owner!==i?(t.delete(r),t.set(`${o.owner}:${r}`,{name:`${o.owner}:${r}`,value:o.value,owner:o.owner}),t.set(`${i}:${r}`,{name:`${i}:${r}`,value:s,owner:i})):t.set(r,{name:r,value:s,owner:i})},get(r){return t.get(r)?.value},resolve(r){return n(r)},setArray(r,s,i){e.set(r,s),t.set(r,{name:r,value:JSON.stringify(s),owner:i})},getArray(r){if(e.has(r))return e.get(r);let s=t.get(r)?.value;if(s)try{let i=JSON.parse(s);if(Array.isArray(i))return i.map(o=>typeof o=="string"?o:JSON.stringify(o))}catch{}},has(r){return t.has(r)||e.has(r)},entries(){return t.entries()},snapshot(){let r={};for(let[s,i]of t)r[s]=i.value;return r}}}var Gr=N(()=>{"use strict"});function Br(t,e,n){let r=t.children.find(g=>g.tag==="settings"),s=r?.children.some(g=>g.tag==="keep-extra-args")??!1,i=r?.children.some(g=>g.tag==="strict-args")??!1,a=r?.children.find(g=>g.tag==="delimiters")?.children.find(g=>g.tag==="delimiter"),c;if(a){let g=a.attrs.value??"",h=g==="\\n"?`
|
|
338
338
|
`:g;c=e.split(h).map(x=>x.trim()).filter(Boolean)}else c=e.trim().split(/\s+/).filter(Boolean);let l=t.children.filter(g=>g.tag==="arg"),d=new Set;for(let g of l.filter(h=>h.attrs.type==="flag")){let h=g.attrs.flag??`--${g.attrs.name}`,x=c.indexOf(h),S=g.attrs.name;S&&(x===-1?n.set(S,"false",void 0):(n.set(S,"true",void 0),d.add(x)))}let u=l.filter(g=>g.attrs.type!=="flag"),m=c.filter((g,h)=>!d.has(h)),p=0;for(let g=0;g<u.length;g++){let h=u[g],x=h.attrs.name,S=h.attrs.type??"string",_=g===u.length-1;if(x){if(p>=m.length){if(!("optional"in h.attrs))throw new ht(`Missing required argument '${x}' (type: ${S})`);n.set(x,"",void 0);continue}if(S==="string"&&_)n.set(x,m.slice(p).join(" "),void 0),p=m.length;else if(S==="number"){let P=m[p++],k=Number(P);if(isNaN(k))throw new ht(`Argument '${x}' expected a number, got '${P}'`);n.set(x,String(k),void 0)}else if(S==="boolean"){let P=m[p++].toLowerCase();if(P!=="true"&&P!=="false")throw new ht(`Argument '${x}' expected true/false, got '${P}'`);n.set(x,P,void 0)}else n.set(x,m[p++]??"",void 0)}}let f=m.slice(p).join(" ");if(f){if(i)throw new ht(`Unexpected extra arguments: '${f}'`);s&&n.set("_extra",f,void 0)}}var ht,Hs=N(()=>{"use strict";ht=class extends Error{constructor(e){super(e),this.name="WxpArgumentsError"}}});function hs(t,e,n){switch(t.position){case"project":return Ye.default.resolve(e,t.path);case"pkg":return Ye.default.resolve(n,t.path);case"absolute":return Ye.default.resolve(t.path)}}function Xs(t,e,n,r){let s=Ye.default.resolve(t),i=`${Ye.default.sep}.planning`;if(s.includes(`${i}${Ye.default.sep}`)||s.endsWith(i))return{ok:!1,reason:".planning/ files are never processed by WXP (hard security invariant)"};for(let o of e.untrustedPaths){let a=hs(o,n,r);if(s.startsWith(a+Ye.default.sep)||s===a)return{ok:!1,reason:`File '${t}' is in an explicitly untrusted path: ${a}`}}for(let o of e.trustedPaths){let a=hs(o,n,r);if(s.startsWith(a+Ye.default.sep)||s===a)return{ok:!0}}return{ok:!1,reason:`File '${t}' is not in a trusted WXP path.`}}function Yr(t,e){let n=Ye.default.basename(t);return e.shellBanlist.includes(n)?{ok:!1,reason:`Command '${n}' is explicitly banned by WXP security config.`}:e.shellAllowlist.includes(n)?{ok:!0}:{ok:!1,reason:`Command '${n}' is not in the WXP shell allowlist. Allowed: ${e.shellAllowlist.join(", ")}`}}var Ye,Jr,Yt=N(()=>{"use strict";Ye=W(require("path")),Jr=["pi-gsd-tools","git","node","cat","ls","echo","find"]});function ys(t,e){if(t.attrs.string!==void 0)return t.attrs.string;if(t.attrs.name!==void 0){let n=e.resolve(t.attrs.name)??"",r=t.attrs.wrap;return r?`${r}${n}${r}`:n}return t.attrs.value!==void 0?t.attrs.value:""}function Xr(t,e,n){let r=t.attrs.command??"",s=Yr(r,n);if(!s.ok)throw new yt(r,"",e.snapshot(),s.reason);let i=t.children.find(u=>u.tag==="args"),o=t.children.find(u=>u.tag==="outs"),a=i?i.children.filter(u=>u.tag==="arg").map(u=>ys(u,e)):[],c=o?o.children.some(u=>u.tag==="suppress-errors"):!1,l=o?o.children.filter(u=>u.tag==="out"&&u.attrs.name).map(u=>u.attrs.name):[],d="";try{d=(0,Hr.execFileSync)(r,a,{encoding:"utf8",timeout:n.shellTimeoutMs,windowsHide:!0}).trim()}catch(u){if(c){for(let f of l)e.set(f,"",void 0);return}let m=u,p=(m.stderr??m.message??String(u)).trim();throw new yt(r,p,e.snapshot(),`Shell '${r} ${a.join(" ")}' failed: ${p}`)}l.length>0&&e.set(l[0],d,void 0)}var Hr,yt,xs=N(()=>{"use strict";Hr=require("child_process");Yt();yt=class extends Error{constructor(n,r,s,i){super(i);this.command=n;this.stderr=r;this.variableSnapshot=s;this.name="WxpShellError"}command;stderr;variableSnapshot}});function Zr(t,e){if(t.attrs.op!=="split")throw new xt('<string-op> only op="split" is supported in v1');let r=t.children.find(m=>m.tag==="args"),s=t.children.find(m=>m.tag==="outs");if(!r||!s)throw new xt("<string-op> requires <args> and <outs>");let i=r.children.filter(m=>m.tag==="arg"),o=s.children.filter(m=>m.tag==="out"),a=i[0],c=i[1];if(!a)throw new xt('<string-op op="split"> requires at least 2 <arg> children');let l=ys(a,e);if(a.attrs.name&&e.get(a.attrs.name)===void 0)throw new xt(`string-op split: source variable '${a.attrs.name}' is not defined`);let d=c?ys(c,e):"",u=l.split(d);o.forEach((m,p)=>{let f=m.attrs.name;f&&e.set(f,u[p+1]??u[p]??"",void 0)})}var xt,Zs=N(()=>{"use strict";xs();xt=class extends Error{constructor(e){super(e),this.name="WxpStringOpError"}}});function Ss(t,e){return t.attrs.name?e.resolve(t.attrs.name)??"":t.attrs.value!==void 0?t.attrs.value:""}function Kr(t){return t.attrs.type==="number"}function Oa(t,e){let n=t.children.find(a=>a.tag==="left"),r=t.children.find(a=>a.tag==="right");if(!n||!r)return!1;if(Kr(n)||Kr(r)){let a=Number(Ss(n,e)),c=Number(Ss(r,e));switch(t.tag){case"equals":return a===c;case"not-equals":return a!==c;case"less-than":return a<c;case"greater-than":return a>c;case"less-than-or-equal":return a<=c;case"greater-than-or-equal":return a>=c;default:return!1}}let i=Ss(n,e),o=Ss(r,e);switch(t.tag){case"equals":return i===o;case"not-equals":return i!==o;case"starts-with":return i.startsWith(o);case"contains":return i.includes(o);case"less-than":return Number(i)<Number(o);case"greater-than":return Number(i)>Number(o);case"less-than-or-equal":return Number(i)<=Number(o);case"greater-than-or-equal":return Number(i)>=Number(o);default:return!1}}function Xt(t,e){return t.tag==="and"?t.children.filter(n=>Ht.has(n.tag)).every(n=>Xt(n,e)):t.tag==="or"?t.children.filter(n=>Ht.has(n.tag)).some(n=>Xt(n,e)):Oa(t,e)}function Qr(t,e){let n=t.children.find(s=>s.tag==="condition");if(!n)return!1;let r=n.children.find(s=>Ht.has(s.tag));return r?Xt(r,e):!1}function ei(t,e){let n=t.children.find(r=>Ht.has(r.tag));return n?Xt(n,e):!0}var Da,Ht,ti=N(()=>{"use strict";Da=new Set(["equals","not-equals","starts-with","contains","less-than","greater-than","less-than-or-equal","greater-than-or-equal"]),Ht=new Set([...Da,"and","or"])});function Na(t,e,n){let r=(t.attrs.msg??"").replace(/\{([^}]+)\}/g,(i,o)=>e.resolve(o)??""),s=t.attrs.level;n.onDisplay(r,s==="warning"||s==="error"?s:"info")}function Wa(t,e){let n=t.attrs.src??"",r=t.attrs.out??"",s=t.attrs.path,i=e.get(n);if(i===void 0)throw new Error(`<json-parse>: source variable '${n}' is not defined`);let o;try{o=JSON.parse(i)}catch{throw new Error(`<json-parse>: '${n}' does not contain valid JSON`)}if(s){let a=s.replace(/^\$\.?/,"").split("."),c=o;for(let l of a){if(c===null||typeof c!="object")throw new Error(`<json-parse>: path '${s}' not found`);c=c[l]}o=c}Array.isArray(o)?e.setArray(r,o.map(a=>typeof a=="string"?a:JSON.stringify(a))):o!==null&&typeof o=="object"?e.set(r,JSON.stringify(o),void 0):e.set(r,o==null?"":String(o),void 0)}function qa(t,e){let n=t.attrs.path??"",r=t.attrs.out??"",s=Zt.default.readFileSync(Kt.default.resolve(n),"utf8");e.set(r,s,void 0)}function La(t,e,n){let r=t.attrs.path??"",s=t.attrs.src??"",i=Kt.default.resolve(r);if(Zt.default.existsSync(i))throw new Error(`<write-file>: '${r}' already exists (create-only, never overwrites)`);for(let a of n.config.trustedPaths){let c=hs(a,n.projectRoot,n.pkgRoot);if(i.startsWith(c+Kt.default.sep)||i===c)throw new Error(`<write-file>: cannot write to trusted harness path '${r}'`)}let o=e.get(s)??"";Zt.default.mkdirSync(Kt.default.dirname(i),{recursive:!0}),Zt.default.writeFileSync(i,o,"utf8")}function Ua(t,e,n){let r=t.attrs.var??"",s=t.attrs.item??"",i=t.children.find(l=>l.tag==="where"),o=t.children.find(l=>l.tag==="sort-by"),a=t.children.filter(l=>l.tag!=="where"&&l.tag!=="sort-by"),c=e.getArray(r);if(c){if(i&&(c=c.filter(l=>(e.set(s,l,void 0),ei(i,e)))),o){let l=o.attrs.key??"",d=o.attrs.type??"string",u=o.attrs.order??"asc";c=[...c].sort((m,p)=>{e.set(s,m,void 0);let f=e.resolve(`${s}.${l}`)??e.resolve(l)??"";e.set(s,p,void 0);let g=e.resolve(`${s}.${l}`)??e.resolve(l)??"",h=d==="number"?Number(f)-Number(g):f.localeCompare(g);return u==="desc"?-h:h})}for(let l of c){e.set(s,l,void 0);for(let d of a)Ks(d,e,n)}}}function Ks(t,e,n){switch(t.tag){case"shell":Xr(t,e,n.config);break;case"string-op":Zr(t,e);break;case"json-parse":Wa(t,e);break;case"read-file":qa(t,e);break;case"write-file":La(t,e,n);break;case"display":Na(t,e,n);break;case"for-each":Ua(t,e,n);break;case"if":{let r=Qr(t,e),s=t.children.find(a=>a.tag==="then"),i=t.children.find(a=>a.tag==="else"),o=r?s:i;if(o)for(let a of o.children)Ks(a,e,n);break}case"gsd-execute":Qs(t,e,n);break;default:break}}function Qs(t,e,n){try{for(let r of t.children)Ks(r,e,n)}catch(r){throw r instanceof yt||r instanceof Error?new bs(r,e.snapshot(),`Execution failed: ${r.message}`):r}}var Zt,Kt,bs,er=N(()=>{"use strict";Zt=W(require("fs")),Kt=W(require("path"));xs();Zs();ti();Yt();bs=class extends Error{constructor(n,r,s){super(s);this.cause=n;this.variableSnapshot=r;this.name="WxpExecutionError"}cause;variableSnapshot}});function ni(t,e){let n=ft(t),r=/<gsd-paste\s+name="([^"]+)"\s*\/>/g,s=[],i;for(;(i=r.exec(t))!==null;)gt(i.index,n)||s.push({index:i.index,full:i[0],name:i[1]});for(let a of s)if(e.get(a.name)===void 0)throw new vs(a.name,e.snapshot());let o=t;for(let a=s.length-1;a>=0;a--){let c=s[a],l=e.get(c.name);o=o.slice(0,c.index)+l+o.slice(c.index+c.full.length)}return o}var vs,tr=N(()=>{"use strict";Ys();vs=class extends Error{constructor(n,r){super(`<gsd-paste name="${n}" /> references undefined variable '${n}'`);this.variableName=n;this.variableSnapshot=r;this.name="WxpPasteError"}variableName;variableSnapshot}});function ri(t,e,n,r,s,i="",o=za){let a=Xs(e,n,r,s);if(!a.ok)throw new St(e,new Error(a.reason),{},[],[]);return Ga(t,e,n,r,s,i,o)}function Ga(t,e,n,r,s,i,o){let a=zr(),c=[],l=t,d={config:n,projectRoot:r,pkgRoot:s,onDisplay:o};for(let u=0;u<Va;u++){let p=Jt(l).filter(g=>g.node.tag!=="gsd-version");if(p.length===0)break;let f=p.map(g=>g.node.tag);try{let g=!1;for(let x of Jt(l)){if(x.node.tag!=="gsd-include"||gt(x.start,ft(l)))continue;let S=x.node.attrs.path;if(!S)continue;let _=Qt.default.resolve(Qt.default.dirname(e),S),P=Xs(_,n,r,s);if(!P.ok)throw new Error(`Include rejected: ${P.reason}`);let k=si.default.readFileSync(_,"utf8"),C=Qt.default.basename(_,Qt.default.extname(_));for(let $ of x.node.children)if($.tag==="gsd-arguments")for(let q of $.children.filter(O=>O.tag==="arg")){let O=q.attrs.name,U=q.attrs.as;if(O&&U){let Y=a.get(O);Y!==void 0&&a.set(U,Y,C)}}let L="include-arguments"in x.node.attrs?`
|
|
339
339
|
${i}`:"";l=gs(l,x.start,x.end,k+L),c.push("gsd-include"),g=!0;break}if(g)continue;for(let x of Jt(l))if(x.node.tag==="gsd-arguments"&&!gt(x.start,ft(l))){Br(x.node,i,a),l=gs(l,x.start,x.end,""),c.push("gsd-arguments"),g=!0;break}if(g)continue;for(let x of Jt(l))if(x.node.tag==="gsd-execute"&&!gt(x.start,ft(l))){Qs(x.node,a,d),l=gs(l,x.start,x.end,""),c.push("gsd-execute"),g=!0;break}if(g)continue;let h=ni(l,a);if(h!==l){l=h,c.push("gsd-paste");continue}break}catch(g){if(g instanceof St)throw g;let h=g instanceof Error?g:new Error(String(g));throw new St(e,h,a.snapshot(),f,c)}}return l}var si,Qt,Va,za,St,ii=N(()=>{"use strict";si=W(require("fs")),Qt=W(require("path"));Ys();Gr();Hs();er();tr();Yt();er();xs();tr();Zs();Hs();Va=50,za=()=>{},St=class extends Error{constructor(n,r,s,i,o){super(["WXP Processing Error",`File: ${n}`,`Error: ${r.message}`,`Variable Namespace: ${JSON.stringify(s,null,2)}`,`Pending Operations: [${i.join(", ")}]`,`Completed Operations: [${o.join(", ")}]`].join(`
|
|
340
|
-
`));this.filePath=n;this.cause=r;this.variableSnapshot=s;this.pendingOperations=i;this.completedOperations=o;this.name="WxpProcessingError"}filePath;cause;variableSnapshot;pendingOperations;completedOperations}});var bt,oi,nr,_s,ai=N(()=>{"use strict";bt=require("@oclif/core"),oi=require("@oclif/core"),nr=W(require("path"));ii();Yt();_s=class t extends oi.Command{static description="Process WXP tags in a workflow file";static args={file:bt.Args.string({description:"File to process",required:!1})};static flags={input:bt.Flags.string({description:"Input content string (alternative to file)"}),arguments:bt.Flags.string({description:"Raw $ARGUMENTS string",default:""}),"project-root":bt.Flags.string({description:"Project root directory",default:process.cwd()}),"pkg-root":bt.Flags.string({description:"Package root directory",default:process.cwd()})};async run(){let{flags:e,args:n}=await this.parse(t),r,s;if(e.input!==void 0)r=e.input,s=nr.default.join(e["project-root"],".pi","gsd","workflows","_inline.md");else if(n.file){let o=await import("fs");s=nr.default.resolve(n.file),r=o.default.readFileSync(s,"utf8")}else{this.error("Provide a file argument or --input string");return}let i={trustedPaths:[{position:"project",path:".pi/gsd"},{position:"pkg",path:".gsd/harnesses/pi/get-shit-done"}],untrustedPaths:[],shellAllowlist:[...Jr],shellBanlist:[],shellTimeoutMs:3e4};try{let o=ri(r,s,i,e["project-root"],e["pkg-root"],e.arguments);process.stdout.write(o)}catch(o){throw o instanceof St&&this.error(o.message,{exit:1}),o}}}});var ci={};he(ci,{AuditUatCommand:()=>Jn,CommitCommand:()=>ss,ConfigEnsureSectionCommand:()=>En,ConfigGetCommand:()=>$n,ConfigNewProjectCommand:()=>Rn,ConfigSetCommand:()=>An,ConfigSetModelProfileCommand:()=>jn,FrontmatterGetCommand:()=>rs,FrontmatterMergeCommand:()=>os,FrontmatterSetCommand:()=>is,InitCommand:()=>vn,MilestoneCompleteCommand:()=>qn,PhaseAddCommand:()=>Mn,PhaseCompleteCommand:()=>Dn,PhaseInsertCommand:()=>In,PhaseNextDecimalCommand:()=>Fn,PhasePlanIndexCommand:()=>On,PhaseRemoveCommand:()=>Tn,ProgressCommand:()=>ds,RequirementsMarkCompleteCommand:()=>Ln,RoadmapAnalyzeCommand:()=>kn,RoadmapGetPhaseCommand:()=>Pn,RoadmapUpdatePlanProgressCommand:()=>Cn,ScaffoldCommand:()=>ts,StateAdvancePlanCommand:()=>gn,StateGetCommand:()=>mn,StateJsonCommand:()=>un,StateLoadCommand:()=>hn,StatePatchCommand:()=>fn,StateUpdateCommand:()=>pn,StateUpdateProgressCommand:()=>yn,StatsCommand:()=>us,SummaryExtractCommand:()=>fs,TemplateFillCommand:()=>ls,TemplateSelectCommand:()=>cs,TodoCompleteCommand:()=>ms,TodoMatchPhaseCommand:()=>ps,ValidateAgentsCommand:()=>Gn,ValidateConsistencyCommand:()=>Vn,ValidateHealthCommand:()=>zn,VerifyCommand:()=>Bn,WorkstreamCompleteCommand:()=>Zn,WorkstreamCreateCommand:()=>Yn,WorkstreamGetCommand:()=>Qn,WorkstreamListCommand:()=>Hn,WorkstreamProgressCommand:()=>es,WorkstreamSetCommand:()=>Kn,WorkstreamStatusCommand:()=>Xn,WxpProcessCommand:()=>_s});var li=N(()=>{"use strict";br();_r();kr();Ar();jr();Rr();Dr();Or();Nr();Wr();qr();Lr();Ur();ai()});var di=ki(($d,Ba)=>{Ba.exports={name:"pi-gsd",version:"2.0.
|
|
340
|
+
`));this.filePath=n;this.cause=r;this.variableSnapshot=s;this.pendingOperations=i;this.completedOperations=o;this.name="WxpProcessingError"}filePath;cause;variableSnapshot;pendingOperations;completedOperations}});var bt,oi,nr,_s,ai=N(()=>{"use strict";bt=require("@oclif/core"),oi=require("@oclif/core"),nr=W(require("path"));ii();Yt();_s=class t extends oi.Command{static description="Process WXP tags in a workflow file";static args={file:bt.Args.string({description:"File to process",required:!1})};static flags={input:bt.Flags.string({description:"Input content string (alternative to file)"}),arguments:bt.Flags.string({description:"Raw $ARGUMENTS string",default:""}),"project-root":bt.Flags.string({description:"Project root directory",default:process.cwd()}),"pkg-root":bt.Flags.string({description:"Package root directory",default:process.cwd()})};async run(){let{flags:e,args:n}=await this.parse(t),r,s;if(e.input!==void 0)r=e.input,s=nr.default.join(e["project-root"],".pi","gsd","workflows","_inline.md");else if(n.file){let o=await import("fs");s=nr.default.resolve(n.file),r=o.default.readFileSync(s,"utf8")}else{this.error("Provide a file argument or --input string");return}let i={trustedPaths:[{position:"project",path:".pi/gsd"},{position:"pkg",path:".gsd/harnesses/pi/get-shit-done"}],untrustedPaths:[],shellAllowlist:[...Jr],shellBanlist:[],shellTimeoutMs:3e4};try{let o=ri(r,s,i,e["project-root"],e["pkg-root"],e.arguments);process.stdout.write(o)}catch(o){throw o instanceof St&&this.error(o.message,{exit:1}),o}}}});var ci={};he(ci,{AuditUatCommand:()=>Jn,CommitCommand:()=>ss,ConfigEnsureSectionCommand:()=>En,ConfigGetCommand:()=>$n,ConfigNewProjectCommand:()=>Rn,ConfigSetCommand:()=>An,ConfigSetModelProfileCommand:()=>jn,FrontmatterGetCommand:()=>rs,FrontmatterMergeCommand:()=>os,FrontmatterSetCommand:()=>is,InitCommand:()=>vn,MilestoneCompleteCommand:()=>qn,PhaseAddCommand:()=>Mn,PhaseCompleteCommand:()=>Dn,PhaseInsertCommand:()=>In,PhaseNextDecimalCommand:()=>Fn,PhasePlanIndexCommand:()=>On,PhaseRemoveCommand:()=>Tn,ProgressCommand:()=>ds,RequirementsMarkCompleteCommand:()=>Ln,RoadmapAnalyzeCommand:()=>kn,RoadmapGetPhaseCommand:()=>Pn,RoadmapUpdatePlanProgressCommand:()=>Cn,ScaffoldCommand:()=>ts,StateAdvancePlanCommand:()=>gn,StateGetCommand:()=>mn,StateJsonCommand:()=>un,StateLoadCommand:()=>hn,StatePatchCommand:()=>fn,StateUpdateCommand:()=>pn,StateUpdateProgressCommand:()=>yn,StatsCommand:()=>us,SummaryExtractCommand:()=>fs,TemplateFillCommand:()=>ls,TemplateSelectCommand:()=>cs,TodoCompleteCommand:()=>ms,TodoMatchPhaseCommand:()=>ps,ValidateAgentsCommand:()=>Gn,ValidateConsistencyCommand:()=>Vn,ValidateHealthCommand:()=>zn,VerifyCommand:()=>Bn,WorkstreamCompleteCommand:()=>Zn,WorkstreamCreateCommand:()=>Yn,WorkstreamGetCommand:()=>Qn,WorkstreamListCommand:()=>Hn,WorkstreamProgressCommand:()=>es,WorkstreamSetCommand:()=>Kn,WorkstreamStatusCommand:()=>Xn,WxpProcessCommand:()=>_s});var li=N(()=>{"use strict";br();_r();kr();Ar();jr();Rr();Dr();Or();Nr();Wr();qr();Lr();Ur();ai()});var di=ki(($d,Ba)=>{Ba.exports={name:"pi-gsd",version:"2.0.6",description:"Get Shit Done - Unofficial port of the renowned AI-native project-planning spec-driven toolkit",main:"dist/pi-gsd-tools.js",bin:{"pi-gsd-tools":"./dist/pi-gsd-tools.js","pi-gsd":"./dist/pi-gsd-tools.js"},scripts:{build:"tsup",dev:"tsup src/cli.ts --format cjs --out-dir dist --watch",typecheck:"tsc --noEmit",check:"tsc --noEmit && npm run build",postinstall:"node scripts/postinstall.js",prepublishOnly:"npm run build",test:"vitest run","test:unit":"vitest run src/wxp/__tests__ --ignore src/wxp/__tests__/integration.test.ts","test:integration":"vitest run src/wxp/__tests__/integration.test.ts",lint:"eslint src/ --ext .ts"},files:["dist","scripts/postinstall.js",".gsd/harnesses","README.md","LICENSE","prompts"],engines:{node:">=18.0.0"},keywords:["ai","agent","planning","cli","workflow","get-shit-done","gsd","productivity","project-management","milestones","phases","spec","pi-package"],author:"Alessio Corsi",license:"MIT",repository:{type:"git",url:"https://github.com/fulgidus/pi-gsd.git"},bugs:{url:"https://github.com/fulgidus/pi-gsd/issues"},homepage:"https://github.com/fulgidus/pi-gsd#readme",publishConfig:{access:"public",registry:"https://registry.npmjs.org/"},pi:{extensions:["./dist/pi-gsd-hooks.js"],prompts:["./prompts"]},dependencies:{"@oclif/core":"^4.10.5","@toon-format/toon":"^2.1.0","jsonpath-plus":"^10.4.0",zod:"^3.25.76"},devDependencies:{"@mariozechner/pi-coding-agent":"^0.65.0","@types/node":"^22.0.0","@typescript-eslint/eslint-plugin":"^8.58.0","@typescript-eslint/parser":"^8.58.0",eslint:"^10.2.0",tsup:"^8.0.0",typescript:"^5.0.0",vitest:"^4.1.2"}}});var ws={};he(ws,{cmdExtractMessages:()=>Za,cmdProfileSample:()=>Ka,cmdScanSessions:()=>Xa});function sr(t){if(t)return t;let e=process.env.HOME??"",n=Ie.join(e,".agent","projects");return ee.existsSync(n)?n:Ie.join(e,".claude","projects")}function rr(){let t=process.env.HOME??"";return Ie.join(t,".pi","agent","sessions")}function ir(t){return t.startsWith("--")&&t.endsWith("--")?"/"+t.slice(2,-2).replace(/-/g,"/"):t}function Ja(t){try{let e=ee.readFileSync(t,"utf-8").split(`
|
|
341
341
|
`).find(r=>r.trim().length>0);if(!e)return!1;let n=JSON.parse(e);return n.type==="session"&&"version"in n}catch{return!1}}function Ya(t){return typeof t=="string"?t:Array.isArray(t)?t.filter(e=>e!==null&&typeof e=="object"&&e.type==="text").map(e=>String(e.text??"")).join(" "):""}function Ha(t){try{let e=ee.readFileSync(t,"utf-8").split(`
|
|
342
342
|
`).filter(Boolean),n=[];for(let r of e)try{let s=JSON.parse(r);s.type==="message"&&s.message&&n.push(s)}catch{}return n}catch{return[]}}async function Xa(t,e,n){let s=(e.harness??null)==="pi",i=rr(),o=ee.existsSync(i),a=[];if(o)try{let m=ee.readdirSync(i,{withFileTypes:!0}).filter(p=>p.isDirectory());for(let p of m){let f=Ie.join(i,p.name),g=ee.readdirSync(f).filter(h=>h.endsWith(".jsonl"));a.push({name:p.name,sessions:g.length,path:f,source:"pi",cwd:ir(p.name)})}}catch{}let c=sr(s&&!t?null:t),l=!s||t?ee.existsSync(c):!1,d=[];if(l&&(!s||t))try{let m=ee.readdirSync(c,{withFileTypes:!0}).filter(p=>p.isDirectory());for(let p of m){let f=Ie.join(c,p.name),g=ee.readdirSync(f).filter(h=>h.endsWith(".jsonl")||h.endsWith(".json"));d.push({name:p.name,sessions:g.length,path:f,source:"claude"})}}catch{}let u=s?[...a,...d]:[...d,...a];if(u.length===0){let m=[];o?m.push(i):m.push(i+" (not found)"),s||m.push(l?c:c+" (not found)"),y({available:!1,reason:`No sessions found. Searched: ${m.join(", ")}`,projects:[],count:0},n);return}y({available:!0,pi_base:o?i:null,claude_base:l?c:null,projects:u,count:u.length},n)}async function Za(t,e,n,r){let s=rr(),i=null,o="claude";if(ee.existsSync(s)){let d=Ie.join(s,t);if(ee.existsSync(d))i=d,o="pi";else try{let u=ee.readdirSync(s,{withFileTypes:!0}).filter(m=>m.isDirectory());for(let m of u){let p=ir(m.name);if(p.endsWith("/"+t)||p===t||m.name===t){i=Ie.join(s,m.name),o="pi";break}}}catch{}}if(!i){let d=sr(r),u=Ie.join(d,t);ee.existsSync(u)&&(i=u,o="claude")}if(!i){y({error:`Project not found: ${t}`,available_projects:[]},n);return}let a=[],c=ee.readdirSync(i).filter(d=>d.endsWith(".jsonl")),l=e.limit??null;for(let d of c){if(e.sessionId&&!d.includes(e.sessionId))continue;let u=Ie.join(i,d);if(o==="pi"||Ja(u))try{let m=ee.readFileSync(u,"utf-8").split(`
|
|
343
343
|
`).filter(Boolean);for(let p of m)try{let f=JSON.parse(p);if(f.type==="message"&&f.message&&(a.push(f.message),l&&a.length>=l))break}catch{}}catch{}else try{let m=ee.readFileSync(u,"utf-8").split(`
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Gather phase context. Args: phase (number)
|
|
2
|
+
description: Gather phase context. Args: phase (number) - Flags: --auto
|
|
3
3
|
---
|
|
4
4
|
<gsd-include path=".pi/gsd/workflows/discuss-phase.md" include-arguments />
|
|
5
5
|
<gsd-include path=".pi/gsd/workflows/discuss-phase-assumptions.md" include-arguments />
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Execute all plans in a phase. Args: phase (number)
|
|
2
|
+
description: Execute all plans in a phase. Args: phase (number) - Flags: --auto (skip transition), --wave N (single wave), --interactive
|
|
3
3
|
---
|
|
4
4
|
<gsd-include path=".pi/gsd/workflows/execute-phase.md" include-arguments />
|
|
5
5
|
<gsd-include path=".pi/gsd/references/ui-brand.md" />
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Plan a phase with research→plan→verify loop. Args: phase (number)
|
|
2
|
+
description: Plan a phase with research→plan→verify loop. Args: phase (number) - Flags: --auto, --skip-research, --gaps, --text
|
|
3
3
|
---
|
|
4
4
|
<gsd-include path=".pi/gsd/workflows/plan-phase.md" include-arguments />
|
|
5
5
|
<gsd-include path=".pi/gsd/references/ui-brand.md" select="tag:core" />
|
package/prompts/gsd-quick.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Run UAT for a phase. Args: phase (number)
|
|
2
|
+
description: Run UAT for a phase. Args: phase (number) - Flags: --plan N (specific plan only)
|
|
3
3
|
---
|
|
4
4
|
<gsd-include path=".pi/gsd/workflows/verify-work.md" include-arguments />
|
|
5
5
|
<gsd-include path=".pi/gsd/templates/UAT.md" />
|