pi-gsd 2.0.21 → 2.0.22

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.
@@ -0,0 +1,215 @@
1
+ <gsd-version v="1.12.4" />
2
+
3
+ <gsd-arguments>
4
+ <settings>
5
+ <keep-extra-args />
6
+ </settings>
7
+ <arg name="subcommand" type="string" optional />
8
+ <arg name="name" type="string" optional />
9
+ </gsd-arguments>
10
+
11
+ <gsd-execute>
12
+ <display msg="Loading workstream state..." />
13
+ <shell command="pi-gsd-tools">
14
+ <args>
15
+ <arg string="workstream" />
16
+ <arg string="list" />
17
+ <arg string="--raw" />
18
+ </args>
19
+ <outs>
20
+ <suppress-errors />
21
+ <out type="string" name="ws-list" />
22
+ </outs>
23
+ </shell>
24
+ <shell command="pi-gsd-tools">
25
+ <args>
26
+ <arg string="workstream" />
27
+ <arg string="get" />
28
+ <arg string="--raw" />
29
+ </args>
30
+ <outs>
31
+ <suppress-errors />
32
+ <out type="string" name="ws-active" />
33
+ </outs>
34
+ </shell>
35
+ <shell command="pi-gsd-tools">
36
+ <args>
37
+ <arg string="state" />
38
+ <arg string="json" />
39
+ <arg string="--raw" />
40
+ </args>
41
+ <outs>
42
+ <suppress-errors />
43
+ <out type="string" name="state" />
44
+ </outs>
45
+ </shell>
46
+ </gsd-execute>
47
+
48
+ ## Workstream Context (pre-injected by WXP)
49
+
50
+ **Subcommand:** <gsd-paste name="subcommand" />
51
+ **Name:** <gsd-paste name="name" />
52
+
53
+ **Active workstream:** <gsd-paste name="ws-active" />
54
+
55
+ **Workstream list:**
56
+ <gsd-paste name="ws-list" />
57
+
58
+ **State:**
59
+ <gsd-paste name="state" />
60
+
61
+ ---
62
+
63
+ <purpose>
64
+ Manage GSD workstreams — isolated parallel tracks of work within a project.
65
+ Each workstream has its own ROADMAP.md, STATE.md, and phase history.
66
+
67
+ Subcommands: list, create &lt;name&gt;, switch &lt;name&gt;, status [name], complete &lt;name&gt;
68
+ </purpose>
69
+
70
+ <process>
71
+
72
+ <step name="route">
73
+ <!-- Context pre-injected above via WXP -->
74
+
75
+ Parse `subcommand` and `name` from injected variables.
76
+
77
+ **Route by subcommand:**
78
+
79
+ | Subcommand | Action |
80
+ |------------|--------|
81
+ | `list` (or empty) | → **list_workstreams** |
82
+ | `create <name>` | → **create_workstream** |
83
+ | `switch <name>` | → **switch_workstream** |
84
+ | `status [name]` | → **show_status** |
85
+ | `complete <name>` | → **complete_workstream** |
86
+
87
+ **If subcommand is unrecognised:** Show help (see offer_help step).
88
+ </step>
89
+
90
+ <step name="list_workstreams">
91
+ <!-- ws-list and ws-active are pre-injected -->
92
+
93
+ Parse `ws-list` JSON for workstream entries. Display:
94
+
95
+ ```
96
+ ## Workstreams
97
+
98
+ Active: {ws-active || "(none — on main planning root)"}
99
+
100
+ | Name | Status | Phases | Progress |
101
+ |------|--------|--------|---------|
102
+ | {name} | {active|inactive} | {phase_count} | {pct}% |
103
+ | ... | ... | ... | ... |
104
+
105
+ ---
106
+ /gsd-workstreams create <name> - create a new workstream
107
+ /gsd-workstreams switch <name> - switch to a workstream
108
+ /gsd-workstreams status <name> - detailed workstream status
109
+ /gsd-workstreams complete <name> - close a workstream
110
+ ```
111
+
112
+ **If no workstreams exist:**
113
+ ```
114
+ No workstreams yet. You're working in the main planning root.
115
+
116
+ Create a workstream to isolate parallel work:
117
+ /gsd-workstreams create <name>
118
+ ```
119
+ </step>
120
+
121
+ <step name="create_workstream">
122
+ **Require `name`:**
123
+ If `name` is empty, ask: "Workstream name? (lowercase, no spaces — e.g. mobile-app, api-v2)"
124
+
125
+ Validate: lowercase alphanumeric with hyphens/underscores only.
126
+
127
+ ```bash
128
+ pi-gsd-tools workstream create {name}
129
+ ```
130
+
131
+ Confirm:
132
+ ```
133
+ ✓ Workstream '{name}' created
134
+
135
+ To switch to it: /gsd-workstreams switch {name}
136
+ ```
137
+ </step>
138
+
139
+ <step name="switch_workstream">
140
+ **Require `name`:** If empty, list available workstreams and ask user to choose.
141
+
142
+ ```bash
143
+ pi-gsd-tools workstream set {name}
144
+ ```
145
+
146
+ Confirm:
147
+ ```
148
+ ✓ Switched to workstream: {name}
149
+
150
+ All subsequent GSD commands will operate within this workstream.
151
+ To return to main: /gsd-workstreams switch main
152
+ ```
153
+ </step>
154
+
155
+ <step name="show_status">
156
+ **Target:** `name` if provided, otherwise the active workstream.
157
+
158
+ ```bash
159
+ pi-gsd-tools workstream status {name}
160
+ ```
161
+
162
+ Display the full status output including phase progress, open todos, and blockers.
163
+ </step>
164
+
165
+ <step name="complete_workstream">
166
+ **Require `name`:** If empty, ask which workstream to complete.
167
+
168
+ Confirm before completing:
169
+ ```
170
+ Complete workstream '{name}'?
171
+
172
+ This will:
173
+ - Mark all phases as complete
174
+ - Archive the workstream planning files
175
+
176
+ Continue? (yes / no)
177
+ ```
178
+
179
+ If yes:
180
+ ```bash
181
+ pi-gsd-tools workstream complete {name}
182
+ ```
183
+
184
+ Confirm:
185
+ ```
186
+ ✓ Workstream '{name}' completed and archived.
187
+ ```
188
+ </step>
189
+
190
+ <step name="offer_help">
191
+ ```
192
+ ## /gsd-workstreams
193
+
194
+ Manage parallel tracks of work within a project.
195
+
196
+ Usage:
197
+ /gsd-workstreams - list all workstreams
198
+ /gsd-workstreams create <name> - create a new workstream
199
+ /gsd-workstreams switch <name> - activate a workstream
200
+ /gsd-workstreams status [name] - show workstream details
201
+ /gsd-workstreams complete <name> - close a finished workstream
202
+
203
+ Current: {ws-active || "main planning root"}
204
+ ```
205
+ </step>
206
+
207
+ </process>
208
+
209
+ <success_criteria>
210
+ - [ ] Active workstream pre-injected (no runtime read needed)
211
+ - [ ] Workstream list pre-injected
212
+ - [ ] Subcommand routed correctly
213
+ - [ ] Each action calls the appropriate CLI command
214
+ - [ ] Confirmations displayed after mutations
215
+ </success_criteria>
@@ -129,7 +129,7 @@
129
129
  "get-shit-done/workflows/ship.md": "1057dbd67b07b420b11adaea9c63a1a7c29ca01c33e8f9d2e8eba8fc61b2e3f7",
130
130
  "get-shit-done/workflows/stats.md": "cbb11eec34f93399e7cc5cf7a19746f11448e840a38c0316688ef8be6ad7e7bf",
131
131
  "get-shit-done/workflows/transition.md": "15b767cabdc476782cdad7d3b9081e3d599316455a76d44866d66e1bb78e1db0",
132
- "get-shit-done/workflows/ui-phase.md": "5e3cccd0b2b868174fafd8cbba638b0d40b917fd0ebb9b0029dc0ebc1b25e8f0",
132
+ "get-shit-done/workflows/ui-phase.md": "e7bd715dc7e2d5d113f52c7b3816023af130c5b9d23762d64e5c11aee07dbe83",
133
133
  "get-shit-done/workflows/ui-review.md": "6e99be78108e16ef325442692667d77d864759ffe8f6379a8f4ec011964999b3",
134
134
  "get-shit-done/workflows/update.md": "01371fe2bdda4aa84d3dc1dff7ab4f016d5b6b6411d99e8b7c6a38aadf0d53e1",
135
135
  "get-shit-done/workflows/validate-phase.md": "a60a09bb99161270b3dbc5539f0b93a8436747ebca56ba2dfa75f937e0e53261",
@@ -339,7 +339,7 @@ ${p}
339
339
  `,h=Jt.default.join(t,s.directory,f);if(cs.default.existsSync(h)){y({error:"File already exists",path:J(Jt.default.relative(t,h))},r);return}cs.default.writeFileSync(h,Ie(g),"utf-8");let x=J(Jt.default.relative(t,h));y({created:!0,path:x,template:e},r,x)}var cs,Jt,Xs=L(()=>{"use strict";cs=U(require("fs")),Jt=U(require("path"));ye();Ve()});var Ye,ls,ds,zr=L(()=>{"use strict";Ye=require("@oclif/core");je();ls=class t extends w{static description="Select a workflow template";static args={type:Ye.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(()=>(Xs(),Hs));i(r,n.type,s)}},ds=class t extends w{static description="Fill a template with values";static args={type:Ye.Args.string({required:!0})};static flags={...w.baseFlags,phase:Ye.Flags.string(),plan:Ye.Flags.string(),name:Ye.Flags.string(),type:Ye.Flags.string({char:"t"}),wave:Ye.Flags.string(),fields:Ye.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(()=>(Xs(),Hs)),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 Ft,us,ms,ps,fs,gs,Br=L(()=>{"use strict";Ft=require("@oclif/core");je();us=class t extends w{static description="Show project progress";static args={format:Ft.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(()=>(_e(),ve));i(r,n.format,s)}},ms=class t extends w{static description="Show project statistics";static args={format:Ft.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(()=>(_e(),ve));i(r,n.format,s)}},ps=class t extends w{static description="Mark a todo as complete";static args={id:Ft.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(()=>(_e(),ve));i(r,n.id,s)}},fs=class t extends w{static description="Match todos to phase";static args={phase:Ft.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(()=>(_e(),ve));i(r,n.phase,s)}},gs=class t extends w{static description="Extract fields from summary files";static args={phase:Ft.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(()=>(_e(),ve)),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 Na(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 Gr(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=Na(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=Gr(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 Yt(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(!Wa.has(o))continue;let a=Gr(t,i);a&&(n.push({node:a.node,start:i,end:a.end}),r.lastIndex=a.end)}return n}function hs(t,e,n,r){return t.slice(0,e)+r+t.slice(n)}var Wa,Zs=L(()=>{"use strict";Wa=new Set(["gsd-execute","gsd-arguments","gsd-paste","gsd-include","gsd-version"])});function Jr(){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 Yr=L(()=>{"use strict"});function Hr(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"?`
340
340
  `: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",v=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"&&v)n.set(x,m.slice(p).join(" "),void 0),p=m.length;else if(S==="number"){let $=m[p++],P=Number($);if(isNaN(P))throw new ht(`Argument '${x}' expected a number, got '${$}'`);n.set(x,String(P),void 0)}else if(S==="boolean"){let $=m[p++].toLowerCase();if($!=="true"&&$!=="false")throw new ht(`Argument '${x}' expected true/false, got '${$}'`);n.set(x,$,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,Ks=L(()=>{"use strict";ht=class extends Error{constructor(e){super(e),this.name="WxpArgumentsError"}}});function ys(t,e,n){switch(t.position){case"project":return He.default.resolve(e,t.path);case"pkg":return He.default.resolve(n,t.path);case"absolute":return He.default.resolve(t.path)}}function Qs(t,e,n,r){let s=He.default.resolve(t),i=`${He.default.sep}.planning`;if(s.includes(`${i}${He.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=ys(o,n,r);if(s.startsWith(a+He.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=ys(o,n,r);if(s.startsWith(a+He.default.sep)||s===a)return{ok:!0}}return{ok:!1,reason:`File '${t}' is not in a trusted WXP path.`}}function Zr(t,e){let n=He.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 He,Xr,Ht=L(()=>{"use strict";He=U(require("path")),Xr=["pi-gsd-tools","git","node","cat","ls","echo","find"]});function xs(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 Qr(t,e,n){let r=t.attrs.command??"",s=Zr(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=>xs(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,Kr.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 Kr,yt,Ss=L(()=>{"use strict";Kr=require("child_process");Ht();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 ei(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=xs(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?xs(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,er=L(()=>{"use strict";Ss();xt=class extends Error{constructor(e){super(e),this.name="WxpStringOpError"}}});function bs(t,e){return t.attrs.name?e.resolve(t.attrs.name)??"":t.attrs.value!==void 0?t.attrs.value:""}function ti(t){return t.attrs.type==="number"}function La(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(ti(n)||ti(r)){let a=Number(bs(n,e)),c=Number(bs(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=bs(n,e),o=bs(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 Zt(t,e){return t.tag==="and"?t.children.filter(n=>Xt.has(n.tag)).every(n=>Zt(n,e)):t.tag==="or"?t.children.filter(n=>Xt.has(n.tag)).some(n=>Zt(n,e)):La(t,e)}function ni(t,e){let n=t.children.find(s=>s.tag==="condition");if(!n)return!1;let r=n.children.find(s=>Xt.has(s.tag));return r?Zt(r,e):!1}function si(t,e){let n=t.children.find(r=>Xt.has(r.tag));return n?Zt(n,e):!0}var qa,Xt,ri=L(()=>{"use strict";qa=new Set(["equals","not-equals","starts-with","contains","less-than","greater-than","less-than-or-equal","greater-than-or-equal"]),Xt=new Set([...qa,"and","or"])});function Ua(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 Va(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 za(t,e){let n=t.attrs.path??"",r=t.attrs.out??"",s=Kt.default.readFileSync(Qt.default.resolve(n),"utf8");e.set(r,s,void 0)}function Ba(t,e,n){let r=t.attrs.path??"",s=t.attrs.src??"",i=Qt.default.resolve(r);if(Kt.default.existsSync(i))throw new Error(`<write-file>: '${r}' already exists (create-only, never overwrites)`);for(let a of n.config.trustedPaths){let c=ys(a,n.projectRoot,n.pkgRoot);if(i.startsWith(c+Qt.default.sep)||i===c)throw new Error(`<write-file>: cannot write to trusted harness path '${r}'`)}let o=e.get(s)??"";Kt.default.mkdirSync(Qt.default.dirname(i),{recursive:!0}),Kt.default.writeFileSync(i,o,"utf8")}function Ga(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),si(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)tr(d,e,n)}}}function tr(t,e,n){switch(t.tag){case"shell":Qr(t,e,n.config);break;case"string-op":ei(t,e);break;case"json-parse":Va(t,e);break;case"read-file":za(t,e);break;case"write-file":Ba(t,e,n);break;case"display":Ua(t,e,n);break;case"for-each":Ga(t,e,n);break;case"if":{let r=ni(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)tr(a,e,n);break}case"gsd-execute":nr(t,e,n);break;default:break}}function nr(t,e,n){try{for(let r of t.children)tr(r,e,n)}catch(r){throw r instanceof yt||r instanceof Error?new vs(r,e.snapshot(),`Execution failed: ${r.message}`):r}}var Kt,Qt,vs,sr=L(()=>{"use strict";Kt=U(require("fs")),Qt=U(require("path"));Ss();er();ri();Ht();vs=class extends Error{constructor(n,r,s){super(s);this.cause=n;this.variableSnapshot=r;this.name="WxpExecutionError"}cause;variableSnapshot}});function ii(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 _s(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 _s,rr=L(()=>{"use strict";Zs();_s=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 oi(t,e,n,r,s,i="",o=Ya){let a=Qs(e,n,r,s);if(!a.ok)throw new St(e,new Error(a.reason),{},[],[]);return Ha(t,e,n,r,s,i,o)}function Ha(t,e,n,r,s,i,o){let a=Jr(),c=[],l=t,d={config:n,projectRoot:r,pkgRoot:s,onDisplay:o};for(let u=0;u<Ja;u++){let p=Yt(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 Yt(l)){if(x.node.tag!=="gsd-include"||gt(x.start,ft(l)))continue;let S=x.node.attrs.path;if(!S)continue;let v=ws.default.resolve(r,S);if(!ir.default.existsSync(v))throw new Error(`Include not found: ${S}`);let $=Qs(v,n,r,s);if(!$.ok)throw new Error(`Include rejected: ${$.reason}`);let P=ir.default.readFileSync(v,"utf8"),C=ws.default.basename(v,ws.default.extname(v));for(let k of x.node.children)if(k.tag==="gsd-arguments")for(let j of k.children.filter(R=>R.tag==="arg")){let R=j.attrs.name,E=j.attrs.as;if(R&&E){let V=a.get(R);V!==void 0&&a.set(E,V,C)}}let T="include-arguments"in x.node.attrs?`
341
341
  ${i}`:"";l=hs(l,x.start,x.end,P+T),c.push("gsd-include"),g=!0;break}if(g)continue;for(let x of Yt(l))if(x.node.tag==="gsd-arguments"&&!gt(x.start,ft(l))){Hr(x.node,i,a),l=hs(l,x.start,x.end,""),c.push("gsd-arguments"),g=!0;break}if(g)continue;for(let x of Yt(l))if(x.node.tag==="gsd-execute"&&!gt(x.start,ft(l))){nr(x.node,a,d),l=hs(l,x.start,x.end,""),c.push("gsd-execute"),g=!0;break}if(g)continue;let h=ii(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 ir,ws,Ja,Ya,St,ai=L(()=>{"use strict";ir=U(require("fs")),ws=U(require("path"));Zs();Yr();Ks();sr();rr();Ht();sr();Ss();rr();er();Ks();Ja=50,Ya=()=>{},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(`
342
- `));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,ci,or,ks,li=L(()=>{"use strict";bt=require("@oclif/core"),ci=require("@oclif/core"),or=U(require("path"));ai();Ht();ks=class t extends ci.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=or.default.join(e["project-root"],".pi","gsd","workflows","_inline.md");else if(n.file){let o=await import("fs");s=or.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:[...Xr],shellBanlist:[],shellTimeoutMs:3e4};try{let o=oi(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 di={};xe(di,{AuditUatCommand:()=>Yn,CommitCommand:()=>rs,ConfigEnsureSectionCommand:()=>Fn,ConfigGetCommand:()=>An,ConfigNewProjectCommand:()=>En,ConfigSetCommand:()=>jn,ConfigSetModelProfileCommand:()=>Rn,FrontmatterGetCommand:()=>is,FrontmatterMergeCommand:()=>as,FrontmatterSetCommand:()=>os,InitCommand:()=>_n,MilestoneCompleteCommand:()=>Ln,PhaseAddCommand:()=>In,PhaseCompleteCommand:()=>On,PhaseInsertCommand:()=>Tn,PhaseNextDecimalCommand:()=>Mn,PhasePlanIndexCommand:()=>Nn,PhaseRemoveCommand:()=>Dn,ProgressCommand:()=>us,RequirementsMarkCompleteCommand:()=>Un,RoadmapAnalyzeCommand:()=>Pn,RoadmapGetPhaseCommand:()=>$n,RoadmapUpdatePlanProgressCommand:()=>Cn,ScaffoldCommand:()=>ns,StateAdvancePlanCommand:()=>gn,StateGetCommand:()=>mn,StateJsonCommand:()=>un,StateLoadCommand:()=>hn,StatePatchCommand:()=>fn,StateReconcileCommand:()=>xn,StateUpdateCommand:()=>pn,StateUpdateProgressCommand:()=>yn,StatsCommand:()=>ms,SummaryExtractCommand:()=>gs,TemplateFillCommand:()=>ds,TemplateSelectCommand:()=>ls,TodoCompleteCommand:()=>ps,TodoMatchPhaseCommand:()=>fs,ValidateAgentsCommand:()=>Gn,ValidateConsistencyCommand:()=>zn,ValidateHealthCommand:()=>Bn,VerifyCommand:()=>Jn,WorkstreamCompleteCommand:()=>Kn,WorkstreamCreateCommand:()=>Hn,WorkstreamGetCommand:()=>es,WorkstreamListCommand:()=>Xn,WorkstreamProgressCommand:()=>ts,WorkstreamSetCommand:()=>Qn,WorkstreamStatusCommand:()=>Zn,WxpProcessCommand:()=>ks});var ui=L(()=>{"use strict";wr();Pr();Cr();Er();Fr();Mr();Wr();qr();Lr();Ur();Vr();zr();Br();li()});var mi=Ci((Fd,Xa)=>{Xa.exports={name:"pi-gsd",version:"2.0.21",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 Ps={};xe(Ps,{cmdExtractMessages:()=>tc,cmdProfileSample:()=>nc,cmdScanSessions:()=>ec});function ar(t){if(t)return t;let e=process.env.HOME??"",n=De.join(e,".agent","projects");return se.existsSync(n)?n:De.join(e,".claude","projects")}function cr(){let t=process.env.HOME??"";return De.join(t,".pi","agent","sessions")}function lr(t){return t.startsWith("--")&&t.endsWith("--")?"/"+t.slice(2,-2).replace(/-/g,"/"):t}function Za(t){try{let e=se.readFileSync(t,"utf-8").split(`
342
+ `));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,ci,or,ks,li=L(()=>{"use strict";bt=require("@oclif/core"),ci=require("@oclif/core"),or=U(require("path"));ai();Ht();ks=class t extends ci.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=or.default.join(e["project-root"],".pi","gsd","workflows","_inline.md");else if(n.file){let o=await import("fs");s=or.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:[...Xr],shellBanlist:[],shellTimeoutMs:3e4};try{let o=oi(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 di={};xe(di,{AuditUatCommand:()=>Yn,CommitCommand:()=>rs,ConfigEnsureSectionCommand:()=>Fn,ConfigGetCommand:()=>An,ConfigNewProjectCommand:()=>En,ConfigSetCommand:()=>jn,ConfigSetModelProfileCommand:()=>Rn,FrontmatterGetCommand:()=>is,FrontmatterMergeCommand:()=>as,FrontmatterSetCommand:()=>os,InitCommand:()=>_n,MilestoneCompleteCommand:()=>Ln,PhaseAddCommand:()=>In,PhaseCompleteCommand:()=>On,PhaseInsertCommand:()=>Tn,PhaseNextDecimalCommand:()=>Mn,PhasePlanIndexCommand:()=>Nn,PhaseRemoveCommand:()=>Dn,ProgressCommand:()=>us,RequirementsMarkCompleteCommand:()=>Un,RoadmapAnalyzeCommand:()=>Pn,RoadmapGetPhaseCommand:()=>$n,RoadmapUpdatePlanProgressCommand:()=>Cn,ScaffoldCommand:()=>ns,StateAdvancePlanCommand:()=>gn,StateGetCommand:()=>mn,StateJsonCommand:()=>un,StateLoadCommand:()=>hn,StatePatchCommand:()=>fn,StateReconcileCommand:()=>xn,StateUpdateCommand:()=>pn,StateUpdateProgressCommand:()=>yn,StatsCommand:()=>ms,SummaryExtractCommand:()=>gs,TemplateFillCommand:()=>ds,TemplateSelectCommand:()=>ls,TodoCompleteCommand:()=>ps,TodoMatchPhaseCommand:()=>fs,ValidateAgentsCommand:()=>Gn,ValidateConsistencyCommand:()=>zn,ValidateHealthCommand:()=>Bn,VerifyCommand:()=>Jn,WorkstreamCompleteCommand:()=>Kn,WorkstreamCreateCommand:()=>Hn,WorkstreamGetCommand:()=>es,WorkstreamListCommand:()=>Xn,WorkstreamProgressCommand:()=>ts,WorkstreamSetCommand:()=>Qn,WorkstreamStatusCommand:()=>Zn,WxpProcessCommand:()=>ks});var ui=L(()=>{"use strict";wr();Pr();Cr();Er();Fr();Mr();Wr();qr();Lr();Ur();Vr();zr();Br();li()});var mi=Ci((Fd,Xa)=>{Xa.exports={name:"pi-gsd",version:"2.0.22",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 Ps={};xe(Ps,{cmdExtractMessages:()=>tc,cmdProfileSample:()=>nc,cmdScanSessions:()=>ec});function ar(t){if(t)return t;let e=process.env.HOME??"",n=De.join(e,".agent","projects");return se.existsSync(n)?n:De.join(e,".claude","projects")}function cr(){let t=process.env.HOME??"";return De.join(t,".pi","agent","sessions")}function lr(t){return t.startsWith("--")&&t.endsWith("--")?"/"+t.slice(2,-2).replace(/-/g,"/"):t}function Za(t){try{let e=se.readFileSync(t,"utf-8").split(`
343
343
  `).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 Ka(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 Qa(t){try{let e=se.readFileSync(t,"utf-8").split(`
344
344
  `).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 ec(t,e,n){let s=(e.harness??null)==="pi",i=cr(),o=se.existsSync(i),a=[];if(o)try{let m=se.readdirSync(i,{withFileTypes:!0}).filter(p=>p.isDirectory());for(let p of m){let f=De.join(i,p.name),g=se.readdirSync(f).filter(h=>h.endsWith(".jsonl"));a.push({name:p.name,sessions:g.length,path:f,source:"pi",cwd:lr(p.name)})}}catch{}let c=ar(s&&!t?null:t),l=!s||t?se.existsSync(c):!1,d=[];if(l&&(!s||t))try{let m=se.readdirSync(c,{withFileTypes:!0}).filter(p=>p.isDirectory());for(let p of m){let f=De.join(c,p.name),g=se.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 tc(t,e,n,r){let s=cr(),i=null,o="claude";if(se.existsSync(s)){let d=De.join(s,t);if(se.existsSync(d))i=d,o="pi";else try{let u=se.readdirSync(s,{withFileTypes:!0}).filter(m=>m.isDirectory());for(let m of u){let p=lr(m.name);if(p.endsWith("/"+t)||p===t||m.name===t){i=De.join(s,m.name),o="pi";break}}}catch{}}if(!i){let d=ar(r),u=De.join(d,t);se.existsSync(u)&&(i=u,o="claude")}if(!i){y({error:`Project not found: ${t}`,available_projects:[]},n);return}let a=[],c=se.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=De.join(i,d);if(o==="pi"||Za(u))try{let m=se.readFileSync(u,"utf-8").split(`
345
345
  `).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=se.readFileSync(u,"utf-8").split(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-gsd",
3
- "version": "2.0.21",
3
+ "version": "2.0.22",
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,4 +1,6 @@
1
1
  ---
2
2
  description: "Park idea in backlog (999.x). Args: idea (string, greedy)"
3
3
  ---
4
+ <gsd-include path=".pi/gsd/workflows/add-backlog.md" include-arguments />
5
+
4
6
  $ARGUMENTS
@@ -1,4 +1,6 @@
1
1
  ---
2
2
  description: "Archive milestone. Args: version (string, e.g. v1.0)"
3
3
  ---
4
+ <gsd-include path=".pi/gsd/workflows/complete-milestone.md" include-arguments />
5
+
4
6
  $ARGUMENTS
@@ -1,4 +1,6 @@
1
1
  ---
2
2
  description: "Systematic debugging session. No required args."
3
3
  ---
4
+ <gsd-include path=".pi/gsd/workflows/debug.md" include-arguments />
5
+
4
6
  $ARGUMENTS
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  description: "Surface agent assumptions before planning. Args: phase (number)"
3
3
  ---
4
- <gsd-include path=".pi/gsd/workflows/list-phase-assumptions.md" />
4
+ <gsd-include path=".pi/gsd/workflows/list-phase-assumptions.md" include-arguments />
5
5
 
6
6
  $ARGUMENTS
@@ -1,4 +1,6 @@
1
1
  ---
2
2
  description: "Research phase implementation. Args: phase (number)"
3
3
  ---
4
+ <gsd-include path=".pi/gsd/workflows/research-phase.md" include-arguments />
5
+
4
6
  $ARGUMENTS
@@ -1,4 +1,6 @@
1
1
  ---
2
2
  description: "Review and promote backlog items. No required args."
3
3
  ---
4
+ <gsd-include path=".pi/gsd/workflows/review-backlog.md" include-arguments />
5
+
4
6
  $ARGUMENTS
@@ -1,4 +1,6 @@
1
1
  ---
2
2
  description: "Set model profile. Args: profile (quality/balanced/budget/inherit)"
3
3
  ---
4
+ <gsd-include path=".pi/gsd/workflows/set-profile.md" include-arguments />
5
+
4
6
  $ARGUMENTS
@@ -1,4 +1,6 @@
1
1
  ---
2
2
  description: "Manage context threads. Subcommands: list, new, switch"
3
3
  ---
4
+ <gsd-include path=".pi/gsd/workflows/thread.md" include-arguments />
5
+
4
6
  $ARGUMENTS
@@ -1,4 +1,6 @@
1
1
  ---
2
2
  description: "Manage workstreams. Subcommands: list, create <name>, switch <name>, status, complete <name>"
3
3
  ---
4
+ <gsd-include path=".pi/gsd/workflows/workstreams.md" include-arguments />
5
+
4
6
  $ARGUMENTS