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.
Files changed (46) hide show
  1. package/.gsd/harnesses/pi/get-shit-done/workflows/add-phase.md +1 -1
  2. package/.gsd/harnesses/pi/get-shit-done/workflows/add-tests.md +1 -1
  3. package/.gsd/harnesses/pi/get-shit-done/workflows/add-todo.md +1 -1
  4. package/.gsd/harnesses/pi/get-shit-done/workflows/audit-milestone.md +1 -1
  5. package/.gsd/harnesses/pi/get-shit-done/workflows/autonomous.md +6 -6
  6. package/.gsd/harnesses/pi/get-shit-done/workflows/check-todos.md +1 -1
  7. package/.gsd/harnesses/pi/get-shit-done/workflows/complete-milestone.md +2 -2
  8. package/.gsd/harnesses/pi/get-shit-done/workflows/discuss-phase-assumptions.md +1 -1
  9. package/.gsd/harnesses/pi/get-shit-done/workflows/discuss-phase.md +1 -1
  10. package/.gsd/harnesses/pi/get-shit-done/workflows/do.md +1 -1
  11. package/.gsd/harnesses/pi/get-shit-done/workflows/execute-milestone.md +38 -38
  12. package/.gsd/harnesses/pi/get-shit-done/workflows/execute-plan.md +1 -1
  13. package/.gsd/harnesses/pi/get-shit-done/workflows/insert-phase.md +1 -1
  14. package/.gsd/harnesses/pi/get-shit-done/workflows/list-workspaces.md +1 -1
  15. package/.gsd/harnesses/pi/get-shit-done/workflows/manager.md +2 -2
  16. package/.gsd/harnesses/pi/get-shit-done/workflows/map-codebase.md +1 -1
  17. package/.gsd/harnesses/pi/get-shit-done/workflows/milestone-summary.md +1 -1
  18. package/.gsd/harnesses/pi/get-shit-done/workflows/new-milestone.md +1 -1
  19. package/.gsd/harnesses/pi/get-shit-done/workflows/new-project.md +1 -1
  20. package/.gsd/harnesses/pi/get-shit-done/workflows/new-workspace.md +1 -1
  21. package/.gsd/harnesses/pi/get-shit-done/workflows/pause-work.md +1 -1
  22. package/.gsd/harnesses/pi/get-shit-done/workflows/plan-milestone.md +8 -8
  23. package/.gsd/harnesses/pi/get-shit-done/workflows/progress.md +1 -1
  24. package/.gsd/harnesses/pi/get-shit-done/workflows/quick.md +1 -1
  25. package/.gsd/harnesses/pi/get-shit-done/workflows/remove-phase.md +1 -1
  26. package/.gsd/harnesses/pi/get-shit-done/workflows/remove-workspace.md +1 -1
  27. package/.gsd/harnesses/pi/get-shit-done/workflows/research-phase.md +1 -1
  28. package/.gsd/harnesses/pi/get-shit-done/workflows/resume-project.md +1 -1
  29. package/.gsd/harnesses/pi/get-shit-done/workflows/review.md +1 -1
  30. package/.gsd/harnesses/pi/get-shit-done/workflows/settings.md +1 -1
  31. package/.gsd/harnesses/pi/get-shit-done/workflows/ship.md +1 -1
  32. package/.gsd/harnesses/pi/get-shit-done/workflows/ui-phase.md +1 -1
  33. package/.gsd/harnesses/pi/get-shit-done/workflows/ui-review.md +1 -1
  34. package/.gsd/harnesses/pi/get-shit-done/workflows/validate-phase.md +1 -1
  35. package/.gsd/harnesses/pi/get-shit-done/workflows/verify-phase.md +1 -1
  36. package/.gsd/harnesses/pi/get-shit-done/workflows/verify-work.md +1 -1
  37. package/README.md +60 -60
  38. package/dist/pi-gsd-hooks.js +4 -4
  39. package/dist/pi-gsd-tools.js +2 -2
  40. package/package.json +1 -1
  41. package/prompts/gsd-discuss-phase.md +1 -1
  42. package/prompts/gsd-execute-phase.md +1 -1
  43. package/prompts/gsd-plan-phase.md +1 -1
  44. package/prompts/gsd-quick.md +1 -1
  45. package/prompts/gsd-verify-work.md +1 -1
  46. 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 variables available via <gsd-paste name="..."> -->
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 variables available via <gsd-paste name="..."> -->
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
  [![npm version](https://img.shields.io/npm/v/pi-gsd.svg)](https://www.npmjs.com/package/pi-gsd)
6
6
  [![license: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](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 all backed by a git-committed `.planning/` directory that survives context resets.
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` 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 |
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/` committed to git, survives `/clear` and context resets.
52
+ All project state lives in `.planning/` - committed to git, survives `/clear` and context resets.
53
53
 
54
54
  ---
55
55
 
56
- ## WXP Workflow XML Preprocessor
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 so the LLM receives clean, data-rich context with zero bash tool calls for setup.
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 | 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 |
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 run `pi-gsd-tools --help` or `pi-gsd-tools <command> --help` for the full reference.
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 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 |
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
- | | 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 | | |
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
- | 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) | | ✔️ |
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 unofficial port. Original GSD by [Get Shit Done](https://github.com/gsd-build/get-shit-done).
225
+ MIT - unofficial port. Original GSD by [Get Shit Done](https://github.com/gsd-build/get-shit-done).
@@ -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 \u2014 use it alone: " + selectExpr);
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 \u2014 start with discussion`;
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 \u2014 continue execution`;
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 \u2014 verify UAT`;
1429
+ reason = `Phase ${n}: all plans done - verify UAT`;
1430
1430
  }
1431
1431
  ctx.ui.notify(
1432
1432
  [
@@ -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}" \u2014 ${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
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.4",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(`
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,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-gsd",
3
- "version": "2.0.4",
3
+ "version": "2.0.6",
4
4
  "description": "Get Shit Done - Unofficial port of the renowned AI-native project-planning spec-driven toolkit",
5
5
  "main": "dist/pi-gsd-tools.js",
6
6
  "bin": {
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Gather phase context. Args: phase (number) Flags: --auto
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) Flags: --auto (skip transition), --wave N (single wave), --interactive
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) Flags: --auto, --skip-research, --gaps, --text
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" />
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Quick tracked task. Args: task (string, greedy) Flags: --no-commit
2
+ description: Quick tracked task. Args: task (string, greedy) - Flags: --no-commit
3
3
  ---
4
4
  <gsd-include path=".pi/gsd/workflows/quick.md" include-arguments />
5
5
 
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Run UAT for a phase. Args: phase (number) Flags: --plan N (specific plan only)
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" />