pi-gsd 1.3.3 → 1.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -117,28 +117,30 @@ Switch profile: `/gsd-set-profile <profile>`
117
117
 
118
118
  ## Comparison with GSD v1.30.0
119
119
 
120
- | Feature | gsd v1.30 | pi-gsd | Details |
121
- | -----------------------------------: | :-------: | :----: | :--------------------------------------------------------------------------------------------------- |
122
- | `.planning/` data format | ✔️ | ✔️ | 100% compatible - projects are portable across tools |
123
- | Workstreams | ✔️ | ✔️ | Full workstream isolation |
124
- | 4 model profiles | ✔️ | ✔️ | quality / balanced / budget / inherit |
125
- | 18 subagents | ✔️ | ✔️ | Identical agent definitions |
126
- | 57 GSD skills | ✔️ | ✔️ | All commands available via pi ~~skill system~~ prompt dispatcher (_more details below_) |
127
- | Different skills paths for pi | ✔️ | ⚡ | All 57 skills moved to `.pi/gsd/` to allow for advanced `pi-gsd-tools` usage (_more details below_) |
128
- | pi harness (`.pi/`) | ❌ | ✔️ | New - GSD installs into pi's config dir |
129
- | Background hooks (pi) | ❌ | ✔️ | TypeScript extension (`gsd-hooks.ts`) installed via postinstall |
130
- | Pi session history ingestion | ❌ | ✔️ | `/gsd-profile-user` reads pi JSONL sessions from `~/.pi/agent/sessions/` |
131
- | `/gsd-setup-pi` onboarding | ❌ | ✔️ | Setup skill for `bun install` where postinstall is skipped (default untrusted behavior) |
132
- | `gsd-tools` →`pi-gsd-tools` CLI | ✔️ | ⚡ | Same commands basic signatures as original (`gsd-tools`) but enhanced |
133
- | `[-o\|--output] [toon\|json]` output | ❌ | ⚡ | Token-efficient toon renderer output (or json, if LLM absolutely needs it...) |
134
- | `[-p\|--pick] {JSONPath}` extraction | ❌ | ⚡ | Field extraction from CLI output |
135
- | TypeScript source | ❌ | ⚡ | Full TS port of gsd-tools (~9k lines) |
136
- | Compile-time type safety | ❌ | ⚠️ | Zod schemas defined; ~25 loose `any` casts remain in lib modules |
137
- | Runtime validation (Zod) | ❌ | ⚠️ | Zod schemas for all `.planning/` types; wired to `config.json` + `validate health` full coverage in progress |
138
- | Smarter `--repair` | ❌ | | Schema-driven repair not yet implemented |
139
- | Instant commands (no LLM cost) | ❌ | ✔️ | `/gsd-progress`, `/gsd-stats`, `/gsd-health`, `/gsd-help`, `/gsd-next` — zero LLM, editor pivot |
140
- | `/gsd-next` auto-advance | ❌ | ✔️ | Deterministic phase routing, pre-fills editor with the correct next command |
141
- | Prompt-dispatch for all skills | ❌ | ✔️ | 54 pi prompt templates — clean autocomplete, arg hints, direct workflow dispatch |
120
+ | Feature | gsd v1.30 | pi-gsd | Details |
121
+ | -----------------------------------: | :-------: | :----: | :----------------------------------------------------------------------------------------------- |
122
+ | `.planning/` data format | ✔️ | ✔️ | 100% compatible - projects are portable across tools |
123
+ | Workstreams | ✔️ | ✔️ | Full workstream isolation |
124
+ | 4 model profiles | ✔️ | ✔️ | quality / balanced / budget / inherit |
125
+ | 18 subagents | ✔️ | ✔️ | Identical agent definitions |
126
+ | 57 GSD skills | ✔️ | ✔️ | All commands available via pi prompt dispatcher (replaces skill system) |
127
+ | Different skills paths for pi | ✔️ | ⚡ | All 57 skills moved to `.pi/gsd/` to enable advanced pi-gsd-tools integration |
128
+ | pi harness (`.pi/`) | ❌ | ✔️ | New - GSD installs into pi's config dir |
129
+ | Background hooks (pi) | ❌ | ✔️ | TypeScript extension (`gsd-hooks.ts`) installed via postinstall |
130
+ | Pi session history ingestion | ❌ | ✔️ | `/gsd-profile-user` reads pi JSONL sessions from `~/.pi/agent/sessions/` |
131
+ | `/gsd-setup-pi` onboarding | ❌ | ✔️ | Setup skill for `bun install` where postinstall is skipped (default untrusted behavior) |
132
+ | `gsd-tools` → `pi-gsd-tools` CLI | ✔️ | ⚡ | Same commands basic signatures as original (`gsd-tools`) but enhanced |
133
+ | `[-o\|--output] [toon\|json]` output | ❌ | ⚡ | Token-efficient toon renderer output (or json, if LLM absolutely needs it...) |
134
+ | `[-p\|--pick] {JSONPath}` extraction | ❌ | ⚡ | Field extraction from CLI output |
135
+ | TypeScript source | ❌ | ⚡ | Full TS port of gsd-tools (~9k lines) |
136
+ | Compile-time type safety | ❌ | ✔️ | Full TypeScript only `FrontmatterObject` root type retains `any` (intentional, documented) |
137
+ | Runtime validation (Zod) | ❌ | ✔️ | Zod schemas for all `.planning/` types; `validate health` checks `config.json` (W005) + `STATE.md` (W011) |
138
+ | Smarter `--repair` | ❌ | ✔️ | Schema defaults fill missing `config.json` fields; W011 STATE.md issues trigger regeneration |
139
+ | Instant commands (no LLM cost) | ❌ | ✔️ | `/gsd-progress`, `/gsd-stats`, `/gsd-health`, `/gsd-help`, `/gsd-next` — zero LLM, editor pivot |
140
+ | `/gsd-next` auto-advance | ❌ | ✔️ | Deterministic phase routing, pre-fills editor with the correct next command |
141
+ | Prompt-dispatch for all skills | ❌ | ✔️ | 54 pi prompt templates — clean autocomplete, arg hints, direct workflow dispatch |
142
+
143
+ Legend: ✔️ done · ⚡ enhanced · ⚠️ in progress · 📃 planned · ❌ not available
142
144
 
143
145
  ---
144
146
 
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
- "use strict";var Tn=Object.create;var Et=Object.defineProperty;var On=Object.getOwnPropertyDescriptor;var Nn=Object.getOwnPropertyNames;var Wn=Object.getPrototypeOf,qn=Object.prototype.hasOwnProperty;var le=(n,e)=>()=>(n&&(e=n(n=0)),e);var pe=(n,e)=>{for(var s in e)Et(n,s,{get:e[s],enumerable:!0})},Ln=(n,e,s,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of Nn(e))!qn.call(n,t)&&t!==s&&Et(n,t,{get:()=>e[t],enumerable:!(i=On(e,t))||i.enumerable});return n};var W=(n,e,s)=>(s=n!=null?Tn(Wn(n)):{},Ln(e||!n||!n.__esModule?Et(s,"default",{value:n,enumerable:!0}):s,n));var rn={};pe(rn,{HARNESS_CONFIG:()=>wt,MODEL_PROFILES:()=>je,VALID_PROFILES:()=>Je,formatAgentToModelMapAsTable:()=>Ft,generateModelProfilesMd:()=>Un,getAgentToModelMapForProfile:()=>Mt});function Mt(n){let e={};for(let[s,i]of Object.entries(je))e[s]=i[n];return e}function Ft(n){let e=Math.max(5,...Object.keys(n).map(o=>o.length)),s=Math.max(5,...Object.values(n).map(o=>o.length)),i="\u2500".repeat(e+2)+"\u253C"+"\u2500".repeat(s+2),r=" "+"Agent".padEnd(e)+" \u2502 "+"Model".padEnd(s)+`
2
+ "use strict";var Dn=Object.create;var Et=Object.defineProperty;var On=Object.getOwnPropertyDescriptor;var Nn=Object.getOwnPropertyNames;var Wn=Object.getPrototypeOf,qn=Object.prototype.hasOwnProperty;var le=(n,e)=>()=>(n&&(e=n(n=0)),e);var fe=(n,e)=>{for(var s in e)Et(n,s,{get:e[s],enumerable:!0})},Ln=(n,e,s,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of Nn(e))!qn.call(n,t)&&t!==s&&Et(n,t,{get:()=>e[t],enumerable:!(i=On(e,t))||i.enumerable});return n};var W=(n,e,s)=>(s=n!=null?Dn(Wn(n)):{},Ln(e||!n||!n.__esModule?Et(s,"default",{value:n,enumerable:!0}):s,n));var rn={};fe(rn,{HARNESS_CONFIG:()=>wt,MODEL_PROFILES:()=>je,VALID_PROFILES:()=>Je,formatAgentToModelMapAsTable:()=>Ft,generateModelProfilesMd:()=>Un,getAgentToModelMapForProfile:()=>Mt});function Mt(n){let e={};for(let[s,i]of Object.entries(je))e[s]=i[n];return e}function Ft(n){let e=Math.max(5,...Object.keys(n).map(o=>o.length)),s=Math.max(5,...Object.values(n).map(o=>o.length)),i="\u2500".repeat(e+2)+"\u253C"+"\u2500".repeat(s+2),r=" "+"Agent".padEnd(e)+" \u2502 "+"Model".padEnd(s)+`
3
3
  `+i+`
4
4
  `;for(let[o,a]of Object.entries(n))r+=" "+o.padEnd(e)+" \u2502 "+a.padEnd(s)+`
5
- `;return r}function Un(n="agent"){let e=wt[n]??wt.agent,{runtimeName:s,cmdPrefix:i,providerHeader:t,providerIntro:r,rationaleAlias:o,nonRuntimeHeading:a,nonRuntimeIntro:l}=e,c=Je,d=Object.keys(je),u=["Agent",...c.map(b=>"`"+b+"`"),"`inherit`"],p="| "+u.join(" | ")+" |",m="|"+u.map(b=>"-".repeat(b.length+2)).join("|")+"|",f=d.map(b=>{let v=c.map(P=>je[b][P]);return"| "+[b,...v,"inherit"].join(" | ")+" |"}),y=[p,m,...f].join(`
5
+ `;return r}function Un(n="agent"){let e=wt[n]??wt.agent,{runtimeName:s,cmdPrefix:i,providerHeader:t,providerIntro:r,rationaleAlias:o,nonRuntimeHeading:a,nonRuntimeIntro:l}=e,c=Je,d=Object.keys(je),u=["Agent",...c.map(b=>"`"+b+"`"),"`inherit`"],f="| "+u.join(" | ")+" |",m="|"+u.map(b=>"-".repeat(b.length+2)).join("|")+"|",p=d.map(b=>{let v=c.map(P=>je[b][P]);return"| "+[b,...v,"inherit"].join(" | ")+" |"}),y=[f,m,...p].join(`
6
6
  `),g=`${i}settings`,_=`${i}set-profile <profile>`;return`<!-- AUTO-GENERATED - do not edit by hand.
7
7
  Source of truth: src/lib/model-profiles.ts
8
8
  Regenerate with: node dist/gsd-tools.js generate-model-profiles-md --harness ${n}
@@ -133,53 +133,53 @@ ${o}'s \`"opus"\` alias maps to a specific model version. Organizations may bloc
133
133
 
134
134
  **Why \`inherit\` profile?**
135
135
  Some runtimes (including OpenCode) let users switch models at runtime (\`/model\`). The \`inherit\` profile keeps all GSD subagents aligned to that live selection.
136
- `}var je,Je,wt,rt=le(()=>{"use strict";je={"gsd-planner":{quality:"opus",balanced:"opus",budget:"sonnet"},"gsd-roadmapper":{quality:"opus",balanced:"sonnet",budget:"sonnet"},"gsd-executor":{quality:"opus",balanced:"sonnet",budget:"sonnet"},"gsd-phase-researcher":{quality:"opus",balanced:"sonnet",budget:"haiku"},"gsd-project-researcher":{quality:"opus",balanced:"sonnet",budget:"haiku"},"gsd-research-synthesizer":{quality:"sonnet",balanced:"sonnet",budget:"haiku"},"gsd-debugger":{quality:"opus",balanced:"sonnet",budget:"sonnet"},"gsd-codebase-mapper":{quality:"sonnet",balanced:"haiku",budget:"haiku"},"gsd-verifier":{quality:"sonnet",balanced:"sonnet",budget:"haiku"},"gsd-plan-checker":{quality:"sonnet",balanced:"sonnet",budget:"haiku"},"gsd-integration-checker":{quality:"sonnet",balanced:"sonnet",budget:"haiku"},"gsd-nyquist-auditor":{quality:"sonnet",balanced:"sonnet",budget:"haiku"},"gsd-ui-researcher":{quality:"opus",balanced:"sonnet",budget:"haiku"},"gsd-ui-checker":{quality:"sonnet",balanced:"sonnet",budget:"haiku"},"gsd-ui-auditor":{quality:"sonnet",balanced:"sonnet",budget:"haiku"}},Je=Object.keys(je["gsd-planner"]),wt={claude:{runtimeName:"Claude",cmdPrefix:"/gsd:",providerHeader:"Using Claude Code with Non-Anthropic Providers (OpenRouter, Local)",providerIntro:"If you're using Claude Code with OpenRouter, a local model, or any non-Anthropic provider, set the `inherit` profile to prevent GSD from calling Anthropic models for subagents:",rationaleAlias:"Claude Code",nonRuntimeHeading:"Using Non-Claude Runtimes (Codex, OpenCode, Gemini CLI)",nonRuntimeIntro:'When installed for a non-Claude runtime, the GSD installer sets `resolve_model_ids: "omit"` in `~/.gsd/defaults.json`. This returns an empty model parameter for all agents, so each agent uses the runtime\'s default model. No manual setup is needed.'},gemini:{runtimeName:"Gemini CLI",cmdPrefix:"/gsd:",providerHeader:"Using Gemini CLI with Non-Google Providers (OpenRouter, Local)",providerIntro:"If you're using Gemini CLI with OpenRouter, a local model, or any non-Google provider, set the `inherit` profile to prevent GSD from calling Google models for subagents:",rationaleAlias:"Gemini CLI",nonRuntimeHeading:"Using Non-Gemini-CLI Runtimes (Codex, OpenCode, Claude Code)",nonRuntimeIntro:'When installed for a non-Gemini-CLI runtime, the GSD installer sets `resolve_model_ids: "omit"` in `~/.gsd/defaults.json`. This returns an empty model parameter for all agents, so each agent uses the runtime\'s default model. No manual setup is needed.'},cursor:{runtimeName:"Claude",cmdPrefix:"/gsd-",providerHeader:"Using Cursor with Non-Anthropic Providers (OpenRouter, Local)",providerIntro:"If you're using Cursor with OpenRouter, a local model, or any non-Anthropic provider, set the `inherit` profile to prevent GSD from calling Anthropic models for subagents:",rationaleAlias:"Cursor",nonRuntimeHeading:"Using Non-Claude Runtimes (Codex, OpenCode, Gemini CLI)",nonRuntimeIntro:'When installed for a non-Claude runtime, the GSD installer sets `resolve_model_ids: "omit"` in `~/.gsd/defaults.json`. This returns an empty model parameter for all agents, so each agent uses the runtime\'s default model. No manual setup is needed.'},windsurf:{runtimeName:"Claude",cmdPrefix:"/gsd-",providerHeader:"Using Windsurf with Non-Anthropic Providers (OpenRouter, Local)",providerIntro:"If you're using Windsurf with OpenRouter, a local model, or any non-Anthropic provider, set the `inherit` profile to prevent GSD from calling Anthropic models for subagents:",rationaleAlias:"Windsurf",nonRuntimeHeading:"Using Non-Claude Runtimes (Codex, OpenCode, Gemini CLI)",nonRuntimeIntro:'When installed for a non-Claude runtime, the GSD installer sets `resolve_model_ids: "omit"` in `~/.gsd/defaults.json`. This returns an empty model parameter for all agents, so each agent uses the runtime\'s default model. No manual setup is needed.'},agent:{runtimeName:"Claude",cmdPrefix:"/gsd-",providerHeader:"Using Claude Code with Non-Anthropic Providers (OpenRouter, Local)",providerIntro:"If you're using Claude Code with OpenRouter, a local model, or any non-Anthropic provider, set the `inherit` profile to prevent GSD from calling Anthropic models for subagents:",rationaleAlias:"Claude Code",nonRuntimeHeading:"Using Non-Claude Runtimes (Codex, OpenCode, Gemini CLI)",nonRuntimeIntro:'When installed for a non-Claude runtime, the GSD installer sets `resolve_model_ids: "omit"` in `~/.gsd/defaults.json`. This returns an empty model parameter for all agents, so each agent uses the runtime\'s default model. No manual setup is needed.'},github:{runtimeName:"Claude",cmdPrefix:"/gsd-",providerHeader:"Using Claude Code with Non-Anthropic Providers (OpenRouter, Local)",providerIntro:"If you're using Claude Code with OpenRouter, a local model, or any non-Anthropic provider, set the `inherit` profile to prevent GSD from calling Anthropic models for subagents:",rationaleAlias:"Claude Code",nonRuntimeHeading:"Using Non-Claude Runtimes (Codex, OpenCode, Gemini CLI)",nonRuntimeIntro:'When installed for a non-Claude runtime, the GSD installer sets `resolve_model_ids: "omit"` in `~/.gsd/defaults.json`. This returns an empty model parameter for all agents, so each agent uses the runtime\'s default model. No manual setup is needed.'},opencode:{runtimeName:"Claude",cmdPrefix:"/gsd-",providerHeader:"Using Claude Code with Non-Anthropic Providers (OpenRouter, Local)",providerIntro:"If you're using Claude Code with OpenRouter, a local model, or any non-Anthropic provider, set the `inherit` profile to prevent GSD from calling Anthropic models for subagents:",rationaleAlias:"Claude Code",nonRuntimeHeading:"Using Non-Claude Runtimes (Codex, OpenCode, Gemini CLI)",nonRuntimeIntro:'When installed for a non-Claude runtime, the GSD installer sets `resolve_model_ids: "omit"` in `~/.gsd/defaults.json`. This returns an empty model parameter for all agents, so each agent uses the runtime\'s default model. No manual setup is needed.'},codex:{runtimeName:"Claude",cmdPrefix:"$gsd-",providerHeader:"Using Claude Code with Non-Anthropic Providers (OpenRouter, Local)",providerIntro:"If you're using Claude Code with OpenRouter, a local model, or any non-Anthropic provider, set the `inherit` profile to prevent GSD from calling Anthropic models for subagents:",rationaleAlias:"Claude Code",nonRuntimeHeading:"Using Non-Claude Runtimes (Codex, OpenCode, Gemini CLI)",nonRuntimeIntro:'When installed for a non-Claude runtime, the GSD installer sets `resolve_model_ids: "omit"` in `~/.gsd/defaults.json`. This returns an empty model parameter for all agents, so each agent uses the runtime\'s default model. No manual setup is needed.'},pi:{runtimeName:"pi",cmdPrefix:"/gsd-",providerHeader:"Using pi with Non-Default Providers (OpenRouter, Local)",providerIntro:"If you're using pi with OpenRouter, a local model, or any non-default provider, set the `inherit` profile to prevent GSD from calling default models for subagents:",rationaleAlias:"pi",nonRuntimeHeading:"Using Non-pi Runtimes (Claude Code, Codex, OpenCode, Gemini CLI)",nonRuntimeIntro:'When installed for a non-pi runtime, the GSD installer sets `resolve_model_ids: "omit"` in `~/.gsd/defaults.json`. This returns an empty model parameter for all agents, so each agent uses the runtime\'s default model. No manual setup is needed.'}}});function z(n){return n.split(I.default.sep).join("/")}function on(n){let e=[];try{let s=T.default.readdirSync(n,{withFileTypes:!0});for(let i of s){if(!i.isDirectory()||i.name.startsWith(".")||i.name==="node_modules")continue;let t=I.default.join(n,i.name,".git");try{T.default.existsSync(t)&&e.push(i.name)}catch{}}}catch{}return e.sort()}function ln(n){let e=I.default.resolve(n),s=I.default.parse(e).root,i=ht.default.homedir(),t=I.default.join(e,".planning");if(T.default.existsSync(t)&&T.default.statSync(t).isDirectory())return n;function r(a){let l=e;for(;l!==s;){if(T.default.existsSync(I.default.join(l,".git")))return!0;if(l===a)break;l=I.default.dirname(l)}return!1}let o=e;for(;o!==s;){let a=I.default.dirname(o);if(a===o||a===i)break;let l=I.default.join(a,".planning");if(T.default.existsSync(l)&&T.default.statSync(l).isDirectory()){let c=I.default.join(l,"config.json");try{let d=JSON.parse(T.default.readFileSync(c,"utf-8")),u=d.sub_repos||d.planning?.sub_repos||[];if(Array.isArray(u)&&u.length>0){let m=I.default.relative(a,e).split(I.default.sep)[0];if(u.includes(m))return a}if(d.multiRepo===!0&&r(a))return a}catch{}if(r(a))return a}o=a}return n}function zn(n="gsd-",{maxAgeMs:e=300*1e3,dirsOnly:s=!1}={}){try{let i=ht.default.tmpdir(),t=Date.now();for(let r of T.default.readdirSync(i)){if(!r.startsWith(n))continue;let o=I.default.join(i,r);try{let a=T.default.statSync(o);t-a.mtimeMs>e&&(a.isDirectory()?T.default.rmSync(o,{recursive:!0,force:!0}):s||T.default.unlinkSync(o))}catch{}}}catch{}}function h(n,e=!1,s){let i;if(e&&s!==void 0)i=String(s);else{let t=JSON.stringify(n,null,2);if(t.length>5e4){zn();let r=I.default.join(ht.default.tmpdir(),`gsd-${Date.now()}.json`);T.default.writeFileSync(r,t,"utf-8"),i="@file:"+r}else i=t}T.default.writeSync(1,i)}function S(n){T.default.writeSync(2,"Error: "+n+`
137
- `),process.exit(1)}function we(n){try{return T.default.readFileSync(n,"utf-8")}catch{return null}}function B(n){let e=I.default.join(n,".planning","config.json"),s={model_profile:"balanced",commit_docs:!0,search_gitignored:!1,branching_strategy:"none",phase_branch_template:"gsd/phase-{phase}-{slug}",milestone_branch_template:"gsd/{milestone}-{slug}",quick_branch_template:null,research:!0,plan_checker:!0,verifier:!0,nyquist_validation:!0,parallelization:!0,brave_search:!1,firecrawl:!1,exa_search:!1,text_mode:!1,sub_repos:[],resolve_model_ids:!1,context_window:2e5,phase_naming:"sequential",model_overrides:null,agent_skills:{}};try{let l=function(d,u){if(r[d]!==void 0)return r[d];if(u&&r[u.section]?.[u.field]!==void 0)return r[u.section][u.field]};var i=l;let t=T.default.readFileSync(e,"utf-8"),r=JSON.parse(t);if("depth"in r&&!("granularity"in r)){let d={quick:"coarse",standard:"standard",comprehensive:"fine"};r.granularity=d[r.depth]||r.depth,delete r.depth;try{T.default.writeFileSync(e,JSON.stringify(r,null,2),"utf-8")}catch{}}let o=!1;if(r.multiRepo===!0&&!r.sub_repos&&!r.planning?.sub_repos){let d=on(n);d.length>0&&(r.sub_repos=d,r.planning||(r.planning={}),r.planning.commit_docs=!1,delete r.multiRepo,o=!0)}let a=r.sub_repos||r.planning?.sub_repos||[];if(Array.isArray(a)&&a.length>0){let d=on(n);if(d.length>0){let u=[...a].sort();JSON.stringify(u)!==JSON.stringify(d)&&(r.sub_repos=d,o=!0)}}if(o)try{T.default.writeFileSync(e,JSON.stringify(r,null,2),"utf-8")}catch{}let c=(()=>{let d=l("parallelization");return typeof d=="boolean"?d:typeof d=="object"&&d!==null&&"enabled"in d?!!d.enabled:s.parallelization})();return{model_profile:l("model_profile")??s.model_profile,commit_docs:(()=>{let d=l("commit_docs",{section:"planning",field:"commit_docs"});return d!==void 0?!!d:Dt(n,".planning/")?!1:s.commit_docs})(),search_gitignored:l("search_gitignored",{section:"planning",field:"search_gitignored"})??s.search_gitignored,branching_strategy:l("branching_strategy",{section:"git",field:"branching_strategy"})??s.branching_strategy,phase_branch_template:l("phase_branch_template",{section:"git",field:"phase_branch_template"})??s.phase_branch_template,milestone_branch_template:l("milestone_branch_template",{section:"git",field:"milestone_branch_template"})??s.milestone_branch_template,quick_branch_template:l("quick_branch_template",{section:"git",field:"quick_branch_template"})??s.quick_branch_template,research:l("research",{section:"workflow",field:"research"})??s.research,plan_checker:l("plan_checker",{section:"workflow",field:"plan_check"})??s.plan_checker,verifier:l("verifier",{section:"workflow",field:"verifier"})??s.verifier,nyquist_validation:l("nyquist_validation",{section:"workflow",field:"nyquist_validation"})??s.nyquist_validation,parallelization:c,brave_search:l("brave_search")??s.brave_search,firecrawl:l("firecrawl")??s.firecrawl,exa_search:l("exa_search")??s.exa_search,text_mode:l("text_mode",{section:"workflow",field:"text_mode"})??s.text_mode,sub_repos:l("sub_repos",{section:"planning",field:"sub_repos"})??s.sub_repos,resolve_model_ids:l("resolve_model_ids")??s.resolve_model_ids,context_window:l("context_window")??s.context_window,phase_naming:l("phase_naming")??s.phase_naming,model_overrides:r.model_overrides||null,agent_skills:r.agent_skills||{}}}catch{return s}}function Dt(n,e){try{return(0,ft.execFileSync)("git",["check-ignore","-q","--no-index","--",e],{cwd:n,stdio:"pipe"}),!0}catch{return!1}}function oe(n,e){let s=(0,ft.spawnSync)("git",e,{cwd:n,stdio:"pipe",encoding:"utf-8"});return{exitCode:s.status??1,stdout:(s.stdout??"").toString().trim(),stderr:(s.stderr??"").toString().trim()}}function Re(n){if(!n||typeof n!="string")return n;let e=n.replace(/\r\n/g,`
136
+ `}var je,Je,wt,rt=le(()=>{"use strict";je={"gsd-planner":{quality:"opus",balanced:"opus",budget:"sonnet"},"gsd-roadmapper":{quality:"opus",balanced:"sonnet",budget:"sonnet"},"gsd-executor":{quality:"opus",balanced:"sonnet",budget:"sonnet"},"gsd-phase-researcher":{quality:"opus",balanced:"sonnet",budget:"haiku"},"gsd-project-researcher":{quality:"opus",balanced:"sonnet",budget:"haiku"},"gsd-research-synthesizer":{quality:"sonnet",balanced:"sonnet",budget:"haiku"},"gsd-debugger":{quality:"opus",balanced:"sonnet",budget:"sonnet"},"gsd-codebase-mapper":{quality:"sonnet",balanced:"haiku",budget:"haiku"},"gsd-verifier":{quality:"sonnet",balanced:"sonnet",budget:"haiku"},"gsd-plan-checker":{quality:"sonnet",balanced:"sonnet",budget:"haiku"},"gsd-integration-checker":{quality:"sonnet",balanced:"sonnet",budget:"haiku"},"gsd-nyquist-auditor":{quality:"sonnet",balanced:"sonnet",budget:"haiku"},"gsd-ui-researcher":{quality:"opus",balanced:"sonnet",budget:"haiku"},"gsd-ui-checker":{quality:"sonnet",balanced:"sonnet",budget:"haiku"},"gsd-ui-auditor":{quality:"sonnet",balanced:"sonnet",budget:"haiku"}},Je=Object.keys(je["gsd-planner"]),wt={claude:{runtimeName:"Claude",cmdPrefix:"/gsd:",providerHeader:"Using Claude Code with Non-Anthropic Providers (OpenRouter, Local)",providerIntro:"If you're using Claude Code with OpenRouter, a local model, or any non-Anthropic provider, set the `inherit` profile to prevent GSD from calling Anthropic models for subagents:",rationaleAlias:"Claude Code",nonRuntimeHeading:"Using Non-Claude Runtimes (Codex, OpenCode, Gemini CLI)",nonRuntimeIntro:'When installed for a non-Claude runtime, the GSD installer sets `resolve_model_ids: "omit"` in `~/.gsd/defaults.json`. This returns an empty model parameter for all agents, so each agent uses the runtime\'s default model. No manual setup is needed.'},gemini:{runtimeName:"Gemini CLI",cmdPrefix:"/gsd:",providerHeader:"Using Gemini CLI with Non-Google Providers (OpenRouter, Local)",providerIntro:"If you're using Gemini CLI with OpenRouter, a local model, or any non-Google provider, set the `inherit` profile to prevent GSD from calling Google models for subagents:",rationaleAlias:"Gemini CLI",nonRuntimeHeading:"Using Non-Gemini-CLI Runtimes (Codex, OpenCode, Claude Code)",nonRuntimeIntro:'When installed for a non-Gemini-CLI runtime, the GSD installer sets `resolve_model_ids: "omit"` in `~/.gsd/defaults.json`. This returns an empty model parameter for all agents, so each agent uses the runtime\'s default model. No manual setup is needed.'},cursor:{runtimeName:"Claude",cmdPrefix:"/gsd-",providerHeader:"Using Cursor with Non-Anthropic Providers (OpenRouter, Local)",providerIntro:"If you're using Cursor with OpenRouter, a local model, or any non-Anthropic provider, set the `inherit` profile to prevent GSD from calling Anthropic models for subagents:",rationaleAlias:"Cursor",nonRuntimeHeading:"Using Non-Claude Runtimes (Codex, OpenCode, Gemini CLI)",nonRuntimeIntro:'When installed for a non-Claude runtime, the GSD installer sets `resolve_model_ids: "omit"` in `~/.gsd/defaults.json`. This returns an empty model parameter for all agents, so each agent uses the runtime\'s default model. No manual setup is needed.'},windsurf:{runtimeName:"Claude",cmdPrefix:"/gsd-",providerHeader:"Using Windsurf with Non-Anthropic Providers (OpenRouter, Local)",providerIntro:"If you're using Windsurf with OpenRouter, a local model, or any non-Anthropic provider, set the `inherit` profile to prevent GSD from calling Anthropic models for subagents:",rationaleAlias:"Windsurf",nonRuntimeHeading:"Using Non-Claude Runtimes (Codex, OpenCode, Gemini CLI)",nonRuntimeIntro:'When installed for a non-Claude runtime, the GSD installer sets `resolve_model_ids: "omit"` in `~/.gsd/defaults.json`. This returns an empty model parameter for all agents, so each agent uses the runtime\'s default model. No manual setup is needed.'},agent:{runtimeName:"Claude",cmdPrefix:"/gsd-",providerHeader:"Using Claude Code with Non-Anthropic Providers (OpenRouter, Local)",providerIntro:"If you're using Claude Code with OpenRouter, a local model, or any non-Anthropic provider, set the `inherit` profile to prevent GSD from calling Anthropic models for subagents:",rationaleAlias:"Claude Code",nonRuntimeHeading:"Using Non-Claude Runtimes (Codex, OpenCode, Gemini CLI)",nonRuntimeIntro:'When installed for a non-Claude runtime, the GSD installer sets `resolve_model_ids: "omit"` in `~/.gsd/defaults.json`. This returns an empty model parameter for all agents, so each agent uses the runtime\'s default model. No manual setup is needed.'},github:{runtimeName:"Claude",cmdPrefix:"/gsd-",providerHeader:"Using Claude Code with Non-Anthropic Providers (OpenRouter, Local)",providerIntro:"If you're using Claude Code with OpenRouter, a local model, or any non-Anthropic provider, set the `inherit` profile to prevent GSD from calling Anthropic models for subagents:",rationaleAlias:"Claude Code",nonRuntimeHeading:"Using Non-Claude Runtimes (Codex, OpenCode, Gemini CLI)",nonRuntimeIntro:'When installed for a non-Claude runtime, the GSD installer sets `resolve_model_ids: "omit"` in `~/.gsd/defaults.json`. This returns an empty model parameter for all agents, so each agent uses the runtime\'s default model. No manual setup is needed.'},opencode:{runtimeName:"Claude",cmdPrefix:"/gsd-",providerHeader:"Using Claude Code with Non-Anthropic Providers (OpenRouter, Local)",providerIntro:"If you're using Claude Code with OpenRouter, a local model, or any non-Anthropic provider, set the `inherit` profile to prevent GSD from calling Anthropic models for subagents:",rationaleAlias:"Claude Code",nonRuntimeHeading:"Using Non-Claude Runtimes (Codex, OpenCode, Gemini CLI)",nonRuntimeIntro:'When installed for a non-Claude runtime, the GSD installer sets `resolve_model_ids: "omit"` in `~/.gsd/defaults.json`. This returns an empty model parameter for all agents, so each agent uses the runtime\'s default model. No manual setup is needed.'},codex:{runtimeName:"Claude",cmdPrefix:"$gsd-",providerHeader:"Using Claude Code with Non-Anthropic Providers (OpenRouter, Local)",providerIntro:"If you're using Claude Code with OpenRouter, a local model, or any non-Anthropic provider, set the `inherit` profile to prevent GSD from calling Anthropic models for subagents:",rationaleAlias:"Claude Code",nonRuntimeHeading:"Using Non-Claude Runtimes (Codex, OpenCode, Gemini CLI)",nonRuntimeIntro:'When installed for a non-Claude runtime, the GSD installer sets `resolve_model_ids: "omit"` in `~/.gsd/defaults.json`. This returns an empty model parameter for all agents, so each agent uses the runtime\'s default model. No manual setup is needed.'},pi:{runtimeName:"pi",cmdPrefix:"/gsd-",providerHeader:"Using pi with Non-Default Providers (OpenRouter, Local)",providerIntro:"If you're using pi with OpenRouter, a local model, or any non-default provider, set the `inherit` profile to prevent GSD from calling default models for subagents:",rationaleAlias:"pi",nonRuntimeHeading:"Using Non-pi Runtimes (Claude Code, Codex, OpenCode, Gemini CLI)",nonRuntimeIntro:'When installed for a non-pi runtime, the GSD installer sets `resolve_model_ids: "omit"` in `~/.gsd/defaults.json`. This returns an empty model parameter for all agents, so each agent uses the runtime\'s default model. No manual setup is needed.'}}});function z(n){return n.split(I.default.sep).join("/")}function on(n){let e=[];try{let s=D.default.readdirSync(n,{withFileTypes:!0});for(let i of s){if(!i.isDirectory()||i.name.startsWith(".")||i.name==="node_modules")continue;let t=I.default.join(n,i.name,".git");try{D.default.existsSync(t)&&e.push(i.name)}catch{}}}catch{}return e.sort()}function ln(n){let e=I.default.resolve(n),s=I.default.parse(e).root,i=ht.default.homedir(),t=I.default.join(e,".planning");if(D.default.existsSync(t)&&D.default.statSync(t).isDirectory())return n;function r(a){let l=e;for(;l!==s;){if(D.default.existsSync(I.default.join(l,".git")))return!0;if(l===a)break;l=I.default.dirname(l)}return!1}let o=e;for(;o!==s;){let a=I.default.dirname(o);if(a===o||a===i)break;let l=I.default.join(a,".planning");if(D.default.existsSync(l)&&D.default.statSync(l).isDirectory()){let c=I.default.join(l,"config.json");try{let d=JSON.parse(D.default.readFileSync(c,"utf-8")),u=d.sub_repos||d.planning?.sub_repos||[];if(Array.isArray(u)&&u.length>0){let m=I.default.relative(a,e).split(I.default.sep)[0];if(u.includes(m))return a}if(d.multiRepo===!0&&r(a))return a}catch{}if(r(a))return a}o=a}return n}function zn(n="gsd-",{maxAgeMs:e=300*1e3,dirsOnly:s=!1}={}){try{let i=ht.default.tmpdir(),t=Date.now();for(let r of D.default.readdirSync(i)){if(!r.startsWith(n))continue;let o=I.default.join(i,r);try{let a=D.default.statSync(o);t-a.mtimeMs>e&&(a.isDirectory()?D.default.rmSync(o,{recursive:!0,force:!0}):s||D.default.unlinkSync(o))}catch{}}}catch{}}function h(n,e=!1,s){let i;if(e&&s!==void 0)i=String(s);else{let t=JSON.stringify(n,null,2);if(t.length>5e4){zn();let r=I.default.join(ht.default.tmpdir(),`gsd-${Date.now()}.json`);D.default.writeFileSync(r,t,"utf-8"),i="@file:"+r}else i=t}D.default.writeSync(1,i)}function S(n){D.default.writeSync(2,"Error: "+n+`
137
+ `),process.exit(1)}function we(n){try{return D.default.readFileSync(n,"utf-8")}catch{return null}}function B(n){let e=I.default.join(n,".planning","config.json"),s={model_profile:"balanced",commit_docs:!0,search_gitignored:!1,branching_strategy:"none",phase_branch_template:"gsd/phase-{phase}-{slug}",milestone_branch_template:"gsd/{milestone}-{slug}",quick_branch_template:null,research:!0,plan_checker:!0,verifier:!0,nyquist_validation:!0,parallelization:!0,brave_search:!1,firecrawl:!1,exa_search:!1,text_mode:!1,sub_repos:[],resolve_model_ids:!1,context_window:2e5,phase_naming:"sequential",model_overrides:null,agent_skills:{}};try{let l=function(d,u){if(r[d]!==void 0)return r[d];let f=r[u?.section??""];if(u&&f?.[u.field]!==void 0)return f[u.field]};var i=l;let t=D.default.readFileSync(e,"utf-8"),r=JSON.parse(t);if("depth"in r&&!("granularity"in r)){let d={quick:"coarse",standard:"standard",comprehensive:"fine"};r.granularity=d[r.depth]||r.depth,delete r.depth;try{D.default.writeFileSync(e,JSON.stringify(r,null,2),"utf-8")}catch{}}let o=!1;if(r.multiRepo===!0&&!r.sub_repos&&!r.planning?.sub_repos){let d=on(n);d.length>0&&(r.sub_repos=d,r.planning||(r.planning={}),r.planning.commit_docs=!1,delete r.multiRepo,o=!0)}let a=r.sub_repos||r.planning?.sub_repos||[];if(Array.isArray(a)&&a.length>0){let d=on(n);if(d.length>0){let u=[...a].sort();JSON.stringify(u)!==JSON.stringify(d)&&(r.sub_repos=d,o=!0)}}if(o)try{D.default.writeFileSync(e,JSON.stringify(r,null,2),"utf-8")}catch{}let c=(()=>{let d=l("parallelization");return typeof d=="boolean"?d:typeof d=="object"&&d!==null&&"enabled"in d?!!d.enabled:s.parallelization})();return{model_profile:l("model_profile")??s.model_profile,commit_docs:(()=>{let d=l("commit_docs",{section:"planning",field:"commit_docs"});return d!==void 0?!!d:Tt(n,".planning/")?!1:s.commit_docs})(),search_gitignored:l("search_gitignored",{section:"planning",field:"search_gitignored"})??s.search_gitignored,branching_strategy:l("branching_strategy",{section:"git",field:"branching_strategy"})??s.branching_strategy,phase_branch_template:l("phase_branch_template",{section:"git",field:"phase_branch_template"})??s.phase_branch_template,milestone_branch_template:l("milestone_branch_template",{section:"git",field:"milestone_branch_template"})??s.milestone_branch_template,quick_branch_template:l("quick_branch_template",{section:"git",field:"quick_branch_template"})??s.quick_branch_template,research:l("research",{section:"workflow",field:"research"})??s.research,plan_checker:l("plan_checker",{section:"workflow",field:"plan_check"})??s.plan_checker,verifier:l("verifier",{section:"workflow",field:"verifier"})??s.verifier,nyquist_validation:l("nyquist_validation",{section:"workflow",field:"nyquist_validation"})??s.nyquist_validation,parallelization:c,brave_search:l("brave_search")??s.brave_search,firecrawl:l("firecrawl")??s.firecrawl,exa_search:l("exa_search")??s.exa_search,text_mode:l("text_mode",{section:"workflow",field:"text_mode"})??s.text_mode,sub_repos:l("sub_repos",{section:"planning",field:"sub_repos"})??s.sub_repos,resolve_model_ids:l("resolve_model_ids")??s.resolve_model_ids,context_window:l("context_window")??s.context_window,phase_naming:l("phase_naming")??s.phase_naming,model_overrides:r.model_overrides??null,agent_skills:r.agent_skills||{}}}catch{return s}}function Tt(n,e){try{return(0,pt.execFileSync)("git",["check-ignore","-q","--no-index","--",e],{cwd:n,stdio:"pipe"}),!0}catch{return!1}}function oe(n,e){let s=(0,pt.spawnSync)("git",e,{cwd:n,stdio:"pipe",encoding:"utf-8"});return{exitCode:s.status??1,stdout:(s.stdout??"").toString().trim(),stderr:(s.stderr??"").toString().trim()}}function Re(n){if(!n||typeof n!="string")return n;let e=n.replace(/\r\n/g,`
138
138
  `),s=e.split(`
139
139
  `),i=[];for(let t=0;t<s.length;t++){let r=s[t],o=t>0?s[t-1]:"",a=o.trimEnd(),l=r.trimEnd();if(/^#{1,6}\s/.test(l)&&t>0&&a!==""&&a!=="---"&&i.push(""),/^```/.test(l)&&t>0&&a!==""&&!Vn(s,t)&&i.push(""),/^(\s*[-*+]\s|\s*\d+\.\s)/.test(r)&&t>0&&a!==""&&!/^(\s*[-*+]\s|\s*\d+\.\s)/.test(o)&&a!=="---"&&i.push(""),i.push(r),/^#{1,6}\s/.test(l)&&t<s.length-1&&s[t+1]?.trimEnd()!==""&&i.push(""),/^```\s*$/.test(l)&&Hn(s,t)&&t<s.length-1&&s[t+1]?.trimEnd()!==""&&i.push(""),/^(\s*[-*+]\s|\s*\d+\.\s)/.test(r)&&t<s.length-1){let c=s[t+1];c!==void 0&&c.trimEnd()!==""&&!/^(\s*[-*+]\s|\s*\d+\.\s)/.test(c)&&!/^\s/.test(c)&&i.push("")}}return e=i.join(`
140
140
  `),e=e.replace(/\n{3,}/g,`
141
141
 
142
142
  `),e=e.replace(/\n*$/,`
143
- `),e}function Vn(n,e){let s=0;for(let i=0;i<e;i++)/^```/.test(n[i].trimEnd())&&s++;return s%2===1}function Hn(n,e){let s=0;for(let i=0;i<=e;i++)/^```/.test(n[i].trimEnd())&&s++;return s%2===0}function cn(n){if(T.default.existsSync(I.default.join(n,".planning")))return n;let e=oe(n,["rev-parse","--git-dir"]),s=oe(n,["rev-parse","--git-common-dir"]);if(e.exitCode!==0||s.exitCode!==0)return n;let i=I.default.resolve(n,e.stdout),t=I.default.resolve(n,s.stdout);return i!==t?I.default.dirname(t):n}function F(n,e){let s=e??process.env.GSD_WORKSTREAM??null;return s?I.default.join(n,".planning","workstreams",s):I.default.join(n,".planning")}function J(n){return I.default.join(n,".planning")}function R(n,e){let s=F(n,e),i=I.default.join(n,".planning");return{planning:s,state:I.default.join(s,"STATE.md"),roadmap:I.default.join(s,"ROADMAP.md"),project:I.default.join(i,"PROJECT.md"),config:I.default.join(i,"config.json"),phases:I.default.join(s,"phases"),requirements:I.default.join(s,"REQUIREMENTS.md")}}function Ye(n){let e=I.default.join(J(n),"active-workstream");try{let s=T.default.readFileSync(e,"utf-8").trim();return!s||!/^[a-zA-Z0-9_-]+$/.test(s)||!T.default.existsSync(I.default.join(J(n),"workstreams",s))?null:s}catch{return null}}function Ke(n,e){let s=I.default.join(J(n),"active-workstream");if(!e){try{T.default.unlinkSync(s)}catch{}return}if(!/^[a-zA-Z0-9_-]+$/.test(e))throw new Error("Invalid workstream name");T.default.writeFileSync(s,e+`
144
- `,"utf-8")}function Q(n){return String(n).replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function ce(n){let e=String(n),s=e.match(/^(\d+)([A-Z])?((?:\.\d+)*)/i);return s?s[1].padStart(2,"0")+(s[2]?s[2].toUpperCase():"")+(s[3]||""):e}function ke(n,e){let s=String(n).match(/^(\d+)([A-Z])?((?:\.\d+)*)/i),i=String(e).match(/^(\d+)([A-Z])?((?:\.\d+)*)/i);if(!s||!i)return String(n).localeCompare(String(e));let t=parseInt(s[1],10)-parseInt(i[1],10);if(t!==0)return t;let r=(s[2]||"").toUpperCase(),o=(i[2]||"").toUpperCase();if(r!==o)return r?o&&r<o?-1:1:-1;let a=s[3]?s[3].slice(1).split(".").map(c=>parseInt(c,10)):[],l=i[3]?i[3].slice(1).split(".").map(c=>parseInt(c,10)):[];if(a.length===0&&l.length>0)return-1;if(l.length===0&&a.length>0)return 1;for(let c=0;c<Math.max(a.length,l.length);c++){let d=Number.isFinite(a[c])?a[c]:0,u=Number.isFinite(l[c])?l[c]:0;if(d!==u)return d-u}return 0}function an(n,e,s){try{let t=Oe(n,!0).find(v=>v.startsWith(s)||v.toUpperCase().startsWith(s.toUpperCase()));if(!t)return null;let r=t.match(/^(\d+[A-Z]?(?:\.\d+)*)-?(.*)/i)||t.match(/^([A-Z][A-Z0-9]*(?:-[A-Z0-9]+)*)-(.+)/i)||[null,t,null],o=r?.[1]??s,a=r?.[2]||null,l=I.default.join(n,t),{plans:c,summaries:d,hasResearch:u,hasContext:p,hasVerification:m,hasReviews:f}=Jn(l),y=c.sort(),g=d.sort(),_=new Set(g.map(v=>v.replace("-SUMMARY.md","").replace("SUMMARY.md",""))),b=y.filter(v=>!_.has(v.replace("-PLAN.md","").replace("PLAN.md","")));return{found:!0,directory:z(I.default.join(e,t)),phase_number:o,phase_name:a,phase_slug:a?a.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,""):null,plans:y,summaries:g,incomplete_plans:b,has_research:u,has_context:p,has_verification:m,has_reviews:f}}catch{return null}}function ue(n,e){if(!e)return null;let s=I.default.join(F(n),"phases"),i=ce(e),t=z(I.default.relative(n,s)),r=an(s,t,i);if(r)return r;let o=I.default.join(n,".planning","milestones");if(!T.default.existsSync(o))return null;try{let a=T.default.readdirSync(o,{withFileTypes:!0}).filter(l=>l.isDirectory()&&/^v[\d.]+-phases$/.test(l.name)).map(l=>l.name).sort().reverse();for(let l of a){let c=l.match(/^(v[\d.]+)-phases$/)[1],d=I.default.join(o,l),u=".planning/milestones/"+l,p=an(d,u,i);if(p)return p.archived=c,p}}catch{}return null}function gt(n){let e=I.default.join(n,".planning","milestones"),s=[];if(!T.default.existsSync(e))return s;try{let i=T.default.readdirSync(e,{withFileTypes:!0}).filter(t=>t.isDirectory()&&/^v[\d.]+-phases$/.test(t.name)).map(t=>t.name).sort().reverse();for(let t of i){let r=t.match(/^(v[\d.]+)-phases$/)[1],o=I.default.join(e,t);for(let a of Oe(o,!0))s.push({name:a,milestone:r,basePath:I.default.join(".planning","milestones",t),fullPath:I.default.join(o,a)})}}catch{}return s}function pt(n){return n.replace(/<details>[\s\S]*?<\/details>/gi,"")}function be(n,e){if(!e)return pt(n);let s=null;try{let u=I.default.join(F(e),"STATE.md");if(T.default.existsSync(u)){let m=T.default.readFileSync(u,"utf-8").match(/^milestone:\s*(.+)/m);m&&(s=m[1].trim())}}catch{}if(!s){let u=n.match(/🚧\s*\*\*v(\d+\.\d+)\s/);u&&(s="v"+u[1])}if(!s)return pt(n);let i=new RegExp(`(^#{1,3}\\s+.*${Q(s)}[^\\n]*)`,"mi"),t=n.match(i);if(!t)return pt(n);let r=t.index,o=t[1].match(/^(#{1,3})\s/)[1].length,l=n.slice(r+t[0].length).match(new RegExp(`^#{1,${o}}\\s+(?:.*v\\d+\\.\\d+|\u2705|\u{1F4CB}|\u{1F6A7})`,"mi")),c=l?r+t[0].length+l.index:n.length;return n.slice(0,r).replace(/<details>[\s\S]*?<\/details>/gi,"")+n.slice(r,c)}function Ze(n,e,s){let i=n.lastIndexOf("</details>");if(i===-1)return n.replace(e,s);let t=i+10,r=n.slice(0,t),o=n.slice(t);return r+o.replace(e,s)}function Qe(n,e){if(!e)return null;let s=I.default.join(F(n),"ROADMAP.md");if(!T.default.existsSync(s))return null;try{let i=be(T.default.readFileSync(s,"utf-8"),n),t=new RegExp(`#{2,4}\\s*Phase\\s+${Q(e)}:\\s*([^\\n]+)`,"i"),r=i.match(t);if(!r)return null;let o=r[1].trim(),a=r.index,c=i.slice(a).match(/\n#{2,4}\s+Phase\s+[\w]/i),d=c?a+c.index:i.length,u=i.slice(a,d).trim(),p=u.match(/\*\*Goal(?:\*\*:|\*?\*?:\*\*)\s*([^\n]+)/i);return{found:!0,phase_number:e.toString(),phase_name:o,goal:p?p[1].trim():null,section:u}}catch{return null}}function Bn(){return I.default.join(__dirname,"..","..","agents")}function ot(){let n=Bn(),e=Object.keys(je),s=[],i=[];if(!T.default.existsSync(n))return{agents_installed:!1,missing_agents:e,installed_agents:[],agents_dir:n};for(let t of e)T.default.existsSync(I.default.join(n,`${t}.md`))?s.push(t):i.push(t);return{agents_installed:s.length>0&&i.length===0,missing_agents:i,installed_agents:s,agents_dir:n}}function X(n,e){let s=B(n),i=s.model_overrides?.[e];if(i)return i;if(s.resolve_model_ids==="omit")return"";let t=String(s.model_profile||"balanced").toLowerCase(),r=je[e];if(!r)return"sonnet";if(t==="inherit")return"inherit";let o=r[t]||r.balanced||"sonnet";return s.resolve_model_ids&&Gn[o]||o}function yt(n){if(!n)return null;let s=n.replace(/^---\n[\s\S]*?\n---\n*/,"").match(/^#[^\n]*\n+\*\*([^*]+)\*\*/m);return s?s[1].trim():null}function Te(n){return n?n.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,""):null}function ie(n){try{let e=T.default.readFileSync(I.default.join(F(n),"ROADMAP.md"),"utf-8"),s=e.match(/🚧\s*\*\*v(\d+(?:\.\d+)+)\s+([^*]+)\*\*/);if(s)return{version:"v"+s[1],name:s[2].trim()};let i=pt(e),t=i.match(/## .*v(\d+(?:\.\d+)+)[:\s]+([^\n(]+)/);if(t)return{version:"v"+t[1],name:t[2].trim()};let r=i.match(/v(\d+(?:\.\d+)+)/);return{version:r?r[0]:"v1.0",name:"milestone"}}catch{return{version:"v1.0",name:"milestone"}}}function Pe(n){let e=new Set;try{let t=be(T.default.readFileSync(I.default.join(F(n),"ROADMAP.md"),"utf-8"),n),r=/#{2,4}\s*Phase\s+([\w][\w.-]*)\s*:/gi,o;for(;(o=r.exec(t))!==null;)e.add(o[1])}catch{}if(e.size===0){let t=r=>!0;return t.phaseCount=0,t}let s=new Set([...e].map(t=>(t.replace(/^0+/,"")||"0").toLowerCase()));function i(t){let r=t.match(/^0*(\d+[A-Za-z]?(?:\.\d+)*)/);if(r&&s.has(r[1].toLowerCase()))return!0;let o=t.match(/^([A-Za-z][A-Za-z0-9]*(?:-[A-Za-z0-9]+)*)/);return!!(o&&s.has(o[1].toLowerCase()))}return i.phaseCount=e.size,i}function at(n){return n.filter(e=>e.endsWith("-PLAN.md")||e==="PLAN.md")}function lt(n){return n.filter(e=>e.endsWith("-SUMMARY.md")||e==="SUMMARY.md")}function Jn(n){let e=T.default.readdirSync(n);return{plans:at(e),summaries:lt(e),hasResearch:e.some(s=>s.endsWith("-RESEARCH.md")||s==="RESEARCH.md"),hasContext:e.some(s=>s.endsWith("-CONTEXT.md")||s==="CONTEXT.md"),hasVerification:e.some(s=>s.endsWith("-VERIFICATION.md")||s==="VERIFICATION.md"),hasReviews:e.some(s=>s.endsWith("-REVIEWS.md")||s==="REVIEWS.md")}}function Oe(n,e=!1){try{let i=T.default.readdirSync(n,{withFileTypes:!0}).filter(t=>t.isDirectory()).map(t=>t.name);return e?i.sort((t,r)=>ke(t,r)):i}catch{return[]}}var ft,T,ht,I,Gn,fe=le(()=>{"use strict";ft=require("child_process"),T=W(require("fs")),ht=W(require("os")),I=W(require("path"));rt();Gn={opus:"claude-opus-4-6",sonnet:"claude-sonnet-4-6",haiku:"claude-haiku-4-5"}});var mn={};pe(mn,{FRONTMATTER_SCHEMAS:()=>Tt,cmdFrontmatterGet:()=>Yn,cmdFrontmatterMerge:()=>Zn,cmdFrontmatterSet:()=>Kn,cmdFrontmatterValidate:()=>Qn,extractFrontmatter:()=>ee,parseMustHavesBlock:()=>St,reconstructFrontmatter:()=>Xe,spliceFrontmatter:()=>Ot});function ee(n){let e={},s=[...n.matchAll(/(?:^|\n)\s*---\r?\n([\s\S]+?)\r?\n---/g)],i=s.length>0?s[s.length-1]:null;if(!i)return e;let r=i[1].split(/\r?\n/),o=[{obj:e,key:null,indent:-1}];for(let a of r){if(a.trim()==="")continue;let l=a.match(/^(\s*)/),c=l?l[1].length:0;for(;o.length>1&&c<=o[o.length-1].indent;)o.pop();let d=o[o.length-1],u=a.match(/^(\s*)([a-zA-Z0-9_-]+):\s*(.*)/);if(u){let p=u[2],m=u[3].trim();m===""||m==="["?(d.obj[p]=m==="["?[]:{},d.key=null,o.push({obj:d.obj[p],key:null,indent:c})):m.startsWith("[")&&m.endsWith("]")?(d.obj[p]=m.slice(1,-1).split(",").map(f=>f.trim().replace(/^["']|["']$/g,"")).filter(Boolean),d.key=null):(d.obj[p]=m.replace(/^["']|["']$/g,""),d.key=null)}else if(a.trim().startsWith("- ")){let p=a.trim().slice(2).replace(/^["']|["']$/g,"");if(typeof d.obj=="object"&&!Array.isArray(d.obj)&&Object.keys(d.obj).length===0){let m=o.length>1?o[o.length-2]:null;if(m){for(let f of Object.keys(m.obj))if(m.obj[f]===d.obj){m.obj[f]=[p],d.obj=m.obj[f];break}}}else Array.isArray(d.obj)&&d.obj.push(p)}}return e}function Xe(n){let e=[];for(let[s,i]of Object.entries(n))if(i!=null)if(Array.isArray(i))if(i.length===0)e.push(`${s}: []`);else if(i.every(t=>typeof t=="string")&&i.length<=3&&i.join(", ").length<60)e.push(`${s}: [${i.join(", ")}]`);else{e.push(`${s}:`);for(let t of i){let r=String(t);e.push(` - ${typeof t=="string"&&(r.includes(":")||r.includes("#"))?`"${r}"`:r}`)}}else if(typeof i=="object"){e.push(`${s}:`);for(let[t,r]of Object.entries(i))if(r!=null)if(Array.isArray(r))if(r.length===0)e.push(` ${t}: []`);else if(r.every(o=>typeof o=="string")&&r.length<=3&&r.join(", ").length<60)e.push(` ${t}: [${r.join(", ")}]`);else{e.push(` ${t}:`);for(let o of r)e.push(` - ${o}`)}else if(typeof r=="object"){e.push(` ${t}:`);for(let[o,a]of Object.entries(r))if(a!=null)if(Array.isArray(a))if(a.length===0)e.push(` ${o}: []`);else{e.push(` ${o}:`);for(let l of a)e.push(` - ${l}`)}else e.push(` ${o}: ${a}`)}else{let o=String(r);e.push(` ${t}: ${o.includes(":")||o.includes("#")?`"${o}"`:o}`)}}else{let t=String(i);t.includes(":")||t.includes("#")||t.startsWith("[")||t.startsWith("{")?e.push(`${s}: "${t}"`):e.push(`${s}: ${t}`)}return e.join(`
143
+ `),e}function Vn(n,e){let s=0;for(let i=0;i<e;i++)/^```/.test(n[i].trimEnd())&&s++;return s%2===1}function Hn(n,e){let s=0;for(let i=0;i<=e;i++)/^```/.test(n[i].trimEnd())&&s++;return s%2===0}function cn(n){if(D.default.existsSync(I.default.join(n,".planning")))return n;let e=oe(n,["rev-parse","--git-dir"]),s=oe(n,["rev-parse","--git-common-dir"]);if(e.exitCode!==0||s.exitCode!==0)return n;let i=I.default.resolve(n,e.stdout),t=I.default.resolve(n,s.stdout);return i!==t?I.default.dirname(t):n}function F(n,e){let s=e??process.env.GSD_WORKSTREAM??null;return s?I.default.join(n,".planning","workstreams",s):I.default.join(n,".planning")}function J(n){return I.default.join(n,".planning")}function R(n,e){let s=F(n,e),i=I.default.join(n,".planning");return{planning:s,state:I.default.join(s,"STATE.md"),roadmap:I.default.join(s,"ROADMAP.md"),project:I.default.join(i,"PROJECT.md"),config:I.default.join(i,"config.json"),phases:I.default.join(s,"phases"),requirements:I.default.join(s,"REQUIREMENTS.md")}}function Ye(n){let e=I.default.join(J(n),"active-workstream");try{let s=D.default.readFileSync(e,"utf-8").trim();return!s||!/^[a-zA-Z0-9_-]+$/.test(s)||!D.default.existsSync(I.default.join(J(n),"workstreams",s))?null:s}catch{return null}}function Ke(n,e){let s=I.default.join(J(n),"active-workstream");if(!e){try{D.default.unlinkSync(s)}catch{}return}if(!/^[a-zA-Z0-9_-]+$/.test(e))throw new Error("Invalid workstream name");D.default.writeFileSync(s,e+`
144
+ `,"utf-8")}function Q(n){return String(n).replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function ce(n){let e=String(n),s=e.match(/^(\d+)([A-Z])?((?:\.\d+)*)/i);return s?s[1].padStart(2,"0")+(s[2]?s[2].toUpperCase():"")+(s[3]||""):e}function ke(n,e){let s=String(n).match(/^(\d+)([A-Z])?((?:\.\d+)*)/i),i=String(e).match(/^(\d+)([A-Z])?((?:\.\d+)*)/i);if(!s||!i)return String(n).localeCompare(String(e));let t=parseInt(s[1],10)-parseInt(i[1],10);if(t!==0)return t;let r=(s[2]||"").toUpperCase(),o=(i[2]||"").toUpperCase();if(r!==o)return r?o&&r<o?-1:1:-1;let a=s[3]?s[3].slice(1).split(".").map(c=>parseInt(c,10)):[],l=i[3]?i[3].slice(1).split(".").map(c=>parseInt(c,10)):[];if(a.length===0&&l.length>0)return-1;if(l.length===0&&a.length>0)return 1;for(let c=0;c<Math.max(a.length,l.length);c++){let d=Number.isFinite(a[c])?a[c]:0,u=Number.isFinite(l[c])?l[c]:0;if(d!==u)return d-u}return 0}function an(n,e,s){try{let t=Oe(n,!0).find(v=>v.startsWith(s)||v.toUpperCase().startsWith(s.toUpperCase()));if(!t)return null;let r=t.match(/^(\d+[A-Z]?(?:\.\d+)*)-?(.*)/i)||t.match(/^([A-Z][A-Z0-9]*(?:-[A-Z0-9]+)*)-(.+)/i)||[null,t,null],o=r?.[1]??s,a=r?.[2]||null,l=I.default.join(n,t),{plans:c,summaries:d,hasResearch:u,hasContext:f,hasVerification:m,hasReviews:p}=Jn(l),y=c.sort(),g=d.sort(),_=new Set(g.map(v=>v.replace("-SUMMARY.md","").replace("SUMMARY.md",""))),b=y.filter(v=>!_.has(v.replace("-PLAN.md","").replace("PLAN.md","")));return{found:!0,directory:z(I.default.join(e,t)),phase_number:o,phase_name:a,phase_slug:a?a.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,""):null,plans:y,summaries:g,incomplete_plans:b,has_research:u,has_context:f,has_verification:m,has_reviews:p}}catch{return null}}function ue(n,e){if(!e)return null;let s=I.default.join(F(n),"phases"),i=ce(e),t=z(I.default.relative(n,s)),r=an(s,t,i);if(r)return r;let o=I.default.join(n,".planning","milestones");if(!D.default.existsSync(o))return null;try{let a=D.default.readdirSync(o,{withFileTypes:!0}).filter(l=>l.isDirectory()&&/^v[\d.]+-phases$/.test(l.name)).map(l=>l.name).sort().reverse();for(let l of a){let c=l.match(/^(v[\d.]+)-phases$/)[1],d=I.default.join(o,l),u=".planning/milestones/"+l,f=an(d,u,i);if(f)return f.archived=c,f}}catch{}return null}function gt(n){let e=I.default.join(n,".planning","milestones"),s=[];if(!D.default.existsSync(e))return s;try{let i=D.default.readdirSync(e,{withFileTypes:!0}).filter(t=>t.isDirectory()&&/^v[\d.]+-phases$/.test(t.name)).map(t=>t.name).sort().reverse();for(let t of i){let r=t.match(/^(v[\d.]+)-phases$/)[1],o=I.default.join(e,t);for(let a of Oe(o,!0))s.push({name:a,milestone:r,basePath:I.default.join(".planning","milestones",t),fullPath:I.default.join(o,a)})}}catch{}return s}function ft(n){return n.replace(/<details>[\s\S]*?<\/details>/gi,"")}function be(n,e){if(!e)return ft(n);let s=null;try{let u=I.default.join(F(e),"STATE.md");if(D.default.existsSync(u)){let m=D.default.readFileSync(u,"utf-8").match(/^milestone:\s*(.+)/m);m&&(s=m[1].trim())}}catch{}if(!s){let u=n.match(/🚧\s*\*\*v(\d+\.\d+)\s/);u&&(s="v"+u[1])}if(!s)return ft(n);let i=new RegExp(`(^#{1,3}\\s+.*${Q(s)}[^\\n]*)`,"mi"),t=n.match(i);if(!t)return ft(n);let r=t.index,o=t[1].match(/^(#{1,3})\s/)[1].length,l=n.slice(r+t[0].length).match(new RegExp(`^#{1,${o}}\\s+(?:.*v\\d+\\.\\d+|\u2705|\u{1F4CB}|\u{1F6A7})`,"mi")),c=l?r+t[0].length+l.index:n.length;return n.slice(0,r).replace(/<details>[\s\S]*?<\/details>/gi,"")+n.slice(r,c)}function Ze(n,e,s){let i=n.lastIndexOf("</details>");if(i===-1)return n.replace(e,s);let t=i+10,r=n.slice(0,t),o=n.slice(t);return r+o.replace(e,s)}function Qe(n,e){if(!e)return null;let s=I.default.join(F(n),"ROADMAP.md");if(!D.default.existsSync(s))return null;try{let i=be(D.default.readFileSync(s,"utf-8"),n),t=new RegExp(`#{2,4}\\s*Phase\\s+${Q(e)}:\\s*([^\\n]+)`,"i"),r=i.match(t);if(!r)return null;let o=r[1].trim(),a=r.index,c=i.slice(a).match(/\n#{2,4}\s+Phase\s+[\w]/i),d=c?a+c.index:i.length,u=i.slice(a,d).trim(),f=u.match(/\*\*Goal(?:\*\*:|\*?\*?:\*\*)\s*([^\n]+)/i);return{found:!0,phase_number:e.toString(),phase_name:o,goal:f?f[1].trim():null,section:u}}catch{return null}}function Bn(){return I.default.join(__dirname,"..","..","agents")}function ot(){let n=Bn(),e=Object.keys(je),s=[],i=[];if(!D.default.existsSync(n))return{agents_installed:!1,missing_agents:e,installed_agents:[],agents_dir:n};for(let t of e)D.default.existsSync(I.default.join(n,`${t}.md`))?s.push(t):i.push(t);return{agents_installed:s.length>0&&i.length===0,missing_agents:i,installed_agents:s,agents_dir:n}}function X(n,e){let s=B(n),i=s.model_overrides?.[e];if(i)return i;if(s.resolve_model_ids==="omit")return"";let t=String(s.model_profile||"balanced").toLowerCase(),r=je[e];if(!r)return"sonnet";if(t==="inherit")return"inherit";let o=r[t]||r.balanced||"sonnet";return s.resolve_model_ids&&Gn[o]||o}function yt(n){if(!n)return null;let s=n.replace(/^---\n[\s\S]*?\n---\n*/,"").match(/^#[^\n]*\n+\*\*([^*]+)\*\*/m);return s?s[1].trim():null}function De(n){return n?n.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,""):null}function ie(n){try{let e=D.default.readFileSync(I.default.join(F(n),"ROADMAP.md"),"utf-8"),s=e.match(/🚧\s*\*\*v(\d+(?:\.\d+)+)\s+([^*]+)\*\*/);if(s)return{version:"v"+s[1],name:s[2].trim()};let i=ft(e),t=i.match(/## .*v(\d+(?:\.\d+)+)[:\s]+([^\n(]+)/);if(t)return{version:"v"+t[1],name:t[2].trim()};let r=i.match(/v(\d+(?:\.\d+)+)/);return{version:r?r[0]:"v1.0",name:"milestone"}}catch{return{version:"v1.0",name:"milestone"}}}function Pe(n){let e=new Set;try{let t=be(D.default.readFileSync(I.default.join(F(n),"ROADMAP.md"),"utf-8"),n),r=/#{2,4}\s*Phase\s+([\w][\w.-]*)\s*:/gi,o;for(;(o=r.exec(t))!==null;)e.add(o[1])}catch{}if(e.size===0){let t=r=>!0;return t.phaseCount=0,t}let s=new Set([...e].map(t=>(t.replace(/^0+/,"")||"0").toLowerCase()));function i(t){let r=t.match(/^0*(\d+[A-Za-z]?(?:\.\d+)*)/);if(r&&s.has(r[1].toLowerCase()))return!0;let o=t.match(/^([A-Za-z][A-Za-z0-9]*(?:-[A-Za-z0-9]+)*)/);return!!(o&&s.has(o[1].toLowerCase()))}return i.phaseCount=e.size,i}function at(n){return n.filter(e=>e.endsWith("-PLAN.md")||e==="PLAN.md")}function lt(n){return n.filter(e=>e.endsWith("-SUMMARY.md")||e==="SUMMARY.md")}function Jn(n){let e=D.default.readdirSync(n);return{plans:at(e),summaries:lt(e),hasResearch:e.some(s=>s.endsWith("-RESEARCH.md")||s==="RESEARCH.md"),hasContext:e.some(s=>s.endsWith("-CONTEXT.md")||s==="CONTEXT.md"),hasVerification:e.some(s=>s.endsWith("-VERIFICATION.md")||s==="VERIFICATION.md"),hasReviews:e.some(s=>s.endsWith("-REVIEWS.md")||s==="REVIEWS.md")}}function Oe(n,e=!1){try{let i=D.default.readdirSync(n,{withFileTypes:!0}).filter(t=>t.isDirectory()).map(t=>t.name);return e?i.sort((t,r)=>ke(t,r)):i}catch{return[]}}var pt,D,ht,I,Gn,pe=le(()=>{"use strict";pt=require("child_process"),D=W(require("fs")),ht=W(require("os")),I=W(require("path"));rt();Gn={opus:"claude-opus-4-6",sonnet:"claude-sonnet-4-6",haiku:"claude-haiku-4-5"}});var mn={};fe(mn,{FRONTMATTER_SCHEMAS:()=>Dt,cmdFrontmatterGet:()=>Yn,cmdFrontmatterMerge:()=>Zn,cmdFrontmatterSet:()=>Kn,cmdFrontmatterValidate:()=>Qn,extractFrontmatter:()=>ee,parseMustHavesBlock:()=>St,reconstructFrontmatter:()=>Xe,spliceFrontmatter:()=>Ot});function ee(n){let e={},s=[...n.matchAll(/(?:^|\n)\s*---\r?\n([\s\S]+?)\r?\n---/g)],i=s.length>0?s[s.length-1]:null;if(!i)return e;let r=i[1].split(/\r?\n/),o=[{obj:e,key:null,indent:-1}];for(let a of r){if(a.trim()==="")continue;let l=a.match(/^(\s*)/),c=l?l[1].length:0;for(;o.length>1&&c<=o[o.length-1].indent;)o.pop();let d=o[o.length-1],u=a.match(/^(\s*)([a-zA-Z0-9_-]+):\s*(.*)/);if(u){let f=u[2],m=u[3].trim();m===""||m==="["?(d.obj[f]=m==="["?[]:{},d.key=null,o.push({obj:d.obj[f],key:null,indent:c})):m.startsWith("[")&&m.endsWith("]")?(d.obj[f]=m.slice(1,-1).split(",").map(p=>p.trim().replace(/^["']|["']$/g,"")).filter(Boolean),d.key=null):(d.obj[f]=m.replace(/^["']|["']$/g,""),d.key=null)}else if(a.trim().startsWith("- ")){let f=a.trim().slice(2).replace(/^["']|["']$/g,"");if(typeof d.obj=="object"&&!Array.isArray(d.obj)&&Object.keys(d.obj).length===0){let m=o.length>1?o[o.length-2]:null;if(m){for(let p of Object.keys(m.obj))if(m.obj[p]===d.obj){m.obj[p]=[f],d.obj=m.obj[p];break}}}else Array.isArray(d.obj)&&d.obj.push(f)}}return e}function Xe(n){let e=[];for(let[s,i]of Object.entries(n))if(i!=null)if(Array.isArray(i))if(i.length===0)e.push(`${s}: []`);else if(i.every(t=>typeof t=="string")&&i.length<=3&&i.join(", ").length<60)e.push(`${s}: [${i.join(", ")}]`);else{e.push(`${s}:`);for(let t of i){let r=String(t);e.push(` - ${typeof t=="string"&&(r.includes(":")||r.includes("#"))?`"${r}"`:r}`)}}else if(typeof i=="object"){e.push(`${s}:`);for(let[t,r]of Object.entries(i))if(r!=null)if(Array.isArray(r))if(r.length===0)e.push(` ${t}: []`);else if(r.every(o=>typeof o=="string")&&r.length<=3&&r.join(", ").length<60)e.push(` ${t}: [${r.join(", ")}]`);else{e.push(` ${t}:`);for(let o of r)e.push(` - ${o}`)}else if(typeof r=="object"){e.push(` ${t}:`);for(let[o,a]of Object.entries(r))if(a!=null)if(Array.isArray(a))if(a.length===0)e.push(` ${o}: []`);else{e.push(` ${o}:`);for(let l of a)e.push(` - ${l}`)}else e.push(` ${o}: ${a}`)}else{let o=String(r);e.push(` ${t}: ${o.includes(":")||o.includes("#")?`"${o}"`:o}`)}}else{let t=String(i);t.includes(":")||t.includes("#")||t.startsWith("[")||t.startsWith("{")?e.push(`${s}: "${t}"`):e.push(`${s}: ${t}`)}return e.join(`
145
145
  `)}function Ot(n,e){let s=Xe(e),i=n.match(/^---\r?\n[\s\S]+?\r?\n---/);return i?`---
146
146
  ${s}
147
147
  ---`+n.slice(i[0].length):`---
148
148
  ${s}
149
149
  ---
150
150
 
151
- `+n}function St(n,e){let s=n.match(/^---\r?\n([\s\S]+?)\r?\n---/);if(!s)return[];let i=s[1],t=i.match(/^(\s*)must_haves:\s*$/m);if(!t)return[];let r=t[1].length,o=new RegExp(`^(\\s+)${e}:\\s*$`,"m"),a=i.match(o);if(!a)return[];let l=a[1].length;if(l<=r)return[];let c=i.indexOf(a[0]);if(c===-1)return[];let u=i.slice(c).split(/\r?\n/).slice(1),p=[],m=null,f=-1;for(let y of u){if(y.trim()==="")continue;let g=y.match(/^(\s*)/)?.[1].length??0;if(g<=l&&y.trim()!=="")break;let _=y.trim();if(_.startsWith("- ")&&(f===-1&&(f=g),g===f)){m&&p.push(m),m={};let b=_.slice(2);if(!b.includes(":"))m=b.replace(/^["']|["']$/g,"");else{let v=b.match(/^(\w+):\s*"?([^"]*)"?\s*$/);v&&(m={},m[v[1]]=v[2])}continue}if(m&&typeof m=="object"&&g>f)if(_.startsWith("- ")){let b=_.slice(2).replace(/^["']|["']$/g,""),v=Object.keys(m),P=v[v.length-1];P&&!Array.isArray(m[P])&&(m[P]=m[P]?[m[P]]:[]),P&&m[P].push(b)}else{let b=_.match(/^(\w+):\s*"?([^"]*)"?\s*$/);if(b){let v=b[2];m[b[1]]=/^\d+$/.test(v)?parseInt(v,10):v}}}return m&&p.push(m),p}function Yn(n,e,s,i){e||S("file path required"),e.includes("\0")&&S("file path contains null bytes");let t=Le.default.isAbsolute(e)?e:Le.default.join(n,e),r=we(t);if(!r){h({error:"File not found",path:e},i);return}let o=ee(r);if(s){let a=o[s];if(a===void 0){h({error:"Field not found",field:s},i);return}h({[s]:a},i,JSON.stringify(a))}else h(o,i)}function Kn(n,e,s,i,t){(!e||!s||i===void 0)&&S("file, field, and value required"),e.includes("\0")&&S("file path contains null bytes");let r=Le.default.isAbsolute(e)?e:Le.default.join(n,e);if(!He.default.existsSync(r)){h({error:"File not found",path:e},t);return}let o=He.default.readFileSync(r,"utf-8"),a=ee(o),l;try{l=JSON.parse(i)}catch{l=i}a[s]=l;let c=Ot(o,a);He.default.writeFileSync(r,Re(c),"utf-8"),h({updated:!0,field:s,value:l},t,"true")}function Zn(n,e,s,i){(!e||!s)&&S("file and data required");let t=Le.default.isAbsolute(e)?e:Le.default.join(n,e);if(!He.default.existsSync(t)){h({error:"File not found",path:e},i);return}let r=He.default.readFileSync(t,"utf-8"),o=ee(r),a;try{a=JSON.parse(s)}catch{S("Invalid JSON for --data");return}Object.assign(o,a);let l=Ot(r,o);He.default.writeFileSync(t,Re(l),"utf-8"),h({merged:!0,fields:Object.keys(a)},i,"true")}function Qn(n,e,s,i){(!e||!s)&&S("file and schema required");let t=Tt[s];if(!t){S(`Unknown schema: ${s}. Available: ${Object.keys(Tt).join(", ")}`);return}let r=Le.default.isAbsolute(e)?e:Le.default.join(n,e),o=we(r);if(!o){h({error:"File not found",path:e},i);return}let a=ee(o),l=t.required.filter(d=>a[d]===void 0),c=t.required.filter(d=>a[d]!==void 0);h({valid:l.length===0,missing:l,present:c,schema:s},i,l.length===0?"valid":"invalid")}var He,Le,Tt,Ue=le(()=>{"use strict";He=W(require("fs")),Le=W(require("path"));fe();Tt={plan:{required:["phase","plan","type","wave","depends_on","files_modified","autonomous","must_haves"]},summary:{required:["phase","plan","subsystem","tags","duration","completed"]},verification:{required:["phase","verified","status","score"]}}});var fn={};pe(fn,{requireSafePath:()=>Wt,safeJsonParse:()=>ts,sanitizeForDisplay:()=>xt,sanitizeForPrompt:()=>Nt,scanForInjection:()=>es,validateFieldName:()=>vt,validatePath:()=>bt});function es(n){let e=[];for(let s of Xn)s.test(n)&&e.push(s.source);return e}function Nt(n){if(!n)return n;let e=n.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g,"");return e.length>pn&&(e=e.slice(0,pn)+"... [truncated]"),e}function ts(n,e={}){try{return{ok:!0,value:JSON.parse(n)}}catch(s){return{ok:!1,error:`Invalid ${e.label??"JSON"}: ${s.message}`}}}function bt(n,e,s={}){if(n.includes("\0"))return{safe:!1,resolved:n,error:"Path contains null bytes"};let i=_t.default.isAbsolute(n)?n:_t.default.resolve(e,n),t=process.env.HOME??"/";return!i.startsWith(t)&&!i.startsWith(e)?{safe:!1,resolved:i,error:"Path traversal rejected"}:!s.allowAbsolute&&_t.default.isAbsolute(n)?{safe:!1,resolved:i,error:"Absolute paths not allowed"}:{safe:!0,resolved:i}}function Wt(n,e,s,i={}){let t=bt(n,e,i);if(!t.safe)throw new Error(`${s||"Path"} validation failed: ${t.error}`);return t.resolved}function xt(n){if(!n||typeof n!="string")return n;let e=n.replace(/[\u200B-\u200F\u2028-\u202F\uFEFF\u00AD]/g,"");return e=e.replace(/<(\/?)(?:system|assistant|human)>/gi,(s,i)=>`\uFF1C${i||""}system-text\uFF1E`),e=e.replace(/\[(SYSTEM|INST)\]/gi,"[$1-TEXT]"),e=e.replace(/<<\s*SYS\s*>>/gi,"\xABSYS-TEXT\xBB"),e}function vt(n){return!n||typeof n!="string"?{valid:!1,error:"Field name must be a non-empty string"}:/^[a-zA-Z][a-zA-Z0-9 _-]*$/.test(n)?{valid:!0}:{valid:!1,error:`Field name "${n}" contains invalid characters. Only letters, digits, spaces, hyphens, and underscores are allowed.`}}var _t,Xn,pn,ct=le(()=>{"use strict";_t=W(require("path")),Xn=[/ignore\s+(?:all\s+)?previous\s+instructions?/i,/forget\s+(?:all\s+)?previous/i,/\bsystem\s+prompt\b/i,/\bdisregard\s+(?:all\s+)?previous\b/i,/\byou\s+are\s+now\b/i,/\bact\s+as\s+(?:a\s+)?(?:new\s+)?(?:AI|assistant|gpt|claude|llm)\b/i,/\bpretend\s+(?:you\s+are|to\s+be)\b/i,/\boverride\s+(?:all\s+)?(?:previous\s+)?(?:instructions?|directives?|rules?|constraints?)\b/i,/\bdo\s+not\s+follow\s+(?:the\s+)?(?:previous\s+)?instructions?\b/i,/\bnew\s+instructions?:\s/i,/\bignore\s+(?:all\s+)?(?:previous\s+)?(?:context|history|instructions?)\b/i,/\bdeveloper\s+mode\b/i,/\bDAN\s+mode\b/i],pn=1e4});var Ut={};pe(Ut,{cmdSignalResume:()=>_s,cmdSignalWaiting:()=>Ss,cmdStateAddBlocker:()=>ms,cmdStateAddDecision:()=>us,cmdStateAdvancePlan:()=>ls,cmdStateBeginPhase:()=>ys,cmdStateGet:()=>rs,cmdStateJson:()=>gs,cmdStateLoad:()=>is,cmdStatePatch:()=>os,cmdStateRecordMetric:()=>cs,cmdStateRecordSession:()=>fs,cmdStateResolveBlocker:()=>ps,cmdStateSnapshot:()=>hs,cmdStateUpdate:()=>as,cmdStateUpdateProgress:()=>ds,stateExtractField:()=>V,stateReplaceField:()=>Se,stateReplaceFieldWithFallback:()=>he,stripFrontmatter:()=>Lt,writeStateMd:()=>te});function ns(n){return R(n).state}function V(n,e){let s=Q(e),i=n.match(new RegExp(`\\*\\*${s}:\\*\\*\\s*(.+)`,"i"));if(i)return i[1].trim();let t=n.match(new RegExp(`^${s}:\\s*(.+)`,"im"));return t?t[1].trim():null}function Se(n,e,s){let i=Q(e),t=new RegExp(`(\\*\\*${i}:\\*\\*\\s*)(.*)`,"i");if(t.test(n))return n.replace(t,(o,a)=>`${a}${s}`);let r=new RegExp(`(^${i}:\\s*)(.*)`,"im");return r.test(n)?n.replace(r,(o,a)=>`${a}${s}`):null}function he(n,e,s,i){let t=Se(n,e,i);if(t)return t;if(s){let r=Se(n,s,i);if(r)return r}return n}function hn(n,e){let s=/(##\s*Current Position\s*\n)([\s\S]*?)(?=\n##|$)/i,i=n.match(s);if(!i)return n;let t=i[2];return e.status&&/^Status:/m.test(t)&&(t=t.replace(/^Status:.*$/m,`Status: ${e.status}`)),e.lastActivity&&/^Last activity:/im.test(t)&&(t=t.replace(/^Last activity:.*$/im,`Last activity: ${e.lastActivity}`)),e.plan&&/^Plan:/m.test(t)&&(t=t.replace(/^Plan:.*$/m,`Plan: ${e.plan}`)),n.replace(s,`${i[1]}${t}`)}function qt(n,e,s,i){if(!s)return e??"";let t=bt(s,n,{allowAbsolute:!0});if(!t.safe)throw new Error(`${i} path rejected: ${t.error}`);try{return C.default.readFileSync(t.resolved,"utf-8").trimEnd()}catch{throw new Error(`${i} file not found: ${s}`)}}function Lt(n){let e=n;for(;;){let s=e.replace(/^\s*---\r?\n[\s\S]*?\r?\n---\s*/,"");if(s===e)break;e=s}return e}function gn(n,e){let s=V(n,"Current Phase"),i=V(n,"Current Phase Name"),t=V(n,"Current Plan"),r=V(n,"Total Phases"),o=V(n,"Total Plans in Phase"),a=V(n,"Status"),l=V(n,"Progress"),c=V(n,"Last Activity"),d=V(n,"Stopped At")||V(n,"Stopped at"),u=V(n,"Paused At"),p=null,m=null;if(e)try{let D=ie(e);p=D.version,m=D.name}catch{}let f=r?parseInt(r,10):null,y=null,g=o?parseInt(o,10):null,_=null;if(e)try{let D=R(e).phases;if(C.default.existsSync(D)){let A=Pe(e),O=C.default.readdirSync(D,{withFileTypes:!0}).filter(de=>de.isDirectory()).map(de=>de.name).filter(A),N=0,L=0,ne=0;for(let de of O){let ve=C.default.readdirSync(Me.default.join(D,de)),se=ve.filter(De=>De.match(/-PLAN\.md$/i)).length,me=ve.filter(De=>De.match(/-SUMMARY\.md$/i)).length;N+=se,L+=me,se>0&&me>=se&&ne++}f=A.phaseCount>0?Math.max(O.length,A.phaseCount):O.length,y=ne,g=N,_=L}}catch{}let b=null;if(l){let D=l.match(/(\d+)%/);D&&(b=parseInt(D[1],10))}let v=a??"unknown",P=(a??"").toLowerCase();P.includes("paused")||P.includes("stopped")||u?v="paused":P.includes("executing")||P.includes("in progress")?v="executing":P.includes("planning")||P.includes("ready to plan")?v="planning":P.includes("discussing")?v="discussing":P.includes("verif")?v="verifying":P.includes("complete")||P.includes("done")?v="completed":P.includes("ready to execute")&&(v="executing");let k={gsd_state_version:"1.0"};p&&(k.milestone=p),m&&(k.milestone_name=m),s&&(k.current_phase=s),i&&(k.current_phase_name=i),t&&(k.current_plan=t),k.status=v,d&&(k.stopped_at=d),u&&(k.paused_at=u),k.last_updated=new Date().toISOString(),c&&(k.last_activity=c);let $={};return f!==null&&($.total_phases=f),y!==null&&($.completed_phases=y),g!==null&&($.total_plans=g),_!==null&&($.completed_plans=_),b!==null&&($.percent=b),Object.keys($).length>0&&(k.progress=$),k}function ss(n,e){let s=ee(n),i=Lt(n),t=gn(i,e);return t.status==="unknown"&&s.status&&s.status!=="unknown"&&(t.status=s.status),`---
151
+ `+n}function St(n,e){let s=n.match(/^---\r?\n([\s\S]+?)\r?\n---/);if(!s)return[];let i=s[1],t=i.match(/^(\s*)must_haves:\s*$/m);if(!t)return[];let r=t[1].length,o=new RegExp(`^(\\s+)${e}:\\s*$`,"m"),a=i.match(o);if(!a)return[];let l=a[1].length;if(l<=r)return[];let c=i.indexOf(a[0]);if(c===-1)return[];let u=i.slice(c).split(/\r?\n/).slice(1),f=[],m=null,p=-1;for(let y of u){if(y.trim()==="")continue;let g=y.match(/^(\s*)/)?.[1].length??0;if(g<=l&&y.trim()!=="")break;let _=y.trim();if(_.startsWith("- ")&&(p===-1&&(p=g),g===p)){m&&f.push(m),m={};let b=_.slice(2);if(!b.includes(":"))m=b.replace(/^["']|["']$/g,"");else{let v=b.match(/^(\w+):\s*"?([^"]*)"?\s*$/);v&&(m={},m[v[1]]=v[2])}continue}if(m&&typeof m=="object"&&g>p)if(_.startsWith("- ")){let b=_.slice(2).replace(/^["']|["']$/g,""),v=Object.keys(m),P=v[v.length-1];P&&!Array.isArray(m[P])&&(m[P]=m[P]?[m[P]]:[]),P&&m[P].push(b)}else{let b=_.match(/^(\w+):\s*"?([^"]*)"?\s*$/);if(b){let v=b[2];m[b[1]]=/^\d+$/.test(v)?parseInt(v,10):v}}}return m&&f.push(m),f}function Yn(n,e,s,i){e||S("file path required"),e.includes("\0")&&S("file path contains null bytes");let t=Le.default.isAbsolute(e)?e:Le.default.join(n,e),r=we(t);if(!r){h({error:"File not found",path:e},i);return}let o=ee(r);if(s){let a=o[s];if(a===void 0){h({error:"Field not found",field:s},i);return}h({[s]:a},i,JSON.stringify(a))}else h(o,i)}function Kn(n,e,s,i,t){(!e||!s||i===void 0)&&S("file, field, and value required"),e.includes("\0")&&S("file path contains null bytes");let r=Le.default.isAbsolute(e)?e:Le.default.join(n,e);if(!He.default.existsSync(r)){h({error:"File not found",path:e},t);return}let o=He.default.readFileSync(r,"utf-8"),a=ee(o),l;try{l=JSON.parse(i)}catch{l=i}a[s]=l;let c=Ot(o,a);He.default.writeFileSync(r,Re(c),"utf-8"),h({updated:!0,field:s,value:l},t,"true")}function Zn(n,e,s,i){(!e||!s)&&S("file and data required");let t=Le.default.isAbsolute(e)?e:Le.default.join(n,e);if(!He.default.existsSync(t)){h({error:"File not found",path:e},i);return}let r=He.default.readFileSync(t,"utf-8"),o=ee(r),a;try{a=JSON.parse(s)}catch{S("Invalid JSON for --data");return}Object.assign(o,a);let l=Ot(r,o);He.default.writeFileSync(t,Re(l),"utf-8"),h({merged:!0,fields:Object.keys(a)},i,"true")}function Qn(n,e,s,i){(!e||!s)&&S("file and schema required");let t=Dt[s];if(!t){S(`Unknown schema: ${s}. Available: ${Object.keys(Dt).join(", ")}`);return}let r=Le.default.isAbsolute(e)?e:Le.default.join(n,e),o=we(r);if(!o){h({error:"File not found",path:e},i);return}let a=ee(o),l=t.required.filter(d=>a[d]===void 0),c=t.required.filter(d=>a[d]!==void 0);h({valid:l.length===0,missing:l,present:c,schema:s},i,l.length===0?"valid":"invalid")}var He,Le,Dt,Ue=le(()=>{"use strict";He=W(require("fs")),Le=W(require("path"));pe();Dt={plan:{required:["phase","plan","type","wave","depends_on","files_modified","autonomous","must_haves"]},summary:{required:["phase","plan","subsystem","tags","duration","completed"]},verification:{required:["phase","verified","status","score"]}}});var pn={};fe(pn,{requireSafePath:()=>Wt,safeJsonParse:()=>ts,sanitizeForDisplay:()=>xt,sanitizeForPrompt:()=>Nt,scanForInjection:()=>es,validateFieldName:()=>vt,validatePath:()=>bt});function es(n){let e=[];for(let s of Xn)s.test(n)&&e.push(s.source);return e}function Nt(n){if(!n)return n;let e=n.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g,"");return e.length>fn&&(e=e.slice(0,fn)+"... [truncated]"),e}function ts(n,e={}){try{return{ok:!0,value:JSON.parse(n)}}catch(s){return{ok:!1,error:`Invalid ${e.label??"JSON"}: ${s.message}`}}}function bt(n,e,s={}){if(n.includes("\0"))return{safe:!1,resolved:n,error:"Path contains null bytes"};let i=_t.default.isAbsolute(n)?n:_t.default.resolve(e,n),t=process.env.HOME??"/";return!i.startsWith(t)&&!i.startsWith(e)?{safe:!1,resolved:i,error:"Path traversal rejected"}:!s.allowAbsolute&&_t.default.isAbsolute(n)?{safe:!1,resolved:i,error:"Absolute paths not allowed"}:{safe:!0,resolved:i}}function Wt(n,e,s,i={}){let t=bt(n,e,i);if(!t.safe)throw new Error(`${s||"Path"} validation failed: ${t.error}`);return t.resolved}function xt(n){if(!n||typeof n!="string")return n;let e=n.replace(/[\u200B-\u200F\u2028-\u202F\uFEFF\u00AD]/g,"");return e=e.replace(/<(\/?)(?:system|assistant|human)>/gi,(s,i)=>`\uFF1C${i||""}system-text\uFF1E`),e=e.replace(/\[(SYSTEM|INST)\]/gi,"[$1-TEXT]"),e=e.replace(/<<\s*SYS\s*>>/gi,"\xABSYS-TEXT\xBB"),e}function vt(n){return!n||typeof n!="string"?{valid:!1,error:"Field name must be a non-empty string"}:/^[a-zA-Z][a-zA-Z0-9 _-]*$/.test(n)?{valid:!0}:{valid:!1,error:`Field name "${n}" contains invalid characters. Only letters, digits, spaces, hyphens, and underscores are allowed.`}}var _t,Xn,fn,ct=le(()=>{"use strict";_t=W(require("path")),Xn=[/ignore\s+(?:all\s+)?previous\s+instructions?/i,/forget\s+(?:all\s+)?previous/i,/\bsystem\s+prompt\b/i,/\bdisregard\s+(?:all\s+)?previous\b/i,/\byou\s+are\s+now\b/i,/\bact\s+as\s+(?:a\s+)?(?:new\s+)?(?:AI|assistant|gpt|claude|llm)\b/i,/\bpretend\s+(?:you\s+are|to\s+be)\b/i,/\boverride\s+(?:all\s+)?(?:previous\s+)?(?:instructions?|directives?|rules?|constraints?)\b/i,/\bdo\s+not\s+follow\s+(?:the\s+)?(?:previous\s+)?instructions?\b/i,/\bnew\s+instructions?:\s/i,/\bignore\s+(?:all\s+)?(?:previous\s+)?(?:context|history|instructions?)\b/i,/\bdeveloper\s+mode\b/i,/\bDAN\s+mode\b/i],fn=1e4});var Ut={};fe(Ut,{cmdSignalResume:()=>_s,cmdSignalWaiting:()=>Ss,cmdStateAddBlocker:()=>ms,cmdStateAddDecision:()=>us,cmdStateAdvancePlan:()=>ls,cmdStateBeginPhase:()=>ys,cmdStateGet:()=>rs,cmdStateJson:()=>gs,cmdStateLoad:()=>is,cmdStatePatch:()=>os,cmdStateRecordMetric:()=>cs,cmdStateRecordSession:()=>ps,cmdStateResolveBlocker:()=>fs,cmdStateSnapshot:()=>hs,cmdStateUpdate:()=>as,cmdStateUpdateProgress:()=>ds,stateExtractField:()=>V,stateReplaceField:()=>Se,stateReplaceFieldWithFallback:()=>he,stripFrontmatter:()=>Lt,writeStateMd:()=>te});function ns(n){return R(n).state}function V(n,e){let s=Q(e),i=n.match(new RegExp(`\\*\\*${s}:\\*\\*\\s*(.+)`,"i"));if(i)return i[1].trim();let t=n.match(new RegExp(`^${s}:\\s*(.+)`,"im"));return t?t[1].trim():null}function Se(n,e,s){let i=Q(e),t=new RegExp(`(\\*\\*${i}:\\*\\*\\s*)(.*)`,"i");if(t.test(n))return n.replace(t,(o,a)=>`${a}${s}`);let r=new RegExp(`(^${i}:\\s*)(.*)`,"im");return r.test(n)?n.replace(r,(o,a)=>`${a}${s}`):null}function he(n,e,s,i){let t=Se(n,e,i);if(t)return t;if(s){let r=Se(n,s,i);if(r)return r}return n}function hn(n,e){let s=/(##\s*Current Position\s*\n)([\s\S]*?)(?=\n##|$)/i,i=n.match(s);if(!i)return n;let t=i[2];return e.status&&/^Status:/m.test(t)&&(t=t.replace(/^Status:.*$/m,`Status: ${e.status}`)),e.lastActivity&&/^Last activity:/im.test(t)&&(t=t.replace(/^Last activity:.*$/im,`Last activity: ${e.lastActivity}`)),e.plan&&/^Plan:/m.test(t)&&(t=t.replace(/^Plan:.*$/m,`Plan: ${e.plan}`)),n.replace(s,`${i[1]}${t}`)}function qt(n,e,s,i){if(!s)return e??"";let t=bt(s,n,{allowAbsolute:!0});if(!t.safe)throw new Error(`${i} path rejected: ${t.error}`);try{return C.default.readFileSync(t.resolved,"utf-8").trimEnd()}catch{throw new Error(`${i} file not found: ${s}`)}}function Lt(n){let e=n;for(;;){let s=e.replace(/^\s*---\r?\n[\s\S]*?\r?\n---\s*/,"");if(s===e)break;e=s}return e}function gn(n,e){let s=V(n,"Current Phase"),i=V(n,"Current Phase Name"),t=V(n,"Current Plan"),r=V(n,"Total Phases"),o=V(n,"Total Plans in Phase"),a=V(n,"Status"),l=V(n,"Progress"),c=V(n,"Last Activity"),d=V(n,"Stopped At")||V(n,"Stopped at"),u=V(n,"Paused At"),f=null,m=null;if(e)try{let T=ie(e);f=T.version,m=T.name}catch{}let p=r?parseInt(r,10):null,y=null,g=o?parseInt(o,10):null,_=null;if(e)try{let T=R(e).phases;if(C.default.existsSync(T)){let A=Pe(e),O=C.default.readdirSync(T,{withFileTypes:!0}).filter(de=>de.isDirectory()).map(de=>de.name).filter(A),N=0,L=0,ne=0;for(let de of O){let ve=C.default.readdirSync(Me.default.join(T,de)),se=ve.filter(Te=>Te.match(/-PLAN\.md$/i)).length,me=ve.filter(Te=>Te.match(/-SUMMARY\.md$/i)).length;N+=se,L+=me,se>0&&me>=se&&ne++}p=A.phaseCount>0?Math.max(O.length,A.phaseCount):O.length,y=ne,g=N,_=L}}catch{}let b=null;if(l){let T=l.match(/(\d+)%/);T&&(b=parseInt(T[1],10))}let v=a??"unknown",P=(a??"").toLowerCase();P.includes("paused")||P.includes("stopped")||u?v="paused":P.includes("executing")||P.includes("in progress")?v="executing":P.includes("planning")||P.includes("ready to plan")?v="planning":P.includes("discussing")?v="discussing":P.includes("verif")?v="verifying":P.includes("complete")||P.includes("done")?v="completed":P.includes("ready to execute")&&(v="executing");let k={gsd_state_version:"1.0"};f&&(k.milestone=f),m&&(k.milestone_name=m),s&&(k.current_phase=s),i&&(k.current_phase_name=i),t&&(k.current_plan=t),k.status=v,d&&(k.stopped_at=d),u&&(k.paused_at=u),k.last_updated=new Date().toISOString(),c&&(k.last_activity=c);let $={};return p!==null&&($.total_phases=p),y!==null&&($.completed_phases=y),g!==null&&($.total_plans=g),_!==null&&($.completed_plans=_),b!==null&&($.percent=b),Object.keys($).length>0&&(k.progress=$),k}function ss(n,e){let s=ee(n),i=Lt(n),t=gn(i,e);return t.status==="unknown"&&s.status&&s.status!=="unknown"&&(t.status=s.status),`---
152
152
  ${Xe(t)}
153
153
  ---
154
154
 
155
155
  ${i}`}function te(n,e,s){let i=ss(e,s),t=n+".lock",r=10,o=200;for(let a=0;a<r;a++)try{let l=C.default.openSync(t,C.default.constants.O_CREAT|C.default.constants.O_EXCL|C.default.constants.O_WRONLY);C.default.writeSync(l,String(process.pid)),C.default.closeSync(l);break}catch(l){if(l.code==="EEXIST"){try{let u=C.default.statSync(t);if(Date.now()-u.mtimeMs>1e4){C.default.unlinkSync(t);continue}}catch{continue}if(a===r-1){try{C.default.unlinkSync(t)}catch{}break}let c=Date.now(),d=Math.floor(Math.random()*50);for(;Date.now()-c<o+d;);continue}break}try{C.default.writeFileSync(n,Re(i),"utf-8")}finally{try{C.default.unlinkSync(t)}catch{}}}function is(n,e){let s=B(n),i=R(n).planning,t="";try{t=C.default.readFileSync(Me.default.join(i,"STATE.md"),"utf-8")}catch{}let r=C.default.existsSync(Me.default.join(i,"config.json")),o=C.default.existsSync(Me.default.join(i,"ROADMAP.md")),a=t.length>0;if(e){let l=s,c=[`model_profile=${l.model_profile}`,`commit_docs=${l.commit_docs}`,`branching_strategy=${l.branching_strategy}`,`phase_branch_template=${l.phase_branch_template}`,`milestone_branch_template=${l.milestone_branch_template}`,`parallelization=${l.parallelization}`,`research=${l.research}`,`plan_checker=${l.plan_checker}`,`verifier=${l.verifier}`,`config_exists=${r}`,`roadmap_exists=${o}`,`state_exists=${a}`];process.stdout.write(c.join(`
156
156
  `)),process.exit(0)}h({config:s,state_raw:t,state_exists:a,roadmap_exists:o,config_exists:r})}function rs(n,e,s){let i=R(n).state;try{let t=C.default.readFileSync(i,"utf-8");if(!e){h({content:t},s,t);return}let r=Q(e),o=t.match(new RegExp(`\\*\\*${r}:\\*\\*\\s*(.*)`,"i"));if(o){h({[e]:o[1].trim()},s,o[1].trim());return}let a=t.match(new RegExp(`^${r}:\\s*(.*)`,"im"));if(a){h({[e]:a[1].trim()},s,a[1].trim());return}let l=t.match(new RegExp(`##\\s*${r}\\s*
157
- ([\\s\\S]*?)(?=\\n##|$)`,"i"));if(l){h({[e]:l[1].trim()},s,l[1].trim());return}h({error:`Section or field "${e}" not found`},s,"")}catch{S("STATE.md not found")}}function os(n,e,s){for(let t of Object.keys(e)){let r=vt(t);r.valid||S(`state patch: ${r.error}`)}let i=R(n).state;try{let t=C.default.readFileSync(i,"utf-8"),r={updated:[],failed:[]};for(let[o,a]of Object.entries(e)){let l=Q(o),c=new RegExp(`(\\*\\*${l}:\\*\\*\\s*)(.*)`,"i"),d=new RegExp(`(^${l}:\\s*)(.*)`,"im");c.test(t)?(t=t.replace(c,(u,p)=>`${p}${a}`),r.updated.push(o)):d.test(t)?(t=t.replace(d,(u,p)=>`${p}${a}`),r.updated.push(o)):r.failed.push(o)}r.updated.length>0&&te(i,t,n),h(r,s,r.updated.length>0?"true":"false")}catch{S("STATE.md not found")}}function as(n,e,s){(!e||s===void 0)&&S("field and value required for state update");let i=vt(e);i.valid||S(`state update: ${i.error}`);let t=R(n).state;try{let r=C.default.readFileSync(t,"utf-8"),o=Q(e),a=new RegExp(`(\\*\\*${o}:\\*\\*\\s*)(.*)`,"i"),l=new RegExp(`(^${o}:\\s*)(.*)`,"im");a.test(r)?(r=r.replace(a,(c,d)=>`${d}${s}`),te(t,r,n),h({updated:!0})):l.test(r)?(r=r.replace(l,(c,d)=>`${d}${s}`),te(t,r,n),h({updated:!0})):h({updated:!1,reason:`Field "${e}" not found in STATE.md`})}catch{h({updated:!1,reason:"STATE.md not found"})}}function ls(n,e){let s=R(n).state;if(!C.default.existsSync(s)){h({error:"STATE.md not found"},e);return}let i=C.default.readFileSync(s,"utf-8"),t=new Date().toISOString().split("T")[0],r=V(i,"Current Plan"),o=V(i,"Total Plans in Phase"),a=V(i,"Plan"),l,c,d=!1;if(r&&o)l=parseInt(r,10),c=parseInt(o,10);else if(a){l=parseInt(a,10);let u=a.match(/of\s+(\d+)/);c=u?parseInt(u[1],10):NaN,d=!0}else{h({error:"Cannot parse plan fields from STATE.md"},e);return}if(isNaN(l)||isNaN(c)){h({error:"Cannot parse Current Plan or Total Plans in Phase from STATE.md"},e);return}if(l>=c)i=he(i,"Status",null,"Phase complete - ready for verification"),i=he(i,"Last Activity","Last activity",t),i=hn(i,{status:"Phase complete - ready for verification",lastActivity:t}),te(s,i,n),h({advanced:!1,reason:"last_plan",current_plan:l,total_plans:c,status:"ready_for_verification"},e,"false");else{let u=l+1,p;d&&a?(p=a.replace(/^\d+/,String(u)),i=Se(i,"Plan",p)??i):(p=`${u} of ${c}`,i=Se(i,"Current Plan",String(u))??i),i=he(i,"Status",null,"Ready to execute"),i=he(i,"Last Activity","Last activity",t),i=hn(i,{status:"Ready to execute",lastActivity:t,plan:p}),te(s,i,n),h({advanced:!0,previous_plan:l,current_plan:u,total_plans:c},e,"true")}}function cs(n,e,s){let i=R(n).state;if(!C.default.existsSync(i)){h({error:"STATE.md not found"},s);return}let{phase:t,plan:r,duration:o,tasks:a,files:l}=e;if(!t||!r||!o){h({error:"phase, plan, and duration required"},s);return}let c=C.default.readFileSync(i,"utf-8"),d=/(##\s*Performance Metrics[\s\S]*?\n\|[^\n]+\n\|[-|\s]+\n)([\s\S]*?)(?=\n##|\n$|$)/i,u=c.match(d);if(u){let p=u[2].trimEnd(),m=`| Phase ${t} P${r} | ${o} | ${a??"-"} tasks | ${l??"-"} files |`;p=!p.trim()||p.includes("None yet")?m:p+`
158
- `+m,c=c.replace(d,(f,y)=>`${y}${p}
159
- `),te(i,c,n),h({recorded:!0,phase:t,plan:r,duration:o},s,"true")}else h({recorded:!1,reason:"Performance Metrics section not found in STATE.md"},s,"false")}function ds(n,e){let s=R(n).state;if(!C.default.existsSync(s)){h({error:"STATE.md not found"},e);return}let i=C.default.readFileSync(s,"utf-8"),t=R(n).phases,r=0,o=0;if(C.default.existsSync(t)){let f=Pe(n),y=C.default.readdirSync(t,{withFileTypes:!0}).filter(g=>g.isDirectory()).map(g=>g.name).filter(f);for(let g of y){let _=C.default.readdirSync(Me.default.join(t,g));r+=_.filter(b=>b.match(/-PLAN\.md$/i)).length,o+=_.filter(b=>b.match(/-SUMMARY\.md$/i)).length}}let a=r>0?Math.min(100,Math.round(o/r*100)):0,l=10,c=Math.round(a/100*l),u=`[${"\u2588".repeat(c)+"\u2591".repeat(l-c)}] ${a}%`,p=/(\*\*Progress:\*\*\s*).*/i,m=/^(Progress:\s*).*/im;p.test(i)?(i=i.replace(p,(f,y)=>`${y}${u}`),te(s,i,n),h({updated:!0,percent:a,completed:o,total:r,bar:u},e,u)):m.test(i)?(i=i.replace(m,(f,y)=>`${y}${u}`),te(s,i,n),h({updated:!0,percent:a,completed:o,total:r,bar:u},e,u)):h({updated:!1,reason:"Progress field not found in STATE.md"},e,"false")}function us(n,e,s){let i=R(n).state;if(!C.default.existsSync(i)){h({error:"STATE.md not found"},s);return}let{phase:t,summary:r,summary_file:o,rationale:a,rationale_file:l}=e,c=null,d="";try{c=qt(n,r??null,o??null,"summary"),d=qt(n,a??"",l??null,"rationale")}catch(y){h({added:!1,reason:y.message},s,"false");return}if(!c){h({error:"summary required"},s);return}let u=C.default.readFileSync(i,"utf-8"),p=`- [Phase ${t??"?"}]: ${c}${d?` - ${d}`:""}`,m=/(###?\s*(?:Decisions|Decisions Made|Accumulated.*Decisions)\s*\n)([\s\S]*?)(?=\n###?|\n##[^#]|$)/i,f=u.match(m);if(f){let y=f[2].replace(/None yet\.?\s*\n?/gi,"").replace(/No decisions yet\.?\s*\n?/gi,"");y=y.trimEnd()+`
160
- `+p+`
161
- `,u=u.replace(m,(g,_)=>`${_}${y}`),te(i,u,n),h({added:!0,decision:p},s,"true")}else h({added:!1,reason:"Decisions section not found in STATE.md"},s,"false")}function ms(n,e,s){let i=R(n).state;if(!C.default.existsSync(i)){h({error:"STATE.md not found"},s);return}let t=typeof e=="object"&&e!==null?e:{text:e},r=null;try{r=qt(n,t.text??null,t.text_file??null,"blocker")}catch(d){h({added:!1,reason:d.message},s,"false");return}if(!r){h({error:"text required"},s);return}let o=C.default.readFileSync(i,"utf-8"),a=`- ${r}`,l=/(###?\s*(?:Blockers|Blockers\/Concerns|Concerns)\s*\n)([\s\S]*?)(?=\n###?|\n##[^#]|$)/i,c=o.match(l);if(c){let d=c[2].replace(/None\.?\s*\n?/gi,"").replace(/None yet\.?\s*\n?/gi,"");d=d.trimEnd()+`
157
+ ([\\s\\S]*?)(?=\\n##|$)`,"i"));if(l){h({[e]:l[1].trim()},s,l[1].trim());return}h({error:`Section or field "${e}" not found`},s,"")}catch{S("STATE.md not found")}}function os(n,e,s){for(let t of Object.keys(e)){let r=vt(t);r.valid||S(`state patch: ${r.error}`)}let i=R(n).state;try{let t=C.default.readFileSync(i,"utf-8"),r={updated:[],failed:[]};for(let[o,a]of Object.entries(e)){let l=Q(o),c=new RegExp(`(\\*\\*${l}:\\*\\*\\s*)(.*)`,"i"),d=new RegExp(`(^${l}:\\s*)(.*)`,"im");c.test(t)?(t=t.replace(c,(u,f)=>`${f}${a}`),r.updated.push(o)):d.test(t)?(t=t.replace(d,(u,f)=>`${f}${a}`),r.updated.push(o)):r.failed.push(o)}r.updated.length>0&&te(i,t,n),h(r,s,r.updated.length>0?"true":"false")}catch{S("STATE.md not found")}}function as(n,e,s){(!e||s===void 0)&&S("field and value required for state update");let i=vt(e);i.valid||S(`state update: ${i.error}`);let t=R(n).state;try{let r=C.default.readFileSync(t,"utf-8"),o=Q(e),a=new RegExp(`(\\*\\*${o}:\\*\\*\\s*)(.*)`,"i"),l=new RegExp(`(^${o}:\\s*)(.*)`,"im");a.test(r)?(r=r.replace(a,(c,d)=>`${d}${s}`),te(t,r,n),h({updated:!0})):l.test(r)?(r=r.replace(l,(c,d)=>`${d}${s}`),te(t,r,n),h({updated:!0})):h({updated:!1,reason:`Field "${e}" not found in STATE.md`})}catch{h({updated:!1,reason:"STATE.md not found"})}}function ls(n,e){let s=R(n).state;if(!C.default.existsSync(s)){h({error:"STATE.md not found"},e);return}let i=C.default.readFileSync(s,"utf-8"),t=new Date().toISOString().split("T")[0],r=V(i,"Current Plan"),o=V(i,"Total Plans in Phase"),a=V(i,"Plan"),l,c,d=!1;if(r&&o)l=parseInt(r,10),c=parseInt(o,10);else if(a){l=parseInt(a,10);let u=a.match(/of\s+(\d+)/);c=u?parseInt(u[1],10):NaN,d=!0}else{h({error:"Cannot parse plan fields from STATE.md"},e);return}if(isNaN(l)||isNaN(c)){h({error:"Cannot parse Current Plan or Total Plans in Phase from STATE.md"},e);return}if(l>=c)i=he(i,"Status",null,"Phase complete - ready for verification"),i=he(i,"Last Activity","Last activity",t),i=hn(i,{status:"Phase complete - ready for verification",lastActivity:t}),te(s,i,n),h({advanced:!1,reason:"last_plan",current_plan:l,total_plans:c,status:"ready_for_verification"},e,"false");else{let u=l+1,f;d&&a?(f=a.replace(/^\d+/,String(u)),i=Se(i,"Plan",f)??i):(f=`${u} of ${c}`,i=Se(i,"Current Plan",String(u))??i),i=he(i,"Status",null,"Ready to execute"),i=he(i,"Last Activity","Last activity",t),i=hn(i,{status:"Ready to execute",lastActivity:t,plan:f}),te(s,i,n),h({advanced:!0,previous_plan:l,current_plan:u,total_plans:c},e,"true")}}function cs(n,e,s){let i=R(n).state;if(!C.default.existsSync(i)){h({error:"STATE.md not found"},s);return}let{phase:t,plan:r,duration:o,tasks:a,files:l}=e;if(!t||!r||!o){h({error:"phase, plan, and duration required"},s);return}let c=C.default.readFileSync(i,"utf-8"),d=/(##\s*Performance Metrics[\s\S]*?\n\|[^\n]+\n\|[-|\s]+\n)([\s\S]*?)(?=\n##|\n$|$)/i,u=c.match(d);if(u){let f=u[2].trimEnd(),m=`| Phase ${t} P${r} | ${o} | ${a??"-"} tasks | ${l??"-"} files |`;f=!f.trim()||f.includes("None yet")?m:f+`
158
+ `+m,c=c.replace(d,(p,y)=>`${y}${f}
159
+ `),te(i,c,n),h({recorded:!0,phase:t,plan:r,duration:o},s,"true")}else h({recorded:!1,reason:"Performance Metrics section not found in STATE.md"},s,"false")}function ds(n,e){let s=R(n).state;if(!C.default.existsSync(s)){h({error:"STATE.md not found"},e);return}let i=C.default.readFileSync(s,"utf-8"),t=R(n).phases,r=0,o=0;if(C.default.existsSync(t)){let p=Pe(n),y=C.default.readdirSync(t,{withFileTypes:!0}).filter(g=>g.isDirectory()).map(g=>g.name).filter(p);for(let g of y){let _=C.default.readdirSync(Me.default.join(t,g));r+=_.filter(b=>b.match(/-PLAN\.md$/i)).length,o+=_.filter(b=>b.match(/-SUMMARY\.md$/i)).length}}let a=r>0?Math.min(100,Math.round(o/r*100)):0,l=10,c=Math.round(a/100*l),u=`[${"\u2588".repeat(c)+"\u2591".repeat(l-c)}] ${a}%`,f=/(\*\*Progress:\*\*\s*).*/i,m=/^(Progress:\s*).*/im;f.test(i)?(i=i.replace(f,(p,y)=>`${y}${u}`),te(s,i,n),h({updated:!0,percent:a,completed:o,total:r,bar:u},e,u)):m.test(i)?(i=i.replace(m,(p,y)=>`${y}${u}`),te(s,i,n),h({updated:!0,percent:a,completed:o,total:r,bar:u},e,u)):h({updated:!1,reason:"Progress field not found in STATE.md"},e,"false")}function us(n,e,s){let i=R(n).state;if(!C.default.existsSync(i)){h({error:"STATE.md not found"},s);return}let{phase:t,summary:r,summary_file:o,rationale:a,rationale_file:l}=e,c=null,d="";try{c=qt(n,r??null,o??null,"summary"),d=qt(n,a??"",l??null,"rationale")}catch(y){h({added:!1,reason:y.message},s,"false");return}if(!c){h({error:"summary required"},s);return}let u=C.default.readFileSync(i,"utf-8"),f=`- [Phase ${t??"?"}]: ${c}${d?` - ${d}`:""}`,m=/(###?\s*(?:Decisions|Decisions Made|Accumulated.*Decisions)\s*\n)([\s\S]*?)(?=\n###?|\n##[^#]|$)/i,p=u.match(m);if(p){let y=p[2].replace(/None yet\.?\s*\n?/gi,"").replace(/No decisions yet\.?\s*\n?/gi,"");y=y.trimEnd()+`
160
+ `+f+`
161
+ `,u=u.replace(m,(g,_)=>`${_}${y}`),te(i,u,n),h({added:!0,decision:f},s,"true")}else h({added:!1,reason:"Decisions section not found in STATE.md"},s,"false")}function ms(n,e,s){let i=R(n).state;if(!C.default.existsSync(i)){h({error:"STATE.md not found"},s);return}let t=typeof e=="object"&&e!==null?e:{text:e},r=null;try{r=qt(n,t.text??null,t.text_file??null,"blocker")}catch(d){h({added:!1,reason:d.message},s,"false");return}if(!r){h({error:"text required"},s);return}let o=C.default.readFileSync(i,"utf-8"),a=`- ${r}`,l=/(###?\s*(?:Blockers|Blockers\/Concerns|Concerns)\s*\n)([\s\S]*?)(?=\n###?|\n##[^#]|$)/i,c=o.match(l);if(c){let d=c[2].replace(/None\.?\s*\n?/gi,"").replace(/None yet\.?\s*\n?/gi,"");d=d.trimEnd()+`
162
162
  `+a+`
163
- `,o=o.replace(l,(u,p)=>`${p}${d}`),te(i,o,n),h({added:!0,blocker:r},s,"true")}else h({added:!1,reason:"Blockers section not found in STATE.md"},s,"false")}function ps(n,e,s){let i=R(n).state;if(!C.default.existsSync(i)){h({error:"STATE.md not found"},s);return}if(!e){h({error:"text required"},s);return}let t=C.default.readFileSync(i,"utf-8"),r=/(###?\s*(?:Blockers|Blockers\/Concerns|Concerns)\s*\n)([\s\S]*?)(?=\n###?|\n##[^#]|$)/i,o=t.match(r);if(o){let c=o[2].split(`
163
+ `,o=o.replace(l,(u,f)=>`${f}${d}`),te(i,o,n),h({added:!0,blocker:r},s,"true")}else h({added:!1,reason:"Blockers section not found in STATE.md"},s,"false")}function fs(n,e,s){let i=R(n).state;if(!C.default.existsSync(i)){h({error:"STATE.md not found"},s);return}if(!e){h({error:"text required"},s);return}let t=C.default.readFileSync(i,"utf-8"),r=/(###?\s*(?:Blockers|Blockers\/Concerns|Concerns)\s*\n)([\s\S]*?)(?=\n###?|\n##[^#]|$)/i,o=t.match(r);if(o){let c=o[2].split(`
164
164
  `).filter(d=>!d.startsWith("- ")||!d.toLowerCase().includes(e.toLowerCase())).join(`
165
165
  `);(!c.trim()||!c.includes("- "))&&(c=`None
166
- `),t=t.replace(r,(d,u)=>`${u}${c}`),te(i,t,n),h({resolved:!0,blocker:e},s,"true")}else h({resolved:!1,reason:"Blockers section not found in STATE.md"},s,"false")}function fs(n,e,s){let i=R(n).state;if(!C.default.existsSync(i)){h({error:"STATE.md not found"},s);return}let t=C.default.readFileSync(i,"utf-8"),r=new Date().toISOString(),o=[],a=d=>{let u=Se(t,d,r);u&&(t=u,o.push(d))};if(a("Last session"),a("Last Date"),e.stopped_at){let d=Se(t,"Stopped At",e.stopped_at)??Se(t,"Stopped at",e.stopped_at);d&&(t=d,o.push("Stopped At"))}let l=e.resume_file??"None",c=Se(t,"Resume File",l)??Se(t,"Resume file",l);c&&(t=c,o.push("Resume File")),o.length>0?(te(i,t,n),h({recorded:!0,updated:o},s,"true")):h({recorded:!1,reason:"No session fields found in STATE.md"},s,"false")}function hs(n,e){let s=ns(n);if(!C.default.existsSync(s)){h({error:"STATE.md not found"},e);return}let i=C.default.readFileSync(s,"utf-8"),t=u=>V(i,u),r=[],o=i.match(/##\s*Decisions Made[\s\S]*?\n\|[^\n]+\n\|[-|\s]+\n([\s\S]*?)(?=\n##|\n$|$)/i);if(o)for(let u of o[1].trim().split(`
167
- `).filter(p=>p.includes("|"))){let p=u.split("|").map(m=>m.trim()).filter(Boolean);p.length>=3&&r.push({phase:p[0],summary:p[1],rationale:p[2]})}let a=[],l=i.match(/##\s*Blockers\s*\n([\s\S]*?)(?=\n##|$)/i);if(l)for(let u of l[1].match(/^-\s+(.+)$/gm)??[])a.push(u.replace(/^-\s+/,"").trim());let c={last_date:null,stopped_at:null,resume_file:null},d=i.match(/##\s*Session\s*\n([\s\S]*?)(?=\n##|$)/i);if(d){let u=d[1];c.last_date=(u.match(/\*\*Last Date:\*\*\s*(.+)/i)??u.match(/^Last Date:\s*(.+)/im))?.[1]?.trim()??null,c.stopped_at=(u.match(/\*\*Stopped At:\*\*\s*(.+)/i)??u.match(/^Stopped At:\s*(.+)/im))?.[1]?.trim()??null,c.resume_file=(u.match(/\*\*Resume File:\*\*\s*(.+)/i)??u.match(/^Resume File:\s*(.+)/im))?.[1]?.trim()??null}h({current_phase:t("Current Phase"),current_phase_name:t("Current Phase Name"),total_phases:t("Total Phases")?parseInt(t("Total Phases"),10):null,current_plan:t("Current Plan"),total_plans_in_phase:t("Total Plans in Phase")?parseInt(t("Total Plans in Phase"),10):null,status:t("Status"),progress_percent:t("Progress")?parseInt(t("Progress").replace("%",""),10):null,last_activity:t("Last Activity"),last_activity_desc:t("Last Activity Description"),decisions:r,blockers:a,paused_at:t("Paused At"),session:c},e)}function gs(n,e){let s=R(n).state;if(!C.default.existsSync(s)){h({error:"STATE.md not found"},e,"STATE.md not found");return}let i=C.default.readFileSync(s,"utf-8"),t=ee(i);if(!t||Object.keys(t).length===0){let r=Lt(i),o=gn(r,n);h(o,e,JSON.stringify(o,null,2));return}h(t,e,JSON.stringify(t,null,2))}function ys(n,e,s,i,t){let r=R(n).state;if(!C.default.existsSync(r)){h({error:"STATE.md not found"},t);return}let o=C.default.readFileSync(r,"utf-8"),a=new Date().toISOString().split("T")[0],l=[],c=(f,y)=>{let g=Se(o,f,y);g&&(o=g,l.push(f))};c("Status",`Executing Phase ${e}`),c("Last Activity",a),c("Last Activity Description",`Phase ${e} execution started`),c("Current Phase",String(e)),s&&c("Current Phase Name",s),c("Current Plan","1"),i&&c("Total Plans in Phase",String(i));let d=s?`Phase ${e} - ${s}`:`Phase ${e}`,u=/(\*\*Current focus:\*\*\s*).*/i;u.test(o)&&(o=o.replace(u,(f,y)=>`${y}${d}`),l.push("Current focus"));let p=/(##\s*Current Position\s*\n)([\s\S]*?)(?=\n##|$)/i,m=o.match(p);if(m){let f=m[1],y=m[2],g=`Phase: ${e}${s?` (${s})`:""} - EXECUTING`;y=/^Phase:/m.test(y)?y.replace(/^Phase:.*$/m,g):g+`
166
+ `),t=t.replace(r,(d,u)=>`${u}${c}`),te(i,t,n),h({resolved:!0,blocker:e},s,"true")}else h({resolved:!1,reason:"Blockers section not found in STATE.md"},s,"false")}function ps(n,e,s){let i=R(n).state;if(!C.default.existsSync(i)){h({error:"STATE.md not found"},s);return}let t=C.default.readFileSync(i,"utf-8"),r=new Date().toISOString(),o=[],a=d=>{let u=Se(t,d,r);u&&(t=u,o.push(d))};if(a("Last session"),a("Last Date"),e.stopped_at){let d=Se(t,"Stopped At",e.stopped_at)??Se(t,"Stopped at",e.stopped_at);d&&(t=d,o.push("Stopped At"))}let l=e.resume_file??"None",c=Se(t,"Resume File",l)??Se(t,"Resume file",l);c&&(t=c,o.push("Resume File")),o.length>0?(te(i,t,n),h({recorded:!0,updated:o},s,"true")):h({recorded:!1,reason:"No session fields found in STATE.md"},s,"false")}function hs(n,e){let s=ns(n);if(!C.default.existsSync(s)){h({error:"STATE.md not found"},e);return}let i=C.default.readFileSync(s,"utf-8"),t=u=>V(i,u),r=[],o=i.match(/##\s*Decisions Made[\s\S]*?\n\|[^\n]+\n\|[-|\s]+\n([\s\S]*?)(?=\n##|\n$|$)/i);if(o)for(let u of o[1].trim().split(`
167
+ `).filter(f=>f.includes("|"))){let f=u.split("|").map(m=>m.trim()).filter(Boolean);f.length>=3&&r.push({phase:f[0],summary:f[1],rationale:f[2]})}let a=[],l=i.match(/##\s*Blockers\s*\n([\s\S]*?)(?=\n##|$)/i);if(l)for(let u of l[1].match(/^-\s+(.+)$/gm)??[])a.push(u.replace(/^-\s+/,"").trim());let c={last_date:null,stopped_at:null,resume_file:null},d=i.match(/##\s*Session\s*\n([\s\S]*?)(?=\n##|$)/i);if(d){let u=d[1];c.last_date=(u.match(/\*\*Last Date:\*\*\s*(.+)/i)??u.match(/^Last Date:\s*(.+)/im))?.[1]?.trim()??null,c.stopped_at=(u.match(/\*\*Stopped At:\*\*\s*(.+)/i)??u.match(/^Stopped At:\s*(.+)/im))?.[1]?.trim()??null,c.resume_file=(u.match(/\*\*Resume File:\*\*\s*(.+)/i)??u.match(/^Resume File:\s*(.+)/im))?.[1]?.trim()??null}h({current_phase:t("Current Phase"),current_phase_name:t("Current Phase Name"),total_phases:t("Total Phases")?parseInt(t("Total Phases"),10):null,current_plan:t("Current Plan"),total_plans_in_phase:t("Total Plans in Phase")?parseInt(t("Total Plans in Phase"),10):null,status:t("Status"),progress_percent:t("Progress")?parseInt(t("Progress").replace("%",""),10):null,last_activity:t("Last Activity"),last_activity_desc:t("Last Activity Description"),decisions:r,blockers:a,paused_at:t("Paused At"),session:c},e)}function gs(n,e){let s=R(n).state;if(!C.default.existsSync(s)){h({error:"STATE.md not found"},e,"STATE.md not found");return}let i=C.default.readFileSync(s,"utf-8"),t=ee(i);if(!t||Object.keys(t).length===0){let r=Lt(i),o=gn(r,n);h(o,e,JSON.stringify(o,null,2));return}h(t,e,JSON.stringify(t,null,2))}function ys(n,e,s,i,t){let r=R(n).state;if(!C.default.existsSync(r)){h({error:"STATE.md not found"},t);return}let o=C.default.readFileSync(r,"utf-8"),a=new Date().toISOString().split("T")[0],l=[],c=(p,y)=>{let g=Se(o,p,y);g&&(o=g,l.push(p))};c("Status",`Executing Phase ${e}`),c("Last Activity",a),c("Last Activity Description",`Phase ${e} execution started`),c("Current Phase",String(e)),s&&c("Current Phase Name",s),c("Current Plan","1"),i&&c("Total Plans in Phase",String(i));let d=s?`Phase ${e} - ${s}`:`Phase ${e}`,u=/(\*\*Current focus:\*\*\s*).*/i;u.test(o)&&(o=o.replace(u,(p,y)=>`${y}${d}`),l.push("Current focus"));let f=/(##\s*Current Position\s*\n)([\s\S]*?)(?=\n##|$)/i,m=o.match(f);if(m){let p=m[1],y=m[2],g=`Phase: ${e}${s?` (${s})`:""} - EXECUTING`;y=/^Phase:/m.test(y)?y.replace(/^Phase:.*$/m,g):g+`
168
168
  `+y;let _=`Plan: 1 of ${i??"?"}`;y=/^Plan:/m.test(y)?y.replace(/^Plan:.*$/m,_):y.replace(/^(Phase:.*$)/m,`$1
169
- ${_}`),/^Status:/m.test(y)&&(y=y.replace(/^Status:.*$/m,`Status: Executing Phase ${e}`)),/^Last activity:/im.test(y)&&(y=y.replace(/^Last activity:.*$/im,`Last activity: ${a} -- Phase ${e} execution started`)),o=o.replace(p,`${f}${y}`),l.push("Current Position")}l.length>0&&te(r,o,n),h({updated:l,phase:e,phase_name:s??null,plan_count:i??null},t,l.length>0?"true":"false")}function Ss(n,e,s,i,t,r){let o=C.default.existsSync(Me.default.join(n,".gsd"))?Me.default.join(n,".gsd"):F(n),a=Me.default.join(o,"WAITING.json"),l={status:"waiting",type:e??"decision_point",question:s??null,options:i?i.split("|").map(c=>c.trim()):[],since:new Date().toISOString(),phase:t??null};try{C.default.mkdirSync(o,{recursive:!0}),C.default.writeFileSync(a,JSON.stringify(l,null,2),"utf-8"),h({signaled:!0,path:a},r,"true")}catch(c){h({signaled:!1,error:c.message},r,"false")}}function _s(n,e){let s=[Me.default.join(n,".gsd","WAITING.json"),Me.default.join(F(n),"WAITING.json")],i=!1;for(let t of s)if(C.default.existsSync(t))try{C.default.unlinkSync(t),i=!0}catch{}h({resumed:!0,removed:i},e,i?"true":"false")}var C,Me,Be=le(()=>{"use strict";C=W(require("fs")),Me=W(require("path"));fe();Ue();ct()});var ge={};pe(ge,{cmdCommit:()=>As,cmdCommitToSubrepo:()=>js,cmdCurrentTimestamp:()=>xs,cmdGenerateSlug:()=>bs,cmdHistoryDigest:()=>Ps,cmdListTodos:()=>vs,cmdProgressRender:()=>Is,cmdResolveModel:()=>$s,cmdScaffold:()=>Ms,cmdStats:()=>Fs,cmdSummaryExtract:()=>Rs,cmdTodoComplete:()=>Es,cmdTodoMatchPhase:()=>ws,cmdVerifyPathExists:()=>ks,cmdWebsearch:()=>Cs});function bs(n,e){n||S("text required for slug generation");let s=n.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");h({slug:s},e,s)}function xs(n,e){let s=new Date,i;n==="date"?i=s.toISOString().split("T")[0]:n==="filename"?i=s.toISOString().replace(/:/g,"-").replace(/\..+/,""):i=s.toISOString(),h({timestamp:i},e,i)}function vs(n,e,s){let i=H.default.join(F(n),"todos","pending"),t=0,r=[];try{let o=q.default.readdirSync(i).filter(a=>a.endsWith(".md"));for(let a of o)try{let l=q.default.readFileSync(H.default.join(i,a),"utf-8"),c=l.match(/^created:\s*(.+)$/m),d=l.match(/^title:\s*(.+)$/m),u=l.match(/^area:\s*(.+)$/m),p=u?u[1].trim():"general";if(e&&p!==e)continue;t++,r.push({file:a,created:c?c[1].trim():"unknown",title:d?d[1].trim():"Untitled",area:p,path:z(H.default.relative(n,H.default.join(i,a)))})}catch{}}catch{}h({count:t,todos:r},s,t.toString())}function ks(n,e,s){e||S("path required for verification"),e.includes("\0")&&S("path contains null bytes");let i=H.default.isAbsolute(e)?e:H.default.join(n,e);try{let t=q.default.statSync(i);h({exists:!0,type:t.isDirectory()?"directory":t.isFile()?"file":"other"},s,"true")}catch{h({exists:!1,type:null},s,"false")}}function Ps(n,e){let s=R(n).phases,i={phases:{},decisions:[],tech_stack:new Set},t=[];for(let r of gt(n))t.push({name:r.name,fullPath:r.fullPath,milestone:r.milestone});if(q.default.existsSync(s))try{for(let r of q.default.readdirSync(s,{withFileTypes:!0}).filter(o=>o.isDirectory()).map(o=>o.name).sort())t.push({name:r,fullPath:H.default.join(s,r),milestone:null})}catch{}if(t.length===0){h({phases:{},decisions:[],tech_stack:[]},e);return}try{for(let{name:o,fullPath:a}of t){let l=q.default.readdirSync(a).filter(c=>c.endsWith("-SUMMARY.md")||c==="SUMMARY.md");for(let c of l)try{let d=q.default.readFileSync(H.default.join(a,c),"utf-8"),u=ee(d),p=u.phase||o.split("-")[0];i.phases[p]||(i.phases[p]={name:u.name||o.split("-").slice(1).join(" ")||"Unknown",provides:new Set,affects:new Set,patterns:new Set}),u["dependency-graph"]?.provides?u["dependency-graph"].provides.forEach(m=>i.phases[p].provides.add(m)):u.provides&&u.provides.forEach(m=>i.phases[p].provides.add(m)),u["dependency-graph"]?.affects&&u["dependency-graph"].affects.forEach(m=>i.phases[p].affects.add(m)),u["patterns-established"]&&u["patterns-established"].forEach(m=>i.phases[p].patterns.add(m)),u["key-decisions"]&&u["key-decisions"].forEach(m=>i.decisions.push({phase:p,decision:m})),u["tech-stack"]?.added&&u["tech-stack"].added.forEach(m=>i.tech_stack.add(typeof m=="string"?m:m.name))}catch{}}let r={phases:Object.fromEntries(Object.entries(i.phases).map(([o,a])=>[o,{name:a.name,provides:[...a.provides],affects:[...a.affects],patterns:[...a.patterns]}])),decisions:i.decisions,tech_stack:[...i.tech_stack]};h(r,e)}catch(r){S("Failed to generate history digest: "+r.message)}}function $s(n,e,s){e||S("agent-type required");let i=B(n),t=X(n,e),r=je[e];h(r?{model:t,profile:i.model_profile}:{model:t,profile:i.model_profile,unknown_agent:!0},s,t)}function As(n,e,s,i,t=!1,r=!1){!e&&!t&&S("commit message required");let o=e;o&&(o=Nt(o));let a=B(n);if(!a.commit_docs){h({committed:!1,hash:null,reason:"skipped_commit_docs_false"},i,"skipped");return}if(Dt(n,".planning")){h({committed:!1,hash:null,reason:"skipped_gitignored"},i,"skipped");return}if(a.branching_strategy&&a.branching_strategy!=="none"){let m=null;if(a.branching_strategy==="phase"){let f=(s||[]).join(" ").match(/(\d+)-/);if(f){let y=ue(n,f[1]);y&&(m=a.phase_branch_template.replace("{phase}",y.phase_number).replace("{slug}",y.phase_slug||"phase"))}}else if(a.branching_strategy==="milestone"){let f=ie(n);f?.version&&(m=a.milestone_branch_template.replace("{milestone}",f.version).replace("{slug}",Te(f.name)||"milestone"))}if(m){let f=oe(n,["rev-parse","--abbrev-ref","HEAD"]);f.exitCode===0&&f.stdout.trim()!==m&&oe(n,["checkout","-b",m]).exitCode!==0&&oe(n,["checkout",m])}}let l=s&&s.length>0?s:[".planning/"];for(let m of l){let f=H.default.join(n,m);q.default.existsSync(f)?oe(n,["add",m]):oe(n,["rm","--cached","--ignore-unmatch",m])}let c=t?["commit","--amend","--no-edit"]:["commit","-m",o];r&&c.push("--no-verify");let d=oe(n,c);if(d.exitCode!==0){if(d.stdout.includes("nothing to commit")||d.stderr.includes("nothing to commit")){h({committed:!1,hash:null,reason:"nothing_to_commit"},i,"nothing");return}h({committed:!1,hash:null,reason:"nothing_to_commit",error:d.stderr},i,"nothing");return}let u=oe(n,["rev-parse","--short","HEAD"]),p=u.exitCode===0?u.stdout:null;h({committed:!0,hash:p,reason:"committed"},i,p||"committed")}function js(n,e,s,i){e||S("commit message required");let r=B(n).sub_repos;(!r||r.length===0)&&S("no sub_repos configured in .planning/config.json"),(!s||s.length===0)&&S("--files required for commit-to-subrepo");let o={},a=[];for(let c of s){let d=r.find(u=>c.startsWith(u+"/"));d?(o[d]||(o[d]=[]),o[d].push(c)):a.push(c)}a.length>0&&process.stderr.write(`Warning: ${a.length} file(s) did not match any sub-repo prefix: ${a.join(", ")}
170
- `);let l={};for(let[c,d]of Object.entries(o)){let u=H.default.join(n,c);for(let f of d)oe(u,["add",f.slice(c.length+1)]);let p=oe(u,["commit","-m",e]);if(p.exitCode!==0){l[c]={committed:!1,hash:null,files:d,reason:p.stdout.includes("nothing to commit")?"nothing_to_commit":"error",error:p.stderr};continue}let m=oe(u,["rev-parse","--short","HEAD"]);l[c]={committed:!0,hash:m.exitCode===0?m.stdout:null,files:d}}h({committed:Object.values(l).some(c=>c.committed),repos:l,unmatched:a.length>0?a:void 0},i,Object.entries(l).map(([c,d])=>`${c}:${d.hash||"skip"}`).join(" "))}function Rs(n,e,s,i){e||S("summary-path required for summary-extract");let t=H.default.join(n,e);if(!q.default.existsSync(t)){h({error:"File not found",path:e},i);return}let r=q.default.readFileSync(t,"utf-8"),o=ee(r),a=c=>(c||[]).map(d=>{let u=d.indexOf(":");return u>0?{summary:d.substring(0,u).trim(),rationale:d.substring(u+1).trim()}:{summary:d,rationale:null}}),l={path:e,one_liner:o["one-liner"]||yt(r)||null,key_files:o["key-files"]||[],tech_added:o["tech-stack"]?.added||[],patterns:o["patterns-established"]||[],decisions:a(o["key-decisions"]),requirements_completed:o["requirements-completed"]||[]};if(s&&s.length>0){let c={path:e};for(let d of s)l[d]!==void 0&&(c[d]=l[d]);h(c,i);return}h(l,i)}async function Cs(n,e,s){let i=process.env.BRAVE_API_KEY;if(!i){h({available:!1,reason:"BRAVE_API_KEY not set"},s,"");return}if(!n){h({available:!1,error:"Query required"},s,"");return}let t=new URLSearchParams({q:n,count:String(e.limit||10),country:"us",search_lang:"en",text_decorations:"false"});e.freshness&&t.set("freshness",e.freshness);try{let r=await fetch(`https://api.search.brave.com/res/v1/web/search?${t}`,{headers:{Accept:"application/json","X-Subscription-Token":i}});if(!r.ok){h({available:!1,error:`API error: ${r.status}`},s,"");return}let a=((await r.json()).web?.results||[]).map(l=>({title:l.title,url:l.url,description:l.description,age:l.age||null}));h({available:!0,query:n,count:a.length,results:a},s,a.map(l=>`${l.title}
169
+ ${_}`),/^Status:/m.test(y)&&(y=y.replace(/^Status:.*$/m,`Status: Executing Phase ${e}`)),/^Last activity:/im.test(y)&&(y=y.replace(/^Last activity:.*$/im,`Last activity: ${a} -- Phase ${e} execution started`)),o=o.replace(f,`${p}${y}`),l.push("Current Position")}l.length>0&&te(r,o,n),h({updated:l,phase:e,phase_name:s??null,plan_count:i??null},t,l.length>0?"true":"false")}function Ss(n,e,s,i,t,r){let o=C.default.existsSync(Me.default.join(n,".gsd"))?Me.default.join(n,".gsd"):F(n),a=Me.default.join(o,"WAITING.json"),l={status:"waiting",type:e??"decision_point",question:s??null,options:i?i.split("|").map(c=>c.trim()):[],since:new Date().toISOString(),phase:t??null};try{C.default.mkdirSync(o,{recursive:!0}),C.default.writeFileSync(a,JSON.stringify(l,null,2),"utf-8"),h({signaled:!0,path:a},r,"true")}catch(c){h({signaled:!1,error:c.message},r,"false")}}function _s(n,e){let s=[Me.default.join(n,".gsd","WAITING.json"),Me.default.join(F(n),"WAITING.json")],i=!1;for(let t of s)if(C.default.existsSync(t))try{C.default.unlinkSync(t),i=!0}catch{}h({resumed:!0,removed:i},e,i?"true":"false")}var C,Me,Be=le(()=>{"use strict";C=W(require("fs")),Me=W(require("path"));pe();Ue();ct()});var ge={};fe(ge,{cmdCommit:()=>As,cmdCommitToSubrepo:()=>js,cmdCurrentTimestamp:()=>xs,cmdGenerateSlug:()=>bs,cmdHistoryDigest:()=>Ps,cmdListTodos:()=>vs,cmdProgressRender:()=>Is,cmdResolveModel:()=>$s,cmdScaffold:()=>Ms,cmdStats:()=>Fs,cmdSummaryExtract:()=>Rs,cmdTodoComplete:()=>Es,cmdTodoMatchPhase:()=>ws,cmdVerifyPathExists:()=>ks,cmdWebsearch:()=>Cs});function bs(n,e){n||S("text required for slug generation");let s=n.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");h({slug:s},e,s)}function xs(n,e){let s=new Date,i;n==="date"?i=s.toISOString().split("T")[0]:n==="filename"?i=s.toISOString().replace(/:/g,"-").replace(/\..+/,""):i=s.toISOString(),h({timestamp:i},e,i)}function vs(n,e,s){let i=H.default.join(F(n),"todos","pending"),t=0,r=[];try{let o=q.default.readdirSync(i).filter(a=>a.endsWith(".md"));for(let a of o)try{let l=q.default.readFileSync(H.default.join(i,a),"utf-8"),c=l.match(/^created:\s*(.+)$/m),d=l.match(/^title:\s*(.+)$/m),u=l.match(/^area:\s*(.+)$/m),f=u?u[1].trim():"general";if(e&&f!==e)continue;t++,r.push({file:a,created:c?c[1].trim():"unknown",title:d?d[1].trim():"Untitled",area:f,path:z(H.default.relative(n,H.default.join(i,a)))})}catch{}}catch{}h({count:t,todos:r},s,t.toString())}function ks(n,e,s){e||S("path required for verification"),e.includes("\0")&&S("path contains null bytes");let i=H.default.isAbsolute(e)?e:H.default.join(n,e);try{let t=q.default.statSync(i);h({exists:!0,type:t.isDirectory()?"directory":t.isFile()?"file":"other"},s,"true")}catch{h({exists:!1,type:null},s,"false")}}function Ps(n,e){let s=R(n).phases,i={phases:{},decisions:[],tech_stack:new Set},t=[];for(let r of gt(n))t.push({name:r.name,fullPath:r.fullPath,milestone:r.milestone});if(q.default.existsSync(s))try{for(let r of q.default.readdirSync(s,{withFileTypes:!0}).filter(o=>o.isDirectory()).map(o=>o.name).sort())t.push({name:r,fullPath:H.default.join(s,r),milestone:null})}catch{}if(t.length===0){h({phases:{},decisions:[],tech_stack:[]},e);return}try{for(let{name:o,fullPath:a}of t){let l=q.default.readdirSync(a).filter(c=>c.endsWith("-SUMMARY.md")||c==="SUMMARY.md");for(let c of l)try{let d=q.default.readFileSync(H.default.join(a,c),"utf-8"),u=ee(d),f=u.phase||o.split("-")[0];i.phases[f]||(i.phases[f]={name:u.name||o.split("-").slice(1).join(" ")||"Unknown",provides:new Set,affects:new Set,patterns:new Set}),u["dependency-graph"]?.provides?u["dependency-graph"].provides.forEach(m=>i.phases[f].provides.add(m)):u.provides&&u.provides.forEach(m=>i.phases[f].provides.add(m)),u["dependency-graph"]?.affects&&u["dependency-graph"].affects.forEach(m=>i.phases[f].affects.add(m)),u["patterns-established"]&&u["patterns-established"].forEach(m=>i.phases[f].patterns.add(m)),u["key-decisions"]&&u["key-decisions"].forEach(m=>i.decisions.push({phase:f,decision:m})),u["tech-stack"]?.added&&u["tech-stack"].added.forEach(m=>i.tech_stack.add(typeof m=="string"?m:m.name))}catch{}}let r={phases:Object.fromEntries(Object.entries(i.phases).map(([o,a])=>[o,{name:a.name,provides:[...a.provides],affects:[...a.affects],patterns:[...a.patterns]}])),decisions:i.decisions,tech_stack:[...i.tech_stack]};h(r,e)}catch(r){S("Failed to generate history digest: "+r.message)}}function $s(n,e,s){e||S("agent-type required");let i=B(n),t=X(n,e),r=je[e];h(r?{model:t,profile:i.model_profile}:{model:t,profile:i.model_profile,unknown_agent:!0},s,t)}function As(n,e,s,i,t=!1,r=!1){!e&&!t&&S("commit message required");let o=e;o&&(o=Nt(o));let a=B(n);if(!a.commit_docs){h({committed:!1,hash:null,reason:"skipped_commit_docs_false"},i,"skipped");return}if(Tt(n,".planning")){h({committed:!1,hash:null,reason:"skipped_gitignored"},i,"skipped");return}if(a.branching_strategy&&a.branching_strategy!=="none"){let m=null;if(a.branching_strategy==="phase"){let p=(s||[]).join(" ").match(/(\d+)-/);if(p){let y=ue(n,p[1]);y&&(m=a.phase_branch_template.replace("{phase}",y.phase_number).replace("{slug}",y.phase_slug||"phase"))}}else if(a.branching_strategy==="milestone"){let p=ie(n);p?.version&&(m=a.milestone_branch_template.replace("{milestone}",p.version).replace("{slug}",De(p.name)||"milestone"))}if(m){let p=oe(n,["rev-parse","--abbrev-ref","HEAD"]);p.exitCode===0&&p.stdout.trim()!==m&&oe(n,["checkout","-b",m]).exitCode!==0&&oe(n,["checkout",m])}}let l=s&&s.length>0?s:[".planning/"];for(let m of l){let p=H.default.join(n,m);q.default.existsSync(p)?oe(n,["add",m]):oe(n,["rm","--cached","--ignore-unmatch",m])}let c=t?["commit","--amend","--no-edit"]:["commit","-m",o];r&&c.push("--no-verify");let d=oe(n,c);if(d.exitCode!==0){if(d.stdout.includes("nothing to commit")||d.stderr.includes("nothing to commit")){h({committed:!1,hash:null,reason:"nothing_to_commit"},i,"nothing");return}h({committed:!1,hash:null,reason:"nothing_to_commit",error:d.stderr},i,"nothing");return}let u=oe(n,["rev-parse","--short","HEAD"]),f=u.exitCode===0?u.stdout:null;h({committed:!0,hash:f,reason:"committed"},i,f||"committed")}function js(n,e,s,i){e||S("commit message required");let r=B(n).sub_repos;(!r||r.length===0)&&S("no sub_repos configured in .planning/config.json"),(!s||s.length===0)&&S("--files required for commit-to-subrepo");let o={},a=[];for(let c of s){let d=r.find(u=>c.startsWith(u+"/"));d?(o[d]||(o[d]=[]),o[d].push(c)):a.push(c)}a.length>0&&process.stderr.write(`Warning: ${a.length} file(s) did not match any sub-repo prefix: ${a.join(", ")}
170
+ `);let l={};for(let[c,d]of Object.entries(o)){let u=H.default.join(n,c);for(let p of d)oe(u,["add",p.slice(c.length+1)]);let f=oe(u,["commit","-m",e]);if(f.exitCode!==0){l[c]={committed:!1,hash:null,files:d,reason:f.stdout.includes("nothing to commit")?"nothing_to_commit":"error",error:f.stderr};continue}let m=oe(u,["rev-parse","--short","HEAD"]);l[c]={committed:!0,hash:m.exitCode===0?m.stdout:null,files:d}}h({committed:Object.values(l).some(c=>c.committed),repos:l,unmatched:a.length>0?a:void 0},i,Object.entries(l).map(([c,d])=>`${c}:${d.hash||"skip"}`).join(" "))}function Rs(n,e,s,i){e||S("summary-path required for summary-extract");let t=H.default.join(n,e);if(!q.default.existsSync(t)){h({error:"File not found",path:e},i);return}let r=q.default.readFileSync(t,"utf-8"),o=ee(r),a=c=>(c||[]).map(d=>{let u=d.indexOf(":");return u>0?{summary:d.substring(0,u).trim(),rationale:d.substring(u+1).trim()}:{summary:d,rationale:null}}),l={path:e,one_liner:o["one-liner"]||yt(r)||null,key_files:o["key-files"]||[],tech_added:o["tech-stack"]?.added||[],patterns:o["patterns-established"]||[],decisions:a(o["key-decisions"]),requirements_completed:o["requirements-completed"]||[]};if(s&&s.length>0){let c={path:e};for(let d of s)l[d]!==void 0&&(c[d]=l[d]);h(c,i);return}h(l,i)}async function Cs(n,e,s){let i=process.env.BRAVE_API_KEY;if(!i){h({available:!1,reason:"BRAVE_API_KEY not set"},s,"");return}if(!n){h({available:!1,error:"Query required"},s,"");return}let t=new URLSearchParams({q:n,count:String(e.limit||10),country:"us",search_lang:"en",text_decorations:"false"});e.freshness&&t.set("freshness",e.freshness);try{let r=await fetch(`https://api.search.brave.com/res/v1/web/search?${t}`,{headers:{Accept:"application/json","X-Subscription-Token":i}});if(!r.ok){h({available:!1,error:`API error: ${r.status}`},s,"");return}let a=((await r.json()).web?.results||[]).map(l=>({title:l.title,url:l.url,description:l.description,age:l.age||null}));h({available:!0,query:n,count:a.length,results:a},s,a.map(l=>`${l.title}
171
171
  ${l.url}
172
172
  ${l.description}`).join(`
173
173
 
174
- `))}catch(r){h({available:!1,error:r.message},s,"")}}function Is(n,e,s){let i=R(n).phases,t=R(n).roadmap,r=ie(n),o=[],a=0,l=0;try{let d=q.default.readdirSync(i,{withFileTypes:!0}).filter(u=>u.isDirectory()).map(u=>u.name).sort((u,p)=>ke(u,p));for(let u of d){let p=u.match(/^(\d+(?:\.\d+)*)-?(.*)/),m=p?p[1]:u,f=p&&p[2]?p[2].replace(/-/g," "):"",y=q.default.readdirSync(H.default.join(i,u)),g=y.filter(v=>v.endsWith("-PLAN.md")||v==="PLAN.md").length,_=y.filter(v=>v.endsWith("-SUMMARY.md")||v==="SUMMARY.md").length;a+=g,l+=_;let b;g===0?b="Pending":_>=g?b="Complete":_>0?b="In Progress":b="Planned",o.push({number:m,name:f,plans:g,summaries:_,status:b})}}catch{}let c=a>0?Math.min(100,Math.round(l/a*100)):0;if(e==="table"){let u=Math.round(c/100*10),p="\u2588".repeat(u)+"\u2591".repeat(10-u),m=`# ${r.version} ${r.name}
174
+ `))}catch(r){h({available:!1,error:r.message},s,"")}}function Is(n,e,s){let i=R(n).phases,t=R(n).roadmap,r=ie(n),o=[],a=0,l=0;try{let d=q.default.readdirSync(i,{withFileTypes:!0}).filter(u=>u.isDirectory()).map(u=>u.name).sort((u,f)=>ke(u,f));for(let u of d){let f=u.match(/^(\d+(?:\.\d+)*)-?(.*)/),m=f?f[1]:u,p=f&&f[2]?f[2].replace(/-/g," "):"",y=q.default.readdirSync(H.default.join(i,u)),g=y.filter(v=>v.endsWith("-PLAN.md")||v==="PLAN.md").length,_=y.filter(v=>v.endsWith("-SUMMARY.md")||v==="SUMMARY.md").length;a+=g,l+=_;let b;g===0?b="Pending":_>=g?b="Complete":_>0?b="In Progress":b="Planned",o.push({number:m,name:p,plans:g,summaries:_,status:b})}}catch{}let c=a>0?Math.min(100,Math.round(l/a*100)):0;if(e==="table"){let u=Math.round(c/100*10),f="\u2588".repeat(u)+"\u2591".repeat(10-u),m=`# ${r.version} ${r.name}
175
175
 
176
- **Progress:** [${p}] ${l}/${a} plans (${c}%)
176
+ **Progress:** [${f}] ${l}/${a} plans (${c}%)
177
177
 
178
178
  | Phase | Name | Plans | Status |
179
179
  |-------|------|-------|--------|
180
- `;for(let f of o)m+=`| ${f.number} | ${f.name} | ${f.summaries}/${f.plans} | ${f.status} |
180
+ `;for(let p of o)m+=`| ${p.number} | ${p.name} | ${p.summaries}/${p.plans} | ${p.status} |
181
181
  `;h({rendered:m},s,m)}else if(e==="bar"){let u=Math.round(c/100*20),m=`[${"\u2588".repeat(u)+"\u2591".repeat(20-u)}] ${l}/${a} plans (${c}%)`;h({bar:m,percent:c,completed:l,total:a},s,m)}else h({milestone_version:r.version,milestone_name:r.name,phases:o,total_plans:a,total_summaries:l,percent:c},s)}function Es(n,e,s){e||S("filename required for todo complete");let i=H.default.join(F(n),"todos","pending"),t=H.default.join(F(n),"todos","completed"),r=H.default.join(i,e);q.default.existsSync(r)||S(`Todo not found: ${e}`),q.default.mkdirSync(t,{recursive:!0});let o=q.default.readFileSync(r,"utf-8"),a=new Date().toISOString().split("T")[0];o=`completed: ${a}
182
- `+o,q.default.writeFileSync(H.default.join(t,e),o,"utf-8"),q.default.unlinkSync(r),h({completed:!0,file:e,date:a},s,"completed")}function ws(n,e,s){e||S("phase required for todo match-phase");let i=H.default.join(F(n),"todos","pending"),t=[];try{for(let p of q.default.readdirSync(i).filter(m=>m.endsWith(".md")))try{let m=q.default.readFileSync(H.default.join(i,p),"utf-8"),f=m.match(/^title:\s*(.+)$/m),y=m.match(/^area:\s*(.+)$/m),g=m.match(/^files:\s*(.+)$/m),_=m.replace(/^(title|area|files|created|priority):.*$/gm,"").trim();t.push({file:p,title:f?f[1].trim():"Untitled",area:y?y[1].trim():"general",files:g?g[1].trim().split(/[,\s]+/).filter(Boolean):[],body:_.slice(0,200)})}catch{}}catch{}if(t.length===0){h({phase:e,matches:[],todo_count:0},s);return}let r=Qe(n,e),o=`${r?.phase_name??""} ${r?.goal??""} ${r?.section??""}`.toLowerCase(),a=new Set(["the","and","for","with","from","that","this","will","are","was","has","have","been","not","but","all","can","into","each","when","any","use","new"]),l=new Set(o.split(/[\s\-_/.,;:()[\]{}|]+/).map(p=>p.replace(/[^a-z0-9]/g,"")).filter(p=>p.length>2&&!a.has(p))),c=ue(n,e),d=[];if(c?.found)try{let p=H.default.join(n,c.directory);for(let m of q.default.readdirSync(p).filter(f=>f.endsWith("-PLAN.md")))try{let y=q.default.readFileSync(H.default.join(p,m),"utf-8").match(/files_modified:\s*\[([^\]]*)\]/);y&&d.push(...y[1].split(",").map(g=>g.trim().replace(/['"]/g,"")).filter(Boolean))}catch{}}catch{}let u=[];for(let p of t){let m=0,f=[],g=`${p.title} ${p.body}`.toLowerCase().split(/[\s\-_/.,;:()[\]{}|]+/).map(_=>_.replace(/[^a-z0-9]/g,"")).filter(_=>_.length>2&&!a.has(_)).filter(_=>l.has(_));if(g.length>0&&(m+=Math.min(g.length*.2,.6),f.push(`keywords: ${[...new Set(g)].slice(0,5).join(", ")}`)),p.area!=="general"&&o.includes(p.area.toLowerCase())&&(m+=.3,f.push(`area: ${p.area}`)),p.files.length>0&&d.length>0){let _=p.files.filter(b=>d.some(v=>v.includes(b)||b.includes(v)));_.length>0&&(m+=.4,f.push(`files: ${_.slice(0,3).join(", ")}`))}m>0&&u.push({file:p.file,title:p.title,area:p.area,score:Math.round(m*100)/100,reasons:f})}u.sort((p,m)=>m.score-p.score),h({phase:e,matches:u,todo_count:t.length},s)}function Ms(n,e,s,i){let{phase:t,name:r}=s,o=t?ce(t):"00",a=new Date().toISOString().split("T")[0],l=t?ue(n,t):null,c=l?H.default.join(n,l.directory):null;t&&!c&&e!=="phase-dir"&&S(`Phase ${t} directory not found`);let d,u;switch(e){case"context":d=H.default.join(c,`${o}-CONTEXT.md`),u=`---
182
+ `+o,q.default.writeFileSync(H.default.join(t,e),o,"utf-8"),q.default.unlinkSync(r),h({completed:!0,file:e,date:a},s,"completed")}function ws(n,e,s){e||S("phase required for todo match-phase");let i=H.default.join(F(n),"todos","pending"),t=[];try{for(let f of q.default.readdirSync(i).filter(m=>m.endsWith(".md")))try{let m=q.default.readFileSync(H.default.join(i,f),"utf-8"),p=m.match(/^title:\s*(.+)$/m),y=m.match(/^area:\s*(.+)$/m),g=m.match(/^files:\s*(.+)$/m),_=m.replace(/^(title|area|files|created|priority):.*$/gm,"").trim();t.push({file:f,title:p?p[1].trim():"Untitled",area:y?y[1].trim():"general",files:g?g[1].trim().split(/[,\s]+/).filter(Boolean):[],body:_.slice(0,200)})}catch{}}catch{}if(t.length===0){h({phase:e,matches:[],todo_count:0},s);return}let r=Qe(n,e),o=`${r?.phase_name??""} ${r?.goal??""} ${r?.section??""}`.toLowerCase(),a=new Set(["the","and","for","with","from","that","this","will","are","was","has","have","been","not","but","all","can","into","each","when","any","use","new"]),l=new Set(o.split(/[\s\-_/.,;:()[\]{}|]+/).map(f=>f.replace(/[^a-z0-9]/g,"")).filter(f=>f.length>2&&!a.has(f))),c=ue(n,e),d=[];if(c?.found)try{let f=H.default.join(n,c.directory);for(let m of q.default.readdirSync(f).filter(p=>p.endsWith("-PLAN.md")))try{let y=q.default.readFileSync(H.default.join(f,m),"utf-8").match(/files_modified:\s*\[([^\]]*)\]/);y&&d.push(...y[1].split(",").map(g=>g.trim().replace(/['"]/g,"")).filter(Boolean))}catch{}}catch{}let u=[];for(let f of t){let m=0,p=[],g=`${f.title} ${f.body}`.toLowerCase().split(/[\s\-_/.,;:()[\]{}|]+/).map(_=>_.replace(/[^a-z0-9]/g,"")).filter(_=>_.length>2&&!a.has(_)).filter(_=>l.has(_));if(g.length>0&&(m+=Math.min(g.length*.2,.6),p.push(`keywords: ${[...new Set(g)].slice(0,5).join(", ")}`)),f.area!=="general"&&o.includes(f.area.toLowerCase())&&(m+=.3,p.push(`area: ${f.area}`)),f.files.length>0&&d.length>0){let _=f.files.filter(b=>d.some(v=>v.includes(b)||b.includes(v)));_.length>0&&(m+=.4,p.push(`files: ${_.slice(0,3).join(", ")}`))}m>0&&u.push({file:f.file,title:f.title,area:f.area,score:Math.round(m*100)/100,reasons:p})}u.sort((f,m)=>m.score-f.score),h({phase:e,matches:u,todo_count:t.length},s)}function Ms(n,e,s,i){let{phase:t,name:r}=s,o=t?ce(t):"00",a=new Date().toISOString().split("T")[0],l=t?ue(n,t):null,c=l?H.default.join(n,l.directory):null;t&&!c&&e!=="phase-dir"&&S(`Phase ${t} directory not found`);let d,u;switch(e){case"context":d=H.default.join(c,`${o}-CONTEXT.md`),u=`---
183
183
  phase: "${o}"
184
184
  name: "${r||l?.phase_name||"Unnamed"}"
185
185
  created: ${a}
@@ -236,34 +236,34 @@ status: pending
236
236
  ## Result
237
237
 
238
238
  _Pending verification_
239
- `;break;case"phase-dir":{(!t||!r)&&S("phase and name required for phase-dir scaffold");let m=Te(r),f=`${o}-${m}`,y=R(n).phases;q.default.mkdirSync(y,{recursive:!0});let g=H.default.join(y,f);q.default.mkdirSync(g,{recursive:!0}),h({created:!0,directory:z(H.default.relative(n,g)),path:g},i,g);return}default:S(`Unknown scaffold type: ${e}. Available: context, uat, verification, phase-dir`);return}if(q.default.existsSync(d)){h({created:!1,reason:"already_exists",path:d},i,"exists");return}q.default.writeFileSync(d,u,"utf-8");let p=z(H.default.relative(n,d));h({created:!0,path:p},i,p)}function Fs(n,e,s){let i=R(n).phases,t=R(n).roadmap,r=R(n).requirements,o=R(n).state,a=ie(n),l=Pe(n),c=new Map,d=0,u=0;try{let A=be(q.default.readFileSync(t,"utf-8"),n),O=/#{2,4}\s*Phase\s+(\d+[A-Z]?(?:\.\d+)*)\s*:\s*([^\n]+)/gi,N;for(;(N=O.exec(A))!==null;)c.set(N[1],{number:N[1],name:N[2].replace(/\(INSERTED\)/i,"").trim(),plans:0,summaries:0,status:"Not Started"})}catch{}try{let A=q.default.readdirSync(i,{withFileTypes:!0}).filter(O=>O.isDirectory()).map(O=>O.name).filter(l).sort((O,N)=>ke(O,N));for(let O of A){let N=O.match(/^(\d+[A-Z]?(?:\.\d+)*)-?(.*)/i),L=N?N[1]:O,ne=N&&N[2]?N[2].replace(/-/g," "):"",de=q.default.readdirSync(H.default.join(i,O)),ve=de.filter(qe=>qe.endsWith("-PLAN.md")||qe==="PLAN.md").length,se=de.filter(qe=>qe.endsWith("-SUMMARY.md")||qe==="SUMMARY.md").length;d+=ve,u+=se;let me;ve===0?me="Not Started":se>=ve?me="Complete":se>0?me="In Progress":me="Planned";let De=c.get(L);c.set(L,{number:L,name:De?.name||ne,plans:ve,summaries:se,status:me})}}catch{}let p=[...c.values()].sort((A,O)=>ke(A.number,O.number)),m=p.filter(A=>A.status==="Complete").length,f=d>0?Math.min(100,Math.round(u/d*100)):0,y=p.length>0?Math.min(100,Math.round(m/p.length*100)):0,g=0,_=0;try{if(q.default.existsSync(r)){let A=q.default.readFileSync(r,"utf-8");_=(A.match(/^- \[x\] \*\*/gm)||[]).length,g=_+(A.match(/^- \[ \] \*\*/gm)||[]).length}}catch{}let b=null;try{if(q.default.existsSync(o)){let A=q.default.readFileSync(o,"utf-8");b=(A.match(/^last_activity:\s*(.+)$/im)??A.match(/\*\*Last Activity:\*\*\s*(.+)/i)??A.match(/^Last Activity:\s*(.+)$/im))?.[1]?.trim()??null}}catch{}let v=0,P=null,k=oe(n,["rev-list","--count","HEAD"]);k.exitCode===0&&(v=parseInt(k.stdout,10)||0);let $=oe(n,["rev-list","--max-parents=0","HEAD"]);if($.exitCode===0&&$.stdout){let A=oe(n,["show","-s","--format=%as",$.stdout.split(`
240
- `)[0].trim()]);A.exitCode===0&&(P=A.stdout||null)}let D={milestone_version:a.version,milestone_name:a.name,phases:p,phases_completed:m,phases_total:p.length,total_plans:d,total_summaries:u,percent:y,plan_percent:f,requirements_total:g,requirements_complete:_,git_commits:v,git_first_commit_date:P,last_activity:b};if(e==="table"){let O=Math.round(y/100*10),N="\u2588".repeat(O)+"\u2591".repeat(10-O),L=`# ${a.version} ${a.name} - Statistics
239
+ `;break;case"phase-dir":{(!t||!r)&&S("phase and name required for phase-dir scaffold");let m=De(r),p=`${o}-${m}`,y=R(n).phases;q.default.mkdirSync(y,{recursive:!0});let g=H.default.join(y,p);q.default.mkdirSync(g,{recursive:!0}),h({created:!0,directory:z(H.default.relative(n,g)),path:g},i,g);return}default:S(`Unknown scaffold type: ${e}. Available: context, uat, verification, phase-dir`);return}if(q.default.existsSync(d)){h({created:!1,reason:"already_exists",path:d},i,"exists");return}q.default.writeFileSync(d,u,"utf-8");let f=z(H.default.relative(n,d));h({created:!0,path:f},i,f)}function Fs(n,e,s){let i=R(n).phases,t=R(n).roadmap,r=R(n).requirements,o=R(n).state,a=ie(n),l=Pe(n),c=new Map,d=0,u=0;try{let A=be(q.default.readFileSync(t,"utf-8"),n),O=/#{2,4}\s*Phase\s+(\d+[A-Z]?(?:\.\d+)*)\s*:\s*([^\n]+)/gi,N;for(;(N=O.exec(A))!==null;)c.set(N[1],{number:N[1],name:N[2].replace(/\(INSERTED\)/i,"").trim(),plans:0,summaries:0,status:"Not Started"})}catch{}try{let A=q.default.readdirSync(i,{withFileTypes:!0}).filter(O=>O.isDirectory()).map(O=>O.name).filter(l).sort((O,N)=>ke(O,N));for(let O of A){let N=O.match(/^(\d+[A-Z]?(?:\.\d+)*)-?(.*)/i),L=N?N[1]:O,ne=N&&N[2]?N[2].replace(/-/g," "):"",de=q.default.readdirSync(H.default.join(i,O)),ve=de.filter(qe=>qe.endsWith("-PLAN.md")||qe==="PLAN.md").length,se=de.filter(qe=>qe.endsWith("-SUMMARY.md")||qe==="SUMMARY.md").length;d+=ve,u+=se;let me;ve===0?me="Not Started":se>=ve?me="Complete":se>0?me="In Progress":me="Planned";let Te=c.get(L);c.set(L,{number:L,name:Te?.name||ne,plans:ve,summaries:se,status:me})}}catch{}let f=[...c.values()].sort((A,O)=>ke(A.number,O.number)),m=f.filter(A=>A.status==="Complete").length,p=d>0?Math.min(100,Math.round(u/d*100)):0,y=f.length>0?Math.min(100,Math.round(m/f.length*100)):0,g=0,_=0;try{if(q.default.existsSync(r)){let A=q.default.readFileSync(r,"utf-8");_=(A.match(/^- \[x\] \*\*/gm)||[]).length,g=_+(A.match(/^- \[ \] \*\*/gm)||[]).length}}catch{}let b=null;try{if(q.default.existsSync(o)){let A=q.default.readFileSync(o,"utf-8");b=(A.match(/^last_activity:\s*(.+)$/im)??A.match(/\*\*Last Activity:\*\*\s*(.+)/i)??A.match(/^Last Activity:\s*(.+)$/im))?.[1]?.trim()??null}}catch{}let v=0,P=null,k=oe(n,["rev-list","--count","HEAD"]);k.exitCode===0&&(v=parseInt(k.stdout,10)||0);let $=oe(n,["rev-list","--max-parents=0","HEAD"]);if($.exitCode===0&&$.stdout){let A=oe(n,["show","-s","--format=%as",$.stdout.split(`
240
+ `)[0].trim()]);A.exitCode===0&&(P=A.stdout||null)}let T={milestone_version:a.version,milestone_name:a.name,phases:f,phases_completed:m,phases_total:f.length,total_plans:d,total_summaries:u,percent:y,plan_percent:p,requirements_total:g,requirements_complete:_,git_commits:v,git_first_commit_date:P,last_activity:b};if(e==="table"){let O=Math.round(y/100*10),N="\u2588".repeat(O)+"\u2591".repeat(10-O),L=`# ${a.version} ${a.name} - Statistics
241
241
 
242
- **Progress:** [${N}] ${m}/${p.length} phases (${y}%)
243
- `;d>0&&(L+=`**Plans:** ${u}/${d} complete (${f}%)
244
- `),L+=`**Phases:** ${m}/${p.length} complete
242
+ **Progress:** [${N}] ${m}/${f.length} phases (${y}%)
243
+ `;d>0&&(L+=`**Plans:** ${u}/${d} complete (${p}%)
244
+ `),L+=`**Phases:** ${m}/${f.length} complete
245
245
  `,g>0&&(L+=`**Requirements:** ${_}/${g} complete
246
246
  `),L+=`
247
247
  | Phase | Name | Plans | Completed | Status |
248
248
  |-------|------|-------|-----------|--------|
249
- `;for(let ne of p)L+=`| ${ne.number} | ${ne.name} | ${ne.plans} | ${ne.summaries} | ${ne.status} |
249
+ `;for(let ne of f)L+=`| ${ne.number} | ${ne.name} | ${ne.plans} | ${ne.summaries} | ${ne.status} |
250
250
  `;v>0&&(L+=`
251
251
  **Git:** ${v} commits`,P&&(L+=` (since ${P})`),L+=`
252
252
  `),b&&(L+=`**Last activity:** ${b}
253
- `),h({rendered:L},s,L)}else h(D,s)}var q,H,ye=le(()=>{"use strict";q=W(require("fs")),H=W(require("path"));fe();Ue();rt();ct()});var dt={};pe(dt,{cmdFindPhase:()=>Os,cmdPhaseAdd:()=>Ws,cmdPhaseComplete:()=>Vs,cmdPhaseInsert:()=>qs,cmdPhaseNextDecimal:()=>Ts,cmdPhasePlanIndex:()=>Ns,cmdPhaseRemove:()=>zs,cmdPhasesList:()=>Ds});function Ds(n,e,s){let i=M.default.join(F(n),"phases"),{type:t,phase:r,includeArchived:o}=e;if(!j.default.existsSync(i)){h(t?{files:[],count:0}:{directories:[],count:0},s,"");return}try{let a=j.default.readdirSync(i,{withFileTypes:!0}).filter(l=>l.isDirectory()).map(l=>l.name);if(o){let l=gt(n);for(let c of l)a.push(`${c.name} [${c.milestone}]`)}if(a.sort((l,c)=>ke(l,c)),r){let l=ce(r),c=a.find(d=>d.startsWith(l));if(!c){h({files:[],count:0,phase_dir:null,error:"Phase not found"},s,"");return}a=[c]}if(t){let l=[];for(let c of a){let d=M.default.join(i,c),u=j.default.readdirSync(d),p;t==="plans"?p=u.filter(m=>m.endsWith("-PLAN.md")||m==="PLAN.md"):t==="summaries"?p=u.filter(m=>m.endsWith("-SUMMARY.md")||m==="SUMMARY.md"):p=u,l.push(...p.sort())}h({files:l,count:l.length,phase_dir:r?a[0]?.replace(/^\d+(?:\.\d+)*-?/,""):null},s,l.join(`
253
+ `),h({rendered:L},s,L)}else h(T,s)}var q,H,ye=le(()=>{"use strict";q=W(require("fs")),H=W(require("path"));pe();Ue();rt();ct()});var dt={};fe(dt,{cmdFindPhase:()=>Os,cmdPhaseAdd:()=>Ws,cmdPhaseComplete:()=>Vs,cmdPhaseInsert:()=>qs,cmdPhaseNextDecimal:()=>Ds,cmdPhasePlanIndex:()=>Ns,cmdPhaseRemove:()=>zs,cmdPhasesList:()=>Ts});function Ts(n,e,s){let i=M.default.join(F(n),"phases"),{type:t,phase:r,includeArchived:o}=e;if(!j.default.existsSync(i)){h(t?{files:[],count:0}:{directories:[],count:0},s,"");return}try{let a=j.default.readdirSync(i,{withFileTypes:!0}).filter(l=>l.isDirectory()).map(l=>l.name);if(o){let l=gt(n);for(let c of l)a.push(`${c.name} [${c.milestone}]`)}if(a.sort((l,c)=>ke(l,c)),r){let l=ce(r),c=a.find(d=>d.startsWith(l));if(!c){h({files:[],count:0,phase_dir:null,error:"Phase not found"},s,"");return}a=[c]}if(t){let l=[];for(let c of a){let d=M.default.join(i,c),u=j.default.readdirSync(d),f;t==="plans"?f=u.filter(m=>m.endsWith("-PLAN.md")||m==="PLAN.md"):t==="summaries"?f=u.filter(m=>m.endsWith("-SUMMARY.md")||m==="SUMMARY.md"):f=u,l.push(...f.sort())}h({files:l,count:l.length,phase_dir:r?a[0]?.replace(/^\d+(?:\.\d+)*-?/,""):null},s,l.join(`
254
254
  `));return}h({directories:a,count:a.length},s,a.join(`
255
- `))}catch(a){S("Failed to list phases: "+a.message)}}function Ts(n,e,s){let i=M.default.join(F(n),"phases"),t=ce(e??"");if(!j.default.existsSync(i)){h({found:!1,base_phase:t,next:`${t}.1`,existing:[]},s,`${t}.1`);return}try{let r=j.default.readdirSync(i,{withFileTypes:!0}).filter(d=>d.isDirectory()).map(d=>d.name),o=r.some(d=>d.startsWith(t+"-")||d===t),a=new RegExp(`^${t}\\.(\\d+)`),l=r.map(d=>{let u=d.match(a);return u?`${t}.${u[1]}`:null}).filter(Boolean);l.sort((d,u)=>ke(d,u));let c=l.length===0?`${t}.1`:`${t}.${parseInt(l[l.length-1].split(".")[1],10)+1}`;h({found:o,base_phase:t,next:c,existing:l},s,c)}catch(r){S("Failed to calculate next decimal phase: "+r.message)}}function Os(n,e,s){e||S("phase identifier required");let i=M.default.join(F(n),"phases"),t=ce(e),r={found:!1,directory:null,phase_number:null,phase_name:null,plans:[],summaries:[]};try{let a=j.default.readdirSync(i,{withFileTypes:!0}).filter(y=>y.isDirectory()).map(y=>y.name).sort((y,g)=>ke(y,g)).find(y=>y.startsWith(t));if(!a){h(r,s,"");return}let l=a.match(/^(\d+[A-Z]?(?:\.\d+)*)-?(.*)/i),c=l?l[1]:t,d=l&&l[2]?l[2]:null,u=M.default.join(i,a),p=j.default.readdirSync(u),m=p.filter(y=>y.endsWith("-PLAN.md")||y==="PLAN.md").sort(),f=p.filter(y=>y.endsWith("-SUMMARY.md")||y==="SUMMARY.md").sort();h({found:!0,directory:z(M.default.join(M.default.relative(n,F(n)),"phases",a)),phase_number:c,phase_name:d,plans:m,summaries:f},s,z(M.default.join(M.default.relative(n,F(n)),"phases",a)))}catch{h(r,s,"")}}function Ns(n,e,s){e||S("phase required for phase-plan-index");let i=M.default.join(F(n),"phases"),t=ce(e),r=null;try{let y=j.default.readdirSync(i,{withFileTypes:!0}).filter(g=>g.isDirectory()).map(g=>g.name).sort((g,_)=>ke(g,_)).find(g=>g.startsWith(t));y&&(r=M.default.join(i,y))}catch{}if(!r){h({phase:t,error:"Phase not found",plans:[],waves:{},incomplete:[],has_checkpoints:!1},s);return}let o=j.default.readdirSync(r),a=o.filter(f=>f.endsWith("-PLAN.md")||f==="PLAN.md").sort(),l=o.filter(f=>f.endsWith("-SUMMARY.md")||f==="SUMMARY.md"),c=new Set(l.map(f=>f.replace("-SUMMARY.md","").replace("SUMMARY.md",""))),d=[],u={},p=[],m=!1;for(let f of a){let y=f.replace("-PLAN.md","").replace("PLAN.md",""),g=j.default.readFileSync(M.default.join(r,f),"utf-8"),_=ee(g),b=g.match(/<task[\s>]/gi)||[],v=g.match(/##\s*Task\s*\d+/gi)||[],P=b.length||v.length,k=parseInt(String(_.wave),10)||1,$=!0;_.autonomous!==void 0&&($=_.autonomous==="true"||_.autonomous===!0),$||(m=!0);let D=[],A=_.files_modified||_["files-modified"];A&&(D=Array.isArray(A)?A:[A]);let O=c.has(y);O||p.push(y),d.push({id:y,wave:k,autonomous:$,objective:g.match(/<objective>\s*\n?\s*(.+)/)?.[1]?.trim()||_.objective||null,files_modified:D,task_count:P,has_summary:O});let N=String(k);u[N]||(u[N]=[]),u[N].push(y)}h({phase:t,plans:d,waves:u,incomplete:p,has_checkpoints:m},s)}function Ws(n,e,s,i){e||S("description required for phase add");let t=B(n),r=M.default.join(F(n),"ROADMAP.md");j.default.existsSync(r)||S("ROADMAP.md not found");let o=j.default.readFileSync(r,"utf-8"),a=be(o,n),l=Te(e),c,d;if(i||t.phase_naming==="custom")c=i||l.toUpperCase().replace(/-/g,"-"),c||S('--id required when phase_naming is "custom"'),d=`${c}-${l}`;else{let g=/#{2,4}\s*Phase\s+(\d+)[A-Z]?(?:\.\d+)*:/gi,_=0,b;for(;(b=g.exec(a))!==null;){let P=parseInt(b[1],10);P>_&&(_=P)}c=_+1,d=`${String(c).padStart(2,"0")}-${l}`}let u=M.default.join(F(n),"phases",d);j.default.mkdirSync(u,{recursive:!0}),j.default.writeFileSync(M.default.join(u,".gitkeep"),"");let p=t.phase_naming==="custom"?"":`
255
+ `))}catch(a){S("Failed to list phases: "+a.message)}}function Ds(n,e,s){let i=M.default.join(F(n),"phases"),t=ce(e??"");if(!j.default.existsSync(i)){h({found:!1,base_phase:t,next:`${t}.1`,existing:[]},s,`${t}.1`);return}try{let r=j.default.readdirSync(i,{withFileTypes:!0}).filter(d=>d.isDirectory()).map(d=>d.name),o=r.some(d=>d.startsWith(t+"-")||d===t),a=new RegExp(`^${t}\\.(\\d+)`),l=r.map(d=>{let u=d.match(a);return u?`${t}.${u[1]}`:null}).filter(Boolean);l.sort((d,u)=>ke(d,u));let c=l.length===0?`${t}.1`:`${t}.${parseInt(l[l.length-1].split(".")[1],10)+1}`;h({found:o,base_phase:t,next:c,existing:l},s,c)}catch(r){S("Failed to calculate next decimal phase: "+r.message)}}function Os(n,e,s){e||S("phase identifier required");let i=M.default.join(F(n),"phases"),t=ce(e),r={found:!1,directory:null,phase_number:null,phase_name:null,plans:[],summaries:[]};try{let a=j.default.readdirSync(i,{withFileTypes:!0}).filter(y=>y.isDirectory()).map(y=>y.name).sort((y,g)=>ke(y,g)).find(y=>y.startsWith(t));if(!a){h(r,s,"");return}let l=a.match(/^(\d+[A-Z]?(?:\.\d+)*)-?(.*)/i),c=l?l[1]:t,d=l&&l[2]?l[2]:null,u=M.default.join(i,a),f=j.default.readdirSync(u),m=f.filter(y=>y.endsWith("-PLAN.md")||y==="PLAN.md").sort(),p=f.filter(y=>y.endsWith("-SUMMARY.md")||y==="SUMMARY.md").sort();h({found:!0,directory:z(M.default.join(M.default.relative(n,F(n)),"phases",a)),phase_number:c,phase_name:d,plans:m,summaries:p},s,z(M.default.join(M.default.relative(n,F(n)),"phases",a)))}catch{h(r,s,"")}}function Ns(n,e,s){e||S("phase required for phase-plan-index");let i=M.default.join(F(n),"phases"),t=ce(e),r=null;try{let y=j.default.readdirSync(i,{withFileTypes:!0}).filter(g=>g.isDirectory()).map(g=>g.name).sort((g,_)=>ke(g,_)).find(g=>g.startsWith(t));y&&(r=M.default.join(i,y))}catch{}if(!r){h({phase:t,error:"Phase not found",plans:[],waves:{},incomplete:[],has_checkpoints:!1},s);return}let o=j.default.readdirSync(r),a=o.filter(p=>p.endsWith("-PLAN.md")||p==="PLAN.md").sort(),l=o.filter(p=>p.endsWith("-SUMMARY.md")||p==="SUMMARY.md"),c=new Set(l.map(p=>p.replace("-SUMMARY.md","").replace("SUMMARY.md",""))),d=[],u={},f=[],m=!1;for(let p of a){let y=p.replace("-PLAN.md","").replace("PLAN.md",""),g=j.default.readFileSync(M.default.join(r,p),"utf-8"),_=ee(g),b=g.match(/<task[\s>]/gi)||[],v=g.match(/##\s*Task\s*\d+/gi)||[],P=b.length||v.length,k=parseInt(String(_.wave),10)||1,$=!0;_.autonomous!==void 0&&($=_.autonomous==="true"||_.autonomous===!0),$||(m=!0);let T=[],A=_.files_modified||_["files-modified"];A&&(T=Array.isArray(A)?A:[A]);let O=c.has(y);O||f.push(y),d.push({id:y,wave:k,autonomous:$,objective:g.match(/<objective>\s*\n?\s*(.+)/)?.[1]?.trim()||_.objective||null,files_modified:T,task_count:P,has_summary:O});let N=String(k);u[N]||(u[N]=[]),u[N].push(y)}h({phase:t,plans:d,waves:u,incomplete:f,has_checkpoints:m},s)}function Ws(n,e,s,i){e||S("description required for phase add");let t=B(n),r=M.default.join(F(n),"ROADMAP.md");j.default.existsSync(r)||S("ROADMAP.md not found");let o=j.default.readFileSync(r,"utf-8"),a=be(o,n),l=De(e),c,d;if(i||t.phase_naming==="custom")c=i||l.toUpperCase().replace(/-/g,"-"),c||S('--id required when phase_naming is "custom"'),d=`${c}-${l}`;else{let g=/#{2,4}\s*Phase\s+(\d+)[A-Z]?(?:\.\d+)*:/gi,_=0,b;for(;(b=g.exec(a))!==null;){let P=parseInt(b[1],10);P>_&&(_=P)}c=_+1,d=`${String(c).padStart(2,"0")}-${l}`}let u=M.default.join(F(n),"phases",d);j.default.mkdirSync(u,{recursive:!0}),j.default.writeFileSync(M.default.join(u,".gitkeep"),"");let f=t.phase_naming==="custom"?"":`
256
256
  **Depends on:** Phase ${typeof c=="number"?c-1:"TBD"}`,m=`
257
257
  ### Phase ${c}: ${e}
258
258
 
259
259
  **Goal:** [To be planned]
260
- **Requirements**: TBD${p}
260
+ **Requirements**: TBD${f}
261
261
  **Plans:** 0 plans
262
262
 
263
263
  Plans:
264
264
  - [ ] TBD (run /gsd-plan-phase ${c} to break down)
265
- `,f=o.lastIndexOf(`
266
- ---`),y=f>0?o.slice(0,f)+m+o.slice(f):o+m;j.default.writeFileSync(r,y,"utf-8"),h({phase_number:typeof c=="number"?c:String(c),padded:typeof c=="number"?String(c).padStart(2,"0"):String(c),name:e,slug:l,directory:z(M.default.join(M.default.relative(n,F(n)),"phases",d)),naming_mode:t.phase_naming},s,typeof c=="number"?String(c).padStart(2,"0"):String(c))}function qs(n,e,s,i){(!e||!s)&&S("after-phase and description required for phase insert");let t=M.default.join(F(n),"ROADMAP.md");j.default.existsSync(t)||S("ROADMAP.md not found");let r=j.default.readFileSync(t,"utf-8"),o=be(r,n),a=Te(s),d=ce(e).replace(/^0+/,"").replace(/\./g,"\\.");new RegExp(`#{2,4}\\s*Phase\\s+0*${d}:`,"i").test(o)||S(`Phase ${e} not found in ROADMAP.md`);let p=M.default.join(F(n),"phases"),m=ce(e),f=[];try{let N=j.default.readdirSync(p,{withFileTypes:!0}).filter(ne=>ne.isDirectory()).map(ne=>ne.name),L=new RegExp(`^${m}\\.(\\d+)`);for(let ne of N){let de=ne.match(L);de&&f.push(parseInt(de[1],10))}}catch{}let y=f.length===0?1:Math.max(...f)+1,g=`${m}.${y}`,_=`${g}-${a}`,b=M.default.join(F(n),"phases",_);j.default.mkdirSync(b,{recursive:!0}),j.default.writeFileSync(M.default.join(b,".gitkeep"),"");let v=`
265
+ `,p=o.lastIndexOf(`
266
+ ---`),y=p>0?o.slice(0,p)+m+o.slice(p):o+m;j.default.writeFileSync(r,y,"utf-8"),h({phase_number:typeof c=="number"?c:String(c),padded:typeof c=="number"?String(c).padStart(2,"0"):String(c),name:e,slug:l,directory:z(M.default.join(M.default.relative(n,F(n)),"phases",d)),naming_mode:t.phase_naming},s,typeof c=="number"?String(c).padStart(2,"0"):String(c))}function qs(n,e,s,i){(!e||!s)&&S("after-phase and description required for phase insert");let t=M.default.join(F(n),"ROADMAP.md");j.default.existsSync(t)||S("ROADMAP.md not found");let r=j.default.readFileSync(t,"utf-8"),o=be(r,n),a=De(s),d=ce(e).replace(/^0+/,"").replace(/\./g,"\\.");new RegExp(`#{2,4}\\s*Phase\\s+0*${d}:`,"i").test(o)||S(`Phase ${e} not found in ROADMAP.md`);let f=M.default.join(F(n),"phases"),m=ce(e),p=[];try{let N=j.default.readdirSync(f,{withFileTypes:!0}).filter(ne=>ne.isDirectory()).map(ne=>ne.name),L=new RegExp(`^${m}\\.(\\d+)`);for(let ne of N){let de=ne.match(L);de&&p.push(parseInt(de[1],10))}}catch{}let y=p.length===0?1:Math.max(...p)+1,g=`${m}.${y}`,_=`${g}-${a}`,b=M.default.join(F(n),"phases",_);j.default.mkdirSync(b,{recursive:!0}),j.default.writeFileSync(M.default.join(b,".gitkeep"),"");let v=`
267
267
  ### Phase ${g}: ${s} (INSERTED)
268
268
 
269
269
  **Goal:** [Urgent work - to be planned]
@@ -273,8 +273,8 @@ Plans:
273
273
 
274
274
  Plans:
275
275
  - [ ] TBD (run /gsd-plan-phase ${g} to break down)
276
- `,P=new RegExp(`(#{2,4}\\s*Phase\\s+0*${d}:[^\\n]*\\n)`,"i"),k=r.match(P);k||S(`Could not find Phase ${e} header`);let $=r.indexOf(k[0]),A=r.slice($+k[0].length).match(/\n#{2,4}\s+Phase\s+\d/i),O=A?$+k[0].length+A.index:r.length;j.default.writeFileSync(t,r.slice(0,O)+v+r.slice(O),"utf-8"),h({phase_number:g,after_phase:e,name:s,slug:a,directory:z(M.default.join(M.default.relative(n,F(n)),"phases",_))},i,g)}function Ls(n,e,s){let i=[],t=[],r=new RegExp(`^${e}\\.(\\d+)-(.+)$`),o=Oe(n,!0).map(a=>{let l=a.match(r);return l?{dir:a,oldDecimal:parseInt(l[1],10),slug:l[2]}:null}).filter(a=>a!==null&&a.oldDecimal>s).sort((a,l)=>l.oldDecimal-a.oldDecimal);for(let a of o){let l=a.oldDecimal-1,c=`${e}.${a.oldDecimal}`,d=`${e}.${l}`,u=`${e}.${l}-${a.slug}`;j.default.renameSync(M.default.join(n,a.dir),M.default.join(n,u)),i.push({from:a.dir,to:u});for(let p of j.default.readdirSync(M.default.join(n,u)))if(p.includes(c)){let m=p.replace(c,d);j.default.renameSync(M.default.join(n,u,p),M.default.join(n,u,m)),t.push({from:p,to:m})}}return{renamedDirs:i,renamedFiles:t}}function Us(n,e){let s=[],i=[],t=Oe(n,!0).map(r=>{let o=r.match(/^(\d+)([A-Z])?(?:\.(\d+))?-(.+)$/i);if(!o)return null;let a=parseInt(o[1],10);return a>e?{dir:r,oldInt:a,letter:o[2]?o[2].toUpperCase():"",decimal:o[3]?parseInt(o[3],10):null,slug:o[4]}:null}).filter(r=>r!==null).sort((r,o)=>r.oldInt!==o.oldInt?o.oldInt-r.oldInt:(o.decimal||0)-(r.decimal||0));for(let r of t){let o=r.oldInt-1,a=String(o).padStart(2,"0"),l=String(r.oldInt).padStart(2,"0"),c=r.letter||"",d=r.decimal!==null?`.${r.decimal}`:"",u=`${l}${c}${d}`,p=`${a}${c}${d}`,m=`${p}-${r.slug}`;j.default.renameSync(M.default.join(n,r.dir),M.default.join(n,m)),s.push({from:r.dir,to:m});for(let f of j.default.readdirSync(M.default.join(n,m)))if(f.startsWith(u)){let y=p+f.slice(u.length);j.default.renameSync(M.default.join(n,m,f),M.default.join(n,m,y)),i.push({from:f,to:y})}}return{renamedDirs:s,renamedFiles:i}}function Gs(n,e,s,i){let t=j.default.readFileSync(n,"utf-8"),r=Q(e);if(t=t.replace(new RegExp(`\\n?#{2,4}\\s*Phase\\s+${r}\\s*:[\\s\\S]*?(?=\\n#{2,4}\\s+Phase\\s+\\d|$)`,"i"),""),t=t.replace(new RegExp(`\\n?-\\s*\\[[ x]\\]\\s*.*Phase\\s+${r}[:\\s][^\\n]*`,"gi"),""),t=t.replace(new RegExp(`\\n?\\|\\s*${r}\\.?\\s[^|]*\\|[^\\n]*`,"gi"),""),!s)for(let o=99;o>i;o--){let a=o-1,l=String(o),c=String(a),d=l.padStart(2,"0"),u=c.padStart(2,"0");t=t.replace(new RegExp(`(#{2,4}\\s*Phase\\s+)${l}(\\s*:)`,"gi"),`$1${c}$2`),t=t.replace(new RegExp(`(Phase\\s+)${l}([:\\s])`,"g"),`$1${c}$2`),t=t.replace(new RegExp(`${d}-(\\d{2})`,"g"),`${u}-$1`),t=t.replace(new RegExp(`(\\|\\s*)${l}\\.\\s`,"g"),`$1${c}. `),t=t.replace(new RegExp(`(Depends on:\\*\\*\\s*Phase\\s+)${l}\\b`,"gi"),`$1${c}`)}j.default.writeFileSync(n,t,"utf-8")}function zs(n,e,s,i){e||S("phase number required for phase remove");let t=M.default.join(F(n),"ROADMAP.md"),r=M.default.join(F(n),"phases");j.default.existsSync(t)||S("ROADMAP.md not found");let o=ce(e),a=e.includes("."),l=s.force||!1,c=Oe(r,!0).find(m=>m.startsWith(o+"-")||m===o)||null;if(c&&!l){let m=j.default.readdirSync(M.default.join(r,c)).filter(f=>f.endsWith("-SUMMARY.md")||f==="SUMMARY.md");m.length>0&&S(`Phase ${e} has ${m.length} executed plan(s). Use --force to remove anyway.`)}c&&j.default.rmSync(M.default.join(r,c),{recursive:!0,force:!0});let d=[],u=[];try{let m=a?Ls(r,o.split(".")[0],parseInt(o.split(".")[1],10)):Us(r,parseInt(o,10));d=m.renamedDirs,u=m.renamedFiles}catch{}Gs(t,e,a,parseInt(o,10));let p=M.default.join(F(n),"STATE.md");if(j.default.existsSync(p)){let m=j.default.readFileSync(p,"utf-8"),f=V(m,"Total Phases");f&&(m=Se(m,"Total Phases",String(parseInt(f,10)-1))??m);let y=m.match(/(\bof\s+)(\d+)(\s*(?:\(|phases?))/i);y&&(m=m.replace(/(\bof\s+)(\d+)(\s*(?:\(|phases?))/i,`$1${parseInt(y[2],10)-1}$3`)),te(p,m,n)}h({removed:e,directory_deleted:c,renamed_directories:d,renamed_files:u,roadmap_updated:!0,state_updated:j.default.existsSync(p)},i)}function Vs(n,e,s){e||S("phase number required for phase complete");let i=M.default.join(F(n),"ROADMAP.md"),t=M.default.join(F(n),"STATE.md"),r=M.default.join(F(n),"phases"),o=ce(e),a=new Date().toISOString().split("T")[0],l=ue(n,e);l||S(`Phase ${e} not found`);let c=l.plans.length,d=l.summaries.length,u=!1,p=[];try{let g=M.default.join(n,l.directory),_=j.default.readdirSync(g);for(let b of _.filter(v=>v.includes("-UAT")&&v.endsWith(".md"))){let v=j.default.readFileSync(M.default.join(g,b),"utf-8");/result: pending/.test(v)&&p.push(`${b}: has pending tests`),/result: blocked/.test(v)&&p.push(`${b}: has blocked tests`),/status: partial/.test(v)&&p.push(`${b}: testing incomplete (partial)`),/status: diagnosed/.test(v)&&p.push(`${b}: has diagnosed gaps`)}for(let b of _.filter(v=>v.includes("-VERIFICATION")&&v.endsWith(".md"))){let v=j.default.readFileSync(M.default.join(g,b),"utf-8");/status: human_needed/.test(v)&&p.push(`${b}: needs human verification`),/status: gaps_found/.test(v)&&p.push(`${b}: has unresolved gaps`)}}catch{}if(j.default.existsSync(i)){let g=j.default.readFileSync(i,"utf-8"),_=new RegExp(`(-\\s*\\[)[ ](\\]\\s*.*Phase\\s+${Q(e)}[:\\s][^\\n]*)`,"i");g=Ze(g,_,`$1x$2 (completed ${a})`);let b=Q(e);g=g.replace(new RegExp(`^(\\|\\s*${b}\\.?\\s[^|]*(?:\\|[^\\n]*))$`,"im"),P=>{let k=P.split("|").slice(1,-1);return k.length===5?(k[3]=" Complete ",k[4]=` ${a} `):k.length===4&&(k[2]=" Complete ",k[3]=` ${a} `),"|"+k.join("|")+"|"}),g=Ze(g,new RegExp(`(#{2,4}\\s*Phase\\s+${b}[\\s\\S]*?\\*\\*Plans:\\*\\*\\s*)[^\\n]+`,"i"),`$1${d}/${c} plans complete`),j.default.writeFileSync(i,g,"utf-8");let v=M.default.join(F(n),"REQUIREMENTS.md");if(j.default.existsSync(v)){let k=be(g,n).match(new RegExp(`(#{2,4}\\s*Phase\\s+${Q(e)}[:\\s][\\s\\S]*?)(?=#{2,4}\\s*Phase\\s+|$)`,"i")),D=(k?k[1]:"").match(/\*\*Requirements:\*\*\s*([^\n]+)/i);if(D){let A=D[1].replace(/[[\]]/g,"").split(/[,\s]+/).map(N=>N.trim()).filter(Boolean),O=j.default.readFileSync(v,"utf-8");for(let N of A){let L=Q(N);O=O.replace(new RegExp(`(-\\s*\\[)[ ](\\]\\s*\\*\\*${L}\\*\\*)`,"gi"),"$1x$2"),O=O.replace(new RegExp(`(\\|\\s*${L}\\s*\\|[^|]+\\|)\\s*(?:Pending|In Progress)\\s*(\\|)`,"gi"),"$1 Complete $2")}j.default.writeFileSync(v,O,"utf-8"),u=!0}}}let m=null,f=null,y=!0;try{let g=Pe(n),_=j.default.readdirSync(r,{withFileTypes:!0}).filter(b=>b.isDirectory()).map(b=>b.name).filter(g).sort((b,v)=>ke(b,v));for(let b of _){let v=b.match(/^(\d+[A-Z]?(?:\.\d+)*)-?(.*)/i);if(v&&ke(v[1],e)>0){m=v[1],f=v[2]||null,y=!1;break}}}catch{}if(y&&j.default.existsSync(i))try{let g=be(j.default.readFileSync(i,"utf-8"),n),_=/#{2,4}\s*Phase\s+(\d+[A-Z]?(?:\.\d+)*)\s*:\s*([^\n]+)/gi,b;for(;(b=_.exec(g))!==null;)if(ke(b[1],e)>0){m=b[1],f=b[2].replace(/\(INSERTED\)/i,"").trim().toLowerCase().replace(/\s+/g,"-"),y=!1;break}}catch{}if(j.default.existsSync(t)){let g=j.default.readFileSync(t,"utf-8"),_=m||e,b=V(g,"Current Phase")||V(g,"Phase"),v=String(_);if(b){let k=b.match(/of\s+(\d+)/),$=b.match(/\(([^)]+)\)/);if(k){let D=f?` (${f.replace(/-/g," ")})`:$?` (${$[1]})`:"";v=`${_} of ${k[1]}${D}`}}g=he(g,"Current Phase","Phase",v),f&&(g=he(g,"Current Phase Name",null,f.replace(/-/g," "))),g=he(g,"Status",null,y?"Milestone complete":"Ready to plan"),g=he(g,"Current Plan","Plan","Not started"),g=he(g,"Last Activity","Last activity",a),g=he(g,"Last Activity Description",null,`Phase ${e} complete${m?`, transitioned to Phase ${m}`:""}`);let P=V(g,"Completed Phases");if(P){let k=parseInt(P,10)+1;g=Se(g,"Completed Phases",String(k))??g;let $=V(g,"Total Phases");if($){let D=parseInt($,10);if(D>0){let A=Math.round(k/D*100);g=Se(g,"Progress",`${A}%`)??g,g=g.replace(/(percent:\s*)\d+/,`$1${A}`)}}}te(t,g,n)}h({completed_phase:e,phase_name:l.phase_name,plans_executed:`${d}/${c}`,next_phase:m,next_phase_name:f,is_last_phase:y,date:a,roadmap_updated:j.default.existsSync(i),state_updated:j.default.existsSync(t),requirements_updated:u,warnings:p,has_warnings:p.length>0},s)}var j,M,ut=le(()=>{"use strict";j=W(require("fs")),M=W(require("path"));fe();Ue();Be()});var x,yn,Ir,Er,wr,Mr,Hs,Fr,Bs,Js,Ys,kt,Sn=le(()=>{"use strict";x=require("zod"),yn=x.z.object({milestone:x.z.string().optional(),milestone_name:x.z.string().optional(),current_phase:x.z.string().optional(),current_phase_name:x.z.string().optional(),current_plan:x.z.string().optional(),total_phases:x.z.coerce.number().int().nonnegative().optional(),total_plans_in_phase:x.z.coerce.number().int().nonnegative().optional(),status:x.z.string().optional(),progress:x.z.string().optional(),last_activity:x.z.string().optional(),paused_at:x.z.string().optional(),stopped_at:x.z.string().optional()}).passthrough(),Ir=x.z.object({found:x.z.literal(!0),phase_number:x.z.string(),phase_name:x.z.string(),goal:x.z.string().nullable(),success_criteria:x.z.array(x.z.string()).default([]),section:x.z.string().optional()}).passthrough(),Er=x.z.object({phase:x.z.union([x.z.string(),x.z.number()]),plan:x.z.union([x.z.string(),x.z.number()]),type:x.z.string(),wave:x.z.union([x.z.string(),x.z.number()]),depends_on:x.z.union([x.z.string(),x.z.array(x.z.string())]),files_modified:x.z.union([x.z.string(),x.z.array(x.z.string())]),autonomous:x.z.union([x.z.boolean(),x.z.string()]),must_haves:x.z.union([x.z.string(),x.z.array(x.z.string())])}).passthrough(),wr=x.z.object({phase:x.z.union([x.z.string(),x.z.number()]),plan:x.z.union([x.z.string(),x.z.number()]),subsystem:x.z.string(),tags:x.z.union([x.z.string(),x.z.array(x.z.string())]),duration:x.z.string(),completed:x.z.string()}).passthrough(),Mr=x.z.object({phase:x.z.union([x.z.string(),x.z.number()]),verified:x.z.union([x.z.boolean(),x.z.string()]),status:x.z.string(),score:x.z.union([x.z.number(),x.z.string()])}).passthrough(),Hs=x.z.object({test:x.z.number().int().positive().optional(),name:x.z.string(),expected:x.z.string().optional(),result:x.z.string(),category:x.z.string(),reason:x.z.string().optional(),blocked_by:x.z.string().optional()}).passthrough(),Fr=x.z.object({phase:x.z.string(),phase_dir:x.z.string(),file:x.z.string(),file_path:x.z.string(),type:x.z.literal("uat"),status:x.z.string(),items:x.z.array(Hs)}).passthrough(),Bs=x.z.object({branching_strategy:x.z.enum(["none","phase","milestone","workstream"]).default("none"),phase_branch_template:x.z.string().default("gsd/phase-{phase}-{slug}"),milestone_branch_template:x.z.string().default("gsd/{milestone}-{slug}"),quick_branch_template:x.z.string().nullable().default(null)}).passthrough(),Js=x.z.object({research:x.z.boolean().default(!0),plan_check:x.z.boolean().default(!0),verifier:x.z.boolean().default(!0),nyquist_validation:x.z.boolean().default(!0),auto_advance:x.z.boolean().default(!1),node_repair:x.z.boolean().default(!0),node_repair_budget:x.z.number().int().nonnegative().default(2),ui_phase:x.z.boolean().default(!0),ui_safety_gate:x.z.boolean().default(!0),text_mode:x.z.boolean().default(!1),research_before_questions:x.z.boolean().default(!1),discuss_mode:x.z.string().default("discuss"),skip_discuss:x.z.boolean().default(!1),_auto_chain_active:x.z.boolean().default(!1)}).passthrough(),Ys=x.z.object({context_warnings:x.z.boolean().default(!0),workflow_guard:x.z.boolean().default(!1)}).passthrough(),kt=x.z.object({model_profile:x.z.enum(["quality","balanced","budget","inherit"]).default("balanced"),commit_docs:x.z.boolean().default(!0),parallelization:x.z.boolean().default(!0),search_gitignored:x.z.boolean().default(!1),brave_search:x.z.boolean().default(!1),firecrawl:x.z.boolean().default(!1),exa_search:x.z.boolean().default(!1),git:Bs.default({}),workflow:Js.default({}),hooks:Ys.default({}),agent_skills:x.z.record(x.z.string(),x.z.unknown()).default({})}).passthrough()});var Pt={};pe(Pt,{cmdValidateAgents:()=>oi,cmdValidateConsistency:()=>ii,cmdValidateHealth:()=>ri,cmdVerifyArtifacts:()=>ni,cmdVerifyCommits:()=>ti,cmdVerifyKeyLinks:()=>si,cmdVerifyPhaseCompleteness:()=>Xs,cmdVerifyPlanStructure:()=>Qs,cmdVerifyReferences:()=>ei,cmdVerifySummary:()=>Zs});function Ks(n,e){let s=n;for(let i of e){if(s==null||typeof s!="object")return;s=s[i]}return s}function Zs(n,e,s,i){e||S("summary-path required");let t=Y.default.join(n,e),r=s||2;if(!K.default.existsSync(t)){h({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"]},i,"failed");return}let o=K.default.readFileSync(t,"utf-8"),a=[],l=new Set;for(let y of[/`([^`]+\.[a-zA-Z]+)`/g,/(?:Created|Modified|Added|Updated|Edited):\s*`?([^\s`]+\.[a-zA-Z]+)`?/gi]){let g;for(;(g=y.exec(o))!==null;)g[1]&&!g[1].startsWith("http")&&g[1].includes("/")&&l.add(g[1])}let c=Array.from(l).slice(0,r),d=c.filter(y=>!K.default.existsSync(Y.default.join(n,y))),u=o.match(/\b[0-9a-f]{7,40}\b/g)||[],p=!1;for(let y of u.slice(0,3))if(oe(n,["cat-file","-t",y]).stdout==="commit"){p=!0;break}let m="not_found";if(/##\s*(?:Self[- ]?Check|Verification|Quality Check)/i.test(o)){let y=o.slice(o.search(/##\s*(?:Self[- ]?Check|Verification|Quality Check)/i));/(?:fail|✗|❌|incomplete|blocked)/i.test(y)?m="failed":/(?:all\s+)?(?:pass|✓|✅|complete|succeeded)/i.test(y)&&(m="passed")}d.length>0&&a.push("Missing files: "+d.join(", ")),!p&&u.length>0&&a.push("Referenced commit hashes not found in git history"),m==="failed"&&a.push("Self-check section indicates failure");let f=d.length===0&&m!=="failed";h({passed:f,checks:{summary_exists:!0,files_created:{checked:c.length,found:c.length-d.length,missing:d},commits_exist:p,self_check:m},errors:a},i,f?"passed":"failed")}function Qs(n,e,s){e||S("file path required");let i=Y.default.isAbsolute(e)?e:Y.default.join(n,e),t=we(i);if(!t){h({error:"File not found",path:e},s);return}let r=ee(t),o=[],a=[];for(let p of["phase","plan","type","wave","depends_on","files_modified","autonomous","must_haves"])r[p]===void 0&&o.push(`Missing required frontmatter field: ${p}`);let l=/<task[^>]*>([\s\S]*?)<\/task>/g,c=[],d;for(;(d=l.exec(t))!==null;){let p=d[1],m=p.match(/<name>([\s\S]*?)<\/name>/),f=m?m[1].trim():"unnamed",y=/<files>/.test(p),g=/<action>/.test(p),_=/<verify>/.test(p),b=/<done>/.test(p);m||o.push("Task missing <name> element"),g||o.push(`Task '${f}' missing <action>`),_||a.push(`Task '${f}' missing <verify>`),b||a.push(`Task '${f}' missing <done>`),y||a.push(`Task '${f}' missing <files>`),c.push({name:f,hasFiles:y,hasAction:g,hasVerify:_,hasDone:b})}c.length===0&&a.push("No <task> elements found"),r.wave&&parseInt(String(r.wave))>1&&(!r.depends_on||Array.isArray(r.depends_on)&&r.depends_on.length===0)&&a.push("Wave > 1 but depends_on is empty"),/<task\s+type=["']?checkpoint/.test(t)&&r.autonomous!=="false"&&r.autonomous!==!1&&o.push("Has checkpoint tasks but autonomous is not false"),h({valid:o.length===0,errors:o,warnings:a,task_count:c.length,tasks:c,frontmatter_fields:Object.keys(r)},s,o.length===0?"valid":"invalid")}function Xs(n,e,s){e||S("phase required");let i=ue(n,e);if(!i?.found){h({error:"Phase not found",phase:e},s);return}let t=Y.default.join(n,i.directory),r=[],o=[],a;try{a=K.default.readdirSync(t)}catch{h({error:"Cannot read phase directory"},s);return}let l=a.filter(f=>f.match(/-PLAN\.md$/i)),c=a.filter(f=>f.match(/-SUMMARY\.md$/i)),d=new Set(l.map(f=>f.replace(/-PLAN\.md$/i,""))),u=new Set(c.map(f=>f.replace(/-SUMMARY\.md$/i,""))),p=[...d].filter(f=>!u.has(f)),m=[...u].filter(f=>!d.has(f));p.length>0&&r.push(`Plans without summaries: ${p.join(", ")}`),m.length>0&&o.push(`Summaries without plans: ${m.join(", ")}`),h({complete:r.length===0,phase:i.phase_number,plan_count:l.length,summary_count:c.length,incomplete_plans:p,orphan_summaries:m,errors:r,warnings:o},s,r.length===0?"complete":"incomplete")}function ei(n,e,s){e||S("file path required");let i=Y.default.isAbsolute(e)?e:Y.default.join(n,e),t=we(i);if(!t){h({error:"File not found",path:e},s);return}let r=[],o=[];for(let a of t.match(/@([^\s\n,)]+\/[^\s\n,)]+)/g)||[]){let l=a.slice(1),c=l.startsWith("~/")?Y.default.join(process.env.HOME??"",l.slice(2)):Y.default.join(n,l);(K.default.existsSync(c)?r:o).push(l)}for(let a of t.match(/`([^`]+\/[^`]+\.[a-zA-Z]{1,10})`/g)||[]){let l=a.slice(1,-1);l.startsWith("http")||l.includes("${")||l.includes("{{")||r.includes(l)||o.includes(l)||(K.default.existsSync(Y.default.join(n,l))?r:o).push(l)}h({valid:o.length===0,found:r.length,missing:o,total:r.length+o.length},s,o.length===0?"valid":"invalid")}function ti(n,e,s){(!e||e.length===0)&&S("At least one commit hash required");let i=[],t=[];for(let r of e)(oe(n,["cat-file","-t",r]).stdout.trim()==="commit"?i:t).push(r);h({all_valid:t.length===0,valid:i,invalid:t,total:e.length},s,t.length===0?"valid":"invalid")}function ni(n,e,s){e||S("plan file path required");let i=Y.default.isAbsolute(e)?e:Y.default.join(n,e),t=we(i);if(!t){h({error:"File not found",path:e},s);return}let r=St(t,"artifacts");if(r.length===0){h({error:"No must_haves.artifacts found in frontmatter",path:e},s);return}let o=[];for(let l of r){if(typeof l=="string")continue;let c=l;if(!c.path)continue;let d=Y.default.join(n,c.path),u=K.default.existsSync(d),p={path:c.path,exists:u,issues:[],passed:!1};if(u){let m=we(d)??"",f=m.split(`
277
- `).length;if(c.min_lines&&f<c.min_lines&&p.issues.push(`Only ${f} lines, need ${c.min_lines}`),c.contains&&!m.includes(c.contains)&&p.issues.push(`Missing pattern: ${c.contains}`),c.exports){let y=Array.isArray(c.exports)?c.exports:[c.exports];for(let g of y)m.includes(g)||p.issues.push(`Missing export: ${g}`)}p.passed=p.issues.length===0}else p.issues.push("File not found");o.push(p)}let a=o.filter(l=>l.passed).length;h({all_passed:a===o.length,passed:a,total:o.length,artifacts:o},s,a===o.length?"valid":"invalid")}function si(n,e,s){e||S("plan file path required");let i=Y.default.isAbsolute(e)?e:Y.default.join(n,e),t=we(i);if(!t){h({error:"File not found",path:e},s);return}let r=St(t,"key_links");if(r.length===0){h({error:"No must_haves.key_links found in frontmatter",path:e},s);return}let o=[];for(let l of r){if(typeof l=="string")continue;let c=l,d={from:c.from??"",to:c.to??"",via:c.via||"",verified:!1,detail:""},u=we(Y.default.join(n,c.from||""));if(!u)d.detail="Source file not found";else if(c.pattern)try{let p=new RegExp(c.pattern);if(p.test(u))d.verified=!0,d.detail="Pattern found in source";else{let m=we(Y.default.join(n,c.to||""));m&&p.test(m)?(d.verified=!0,d.detail="Pattern found in target"):d.detail=`Pattern "${c.pattern}" not found in source or target`}}catch{d.detail=`Invalid regex pattern: ${c.pattern}`}else u.includes(c.to||"")?(d.verified=!0,d.detail="Target referenced in source"):d.detail="Target not referenced in source";o.push(d)}let a=o.filter(l=>l.verified).length;h({all_verified:a===o.length,verified:a,total:o.length,links:o},s,a===o.length?"valid":"invalid")}function ii(n,e){let s=Y.default.join(F(n),"ROADMAP.md"),i=Y.default.join(F(n),"phases"),t=[],r=[];if(!K.default.existsSync(s)){t.push("ROADMAP.md not found"),h({passed:!1,errors:t,warnings:r},e,"failed");return}let o=be(K.default.readFileSync(s,"utf-8"),n),a=new Set,l=/#{2,4}\s*Phase\s+(\d+[A-Z]?(?:\.\d+)*)\s*:/gi,c;for(;(c=l.exec(o))!==null;)a.add(c[1]);let d=new Set;try{K.default.readdirSync(i,{withFileTypes:!0}).filter(m=>m.isDirectory()).map(m=>m.name).forEach(m=>{let f=m.match(/^(\d+[A-Z]?(?:\.\d+)*)/i);f&&d.add(f[1])})}catch{}for(let m of a)!d.has(m)&&!d.has(ce(m))&&r.push(`Phase ${m} in ROADMAP.md but no directory on disk`);for(let m of d){let f=String(parseInt(m,10));!a.has(m)&&!a.has(f)&&r.push(`Phase ${m} exists on disk but not in ROADMAP.md`)}if(B(n).phase_naming!=="custom"){let m=[...d].filter(f=>!f.includes(".")).map(f=>parseInt(f,10)).sort((f,y)=>f-y);for(let f=1;f<m.length;f++)m[f]!==m[f-1]+1&&r.push(`Gap in phase numbering: ${m[f-1]} \u2192 ${m[f]}`)}let p=t.length===0;h({passed:p,errors:t,warnings:r,warning_count:r.length},e,p?"passed":"failed")}function ri(n,e,s){let i=Y.default.resolve(n);if(i===_n.default.homedir()){h({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: ${i}`}],repairable_count:0},s);return}let t=F(n),r=J(n),o=Y.default.join(r,"PROJECT.md"),a=Y.default.join(t,"ROADMAP.md"),l=Y.default.join(t,"STATE.md"),c=Y.default.join(r,"config.json"),d=Y.default.join(t,"phases"),u=[],p=[],m=[],f=[],y=(b,v,P,k,$=!1,D)=>{let A={code:v,message:P,fix:k,repairable:$,...D};b==="error"?u.push(A):b==="warning"?p.push(A):m.push(A)};if(!K.default.existsSync(t)){y("error","E001",".planning/ directory not found","Run /gsd-new-project to initialize"),h({status:"broken",errors:u,warnings:p,info:m,repairable_count:0},s);return}if(!K.default.existsSync(o))y("error","E002","PROJECT.md not found","Run /gsd-new-project to create");else{let b=K.default.readFileSync(o,"utf-8");for(let v of["## What This Is","## Core Value","## Requirements"])b.includes(v)||y("warning","W001",`PROJECT.md missing section: ${v}`,"Add section manually")}if(K.default.existsSync(a)||y("error","E003","ROADMAP.md not found","Run /gsd-new-milestone to create roadmap"),!K.default.existsSync(l))y("error","E004","STATE.md not found","Run /gsd-health --repair to regenerate",!0),f.push("regenerateState");else try{let b=K.default.readFileSync(l,"utf-8"),v=ee(b),P=yn.safeParse(v);if(!P.success){for(let k of P.error.issues){let $=k.path.join(".")||"(root)";y("warning","W011",`STATE.md frontmatter: field "${$}" \u2014 ${k.message}`,"Check STATE.md frontmatter manually or run /gsd-health --repair to regenerate",!0)}f.includes("regenerateState")||f.push("regenerateState")}}catch{}if(!K.default.existsSync(c))y("warning","W003","config.json not found","Run /gsd-health --repair to create with defaults",!0),f.push("createConfig");else try{let b=JSON.parse(K.default.readFileSync(c,"utf-8")),v=kt.safeParse(b);if(!v.success){for(let P of v.error.issues){let k=P.path.join(".")||"(root)",$=Ks(b,P.path);y("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:$})}f.includes("fixSchemaDefaults")||f.push("fixSchemaDefaults")}}catch(b){y("error","E005",`config.json: JSON parse error - ${b.message}`,"Run pi-gsd-tools validate health --repair to reset to defaults",!0),f.push("resetConfig")}try{let b=ot();b.agents_installed||y("warning","W010",b.installed_agents.length===0?`No GSD agents found in ${b.agents_dir}`:`Missing ${b.missing_agents.length} GSD agents: ${b.missing_agents.join(", ")}`,"Run the GSD installer: pi install npm:pi-gsd")}catch{}let g=[];if(e.repair&&f.length>0)for(let b of f)try{if(b==="createConfig"||b==="resetConfig"){let v=kt.parse({});K.default.writeFileSync(c,JSON.stringify(v,null,2),"utf-8"),g.push({action:b,success:!0,path:"config.json"})}else if(b==="fixSchemaDefaults"&&K.default.existsSync(c)){let v=JSON.parse(K.default.readFileSync(c,"utf-8")),P=kt.parse(v);K.default.writeFileSync(c,JSON.stringify(P,null,2),"utf-8"),g.push({action:b,success:!0,path:"config.json"})}else if(b==="regenerateState"){if(K.default.existsSync(l)){let P=new Date().toISOString().replace(/[:.]/g,"-").slice(0,19),k=`${l}.bak-${P}`;K.default.copyFileSync(l,k),g.push({action:"backupState",success:!0,path:k})}let v=ie(n);te(l,`# Session State
276
+ `,P=new RegExp(`(#{2,4}\\s*Phase\\s+0*${d}:[^\\n]*\\n)`,"i"),k=r.match(P);k||S(`Could not find Phase ${e} header`);let $=r.indexOf(k[0]),A=r.slice($+k[0].length).match(/\n#{2,4}\s+Phase\s+\d/i),O=A?$+k[0].length+A.index:r.length;j.default.writeFileSync(t,r.slice(0,O)+v+r.slice(O),"utf-8"),h({phase_number:g,after_phase:e,name:s,slug:a,directory:z(M.default.join(M.default.relative(n,F(n)),"phases",_))},i,g)}function Ls(n,e,s){let i=[],t=[],r=new RegExp(`^${e}\\.(\\d+)-(.+)$`),o=Oe(n,!0).map(a=>{let l=a.match(r);return l?{dir:a,oldDecimal:parseInt(l[1],10),slug:l[2]}:null}).filter(a=>a!==null&&a.oldDecimal>s).sort((a,l)=>l.oldDecimal-a.oldDecimal);for(let a of o){let l=a.oldDecimal-1,c=`${e}.${a.oldDecimal}`,d=`${e}.${l}`,u=`${e}.${l}-${a.slug}`;j.default.renameSync(M.default.join(n,a.dir),M.default.join(n,u)),i.push({from:a.dir,to:u});for(let f of j.default.readdirSync(M.default.join(n,u)))if(f.includes(c)){let m=f.replace(c,d);j.default.renameSync(M.default.join(n,u,f),M.default.join(n,u,m)),t.push({from:f,to:m})}}return{renamedDirs:i,renamedFiles:t}}function Us(n,e){let s=[],i=[],t=Oe(n,!0).map(r=>{let o=r.match(/^(\d+)([A-Z])?(?:\.(\d+))?-(.+)$/i);if(!o)return null;let a=parseInt(o[1],10);return a>e?{dir:r,oldInt:a,letter:o[2]?o[2].toUpperCase():"",decimal:o[3]?parseInt(o[3],10):null,slug:o[4]}:null}).filter(r=>r!==null).sort((r,o)=>r.oldInt!==o.oldInt?o.oldInt-r.oldInt:(o.decimal||0)-(r.decimal||0));for(let r of t){let o=r.oldInt-1,a=String(o).padStart(2,"0"),l=String(r.oldInt).padStart(2,"0"),c=r.letter||"",d=r.decimal!==null?`.${r.decimal}`:"",u=`${l}${c}${d}`,f=`${a}${c}${d}`,m=`${f}-${r.slug}`;j.default.renameSync(M.default.join(n,r.dir),M.default.join(n,m)),s.push({from:r.dir,to:m});for(let p of j.default.readdirSync(M.default.join(n,m)))if(p.startsWith(u)){let y=f+p.slice(u.length);j.default.renameSync(M.default.join(n,m,p),M.default.join(n,m,y)),i.push({from:p,to:y})}}return{renamedDirs:s,renamedFiles:i}}function Gs(n,e,s,i){let t=j.default.readFileSync(n,"utf-8"),r=Q(e);if(t=t.replace(new RegExp(`\\n?#{2,4}\\s*Phase\\s+${r}\\s*:[\\s\\S]*?(?=\\n#{2,4}\\s+Phase\\s+\\d|$)`,"i"),""),t=t.replace(new RegExp(`\\n?-\\s*\\[[ x]\\]\\s*.*Phase\\s+${r}[:\\s][^\\n]*`,"gi"),""),t=t.replace(new RegExp(`\\n?\\|\\s*${r}\\.?\\s[^|]*\\|[^\\n]*`,"gi"),""),!s)for(let o=99;o>i;o--){let a=o-1,l=String(o),c=String(a),d=l.padStart(2,"0"),u=c.padStart(2,"0");t=t.replace(new RegExp(`(#{2,4}\\s*Phase\\s+)${l}(\\s*:)`,"gi"),`$1${c}$2`),t=t.replace(new RegExp(`(Phase\\s+)${l}([:\\s])`,"g"),`$1${c}$2`),t=t.replace(new RegExp(`${d}-(\\d{2})`,"g"),`${u}-$1`),t=t.replace(new RegExp(`(\\|\\s*)${l}\\.\\s`,"g"),`$1${c}. `),t=t.replace(new RegExp(`(Depends on:\\*\\*\\s*Phase\\s+)${l}\\b`,"gi"),`$1${c}`)}j.default.writeFileSync(n,t,"utf-8")}function zs(n,e,s,i){e||S("phase number required for phase remove");let t=M.default.join(F(n),"ROADMAP.md"),r=M.default.join(F(n),"phases");j.default.existsSync(t)||S("ROADMAP.md not found");let o=ce(e),a=e.includes("."),l=s.force||!1,c=Oe(r,!0).find(m=>m.startsWith(o+"-")||m===o)||null;if(c&&!l){let m=j.default.readdirSync(M.default.join(r,c)).filter(p=>p.endsWith("-SUMMARY.md")||p==="SUMMARY.md");m.length>0&&S(`Phase ${e} has ${m.length} executed plan(s). Use --force to remove anyway.`)}c&&j.default.rmSync(M.default.join(r,c),{recursive:!0,force:!0});let d=[],u=[];try{let m=a?Ls(r,o.split(".")[0],parseInt(o.split(".")[1],10)):Us(r,parseInt(o,10));d=m.renamedDirs,u=m.renamedFiles}catch{}Gs(t,e,a,parseInt(o,10));let f=M.default.join(F(n),"STATE.md");if(j.default.existsSync(f)){let m=j.default.readFileSync(f,"utf-8"),p=V(m,"Total Phases");p&&(m=Se(m,"Total Phases",String(parseInt(p,10)-1))??m);let y=m.match(/(\bof\s+)(\d+)(\s*(?:\(|phases?))/i);y&&(m=m.replace(/(\bof\s+)(\d+)(\s*(?:\(|phases?))/i,`$1${parseInt(y[2],10)-1}$3`)),te(f,m,n)}h({removed:e,directory_deleted:c,renamed_directories:d,renamed_files:u,roadmap_updated:!0,state_updated:j.default.existsSync(f)},i)}function Vs(n,e,s){e||S("phase number required for phase complete");let i=M.default.join(F(n),"ROADMAP.md"),t=M.default.join(F(n),"STATE.md"),r=M.default.join(F(n),"phases"),o=ce(e),a=new Date().toISOString().split("T")[0],l=ue(n,e);l||S(`Phase ${e} not found`);let c=l.plans.length,d=l.summaries.length,u=!1,f=[];try{let g=M.default.join(n,l.directory),_=j.default.readdirSync(g);for(let b of _.filter(v=>v.includes("-UAT")&&v.endsWith(".md"))){let v=j.default.readFileSync(M.default.join(g,b),"utf-8");/result: pending/.test(v)&&f.push(`${b}: has pending tests`),/result: blocked/.test(v)&&f.push(`${b}: has blocked tests`),/status: partial/.test(v)&&f.push(`${b}: testing incomplete (partial)`),/status: diagnosed/.test(v)&&f.push(`${b}: has diagnosed gaps`)}for(let b of _.filter(v=>v.includes("-VERIFICATION")&&v.endsWith(".md"))){let v=j.default.readFileSync(M.default.join(g,b),"utf-8");/status: human_needed/.test(v)&&f.push(`${b}: needs human verification`),/status: gaps_found/.test(v)&&f.push(`${b}: has unresolved gaps`)}}catch{}if(j.default.existsSync(i)){let g=j.default.readFileSync(i,"utf-8"),_=new RegExp(`(-\\s*\\[)[ ](\\]\\s*.*Phase\\s+${Q(e)}[:\\s][^\\n]*)`,"i");g=Ze(g,_,`$1x$2 (completed ${a})`);let b=Q(e);g=g.replace(new RegExp(`^(\\|\\s*${b}\\.?\\s[^|]*(?:\\|[^\\n]*))$`,"im"),P=>{let k=P.split("|").slice(1,-1);return k.length===5?(k[3]=" Complete ",k[4]=` ${a} `):k.length===4&&(k[2]=" Complete ",k[3]=` ${a} `),"|"+k.join("|")+"|"}),g=Ze(g,new RegExp(`(#{2,4}\\s*Phase\\s+${b}[\\s\\S]*?\\*\\*Plans:\\*\\*\\s*)[^\\n]+`,"i"),`$1${d}/${c} plans complete`),j.default.writeFileSync(i,g,"utf-8");let v=M.default.join(F(n),"REQUIREMENTS.md");if(j.default.existsSync(v)){let k=be(g,n).match(new RegExp(`(#{2,4}\\s*Phase\\s+${Q(e)}[:\\s][\\s\\S]*?)(?=#{2,4}\\s*Phase\\s+|$)`,"i")),T=(k?k[1]:"").match(/\*\*Requirements:\*\*\s*([^\n]+)/i);if(T){let A=T[1].replace(/[[\]]/g,"").split(/[,\s]+/).map(N=>N.trim()).filter(Boolean),O=j.default.readFileSync(v,"utf-8");for(let N of A){let L=Q(N);O=O.replace(new RegExp(`(-\\s*\\[)[ ](\\]\\s*\\*\\*${L}\\*\\*)`,"gi"),"$1x$2"),O=O.replace(new RegExp(`(\\|\\s*${L}\\s*\\|[^|]+\\|)\\s*(?:Pending|In Progress)\\s*(\\|)`,"gi"),"$1 Complete $2")}j.default.writeFileSync(v,O,"utf-8"),u=!0}}}let m=null,p=null,y=!0;try{let g=Pe(n),_=j.default.readdirSync(r,{withFileTypes:!0}).filter(b=>b.isDirectory()).map(b=>b.name).filter(g).sort((b,v)=>ke(b,v));for(let b of _){let v=b.match(/^(\d+[A-Z]?(?:\.\d+)*)-?(.*)/i);if(v&&ke(v[1],e)>0){m=v[1],p=v[2]||null,y=!1;break}}}catch{}if(y&&j.default.existsSync(i))try{let g=be(j.default.readFileSync(i,"utf-8"),n),_=/#{2,4}\s*Phase\s+(\d+[A-Z]?(?:\.\d+)*)\s*:\s*([^\n]+)/gi,b;for(;(b=_.exec(g))!==null;)if(ke(b[1],e)>0){m=b[1],p=b[2].replace(/\(INSERTED\)/i,"").trim().toLowerCase().replace(/\s+/g,"-"),y=!1;break}}catch{}if(j.default.existsSync(t)){let g=j.default.readFileSync(t,"utf-8"),_=m||e,b=V(g,"Current Phase")||V(g,"Phase"),v=String(_);if(b){let k=b.match(/of\s+(\d+)/),$=b.match(/\(([^)]+)\)/);if(k){let T=p?` (${p.replace(/-/g," ")})`:$?` (${$[1]})`:"";v=`${_} of ${k[1]}${T}`}}g=he(g,"Current Phase","Phase",v),p&&(g=he(g,"Current Phase Name",null,p.replace(/-/g," "))),g=he(g,"Status",null,y?"Milestone complete":"Ready to plan"),g=he(g,"Current Plan","Plan","Not started"),g=he(g,"Last Activity","Last activity",a),g=he(g,"Last Activity Description",null,`Phase ${e} complete${m?`, transitioned to Phase ${m}`:""}`);let P=V(g,"Completed Phases");if(P){let k=parseInt(P,10)+1;g=Se(g,"Completed Phases",String(k))??g;let $=V(g,"Total Phases");if($){let T=parseInt($,10);if(T>0){let A=Math.round(k/T*100);g=Se(g,"Progress",`${A}%`)??g,g=g.replace(/(percent:\s*)\d+/,`$1${A}`)}}}te(t,g,n)}h({completed_phase:e,phase_name:l.phase_name,plans_executed:`${d}/${c}`,next_phase:m,next_phase_name:p,is_last_phase:y,date:a,roadmap_updated:j.default.existsSync(i),state_updated:j.default.existsSync(t),requirements_updated:u,warnings:f,has_warnings:f.length>0},s)}var j,M,ut=le(()=>{"use strict";j=W(require("fs")),M=W(require("path"));pe();Ue();Be()});var x,yn,Ir,Er,wr,Mr,Hs,Fr,Bs,Js,Ys,kt,Sn=le(()=>{"use strict";x=require("zod"),yn=x.z.object({milestone:x.z.string().optional(),milestone_name:x.z.string().optional(),current_phase:x.z.string().optional(),current_phase_name:x.z.string().optional(),current_plan:x.z.string().optional(),total_phases:x.z.coerce.number().int().nonnegative().optional(),total_plans_in_phase:x.z.coerce.number().int().nonnegative().optional(),status:x.z.string().optional(),progress:x.z.string().optional(),last_activity:x.z.string().optional(),paused_at:x.z.string().optional(),stopped_at:x.z.string().optional()}).passthrough(),Ir=x.z.object({found:x.z.literal(!0),phase_number:x.z.string(),phase_name:x.z.string(),goal:x.z.string().nullable(),success_criteria:x.z.array(x.z.string()).default([]),section:x.z.string().optional()}).passthrough(),Er=x.z.object({phase:x.z.union([x.z.string(),x.z.number()]),plan:x.z.union([x.z.string(),x.z.number()]),type:x.z.string(),wave:x.z.union([x.z.string(),x.z.number()]),depends_on:x.z.union([x.z.string(),x.z.array(x.z.string())]),files_modified:x.z.union([x.z.string(),x.z.array(x.z.string())]),autonomous:x.z.union([x.z.boolean(),x.z.string()]),must_haves:x.z.union([x.z.string(),x.z.array(x.z.string())])}).passthrough(),wr=x.z.object({phase:x.z.union([x.z.string(),x.z.number()]),plan:x.z.union([x.z.string(),x.z.number()]),subsystem:x.z.string(),tags:x.z.union([x.z.string(),x.z.array(x.z.string())]),duration:x.z.string(),completed:x.z.string()}).passthrough(),Mr=x.z.object({phase:x.z.union([x.z.string(),x.z.number()]),verified:x.z.union([x.z.boolean(),x.z.string()]),status:x.z.string(),score:x.z.union([x.z.number(),x.z.string()])}).passthrough(),Hs=x.z.object({test:x.z.number().int().positive().optional(),name:x.z.string(),expected:x.z.string().optional(),result:x.z.string(),category:x.z.string(),reason:x.z.string().optional(),blocked_by:x.z.string().optional()}).passthrough(),Fr=x.z.object({phase:x.z.string(),phase_dir:x.z.string(),file:x.z.string(),file_path:x.z.string(),type:x.z.literal("uat"),status:x.z.string(),items:x.z.array(Hs)}).passthrough(),Bs=x.z.object({branching_strategy:x.z.enum(["none","phase","milestone","workstream"]).default("none"),phase_branch_template:x.z.string().default("gsd/phase-{phase}-{slug}"),milestone_branch_template:x.z.string().default("gsd/{milestone}-{slug}"),quick_branch_template:x.z.string().nullable().default(null)}).passthrough(),Js=x.z.object({research:x.z.boolean().default(!0),plan_check:x.z.boolean().default(!0),verifier:x.z.boolean().default(!0),nyquist_validation:x.z.boolean().default(!0),auto_advance:x.z.boolean().default(!1),node_repair:x.z.boolean().default(!0),node_repair_budget:x.z.number().int().nonnegative().default(2),ui_phase:x.z.boolean().default(!0),ui_safety_gate:x.z.boolean().default(!0),text_mode:x.z.boolean().default(!1),research_before_questions:x.z.boolean().default(!1),discuss_mode:x.z.string().default("discuss"),skip_discuss:x.z.boolean().default(!1),_auto_chain_active:x.z.boolean().default(!1)}).passthrough(),Ys=x.z.object({context_warnings:x.z.boolean().default(!0),workflow_guard:x.z.boolean().default(!1)}).passthrough(),kt=x.z.object({model_profile:x.z.enum(["quality","balanced","budget","inherit"]).default("balanced"),commit_docs:x.z.boolean().default(!0),parallelization:x.z.boolean().default(!0),search_gitignored:x.z.boolean().default(!1),brave_search:x.z.boolean().default(!1),firecrawl:x.z.boolean().default(!1),exa_search:x.z.boolean().default(!1),git:Bs.default({}),workflow:Js.default({}),hooks:Ys.default({}),agent_skills:x.z.record(x.z.string(),x.z.unknown()).default({})}).passthrough()});var Pt={};fe(Pt,{cmdValidateAgents:()=>oi,cmdValidateConsistency:()=>ii,cmdValidateHealth:()=>ri,cmdVerifyArtifacts:()=>ni,cmdVerifyCommits:()=>ti,cmdVerifyKeyLinks:()=>si,cmdVerifyPhaseCompleteness:()=>Xs,cmdVerifyPlanStructure:()=>Qs,cmdVerifyReferences:()=>ei,cmdVerifySummary:()=>Zs});function Ks(n,e){let s=n;for(let i of e){if(s==null||typeof s!="object")return;s=s[i]}return s}function Zs(n,e,s,i){e||S("summary-path required");let t=Y.default.join(n,e),r=s||2;if(!K.default.existsSync(t)){h({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"]},i,"failed");return}let o=K.default.readFileSync(t,"utf-8"),a=[],l=new Set;for(let y of[/`([^`]+\.[a-zA-Z]+)`/g,/(?:Created|Modified|Added|Updated|Edited):\s*`?([^\s`]+\.[a-zA-Z]+)`?/gi]){let g;for(;(g=y.exec(o))!==null;)g[1]&&!g[1].startsWith("http")&&g[1].includes("/")&&l.add(g[1])}let c=Array.from(l).slice(0,r),d=c.filter(y=>!K.default.existsSync(Y.default.join(n,y))),u=o.match(/\b[0-9a-f]{7,40}\b/g)||[],f=!1;for(let y of u.slice(0,3))if(oe(n,["cat-file","-t",y]).stdout==="commit"){f=!0;break}let m="not_found";if(/##\s*(?:Self[- ]?Check|Verification|Quality Check)/i.test(o)){let y=o.slice(o.search(/##\s*(?:Self[- ]?Check|Verification|Quality Check)/i));/(?:fail|✗|❌|incomplete|blocked)/i.test(y)?m="failed":/(?:all\s+)?(?:pass|✓|✅|complete|succeeded)/i.test(y)&&(m="passed")}d.length>0&&a.push("Missing files: "+d.join(", ")),!f&&u.length>0&&a.push("Referenced commit hashes not found in git history"),m==="failed"&&a.push("Self-check section indicates failure");let p=d.length===0&&m!=="failed";h({passed:p,checks:{summary_exists:!0,files_created:{checked:c.length,found:c.length-d.length,missing:d},commits_exist:f,self_check:m},errors:a},i,p?"passed":"failed")}function Qs(n,e,s){e||S("file path required");let i=Y.default.isAbsolute(e)?e:Y.default.join(n,e),t=we(i);if(!t){h({error:"File not found",path:e},s);return}let r=ee(t),o=[],a=[];for(let f of["phase","plan","type","wave","depends_on","files_modified","autonomous","must_haves"])r[f]===void 0&&o.push(`Missing required frontmatter field: ${f}`);let l=/<task[^>]*>([\s\S]*?)<\/task>/g,c=[],d;for(;(d=l.exec(t))!==null;){let f=d[1],m=f.match(/<name>([\s\S]*?)<\/name>/),p=m?m[1].trim():"unnamed",y=/<files>/.test(f),g=/<action>/.test(f),_=/<verify>/.test(f),b=/<done>/.test(f);m||o.push("Task missing <name> element"),g||o.push(`Task '${p}' missing <action>`),_||a.push(`Task '${p}' missing <verify>`),b||a.push(`Task '${p}' missing <done>`),y||a.push(`Task '${p}' missing <files>`),c.push({name:p,hasFiles:y,hasAction:g,hasVerify:_,hasDone:b})}c.length===0&&a.push("No <task> elements found"),r.wave&&parseInt(String(r.wave))>1&&(!r.depends_on||Array.isArray(r.depends_on)&&r.depends_on.length===0)&&a.push("Wave > 1 but depends_on is empty"),/<task\s+type=["']?checkpoint/.test(t)&&r.autonomous!=="false"&&r.autonomous!==!1&&o.push("Has checkpoint tasks but autonomous is not false"),h({valid:o.length===0,errors:o,warnings:a,task_count:c.length,tasks:c,frontmatter_fields:Object.keys(r)},s,o.length===0?"valid":"invalid")}function Xs(n,e,s){e||S("phase required");let i=ue(n,e);if(!i?.found){h({error:"Phase not found",phase:e},s);return}let t=Y.default.join(n,i.directory),r=[],o=[],a;try{a=K.default.readdirSync(t)}catch{h({error:"Cannot read phase directory"},s);return}let l=a.filter(p=>p.match(/-PLAN\.md$/i)),c=a.filter(p=>p.match(/-SUMMARY\.md$/i)),d=new Set(l.map(p=>p.replace(/-PLAN\.md$/i,""))),u=new Set(c.map(p=>p.replace(/-SUMMARY\.md$/i,""))),f=[...d].filter(p=>!u.has(p)),m=[...u].filter(p=>!d.has(p));f.length>0&&r.push(`Plans without summaries: ${f.join(", ")}`),m.length>0&&o.push(`Summaries without plans: ${m.join(", ")}`),h({complete:r.length===0,phase:i.phase_number,plan_count:l.length,summary_count:c.length,incomplete_plans:f,orphan_summaries:m,errors:r,warnings:o},s,r.length===0?"complete":"incomplete")}function ei(n,e,s){e||S("file path required");let i=Y.default.isAbsolute(e)?e:Y.default.join(n,e),t=we(i);if(!t){h({error:"File not found",path:e},s);return}let r=[],o=[];for(let a of t.match(/@([^\s\n,)]+\/[^\s\n,)]+)/g)||[]){let l=a.slice(1),c=l.startsWith("~/")?Y.default.join(process.env.HOME??"",l.slice(2)):Y.default.join(n,l);(K.default.existsSync(c)?r:o).push(l)}for(let a of t.match(/`([^`]+\/[^`]+\.[a-zA-Z]{1,10})`/g)||[]){let l=a.slice(1,-1);l.startsWith("http")||l.includes("${")||l.includes("{{")||r.includes(l)||o.includes(l)||(K.default.existsSync(Y.default.join(n,l))?r:o).push(l)}h({valid:o.length===0,found:r.length,missing:o,total:r.length+o.length},s,o.length===0?"valid":"invalid")}function ti(n,e,s){(!e||e.length===0)&&S("At least one commit hash required");let i=[],t=[];for(let r of e)(oe(n,["cat-file","-t",r]).stdout.trim()==="commit"?i:t).push(r);h({all_valid:t.length===0,valid:i,invalid:t,total:e.length},s,t.length===0?"valid":"invalid")}function ni(n,e,s){e||S("plan file path required");let i=Y.default.isAbsolute(e)?e:Y.default.join(n,e),t=we(i);if(!t){h({error:"File not found",path:e},s);return}let r=St(t,"artifacts");if(r.length===0){h({error:"No must_haves.artifacts found in frontmatter",path:e},s);return}let o=[];for(let l of r){if(typeof l=="string")continue;let c=l;if(!c.path)continue;let d=Y.default.join(n,c.path),u=K.default.existsSync(d),f={path:c.path,exists:u,issues:[],passed:!1};if(u){let m=we(d)??"",p=m.split(`
277
+ `).length;if(c.min_lines&&p<c.min_lines&&f.issues.push(`Only ${p} lines, need ${c.min_lines}`),c.contains&&!m.includes(c.contains)&&f.issues.push(`Missing pattern: ${c.contains}`),c.exports){let y=Array.isArray(c.exports)?c.exports:[c.exports];for(let g of y)m.includes(g)||f.issues.push(`Missing export: ${g}`)}f.passed=f.issues.length===0}else f.issues.push("File not found");o.push(f)}let a=o.filter(l=>l.passed).length;h({all_passed:a===o.length,passed:a,total:o.length,artifacts:o},s,a===o.length?"valid":"invalid")}function si(n,e,s){e||S("plan file path required");let i=Y.default.isAbsolute(e)?e:Y.default.join(n,e),t=we(i);if(!t){h({error:"File not found",path:e},s);return}let r=St(t,"key_links");if(r.length===0){h({error:"No must_haves.key_links found in frontmatter",path:e},s);return}let o=[];for(let l of r){if(typeof l=="string")continue;let c=l,d={from:c.from??"",to:c.to??"",via:c.via||"",verified:!1,detail:""},u=we(Y.default.join(n,c.from||""));if(!u)d.detail="Source file not found";else if(c.pattern)try{let f=new RegExp(c.pattern);if(f.test(u))d.verified=!0,d.detail="Pattern found in source";else{let m=we(Y.default.join(n,c.to||""));m&&f.test(m)?(d.verified=!0,d.detail="Pattern found in target"):d.detail=`Pattern "${c.pattern}" not found in source or target`}}catch{d.detail=`Invalid regex pattern: ${c.pattern}`}else u.includes(c.to||"")?(d.verified=!0,d.detail="Target referenced in source"):d.detail="Target not referenced in source";o.push(d)}let a=o.filter(l=>l.verified).length;h({all_verified:a===o.length,verified:a,total:o.length,links:o},s,a===o.length?"valid":"invalid")}function ii(n,e){let s=Y.default.join(F(n),"ROADMAP.md"),i=Y.default.join(F(n),"phases"),t=[],r=[];if(!K.default.existsSync(s)){t.push("ROADMAP.md not found"),h({passed:!1,errors:t,warnings:r},e,"failed");return}let o=be(K.default.readFileSync(s,"utf-8"),n),a=new Set,l=/#{2,4}\s*Phase\s+(\d+[A-Z]?(?:\.\d+)*)\s*:/gi,c;for(;(c=l.exec(o))!==null;)a.add(c[1]);let d=new Set;try{K.default.readdirSync(i,{withFileTypes:!0}).filter(m=>m.isDirectory()).map(m=>m.name).forEach(m=>{let p=m.match(/^(\d+[A-Z]?(?:\.\d+)*)/i);p&&d.add(p[1])})}catch{}for(let m of a)!d.has(m)&&!d.has(ce(m))&&r.push(`Phase ${m} in ROADMAP.md but no directory on disk`);for(let m of d){let p=String(parseInt(m,10));!a.has(m)&&!a.has(p)&&r.push(`Phase ${m} exists on disk but not in ROADMAP.md`)}if(B(n).phase_naming!=="custom"){let m=[...d].filter(p=>!p.includes(".")).map(p=>parseInt(p,10)).sort((p,y)=>p-y);for(let p=1;p<m.length;p++)m[p]!==m[p-1]+1&&r.push(`Gap in phase numbering: ${m[p-1]} \u2192 ${m[p]}`)}let f=t.length===0;h({passed:f,errors:t,warnings:r,warning_count:r.length},e,f?"passed":"failed")}function ri(n,e,s){let i=Y.default.resolve(n);if(i===_n.default.homedir()){h({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: ${i}`}],repairable_count:0},s);return}let t=F(n),r=J(n),o=Y.default.join(r,"PROJECT.md"),a=Y.default.join(t,"ROADMAP.md"),l=Y.default.join(t,"STATE.md"),c=Y.default.join(r,"config.json"),d=Y.default.join(t,"phases"),u=[],f=[],m=[],p=[],y=(b,v,P,k,$=!1,T)=>{let A={code:v,message:P,fix:k,repairable:$,...T};b==="error"?u.push(A):b==="warning"?f.push(A):m.push(A)};if(!K.default.existsSync(t)){y("error","E001",".planning/ directory not found","Run /gsd-new-project to initialize"),h({status:"broken",errors:u,warnings:f,info:m,repairable_count:0},s);return}if(!K.default.existsSync(o))y("error","E002","PROJECT.md not found","Run /gsd-new-project to create");else{let b=K.default.readFileSync(o,"utf-8");for(let v of["## What This Is","## Core Value","## Requirements"])b.includes(v)||y("warning","W001",`PROJECT.md missing section: ${v}`,"Add section manually")}if(K.default.existsSync(a)||y("error","E003","ROADMAP.md not found","Run /gsd-new-milestone to create roadmap"),!K.default.existsSync(l))y("error","E004","STATE.md not found","Run /gsd-health --repair to regenerate",!0),p.push("regenerateState");else try{let b=K.default.readFileSync(l,"utf-8"),v=ee(b),P=yn.safeParse(v);if(!P.success){for(let k of P.error.issues){let $=k.path.join(".")||"(root)";y("warning","W011",`STATE.md frontmatter: field "${$}" \u2014 ${k.message}`,"Check STATE.md frontmatter manually or run /gsd-health --repair to regenerate",!0)}p.includes("regenerateState")||p.push("regenerateState")}}catch{}if(!K.default.existsSync(c))y("warning","W003","config.json not found","Run /gsd-health --repair to create with defaults",!0),p.push("createConfig");else try{let b=JSON.parse(K.default.readFileSync(c,"utf-8")),v=kt.safeParse(b);if(!v.success){for(let P of v.error.issues){let k=P.path.join(".")||"(root)",$=Ks(b,P.path);y("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:$})}p.includes("fixSchemaDefaults")||p.push("fixSchemaDefaults")}}catch(b){y("error","E005",`config.json: JSON parse error - ${b.message}`,"Run pi-gsd-tools validate health --repair to reset to defaults",!0),p.push("resetConfig")}try{let b=ot();b.agents_installed||y("warning","W010",b.installed_agents.length===0?`No GSD agents found in ${b.agents_dir}`:`Missing ${b.missing_agents.length} GSD agents: ${b.missing_agents.join(", ")}`,"Run the GSD installer: pi install npm:pi-gsd")}catch{}let g=[];if(e.repair&&p.length>0)for(let b of p)try{if(b==="createConfig"||b==="resetConfig"){let v=kt.parse({});K.default.writeFileSync(c,JSON.stringify(v,null,2),"utf-8"),g.push({action:b,success:!0,path:"config.json"})}else if(b==="fixSchemaDefaults"&&K.default.existsSync(c)){let v=JSON.parse(K.default.readFileSync(c,"utf-8")),P=kt.parse(v);K.default.writeFileSync(c,JSON.stringify(P,null,2),"utf-8"),g.push({action:b,success:!0,path:"config.json"})}else if(b==="regenerateState"){if(K.default.existsSync(l)){let P=new Date().toISOString().replace(/[:.]/g,"-").slice(0,19),k=`${l}.bak-${P}`;K.default.copyFileSync(l,k),g.push({action:"backupState",success:!0,path:k})}let v=ie(n);te(l,`# Session State
278
278
 
279
279
  ## Project Reference
280
280
 
@@ -289,15 +289,15 @@ See: .planning/PROJECT.md
289
289
  ## Session Log
290
290
 
291
291
  - ${new Date().toISOString().split("T")[0]}: STATE.md regenerated by /gsd-health --repair
292
- `,n),g.push({action:b,success:!0,path:"STATE.md"})}}catch(v){g.push({action:b,success:!1,error:v.message})}let _=u.length>0?"broken":p.length>0?"degraded":"healthy";h({status:_,errors:u,warnings:p,info:m,repairable_count:u.filter(b=>b.repairable).length+p.filter(b=>b.repairable).length,repairs_performed:g.length>0?g:void 0},s)}function oi(n,e){let s=ot();h({agents_dir:s.agents_dir,agents_found:s.agents_installed,installed:s.installed_agents,missing:s.missing_agents,expected:Object.keys(je)},e)}var K,_n,Y,$t=le(()=>{"use strict";K=W(require("fs")),_n=W(require("os")),Y=W(require("path"));fe();Ue();Sn();Be()});var bn={};pe(bn,{cmdTemplateFill:()=>li,cmdTemplateSelect:()=>ai});function ai(n,e,s){e||S("plan-path required");try{let i=mt.default.join(n,e),t=At.default.readFileSync(i,"utf-8"),r=(t.match(/###\s*Task\s*\d+/g)||[]).length,o=(t.match(/decision/gi)||[]).length>0,a=new Set,l=/`([^`]+\.[a-zA-Z]+)`/g,c;for(;(c=l.exec(t))!==null;)c[1].includes("/")&&!c[1].startsWith("http")&&a.add(c[1]);let d=a.size,u="templates/summary-standard.md",p="standard";r<=2&&d<=3&&!o?(u="templates/summary-minimal.md",p="minimal"):(o||d>6||r>5)&&(u="templates/summary-complex.md",p="complex"),h({template:u,type:p,taskCount:r,fileCount:d,hasDecisions:o},s,u)}catch(i){h({template:"templates/summary-standard.md",type:"standard",error:i.message},s,"templates/summary-standard.md")}}function li(n,e,s,i){e||S("template type required: summary, plan, or verification"),s.phase||S("--phase required");let t=ue(n,s.phase);if(!t||!t.found){h({error:"Phase not found",phase:s.phase},i);return}let r=ce(s.phase),o=new Date().toISOString().split("T")[0],a=s.name||t.phase_name||"Unnamed",l=t.phase_slug||Te(a),c=`${r}-${l}`,d=(s.plan||"01").padStart(2,"0"),u=s.fields||{},p,m,f;switch(e){case"summary":p={phase:c,plan:d,subsystem:"[primary category]",tags:[],provides:[],affects:[],"tech-stack":{added:[],patterns:[]},"key-files":{created:[],modified:[]},"key-decisions":[],"patterns-established":[],duration:"[X]min",completed:o,...u},m=[`# Phase ${s.phase}: ${a} Summary`,"","**[Substantive one-liner describing outcome]**","","## Performance","- **Duration:** [time]","- **Tasks:** [count completed]","- **Files modified:** [count]","","## Accomplishments","- [Key outcome 1]","- [Key outcome 2]","","## Task Commits","1. **Task 1: [task name]** - `hash`","","## Files Created/Modified","- `path/to/file.ts` - What it does","","## Decisions & Deviations",'[Key decisions or "None - followed plan as specified"]',"","## Next Phase Readiness","[What's ready for next phase]"].join(`
293
- `),f=`${r}-${d}-SUMMARY.md`;break;case"plan":p={phase:c,plan:d,type:s.type||"execute",wave:parseInt(s.wave||"1"),depends_on:[],files_modified:[],autonomous:!0,user_setup:[],must_haves:{truths:[],artifacts:[],key_links:[]},...u},m=[`# Phase ${s.phase} Plan ${d}: [Title]`,"","## Objective","- **What:** [What this plan builds]","- **Why:** [Why it matters for the phase goal]","- **Output:** [Concrete deliverable]","","## Context","@.planning/PROJECT.md","@.planning/ROADMAP.md","@.planning/STATE.md","","## Tasks","",'<task type="code">'," <name>[Task name]</name>"," <files>[file paths]</files>"," <action>[What to do]</action>"," <verify>[How to verify]</verify>"," <done>[Definition of done]</done>","</task>","","## Verification","[How to verify this plan achieved its objective]","","## Success Criteria","- [ ] [Criterion 1]","- [ ] [Criterion 2]"].join(`
294
- `),f=`${r}-${d}-PLAN.md`;break;case"verification":p={phase:c,verified:new Date().toISOString(),status:"pending",score:"0/0 must-haves verified",...u},m=[`# Phase ${s.phase}: ${a} - Verification`,"","## Observable Truths","| # | Truth | Status | Evidence |","|---|-------|--------|----------|","| 1 | [Truth] | pending | |","","## Required Artifacts","| Artifact | Expected | Status | Details |","|----------|----------|--------|---------|","| [path] | [what] | pending | |","","## Key Link Verification","| From | To | Via | Status | Details |","|------|----|----|--------|---------|","| [source] | [target] | [connection] | pending | |","","## Requirements Coverage","| Requirement | Status | Blocking Issue |","|-------------|--------|----------------|","| [req] | pending | |","","## Result","[Pending verification]"].join(`
295
- `),f=`${r}-VERIFICATION.md`;break;default:S(`Unknown template type: ${e}. Available: summary, plan, verification`);return}let y=`---
296
- ${Xe(p)}
292
+ `,n),g.push({action:b,success:!0,path:"STATE.md"})}}catch(v){g.push({action:b,success:!1,error:v.message})}let _=u.length>0?"broken":f.length>0?"degraded":"healthy";h({status:_,errors:u,warnings:f,info:m,repairable_count:u.filter(b=>b.repairable).length+f.filter(b=>b.repairable).length,repairs_performed:g.length>0?g:void 0},s)}function oi(n,e){let s=ot();h({agents_dir:s.agents_dir,agents_found:s.agents_installed,installed:s.installed_agents,missing:s.missing_agents,expected:Object.keys(je)},e)}var K,_n,Y,$t=le(()=>{"use strict";K=W(require("fs")),_n=W(require("os")),Y=W(require("path"));pe();Ue();Sn();Be()});var bn={};fe(bn,{cmdTemplateFill:()=>li,cmdTemplateSelect:()=>ai});function ai(n,e,s){e||S("plan-path required");try{let i=mt.default.join(n,e),t=At.default.readFileSync(i,"utf-8"),r=(t.match(/###\s*Task\s*\d+/g)||[]).length,o=(t.match(/decision/gi)||[]).length>0,a=new Set,l=/`([^`]+\.[a-zA-Z]+)`/g,c;for(;(c=l.exec(t))!==null;)c[1].includes("/")&&!c[1].startsWith("http")&&a.add(c[1]);let d=a.size,u="templates/summary-standard.md",f="standard";r<=2&&d<=3&&!o?(u="templates/summary-minimal.md",f="minimal"):(o||d>6||r>5)&&(u="templates/summary-complex.md",f="complex"),h({template:u,type:f,taskCount:r,fileCount:d,hasDecisions:o},s,u)}catch(i){h({template:"templates/summary-standard.md",type:"standard",error:i.message},s,"templates/summary-standard.md")}}function li(n,e,s,i){e||S("template type required: summary, plan, or verification"),s.phase||S("--phase required");let t=ue(n,s.phase);if(!t||!t.found){h({error:"Phase not found",phase:s.phase},i);return}let r=ce(s.phase),o=new Date().toISOString().split("T")[0],a=s.name||t.phase_name||"Unnamed",l=t.phase_slug||De(a),c=`${r}-${l}`,d=(s.plan||"01").padStart(2,"0"),u=s.fields||{},f,m,p;switch(e){case"summary":f={phase:c,plan:d,subsystem:"[primary category]",tags:[],provides:[],affects:[],"tech-stack":{added:[],patterns:[]},"key-files":{created:[],modified:[]},"key-decisions":[],"patterns-established":[],duration:"[X]min",completed:o,...u},m=[`# Phase ${s.phase}: ${a} Summary`,"","**[Substantive one-liner describing outcome]**","","## Performance","- **Duration:** [time]","- **Tasks:** [count completed]","- **Files modified:** [count]","","## Accomplishments","- [Key outcome 1]","- [Key outcome 2]","","## Task Commits","1. **Task 1: [task name]** - `hash`","","## Files Created/Modified","- `path/to/file.ts` - What it does","","## Decisions & Deviations",'[Key decisions or "None - followed plan as specified"]',"","## Next Phase Readiness","[What's ready for next phase]"].join(`
293
+ `),p=`${r}-${d}-SUMMARY.md`;break;case"plan":f={phase:c,plan:d,type:s.type||"execute",wave:parseInt(s.wave||"1"),depends_on:[],files_modified:[],autonomous:!0,user_setup:[],must_haves:{truths:[],artifacts:[],key_links:[]},...u},m=[`# Phase ${s.phase} Plan ${d}: [Title]`,"","## Objective","- **What:** [What this plan builds]","- **Why:** [Why it matters for the phase goal]","- **Output:** [Concrete deliverable]","","## Context","@.planning/PROJECT.md","@.planning/ROADMAP.md","@.planning/STATE.md","","## Tasks","",'<task type="code">'," <name>[Task name]</name>"," <files>[file paths]</files>"," <action>[What to do]</action>"," <verify>[How to verify]</verify>"," <done>[Definition of done]</done>","</task>","","## Verification","[How to verify this plan achieved its objective]","","## Success Criteria","- [ ] [Criterion 1]","- [ ] [Criterion 2]"].join(`
294
+ `),p=`${r}-${d}-PLAN.md`;break;case"verification":f={phase:c,verified:new Date().toISOString(),status:"pending",score:"0/0 must-haves verified",...u},m=[`# Phase ${s.phase}: ${a} - Verification`,"","## Observable Truths","| # | Truth | Status | Evidence |","|---|-------|--------|----------|","| 1 | [Truth] | pending | |","","## Required Artifacts","| Artifact | Expected | Status | Details |","|----------|----------|--------|---------|","| [path] | [what] | pending | |","","## Key Link Verification","| From | To | Via | Status | Details |","|------|----|----|--------|---------|","| [source] | [target] | [connection] | pending | |","","## Requirements Coverage","| Requirement | Status | Blocking Issue |","|-------------|--------|----------------|","| [req] | pending | |","","## Result","[Pending verification]"].join(`
295
+ `),p=`${r}-VERIFICATION.md`;break;default:S(`Unknown template type: ${e}. Available: summary, plan, verification`);return}let y=`---
296
+ ${Xe(f)}
297
297
  ---
298
298
 
299
299
  ${m}
300
- `,g=mt.default.join(n,t.directory,f);if(At.default.existsSync(g)){h({error:"File already exists",path:z(mt.default.relative(n,g))},i);return}At.default.writeFileSync(g,Re(y),"utf-8");let _=z(mt.default.relative(n,g));h({created:!0,path:_,template:e},i,_)}var At,mt,xn=le(()=>{"use strict";At=W(require("fs")),mt=W(require("path"));fe();Ue()});var et={};pe(et,{cmdConfigEnsureSection:()=>pi,cmdConfigGet:()=>hi,cmdConfigNewProject:()=>mi,cmdConfigSet:()=>fi,cmdConfigSetModelProfile:()=>gi,ensureConfigFile:()=>Gt,setConfigValue:()=>zt});function di(n){return!!(kn.has(n)||/^agent_skills\.[a-zA-Z0-9_-]+$/.test(n))}function ui(n){let e=ci[n];e&&S(`Unknown config key: ${n}. Did you mean ${e}?`)}function Pn(n){let e=n||{},s=vn.default.homedir(),i=Ge.default.join(s,".gsd","brave_api_key"),t=!!(process.env.BRAVE_API_KEY||re.default.existsSync(i)),r=Ge.default.join(s,".gsd","firecrawl_api_key"),o=!!(process.env.FIRECRAWL_API_KEY||re.default.existsSync(r)),a=Ge.default.join(s,".gsd","exa_api_key"),l=!!(process.env.EXA_API_KEY||re.default.existsSync(a)),c=Ge.default.join(s,".gsd","defaults.json"),d={};try{if(re.default.existsSync(c)&&(d=JSON.parse(re.default.readFileSync(c,"utf-8")),"depth"in d&&!("granularity"in d))){let p={quick:"coarse",standard:"standard",comprehensive:"fine"};d.granularity=p[d.depth]||d.depth,delete d.depth;try{re.default.writeFileSync(c,JSON.stringify(d,null,2),"utf-8")}catch{}}}catch{}let u={model_profile:"balanced",commit_docs:!0,parallelization:!0,search_gitignored:!1,brave_search:t,firecrawl:o,exa_search:l,git:{branching_strategy:"none",phase_branch_template:"gsd/phase-{phase}-{slug}",milestone_branch_template:"gsd/{milestone}-{slug}",quick_branch_template:null},workflow:{research:!0,plan_check:!0,verifier:!0,nyquist_validation:!0,auto_advance:!1,node_repair:!0,node_repair_budget:2,ui_phase:!0,ui_safety_gate:!0,text_mode:!1,research_before_questions:!1,discuss_mode:"discuss",skip_discuss:!1},hooks:{context_warnings:!0},agent_skills:{}};return{...u,...d,...e,git:{...u.git,...d.git||{},...e.git||{}},workflow:{...u.workflow,...d.workflow||{},...e.workflow||{}},hooks:{...u.hooks,...d.hooks||{},...e.hooks||{}},agent_skills:{...u.agent_skills,...d.agent_skills||{},...e.agent_skills||{}}}}function Gt(n){let e=J(n),s=Ge.default.join(e,"config.json");try{re.default.existsSync(e)||re.default.mkdirSync(e,{recursive:!0})}catch(t){S("Failed to create .planning directory: "+t.message)}if(re.default.existsSync(s))return{created:!1,reason:"already_exists"};let i=Pn({});try{return re.default.writeFileSync(s,JSON.stringify(i,null,2),"utf-8"),{created:!0,path:".planning/config.json"}}catch(t){S("Failed to create config.json: "+t.message)}}function zt(n,e,s){let i=Ge.default.join(J(n),"config.json"),t={};try{re.default.existsSync(i)&&(t=JSON.parse(re.default.readFileSync(i,"utf-8")))}catch(l){S("Failed to read config.json: "+l.message)}let r=e.split("."),o=t;for(let l=0;l<r.length-1;l++){let c=r[l];(o[c]===void 0||typeof o[c]!="object")&&(o[c]={}),o=o[c]}let a=o[r[r.length-1]];o[r[r.length-1]]=s;try{return re.default.writeFileSync(i,JSON.stringify(t,null,2),"utf-8"),{updated:!0,key:e,value:s,previousValue:a}}catch(l){S("Failed to write config.json: "+l.message)}}function mi(n,e,s){let i=J(n),t=Ge.default.join(i,"config.json");if(re.default.existsSync(t)){h({created:!1,reason:"already_exists"},s,"exists");return}let r={};if(e&&e.trim())try{r=JSON.parse(e)}catch(a){S("Invalid JSON for config-new-project: "+a.message)}try{re.default.existsSync(i)||re.default.mkdirSync(i,{recursive:!0})}catch(a){S("Failed to create .planning directory: "+a.message)}let o=Pn(r);try{re.default.writeFileSync(t,JSON.stringify(o,null,2),"utf-8"),h({created:!0,path:".planning/config.json"},s,"created")}catch(a){S("Failed to write config.json: "+a.message)}}function pi(n,e){let s=Gt(n);h(s,e,s?.created?"created":"exists")}function fi(n,e,s,i){e||S("Usage: config-set <key.path> <value>"),ui(e),di(e)||S(`Unknown config key: "${e}". Valid keys: ${[...kn].sort().join(", ")}, agent_skills.<agent-type>`);let t=s;if(s==="true")t=!0;else if(s==="false")t=!1;else if(s!==void 0&&!isNaN(Number(s))&&s!=="")t=Number(s);else if(typeof s=="string"&&(s.startsWith("[")||s.startsWith("{")))try{t=JSON.parse(s)}catch{}let r=zt(n,e,t);h(r,i,`${e}=${t}`)}function hi(n,e,s){e||S("Usage: config-get <key.path>");let i=Ge.default.join(J(n),"config.json"),t={};try{re.default.existsSync(i)?t=JSON.parse(re.default.readFileSync(i,"utf-8")):S("No config.json found at "+i)}catch(a){if(a.message.startsWith("Error:"))throw a;S("Failed to read config.json: "+a.message)}let r=e.split("."),o=t;for(let a of r)(o==null||typeof o!="object")&&S(`Key not found: ${e}`),o=o[a];o===void 0&&S(`Key not found: ${e}`),h(o,s,String(o))}function gi(n,e,s){e||S(`Usage: config-set-model-profile <${Je.join("|")}>`);let i=e.toLowerCase().trim();Je.includes(i)||S(`Invalid profile '${e}'. Valid profiles: ${Je.join(", ")}`),Gt(n);let r=zt(n,"model_profile",i)?.previousValue||"balanced",o=Mt(i),a=Ft(o),c=r!==i?`\u2713 Model profile set to: ${i} (was: ${r})
300
+ `,g=mt.default.join(n,t.directory,p);if(At.default.existsSync(g)){h({error:"File already exists",path:z(mt.default.relative(n,g))},i);return}At.default.writeFileSync(g,Re(y),"utf-8");let _=z(mt.default.relative(n,g));h({created:!0,path:_,template:e},i,_)}var At,mt,xn=le(()=>{"use strict";At=W(require("fs")),mt=W(require("path"));pe();Ue()});var et={};fe(et,{cmdConfigEnsureSection:()=>fi,cmdConfigGet:()=>hi,cmdConfigNewProject:()=>mi,cmdConfigSet:()=>pi,cmdConfigSetModelProfile:()=>gi,ensureConfigFile:()=>Gt,setConfigValue:()=>zt});function di(n){return!!(kn.has(n)||/^agent_skills\.[a-zA-Z0-9_-]+$/.test(n))}function ui(n){let e=ci[n];e&&S(`Unknown config key: ${n}. Did you mean ${e}?`)}function Pn(n){let e=n||{},s=vn.default.homedir(),i=Ge.default.join(s,".gsd","brave_api_key"),t=!!(process.env.BRAVE_API_KEY||re.default.existsSync(i)),r=Ge.default.join(s,".gsd","firecrawl_api_key"),o=!!(process.env.FIRECRAWL_API_KEY||re.default.existsSync(r)),a=Ge.default.join(s,".gsd","exa_api_key"),l=!!(process.env.EXA_API_KEY||re.default.existsSync(a)),c=Ge.default.join(s,".gsd","defaults.json"),d={};try{if(re.default.existsSync(c)&&(d=JSON.parse(re.default.readFileSync(c,"utf-8")),"depth"in d&&!("granularity"in d))){let f={quick:"coarse",standard:"standard",comprehensive:"fine"};d.granularity=f[d.depth]||d.depth,delete d.depth;try{re.default.writeFileSync(c,JSON.stringify(d,null,2),"utf-8")}catch{}}}catch{}let u={model_profile:"balanced",commit_docs:!0,parallelization:!0,search_gitignored:!1,brave_search:t,firecrawl:o,exa_search:l,git:{branching_strategy:"none",phase_branch_template:"gsd/phase-{phase}-{slug}",milestone_branch_template:"gsd/{milestone}-{slug}",quick_branch_template:null},workflow:{research:!0,plan_check:!0,verifier:!0,nyquist_validation:!0,auto_advance:!1,node_repair:!0,node_repair_budget:2,ui_phase:!0,ui_safety_gate:!0,text_mode:!1,research_before_questions:!1,discuss_mode:"discuss",skip_discuss:!1},hooks:{context_warnings:!0},agent_skills:{}};return{...u,...d,...e,git:{...u.git,...d.git||{},...e.git||{}},workflow:{...u.workflow,...d.workflow||{},...e.workflow||{}},hooks:{...u.hooks,...d.hooks||{},...e.hooks||{}},agent_skills:{...u.agent_skills,...d.agent_skills||{},...e.agent_skills||{}}}}function Gt(n){let e=J(n),s=Ge.default.join(e,"config.json");try{re.default.existsSync(e)||re.default.mkdirSync(e,{recursive:!0})}catch(t){S("Failed to create .planning directory: "+t.message)}if(re.default.existsSync(s))return{created:!1,reason:"already_exists"};let i=Pn({});try{return re.default.writeFileSync(s,JSON.stringify(i,null,2),"utf-8"),{created:!0,path:".planning/config.json"}}catch(t){S("Failed to create config.json: "+t.message)}}function zt(n,e,s){let i=Ge.default.join(J(n),"config.json"),t={};try{re.default.existsSync(i)&&(t=JSON.parse(re.default.readFileSync(i,"utf-8")))}catch(l){S("Failed to read config.json: "+l.message)}let r=e.split("."),o=t;for(let l=0;l<r.length-1;l++){let c=r[l];(o[c]===void 0||typeof o[c]!="object")&&(o[c]={}),o=o[c]}let a=o[r[r.length-1]];o[r[r.length-1]]=s;try{return re.default.writeFileSync(i,JSON.stringify(t,null,2),"utf-8"),{updated:!0,key:e,value:s,previousValue:a}}catch(l){S("Failed to write config.json: "+l.message)}}function mi(n,e,s){let i=J(n),t=Ge.default.join(i,"config.json");if(re.default.existsSync(t)){h({created:!1,reason:"already_exists"},s,"exists");return}let r={};if(e&&e.trim())try{r=JSON.parse(e)}catch(a){S("Invalid JSON for config-new-project: "+a.message)}try{re.default.existsSync(i)||re.default.mkdirSync(i,{recursive:!0})}catch(a){S("Failed to create .planning directory: "+a.message)}let o=Pn(r);try{re.default.writeFileSync(t,JSON.stringify(o,null,2),"utf-8"),h({created:!0,path:".planning/config.json"},s,"created")}catch(a){S("Failed to write config.json: "+a.message)}}function fi(n,e){let s=Gt(n);h(s,e,s?.created?"created":"exists")}function pi(n,e,s,i){e||S("Usage: config-set <key.path> <value>"),ui(e),di(e)||S(`Unknown config key: "${e}". Valid keys: ${[...kn].sort().join(", ")}, agent_skills.<agent-type>`);let t=s;if(s==="true")t=!0;else if(s==="false")t=!1;else if(s!==void 0&&!isNaN(Number(s))&&s!=="")t=Number(s);else if(typeof s=="string"&&(s.startsWith("[")||s.startsWith("{")))try{t=JSON.parse(s)}catch{}let r=zt(n,e,t);h(r,i,`${e}=${t}`)}function hi(n,e,s){e||S("Usage: config-get <key.path>");let i=Ge.default.join(J(n),"config.json"),t={};try{re.default.existsSync(i)?t=JSON.parse(re.default.readFileSync(i,"utf-8")):S("No config.json found at "+i)}catch(a){if(a.message.startsWith("Error:"))throw a;S("Failed to read config.json: "+a.message)}let r=e.split("."),o=t;for(let a of r)(o==null||typeof o!="object")&&S(`Key not found: ${e}`),o=o[a];o===void 0&&S(`Key not found: ${e}`),h(o,s,String(o))}function gi(n,e,s){e||S(`Usage: config-set-model-profile <${Je.join("|")}>`);let i=e.toLowerCase().trim();Je.includes(i)||S(`Invalid profile '${e}'. Valid profiles: ${Je.join(", ")}`),Gt(n);let r=zt(n,"model_profile",i)?.previousValue||"balanced",o=Mt(i),a=Ft(o),c=r!==i?`\u2713 Model profile set to: ${i} (was: ${r})
301
301
 
302
302
  Agents will now use:
303
303
 
@@ -306,8 +306,8 @@ Next spawned agents will use the new profile.`:`\u2713 Model profile is already
306
306
 
307
307
  Agents are using:
308
308
 
309
- ${a}`;h({updated:!0,profile:i,previousProfile:r,agentToModelMap:o},s,c)}var re,vn,Ge,kn,ci,tt=le(()=>{"use strict";re=W(require("fs")),vn=W(require("os")),Ge=W(require("path"));fe();rt();kn=new Set(["mode","granularity","parallelization","commit_docs","model_profile","search_gitignored","brave_search","firecrawl","exa_search","workflow.research","workflow.plan_check","workflow.verifier","workflow.nyquist_validation","workflow.ui_phase","workflow.ui_safety_gate","workflow.auto_advance","workflow.node_repair","workflow.node_repair_budget","workflow.text_mode","workflow.research_before_questions","workflow.discuss_mode","workflow.skip_discuss","workflow._auto_chain_active","git.branching_strategy","git.phase_branch_template","git.milestone_branch_template","git.quick_branch_template","planning.commit_docs","planning.search_gitignored","hooks.context_warnings"]),ci={"workflow.nyquist_validation_enabled":"workflow.nyquist_validation","agents.nyquist_validation_enabled":"workflow.nyquist_validation","nyquist.validation_enabled":"workflow.nyquist_validation","hooks.research_questions":"workflow.research_before_questions","workflow.research_questions":"workflow.research_before_questions"}});var Vt={};pe(Vt,{cmdAgentSkills:()=>Mi,cmdInitExecutePhase:()=>yi,cmdInitListWorkspaces:()=>Ei,cmdInitManager:()=>Ci,cmdInitMapCodebase:()=>ji,cmdInitMilestoneOp:()=>Ai,cmdInitNewMilestone:()=>bi,cmdInitNewProject:()=>_i,cmdInitNewWorkspace:()=>Ii,cmdInitPhaseOp:()=>Pi,cmdInitPlanPhase:()=>Si,cmdInitProgress:()=>Ri,cmdInitQuick:()=>xi,cmdInitRemoveWorkspace:()=>wi,cmdInitResume:()=>vi,cmdInitTodos:()=>$i,cmdInitVerifyWork:()=>ki});function $n(n){let e=$e.default.join(J(n),"MILESTONES.md");if(!U.default.existsSync(e))return null;try{let i=U.default.readFileSync(e,"utf-8").match(/^##\s+(v[\d.]+)\s+(.+?)\s+\(Shipped:/m);return i?{version:i[1],name:i[2].trim()}:null}catch{return null}}function ae(n,e){e.project_root=n,e.gsd_bin="dist/gsd-tools.js",e.gsd_root=".",e.gsd_harness_dir=".";let s=ot();return e.agents_installed=s.agents_installed,e.missing_agents=s.missing_agents,e}function yi(n,e,s){e||S("phase required for init execute-phase");let i=B(n),t=ue(n,e),r=ie(n),o=Qe(n,e);if(!t&&o?.found){let d=o.phase_name;t={found:!0,directory:null,phase_number:o.phase_number,phase_name:d,phase_slug:d?d.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,""):null,plans:[],summaries:[],incomplete_plans:[],has_research:!1,has_context:!1,has_verification:!1,has_reviews:!1}}let a=o?.section?.match(/^\*\*Requirements\*\*:[^\S\n]*([^\n]*)$/m),l=a?a[1].replace(/[[\]]/g,"").split(",").map(d=>d.trim()).filter(Boolean).join(", "):null,c=ae(n,{executor_model:X(n,"gsd-executor"),verifier_model:X(n,"gsd-verifier"),commit_docs:i.commit_docs,sub_repos:i.sub_repos,parallelization:i.parallelization,context_window:i.context_window,branching_strategy:i.branching_strategy,phase_branch_template:i.phase_branch_template,milestone_branch_template:i.milestone_branch_template,verifier_enabled:i.verifier,phase_found:!!t,phase_dir:t?.directory??null,phase_number:t?.phase_number??null,phase_name:t?.phase_name??null,phase_slug:t?.phase_slug??null,phase_req_ids:l&&l!=="TBD"?l:null,plans:t?.plans??[],summaries:t?.summaries??[],incomplete_plans:t?.incomplete_plans??[],has_research:t?.has_research??!1,has_context:t?.has_context??!1,has_verification:t?.has_verification??!1,has_reviews:t?.has_reviews??!1,roadmap_goal:o?.goal??null,roadmap_section:o?.section??null,milestone_version:r.version,milestone_name:r.name});h(c,s)}function Si(n,e,s){e||S("phase required for init plan-phase");let i=B(n),t=ue(n,e),r=Qe(n,e),o=ie(n),a=ae(n,{planner_model:X(n,"gsd-planner"),researcher_model:X(n,"gsd-phase-researcher"),synthesizer_model:X(n,"gsd-research-synthesizer"),commit_docs:i.commit_docs,research_enabled:i.research,plan_checker_enabled:i.plan_checker,context_window:i.context_window,phase_found:!!t,phase_dir:t?.directory??null,phase_number:t?.phase_number??null,phase_name:t?.phase_name??null,roadmap_goal:r?.goal??null,roadmap_section:r?.section??null,milestone_version:o.version,milestone_name:o.name});h(a,s)}function _i(n,e){let s=B(n),i=J(n),t=ae(n,{planner_model:X(n,"gsd-planner"),roadmapper_model:X(n,"gsd-roadmapper"),commit_docs:s.commit_docs,context_window:s.context_window,planning_exists:U.default.existsSync(i),project_exists:U.default.existsSync($e.default.join(i,"PROJECT.md")),config_exists:U.default.existsSync($e.default.join(i,"config.json")),roadmap_exists:U.default.existsSync($e.default.join(i,"ROADMAP.md")),state_exists:U.default.existsSync($e.default.join(i,"STATE.md"))});h(t,e)}function bi(n,e){let s=B(n),i=ie(n),t=$n(n),r=ae(n,{roadmapper_model:X(n,"gsd-roadmapper"),commit_docs:s.commit_docs,context_window:s.context_window,current_milestone:i,last_completed_milestone:t,roadmap_exists:U.default.existsSync(R(n).roadmap)});h(r,e)}function xi(n,e,s){let i=B(n),t=ie(n),r=ae(n,{executor_model:X(n,"gsd-executor"),commit_docs:i.commit_docs,context_window:i.context_window,branching_strategy:i.branching_strategy,quick_branch_template:i.quick_branch_template,description:e||null,milestone_version:t.version,milestone_name:t.name,state_exists:U.default.existsSync(R(n).state)});h(r,s)}function vi(n,e){let s=B(n),i=ie(n),t=U.default.existsSync(R(n).state),r="";if(t)try{r=U.default.readFileSync(R(n).state,"utf-8")}catch{}let o=ae(n,{executor_model:X(n,"gsd-executor"),commit_docs:s.commit_docs,context_window:s.context_window,state_exists:t,state_raw:r,roadmap_exists:U.default.existsSync(R(n).roadmap),config_exists:U.default.existsSync(R(n).config),milestone_version:i.version,milestone_name:i.name});h(o,e)}function ki(n,e,s){e||S("phase required for init verify-work");let i=B(n),t=ue(n,e),r=Qe(n,e),o=ae(n,{verifier_model:X(n,"gsd-verifier"),nyquist_model:X(n,"gsd-nyquist-auditor"),commit_docs:i.commit_docs,nyquist_validation:i.nyquist_validation,context_window:i.context_window,phase_found:!!t,phase_dir:t?.directory??null,phase_number:t?.phase_number??null,phase_name:t?.phase_name??null,plans:t?.plans??[],summaries:t?.summaries??[],roadmap_goal:r?.goal??null});h(o,s)}function Pi(n,e,s){let i=B(n),t=e?ue(n,e):null,r=ie(n),o=ae(n,{planner_model:X(n,"gsd-planner"),commit_docs:i.commit_docs,context_window:i.context_window,phase_found:!!t,phase_dir:t?.directory??null,phase_number:t?.phase_number??null,phase_name:t?.phase_name??null,milestone_version:r.version,milestone_name:r.name});h(o,s)}function $i(n,e,s){let i=B(n),t=$e.default.join(F(n),"todos","pending"),r=[];if(U.default.existsSync(t))try{for(let a of U.default.readdirSync(t).filter(l=>l.endsWith(".md")))try{let l=U.default.readFileSync($e.default.join(t,a),"utf-8"),c=l.match(/^title:\s*(.+)$/m),d=l.match(/^area:\s*(.+)$/m),u=d?d[1].trim():"general";if(e&&u!==e)continue;r.push({file:a,title:c?c[1].trim():"Untitled",area:u})}catch{}}catch{}let o=ae(n,{executor_model:X(n,"gsd-executor"),commit_docs:i.commit_docs,todos:r,todo_count:r.length,area:e??null});h(o,s)}function Ai(n,e){let s=B(n),i=ie(n),t=$n(n),r=ae(n,{planner_model:X(n,"gsd-planner"),commit_docs:s.commit_docs,context_window:s.context_window,milestone_version:i.version,milestone_name:i.name,last_completed_milestone:t,roadmap_exists:U.default.existsSync(R(n).roadmap),state_exists:U.default.existsSync(R(n).state)});h(r,e)}function ji(n,e){let s=B(n),i=ae(n,{mapper_model:X(n,"gsd-codebase-mapper"),commit_docs:s.commit_docs,search_gitignored:s.search_gitignored,context_window:s.context_window,project_exists:U.default.existsSync($e.default.join(J(n),"PROJECT.md"))});h(i,e)}function Ri(n,e){let s=B(n),i=ie(n),t=Pe(n),r=R(n).phases,o=0,a=0,l=0;if(U.default.existsSync(r))try{let d=U.default.readdirSync(r,{withFileTypes:!0}).filter(u=>u.isDirectory()).map(u=>u.name).filter(t);l=d.length;for(let u of d){let p=U.default.readdirSync($e.default.join(r,u));o+=p.filter(m=>m.match(/-PLAN\.md$/i)).length,a+=p.filter(m=>m.match(/-SUMMARY\.md$/i)).length}}catch{}let c=ae(n,{commit_docs:s.commit_docs,context_window:s.context_window,milestone_version:i.version,milestone_name:i.name,phase_count:l,total_plans:o,total_summaries:a,percent:o>0?Math.min(100,Math.round(a/o*100)):0});h(c,e)}function Ci(n,e){let s=B(n),i=ie(n),t=ae(n,{planner_model:X(n,"gsd-planner"),roadmapper_model:X(n,"gsd-roadmapper"),commit_docs:s.commit_docs,context_window:s.context_window,milestone_version:i.version,milestone_name:i.name,state_exists:U.default.existsSync(R(n).state),roadmap_exists:U.default.existsSync(R(n).roadmap)});h(t,e)}function Ii(n,e){let s=B(n),i=$e.default.join(J(n),"workstreams"),t=ae(n,{commit_docs:s.commit_docs,context_window:s.context_window,workstream_mode:U.default.existsSync(i),workstreams:U.default.existsSync(i)?U.default.readdirSync(i,{withFileTypes:!0}).filter(r=>r.isDirectory()).map(r=>r.name):[]});h(t,e)}function Ei(n,e){let s=$e.default.join(J(n),"workstreams");if(!U.default.existsSync(s)){h(ae(n,{mode:"flat",workstreams:[],count:0}),e);return}let i=U.default.readdirSync(s,{withFileTypes:!0}).filter(t=>t.isDirectory()).map(t=>t.name);h(ae(n,{mode:"workstream",workstreams:i,count:i.length}),e)}function wi(n,e,s){e||S("workstream name required for init remove-workspace");let i=$e.default.join(J(n),"workstreams",e);if(!U.default.existsSync(i)){h(ae(n,{removed:!1,reason:"not_found",workstream:e}),s);return}try{U.default.rmSync(i,{recursive:!0,force:!0})}catch(t){h(ae(n,{removed:!1,reason:t.message,workstream:e}),s);return}h(ae(n,{removed:!0,workstream:e}),s)}function Mi(n,e,s){e||S("agent-type required");let t=B(n).agent_skills[e]??{};h({agent:e,skills:t},s,JSON.stringify(t))}var U,$e,Ht=le(()=>{"use strict";U=W(require("fs")),$e=W(require("path"));fe()});var jn={};pe(jn,{cmdRoadmapAnalyze:()=>Di,cmdRoadmapGetPhase:()=>Fi,cmdRoadmapUpdatePlanProgress:()=>Ti});function Fi(n,e,s){let i=R(n).roadmap;if(!Ne.default.existsSync(i)){h({found:!1,error:"ROADMAP.md not found"},s,"");return}try{let t=be(Ne.default.readFileSync(i,"utf-8"),n),r=Q(e??""),o=new RegExp(`#{2,4}\\s*Phase\\s+${r}:\\s*([^\\n]+)`,"i"),a=t.match(o);if(!a){let _=new RegExp(`-\\s*\\[[ x]\\]\\s*\\*\\*Phase\\s+${r}:\\s*([^*]+)\\*\\*`,"i"),b=t.match(_);if(b){h({found:!1,phase_number:e,phase_name:b[1].trim(),error:"malformed_roadmap",message:`Phase ${e} exists in summary list but missing detail section.`},s,"");return}h({found:!1,phase_number:e},s,"");return}let l=a[1].trim(),c=a.index,u=t.slice(c).match(/\n#{2,4}\s+Phase\s+\d/i),p=u?c+u.index:t.length,m=t.slice(c,p).trim(),f=m.match(/\*\*Goal(?::\*\*|\*\*:)\s*([^\n]+)/i),y=m.match(/\*\*Success Criteria\*\*[^\n]*:\s*\n((?:\s*\d+\.\s*[^\n]+\n?)+)/i),g=y?y[1].trim().split(`
310
- `).map(_=>_.replace(/^\s*\d+\.\s*/,"").trim()).filter(Boolean):[];h({found:!0,phase_number:e,phase_name:l,goal:f?f[1].trim():null,success_criteria:g,section:m},s,m)}catch(t){S("Failed to read ROADMAP.md: "+t.message)}}function Di(n,e){let s=R(n).roadmap;if(!Ne.default.existsSync(s)){h({error:"ROADMAP.md not found",milestones:[],phases:[],current_phase:null},e);return}let i=Ne.default.readFileSync(s,"utf-8"),t=be(i,n),r=R(n).phases,o=/#{2,4}\s*Phase\s+(\d+[A-Z]?(?:\.\d+)*)\s*:\s*([^\n]+)/gi,a=[],l;for(;(l=o.exec(t))!==null;){let $=l[1],D=l[2].replace(/\(INSERTED\)/i,"").trim(),A=l.index,O=t.slice(A).match(/\n#{2,4}\s+Phase\s+\d/i),N=O?A+O.index:t.length,L=t.slice(A,N),ne=L.match(/\*\*Goal(?::\*\*|\*\*:)\s*([^\n]+)/i),de=L.match(/\*\*Depends on(?::\*\*|\*\*:)\s*([^\n]+)/i),ve=ce($),se="no_directory",me=0,De=0,qe=!1,It=!1;try{let sn=Ne.default.readdirSync(r,{withFileTypes:!0}).filter(Ie=>Ie.isDirectory()).map(Ie=>Ie.name).find(Ie=>Ie.startsWith(ve+"-")||Ie===ve);if(sn){let Ie=Ne.default.readdirSync(An.default.join(r,sn));me=Ie.filter(Ee=>Ee.endsWith("-PLAN.md")||Ee==="PLAN.md").length,De=Ie.filter(Ee=>Ee.endsWith("-SUMMARY.md")||Ee==="SUMMARY.md").length,qe=Ie.some(Ee=>Ee.endsWith("-CONTEXT.md")||Ee==="CONTEXT.md"),It=Ie.some(Ee=>Ee.endsWith("-RESEARCH.md")||Ee==="RESEARCH.md"),De>=me&&me>0?se="complete":De>0?se="partial":me>0?se="planned":It?se="researched":qe?se="discussed":se="empty"}}catch{}let Dn=new RegExp(`-\\s*\\[(x| )\\]\\s*.*Phase\\s+${Q($)}[:\\s]`,"i"),tn=t.match(Dn),nn=tn?tn[1]==="x":!1;nn&&se!=="complete"&&(se="complete"),a.push({number:$,name:D,goal:ne?ne[1].trim():null,depends_on:de?de[1].trim():null,plan_count:me,summary_count:De,has_context:qe,has_research:It,disk_status:se,roadmap_complete:nn})}let c=[],d=/##\s*(.*v(\d+(?:\.\d+)+)[^(\n]*)/gi,u;for(;(u=d.exec(t))!==null;)c.push({heading:u[1].trim(),version:"v"+u[2]});let p=a.find($=>$.disk_status==="planned"||$.disk_status==="partial")??null,m=a.find($=>["empty","no_directory","discussed","researched"].includes($.disk_status))??null,f=a.reduce(($,D)=>$+D.plan_count,0),y=a.reduce(($,D)=>$+D.summary_count,0),g=a.filter($=>$.disk_status==="complete").length,_=/-\s*\[[ x]\]\s*\*\*Phase\s+(\d+[A-Z]?(?:\.\d+)*)/gi,b=new Set,v;for(;(v=_.exec(t))!==null;)b.add(v[1]);let P=new Set(a.map($=>$.number)),k=[...b].filter($=>!P.has($));h({milestones:c,phases:a,phase_count:a.length,completed_phases:g,total_plans:f,total_summaries:y,progress_percent:f>0?Math.min(100,Math.round(y/f*100)):0,current_phase:p?p.number:null,next_phase:m?m.number:null,missing_phase_details:k.length>0?k:null},e)}function Ti(n,e,s){e||S("phase number required for roadmap update-plan-progress");let i=R(n).roadmap,t=ue(n,e);t||S(`Phase ${e} not found`);let r=t.plans.length,o=t.summaries.length;if(r===0){h({updated:!1,reason:"No plans found",plan_count:0,summary_count:0},s,"no plans");return}let a=o>=r,l=a?"Complete":o>0?"In Progress":"Planned",c=new Date().toISOString().split("T")[0];if(!Ne.default.existsSync(i)){h({updated:!1,reason:"ROADMAP.md not found",plan_count:r,summary_count:o},s,"no roadmap");return}let d=Ne.default.readFileSync(i,"utf-8"),u=Q(e),p=new RegExp(`^(\\|\\s*${u}\\.?\\s[^|]*(?:\\|[^\\n]*))$`,"im"),m=a?` ${c} `:" ";d=d.replace(p,y=>{let g=y.split("|").slice(1,-1);return g.length===5?(g[2]=` ${o}/${r} `,g[3]=` ${l.padEnd(11)}`,g[4]=m):g.length===4&&(g[1]=` ${o}/${r} `,g[2]=` ${l.padEnd(11)}`,g[3]=m),"|"+g.join("|")+"|"});let f=new RegExp(`(#{2,4}\\s*Phase\\s+${u}[\\s\\S]*?\\*\\*Plans:\\*\\*\\s*)[^\\n]+`,"i");if(d=Ze(d,f,`$1${a?`${o}/${r} plans complete`:`${o}/${r} plans executed`}`),a){let y=new RegExp(`(-\\s*\\[)[ ](\\]\\s*.*Phase\\s+${u}[:\\s][^\\n]*)`,"i");d=Ze(d,y,`$1x$2 (completed ${c})`)}for(let y of t.summaries){let g=y.replace("-SUMMARY.md","").replace("SUMMARY.md","");g&&(d=d.replace(new RegExp(`(-\\s*\\[) (\\]\\s*${Q(g)})`,"i"),"$1x$2"))}Ne.default.writeFileSync(i,d,"utf-8"),h({updated:!0,phase:e,plan_count:r,summary_count:o,status:l,complete:a},s,`${o}/${r} ${l}`)}var Ne,An,Rn=le(()=>{"use strict";Ne=W(require("fs")),An=W(require("path"));fe()});var Bt={};pe(Bt,{cmdMilestoneComplete:()=>Ni,cmdRequirementsMarkComplete:()=>Oi});function Oi(n,e,s){(!e||e.length===0)&&S("requirement IDs required.");let i=e.join(" ").replace(/[[\]]/g,"").split(/[,\s]+/).map(c=>c.trim()).filter(Boolean);i.length===0&&S("no valid requirement IDs found");let t=R(n).requirements;if(!G.default.existsSync(t)){h({updated:!1,reason:"REQUIREMENTS.md not found",ids:i},s,"no requirements file");return}let r=G.default.readFileSync(t,"utf-8"),o=[],a=[],l=[];for(let c of i){let d=!1,u=Q(c);new RegExp(`(-\\s*\\[)[ ](\\]\\s*\\*\\*${u}\\*\\*)`,"gi").test(r)&&(r=r.replace(new RegExp(`(-\\s*\\[)[ ](\\]\\s*\\*\\*${u}\\*\\*)`,"gi"),"$1x$2"),d=!0),new RegExp(`(\\|\\s*${u}\\s*\\|[^|]+\\|)\\s*Pending\\s*(\\|)`,"gi").test(r)&&(r=r.replace(new RegExp(`(\\|\\s*${u}\\s*\\|[^|]+\\|)\\s*Pending\\s*(\\|)`,"gi"),"$1 Complete $2"),d=!0),d?o.push(c):new RegExp(`-\\s*\\[x\\]\\s*\\*\\*${u}\\*\\*`,"gi").test(r)||new RegExp(`\\|\\s*${u}\\s*\\|[^|]+\\|\\s*Complete\\s*\\|`,"gi").test(r)?a.push(c):l.push(c)}o.length>0&&G.default.writeFileSync(t,r,"utf-8"),h({updated:o.length>0,marked_complete:o,already_complete:a,not_found:l,total:i.length},s,`${o.length}/${i.length} requirements marked complete`)}function Ni(n,e,s,i){e||S("version required for milestone complete (e.g., v1.0)");let t=R(n).roadmap,r=R(n).requirements,o=R(n).state,a=_e.default.join(n,".planning","MILESTONES.md"),l=_e.default.join(n,".planning","milestones"),c=R(n).phases,d=new Date().toISOString().split("T")[0],u=s.name||e;G.default.mkdirSync(l,{recursive:!0});let p=Pe(n),m=0,f=0,y=0,g=[];try{let k=G.default.readdirSync(c,{withFileTypes:!0}).filter($=>$.isDirectory()).map($=>$.name).sort();for(let $ of k){if(!p($))continue;m++;let D=G.default.readdirSync(_e.default.join(c,$)),A=D.filter(N=>N.endsWith("-PLAN.md")||N==="PLAN.md"),O=D.filter(N=>N.endsWith("-SUMMARY.md")||N==="SUMMARY.md");f+=A.length;for(let N of O)try{let L=G.default.readFileSync(_e.default.join(c,$,N),"utf-8"),de=ee(L)["one-liner"]||yt(L);de&&g.push(de);let ve=L.match(/\*\*Tasks:\*\*\s*(\d+)/);if(ve)y+=parseInt(ve[1],10);else{let se=L.match(/<task[\s>]/gi)||[],me=L.match(/##\s*Task\s*\d+/gi)||[];y+=se.length||me.length}}catch{}}}catch{}G.default.existsSync(t)&&G.default.writeFileSync(_e.default.join(l,`${e}-ROADMAP.md`),G.default.readFileSync(t,"utf-8"),"utf-8"),G.default.existsSync(r)&&G.default.writeFileSync(_e.default.join(l,`${e}-REQUIREMENTS.md`),`# Requirements Archive: ${e} ${u}
309
+ ${a}`;h({updated:!0,profile:i,previousProfile:r,agentToModelMap:o},s,c)}var re,vn,Ge,kn,ci,tt=le(()=>{"use strict";re=W(require("fs")),vn=W(require("os")),Ge=W(require("path"));pe();rt();kn=new Set(["mode","granularity","parallelization","commit_docs","model_profile","search_gitignored","brave_search","firecrawl","exa_search","workflow.research","workflow.plan_check","workflow.verifier","workflow.nyquist_validation","workflow.ui_phase","workflow.ui_safety_gate","workflow.auto_advance","workflow.node_repair","workflow.node_repair_budget","workflow.text_mode","workflow.research_before_questions","workflow.discuss_mode","workflow.skip_discuss","workflow._auto_chain_active","git.branching_strategy","git.phase_branch_template","git.milestone_branch_template","git.quick_branch_template","planning.commit_docs","planning.search_gitignored","hooks.context_warnings"]),ci={"workflow.nyquist_validation_enabled":"workflow.nyquist_validation","agents.nyquist_validation_enabled":"workflow.nyquist_validation","nyquist.validation_enabled":"workflow.nyquist_validation","hooks.research_questions":"workflow.research_before_questions","workflow.research_questions":"workflow.research_before_questions"}});var Vt={};fe(Vt,{cmdAgentSkills:()=>Mi,cmdInitExecutePhase:()=>yi,cmdInitListWorkspaces:()=>Ei,cmdInitManager:()=>Ci,cmdInitMapCodebase:()=>ji,cmdInitMilestoneOp:()=>Ai,cmdInitNewMilestone:()=>bi,cmdInitNewProject:()=>_i,cmdInitNewWorkspace:()=>Ii,cmdInitPhaseOp:()=>Pi,cmdInitPlanPhase:()=>Si,cmdInitProgress:()=>Ri,cmdInitQuick:()=>xi,cmdInitRemoveWorkspace:()=>wi,cmdInitResume:()=>vi,cmdInitTodos:()=>$i,cmdInitVerifyWork:()=>ki});function $n(n){let e=$e.default.join(J(n),"MILESTONES.md");if(!U.default.existsSync(e))return null;try{let i=U.default.readFileSync(e,"utf-8").match(/^##\s+(v[\d.]+)\s+(.+?)\s+\(Shipped:/m);return i?{version:i[1],name:i[2].trim()}:null}catch{return null}}function ae(n,e){e.project_root=n,e.gsd_bin="dist/gsd-tools.js",e.gsd_root=".",e.gsd_harness_dir=".";let s=ot();return e.agents_installed=s.agents_installed,e.missing_agents=s.missing_agents,e}function yi(n,e,s){e||S("phase required for init execute-phase");let i=B(n),t=ue(n,e),r=ie(n),o=Qe(n,e);if(!t&&o?.found){let d=o.phase_name;t={found:!0,directory:null,phase_number:o.phase_number,phase_name:d,phase_slug:d?d.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,""):null,plans:[],summaries:[],incomplete_plans:[],has_research:!1,has_context:!1,has_verification:!1,has_reviews:!1}}let a=o?.section?.match(/^\*\*Requirements\*\*:[^\S\n]*([^\n]*)$/m),l=a?a[1].replace(/[[\]]/g,"").split(",").map(d=>d.trim()).filter(Boolean).join(", "):null,c=ae(n,{executor_model:X(n,"gsd-executor"),verifier_model:X(n,"gsd-verifier"),commit_docs:i.commit_docs,sub_repos:i.sub_repos,parallelization:i.parallelization,context_window:i.context_window,branching_strategy:i.branching_strategy,phase_branch_template:i.phase_branch_template,milestone_branch_template:i.milestone_branch_template,verifier_enabled:i.verifier,phase_found:!!t,phase_dir:t?.directory??null,phase_number:t?.phase_number??null,phase_name:t?.phase_name??null,phase_slug:t?.phase_slug??null,phase_req_ids:l&&l!=="TBD"?l:null,plans:t?.plans??[],summaries:t?.summaries??[],incomplete_plans:t?.incomplete_plans??[],has_research:t?.has_research??!1,has_context:t?.has_context??!1,has_verification:t?.has_verification??!1,has_reviews:t?.has_reviews??!1,roadmap_goal:o?.goal??null,roadmap_section:o?.section??null,milestone_version:r.version,milestone_name:r.name});h(c,s)}function Si(n,e,s){e||S("phase required for init plan-phase");let i=B(n),t=ue(n,e),r=Qe(n,e),o=ie(n),a=ae(n,{planner_model:X(n,"gsd-planner"),researcher_model:X(n,"gsd-phase-researcher"),synthesizer_model:X(n,"gsd-research-synthesizer"),commit_docs:i.commit_docs,research_enabled:i.research,plan_checker_enabled:i.plan_checker,context_window:i.context_window,phase_found:!!t,phase_dir:t?.directory??null,phase_number:t?.phase_number??null,phase_name:t?.phase_name??null,roadmap_goal:r?.goal??null,roadmap_section:r?.section??null,milestone_version:o.version,milestone_name:o.name});h(a,s)}function _i(n,e){let s=B(n),i=J(n),t=ae(n,{planner_model:X(n,"gsd-planner"),roadmapper_model:X(n,"gsd-roadmapper"),commit_docs:s.commit_docs,context_window:s.context_window,planning_exists:U.default.existsSync(i),project_exists:U.default.existsSync($e.default.join(i,"PROJECT.md")),config_exists:U.default.existsSync($e.default.join(i,"config.json")),roadmap_exists:U.default.existsSync($e.default.join(i,"ROADMAP.md")),state_exists:U.default.existsSync($e.default.join(i,"STATE.md"))});h(t,e)}function bi(n,e){let s=B(n),i=ie(n),t=$n(n),r=ae(n,{roadmapper_model:X(n,"gsd-roadmapper"),commit_docs:s.commit_docs,context_window:s.context_window,current_milestone:i,last_completed_milestone:t,roadmap_exists:U.default.existsSync(R(n).roadmap)});h(r,e)}function xi(n,e,s){let i=B(n),t=ie(n),r=ae(n,{executor_model:X(n,"gsd-executor"),commit_docs:i.commit_docs,context_window:i.context_window,branching_strategy:i.branching_strategy,quick_branch_template:i.quick_branch_template,description:e||null,milestone_version:t.version,milestone_name:t.name,state_exists:U.default.existsSync(R(n).state)});h(r,s)}function vi(n,e){let s=B(n),i=ie(n),t=U.default.existsSync(R(n).state),r="";if(t)try{r=U.default.readFileSync(R(n).state,"utf-8")}catch{}let o=ae(n,{executor_model:X(n,"gsd-executor"),commit_docs:s.commit_docs,context_window:s.context_window,state_exists:t,state_raw:r,roadmap_exists:U.default.existsSync(R(n).roadmap),config_exists:U.default.existsSync(R(n).config),milestone_version:i.version,milestone_name:i.name});h(o,e)}function ki(n,e,s){e||S("phase required for init verify-work");let i=B(n),t=ue(n,e),r=Qe(n,e),o=ae(n,{verifier_model:X(n,"gsd-verifier"),nyquist_model:X(n,"gsd-nyquist-auditor"),commit_docs:i.commit_docs,nyquist_validation:i.nyquist_validation,context_window:i.context_window,phase_found:!!t,phase_dir:t?.directory??null,phase_number:t?.phase_number??null,phase_name:t?.phase_name??null,plans:t?.plans??[],summaries:t?.summaries??[],roadmap_goal:r?.goal??null});h(o,s)}function Pi(n,e,s){let i=B(n),t=e?ue(n,e):null,r=ie(n),o=ae(n,{planner_model:X(n,"gsd-planner"),commit_docs:i.commit_docs,context_window:i.context_window,phase_found:!!t,phase_dir:t?.directory??null,phase_number:t?.phase_number??null,phase_name:t?.phase_name??null,milestone_version:r.version,milestone_name:r.name});h(o,s)}function $i(n,e,s){let i=B(n),t=$e.default.join(F(n),"todos","pending"),r=[];if(U.default.existsSync(t))try{for(let a of U.default.readdirSync(t).filter(l=>l.endsWith(".md")))try{let l=U.default.readFileSync($e.default.join(t,a),"utf-8"),c=l.match(/^title:\s*(.+)$/m),d=l.match(/^area:\s*(.+)$/m),u=d?d[1].trim():"general";if(e&&u!==e)continue;r.push({file:a,title:c?c[1].trim():"Untitled",area:u})}catch{}}catch{}let o=ae(n,{executor_model:X(n,"gsd-executor"),commit_docs:i.commit_docs,todos:r,todo_count:r.length,area:e??null});h(o,s)}function Ai(n,e){let s=B(n),i=ie(n),t=$n(n),r=ae(n,{planner_model:X(n,"gsd-planner"),commit_docs:s.commit_docs,context_window:s.context_window,milestone_version:i.version,milestone_name:i.name,last_completed_milestone:t,roadmap_exists:U.default.existsSync(R(n).roadmap),state_exists:U.default.existsSync(R(n).state)});h(r,e)}function ji(n,e){let s=B(n),i=ae(n,{mapper_model:X(n,"gsd-codebase-mapper"),commit_docs:s.commit_docs,search_gitignored:s.search_gitignored,context_window:s.context_window,project_exists:U.default.existsSync($e.default.join(J(n),"PROJECT.md"))});h(i,e)}function Ri(n,e){let s=B(n),i=ie(n),t=Pe(n),r=R(n).phases,o=0,a=0,l=0;if(U.default.existsSync(r))try{let d=U.default.readdirSync(r,{withFileTypes:!0}).filter(u=>u.isDirectory()).map(u=>u.name).filter(t);l=d.length;for(let u of d){let f=U.default.readdirSync($e.default.join(r,u));o+=f.filter(m=>m.match(/-PLAN\.md$/i)).length,a+=f.filter(m=>m.match(/-SUMMARY\.md$/i)).length}}catch{}let c=ae(n,{commit_docs:s.commit_docs,context_window:s.context_window,milestone_version:i.version,milestone_name:i.name,phase_count:l,total_plans:o,total_summaries:a,percent:o>0?Math.min(100,Math.round(a/o*100)):0});h(c,e)}function Ci(n,e){let s=B(n),i=ie(n),t=ae(n,{planner_model:X(n,"gsd-planner"),roadmapper_model:X(n,"gsd-roadmapper"),commit_docs:s.commit_docs,context_window:s.context_window,milestone_version:i.version,milestone_name:i.name,state_exists:U.default.existsSync(R(n).state),roadmap_exists:U.default.existsSync(R(n).roadmap)});h(t,e)}function Ii(n,e){let s=B(n),i=$e.default.join(J(n),"workstreams"),t=ae(n,{commit_docs:s.commit_docs,context_window:s.context_window,workstream_mode:U.default.existsSync(i),workstreams:U.default.existsSync(i)?U.default.readdirSync(i,{withFileTypes:!0}).filter(r=>r.isDirectory()).map(r=>r.name):[]});h(t,e)}function Ei(n,e){let s=$e.default.join(J(n),"workstreams");if(!U.default.existsSync(s)){h(ae(n,{mode:"flat",workstreams:[],count:0}),e);return}let i=U.default.readdirSync(s,{withFileTypes:!0}).filter(t=>t.isDirectory()).map(t=>t.name);h(ae(n,{mode:"workstream",workstreams:i,count:i.length}),e)}function wi(n,e,s){e||S("workstream name required for init remove-workspace");let i=$e.default.join(J(n),"workstreams",e);if(!U.default.existsSync(i)){h(ae(n,{removed:!1,reason:"not_found",workstream:e}),s);return}try{U.default.rmSync(i,{recursive:!0,force:!0})}catch(t){h(ae(n,{removed:!1,reason:t.message,workstream:e}),s);return}h(ae(n,{removed:!0,workstream:e}),s)}function Mi(n,e,s){e||S("agent-type required");let t=B(n).agent_skills[e]??{};h({agent:e,skills:t},s,JSON.stringify(t))}var U,$e,Ht=le(()=>{"use strict";U=W(require("fs")),$e=W(require("path"));pe()});var jn={};fe(jn,{cmdRoadmapAnalyze:()=>Ti,cmdRoadmapGetPhase:()=>Fi,cmdRoadmapUpdatePlanProgress:()=>Di});function Fi(n,e,s){let i=R(n).roadmap;if(!Ne.default.existsSync(i)){h({found:!1,error:"ROADMAP.md not found"},s,"");return}try{let t=be(Ne.default.readFileSync(i,"utf-8"),n),r=Q(e??""),o=new RegExp(`#{2,4}\\s*Phase\\s+${r}:\\s*([^\\n]+)`,"i"),a=t.match(o);if(!a){let _=new RegExp(`-\\s*\\[[ x]\\]\\s*\\*\\*Phase\\s+${r}:\\s*([^*]+)\\*\\*`,"i"),b=t.match(_);if(b){h({found:!1,phase_number:e,phase_name:b[1].trim(),error:"malformed_roadmap",message:`Phase ${e} exists in summary list but missing detail section.`},s,"");return}h({found:!1,phase_number:e},s,"");return}let l=a[1].trim(),c=a.index,u=t.slice(c).match(/\n#{2,4}\s+Phase\s+\d/i),f=u?c+u.index:t.length,m=t.slice(c,f).trim(),p=m.match(/\*\*Goal(?::\*\*|\*\*:)\s*([^\n]+)/i),y=m.match(/\*\*Success Criteria\*\*[^\n]*:\s*\n((?:\s*\d+\.\s*[^\n]+\n?)+)/i),g=y?y[1].trim().split(`
310
+ `).map(_=>_.replace(/^\s*\d+\.\s*/,"").trim()).filter(Boolean):[];h({found:!0,phase_number:e,phase_name:l,goal:p?p[1].trim():null,success_criteria:g,section:m},s,m)}catch(t){S("Failed to read ROADMAP.md: "+t.message)}}function Ti(n,e){let s=R(n).roadmap;if(!Ne.default.existsSync(s)){h({error:"ROADMAP.md not found",milestones:[],phases:[],current_phase:null},e);return}let i=Ne.default.readFileSync(s,"utf-8"),t=be(i,n),r=R(n).phases,o=/#{2,4}\s*Phase\s+(\d+[A-Z]?(?:\.\d+)*)\s*:\s*([^\n]+)/gi,a=[],l;for(;(l=o.exec(t))!==null;){let $=l[1],T=l[2].replace(/\(INSERTED\)/i,"").trim(),A=l.index,O=t.slice(A).match(/\n#{2,4}\s+Phase\s+\d/i),N=O?A+O.index:t.length,L=t.slice(A,N),ne=L.match(/\*\*Goal(?::\*\*|\*\*:)\s*([^\n]+)/i),de=L.match(/\*\*Depends on(?::\*\*|\*\*:)\s*([^\n]+)/i),ve=ce($),se="no_directory",me=0,Te=0,qe=!1,It=!1;try{let sn=Ne.default.readdirSync(r,{withFileTypes:!0}).filter(Ie=>Ie.isDirectory()).map(Ie=>Ie.name).find(Ie=>Ie.startsWith(ve+"-")||Ie===ve);if(sn){let Ie=Ne.default.readdirSync(An.default.join(r,sn));me=Ie.filter(Ee=>Ee.endsWith("-PLAN.md")||Ee==="PLAN.md").length,Te=Ie.filter(Ee=>Ee.endsWith("-SUMMARY.md")||Ee==="SUMMARY.md").length,qe=Ie.some(Ee=>Ee.endsWith("-CONTEXT.md")||Ee==="CONTEXT.md"),It=Ie.some(Ee=>Ee.endsWith("-RESEARCH.md")||Ee==="RESEARCH.md"),Te>=me&&me>0?se="complete":Te>0?se="partial":me>0?se="planned":It?se="researched":qe?se="discussed":se="empty"}}catch{}let Tn=new RegExp(`-\\s*\\[(x| )\\]\\s*.*Phase\\s+${Q($)}[:\\s]`,"i"),tn=t.match(Tn),nn=tn?tn[1]==="x":!1;nn&&se!=="complete"&&(se="complete"),a.push({number:$,name:T,goal:ne?ne[1].trim():null,depends_on:de?de[1].trim():null,plan_count:me,summary_count:Te,has_context:qe,has_research:It,disk_status:se,roadmap_complete:nn})}let c=[],d=/##\s*(.*v(\d+(?:\.\d+)+)[^(\n]*)/gi,u;for(;(u=d.exec(t))!==null;)c.push({heading:u[1].trim(),version:"v"+u[2]});let f=a.find($=>$.disk_status==="planned"||$.disk_status==="partial")??null,m=a.find($=>["empty","no_directory","discussed","researched"].includes($.disk_status))??null,p=a.reduce(($,T)=>$+T.plan_count,0),y=a.reduce(($,T)=>$+T.summary_count,0),g=a.filter($=>$.disk_status==="complete").length,_=/-\s*\[[ x]\]\s*\*\*Phase\s+(\d+[A-Z]?(?:\.\d+)*)/gi,b=new Set,v;for(;(v=_.exec(t))!==null;)b.add(v[1]);let P=new Set(a.map($=>$.number)),k=[...b].filter($=>!P.has($));h({milestones:c,phases:a,phase_count:a.length,completed_phases:g,total_plans:p,total_summaries:y,progress_percent:p>0?Math.min(100,Math.round(y/p*100)):0,current_phase:f?f.number:null,next_phase:m?m.number:null,missing_phase_details:k.length>0?k:null},e)}function Di(n,e,s){e||S("phase number required for roadmap update-plan-progress");let i=R(n).roadmap,t=ue(n,e);t||S(`Phase ${e} not found`);let r=t.plans.length,o=t.summaries.length;if(r===0){h({updated:!1,reason:"No plans found",plan_count:0,summary_count:0},s,"no plans");return}let a=o>=r,l=a?"Complete":o>0?"In Progress":"Planned",c=new Date().toISOString().split("T")[0];if(!Ne.default.existsSync(i)){h({updated:!1,reason:"ROADMAP.md not found",plan_count:r,summary_count:o},s,"no roadmap");return}let d=Ne.default.readFileSync(i,"utf-8"),u=Q(e),f=new RegExp(`^(\\|\\s*${u}\\.?\\s[^|]*(?:\\|[^\\n]*))$`,"im"),m=a?` ${c} `:" ";d=d.replace(f,y=>{let g=y.split("|").slice(1,-1);return g.length===5?(g[2]=` ${o}/${r} `,g[3]=` ${l.padEnd(11)}`,g[4]=m):g.length===4&&(g[1]=` ${o}/${r} `,g[2]=` ${l.padEnd(11)}`,g[3]=m),"|"+g.join("|")+"|"});let p=new RegExp(`(#{2,4}\\s*Phase\\s+${u}[\\s\\S]*?\\*\\*Plans:\\*\\*\\s*)[^\\n]+`,"i");if(d=Ze(d,p,`$1${a?`${o}/${r} plans complete`:`${o}/${r} plans executed`}`),a){let y=new RegExp(`(-\\s*\\[)[ ](\\]\\s*.*Phase\\s+${u}[:\\s][^\\n]*)`,"i");d=Ze(d,y,`$1x$2 (completed ${c})`)}for(let y of t.summaries){let g=y.replace("-SUMMARY.md","").replace("SUMMARY.md","");g&&(d=d.replace(new RegExp(`(-\\s*\\[) (\\]\\s*${Q(g)})`,"i"),"$1x$2"))}Ne.default.writeFileSync(i,d,"utf-8"),h({updated:!0,phase:e,plan_count:r,summary_count:o,status:l,complete:a},s,`${o}/${r} ${l}`)}var Ne,An,Rn=le(()=>{"use strict";Ne=W(require("fs")),An=W(require("path"));pe()});var Bt={};fe(Bt,{cmdMilestoneComplete:()=>Ni,cmdRequirementsMarkComplete:()=>Oi});function Oi(n,e,s){(!e||e.length===0)&&S("requirement IDs required.");let i=e.join(" ").replace(/[[\]]/g,"").split(/[,\s]+/).map(c=>c.trim()).filter(Boolean);i.length===0&&S("no valid requirement IDs found");let t=R(n).requirements;if(!G.default.existsSync(t)){h({updated:!1,reason:"REQUIREMENTS.md not found",ids:i},s,"no requirements file");return}let r=G.default.readFileSync(t,"utf-8"),o=[],a=[],l=[];for(let c of i){let d=!1,u=Q(c);new RegExp(`(-\\s*\\[)[ ](\\]\\s*\\*\\*${u}\\*\\*)`,"gi").test(r)&&(r=r.replace(new RegExp(`(-\\s*\\[)[ ](\\]\\s*\\*\\*${u}\\*\\*)`,"gi"),"$1x$2"),d=!0),new RegExp(`(\\|\\s*${u}\\s*\\|[^|]+\\|)\\s*Pending\\s*(\\|)`,"gi").test(r)&&(r=r.replace(new RegExp(`(\\|\\s*${u}\\s*\\|[^|]+\\|)\\s*Pending\\s*(\\|)`,"gi"),"$1 Complete $2"),d=!0),d?o.push(c):new RegExp(`-\\s*\\[x\\]\\s*\\*\\*${u}\\*\\*`,"gi").test(r)||new RegExp(`\\|\\s*${u}\\s*\\|[^|]+\\|\\s*Complete\\s*\\|`,"gi").test(r)?a.push(c):l.push(c)}o.length>0&&G.default.writeFileSync(t,r,"utf-8"),h({updated:o.length>0,marked_complete:o,already_complete:a,not_found:l,total:i.length},s,`${o.length}/${i.length} requirements marked complete`)}function Ni(n,e,s,i){e||S("version required for milestone complete (e.g., v1.0)");let t=R(n).roadmap,r=R(n).requirements,o=R(n).state,a=_e.default.join(n,".planning","MILESTONES.md"),l=_e.default.join(n,".planning","milestones"),c=R(n).phases,d=new Date().toISOString().split("T")[0],u=s.name||e;G.default.mkdirSync(l,{recursive:!0});let f=Pe(n),m=0,p=0,y=0,g=[];try{let k=G.default.readdirSync(c,{withFileTypes:!0}).filter($=>$.isDirectory()).map($=>$.name).sort();for(let $ of k){if(!f($))continue;m++;let T=G.default.readdirSync(_e.default.join(c,$)),A=T.filter(N=>N.endsWith("-PLAN.md")||N==="PLAN.md"),O=T.filter(N=>N.endsWith("-SUMMARY.md")||N==="SUMMARY.md");p+=A.length;for(let N of O)try{let L=G.default.readFileSync(_e.default.join(c,$,N),"utf-8"),de=ee(L)["one-liner"]||yt(L);de&&g.push(de);let ve=L.match(/\*\*Tasks:\*\*\s*(\d+)/);if(ve)y+=parseInt(ve[1],10);else{let se=L.match(/<task[\s>]/gi)||[],me=L.match(/##\s*Task\s*\d+/gi)||[];y+=se.length||me.length}}catch{}}}catch{}G.default.existsSync(t)&&G.default.writeFileSync(_e.default.join(l,`${e}-ROADMAP.md`),G.default.readFileSync(t,"utf-8"),"utf-8"),G.default.existsSync(r)&&G.default.writeFileSync(_e.default.join(l,`${e}-REQUIREMENTS.md`),`# Requirements Archive: ${e} ${u}
311
311
 
312
312
  **Archived:** ${d}
313
313
  **Status:** SHIPPED
@@ -317,7 +317,7 @@ ${a}`;h({updated:!0,profile:i,previousProfile:r,agentToModelMap:o},s,c)}var re,v
317
317
  `+G.default.readFileSync(r,"utf-8"),"utf-8");let _=_e.default.join(n,".planning",`${e}-MILESTONE-AUDIT.md`);G.default.existsSync(_)&&G.default.renameSync(_,_e.default.join(l,`${e}-MILESTONE-AUDIT.md`));let b=g.map(k=>`- ${k}`).join(`
318
318
  `),v=`## ${e} ${u} (Shipped: ${d})
319
319
 
320
- **Phases completed:** ${m} phases, ${f} plans, ${y} tasks
320
+ **Phases completed:** ${m} phases, ${p} plans, ${y} tasks
321
321
 
322
322
  **Key accomplishments:**
323
323
  ${b||"- (none recorded)"}
@@ -328,17 +328,17 @@ ${b||"- (none recorded)"}
328
328
 
329
329
  ${v}`),"utf-8");else{let $=k.match(/^(#{1,3}\s+[^\n]*\n\n?)/);$?G.default.writeFileSync(a,Re($[1]+v+k.slice($[1].length)),"utf-8"):G.default.writeFileSync(a,Re(v+k),"utf-8")}}else G.default.writeFileSync(a,Re(`# Milestones
330
330
 
331
- ${v}`),"utf-8");if(G.default.existsSync(o)){let k=G.default.readFileSync(o,"utf-8");k=he(k,"Status",null,`${e} milestone complete`),k=he(k,"Last Activity","Last activity",d),k=he(k,"Last Activity Description",null,`${e} milestone completed and archived`),te(o,k,n)}let P=!1;if(s.archivePhases)try{let k=_e.default.join(l,`${e}-phases`);G.default.mkdirSync(k,{recursive:!0});let $=G.default.readdirSync(c,{withFileTypes:!0}).filter(A=>A.isDirectory()).map(A=>A.name),D=0;for(let A of $)p(A)&&(G.default.renameSync(_e.default.join(c,A),_e.default.join(k,A)),D++);P=D>0}catch{}h({version:e,name:u,date:d,phases:m,plans:f,tasks:y,accomplishments:g,archived:{roadmap:G.default.existsSync(_e.default.join(l,`${e}-ROADMAP.md`)),requirements:G.default.existsSync(_e.default.join(l,`${e}-REQUIREMENTS.md`)),audit:G.default.existsSync(_e.default.join(l,`${e}-MILESTONE-AUDIT.md`)),phases:P},milestones_updated:!0,state_updated:G.default.existsSync(o)},i)}var G,_e,Jt=le(()=>{"use strict";G=W(require("fs")),_e=W(require("path"));fe();Ue();Be()});var Yt={};pe(Yt,{buildCheckpoint:()=>In,cmdAuditUat:()=>Wi,cmdRenderCheckpoint:()=>qi,parseCurrentTest:()=>Cn});function Wi(n,e){let s=We.default.join(F(n),"phases");Ve.default.existsSync(s)||S("No phases directory found in planning directory");let i=Pe(n),t=[],r=Ve.default.readdirSync(s,{withFileTypes:!0}).filter(a=>a.isDirectory()).map(a=>a.name).filter(i).sort();for(let a of r){let l=a.match(/^(\d+[A-Z]?(?:\.\d+)*)/i),c=l?l[1]:a,d=We.default.join(s,a),u=Ve.default.readdirSync(d);for(let p of u.filter(m=>m.includes("-UAT")&&m.endsWith(".md"))){let m=Ve.default.readFileSync(We.default.join(d,p),"utf-8"),f=Li(m);f.length>0&&t.push({phase:c,phase_dir:a,file:p,file_path:z(We.default.relative(n,We.default.join(d,p))),type:"uat",status:ee(m).status||"unknown",items:f})}for(let p of u.filter(m=>m.includes("-VERIFICATION")&&m.endsWith(".md"))){let m=Ve.default.readFileSync(We.default.join(d,p),"utf-8"),f=ee(m).status||"unknown";if(f==="human_needed"||f==="gaps_found"){let y=Ui(m,f);y.length>0&&t.push({phase:c,phase_dir:a,file:p,file_path:z(We.default.relative(n,We.default.join(d,p))),type:"verification",status:f,items:y})}}}let o={total_files:t.length,total_items:t.reduce((a,l)=>a+l.items.length,0),by_category:{},by_phase:{}};for(let a of t){o.by_phase[a.phase]||(o.by_phase[a.phase]=0);for(let l of a.items)o.by_phase[a.phase]++,o.by_category[l.category]=(o.by_category[l.category]||0)+1}h({results:t,summary:o},e)}function qi(n,e,s){let i=e.file;i||S("UAT file required: use uat render-checkpoint --file <path>");let t=Wt(i,n,"UAT file",{allowAbsolute:!0});Ve.default.existsSync(t)||S(`UAT file not found: ${i}`);let r=Ve.default.readFileSync(t,"utf-8"),o=Cn(r);o.complete&&S("UAT session is already complete; no pending checkpoint to render");let a=In(o);h({file_path:z(We.default.relative(n,t)),test_number:o.number,test_name:o.name,checkpoint:a},s,a)}function Cn(n){let e=n.match(/##\s*Current Test\s*(?:\n<!--[\s\S]*?-->)?\n([\s\S]*?)(?=\n##\s|$)/i);e||S("UAT file is missing a Current Test section");let s=e[1].trimEnd();if(s.trim()||S("Current Test section is empty"),/\[testing complete\]/i.test(s))return{complete:!0};let i=s.match(/^number:\s*(\d+)\s*$/m),t=s.match(/^name:\s*(.+)\s*$/m),r=s.match(/^expected:\s*\|\n([\s\S]*?)(?=^\w[\w-]*:\s)/m)||s.match(/^expected:\s*\|\n([\s\S]+)/m),o=s.match(/^expected:\s*(.+)\s*$/m);(!i||!t||!r&&!o)&&S("Current Test section is malformed");let a;return r?a=r[1].split(`
331
+ ${v}`),"utf-8");if(G.default.existsSync(o)){let k=G.default.readFileSync(o,"utf-8");k=he(k,"Status",null,`${e} milestone complete`),k=he(k,"Last Activity","Last activity",d),k=he(k,"Last Activity Description",null,`${e} milestone completed and archived`),te(o,k,n)}let P=!1;if(s.archivePhases)try{let k=_e.default.join(l,`${e}-phases`);G.default.mkdirSync(k,{recursive:!0});let $=G.default.readdirSync(c,{withFileTypes:!0}).filter(A=>A.isDirectory()).map(A=>A.name),T=0;for(let A of $)f(A)&&(G.default.renameSync(_e.default.join(c,A),_e.default.join(k,A)),T++);P=T>0}catch{}h({version:e,name:u,date:d,phases:m,plans:p,tasks:y,accomplishments:g,archived:{roadmap:G.default.existsSync(_e.default.join(l,`${e}-ROADMAP.md`)),requirements:G.default.existsSync(_e.default.join(l,`${e}-REQUIREMENTS.md`)),audit:G.default.existsSync(_e.default.join(l,`${e}-MILESTONE-AUDIT.md`)),phases:P},milestones_updated:!0,state_updated:G.default.existsSync(o)},i)}var G,_e,Jt=le(()=>{"use strict";G=W(require("fs")),_e=W(require("path"));pe();Ue();Be()});var Yt={};fe(Yt,{buildCheckpoint:()=>In,cmdAuditUat:()=>Wi,cmdRenderCheckpoint:()=>qi,parseCurrentTest:()=>Cn});function Wi(n,e){let s=We.default.join(F(n),"phases");Ve.default.existsSync(s)||S("No phases directory found in planning directory");let i=Pe(n),t=[],r=Ve.default.readdirSync(s,{withFileTypes:!0}).filter(a=>a.isDirectory()).map(a=>a.name).filter(i).sort();for(let a of r){let l=a.match(/^(\d+[A-Z]?(?:\.\d+)*)/i),c=l?l[1]:a,d=We.default.join(s,a),u=Ve.default.readdirSync(d);for(let f of u.filter(m=>m.includes("-UAT")&&m.endsWith(".md"))){let m=Ve.default.readFileSync(We.default.join(d,f),"utf-8"),p=Li(m);p.length>0&&t.push({phase:c,phase_dir:a,file:f,file_path:z(We.default.relative(n,We.default.join(d,f))),type:"uat",status:ee(m).status||"unknown",items:p})}for(let f of u.filter(m=>m.includes("-VERIFICATION")&&m.endsWith(".md"))){let m=Ve.default.readFileSync(We.default.join(d,f),"utf-8"),p=ee(m).status||"unknown";if(p==="human_needed"||p==="gaps_found"){let y=Ui(m,p);y.length>0&&t.push({phase:c,phase_dir:a,file:f,file_path:z(We.default.relative(n,We.default.join(d,f))),type:"verification",status:p,items:y})}}}let o={total_files:t.length,total_items:t.reduce((a,l)=>a+l.items.length,0),by_category:{},by_phase:{}};for(let a of t){o.by_phase[a.phase]||(o.by_phase[a.phase]=0);for(let l of a.items)o.by_phase[a.phase]++,o.by_category[l.category]=(o.by_category[l.category]||0)+1}h({results:t,summary:o},e)}function qi(n,e,s){let i=e.file;i||S("UAT file required: use uat render-checkpoint --file <path>");let t=Wt(i,n,"UAT file",{allowAbsolute:!0});Ve.default.existsSync(t)||S(`UAT file not found: ${i}`);let r=Ve.default.readFileSync(t,"utf-8"),o=Cn(r);o.complete&&S("UAT session is already complete; no pending checkpoint to render");let a=In(o);h({file_path:z(We.default.relative(n,t)),test_number:o.number,test_name:o.name,checkpoint:a},s,a)}function Cn(n){let e=n.match(/##\s*Current Test\s*(?:\n<!--[\s\S]*?-->)?\n([\s\S]*?)(?=\n##\s|$)/i);e||S("UAT file is missing a Current Test section");let s=e[1].trimEnd();if(s.trim()||S("Current Test section is empty"),/\[testing complete\]/i.test(s))return{complete:!0};let i=s.match(/^number:\s*(\d+)\s*$/m),t=s.match(/^name:\s*(.+)\s*$/m),r=s.match(/^expected:\s*\|\n([\s\S]*?)(?=^\w[\w-]*:\s)/m)||s.match(/^expected:\s*\|\n([\s\S]+)/m),o=s.match(/^expected:\s*(.+)\s*$/m);(!i||!t||!r&&!o)&&S("Current Test section is malformed");let a;return r?a=r[1].split(`
332
332
  `).map(l=>l.replace(/^ {2}/,"")).join(`
333
333
  `).trim():a=o[1].trim(),{complete:!1,number:parseInt(i[1],10),name:xt(t[1].trim()),expected:xt(a)}}function In(n){return["\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557","\u2551 CHECKPOINT: Verification Required \u2551","\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D","",`**Test ${n.number}: ${n.name}**`,"",n.expected,"","\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500","Type `pass` or describe what's wrong.","\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"].join(`
334
334
  `)}function Li(n){let e=[],s=/###\s*(\d+)\.\s*([^\n]+)\nexpected:\s*([^\n]+)\nresult:\s*(\w+)(?:\n(?:reported|reason|blocked_by):\s*[^\n]*)?/g,i;for(;(i=s.exec(n))!==null;){let[,t,r,o,a]=i;if(a==="pending"||a==="skipped"||a==="blocked"){let l=n.slice(i.index),c=l.indexOf(`
335
- ###`,1),d=c>0?l.slice(0,c):l,u=d.match(/reason:\s*(.+)/),p=d.match(/blocked_by:\s*(.+)/),m={test:parseInt(t,10),name:r.trim(),expected:o.trim(),result:a,category:Gi(a,u?.[1],p?.[1])};u&&(m.reason=u[1].trim()),p&&(m.blocked_by=p[1].trim()),e.push(m)}}return e}function Ui(n,e){let s=[];if(e==="human_needed"){let i=n.match(/##\s*Human Verification.*?\n([\s\S]*?)(?=\n##\s|\n---\s|$)/i);if(i)for(let t of i[1].split(`
336
- `)){let r=t.match(/\|\s*(\d+)\s*\|\s*([^|]+)/),o=t.match(/^[-*]\s+(.+)/),a=t.match(/^(\d+)\.\s+(.+)/);r?s.push({test:parseInt(r[1],10),name:r[2].trim(),result:"human_needed",category:"human_uat"}):a?s.push({test:parseInt(a[1],10),name:a[2].trim(),result:"human_needed",category:"human_uat"}):o&&o[1].length>10&&s.push({name:o[1].trim(),result:"human_needed",category:"human_uat"})}}return s}function Gi(n,e,s){if(n==="blocked"||s){if(s){if(/server/i.test(s))return"server_blocked";if(/device|physical/i.test(s))return"device_needed";if(/build|release|preview/i.test(s))return"build_needed";if(/third.party|twilio|stripe/i.test(s))return"third_party"}return"blocked"}return n==="skipped"&&e?/server|not running|not available/i.test(e)?"server_blocked":/simulator|physical|device/i.test(e)?"device_needed":/build|release|preview/i.test(e)?"build_needed":"skipped_unresolved":n==="pending"?"pending":n==="human_needed"?"human_uat":"unknown"}var Ve,We,Kt=le(()=>{"use strict";Ve=W(require("fs")),We=W(require("path"));fe();Ue();ct()});var jt={};pe(jt,{cmdExtractMessages:()=>Ji,cmdProfileSample:()=>Yi,cmdScanSessions:()=>Bi});function Zt(n){if(n)return n;let e=process.env.HOME??"",s=Ae.join(e,".agent","projects");return Z.existsSync(s)?s:Ae.join(e,".claude","projects")}function Qt(){let n=process.env.HOME??"";return Ae.join(n,".pi","agent","sessions")}function Xt(n){return n.startsWith("--")&&n.endsWith("--")?"/"+n.slice(2,-2).replace(/-/g,"/"):n}function zi(n){try{let e=Z.readFileSync(n,"utf-8").split(`
335
+ ###`,1),d=c>0?l.slice(0,c):l,u=d.match(/reason:\s*(.+)/),f=d.match(/blocked_by:\s*(.+)/),m={test:parseInt(t,10),name:r.trim(),expected:o.trim(),result:a,category:Gi(a,u?.[1],f?.[1])};u&&(m.reason=u[1].trim()),f&&(m.blocked_by=f[1].trim()),e.push(m)}}return e}function Ui(n,e){let s=[];if(e==="human_needed"){let i=n.match(/##\s*Human Verification.*?\n([\s\S]*?)(?=\n##\s|\n---\s|$)/i);if(i)for(let t of i[1].split(`
336
+ `)){let r=t.match(/\|\s*(\d+)\s*\|\s*([^|]+)/),o=t.match(/^[-*]\s+(.+)/),a=t.match(/^(\d+)\.\s+(.+)/);r?s.push({test:parseInt(r[1],10),name:r[2].trim(),result:"human_needed",category:"human_uat"}):a?s.push({test:parseInt(a[1],10),name:a[2].trim(),result:"human_needed",category:"human_uat"}):o&&o[1].length>10&&s.push({name:o[1].trim(),result:"human_needed",category:"human_uat"})}}return s}function Gi(n,e,s){if(n==="blocked"||s){if(s){if(/server/i.test(s))return"server_blocked";if(/device|physical/i.test(s))return"device_needed";if(/build|release|preview/i.test(s))return"build_needed";if(/third.party|twilio|stripe/i.test(s))return"third_party"}return"blocked"}return n==="skipped"&&e?/server|not running|not available/i.test(e)?"server_blocked":/simulator|physical|device/i.test(e)?"device_needed":/build|release|preview/i.test(e)?"build_needed":"skipped_unresolved":n==="pending"?"pending":n==="human_needed"?"human_uat":"unknown"}var Ve,We,Kt=le(()=>{"use strict";Ve=W(require("fs")),We=W(require("path"));pe();Ue();ct()});var jt={};fe(jt,{cmdExtractMessages:()=>Ji,cmdProfileSample:()=>Yi,cmdScanSessions:()=>Bi});function Zt(n){if(n)return n;let e=process.env.HOME??"",s=Ae.join(e,".agent","projects");return Z.existsSync(s)?s:Ae.join(e,".claude","projects")}function Qt(){let n=process.env.HOME??"";return Ae.join(n,".pi","agent","sessions")}function Xt(n){return n.startsWith("--")&&n.endsWith("--")?"/"+n.slice(2,-2).replace(/-/g,"/"):n}function zi(n){try{let e=Z.readFileSync(n,"utf-8").split(`
337
337
  `).find(i=>i.trim().length>0);if(!e)return!1;let s=JSON.parse(e);return s.type==="session"&&"version"in s}catch{return!1}}function Vi(n){return typeof n=="string"?n:Array.isArray(n)?n.filter(e=>e!==null&&typeof e=="object"&&e.type==="text").map(e=>String(e.text??"")).join(" "):""}function Hi(n){try{let e=Z.readFileSync(n,"utf-8").split(`
338
- `).filter(Boolean),s=[];for(let i of e)try{let t=JSON.parse(i);t.type==="message"&&t.message&&s.push(t)}catch{}return s}catch{return[]}}async function Bi(n,e,s){let t=(e.harness??null)==="pi",r=Qt(),o=Z.existsSync(r),a=[];if(o)try{let p=Z.readdirSync(r,{withFileTypes:!0}).filter(m=>m.isDirectory());for(let m of p){let f=Ae.join(r,m.name),y=Z.readdirSync(f).filter(g=>g.endsWith(".jsonl"));a.push({name:m.name,sessions:y.length,path:f,source:"pi",cwd:Xt(m.name)})}}catch{}let l=Zt(t&&!n?null:n),c=!t||n?Z.existsSync(l):!1,d=[];if(c&&(!t||n))try{let p=Z.readdirSync(l,{withFileTypes:!0}).filter(m=>m.isDirectory());for(let m of p){let f=Ae.join(l,m.name),y=Z.readdirSync(f).filter(g=>g.endsWith(".jsonl")||g.endsWith(".json"));d.push({name:m.name,sessions:y.length,path:f,source:"claude"})}}catch{}let u=t?[...a,...d]:[...d,...a];if(u.length===0){let p=[];o?p.push(r):p.push(r+" (not found)"),t||p.push(c?l:l+" (not found)"),h({available:!1,reason:`No sessions found. Searched: ${p.join(", ")}`,projects:[],count:0},s);return}h({available:!0,pi_base:o?r:null,claude_base:c?l:null,projects:u,count:u.length},s)}async function Ji(n,e,s,i){let t=Qt(),r=null,o="claude";if(Z.existsSync(t)){let d=Ae.join(t,n);if(Z.existsSync(d))r=d,o="pi";else try{let u=Z.readdirSync(t,{withFileTypes:!0}).filter(p=>p.isDirectory());for(let p of u){let m=Xt(p.name);if(m.endsWith("/"+n)||m===n||p.name===n){r=Ae.join(t,p.name),o="pi";break}}}catch{}}if(!r){let d=Zt(i),u=Ae.join(d,n);Z.existsSync(u)&&(r=u,o="claude")}if(!r){h({error:`Project not found: ${n}`,available_projects:[]},s);return}let a=[],l=Z.readdirSync(r).filter(d=>d.endsWith(".jsonl")),c=e.limit??null;for(let d of l){if(e.sessionId&&!d.includes(e.sessionId))continue;let u=Ae.join(r,d);if(o==="pi"||zi(u))try{let p=Z.readFileSync(u,"utf-8").split(`
339
- `).filter(Boolean);for(let m of p)try{let f=JSON.parse(m);if(f.type==="message"&&f.message&&(a.push(f.message),c&&a.length>=c))break}catch{}}catch{}else try{let p=Z.readFileSync(u,"utf-8").split(`
340
- `).filter(Boolean);for(let m of p)try{let f=JSON.parse(m);if(a.push(f),c&&a.length>=c)break}catch{}}catch{}if(c&&a.length>=c)break}h({project:n,source:o,messages:a,count:a.length},s)}async function Yi(n,e,s){let t=(e.harness??null)==="pi",r=e.limit??150,o=e.maxChars??500,a=[],l=Qt();if(Z.existsSync(l))try{let d=Z.readdirSync(l,{withFileTypes:!0}).filter(u=>u.isDirectory());e:for(let u of d){let p=Ae.join(l,u.name),m=Z.readdirSync(p).filter(y=>y.endsWith(".jsonl")),f=0;for(let y of m){let g=Hi(Ae.join(p,y));for(let _ of g)if(_.message?.role==="user"){let b=Vi(_.message.content).slice(0,o);if(b.length>20){if(a.push({project:Xt(u.name),text:b,source:"pi"}),f++,e.maxPerProject&&f>=e.maxPerProject)break;if(a.length>=r)break e}}}}}catch{}if(!(t&&!n&&a.length>=r)){let d=Zt(n);if(Z.existsSync(d))try{let u=Z.readdirSync(d,{withFileTypes:!0}).filter(p=>p.isDirectory());e:for(let p of u){let m=Ae.join(d,p.name),f=Z.readdirSync(m).filter(g=>g.endsWith(".jsonl")),y=0;for(let g of f)try{let _=Z.readFileSync(Ae.join(m,g),"utf-8").split(`
341
- `).filter(Boolean);for(let b of _)try{let v=JSON.parse(b);if(v.role==="human"||v.type==="human"){let P=(v.content||v.message||"").slice(0,o);if(P.length>20){if(a.push({project:p.name,text:P,source:"claude"}),y++,e.maxPerProject&&y>=e.maxPerProject)break;if(a.length>=r)break e}}}catch{}}catch{}}}catch{}}if(a.length===0){h({available:!1,reason:"No user messages found in any session",samples:[],count:0},s);return}h({available:!0,samples:a,count:a.length},s)}var Z,Ae,Rt=le(()=>{"use strict";fe();Z=require("fs"),Ae=require("path")});var nt={};pe(nt,{cmdGenerateClaudeMd:()=>tr,cmdGenerateClaudeProfile:()=>er,cmdGenerateDevPreferences:()=>Xi,cmdProfileQuestionnaire:()=>Qi,cmdWriteProfile:()=>Zi});function Ct(n,e,s="CLAUDE.md"){return e?Ce.default.resolve(e):Ce.default.join(n,s)}function en(n,e){if(!n)return null;let s=Ce.default.isAbsolute(n)?n:Ce.default.join(e,n);if(!ze.default.existsSync(s))return null;try{return JSON.parse(ze.default.readFileSync(s,"utf-8"))}catch{return null}}function Ki(n){return n.map(e=>`## ${e.heading}
338
+ `).filter(Boolean),s=[];for(let i of e)try{let t=JSON.parse(i);t.type==="message"&&t.message&&s.push(t)}catch{}return s}catch{return[]}}async function Bi(n,e,s){let t=(e.harness??null)==="pi",r=Qt(),o=Z.existsSync(r),a=[];if(o)try{let f=Z.readdirSync(r,{withFileTypes:!0}).filter(m=>m.isDirectory());for(let m of f){let p=Ae.join(r,m.name),y=Z.readdirSync(p).filter(g=>g.endsWith(".jsonl"));a.push({name:m.name,sessions:y.length,path:p,source:"pi",cwd:Xt(m.name)})}}catch{}let l=Zt(t&&!n?null:n),c=!t||n?Z.existsSync(l):!1,d=[];if(c&&(!t||n))try{let f=Z.readdirSync(l,{withFileTypes:!0}).filter(m=>m.isDirectory());for(let m of f){let p=Ae.join(l,m.name),y=Z.readdirSync(p).filter(g=>g.endsWith(".jsonl")||g.endsWith(".json"));d.push({name:m.name,sessions:y.length,path:p,source:"claude"})}}catch{}let u=t?[...a,...d]:[...d,...a];if(u.length===0){let f=[];o?f.push(r):f.push(r+" (not found)"),t||f.push(c?l:l+" (not found)"),h({available:!1,reason:`No sessions found. Searched: ${f.join(", ")}`,projects:[],count:0},s);return}h({available:!0,pi_base:o?r:null,claude_base:c?l:null,projects:u,count:u.length},s)}async function Ji(n,e,s,i){let t=Qt(),r=null,o="claude";if(Z.existsSync(t)){let d=Ae.join(t,n);if(Z.existsSync(d))r=d,o="pi";else try{let u=Z.readdirSync(t,{withFileTypes:!0}).filter(f=>f.isDirectory());for(let f of u){let m=Xt(f.name);if(m.endsWith("/"+n)||m===n||f.name===n){r=Ae.join(t,f.name),o="pi";break}}}catch{}}if(!r){let d=Zt(i),u=Ae.join(d,n);Z.existsSync(u)&&(r=u,o="claude")}if(!r){h({error:`Project not found: ${n}`,available_projects:[]},s);return}let a=[],l=Z.readdirSync(r).filter(d=>d.endsWith(".jsonl")),c=e.limit??null;for(let d of l){if(e.sessionId&&!d.includes(e.sessionId))continue;let u=Ae.join(r,d);if(o==="pi"||zi(u))try{let f=Z.readFileSync(u,"utf-8").split(`
339
+ `).filter(Boolean);for(let m of f)try{let p=JSON.parse(m);if(p.type==="message"&&p.message&&(a.push(p.message),c&&a.length>=c))break}catch{}}catch{}else try{let f=Z.readFileSync(u,"utf-8").split(`
340
+ `).filter(Boolean);for(let m of f)try{let p=JSON.parse(m);if(a.push(p),c&&a.length>=c)break}catch{}}catch{}if(c&&a.length>=c)break}h({project:n,source:o,messages:a,count:a.length},s)}async function Yi(n,e,s){let t=(e.harness??null)==="pi",r=e.limit??150,o=e.maxChars??500,a=[],l=Qt();if(Z.existsSync(l))try{let d=Z.readdirSync(l,{withFileTypes:!0}).filter(u=>u.isDirectory());e:for(let u of d){let f=Ae.join(l,u.name),m=Z.readdirSync(f).filter(y=>y.endsWith(".jsonl")),p=0;for(let y of m){let g=Hi(Ae.join(f,y));for(let _ of g)if(_.message?.role==="user"){let b=Vi(_.message.content).slice(0,o);if(b.length>20){if(a.push({project:Xt(u.name),text:b,source:"pi"}),p++,e.maxPerProject&&p>=e.maxPerProject)break;if(a.length>=r)break e}}}}}catch{}if(!(t&&!n&&a.length>=r)){let d=Zt(n);if(Z.existsSync(d))try{let u=Z.readdirSync(d,{withFileTypes:!0}).filter(f=>f.isDirectory());e:for(let f of u){let m=Ae.join(d,f.name),p=Z.readdirSync(m).filter(g=>g.endsWith(".jsonl")),y=0;for(let g of p)try{let _=Z.readFileSync(Ae.join(m,g),"utf-8").split(`
341
+ `).filter(Boolean);for(let b of _)try{let v=JSON.parse(b);if(v.role==="human"||v.type==="human"){let P=(v.content||v.message||"").slice(0,o);if(P.length>20){if(a.push({project:f.name,text:P,source:"claude"}),y++,e.maxPerProject&&y>=e.maxPerProject)break;if(a.length>=r)break e}}}catch{}}catch{}}}catch{}}if(a.length===0){h({available:!1,reason:"No user messages found in any session",samples:[],count:0},s);return}h({available:!0,samples:a,count:a.length},s)}var Z,Ae,Rt=le(()=>{"use strict";pe();Z=require("fs"),Ae=require("path")});var nt={};fe(nt,{cmdGenerateClaudeMd:()=>tr,cmdGenerateClaudeProfile:()=>er,cmdGenerateDevPreferences:()=>Xi,cmdProfileQuestionnaire:()=>Qi,cmdWriteProfile:()=>Zi});function Ct(n,e,s="CLAUDE.md"){return e?Ce.default.resolve(e):Ce.default.join(n,s)}function en(n,e){if(!n)return null;let s=Ce.default.isAbsolute(n)?n:Ce.default.join(e,n);if(!ze.default.existsSync(s))return null;try{return JSON.parse(ze.default.readFileSync(s,"utf-8"))}catch{return null}}function Ki(n){return n.map(e=>`## ${e.heading}
342
342
 
343
343
  ${e.body}`).join(`
344
344
 
@@ -375,9 +375,9 @@ See \`.planning/PROJECT.md\` for project overview.
375
375
  ## GSD Integration
376
376
 
377
377
  This project uses GSD (Get Shit Done) for structured development. Run \`/gsd-help\` to see available commands.
378
- `;ze.default.writeFileSync(t,o,"utf-8"),h({written:!0,path:z(Ce.default.relative(n,t))},s,t)}var ze,Ce,st=le(()=>{"use strict";ze=W(require("fs")),Ce=W(require("path"));fe()});var En={};pe(En,{cmdWorkstreamComplete:()=>or,cmdWorkstreamCreate:()=>sr,cmdWorkstreamGet:()=>lr,cmdWorkstreamList:()=>ir,cmdWorkstreamProgress:()=>cr,cmdWorkstreamSet:()=>ar,cmdWorkstreamStatus:()=>rr});function nr(n,e){if(!e||/[/\\]/.test(e)||e==="."||e==="..")throw new Error("Invalid workstream name for migration");let s=J(n),i=w.default.join(s,"workstreams",e);if(E.default.existsSync(w.default.join(s,"workstreams")))throw new Error("Already in workstream mode - .planning/workstreams/ exists");let t=[{name:"ROADMAP.md",type:"file"},{name:"STATE.md",type:"file"},{name:"REQUIREMENTS.md",type:"file"},{name:"phases",type:"dir"}];E.default.mkdirSync(i,{recursive:!0});let r=[];try{for(let o of t){let a=w.default.join(s,o.name);E.default.existsSync(a)&&(E.default.renameSync(a,w.default.join(i,o.name)),r.push(o.name))}}catch(o){for(let a of r)try{E.default.renameSync(w.default.join(i,a),w.default.join(s,a))}catch{}try{E.default.rmSync(i,{recursive:!0})}catch{}try{E.default.rmdirSync(w.default.join(s,"workstreams"))}catch{}throw o}return{migrated:!0,workstream:e,files_moved:r}}function sr(n,e,s,i){e||S("workstream name required. Usage: workstream create <name>");let t=e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");t||S("Invalid workstream name - must contain at least one alphanumeric character");let r=J(n);E.default.existsSync(r)||S(".planning/ directory not found - run /gsd-new-project first");let o=w.default.join(r,"workstreams"),a=w.default.join(o,t);if(E.default.existsSync(a)&&E.default.existsSync(w.default.join(a,"STATE.md"))){h({created:!1,error:"already_exists",workstream:t,path:z(w.default.relative(n,a))},i);return}let l=!E.default.existsSync(o),c=null;if(l&&s.migrate!==!1)if(E.default.existsSync(w.default.join(r,"ROADMAP.md"))||E.default.existsSync(w.default.join(r,"STATE.md"))||E.default.existsSync(w.default.join(r,"phases"))){let y=s.migrateName??null,g;if(y)g=y;else try{let _=ie(n);g=Te(_.name)||"default"}catch{g="default"}try{c=nr(n,g)}catch(_){h({created:!1,error:"migration_failed",message:_.message},i);return}}else E.default.mkdirSync(o,{recursive:!0});E.default.mkdirSync(a,{recursive:!0}),E.default.mkdirSync(w.default.join(a,"phases"),{recursive:!0});let d=new Date().toISOString().split("T")[0],u=["---",`workstream: ${t}`,`created: ${d}`,"---","","# Project State","","## Current Position","**Status:** Not started","**Current Phase:** None",`**Last Activity:** ${d}`,"**Last Activity Description:** Workstream created","","## Progress","**Phases Complete:** 0","**Current Plan:** N/A","","## Session Continuity","**Stopped At:** N/A","**Resume File:** None",""].join(`
379
- `),p=w.default.join(a,"STATE.md");E.default.existsSync(p)||E.default.writeFileSync(p,u,"utf-8"),Ke(n,t);let m=z(w.default.relative(n,a));h({created:!0,workstream:t,path:m,state_path:m+"/STATE.md",phases_path:m+"/phases",migration:c??null,active:!0},i)}function ir(n,e){let s=w.default.join(J(n),"workstreams");if(!E.default.existsSync(s)){h({mode:"flat",workstreams:[],message:"No workstreams - operating in flat mode"},e);return}let i=[];for(let t of E.default.readdirSync(s,{withFileTypes:!0}).filter(r=>r.isDirectory())){let r=w.default.join(s,t.name),o=w.default.join(r,"phases"),a=Oe(o),l=0;for(let u of a)try{let p=E.default.readdirSync(w.default.join(o,u)),m=at(p),f=lt(p);m.length>0&&f.length>=m.length&&l++}catch{}let c="unknown",d=null;try{let u=E.default.readFileSync(w.default.join(r,"STATE.md"),"utf-8");c=V(u,"Status")||"unknown",d=V(u,"Current Phase")}catch{}i.push({name:t.name,path:z(w.default.relative(n,r)),has_roadmap:E.default.existsSync(w.default.join(r,"ROADMAP.md")),has_state:E.default.existsSync(w.default.join(r,"STATE.md")),status:c,current_phase:d,phase_count:a.length,completed_phases:l})}h({mode:"workstream",workstreams:i,count:i.length},e)}function rr(n,e,s){e||S("workstream name required. Usage: workstream status <name>"),(/[/\\]/.test(e)||e==="."||e==="..")&&S("Invalid workstream name");let i=w.default.join(J(n),"workstreams",e);if(!E.default.existsSync(i)){h({found:!1,workstream:e},s);return}let t=R(n,e),r={roadmap:E.default.existsSync(t.roadmap),state:E.default.existsSync(t.state),requirements:E.default.existsSync(t.requirements)},o=[];for(let l of Oe(t.phases).sort())try{let c=E.default.readdirSync(w.default.join(t.phases,l)),d=at(c),u=lt(c);o.push({directory:l,status:u.length>=d.length&&d.length>0?"complete":d.length>0?"in_progress":"pending",plan_count:d.length,summary_count:u.length})}catch{}let a={status:"unknown",current_phase:null,last_activity:null};try{let l=E.default.readFileSync(t.state,"utf-8");a={status:V(l,"Status")||"unknown",current_phase:V(l,"Current Phase"),last_activity:V(l,"Last Activity")}}catch{}h({found:!0,workstream:e,path:z(w.default.relative(n,i)),files:r,phases:o,phase_count:o.length,completed_phases:o.filter(l=>l.status==="complete").length,...a},s)}function or(n,e,s,i){e||S("workstream name required. Usage: workstream complete <name>"),(/[/\\]/.test(e)||e==="."||e==="..")&&S("Invalid workstream name");let t=J(n),r=w.default.join(t,"workstreams"),o=w.default.join(r,e);if(!E.default.existsSync(o)){h({completed:!1,error:"not_found",workstream:e},i);return}let a=Ye(n);a===e&&Ke(n,null);let l=w.default.join(t,"milestones"),c=new Date().toISOString().split("T")[0],d=w.default.join(l,`ws-${e}-${c}`),u=1;for(;E.default.existsSync(d);)d=w.default.join(l,`ws-${e}-${c}-${u++}`);E.default.mkdirSync(d,{recursive:!0});let p=[];try{for(let f of E.default.readdirSync(o,{withFileTypes:!0}))E.default.renameSync(w.default.join(o,f.name),w.default.join(d,f.name)),p.push(f.name)}catch(f){for(let y of p)try{E.default.renameSync(w.default.join(d,y),w.default.join(o,y))}catch{}try{E.default.rmSync(d,{recursive:!0})}catch{}a===e&&Ke(n,e),h({completed:!1,error:"archive_failed",message:f.message,workstream:e},i);return}try{E.default.rmdirSync(o)}catch{}let m=0;try{m=E.default.readdirSync(r,{withFileTypes:!0}).filter(f=>f.isDirectory()).length,m===0&&E.default.rmdirSync(r)}catch{}h({completed:!0,workstream:e,archived_to:z(w.default.relative(n,d)),remaining_workstreams:m,reverted_to_flat:m===0},i)}function ar(n,e,s){if(!e){Ke(n,null),h({active:null,cleared:!0},s);return}if(!/^[a-zA-Z0-9_-]+$/.test(e)){h({active:null,error:"invalid_name",message:"Workstream name must be alphanumeric, hyphens, and underscores only"},s);return}let i=w.default.join(J(n),"workstreams",e);if(!E.default.existsSync(i)){h({active:null,error:"not_found",workstream:e},s);return}Ke(n,e),h({active:e,set:!0},s,e)}function lr(n,e){let s=Ye(n),i=w.default.join(J(n),"workstreams");h({active:s,mode:E.default.existsSync(i)?"workstream":"flat"},e,s||"none")}function cr(n,e){let s=J(n),i=w.default.join(s,"workstreams");if(!E.default.existsSync(i)){h({mode:"flat",workstreams:[],message:"No workstreams - operating in flat mode"},e);return}let t=Ye(n),r=[];for(let o of E.default.readdirSync(i,{withFileTypes:!0}).filter(a=>a.isDirectory())){let a=w.default.join(i,o.name),l=w.default.join(a,"phases"),c=Oe(l),d=0,u=0,p=0;for(let g of c)try{let _=E.default.readdirSync(w.default.join(l,g)),b=at(_),v=lt(_);u+=b.length,p+=Math.min(v.length,b.length),b.length>0&&v.length>=b.length&&d++}catch{}let m=c.length;try{let _=E.default.readFileSync(w.default.join(a,"ROADMAP.md"),"utf-8").match(/^###?\s+Phase\s+\d/gm);_&&(m=_.length)}catch{}let f="unknown",y=null;try{let g=E.default.readFileSync(w.default.join(a,"STATE.md"),"utf-8");f=V(g,"Status")||"unknown",y=V(g,"Current Phase")}catch{}r.push({name:o.name,active:o.name===t,status:f,current_phase:y,phases:`${d}/${m}`,plans:`${p}/${u}`,progress_percent:m>0?Math.round(d/m*100):0})}h({mode:"workstream",active:t,workstreams:r,count:r.length},e)}var E,w,wn=le(()=>{"use strict";E=W(require("fs")),w=W(require("path"));fe();Be()});var Fe=W(require("fs")),it=W(require("path"));fe();var dn=require("jsonpath-plus");function un(n,e,s){let i=n;if(s&&(i=(0,dn.JSONPath)({path:s,json:n,wrap:!1})),e==="toon"){let{encode:t}=require("@toon-format/toon");return t(i)}return JSON.stringify(i,null,2)}function xe(n,e=[],s=[]){let i={};for(let t of e){let r=n.indexOf(`--${t}`);i[t]=r!==-1&&n[r+1]!==void 0&&!n[r+1].startsWith("--")?n[r+1]:null}for(let t of s)i[t]=n.includes(`--${t}`);return i}function Mn(n,e){let s=n.indexOf(`--${e}`);if(s===-1)return null;let i=[];for(let t=s+1;t<n.length&&!n[t].startsWith("--");t++)i.push(n[t]);return i.length>0?i.join(" "):null}function dr(n,e){let s=e.split("."),i=n;for(let t of s){if(i==null)return;let r=t.match(/^(.+?)\[(-?\d+)]$/);if(r){let o=r[1],a=parseInt(r[2],10);if(i=i[o],!Array.isArray(i))return;i=a<0?i[i.length+a]:i[a]}else i=i[t]}return i}async function ur(){let n=process.argv.slice(2),e=process.cwd(),s=n.find(_=>_.startsWith("--cwd=")),i=n.indexOf("--cwd");if(s){let _=s.slice(6).trim();_||S("Missing value for --cwd"),n.splice(n.indexOf(s),1),e=it.default.resolve(_)}else if(i!==-1){let _=n[i+1];(!_||_.startsWith("--"))&&S("Missing value for --cwd"),n.splice(i,2),e=it.default.resolve(_)}if((!Fe.default.existsSync(e)||!Fe.default.statSync(e).isDirectory())&&S(`Invalid --cwd: ${e}`),!Fe.default.existsSync(it.default.join(e,".planning"))){let _=cn(e);_!==e&&(e=_)}let t=n.find(_=>_.startsWith("--ws=")),r=n.indexOf("--ws"),o=null;t?(o=t.slice(5).trim(),o||S("Missing value for --ws"),n.splice(n.indexOf(t),1)):r!==-1?(o=n[r+1],(!o||o.startsWith("--"))&&S("Missing value for --ws"),n.splice(r,2)):process.env.GSD_WORKSTREAM?o=process.env.GSD_WORKSTREAM.trim():o=Ye(e),o&&!/^[a-zA-Z0-9_-]+$/.test(o)&&S("Invalid workstream name"),o&&(process.env.GSD_WORKSTREAM=o);let a=n.indexOf("--raw"),l=a!==-1;a!==-1&&n.splice(a,1);let c="json",d=n.findIndex(_=>_==="--output"||_==="-o");if(d!==-1){let _=n[d+1];(!_||_.startsWith("--"))&&S("Missing value for --output"),_!=="json"&&_!=="toon"&&S('--output must be "json" or "toon"'),c=_,n.splice(d,2)}let u=null,p=n.findIndex(_=>_==="--pick"||_==="-p");p!==-1&&(u=n[p+1],(!u||u.startsWith("--"))&&S("Missing value for --pick"),n.splice(p,2));let m=n.indexOf("--pick"),f=null;m!==-1&&(f=n[m+1],(!f||f.startsWith("--"))&&S("Missing value for --pick"),n.splice(m,2));let y=n[0];if(y||S(`Usage: pi-gsd-tools <command> [args] [--raw] [--output json|toon] [--pick <path>] [--cwd <path>] [--ws <name>]
380
- Commands: state, resolve-model, find-phase, commit, verify, frontmatter, template, generate-slug, current-timestamp, list-todos, verify-path-exists, config-ensure-section, init, workstream, phase, roadmap, milestone, scaffold, progress, audit-uat, uat, validate, stats, todo, frontmatter, verify-summary`),new Set(["generate-slug","current-timestamp","verify-path-exists","verify-summary","template","frontmatter","generate-model-profiles-md"]).has(y)||(e=ln(e)),f||u||c!=="json"){let _=Fe.default.writeSync.bind(Fe.default),b=[];Fe.default.writeSync=(P,k,...$)=>P===1?(b.push(String(k)),String(k).length):_(P,k,...$);let v=()=>{Fe.default.writeSync=_;let P=b.join(""),k=P;k.startsWith("@file:")&&(k=Fe.default.readFileSync(k.slice(6),"utf-8"));try{let $=JSON.parse(k),D=$;f&&(D=dr($,f)??"");let A=un(D,c,u??void 0);_(1,A)}catch{_(1,P)}};try{await Fn(y,n,e,l),v()}catch(P){throw Fe.default.writeSync=_,P}return}await Fn(y,n,e,l)}async function Fn(n,e,s,i){switch(n){case"state":{let t=await Promise.resolve().then(()=>(Be(),Ut)),r=e[1];if(r==="json")t.cmdStateJson(s,i);else if(r==="update")t.cmdStateUpdate(s,e[2],e[3]);else if(r==="get")t.cmdStateGet(s,e[2],i);else if(r==="patch"){let o={};for(let a=2;a<e.length;a+=2){let l=e[a].replace(/^--/,"");l&&e[a+1]!==void 0&&(o[l]=e[a+1])}t.cmdStatePatch(s,o,i)}else if(r==="advance-plan")t.cmdStateAdvancePlan(s,i);else if(r==="record-metric"){let{phase:o,plan:a,duration:l,tasks:c,files:d}=xe(e,["phase","plan","duration","tasks","files"]);t.cmdStateRecordMetric(s,{phase:o,plan:a,duration:l,tasks:c,files:d},i)}else if(r==="update-progress")t.cmdStateUpdateProgress(s,i);else if(r==="add-decision"){let{phase:o,summary:a,"summary-file":l,rationale:c,"rationale-file":d}=xe(e,["phase","summary","summary-file","rationale","rationale-file"]);t.cmdStateAddDecision(s,{phase:o,summary:a,summary_file:l,rationale:c||"",rationale_file:d},i)}else if(r==="add-blocker"){let{text:o,"text-file":a}=xe(e,["text","text-file"]);t.cmdStateAddBlocker(s,{text:o,text_file:a},i)}else if(r==="resolve-blocker")t.cmdStateResolveBlocker(s,xe(e,["text"]).text,i);else if(r==="record-session"){let{"stopped-at":o,"resume-file":a}=xe(e,["stopped-at","resume-file"]);t.cmdStateRecordSession(s,{stopped_at:o,resume_file:a||"None"},i)}else if(r==="begin-phase"){let{phase:o,name:a,plans:l}=xe(e,["phase","name","plans"]);t.cmdStateBeginPhase(s,o,a,l!==null?parseInt(l,10):null,i)}else if(r==="signal-waiting"){let{type:o,question:a,options:l,phase:c}=xe(e,["type","question","options","phase"]);t.cmdSignalWaiting(s,o,a,l,c,i)}else r==="signal-resume"?t.cmdSignalResume(s,i):t.cmdStateLoad(s,i);break}case"resolve-model":{let{cmdResolveModel:t}=await Promise.resolve().then(()=>(ye(),ge));t(s,e[1],i);break}case"find-phase":{let{cmdFindPhase:t}=await Promise.resolve().then(()=>(ut(),dt));t(s,e[1],i);break}case"commit":{let{cmdCommit:t}=await Promise.resolve().then(()=>(ye(),ge)),r=e.includes("--amend"),o=e.includes("--no-verify"),a=e.indexOf("--files"),l=a!==-1?a:e.length,d=e.slice(1,l).filter(p=>!p.startsWith("--")).join(" ")||void 0,u=a!==-1?e.slice(a+1).filter(p=>!p.startsWith("--")):[];t(s,d,u,i,r,o);break}case"commit-to-subrepo":{let{cmdCommitToSubrepo:t}=await Promise.resolve().then(()=>(ye(),ge)),r=e.indexOf("--files"),o=r!==-1?e.slice(r+1).filter(a=>!a.startsWith("--")):[];t(s,e[1],o,i);break}case"verify-summary":{let{cmdVerifySummary:t}=await Promise.resolve().then(()=>($t(),Pt)),r=e.indexOf("--check-count"),o=r!==-1?parseInt(e[r+1],10):2;t(s,e[1],o,i);break}case"template":{let{cmdTemplateSelect:t,cmdTemplateFill:r}=await Promise.resolve().then(()=>(xn(),bn)),o=e[1];if(o==="select")t(s,e[2],i);else if(o==="fill"){let a=e[2],{phase:l,plan:c,name:d,type:u,wave:p,fields:m}=xe(e,["phase","plan","name","type","wave","fields"]),f={};if(m){let{safeJsonParse:y}=await Promise.resolve().then(()=>(ct(),fn)),g=y(m,{label:"--fields"});g.ok||S(g.error),f=g.value}r(s,a,{phase:l,plan:c,name:d,fields:f,type:u||"execute",wave:p||"1"},i)}else S("Unknown template subcommand. Available: select, fill");break}case"frontmatter":{let t=await Promise.resolve().then(()=>(Ue(),mn)),r=e[1],o=e[2];if(r==="get")t.cmdFrontmatterGet(s,o,xe(e,["field"]).field,i);else if(r==="set"){let{field:a,value:l}=xe(e,["field","value"]);t.cmdFrontmatterSet(s,o,a??void 0,l??void 0,i)}else r==="merge"?t.cmdFrontmatterMerge(s,o,xe(e,["data"]).data??void 0,i):r==="validate"?t.cmdFrontmatterValidate(s,o,xe(e,["schema"]).schema??void 0,i):S("Unknown frontmatter subcommand. Available: get, set, merge, validate");break}case"verify":{let t=await Promise.resolve().then(()=>($t(),Pt)),r=e[1];r==="plan-structure"?t.cmdVerifyPlanStructure(s,e[2],i):r==="phase-completeness"?t.cmdVerifyPhaseCompleteness(s,e[2],i):r==="references"?t.cmdVerifyReferences(s,e[2],i):r==="commits"?t.cmdVerifyCommits(s,e.slice(2),i):r==="artifacts"?t.cmdVerifyArtifacts(s,e[2],i):r==="key-links"?t.cmdVerifyKeyLinks(s,e[2],i):S("Unknown verify subcommand. Available: plan-structure, phase-completeness, references, commits, artifacts, key-links");break}case"generate-slug":{let{cmdGenerateSlug:t}=await Promise.resolve().then(()=>(ye(),ge));t(e[1],i);break}case"current-timestamp":{let{cmdCurrentTimestamp:t}=await Promise.resolve().then(()=>(ye(),ge));t(e[1]||"full",i);break}case"list-todos":{let{cmdListTodos:t}=await Promise.resolve().then(()=>(ye(),ge));t(s,e[1],i);break}case"verify-path-exists":{let{cmdVerifyPathExists:t}=await Promise.resolve().then(()=>(ye(),ge));t(s,e[1],i);break}case"config-ensure-section":{let{cmdConfigEnsureSection:t}=await Promise.resolve().then(()=>(tt(),et));t(s,i);break}case"config-set":{let{cmdConfigSet:t}=await Promise.resolve().then(()=>(tt(),et));t(s,e[1],e[2],i);break}case"config-set-model-profile":{let{cmdConfigSetModelProfile:t}=await Promise.resolve().then(()=>(tt(),et));t(s,e[1],i);break}case"config-get":{let{cmdConfigGet:t}=await Promise.resolve().then(()=>(tt(),et));t(s,e[1],i);break}case"config-new-project":{let{cmdConfigNewProject:t}=await Promise.resolve().then(()=>(tt(),et));t(s,e[1],i);break}case"agent-skills":{let{cmdAgentSkills:t}=await Promise.resolve().then(()=>(Ht(),Vt));t(s,e[1],i);break}case"history-digest":{let{cmdHistoryDigest:t}=await Promise.resolve().then(()=>(ye(),ge));t(s,i);break}case"phases":{let{cmdPhasesList:t}=await Promise.resolve().then(()=>(ut(),dt));if(e[1]==="list"){let o=e.indexOf("--type"),a=e.indexOf("--phase");t(s,{type:o!==-1?e[o+1]:null,phase:a!==-1?e[a+1]:null,includeArchived:e.includes("--include-archived")},i)}else S("Unknown phases subcommand. Available: list");break}case"roadmap":{let t=await Promise.resolve().then(()=>(Rn(),jn)),r=e[1];r==="get-phase"?t.cmdRoadmapGetPhase(s,e[2],i):r==="analyze"?t.cmdRoadmapAnalyze(s,i):r==="update-plan-progress"?t.cmdRoadmapUpdatePlanProgress(s,e[2],i):S("Unknown roadmap subcommand. Available: get-phase, analyze, update-plan-progress");break}case"requirements":{let{cmdRequirementsMarkComplete:t}=await Promise.resolve().then(()=>(Jt(),Bt));e[1]==="mark-complete"?t(s,e.slice(2),i):S("Unknown requirements subcommand. Available: mark-complete");break}case"phase":{let t=await Promise.resolve().then(()=>(ut(),dt)),r=e[1];if(r==="next-decimal")t.cmdPhaseNextDecimal(s,e[2],i);else if(r==="add"){let o=e.indexOf("--id"),a=null,l=[];for(let c=2;c<e.length;c++)e[c]==="--id"&&c+1<e.length?(a=e[c+1],c++):l.push(e[c]);t.cmdPhaseAdd(s,l.join(" "),i,a)}else r==="insert"?t.cmdPhaseInsert(s,e[2],e.slice(3).join(" "),i):r==="remove"?t.cmdPhaseRemove(s,e[2],{force:e.includes("--force")},i):r==="complete"?t.cmdPhaseComplete(s,e[2],i):S("Unknown phase subcommand. Available: next-decimal, add, insert, remove, complete");break}case"milestone":{let{cmdMilestoneComplete:t}=await Promise.resolve().then(()=>(Jt(),Bt));if(e[1]==="complete"){let r=Mn(e,"name");t(s,e[2],{name:r,archivePhases:e.includes("--archive-phases")},i)}else S("Unknown milestone subcommand. Available: complete");break}case"validate":{let t=await Promise.resolve().then(()=>($t(),Pt)),r=e[1];r==="consistency"?t.cmdValidateConsistency(s,i):r==="health"?t.cmdValidateHealth(s,{repair:e.includes("--repair")},i):r==="agents"?t.cmdValidateAgents(s,i):S("Unknown validate subcommand. Available: consistency, health, agents");break}case"progress":{let{cmdProgressRender:t}=await Promise.resolve().then(()=>(ye(),ge));t(s,e[1]||"json",i);break}case"audit-uat":{let{cmdAuditUat:t}=await Promise.resolve().then(()=>(Kt(),Yt));t(s,i);break}case"uat":{let t=await Promise.resolve().then(()=>(Kt(),Yt));e[1]==="render-checkpoint"?t.cmdRenderCheckpoint(s,xe(e,["file"]),i):S("Unknown uat subcommand. Available: render-checkpoint");break}case"stats":{let{cmdStats:t}=await Promise.resolve().then(()=>(ye(),ge));t(s,e[1]||"json",i);break}case"todo":{let t=e[1];if(t==="complete"){let{cmdTodoComplete:r}=await Promise.resolve().then(()=>(ye(),ge));r(s,e[2],i)}else if(t==="match-phase"){let{cmdTodoMatchPhase:r}=await Promise.resolve().then(()=>(ye(),ge));r(s,e[2],i)}else S("Unknown todo subcommand. Available: complete, match-phase");break}case"scaffold":{let{cmdScaffold:t}=await Promise.resolve().then(()=>(ye(),ge));t(s,e[1],{phase:xe(e,["phase"]).phase,name:Mn(e,"name")},i);break}case"init":{let t=await Promise.resolve().then(()=>(Ht(),Vt)),r=e[1];switch(r){case"execute-phase":t.cmdInitExecutePhase(s,e[2],i);break;case"plan-phase":t.cmdInitPlanPhase(s,e[2],i);break;case"new-project":t.cmdInitNewProject(s,i);break;case"new-milestone":t.cmdInitNewMilestone(s,i);break;case"quick":t.cmdInitQuick(s,e.slice(2).join(" "),i);break;case"resume":t.cmdInitResume(s,i);break;case"verify-work":t.cmdInitVerifyWork(s,e[2],i);break;case"phase-op":t.cmdInitPhaseOp(s,e[2],i);break;case"todos":t.cmdInitTodos(s,e[2],i);break;case"milestone-op":t.cmdInitMilestoneOp(s,i);break;case"map-codebase":t.cmdInitMapCodebase(s,i);break;case"progress":t.cmdInitProgress(s,i);break;case"manager":t.cmdInitManager(s,i);break;case"new-workspace":t.cmdInitNewWorkspace(s,i);break;case"list-workspaces":t.cmdInitListWorkspaces(s,i);break;case"remove-workspace":t.cmdInitRemoveWorkspace(s,e[2],i);break;default:S(`Unknown init workflow: ${r}
381
- Available: execute-phase, plan-phase, new-project, new-milestone, quick, resume, verify-work, phase-op, todos, milestone-op, map-codebase, progress, manager, new-workspace, list-workspaces, remove-workspace`)}break}case"phase-plan-index":{let{cmdPhasePlanIndex:t}=await Promise.resolve().then(()=>(ut(),dt));t(s,e[1],i);break}case"state-snapshot":{let{cmdStateSnapshot:t}=await Promise.resolve().then(()=>(Be(),Ut));t(s,i);break}case"summary-extract":{let{cmdSummaryExtract:t}=await Promise.resolve().then(()=>(ye(),ge)),r=e.indexOf("--fields"),o=r!==-1?e[r+1].split(","):null;t(s,e[1],o,i);break}case"websearch":{let{cmdWebsearch:t}=await Promise.resolve().then(()=>(ye(),ge)),r=e.indexOf("--limit"),o=e.indexOf("--freshness");await t(e[1],{limit:r!==-1?parseInt(e[r+1],10):10,freshness:o!==-1?e[o+1]:null},i);break}case"scan-sessions":{let{cmdScanSessions:t}=await Promise.resolve().then(()=>(Rt(),jt)),r=e.indexOf("--path"),o=e.indexOf("--harness");await t(r!==-1?e[r+1]:null,{verbose:e.includes("--verbose"),json:e.includes("--json"),harness:o!==-1?e[o+1]:null},i);break}case"extract-messages":{let{cmdExtractMessages:t}=await Promise.resolve().then(()=>(Rt(),jt)),r=e.indexOf("--session"),o=e.indexOf("--limit"),a=e.indexOf("--path"),l=c=>c.startsWith("--")&&c.endsWith("--")&&c.length>4;(!e[1]||e[1].startsWith("--")&&!l(e[1]))&&S("Usage: pi-gsd-tools extract-messages <project> [--session <id>] [--limit N] [--path <dir>]"),await t(e[1],{sessionId:r!==-1?e[r+1]:null,limit:o!==-1?parseInt(e[o+1],10):null},i,a!==-1?e[a+1]:null);break}case"profile-sample":{let{cmdProfileSample:t}=await Promise.resolve().then(()=>(Rt(),jt)),r=e.indexOf("--path"),o=e.indexOf("--limit"),a=e.indexOf("--max-per-project"),l=e.indexOf("--max-chars"),c=e.indexOf("--harness");await t(r!==-1?e[r+1]:null,{limit:o!==-1?parseInt(e[o+1],10):150,maxPerProject:a!==-1?parseInt(e[a+1],10):null,harness:c!==-1?e[c+1]:null,maxChars:l!==-1?parseInt(e[l+1],10):500},i);break}case"write-profile":{let{cmdWriteProfile:t}=await Promise.resolve().then(()=>(st(),nt)),r=e.indexOf("--input"),o=e.indexOf("--output");r===-1&&S("--input <analysis-json-path> is required"),t(s,{input:e[r+1],output:o!==-1?e[o+1]:null},i);break}case"profile-questionnaire":{let{cmdProfileQuestionnaire:t}=await Promise.resolve().then(()=>(st(),nt)),r=e.indexOf("--answers");t({answers:r!==-1?e[r+1]:null},i);break}case"generate-dev-preferences":{let{cmdGenerateDevPreferences:t}=await Promise.resolve().then(()=>(st(),nt)),r=e.indexOf("--analysis"),o=e.indexOf("--output"),a=e.indexOf("--stack");t(s,{analysis:r!==-1?e[r+1]:null,output:o!==-1?e[o+1]:null,stack:a!==-1?e[a+1]:null},i);break}case"generate-claude-profile":{let{cmdGenerateClaudeProfile:t}=await Promise.resolve().then(()=>(st(),nt)),r=e.indexOf("--analysis"),o=e.indexOf("--output");t(s,{analysis:r!==-1?e[r+1]:null,output:o!==-1?e[o+1]:null,global:e.includes("--global")},i);break}case"generate-claude-md":{let{cmdGenerateClaudeMd:t}=await Promise.resolve().then(()=>(st(),nt)),r=e.indexOf("--output"),o=e.indexOf("--harness");t(s,{output:r!==-1?e[r+1]:null,auto:e.includes("--auto"),force:e.includes("--force"),harness:o!==-1?e[o+1]:null},i);break}case"workstream":{let t=await Promise.resolve().then(()=>(wn(),En)),r=e[1];if(r==="create"){let o=e.indexOf("--migrate-name");t.cmdWorkstreamCreate(s,e[2],{migrate:!e.includes("--no-migrate"),migrateName:o!==-1?e[o+1]:null},i)}else r==="list"?t.cmdWorkstreamList(s,i):r==="status"?t.cmdWorkstreamStatus(s,e[2],i):r==="complete"?t.cmdWorkstreamComplete(s,e[2],{},i):r==="set"?t.cmdWorkstreamSet(s,e[2],i):r==="get"?t.cmdWorkstreamGet(s,i):r==="progress"?t.cmdWorkstreamProgress(s,i):S("Unknown workstream subcommand. Available: create, list, status, complete, set, get, progress");break}case"generate-model-profiles-md":{let{generateModelProfilesMd:t,HARNESS_CONFIG:r}=await Promise.resolve().then(()=>(rt(),rn)),o=e.indexOf("--harness"),a=e.indexOf("--output"),l=e.includes("--stdout"),c=o!==-1?e[o+1]:null,d=a!==-1?e[a+1]:null;if(!c){let f=__dirname.match(/\.([a-z]+)\/gsd\/bin/);c=f?f[1]:"agent"}r[c]||S(`Unknown harness: "${c}". Valid values: ${Object.keys(r).join(", ")}`);let u=t(c);if(l){process.stdout.write(u);break}let p=d?it.default.resolve(d):it.default.resolve(__dirname,"..","references","model-profiles.md");import("fs").then(({writeFileSync:m})=>m(p,u,"utf-8")),Fe.default.writeFileSync(p,u,"utf-8"),i?process.stdout.write(p):process.stdout.write(`Wrote ${p}
378
+ `;ze.default.writeFileSync(t,o,"utf-8"),h({written:!0,path:z(Ce.default.relative(n,t))},s,t)}var ze,Ce,st=le(()=>{"use strict";ze=W(require("fs")),Ce=W(require("path"));pe()});var En={};fe(En,{cmdWorkstreamComplete:()=>or,cmdWorkstreamCreate:()=>sr,cmdWorkstreamGet:()=>lr,cmdWorkstreamList:()=>ir,cmdWorkstreamProgress:()=>cr,cmdWorkstreamSet:()=>ar,cmdWorkstreamStatus:()=>rr});function nr(n,e){if(!e||/[/\\]/.test(e)||e==="."||e==="..")throw new Error("Invalid workstream name for migration");let s=J(n),i=w.default.join(s,"workstreams",e);if(E.default.existsSync(w.default.join(s,"workstreams")))throw new Error("Already in workstream mode - .planning/workstreams/ exists");let t=[{name:"ROADMAP.md",type:"file"},{name:"STATE.md",type:"file"},{name:"REQUIREMENTS.md",type:"file"},{name:"phases",type:"dir"}];E.default.mkdirSync(i,{recursive:!0});let r=[];try{for(let o of t){let a=w.default.join(s,o.name);E.default.existsSync(a)&&(E.default.renameSync(a,w.default.join(i,o.name)),r.push(o.name))}}catch(o){for(let a of r)try{E.default.renameSync(w.default.join(i,a),w.default.join(s,a))}catch{}try{E.default.rmSync(i,{recursive:!0})}catch{}try{E.default.rmdirSync(w.default.join(s,"workstreams"))}catch{}throw o}return{migrated:!0,workstream:e,files_moved:r}}function sr(n,e,s,i){e||S("workstream name required. Usage: workstream create <name>");let t=e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");t||S("Invalid workstream name - must contain at least one alphanumeric character");let r=J(n);E.default.existsSync(r)||S(".planning/ directory not found - run /gsd-new-project first");let o=w.default.join(r,"workstreams"),a=w.default.join(o,t);if(E.default.existsSync(a)&&E.default.existsSync(w.default.join(a,"STATE.md"))){h({created:!1,error:"already_exists",workstream:t,path:z(w.default.relative(n,a))},i);return}let l=!E.default.existsSync(o),c=null;if(l&&s.migrate!==!1)if(E.default.existsSync(w.default.join(r,"ROADMAP.md"))||E.default.existsSync(w.default.join(r,"STATE.md"))||E.default.existsSync(w.default.join(r,"phases"))){let y=s.migrateName??null,g;if(y)g=y;else try{let _=ie(n);g=De(_.name)||"default"}catch{g="default"}try{c=nr(n,g)}catch(_){h({created:!1,error:"migration_failed",message:_.message},i);return}}else E.default.mkdirSync(o,{recursive:!0});E.default.mkdirSync(a,{recursive:!0}),E.default.mkdirSync(w.default.join(a,"phases"),{recursive:!0});let d=new Date().toISOString().split("T")[0],u=["---",`workstream: ${t}`,`created: ${d}`,"---","","# Project State","","## Current Position","**Status:** Not started","**Current Phase:** None",`**Last Activity:** ${d}`,"**Last Activity Description:** Workstream created","","## Progress","**Phases Complete:** 0","**Current Plan:** N/A","","## Session Continuity","**Stopped At:** N/A","**Resume File:** None",""].join(`
379
+ `),f=w.default.join(a,"STATE.md");E.default.existsSync(f)||E.default.writeFileSync(f,u,"utf-8"),Ke(n,t);let m=z(w.default.relative(n,a));h({created:!0,workstream:t,path:m,state_path:m+"/STATE.md",phases_path:m+"/phases",migration:c??null,active:!0},i)}function ir(n,e){let s=w.default.join(J(n),"workstreams");if(!E.default.existsSync(s)){h({mode:"flat",workstreams:[],message:"No workstreams - operating in flat mode"},e);return}let i=[];for(let t of E.default.readdirSync(s,{withFileTypes:!0}).filter(r=>r.isDirectory())){let r=w.default.join(s,t.name),o=w.default.join(r,"phases"),a=Oe(o),l=0;for(let u of a)try{let f=E.default.readdirSync(w.default.join(o,u)),m=at(f),p=lt(f);m.length>0&&p.length>=m.length&&l++}catch{}let c="unknown",d=null;try{let u=E.default.readFileSync(w.default.join(r,"STATE.md"),"utf-8");c=V(u,"Status")||"unknown",d=V(u,"Current Phase")}catch{}i.push({name:t.name,path:z(w.default.relative(n,r)),has_roadmap:E.default.existsSync(w.default.join(r,"ROADMAP.md")),has_state:E.default.existsSync(w.default.join(r,"STATE.md")),status:c,current_phase:d,phase_count:a.length,completed_phases:l})}h({mode:"workstream",workstreams:i,count:i.length},e)}function rr(n,e,s){e||S("workstream name required. Usage: workstream status <name>"),(/[/\\]/.test(e)||e==="."||e==="..")&&S("Invalid workstream name");let i=w.default.join(J(n),"workstreams",e);if(!E.default.existsSync(i)){h({found:!1,workstream:e},s);return}let t=R(n,e),r={roadmap:E.default.existsSync(t.roadmap),state:E.default.existsSync(t.state),requirements:E.default.existsSync(t.requirements)},o=[];for(let l of Oe(t.phases).sort())try{let c=E.default.readdirSync(w.default.join(t.phases,l)),d=at(c),u=lt(c);o.push({directory:l,status:u.length>=d.length&&d.length>0?"complete":d.length>0?"in_progress":"pending",plan_count:d.length,summary_count:u.length})}catch{}let a={status:"unknown",current_phase:null,last_activity:null};try{let l=E.default.readFileSync(t.state,"utf-8");a={status:V(l,"Status")||"unknown",current_phase:V(l,"Current Phase"),last_activity:V(l,"Last Activity")}}catch{}h({found:!0,workstream:e,path:z(w.default.relative(n,i)),files:r,phases:o,phase_count:o.length,completed_phases:o.filter(l=>l.status==="complete").length,...a},s)}function or(n,e,s,i){e||S("workstream name required. Usage: workstream complete <name>"),(/[/\\]/.test(e)||e==="."||e==="..")&&S("Invalid workstream name");let t=J(n),r=w.default.join(t,"workstreams"),o=w.default.join(r,e);if(!E.default.existsSync(o)){h({completed:!1,error:"not_found",workstream:e},i);return}let a=Ye(n);a===e&&Ke(n,null);let l=w.default.join(t,"milestones"),c=new Date().toISOString().split("T")[0],d=w.default.join(l,`ws-${e}-${c}`),u=1;for(;E.default.existsSync(d);)d=w.default.join(l,`ws-${e}-${c}-${u++}`);E.default.mkdirSync(d,{recursive:!0});let f=[];try{for(let p of E.default.readdirSync(o,{withFileTypes:!0}))E.default.renameSync(w.default.join(o,p.name),w.default.join(d,p.name)),f.push(p.name)}catch(p){for(let y of f)try{E.default.renameSync(w.default.join(d,y),w.default.join(o,y))}catch{}try{E.default.rmSync(d,{recursive:!0})}catch{}a===e&&Ke(n,e),h({completed:!1,error:"archive_failed",message:p.message,workstream:e},i);return}try{E.default.rmdirSync(o)}catch{}let m=0;try{m=E.default.readdirSync(r,{withFileTypes:!0}).filter(p=>p.isDirectory()).length,m===0&&E.default.rmdirSync(r)}catch{}h({completed:!0,workstream:e,archived_to:z(w.default.relative(n,d)),remaining_workstreams:m,reverted_to_flat:m===0},i)}function ar(n,e,s){if(!e){Ke(n,null),h({active:null,cleared:!0},s);return}if(!/^[a-zA-Z0-9_-]+$/.test(e)){h({active:null,error:"invalid_name",message:"Workstream name must be alphanumeric, hyphens, and underscores only"},s);return}let i=w.default.join(J(n),"workstreams",e);if(!E.default.existsSync(i)){h({active:null,error:"not_found",workstream:e},s);return}Ke(n,e),h({active:e,set:!0},s,e)}function lr(n,e){let s=Ye(n),i=w.default.join(J(n),"workstreams");h({active:s,mode:E.default.existsSync(i)?"workstream":"flat"},e,s||"none")}function cr(n,e){let s=J(n),i=w.default.join(s,"workstreams");if(!E.default.existsSync(i)){h({mode:"flat",workstreams:[],message:"No workstreams - operating in flat mode"},e);return}let t=Ye(n),r=[];for(let o of E.default.readdirSync(i,{withFileTypes:!0}).filter(a=>a.isDirectory())){let a=w.default.join(i,o.name),l=w.default.join(a,"phases"),c=Oe(l),d=0,u=0,f=0;for(let g of c)try{let _=E.default.readdirSync(w.default.join(l,g)),b=at(_),v=lt(_);u+=b.length,f+=Math.min(v.length,b.length),b.length>0&&v.length>=b.length&&d++}catch{}let m=c.length;try{let _=E.default.readFileSync(w.default.join(a,"ROADMAP.md"),"utf-8").match(/^###?\s+Phase\s+\d/gm);_&&(m=_.length)}catch{}let p="unknown",y=null;try{let g=E.default.readFileSync(w.default.join(a,"STATE.md"),"utf-8");p=V(g,"Status")||"unknown",y=V(g,"Current Phase")}catch{}r.push({name:o.name,active:o.name===t,status:p,current_phase:y,phases:`${d}/${m}`,plans:`${f}/${u}`,progress_percent:m>0?Math.round(d/m*100):0})}h({mode:"workstream",active:t,workstreams:r,count:r.length},e)}var E,w,wn=le(()=>{"use strict";E=W(require("fs")),w=W(require("path"));pe();Be()});var Fe=W(require("fs")),it=W(require("path"));pe();var dn=require("jsonpath-plus");function un(n,e,s){let i=n;if(s&&(i=(0,dn.JSONPath)({path:s,json:n,wrap:!1})),e==="toon"){let{encode:t}=require("@toon-format/toon");return t(i)}return JSON.stringify(i,null,2)}function xe(n,e=[],s=[]){let i={};for(let t of e){let r=n.indexOf(`--${t}`);i[t]=r!==-1&&n[r+1]!==void 0&&!n[r+1].startsWith("--")?n[r+1]:null}for(let t of s)i[t]=n.includes(`--${t}`);return i}function Mn(n,e){let s=n.indexOf(`--${e}`);if(s===-1)return null;let i=[];for(let t=s+1;t<n.length&&!n[t].startsWith("--");t++)i.push(n[t]);return i.length>0?i.join(" "):null}function dr(n,e){let s=e.split("."),i=n;for(let t of s){if(i==null)return;let r=t.match(/^(.+?)\[(-?\d+)]$/);if(r){let o=r[1],a=parseInt(r[2],10);if(i=i[o],!Array.isArray(i))return;i=a<0?i[i.length+a]:i[a]}else i=i[t]}return i}async function ur(){let n=process.argv.slice(2),e=process.cwd(),s=n.find(_=>_.startsWith("--cwd=")),i=n.indexOf("--cwd");if(s){let _=s.slice(6).trim();_||S("Missing value for --cwd"),n.splice(n.indexOf(s),1),e=it.default.resolve(_)}else if(i!==-1){let _=n[i+1];(!_||_.startsWith("--"))&&S("Missing value for --cwd"),n.splice(i,2),e=it.default.resolve(_)}if((!Fe.default.existsSync(e)||!Fe.default.statSync(e).isDirectory())&&S(`Invalid --cwd: ${e}`),!Fe.default.existsSync(it.default.join(e,".planning"))){let _=cn(e);_!==e&&(e=_)}let t=n.find(_=>_.startsWith("--ws=")),r=n.indexOf("--ws"),o=null;t?(o=t.slice(5).trim(),o||S("Missing value for --ws"),n.splice(n.indexOf(t),1)):r!==-1?(o=n[r+1],(!o||o.startsWith("--"))&&S("Missing value for --ws"),n.splice(r,2)):process.env.GSD_WORKSTREAM?o=process.env.GSD_WORKSTREAM.trim():o=Ye(e),o&&!/^[a-zA-Z0-9_-]+$/.test(o)&&S("Invalid workstream name"),o&&(process.env.GSD_WORKSTREAM=o);let a=n.indexOf("--raw"),l=a!==-1;a!==-1&&n.splice(a,1);let c="json",d=n.findIndex(_=>_==="--output"||_==="-o");if(d!==-1){let _=n[d+1];(!_||_.startsWith("--"))&&S("Missing value for --output"),_!=="json"&&_!=="toon"&&S('--output must be "json" or "toon"'),c=_,n.splice(d,2)}let u=null,f=n.findIndex(_=>_==="--pick"||_==="-p");f!==-1&&(u=n[f+1],(!u||u.startsWith("--"))&&S("Missing value for --pick"),n.splice(f,2));let m=n.indexOf("--pick"),p=null;m!==-1&&(p=n[m+1],(!p||p.startsWith("--"))&&S("Missing value for --pick"),n.splice(m,2));let y=n[0];if(y||S(`Usage: pi-gsd-tools <command> [args] [--raw] [--output json|toon] [--pick <path>] [--cwd <path>] [--ws <name>]
380
+ Commands: state, resolve-model, find-phase, commit, verify, frontmatter, template, generate-slug, current-timestamp, list-todos, verify-path-exists, config-ensure-section, init, workstream, phase, roadmap, milestone, scaffold, progress, audit-uat, uat, validate, stats, todo, frontmatter, verify-summary`),new Set(["generate-slug","current-timestamp","verify-path-exists","verify-summary","template","frontmatter","generate-model-profiles-md"]).has(y)||(e=ln(e)),p||u||c!=="json"){let _=Fe.default.writeSync.bind(Fe.default),b=[];Fe.default.writeSync=(P,k,...$)=>P===1?(b.push(String(k)),String(k).length):_(P,k,...$);let v=()=>{Fe.default.writeSync=_;let P=b.join(""),k=P;k.startsWith("@file:")&&(k=Fe.default.readFileSync(k.slice(6),"utf-8"));try{let $=JSON.parse(k),T=$;p&&(T=dr($,p)??"");let A=un(T,c,u??void 0);_(1,A)}catch{_(1,P)}};try{await Fn(y,n,e,l),v()}catch(P){throw Fe.default.writeSync=_,P}return}await Fn(y,n,e,l)}async function Fn(n,e,s,i){switch(n){case"state":{let t=await Promise.resolve().then(()=>(Be(),Ut)),r=e[1];if(r==="json")t.cmdStateJson(s,i);else if(r==="update")t.cmdStateUpdate(s,e[2],e[3]);else if(r==="get")t.cmdStateGet(s,e[2],i);else if(r==="patch"){let o={};for(let a=2;a<e.length;a+=2){let l=e[a].replace(/^--/,"");l&&e[a+1]!==void 0&&(o[l]=e[a+1])}t.cmdStatePatch(s,o,i)}else if(r==="advance-plan")t.cmdStateAdvancePlan(s,i);else if(r==="record-metric"){let{phase:o,plan:a,duration:l,tasks:c,files:d}=xe(e,["phase","plan","duration","tasks","files"]);t.cmdStateRecordMetric(s,{phase:o,plan:a,duration:l,tasks:c,files:d},i)}else if(r==="update-progress")t.cmdStateUpdateProgress(s,i);else if(r==="add-decision"){let{phase:o,summary:a,"summary-file":l,rationale:c,"rationale-file":d}=xe(e,["phase","summary","summary-file","rationale","rationale-file"]);t.cmdStateAddDecision(s,{phase:o,summary:a,summary_file:l,rationale:c||"",rationale_file:d},i)}else if(r==="add-blocker"){let{text:o,"text-file":a}=xe(e,["text","text-file"]);t.cmdStateAddBlocker(s,{text:o,text_file:a},i)}else if(r==="resolve-blocker")t.cmdStateResolveBlocker(s,xe(e,["text"]).text,i);else if(r==="record-session"){let{"stopped-at":o,"resume-file":a}=xe(e,["stopped-at","resume-file"]);t.cmdStateRecordSession(s,{stopped_at:o,resume_file:a||"None"},i)}else if(r==="begin-phase"){let{phase:o,name:a,plans:l}=xe(e,["phase","name","plans"]);t.cmdStateBeginPhase(s,o,a,l!==null?parseInt(l,10):null,i)}else if(r==="signal-waiting"){let{type:o,question:a,options:l,phase:c}=xe(e,["type","question","options","phase"]);t.cmdSignalWaiting(s,o,a,l,c,i)}else r==="signal-resume"?t.cmdSignalResume(s,i):t.cmdStateLoad(s,i);break}case"resolve-model":{let{cmdResolveModel:t}=await Promise.resolve().then(()=>(ye(),ge));t(s,e[1],i);break}case"find-phase":{let{cmdFindPhase:t}=await Promise.resolve().then(()=>(ut(),dt));t(s,e[1],i);break}case"commit":{let{cmdCommit:t}=await Promise.resolve().then(()=>(ye(),ge)),r=e.includes("--amend"),o=e.includes("--no-verify"),a=e.indexOf("--files"),l=a!==-1?a:e.length,d=e.slice(1,l).filter(f=>!f.startsWith("--")).join(" ")||void 0,u=a!==-1?e.slice(a+1).filter(f=>!f.startsWith("--")):[];t(s,d,u,i,r,o);break}case"commit-to-subrepo":{let{cmdCommitToSubrepo:t}=await Promise.resolve().then(()=>(ye(),ge)),r=e.indexOf("--files"),o=r!==-1?e.slice(r+1).filter(a=>!a.startsWith("--")):[];t(s,e[1],o,i);break}case"verify-summary":{let{cmdVerifySummary:t}=await Promise.resolve().then(()=>($t(),Pt)),r=e.indexOf("--check-count"),o=r!==-1?parseInt(e[r+1],10):2;t(s,e[1],o,i);break}case"template":{let{cmdTemplateSelect:t,cmdTemplateFill:r}=await Promise.resolve().then(()=>(xn(),bn)),o=e[1];if(o==="select")t(s,e[2],i);else if(o==="fill"){let a=e[2],{phase:l,plan:c,name:d,type:u,wave:f,fields:m}=xe(e,["phase","plan","name","type","wave","fields"]),p={};if(m){let{safeJsonParse:y}=await Promise.resolve().then(()=>(ct(),pn)),g=y(m,{label:"--fields"});g.ok||S(g.error),p=g.value}r(s,a,{phase:l,plan:c,name:d,fields:p,type:u||"execute",wave:f||"1"},i)}else S("Unknown template subcommand. Available: select, fill");break}case"frontmatter":{let t=await Promise.resolve().then(()=>(Ue(),mn)),r=e[1],o=e[2];if(r==="get")t.cmdFrontmatterGet(s,o,xe(e,["field"]).field,i);else if(r==="set"){let{field:a,value:l}=xe(e,["field","value"]);t.cmdFrontmatterSet(s,o,a??void 0,l??void 0,i)}else r==="merge"?t.cmdFrontmatterMerge(s,o,xe(e,["data"]).data??void 0,i):r==="validate"?t.cmdFrontmatterValidate(s,o,xe(e,["schema"]).schema??void 0,i):S("Unknown frontmatter subcommand. Available: get, set, merge, validate");break}case"verify":{let t=await Promise.resolve().then(()=>($t(),Pt)),r=e[1];r==="plan-structure"?t.cmdVerifyPlanStructure(s,e[2],i):r==="phase-completeness"?t.cmdVerifyPhaseCompleteness(s,e[2],i):r==="references"?t.cmdVerifyReferences(s,e[2],i):r==="commits"?t.cmdVerifyCommits(s,e.slice(2),i):r==="artifacts"?t.cmdVerifyArtifacts(s,e[2],i):r==="key-links"?t.cmdVerifyKeyLinks(s,e[2],i):S("Unknown verify subcommand. Available: plan-structure, phase-completeness, references, commits, artifacts, key-links");break}case"generate-slug":{let{cmdGenerateSlug:t}=await Promise.resolve().then(()=>(ye(),ge));t(e[1],i);break}case"current-timestamp":{let{cmdCurrentTimestamp:t}=await Promise.resolve().then(()=>(ye(),ge));t(e[1]||"full",i);break}case"list-todos":{let{cmdListTodos:t}=await Promise.resolve().then(()=>(ye(),ge));t(s,e[1],i);break}case"verify-path-exists":{let{cmdVerifyPathExists:t}=await Promise.resolve().then(()=>(ye(),ge));t(s,e[1],i);break}case"config-ensure-section":{let{cmdConfigEnsureSection:t}=await Promise.resolve().then(()=>(tt(),et));t(s,i);break}case"config-set":{let{cmdConfigSet:t}=await Promise.resolve().then(()=>(tt(),et));t(s,e[1],e[2],i);break}case"config-set-model-profile":{let{cmdConfigSetModelProfile:t}=await Promise.resolve().then(()=>(tt(),et));t(s,e[1],i);break}case"config-get":{let{cmdConfigGet:t}=await Promise.resolve().then(()=>(tt(),et));t(s,e[1],i);break}case"config-new-project":{let{cmdConfigNewProject:t}=await Promise.resolve().then(()=>(tt(),et));t(s,e[1],i);break}case"agent-skills":{let{cmdAgentSkills:t}=await Promise.resolve().then(()=>(Ht(),Vt));t(s,e[1],i);break}case"history-digest":{let{cmdHistoryDigest:t}=await Promise.resolve().then(()=>(ye(),ge));t(s,i);break}case"phases":{let{cmdPhasesList:t}=await Promise.resolve().then(()=>(ut(),dt));if(e[1]==="list"){let o=e.indexOf("--type"),a=e.indexOf("--phase");t(s,{type:o!==-1?e[o+1]:null,phase:a!==-1?e[a+1]:null,includeArchived:e.includes("--include-archived")},i)}else S("Unknown phases subcommand. Available: list");break}case"roadmap":{let t=await Promise.resolve().then(()=>(Rn(),jn)),r=e[1];r==="get-phase"?t.cmdRoadmapGetPhase(s,e[2],i):r==="analyze"?t.cmdRoadmapAnalyze(s,i):r==="update-plan-progress"?t.cmdRoadmapUpdatePlanProgress(s,e[2],i):S("Unknown roadmap subcommand. Available: get-phase, analyze, update-plan-progress");break}case"requirements":{let{cmdRequirementsMarkComplete:t}=await Promise.resolve().then(()=>(Jt(),Bt));e[1]==="mark-complete"?t(s,e.slice(2),i):S("Unknown requirements subcommand. Available: mark-complete");break}case"phase":{let t=await Promise.resolve().then(()=>(ut(),dt)),r=e[1];if(r==="next-decimal")t.cmdPhaseNextDecimal(s,e[2],i);else if(r==="add"){let o=e.indexOf("--id"),a=null,l=[];for(let c=2;c<e.length;c++)e[c]==="--id"&&c+1<e.length?(a=e[c+1],c++):l.push(e[c]);t.cmdPhaseAdd(s,l.join(" "),i,a)}else r==="insert"?t.cmdPhaseInsert(s,e[2],e.slice(3).join(" "),i):r==="remove"?t.cmdPhaseRemove(s,e[2],{force:e.includes("--force")},i):r==="complete"?t.cmdPhaseComplete(s,e[2],i):S("Unknown phase subcommand. Available: next-decimal, add, insert, remove, complete");break}case"milestone":{let{cmdMilestoneComplete:t}=await Promise.resolve().then(()=>(Jt(),Bt));if(e[1]==="complete"){let r=Mn(e,"name");t(s,e[2],{name:r,archivePhases:e.includes("--archive-phases")},i)}else S("Unknown milestone subcommand. Available: complete");break}case"validate":{let t=await Promise.resolve().then(()=>($t(),Pt)),r=e[1];r==="consistency"?t.cmdValidateConsistency(s,i):r==="health"?t.cmdValidateHealth(s,{repair:e.includes("--repair")},i):r==="agents"?t.cmdValidateAgents(s,i):S("Unknown validate subcommand. Available: consistency, health, agents");break}case"progress":{let{cmdProgressRender:t}=await Promise.resolve().then(()=>(ye(),ge));t(s,e[1]||"json",i);break}case"audit-uat":{let{cmdAuditUat:t}=await Promise.resolve().then(()=>(Kt(),Yt));t(s,i);break}case"uat":{let t=await Promise.resolve().then(()=>(Kt(),Yt));e[1]==="render-checkpoint"?t.cmdRenderCheckpoint(s,xe(e,["file"]),i):S("Unknown uat subcommand. Available: render-checkpoint");break}case"stats":{let{cmdStats:t}=await Promise.resolve().then(()=>(ye(),ge));t(s,e[1]||"json",i);break}case"todo":{let t=e[1];if(t==="complete"){let{cmdTodoComplete:r}=await Promise.resolve().then(()=>(ye(),ge));r(s,e[2],i)}else if(t==="match-phase"){let{cmdTodoMatchPhase:r}=await Promise.resolve().then(()=>(ye(),ge));r(s,e[2],i)}else S("Unknown todo subcommand. Available: complete, match-phase");break}case"scaffold":{let{cmdScaffold:t}=await Promise.resolve().then(()=>(ye(),ge));t(s,e[1],{phase:xe(e,["phase"]).phase,name:Mn(e,"name")},i);break}case"init":{let t=await Promise.resolve().then(()=>(Ht(),Vt)),r=e[1];switch(r){case"execute-phase":t.cmdInitExecutePhase(s,e[2],i);break;case"plan-phase":t.cmdInitPlanPhase(s,e[2],i);break;case"new-project":t.cmdInitNewProject(s,i);break;case"new-milestone":t.cmdInitNewMilestone(s,i);break;case"quick":t.cmdInitQuick(s,e.slice(2).join(" "),i);break;case"resume":t.cmdInitResume(s,i);break;case"verify-work":t.cmdInitVerifyWork(s,e[2],i);break;case"phase-op":t.cmdInitPhaseOp(s,e[2],i);break;case"todos":t.cmdInitTodos(s,e[2],i);break;case"milestone-op":t.cmdInitMilestoneOp(s,i);break;case"map-codebase":t.cmdInitMapCodebase(s,i);break;case"progress":t.cmdInitProgress(s,i);break;case"manager":t.cmdInitManager(s,i);break;case"new-workspace":t.cmdInitNewWorkspace(s,i);break;case"list-workspaces":t.cmdInitListWorkspaces(s,i);break;case"remove-workspace":t.cmdInitRemoveWorkspace(s,e[2],i);break;default:S(`Unknown init workflow: ${r}
381
+ Available: execute-phase, plan-phase, new-project, new-milestone, quick, resume, verify-work, phase-op, todos, milestone-op, map-codebase, progress, manager, new-workspace, list-workspaces, remove-workspace`)}break}case"phase-plan-index":{let{cmdPhasePlanIndex:t}=await Promise.resolve().then(()=>(ut(),dt));t(s,e[1],i);break}case"state-snapshot":{let{cmdStateSnapshot:t}=await Promise.resolve().then(()=>(Be(),Ut));t(s,i);break}case"summary-extract":{let{cmdSummaryExtract:t}=await Promise.resolve().then(()=>(ye(),ge)),r=e.indexOf("--fields"),o=r!==-1?e[r+1].split(","):null;t(s,e[1],o,i);break}case"websearch":{let{cmdWebsearch:t}=await Promise.resolve().then(()=>(ye(),ge)),r=e.indexOf("--limit"),o=e.indexOf("--freshness");await t(e[1],{limit:r!==-1?parseInt(e[r+1],10):10,freshness:o!==-1?e[o+1]:null},i);break}case"scan-sessions":{let{cmdScanSessions:t}=await Promise.resolve().then(()=>(Rt(),jt)),r=e.indexOf("--path"),o=e.indexOf("--harness");await t(r!==-1?e[r+1]:null,{verbose:e.includes("--verbose"),json:e.includes("--json"),harness:o!==-1?e[o+1]:null},i);break}case"extract-messages":{let{cmdExtractMessages:t}=await Promise.resolve().then(()=>(Rt(),jt)),r=e.indexOf("--session"),o=e.indexOf("--limit"),a=e.indexOf("--path"),l=c=>c.startsWith("--")&&c.endsWith("--")&&c.length>4;(!e[1]||e[1].startsWith("--")&&!l(e[1]))&&S("Usage: pi-gsd-tools extract-messages <project> [--session <id>] [--limit N] [--path <dir>]"),await t(e[1],{sessionId:r!==-1?e[r+1]:null,limit:o!==-1?parseInt(e[o+1],10):null},i,a!==-1?e[a+1]:null);break}case"profile-sample":{let{cmdProfileSample:t}=await Promise.resolve().then(()=>(Rt(),jt)),r=e.indexOf("--path"),o=e.indexOf("--limit"),a=e.indexOf("--max-per-project"),l=e.indexOf("--max-chars"),c=e.indexOf("--harness");await t(r!==-1?e[r+1]:null,{limit:o!==-1?parseInt(e[o+1],10):150,maxPerProject:a!==-1?parseInt(e[a+1],10):null,harness:c!==-1?e[c+1]:null,maxChars:l!==-1?parseInt(e[l+1],10):500},i);break}case"write-profile":{let{cmdWriteProfile:t}=await Promise.resolve().then(()=>(st(),nt)),r=e.indexOf("--input"),o=e.indexOf("--output");r===-1&&S("--input <analysis-json-path> is required"),t(s,{input:e[r+1],output:o!==-1?e[o+1]:null},i);break}case"profile-questionnaire":{let{cmdProfileQuestionnaire:t}=await Promise.resolve().then(()=>(st(),nt)),r=e.indexOf("--answers");t({answers:r!==-1?e[r+1]:null},i);break}case"generate-dev-preferences":{let{cmdGenerateDevPreferences:t}=await Promise.resolve().then(()=>(st(),nt)),r=e.indexOf("--analysis"),o=e.indexOf("--output"),a=e.indexOf("--stack");t(s,{analysis:r!==-1?e[r+1]:null,output:o!==-1?e[o+1]:null,stack:a!==-1?e[a+1]:null},i);break}case"generate-claude-profile":{let{cmdGenerateClaudeProfile:t}=await Promise.resolve().then(()=>(st(),nt)),r=e.indexOf("--analysis"),o=e.indexOf("--output");t(s,{analysis:r!==-1?e[r+1]:null,output:o!==-1?e[o+1]:null,global:e.includes("--global")},i);break}case"generate-claude-md":{let{cmdGenerateClaudeMd:t}=await Promise.resolve().then(()=>(st(),nt)),r=e.indexOf("--output"),o=e.indexOf("--harness");t(s,{output:r!==-1?e[r+1]:null,auto:e.includes("--auto"),force:e.includes("--force"),harness:o!==-1?e[o+1]:null},i);break}case"workstream":{let t=await Promise.resolve().then(()=>(wn(),En)),r=e[1];if(r==="create"){let o=e.indexOf("--migrate-name");t.cmdWorkstreamCreate(s,e[2],{migrate:!e.includes("--no-migrate"),migrateName:o!==-1?e[o+1]:null},i)}else r==="list"?t.cmdWorkstreamList(s,i):r==="status"?t.cmdWorkstreamStatus(s,e[2],i):r==="complete"?t.cmdWorkstreamComplete(s,e[2],{},i):r==="set"?t.cmdWorkstreamSet(s,e[2],i):r==="get"?t.cmdWorkstreamGet(s,i):r==="progress"?t.cmdWorkstreamProgress(s,i):S("Unknown workstream subcommand. Available: create, list, status, complete, set, get, progress");break}case"generate-model-profiles-md":{let{generateModelProfilesMd:t,HARNESS_CONFIG:r}=await Promise.resolve().then(()=>(rt(),rn)),o=e.indexOf("--harness"),a=e.indexOf("--output"),l=e.includes("--stdout"),c=o!==-1?e[o+1]:null,d=a!==-1?e[a+1]:null;if(!c){let p=__dirname.match(/\.([a-z]+)\/gsd\/bin/);c=p?p[1]:"agent"}r[c]||S(`Unknown harness: "${c}". Valid values: ${Object.keys(r).join(", ")}`);let u=t(c);if(l){process.stdout.write(u);break}let f=d?it.default.resolve(d):it.default.resolve(__dirname,"..","references","model-profiles.md");import("fs").then(({writeFileSync:m})=>m(f,u,"utf-8")),Fe.default.writeFileSync(f,u,"utf-8"),i?process.stdout.write(f):process.stdout.write(`Wrote ${f}
382
382
  `);break}default:S(`Unknown command: ${n}`)}}ur().catch(n=>{process.stderr.write("Fatal: "+n.message+`
383
383
  `),process.exit(1)});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-gsd",
3
- "version": "1.3.3",
3
+ "version": "1.3.4",
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": {