pi-gsd 2.1.0 → 2.1.2
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/dist/pi-gsd-tools.js +13 -13
- package/gsd/workflows/new-project.md +2 -2
- package/package.json +2 -2
package/dist/pi-gsd-tools.js
CHANGED
|
@@ -133,22 +133,22 @@ pi's \`"opus"\` alias maps to a specific model version. Organizations may block
|
|
|
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 Me,vt,Mi,Ii,Ot=L(()=>{"use strict";Me={"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"}},vt=Object.keys(Me["gsd-planner"]),Mi="/gsd-",Ii="pi"});var Sr={};xe(Sr,{MODEL_ALIAS_MAP:()=>gr,MODEL_PROFILES:()=>Me,checkAgentsInstalled:()=>_t,comparePhaseNum:()=>Se,detectSubRepos:()=>Ms,escapeRegex:()=>ie,execGit:()=>de,extractCurrentMilestone:()=>we,extractOneLinerFromBody:()=>Vt,filterPlanFiles:()=>wt,filterSummaryFiles:()=>kt,findPhaseInternal:()=>he,findProjectRoot:()=>qt,generateSlugInternal:()=>Le,getActiveWorkstream:()=>Ke,getAgentsDir:()=>yr,getArchivedPhaseDirs:()=>Ut,getMilestoneInfo:()=>ce,getMilestonePhaseFilter:()=>ke,getPhaseFileStats:()=>xr,getRoadmapPhaseInternal:()=>
|
|
136
|
+
`}var Me,vt,Mi,Ii,Ot=L(()=>{"use strict";Me={"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"}},vt=Object.keys(Me["gsd-planner"]),Mi="/gsd-",Ii="pi"});var Sr={};xe(Sr,{MODEL_ALIAS_MAP:()=>gr,MODEL_PROFILES:()=>Me,checkAgentsInstalled:()=>_t,comparePhaseNum:()=>Se,detectSubRepos:()=>Ms,escapeRegex:()=>ie,execGit:()=>de,extractCurrentMilestone:()=>we,extractOneLinerFromBody:()=>Vt,filterPlanFiles:()=>wt,filterSummaryFiles:()=>kt,findPhaseInternal:()=>he,findProjectRoot:()=>qt,generateSlugInternal:()=>Le,getActiveWorkstream:()=>Ke,getAgentsDir:()=>yr,getArchivedPhaseDirs:()=>Ut,getMilestoneInfo:()=>ce,getMilestonePhaseFilter:()=>ke,getPhaseFileStats:()=>xr,getRoadmapPhaseInternal:()=>ut,gsdError:()=>b,isGitIgnored:()=>rn,loadConfig:()=>Q,normalizeMd:()=>Ie,normalizePhaseName:()=>pe,output:()=>y,pathExistsInternal:()=>Wi,planningDir:()=>W,planningPaths:()=>F,planningRoot:()=>ee,readSubdirectories:()=>Ue,reapStaleTempFiles:()=>hr,replaceInCurrentMilestone:()=>dt,resolveModelInternal:()=>oe,resolveWorktreeRoot:()=>Lt,safeReadFile:()=>Ne,searchPhaseInDir:()=>Is,setActiveWorkstream:()=>lt,stripShippedMilestones:()=>Nt,toPosixPath:()=>J,withPlanningLock:()=>Ni});function J(t){return t.split(M.default.sep).join("/")}function Ms(t){let e=[];try{let s=N.default.readdirSync(t,{withFileTypes:!0});for(let r of s){if(!r.isDirectory()||r.name.startsWith(".")||r.name==="node_modules")continue;let n=M.default.join(t,r.name,".git");try{N.default.existsSync(n)&&e.push(r.name)}catch{}}}catch{}return e.sort()}function qt(t){let e=M.default.resolve(t),s=M.default.parse(e).root,r=sn.default.homedir(),n=M.default.join(e,".planning");if(N.default.existsSync(n)&&N.default.statSync(n).isDirectory())return t;function i(a){let c=e;for(;c!==s;){if(N.default.existsSync(M.default.join(c,".git")))return!0;if(c===a)break;c=M.default.dirname(c)}return!1}let o=e;for(;o!==s;){let a=M.default.dirname(o);if(a===o||a===r)break;let c=M.default.join(a,".planning");if(N.default.existsSync(c)&&N.default.statSync(c).isDirectory()){let l=M.default.join(c,"config.json");try{let d=JSON.parse(N.default.readFileSync(l,"utf-8")),u=d.sub_repos||d.planning?.sub_repos||[];if(Array.isArray(u)&&u.length>0){let p=M.default.relative(a,e).split(M.default.sep)[0];if(u.includes(p))return a}if(d.multiRepo===!0&&i(a))return a}catch{}if(i(a))return a}o=a}return t}function hr(t="gsd-",{maxAgeMs:e=300*1e3,dirsOnly:s=!1}={}){try{let r=sn.default.tmpdir(),n=Date.now();for(let i of N.default.readdirSync(r)){if(!i.startsWith(t))continue;let o=M.default.join(r,i);try{let a=N.default.statSync(o);n-a.mtimeMs>e&&(a.isDirectory()?N.default.rmSync(o,{recursive:!0,force:!0}):s||N.default.unlinkSync(o))}catch{}}}catch{}}function y(t,e=!1,s){let r;if(e&&s!==void 0)r=String(s);else{let n=JSON.stringify(t,null,2);if(n.length>5e4){hr();let i=M.default.join(sn.default.tmpdir(),`gsd-${Date.now()}.json`);N.default.writeFileSync(i,n,"utf-8"),r="@file:"+i}else r=n}N.default.writeSync(1,r)}function b(t){N.default.writeSync(2,"Error: "+t+`
|
|
137
137
|
`),process.exit(1)}function Ne(t){try{return N.default.readFileSync(t,"utf-8")}catch{return null}}function Q(t){let e=M.default.join(t,".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 c=function(d,u){if(i[d]!==void 0)return i[d];let m=i[u?.section??""];if(u&&m?.[u.field]!==void 0)return m[u.field]};var r=c;let n=N.default.readFileSync(e,"utf-8"),i=JSON.parse(n);if("depth"in i&&!("granularity"in i)){let d={quick:"coarse",standard:"standard",comprehensive:"fine"};i.granularity=d[i.depth]||i.depth,delete i.depth;try{N.default.writeFileSync(e,JSON.stringify(i,null,2),"utf-8")}catch{}}let o=!1;if(i.multiRepo===!0&&!i.sub_repos&&!i.planning?.sub_repos){let d=Ms(t);d.length>0&&(i.sub_repos=d,i.planning||(i.planning={}),i.planning.commit_docs=!1,delete i.multiRepo,o=!0)}let a=i.sub_repos||i.planning?.sub_repos||[];if(Array.isArray(a)&&a.length>0){let d=Ms(t);if(d.length>0){let u=[...a].sort();JSON.stringify(u)!==JSON.stringify(d)&&(i.sub_repos=d,o=!0)}}if(o)try{N.default.writeFileSync(e,JSON.stringify(i,null,2),"utf-8")}catch{}let l=(()=>{let d=c("parallelization");return typeof d=="boolean"?d:typeof d=="object"&&d!==null&&"enabled"in d?!!d.enabled:s.parallelization})();return{model_profile:c("model_profile")??s.model_profile,commit_docs:(()=>{let d=c("commit_docs",{section:"planning",field:"commit_docs"});return d!==void 0?!!d:rn(t,".planning/")?!1:s.commit_docs})(),search_gitignored:c("search_gitignored",{section:"planning",field:"search_gitignored"})??s.search_gitignored,branching_strategy:c("branching_strategy",{section:"git",field:"branching_strategy"})??s.branching_strategy,phase_branch_template:c("phase_branch_template",{section:"git",field:"phase_branch_template"})??s.phase_branch_template,milestone_branch_template:c("milestone_branch_template",{section:"git",field:"milestone_branch_template"})??s.milestone_branch_template,quick_branch_template:c("quick_branch_template",{section:"git",field:"quick_branch_template"})??s.quick_branch_template,research:c("research",{section:"workflow",field:"research"})??s.research,plan_checker:c("plan_checker",{section:"workflow",field:"plan_check"})??s.plan_checker,verifier:c("verifier",{section:"workflow",field:"verifier"})??s.verifier,nyquist_validation:c("nyquist_validation",{section:"workflow",field:"nyquist_validation"})??s.nyquist_validation,parallelization:l,brave_search:c("brave_search")??s.brave_search,firecrawl:c("firecrawl")??s.firecrawl,exa_search:c("exa_search")??s.exa_search,text_mode:c("text_mode",{section:"workflow",field:"text_mode"})??s.text_mode,sub_repos:c("sub_repos",{section:"planning",field:"sub_repos"})??s.sub_repos,resolve_model_ids:c("resolve_model_ids")??s.resolve_model_ids,context_window:c("context_window")??s.context_window,phase_naming:c("phase_naming")??s.phase_naming,model_overrides:i.model_overrides??null,agent_skills:i.agent_skills||{}}}catch{return s}}function rn(t,e){try{return(0,Wt.execFileSync)("git",["check-ignore","-q","--no-index","--",e],{cwd:t,stdio:"pipe"}),!0}catch{return!1}}function de(t,e){let s=(0,Wt.spawnSync)("git",e,{cwd:t,stdio:"pipe",encoding:"utf-8"});return{exitCode:s.status??1,stdout:(s.stdout??"").toString().trim(),stderr:(s.stderr??"").toString().trim()}}function Ie(t){if(!t||typeof t!="string")return t;let e=t.replace(/\r\n/g,`
|
|
138
138
|
`),s=e.split(`
|
|
139
139
|
`),r=[];for(let n=0;n<s.length;n++){let i=s[n],o=n>0?s[n-1]:"",a=o.trimEnd(),c=i.trimEnd();if(/^#{1,6}\s/.test(c)&&n>0&&a!==""&&a!=="---"&&r.push(""),/^```/.test(c)&&n>0&&a!==""&&!Di(s,n)&&r.push(""),/^(\s*[-*+]\s|\s*\d+\.\s)/.test(i)&&n>0&&a!==""&&!/^(\s*[-*+]\s|\s*\d+\.\s)/.test(o)&&a!=="---"&&r.push(""),r.push(i),/^#{1,6}\s/.test(c)&&n<s.length-1&&s[n+1]?.trimEnd()!==""&&r.push(""),/^```\s*$/.test(c)&&Oi(s,n)&&n<s.length-1&&s[n+1]?.trimEnd()!==""&&r.push(""),/^(\s*[-*+]\s|\s*\d+\.\s)/.test(i)&&n<s.length-1){let l=s[n+1];l!==void 0&&l.trimEnd()!==""&&!/^(\s*[-*+]\s|\s*\d+\.\s)/.test(l)&&!/^\s/.test(l)&&r.push("")}}return e=r.join(`
|
|
140
140
|
`),e=e.replace(/\n{3,}/g,`
|
|
141
141
|
|
|
142
142
|
`),e=e.replace(/\n*$/,`
|
|
143
|
-
`),e}function Di(t,e){let s=0;for(let r=0;r<e;r++)/^```/.test(t[r].trimEnd())&&s++;return s%2===1}function Oi(t,e){let s=0;for(let r=0;r<=e;r++)/^```/.test(t[r].trimEnd())&&s++;return s%2===0}function Lt(t){if(N.default.existsSync(M.default.join(t,".planning")))return t;let e=de(t,["rev-parse","--git-dir"]),s=de(t,["rev-parse","--git-common-dir"]);if(e.exitCode!==0||s.exitCode!==0)return t;let r=M.default.resolve(t,e.stdout),n=M.default.resolve(t,s.stdout);return r!==n?M.default.dirname(n):t}function Ni(t,e){let s=M.default.join(W(t),".lock"),r=1e4,n=100,i=Date.now();try{N.default.mkdirSync(W(t),{recursive:!0})}catch{}for(;Date.now()-i<r;)try{N.default.writeFileSync(s,JSON.stringify({pid:process.pid,cwd:t,acquired:new Date().toISOString()}),{flag:"wx"});try{return e()}finally{try{N.default.unlinkSync(s)}catch{}}}catch(o){if(o.code==="EEXIST"){try{let a=N.default.statSync(s);if(Date.now()-a.mtimeMs>3e4){N.default.unlinkSync(s);continue}}catch{continue}(0,Wt.spawnSync)("sleep",["0.1"],{stdio:"ignore"});continue}throw o}try{N.default.unlinkSync(s)}catch{}return e()}function W(t,e){let s=e??process.env.GSD_WORKSTREAM??null;return s?M.default.join(t,".planning","workstreams",s):M.default.join(t,".planning")}function ee(t){return M.default.join(t,".planning")}function F(t,e){let s=W(t,e),r=M.default.join(t,".planning");return{planning:s,state:M.default.join(s,"STATE.md"),roadmap:M.default.join(s,"ROADMAP.md"),project:M.default.join(r,"PROJECT.md"),config:M.default.join(r,"config.json"),phases:M.default.join(s,"phases"),requirements:M.default.join(s,"REQUIREMENTS.md")}}function Ke(t){let e=M.default.join(ee(t),"active-workstream");try{let s=N.default.readFileSync(e,"utf-8").trim();return!s||!/^[a-zA-Z0-9_-]+$/.test(s)||!N.default.existsSync(M.default.join(ee(t),"workstreams",s))?null:s}catch{return null}}function
|
|
144
|
-
`,"utf-8")}function ie(t){return String(t).replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function pe(t){let e=String(t),s=e.match(/^(\d+)([A-Z])?((?:\.\d+)*)/i);return s?s[1].padStart(2,"0")+(s[2]?s[2].toUpperCase():"")+(s[3]||""):e}function Se(t,e){let s=String(t).match(/^(\d+)([A-Z])?((?:\.\d+)*)/i),r=String(e).match(/^(\d+)([A-Z])?((?:\.\d+)*)/i);if(!s||!r)return String(t).localeCompare(String(e));let n=parseInt(s[1],10)-parseInt(r[1],10);if(n!==0)return n;let i=(s[2]||"").toUpperCase(),o=(r[2]||"").toUpperCase();if(i!==o)return i?o&&i<o?-1:1:-1;let a=s[3]?s[3].slice(1).split(".").map(l=>parseInt(l,10)):[],c=r[3]?r[3].slice(1).split(".").map(l=>parseInt(l,10)):[];if(a.length===0&&c.length>0)return-1;if(c.length===0&&a.length>0)return 1;for(let l=0;l<Math.max(a.length,c.length);l++){let d=Number.isFinite(a[l])?a[l]:0,u=Number.isFinite(c[l])?c[l]:0;if(d!==u)return d-u}return 0}function Is(t,e,s){try{let n=Ue(t,!0).find(v=>v.startsWith(s)||v.toUpperCase().startsWith(s.toUpperCase()));if(!n)return null;let i=n.match(/^(\d+[A-Z]?(?:\.\d+)*)-?(.*)/i)||n.match(/^([A-Z][A-Z0-9]*(?:-[A-Z0-9]+)*)-(.+)/i)||[null,n,null],o=i?.[1]??s,a=i?.[2]||null,c=M.default.join(t,n),{plans:l,summaries:d,hasResearch:u,hasContext:m,hasVerification:p,hasReviews:f}=xr(c),g=l.sort(),h=d.sort(),x=new Set(h.map(v=>v.replace("-SUMMARY.md","").replace("SUMMARY.md",""))),S=g.filter(v=>!x.has(v.replace("-PLAN.md","").replace("PLAN.md","")));return{found:!0,directory:J(M.default.join(e,n)),phase_number:o,phase_name:a,phase_slug:a?a.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,""):null,plans:g,summaries:h,incomplete_plans:S,has_research:u,has_context:m,has_verification:p,has_reviews:f}}catch{return null}}function he(t,e){if(!e)return null;let s=M.default.join(W(t),"phases"),r=pe(e),n=J(M.default.relative(t,s)),i=Is(s,n,r);if(i)return i;let o=M.default.join(t,".planning","milestones");if(!N.default.existsSync(o))return null;try{let a=N.default.readdirSync(o,{withFileTypes:!0}).filter(c=>c.isDirectory()&&/^v[\d.]+-phases$/.test(c.name)).map(c=>c.name).sort().reverse();for(let c of a){let l=c.match(/^(v[\d.]+)-phases$/)[1],d=M.default.join(o,c),u=".planning/milestones/"+c,m=Is(d,u,r);if(m)return m.archived=l,m}}catch{}return null}function Ut(t){let e=M.default.join(t,".planning","milestones"),s=[];if(!N.default.existsSync(e))return s;try{let r=N.default.readdirSync(e,{withFileTypes:!0}).filter(n=>n.isDirectory()&&/^v[\d.]+-phases$/.test(n.name)).map(n=>n.name).sort().reverse();for(let n of r){let i=n.match(/^(v[\d.]+)-phases$/)[1],o=M.default.join(e,n);for(let a of Ue(o,!0))s.push({name:a,milestone:i,basePath:M.default.join(".planning","milestones",n),fullPath:M.default.join(o,a)})}}catch{}return s}function Nt(t){return t.replace(/<details>[\s\S]*?<\/details>/gi,"")}function we(t,e){if(!e)return Nt(t);let s=null;try{let u=M.default.join(W(e),"STATE.md");if(N.default.existsSync(u)){let p=N.default.readFileSync(u,"utf-8").match(/^milestone:\s*(.+)/m);p&&(s=p[1].trim())}}catch{}if(!s){let u=t.match(/🚧\s*\*\*v(\d+\.\d+)\s/);u&&(s="v"+u[1])}if(!s)return Nt(t);let r=new RegExp(`(^#{1,3}\\s+.*${ie(s)}[^\\n]*)`,"mi"),n=t.match(r);if(!n)return Nt(t);let i=n.index,o=n[1].match(/^(#{1,3})\s/)[1].length,c=t.slice(i+n[0].length).match(new RegExp(`^#{1,${o}}\\s+(?:.*v\\d+\\.\\d+|\u2705|\u{1F4CB}|\u{1F6A7})`,"mi")),l=c?i+n[0].length+c.index:t.length;return t.slice(0,i).replace(/<details>[\s\S]*?<\/details>/gi,"")+t.slice(i,l)}function lt(t,e,s){let r=t.lastIndexOf("</details>");if(r===-1)return t.replace(e,s);let n=r+10,i=t.slice(0,n),o=t.slice(n);return i+o.replace(e,s)}function dt(t,e){if(!e)return null;let s=M.default.join(W(t),"ROADMAP.md");if(!N.default.existsSync(s))return null;try{let r=we(N.default.readFileSync(s,"utf-8"),t),n=new RegExp(`#{2,4}\\s*Phase\\s+${ie(e)}:\\s*([^\\n]+)`,"i"),i=r.match(n);if(!i)return null;let o=i[1].trim(),a=i.index,l=r.slice(a).match(/\n#{2,4}\s+Phase\s+[\w]/i),d=l?a+l.index:r.length,u=r.slice(a,d).trim(),m=u.match(/\*\*Goal(?:\*\*:|\*?\*?:\*\*)\s*([^\n]+)/i);return{found:!0,phase_number:e.toString(),phase_name:o,goal:m?m[1].trim():null,section:u}}catch{return null}}function yr(){return M.default.join(__dirname,"..","..","agents")}function _t(){let t=yr(),e=Object.keys(Me),s=[],r=[];if(!N.default.existsSync(t))return{agents_installed:!1,missing_agents:e,installed_agents:[],agents_dir:t};for(let n of e)N.default.existsSync(M.default.join(t,`${n}.md`))?s.push(n):r.push(n);return{agents_installed:s.length>0&&r.length===0,missing_agents:r,installed_agents:s,agents_dir:t}}function oe(t,e){let s=Q(t),r=s.model_overrides?.[e];if(r)return r;if(s.resolve_model_ids==="omit")return"";let n=String(s.model_profile||"balanced").toLowerCase(),i=Me[e];if(!i)return"sonnet";if(n==="inherit")return"inherit";let o=i[n]||i.balanced||"sonnet";return s.resolve_model_ids&&gr[o]||o}function Vt(t){if(!t)return null;let s=t.replace(/^---\n[\s\S]*?\n---\n*/,"").match(/^#[^\n]*\n+\*\*([^*]+)\*\*/m);return s?s[1].trim():null}function Wi(t,e){let s=M.default.isAbsolute(e)?e:M.default.join(t,e);try{return N.default.statSync(s),!0}catch{return!1}}function Le(t){return t?t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,""):null}function ce(t){try{let e=N.default.readFileSync(M.default.join(W(t),"ROADMAP.md"),"utf-8"),s=e.match(/🚧\s*\*\*v(\d+(?:\.\d+)+)\s+([^*]+)\*\*/);if(s)return{version:"v"+s[1],name:s[2].trim()};let r=Nt(e),n=r.match(/## .*v(\d+(?:\.\d+)+)[:\s]+([^\n(]+)/);if(n)return{version:"v"+n[1],name:n[2].trim()};let i=r.match(/v(\d+(?:\.\d+)+)/);return{version:i?i[0]:"v1.0",name:"milestone"}}catch{return{version:"v1.0",name:"milestone"}}}function ke(t){let e=new Set;try{let n=we(N.default.readFileSync(M.default.join(W(t),"ROADMAP.md"),"utf-8"),t),i=/#{2,4}\s*Phase\s+([\w][\w.-]*)\s*:/gi,o;for(;(o=i.exec(n))!==null;)e.add(o[1])}catch{}if(e.size===0){let n=i=>!0;return n.phaseCount=0,n}let s=new Set([...e].map(n=>(n.replace(/^0+/,"")||"0").toLowerCase()));function r(n){let i=n.match(/^0*(\d+[A-Za-z]?(?:\.\d+)*)/);if(i&&s.has(i[1].toLowerCase()))return!0;let o=n.match(/^([A-Za-z][A-Za-z0-9]*(?:-[A-Za-z0-9]+)*)/);return!!(o&&s.has(o[1].toLowerCase()))}return r.phaseCount=e.size,r}function wt(t){return t.filter(e=>e.endsWith("-PLAN.md")||e==="PLAN.md")}function kt(t){return t.filter(e=>e.endsWith("-SUMMARY.md")||e==="SUMMARY.md")}function xr(t){let e=N.default.readdirSync(t);return{plans:wt(e),summaries:kt(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 Ue(t,e=!1){try{let r=N.default.readdirSync(t,{withFileTypes:!0}).filter(n=>n.isDirectory()).map(n=>n.name);return e?r.sort((n,i)=>Se(n,i)):r}catch{return[]}}var Wt,N,sn,M,gr,ye=L(()=>{"use strict";Wt=require("child_process"),N=U(require("fs")),sn=U(require("os")),M=U(require("path"));Ot();gr={opus:"claude-opus-4-6",sonnet:"claude-sonnet-4-6",haiku:"claude-haiku-4-5"}});var st,Ds,on,w,je=L(()=>{"use strict";st=require("@oclif/core"),Ds=U(require("path")),on=U(require("fs"));ye();w=class extends st.Command{static enableJsonFlag=!1;static baseFlags={cwd:st.Flags.string({description:"Working directory",default:""}),ws:st.Flags.string({description:"Workstream override",default:""}),raw:st.Flags.boolean({description:"Raw JSON output",default:!1}),output:st.Flags.string({description:"Output format",options:["json","toon"],default:"json"}),pick:st.Flags.string({description:"JSONPath pick expression",default:""})};resolveContext(e){let s=e.cwd?Ds.default.resolve(e.cwd):process.cwd();if((!on.default.existsSync(s)||!on.default.statSync(s).isDirectory())&&b(`Invalid --cwd: ${s}`),!on.default.existsSync(Ds.default.join(s,".planning"))){let n=Lt(s);n!==s&&(s=n)}let r=null;return e.ws?r=e.ws:process.env.GSD_WORKSTREAM?r=process.env.GSD_WORKSTREAM.trim():r=Ke(s),r&&!/^[a-zA-Z0-9_-]+$/.test(r)&&b("Invalid workstream name"),r&&(process.env.GSD_WORKSTREAM=r),s=qt(s),{cwd:s,ws:r,raw:e.raw??!1}}}});var cn={};xe(cn,{FRONTMATTER_SCHEMAS:()=>Os,asArr:()=>Pe,asObj:()=>Pt,asStr:()=>fe,cmdFrontmatterGet:()=>qi,cmdFrontmatterMerge:()=>Ui,cmdFrontmatterSet:()=>Li,cmdFrontmatterValidate:()=>Vi,extractFrontmatter:()=>le,parseMustHavesBlock:()=>an,reconstructFrontmatter:()=>$t,spliceFrontmatter:()=>Ns});function fe(t){return typeof t=="string"?t:void 0}function Pe(t){return Array.isArray(t)?t:void 0}function Pt(t){return t!==null&&typeof t=="object"&&!Array.isArray(t)?t:void 0}function le(t){let e={},s=[...t.matchAll(/(?:^|\n)\s*---\r?\n([\s\S]+?)\r?\n---/g)],r=s.length>0?s[s.length-1]:null;if(!r)return e;let i=r[1].split(/\r?\n/),o=[{obj:e,key:null,indent:-1}];for(let a of i){if(a.trim()==="")continue;let c=a.match(/^(\s*)/),l=c?c[1].length:0;for(;o.length>1&&l<=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 m=u[2],p=u[3].trim();if(p===""||p==="["){d.obj[m]=p==="["?[]:{},d.key=null;let f=d.obj[m];f!==null&&typeof f=="object"&&o.push({obj:f,key:null,indent:l})}else p.startsWith("[")&&p.endsWith("]")?(d.obj[m]=p.slice(1,-1).split(",").map(f=>f.trim().replace(/^["']|["']$/g,"")).filter(Boolean),d.key=null):(d.obj[m]=p.replace(/^["']|["']$/g,""),d.key=null)}else if(a.trim().startsWith("- ")){let m=a.trim().slice(2).replace(/^["']|["']$/g,"");if(typeof d.obj=="object"&&!Array.isArray(d.obj)&&Object.keys(d.obj).length===0){let p=o.length>1?o[o.length-2]:null;if(p){for(let f of Object.keys(p.obj))if(p.obj[f]===d.obj){p.obj[f]=[m],d.obj=p.obj[f];break}}}else Array.isArray(d.obj)&&d.obj.push(m)}}return e}function $t(t){let e=[];for(let[s,r]of Object.entries(t))if(r!=null)if(Array.isArray(r))if(r.length===0)e.push(`${s}: []`);else if(r.every(n=>typeof n=="string")&&r.length<=3&&r.join(", ").length<60)e.push(`${s}: [${r.join(", ")}]`);else{e.push(`${s}:`);for(let n of r){let i=String(n);e.push(` - ${typeof n=="string"&&(i.includes(":")||i.includes("#"))?`"${i}"`:i}`)}}else if(typeof r=="object"){e.push(`${s}:`);for(let[n,i]of Object.entries(r))if(i!=null)if(Array.isArray(i))if(i.length===0)e.push(` ${n}: []`);else if(i.every(o=>typeof o=="string")&&i.length<=3&&i.join(", ").length<60)e.push(` ${n}: [${i.join(", ")}]`);else{e.push(` ${n}:`);for(let o of i)e.push(` - ${o}`)}else if(typeof i=="object"){e.push(` ${n}:`);for(let[o,a]of Object.entries(i))if(a!=null)if(Array.isArray(a))if(a.length===0)e.push(` ${o}: []`);else{e.push(` ${o}:`);for(let c of a)e.push(` - ${c}`)}else e.push(` ${o}: ${a}`)}else{let o=String(i);e.push(` ${n}: ${o.includes(":")||o.includes("#")?`"${o}"`:o}`)}}else{let n=String(r);n.includes(":")||n.includes("#")||n.startsWith("[")||n.startsWith("{")?e.push(`${s}: "${n}"`):e.push(`${s}: ${n}`)}return e.join(`
|
|
143
|
+
`),e}function Di(t,e){let s=0;for(let r=0;r<e;r++)/^```/.test(t[r].trimEnd())&&s++;return s%2===1}function Oi(t,e){let s=0;for(let r=0;r<=e;r++)/^```/.test(t[r].trimEnd())&&s++;return s%2===0}function Lt(t){if(N.default.existsSync(M.default.join(t,".planning")))return t;let e=de(t,["rev-parse","--git-dir"]),s=de(t,["rev-parse","--git-common-dir"]);if(e.exitCode!==0||s.exitCode!==0)return t;let r=M.default.resolve(t,e.stdout),n=M.default.resolve(t,s.stdout);return r!==n?M.default.dirname(n):t}function Ni(t,e){let s=M.default.join(W(t),".lock"),r=1e4,n=100,i=Date.now();try{N.default.mkdirSync(W(t),{recursive:!0})}catch{}for(;Date.now()-i<r;)try{N.default.writeFileSync(s,JSON.stringify({pid:process.pid,cwd:t,acquired:new Date().toISOString()}),{flag:"wx"});try{return e()}finally{try{N.default.unlinkSync(s)}catch{}}}catch(o){if(o.code==="EEXIST"){try{let a=N.default.statSync(s);if(Date.now()-a.mtimeMs>3e4){N.default.unlinkSync(s);continue}}catch{continue}(0,Wt.spawnSync)("sleep",["0.1"],{stdio:"ignore"});continue}throw o}try{N.default.unlinkSync(s)}catch{}return e()}function W(t,e){let s=e??process.env.GSD_WORKSTREAM??null;return s?M.default.join(t,".planning","workstreams",s):M.default.join(t,".planning")}function ee(t){return M.default.join(t,".planning")}function F(t,e){let s=W(t,e),r=M.default.join(t,".planning");return{planning:s,state:M.default.join(s,"STATE.md"),roadmap:M.default.join(s,"ROADMAP.md"),project:M.default.join(r,"PROJECT.md"),config:M.default.join(r,"config.json"),phases:M.default.join(s,"phases"),requirements:M.default.join(s,"REQUIREMENTS.md")}}function Ke(t){let e=M.default.join(ee(t),"active-workstream");try{let s=N.default.readFileSync(e,"utf-8").trim();return!s||!/^[a-zA-Z0-9_-]+$/.test(s)||!N.default.existsSync(M.default.join(ee(t),"workstreams",s))?null:s}catch{return null}}function lt(t,e){let s=M.default.join(ee(t),"active-workstream");if(!e){try{N.default.unlinkSync(s)}catch{}return}if(!/^[a-zA-Z0-9_-]+$/.test(e))throw new Error("Invalid workstream name");N.default.writeFileSync(s,e+`
|
|
144
|
+
`,"utf-8")}function ie(t){return String(t).replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function pe(t){let e=String(t),s=e.match(/^(\d+)([A-Z])?((?:\.\d+)*)/i);return s?s[1].padStart(2,"0")+(s[2]?s[2].toUpperCase():"")+(s[3]||""):e}function Se(t,e){let s=String(t).match(/^(\d+)([A-Z])?((?:\.\d+)*)/i),r=String(e).match(/^(\d+)([A-Z])?((?:\.\d+)*)/i);if(!s||!r)return String(t).localeCompare(String(e));let n=parseInt(s[1],10)-parseInt(r[1],10);if(n!==0)return n;let i=(s[2]||"").toUpperCase(),o=(r[2]||"").toUpperCase();if(i!==o)return i?o&&i<o?-1:1:-1;let a=s[3]?s[3].slice(1).split(".").map(l=>parseInt(l,10)):[],c=r[3]?r[3].slice(1).split(".").map(l=>parseInt(l,10)):[];if(a.length===0&&c.length>0)return-1;if(c.length===0&&a.length>0)return 1;for(let l=0;l<Math.max(a.length,c.length);l++){let d=Number.isFinite(a[l])?a[l]:0,u=Number.isFinite(c[l])?c[l]:0;if(d!==u)return d-u}return 0}function Is(t,e,s){try{let n=Ue(t,!0).find(v=>v.startsWith(s)||v.toUpperCase().startsWith(s.toUpperCase()));if(!n)return null;let i=n.match(/^(\d+[A-Z]?(?:\.\d+)*)-?(.*)/i)||n.match(/^([A-Z][A-Z0-9]*(?:-[A-Z0-9]+)*)-(.+)/i)||[null,n,null],o=i?.[1]??s,a=i?.[2]||null,c=M.default.join(t,n),{plans:l,summaries:d,hasResearch:u,hasContext:m,hasVerification:p,hasReviews:f}=xr(c),g=l.sort(),h=d.sort(),x=new Set(h.map(v=>v.replace("-SUMMARY.md","").replace("SUMMARY.md",""))),S=g.filter(v=>!x.has(v.replace("-PLAN.md","").replace("PLAN.md","")));return{found:!0,directory:J(M.default.join(e,n)),phase_number:o,phase_name:a,phase_slug:a?a.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,""):null,plans:g,summaries:h,incomplete_plans:S,has_research:u,has_context:m,has_verification:p,has_reviews:f}}catch{return null}}function he(t,e){if(!e)return null;let s=M.default.join(W(t),"phases"),r=pe(e),n=J(M.default.relative(t,s)),i=Is(s,n,r);if(i)return i;let o=M.default.join(t,".planning","milestones");if(!N.default.existsSync(o))return null;try{let a=N.default.readdirSync(o,{withFileTypes:!0}).filter(c=>c.isDirectory()&&/^v[\d.]+-phases$/.test(c.name)).map(c=>c.name).sort().reverse();for(let c of a){let l=c.match(/^(v[\d.]+)-phases$/)[1],d=M.default.join(o,c),u=".planning/milestones/"+c,m=Is(d,u,r);if(m)return m.archived=l,m}}catch{}return null}function Ut(t){let e=M.default.join(t,".planning","milestones"),s=[];if(!N.default.existsSync(e))return s;try{let r=N.default.readdirSync(e,{withFileTypes:!0}).filter(n=>n.isDirectory()&&/^v[\d.]+-phases$/.test(n.name)).map(n=>n.name).sort().reverse();for(let n of r){let i=n.match(/^(v[\d.]+)-phases$/)[1],o=M.default.join(e,n);for(let a of Ue(o,!0))s.push({name:a,milestone:i,basePath:M.default.join(".planning","milestones",n),fullPath:M.default.join(o,a)})}}catch{}return s}function Nt(t){return t.replace(/<details>[\s\S]*?<\/details>/gi,"")}function we(t,e){if(!e)return Nt(t);let s=null;try{let u=M.default.join(W(e),"STATE.md");if(N.default.existsSync(u)){let p=N.default.readFileSync(u,"utf-8").match(/^milestone:\s*(.+)/m);p&&(s=p[1].trim())}}catch{}if(!s){let u=t.match(/🚧\s*\*\*v(\d+\.\d+)\s/);u&&(s="v"+u[1])}if(!s)return Nt(t);let r=new RegExp(`(^#{1,3}\\s+.*${ie(s)}[^\\n]*)`,"mi"),n=t.match(r);if(!n)return Nt(t);let i=n.index,o=n[1].match(/^(#{1,3})\s/)[1].length,c=t.slice(i+n[0].length).match(new RegExp(`^#{1,${o}}\\s+(?:.*v\\d+\\.\\d+|\u2705|\u{1F4CB}|\u{1F6A7})`,"mi")),l=c?i+n[0].length+c.index:t.length;return t.slice(0,i).replace(/<details>[\s\S]*?<\/details>/gi,"")+t.slice(i,l)}function dt(t,e,s){let r=t.lastIndexOf("</details>");if(r===-1)return t.replace(e,s);let n=r+10,i=t.slice(0,n),o=t.slice(n);return i+o.replace(e,s)}function ut(t,e){if(!e)return null;let s=M.default.join(W(t),"ROADMAP.md");if(!N.default.existsSync(s))return null;try{let r=we(N.default.readFileSync(s,"utf-8"),t),n=new RegExp(`#{2,4}\\s*Phase\\s+${ie(e)}:\\s*([^\\n]+)`,"i"),i=r.match(n);if(!i)return null;let o=i[1].trim(),a=i.index,l=r.slice(a).match(/\n#{2,4}\s+Phase\s+[\w]/i),d=l?a+l.index:r.length,u=r.slice(a,d).trim(),m=u.match(/\*\*Goal(?:\*\*:|\*?\*?:\*\*)\s*([^\n]+)/i);return{found:!0,phase_number:e.toString(),phase_name:o,goal:m?m[1].trim():null,section:u}}catch{return null}}function yr(){return M.default.join(__dirname,"..","..","agents")}function _t(){let t=yr(),e=Object.keys(Me),s=[],r=[];if(!N.default.existsSync(t))return{agents_installed:!1,missing_agents:e,installed_agents:[],agents_dir:t};for(let n of e)N.default.existsSync(M.default.join(t,`${n}.md`))?s.push(n):r.push(n);return{agents_installed:s.length>0&&r.length===0,missing_agents:r,installed_agents:s,agents_dir:t}}function oe(t,e){let s=Q(t),r=s.model_overrides?.[e];if(r)return r;if(s.resolve_model_ids==="omit")return"";let n=String(s.model_profile||"balanced").toLowerCase(),i=Me[e];if(!i)return"sonnet";if(n==="inherit")return"inherit";let o=i[n]||i.balanced||"sonnet";return s.resolve_model_ids&&gr[o]||o}function Vt(t){if(!t)return null;let s=t.replace(/^---\n[\s\S]*?\n---\n*/,"").match(/^#[^\n]*\n+\*\*([^*]+)\*\*/m);return s?s[1].trim():null}function Wi(t,e){let s=M.default.isAbsolute(e)?e:M.default.join(t,e);try{return N.default.statSync(s),!0}catch{return!1}}function Le(t){return t?t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,""):null}function ce(t){try{let e=N.default.readFileSync(M.default.join(W(t),"ROADMAP.md"),"utf-8"),s=e.match(/🚧\s*\*\*v(\d+(?:\.\d+)+)\s+([^*]+)\*\*/);if(s)return{version:"v"+s[1],name:s[2].trim()};let r=Nt(e),n=r.match(/## .*v(\d+(?:\.\d+)+)[:\s]+([^\n(]+)/);if(n)return{version:"v"+n[1],name:n[2].trim()};let i=r.match(/v(\d+(?:\.\d+)+)/);return{version:i?i[0]:"v1.0",name:"milestone"}}catch{return{version:"v1.0",name:"milestone"}}}function ke(t){let e=new Set;try{let n=we(N.default.readFileSync(M.default.join(W(t),"ROADMAP.md"),"utf-8"),t),i=/#{2,4}\s*Phase\s+([\w][\w.-]*)\s*:/gi,o;for(;(o=i.exec(n))!==null;)e.add(o[1])}catch{}if(e.size===0){let n=i=>!0;return n.phaseCount=0,n}let s=new Set([...e].map(n=>(n.replace(/^0+/,"")||"0").toLowerCase()));function r(n){let i=n.match(/^0*(\d+[A-Za-z]?(?:\.\d+)*)/);if(i&&s.has(i[1].toLowerCase()))return!0;let o=n.match(/^([A-Za-z][A-Za-z0-9]*(?:-[A-Za-z0-9]+)*)/);return!!(o&&s.has(o[1].toLowerCase()))}return r.phaseCount=e.size,r}function wt(t){return t.filter(e=>e.endsWith("-PLAN.md")||e==="PLAN.md")}function kt(t){return t.filter(e=>e.endsWith("-SUMMARY.md")||e==="SUMMARY.md")}function xr(t){let e=N.default.readdirSync(t);return{plans:wt(e),summaries:kt(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 Ue(t,e=!1){try{let r=N.default.readdirSync(t,{withFileTypes:!0}).filter(n=>n.isDirectory()).map(n=>n.name);return e?r.sort((n,i)=>Se(n,i)):r}catch{return[]}}var Wt,N,sn,M,gr,ye=L(()=>{"use strict";Wt=require("child_process"),N=U(require("fs")),sn=U(require("os")),M=U(require("path"));Ot();gr={opus:"claude-opus-4-6",sonnet:"claude-sonnet-4-6",haiku:"claude-haiku-4-5"}});var st,Ds,on,w,je=L(()=>{"use strict";st=require("@oclif/core"),Ds=U(require("path")),on=U(require("fs"));ye();w=class extends st.Command{static enableJsonFlag=!1;static baseFlags={cwd:st.Flags.string({description:"Working directory",default:""}),ws:st.Flags.string({description:"Workstream override",default:""}),raw:st.Flags.boolean({description:"Raw JSON output",default:!1}),output:st.Flags.string({description:"Output format",options:["json","toon"],default:"json"}),pick:st.Flags.string({description:"JSONPath pick expression",default:""})};resolveContext(e){let s=e.cwd?Ds.default.resolve(e.cwd):process.cwd();if((!on.default.existsSync(s)||!on.default.statSync(s).isDirectory())&&b(`Invalid --cwd: ${s}`),!on.default.existsSync(Ds.default.join(s,".planning"))){let n=Lt(s);n!==s&&(s=n)}let r=null;return e.ws?r=e.ws:process.env.GSD_WORKSTREAM?r=process.env.GSD_WORKSTREAM.trim():r=Ke(s),r&&!/^[a-zA-Z0-9_-]+$/.test(r)&&b("Invalid workstream name"),r&&(process.env.GSD_WORKSTREAM=r),s=qt(s),{cwd:s,ws:r,raw:e.raw??!1}}}});var cn={};xe(cn,{FRONTMATTER_SCHEMAS:()=>Os,asArr:()=>Pe,asObj:()=>Pt,asStr:()=>fe,cmdFrontmatterGet:()=>qi,cmdFrontmatterMerge:()=>Ui,cmdFrontmatterSet:()=>Li,cmdFrontmatterValidate:()=>Vi,extractFrontmatter:()=>le,parseMustHavesBlock:()=>an,reconstructFrontmatter:()=>$t,spliceFrontmatter:()=>Ns});function fe(t){return typeof t=="string"?t:void 0}function Pe(t){return Array.isArray(t)?t:void 0}function Pt(t){return t!==null&&typeof t=="object"&&!Array.isArray(t)?t:void 0}function le(t){let e={},s=[...t.matchAll(/(?:^|\n)\s*---\r?\n([\s\S]+?)\r?\n---/g)],r=s.length>0?s[s.length-1]:null;if(!r)return e;let i=r[1].split(/\r?\n/),o=[{obj:e,key:null,indent:-1}];for(let a of i){if(a.trim()==="")continue;let c=a.match(/^(\s*)/),l=c?c[1].length:0;for(;o.length>1&&l<=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 m=u[2],p=u[3].trim();if(p===""||p==="["){d.obj[m]=p==="["?[]:{},d.key=null;let f=d.obj[m];f!==null&&typeof f=="object"&&o.push({obj:f,key:null,indent:l})}else p.startsWith("[")&&p.endsWith("]")?(d.obj[m]=p.slice(1,-1).split(",").map(f=>f.trim().replace(/^["']|["']$/g,"")).filter(Boolean),d.key=null):(d.obj[m]=p.replace(/^["']|["']$/g,""),d.key=null)}else if(a.trim().startsWith("- ")){let m=a.trim().slice(2).replace(/^["']|["']$/g,"");if(typeof d.obj=="object"&&!Array.isArray(d.obj)&&Object.keys(d.obj).length===0){let p=o.length>1?o[o.length-2]:null;if(p){for(let f of Object.keys(p.obj))if(p.obj[f]===d.obj){p.obj[f]=[m],d.obj=p.obj[f];break}}}else Array.isArray(d.obj)&&d.obj.push(m)}}return e}function $t(t){let e=[];for(let[s,r]of Object.entries(t))if(r!=null)if(Array.isArray(r))if(r.length===0)e.push(`${s}: []`);else if(r.every(n=>typeof n=="string")&&r.length<=3&&r.join(", ").length<60)e.push(`${s}: [${r.join(", ")}]`);else{e.push(`${s}:`);for(let n of r){let i=String(n);e.push(` - ${typeof n=="string"&&(i.includes(":")||i.includes("#"))?`"${i}"`:i}`)}}else if(typeof r=="object"){e.push(`${s}:`);for(let[n,i]of Object.entries(r))if(i!=null)if(Array.isArray(i))if(i.length===0)e.push(` ${n}: []`);else if(i.every(o=>typeof o=="string")&&i.length<=3&&i.join(", ").length<60)e.push(` ${n}: [${i.join(", ")}]`);else{e.push(` ${n}:`);for(let o of i)e.push(` - ${o}`)}else if(typeof i=="object"){e.push(` ${n}:`);for(let[o,a]of Object.entries(i))if(a!=null)if(Array.isArray(a))if(a.length===0)e.push(` ${o}: []`);else{e.push(` ${o}:`);for(let c of a)e.push(` - ${c}`)}else e.push(` ${o}: ${a}`)}else{let o=String(i);e.push(` ${n}: ${o.includes(":")||o.includes("#")?`"${o}"`:o}`)}}else{let n=String(r);n.includes(":")||n.includes("#")||n.startsWith("[")||n.startsWith("{")?e.push(`${s}: "${n}"`):e.push(`${s}: ${n}`)}return e.join(`
|
|
145
145
|
`)}function Ns(t,e){let s=$t(e),r=t.match(/^---\r?\n[\s\S]+?\r?\n---/);return r?`---
|
|
146
146
|
${s}
|
|
147
147
|
---`+t.slice(r[0].length):`---
|
|
148
148
|
${s}
|
|
149
149
|
---
|
|
150
150
|
|
|
151
|
-
`+t}function an(t,e){let s=t.match(/^---\r?\n([\s\S]+?)\r?\n---/);if(!s)return[];let r=s[1],n=r.match(/^(\s*)must_haves:\s*$/m);if(!n)return[];let i=n[1].length,o=new RegExp(`^(\\s+)${e}:\\s*$`,"m"),a=r.match(o);if(!a)return[];let c=a[1].length;if(c<=i)return[];let l=r.indexOf(a[0]);if(l===-1)return[];let u=r.slice(l).split(/\r?\n/).slice(1),m=[],p=null,f=-1;for(let g of u){if(g.trim()==="")continue;let h=g.match(/^(\s*)/)?.[1].length??0;if(h<=c&&g.trim()!=="")break;let x=g.trim();if(x.startsWith("- ")&&(f===-1&&(f=h),h===f)){p&&m.push(p),p={};let S=x.slice(2);if(!S.includes(":"))p=S.replace(/^["']|["']$/g,"");else{let v=S.match(/^(\w+):\s*"?([^"]*)"?\s*$/);v&&(p={},p[v[1]]=v[2])}continue}if(p&&typeof p=="object"&&h>f)if(x.startsWith("- ")){let S=x.slice(2).replace(/^["']|["']$/g,""),v=Object.keys(p),C=v[v.length-1];C&&!Array.isArray(p[C])&&(p[C]=p[C]?[p[C]]:[]);let P=p[C];C&&Array.isArray(P)&&P.push(S)}else{let S=x.match(/^(\w+):\s*"?([^"]*)"?\s*$/);if(S){let v=S[2];p[S[1]]=/^\d+$/.test(v)?parseInt(v,10):v}}}return p&&m.push(p),m}function qi(t,e,s,r){e||b("file path required"),e.includes("\0")&&b("file path contains null bytes");let n=Qe.default.isAbsolute(e)?e:Qe.default.join(t,e),i=Ne(n);if(!i){y({error:"File not found",path:e},r);return}let o=le(i);if(s){let a=o[s];if(a===void 0){y({error:"Field not found",field:s},r);return}y({[s]:a},r,JSON.stringify(a))}else y(o,r)}function Li(t,e,s,r,n){(!e||!s||r===void 0)&&b("file, field, and value required"),e.includes("\0")&&b("file path contains null bytes");let i=Qe.default.isAbsolute(e)?e:Qe.default.join(t,e);if(!
|
|
151
|
+
`+t}function an(t,e){let s=t.match(/^---\r?\n([\s\S]+?)\r?\n---/);if(!s)return[];let r=s[1],n=r.match(/^(\s*)must_haves:\s*$/m);if(!n)return[];let i=n[1].length,o=new RegExp(`^(\\s+)${e}:\\s*$`,"m"),a=r.match(o);if(!a)return[];let c=a[1].length;if(c<=i)return[];let l=r.indexOf(a[0]);if(l===-1)return[];let u=r.slice(l).split(/\r?\n/).slice(1),m=[],p=null,f=-1;for(let g of u){if(g.trim()==="")continue;let h=g.match(/^(\s*)/)?.[1].length??0;if(h<=c&&g.trim()!=="")break;let x=g.trim();if(x.startsWith("- ")&&(f===-1&&(f=h),h===f)){p&&m.push(p),p={};let S=x.slice(2);if(!S.includes(":"))p=S.replace(/^["']|["']$/g,"");else{let v=S.match(/^(\w+):\s*"?([^"]*)"?\s*$/);v&&(p={},p[v[1]]=v[2])}continue}if(p&&typeof p=="object"&&h>f)if(x.startsWith("- ")){let S=x.slice(2).replace(/^["']|["']$/g,""),v=Object.keys(p),C=v[v.length-1];C&&!Array.isArray(p[C])&&(p[C]=p[C]?[p[C]]:[]);let P=p[C];C&&Array.isArray(P)&&P.push(S)}else{let S=x.match(/^(\w+):\s*"?([^"]*)"?\s*$/);if(S){let v=S[2];p[S[1]]=/^\d+$/.test(v)?parseInt(v,10):v}}}return p&&m.push(p),m}function qi(t,e,s,r){e||b("file path required"),e.includes("\0")&&b("file path contains null bytes");let n=Qe.default.isAbsolute(e)?e:Qe.default.join(t,e),i=Ne(n);if(!i){y({error:"File not found",path:e},r);return}let o=le(i);if(s){let a=o[s];if(a===void 0){y({error:"Field not found",field:s},r);return}y({[s]:a},r,JSON.stringify(a))}else y(o,r)}function Li(t,e,s,r,n){(!e||!s||r===void 0)&&b("file, field, and value required"),e.includes("\0")&&b("file path contains null bytes");let i=Qe.default.isAbsolute(e)?e:Qe.default.join(t,e);if(!mt.default.existsSync(i)){y({error:"File not found",path:e},n);return}let o=mt.default.readFileSync(i,"utf-8"),a=le(o),c;try{c=JSON.parse(r)}catch{c=r}a[s]=c;let l=Ns(o,a);mt.default.writeFileSync(i,Ie(l),"utf-8"),y({updated:!0,field:s,value:c},n,"true")}function Ui(t,e,s,r){(!e||!s)&&b("file and data required");let n=Qe.default.isAbsolute(e)?e:Qe.default.join(t,e);if(!mt.default.existsSync(n)){y({error:"File not found",path:e},r);return}let i=mt.default.readFileSync(n,"utf-8"),o=le(i),a;try{a=JSON.parse(s)}catch{b("Invalid JSON for --data");return}Object.assign(o,a);let c=Ns(i,o);mt.default.writeFileSync(n,Ie(c),"utf-8"),y({merged:!0,fields:Object.keys(a)},r,"true")}function Vi(t,e,s,r){(!e||!s)&&b("file and schema required");let n=Os[s];if(!n){b(`Unknown schema: ${s}. Available: ${Object.keys(Os).join(", ")}`);return}let i=Qe.default.isAbsolute(e)?e:Qe.default.join(t,e),o=Ne(i);if(!o){y({error:"File not found",path:e},r);return}let a=le(o),c=n.required.filter(d=>a[d]===void 0),l=n.required.filter(d=>a[d]!==void 0);y({valid:c.length===0,missing:c,present:l,schema:s},r,c.length===0?"valid":"invalid")}var mt,Qe,Os,Ve=L(()=>{"use strict";mt=U(require("fs")),Qe=U(require("path"));ye();Os={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"]}}});function _r(t){if(!t)return t;let e=t.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g,"");return e.length>vr&&(e=e.slice(0,vr)+"... [truncated]"),e}function Ws(t,e,s={}){if(t.includes("\0"))return{safe:!1,resolved:t,error:"Path contains null bytes"};let r=ln.default.isAbsolute(t)?t:ln.default.resolve(e,t),n=process.env.HOME??"/";return!r.startsWith(n)&&!r.startsWith(e)?{safe:!1,resolved:r,error:"Path traversal rejected"}:!s.allowAbsolute&&ln.default.isAbsolute(t)?{safe:!1,resolved:r,error:"Absolute paths not allowed"}:{safe:!0,resolved:r}}function wr(t,e,s,r={}){let n=Ws(t,e,r);if(!n.safe)throw new Error(`${s||"Path"} validation failed: ${n.error}`);return n.resolved}function qs(t){if(!t||typeof t!="string")return t;let e=t.replace(/[\u200B-\u200F\u2028-\u202F\uFEFF\u00AD]/g,"");return e=e.replace(/<(\/?)(?:system|assistant|human)>/gi,(s,r)=>`\uFF1C${r||""}system-text\uFF1E`),e=e.replace(/\[(SYSTEM|INST)\]/gi,"[$1-TEXT]"),e=e.replace(/<<\s*SYS\s*>>/gi,"\xABSYS-TEXT\xBB"),e}function Ls(t){return!t||typeof t!="string"?{valid:!1,error:"Field name must be a non-empty string"}:/^[a-zA-Z][a-zA-Z0-9 _-]*$/.test(t)?{valid:!0}:{valid:!1,error:`Field name "${t}" contains invalid characters. Only letters, digits, spaces, hyphens, and underscores are allowed.`}}var ln,vr,dn=L(()=>{"use strict";ln=U(require("path")),vr=1e4});var ze={};xe(ze,{cmdSignalResume:()=>ao,cmdSignalWaiting:()=>oo,cmdStateAddBlocker:()=>eo,cmdStateAddDecision:()=>Qi,cmdStateAdvancePlan:()=>Xi,cmdStateBeginPhase:()=>io,cmdStateGet:()=>Ji,cmdStateJson:()=>ro,cmdStateLoad:()=>Gi,cmdStateNote:()=>Bs,cmdStatePatch:()=>Yi,cmdStateReconcile:()=>co,cmdStateRecordMetric:()=>Zi,cmdStateRecordSession:()=>no,cmdStateResolveBlocker:()=>to,cmdStateSnapshot:()=>so,cmdStateUpdate:()=>Hi,cmdStateUpdateProgress:()=>Ki,reconcileState:()=>Ct,stateExtractField:()=>z,stateReplaceField:()=>be,stateReplaceFieldWithFallback:()=>ue,stripFrontmatter:()=>zs,writeStateMd:()=>ne});function zi(t){return F(t).state}function z(t,e){let s=ie(e),r=t.match(new RegExp(`\\*\\*${s}:\\*\\*\\s*(.+)`,"i"));if(r)return r[1].trim();let n=t.match(new RegExp(`^${s}:\\s*(.+)`,"im"));return n?n[1].trim():null}function be(t,e,s){let r=ie(e),n=new RegExp(`(\\*\\*${r}:\\*\\*\\s*)(.*)`,"i");if(n.test(t))return t.replace(n,(o,a)=>`${a}${s}`);let i=new RegExp(`(^${r}:\\s*)(.*)`,"im");return i.test(t)?t.replace(i,(o,a)=>`${a}${s}`):null}function ue(t,e,s,r){let n=be(t,e,r);if(n)return n;if(s){let i=be(t,s,r);if(i)return i}return t}function Us(t,e){let s=/(##\s*Current Position\s*\n)([\s\S]*?)(?=\n##|$)/i,r=t.match(s);if(!r)return t;let n=r[2];return e.status&&/^Status:/m.test(n)&&(n=n.replace(/^Status:.*$/m,`Status: ${e.status}`)),e.lastActivity&&/^Last activity:/im.test(n)&&(n=n.replace(/^Last activity:.*$/im,`Last activity: ${e.lastActivity}`)),e.plan&&/^Plan:/m.test(n)&&(n=n.replace(/^Plan:.*$/m,`Plan: ${e.plan}`)),t.replace(s,`${r[1]}${n}`)}function Vs(t,e,s,r){if(!s)return e??"";let n=Ws(s,t,{allowAbsolute:!0});if(!n.safe)throw new Error(`${r} path rejected: ${n.error}`);try{return A.default.readFileSync(n.resolved,"utf-8").trimEnd()}catch{throw new Error(`${r} file not found: ${s}`)}}function zs(t){let e=t;for(;;){let s=e.replace(/^\s*---\r?\n[\s\S]*?\r?\n---\s*/,"");if(s===e)break;e=s}return e}function kr(t,e){let s=z(t,"Current Phase"),r=z(t,"Current Phase Name"),n=z(t,"Current Plan"),i=z(t,"Total Phases"),o=z(t,"Total Plans in Phase"),a=z(t,"Status"),c=z(t,"Progress"),l=z(t,"Last Activity"),d=z(t,"Stopped At")||z(t,"Stopped at"),u=z(t,"Paused At"),m=null,p=null;if(e)try{let T=ce(e);m=T.version,p=T.name}catch{}let f=i?parseInt(i,10):null,g=null,h=o?parseInt(o,10):null,x=null;if(e)try{let T=F(e).phases;if(A.default.existsSync(T)){let k=ke(e),j=A.default.readdirSync(T,{withFileTypes:!0}).filter(H=>H.isDirectory()).map(H=>H.name).filter(k),R=0,E=0,V=0;for(let H of j){let ae=A.default.readdirSync(Re.default.join(T,H)),X=ae.filter(Ae=>Ae.match(/-PLAN\.md$/i)).length,Z=ae.filter(Ae=>Ae.match(/-SUMMARY\.md$/i)).length;R+=X,E+=Z,X>0&&Z>=X&&V++}f=k.phaseCount>0?Math.max(j.length,k.phaseCount):j.length,g=V,h=R,x=E}}catch{}let S=null;if(c){let T=c.match(/(\d+)%/);T&&(S=parseInt(T[1],10))}let v=a??"unknown",C=(a??"").toLowerCase();C.includes("paused")||C.includes("stopped")||u?v="paused":C.includes("executing")||C.includes("in progress")?v="executing":C.includes("planning")||C.includes("ready to plan")?v="planning":C.includes("discussing")?v="discussing":C.includes("verif")?v="verifying":C.includes("complete")||C.includes("done")?v="completed":C.includes("ready to execute")&&(v="executing");let P={gsd_state_version:"1.0"};m&&(P.milestone=m),p&&(P.milestone_name=p),s&&(P.current_phase=s),r&&(P.current_phase_name=r),n&&(P.current_plan=n),P.status=v,d&&(P.stopped_at=d),u&&(P.paused_at=u),P.last_updated=new Date().toISOString(),l&&(P.last_activity=l);let $={};return f!==null&&($.total_phases=f),g!==null&&($.completed_phases=g),h!==null&&($.total_plans=h),x!==null&&($.completed_plans=x),S!==null&&($.percent=S),Object.keys($).length>0&&(P.progress=$),P}function Bi(t,e){let s=le(t),r=zs(t),n=kr(r,e);return n.status==="unknown"&&s.status&&s.status!=="unknown"&&(n.status=s.status),`---
|
|
152
152
|
${$t(n)}
|
|
153
153
|
---
|
|
154
154
|
|
|
@@ -179,8 +179,8 @@ ${i}
|
|
|
179
179
|
`+g;let x=`Plan: 1 of ${r??"?"}`;g=/^Plan:/m.test(g)?g.replace(/^Plan:.*$/m,x):g.replace(/^(Phase:.*$)/m,`$1
|
|
180
180
|
${x}`),/^Status:/m.test(g)&&(g=g.replace(/^Status:.*$/m,`Status: Executing Phase ${e}`)),/^Last activity:/im.test(g)&&(g=g.replace(/^Last activity:.*$/im,`Last activity: ${a} -- Phase ${e} execution started`)),o=o.replace(m,`${f}${g}`),c.push("Current Position")}c.length>0&&ne(i,o,t),y({updated:c,phase:e,phase_name:s??null,plan_count:r??null},n,c.length>0?"true":"false")}function oo(t,e,s,r,n,i){let o=A.default.existsSync(Re.default.join(t,".gsd"))?Re.default.join(t,".gsd"):W(t),a=Re.default.join(o,"WAITING.json"),c={status:"waiting",type:e??"decision_point",question:s??null,options:r?r.split("|").map(l=>l.trim()):[],since:new Date().toISOString(),phase:n??null};try{A.default.mkdirSync(o,{recursive:!0}),A.default.writeFileSync(a,JSON.stringify(c,null,2),"utf-8"),y({signaled:!0,path:a},i,"true")}catch(l){y({signaled:!1,error:l.message},i,"false")}}function ao(t,e){let s=[Re.default.join(t,".gsd","WAITING.json"),Re.default.join(W(t),"WAITING.json")],r=!1;for(let n of s)if(A.default.existsSync(n))try{A.default.unlinkSync(n),r=!0}catch{}y({resumed:!0,removed:r},e,r?"true":"false")}function Ct(t){let e=F(t);if(!A.default.existsSync(e.state))return{reconciled:!1,changes:[],phases_complete:0,phases_total:0,plans_complete:0,plans_total:0,percent:0};if(!A.default.existsSync(e.phases))return{reconciled:!1,changes:[],phases_complete:0,phases_total:0,plans_complete:0,plans_total:0,percent:0};let s=ke(t),r=A.default.readdirSync(e.phases,{withFileTypes:!0}).filter(k=>k.isDirectory()).map(k=>k.name).filter(s).sort(),n=0,i=0,o=0,a=r.length,c=[],l=new Date().toISOString().split("T")[0],d=[];for(let k of r){let j=Re.default.join(e.phases,k),R=A.default.readdirSync(j),E=R.filter(Z=>Z.match(/-PLAN\.md$/i)).length,V=R.filter(Z=>Z.match(/-SUMMARY\.md$/i)).length,H=R.some(Z=>Z.match(/CONTEXT\.md$/i)),ae=k.match(/^(\d+(?:\.\d+)?)/)?.[1]??k.split("-")[0],X=E>0&&V>=E;n+=E,i+=V,X&&o++,d.push({dir:k,dirPath:j,phaseNum:ae,numVal:parseFloat(ae),plans:E,summaries:V,hasContext:H,complete:X})}for(let k of d){if(k.plans>0||k.complete||!d.some(H=>H.numVal>k.numVal&&H.complete))continue;let R=k.phaseNum.replace(".","-"),E=Re.default.join(k.dirPath,`${R}-01-PLAN.md`),V=Re.default.join(k.dirPath,`${R}-01-SUMMARY.md`);A.default.existsSync(E)||A.default.writeFileSync(E,["---",`plan: "${R}-01"`,`phase: "${k.phaseNum}"`,"status: complete","absorbed: true","---","",`# Plan ${R}-01 \u2014 [ABSORBED]`,"","Phase absorbed into a later phase. All deliverables completed there.",""].join(`
|
|
181
181
|
`),"utf-8"),A.default.existsSync(V)||A.default.writeFileSync(V,["---",`plan: "${R}-01"`,`phase: "${k.phaseNum}"`,"status: complete","absorbed: true",`completed_at: "${l}"`,"---","",`# Summary ${R}-01 \u2014 Phase ${k.phaseNum} Absorbed`,"","Phase deliverables completed as part of a later phase execution.",""].join(`
|
|
182
|
-
`),"utf-8"),n++,i++,o++,k.complete=!0,c.push(`Phase ${k.phaseNum}: absorbed (0 plans, later phase complete) \u2014 created stubs`)}if(A.default.existsSync(e.roadmap)){let k=A.default.readFileSync(e.roadmap,"utf-8"),j=!1;for(let R of d){if(!R.complete)continue;let E=R.phaseNum.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),V=new RegExp(`(-\\s*\\[)[ ](\\]\\s*(?:\\*\\*)?\\s*Phase\\s+${E}[^\\n]*)`,"i");if(V.test(k)){k=k.replace(V,"$1x$2"),j=!0;continue}let H=new RegExp(`(\\|\\s*${E}\\.?\\s+[^|]*(?:\\|[^|]*)*\\|[^|]*)\\b(?:Pending|In Progress|Planning|Executing|Verifying|Discussed|Researched|Empty)\\b`,"i");H.test(k)&&(k=k.replace(H,"$1Complete"),j=!0)}j&&(A.default.writeFileSync(e.roadmap,k,"utf-8"),c.push("ROADMAP.md updated to match disk completion status"))}let u=A.default.readFileSync(e.state,"utf-8"),m=n>0?Math.min(100,Math.round(i/n*100)):0,p=Math.round(m/100*10),f=`${"\u2588".repeat(p)}${"\u2591".repeat(10-p)}] ${m}%`,g=/(\*\*Progress:\*\*\s*).*/i,h=/^(Progress:\s*).*/im;g.test(u)?u=u.replace(g,(k,j)=>`${j}[${f}`):h.test(u)&&(u=u.replace(h,(k,j)=>`${j}[${f}`));let x=[...d].sort((k,j)=>Se(k.phaseNum,j.phaseNum)),S=x.find(k=>k.plans>0&&k.summaries<k.plans),v=x.find(k=>k.plans===0&&!k.complete),C=x.length>0&&x.every(k=>k.complete),P=null,$="",T="";if(S){P=S;let k=S.summaries+1;$=`Executing Phase ${S.phaseNum}`,T=`${k} of ${S.plans}`}else if(C)if(v)P=v,$="Ready to plan",T="Not started";else{let k=x[x.length-1];P=k,$="Milestone complete",T=`${k.plans} of ${k.plans}`}else{let k=x.find(j=>!j.complete);k&&(P=k,k.plans>0?($="Ready to execute",T=`1 of ${k.plans}`):($="Ready to plan",T="Not started"))}if(P){let k=z(u,"Current Phase"),j=z(u,"Status"),R=k?.match(/^(\d+(?:\.\d+)?)/)?.[1]??null,E=P.phaseNum,V=R===E,H=!V||j&&!j.toLowerCase().includes($.toLowerCase().split(" ")[0]);if(!V){let Z=P.dir.replace(/^\d+(?:\.\d+)?-?/,"").replace(/-/g," "),Ae=a>0?`${E} of ${a}${Z?` (${Z})`:""}`:E;u=ue(u,"Current Phase","Phase",Ae),Z&&(u=ue(u,"Current Phase Name",null,Z)),c.push(`Current Phase: ${R??"(unset)"} \u2192 ${E}`)}H&&(u=ue(u,"Status",null,$),c.push(`Status: ${j??"(unset)"} \u2192 ${$}`));let ae=z(u,"Current Plan")??z(u,"Plan");ae!==T&&(u=ue(u,"Current Plan","Plan",T),c.push(`Plan: ${ae??"(unset)"} \u2192 ${T}`));let X=z(u,"Total Phases");X&&parseInt(X,10)!==a&&(u=be(u,"Total Phases",String(a))??u,c.push(`Total Phases: ${X} \u2192 ${a}`)),u=Us(u,{status:$,plan:T})}return ne(e.state,u,t),{reconciled:!0,changes:c,phases_complete:o,phases_total:a,plans_complete:i,plans_total:n,percent:m}}function co(t,e){let s=F(t);if(!A.default.existsSync(s.state)){y({reconciled:!1,reason:"no STATE.md"},e,"false");return}if(!A.default.existsSync(s.phases)){y({reconciled:!1,reason:"no phases dir"},e,"false");return}let r=Ct(t);y(r,e,r.changes.length>0?`Reconciled: ${r.changes.join("; ")}`:`State consistent (${r.phases_complete}/${r.phases_total} phases, ${r.plans_complete}/${r.plans_total} plans)`)}var A,Re,$e=L(()=>{"use strict";A=U(require("fs")),Re=U(require("path"));ye();Ve();dn()});var mt,un,mn,pn,fn,gn,hn,yn,xn,Pr=L(()=>{"use strict";mt=require("@oclif/core");je();un=class t extends w{static description="Output GSD state as JSON";static flags={...w.baseFlags};async run(){let{flags:e}=await this.parse(t),{cwd:s,raw:r}=this.resolveContext(e);(await Promise.resolve().then(()=>($e(),ze))).cmdStateJson(s,r)}},mn=class t extends w{static description="Get a specific state field";static args={field:mt.Args.string({required:!0})};static flags={...w.baseFlags};async run(){let{flags:e,args:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e);(await Promise.resolve().then(()=>($e(),ze))).cmdStateGet(r,s.field,n)}},pn=class t extends w{static description="Update a state field";static args={field:mt.Args.string({required:!0}),value:mt.Args.string({required:!0})};static flags={...w.baseFlags};async run(){let{flags:e,args:s}=await this.parse(t),{cwd:r}=this.resolveContext(e);(await Promise.resolve().then(()=>($e(),ze))).cmdStateUpdate(r,s.field,s.value)}},fn=class t extends w{static description="Patch multiple state fields";static args={pairs:mt.Args.string({required:!1})};static flags={...w.baseFlags,field:mt.Flags.string({multiple:!0,description:"field=value pair"})};async run(){let{flags:e,argv:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e),i=await Promise.resolve().then(()=>($e(),ze)),o={},a=s.filter(c=>!c.startsWith("--"));for(let c=0;c<a.length;c+=2){let l=a[c].replace(/^--/,"");l&&a[c+1]!==void 0&&(o[l]=a[c+1])}i.cmdStatePatch(r,o,n)}},gn=class t extends w{static description="Advance to next plan";static flags={...w.baseFlags};async run(){let{flags:e}=await this.parse(t),{cwd:s,raw:r}=this.resolveContext(e);(await Promise.resolve().then(()=>($e(),ze))).cmdStateAdvancePlan(s,r)}},hn=class t extends w{static description="Load and display state";static flags={...w.baseFlags};async run(){let{flags:e}=await this.parse(t),{cwd:s,raw:r}=this.resolveContext(e);(await Promise.resolve().then(()=>($e(),ze))).cmdStateLoad(s,r)}},yn=class t extends w{static description="Update progress counters";static flags={...w.baseFlags};async run(){let{flags:e}=await this.parse(t),{cwd:s,raw:r}=this.resolveContext(e);(await Promise.resolve().then(()=>($e(),ze))).cmdStateUpdateProgress(s,r)}},xn=class t extends w{static description="Reconcile STATE.md with disk truth";static flags={...w.baseFlags};async run(){let{flags:e}=await this.parse(t),{cwd:s,raw:r}=this.resolveContext(e);(await Promise.resolve().then(()=>($e(),ze))).cmdStateReconcile(s,r)}}});var Sn={};xe(Sn,{cmdAgentSkills:()=>$o,cmdInitExecutePhase:()=>lo,cmdInitListWorkspaces:()=>ko,cmdInitManager:()=>_o,cmdInitMapCodebase:()=>bo,cmdInitMilestoneOp:()=>So,cmdInitNewMilestone:()=>po,cmdInitNewProject:()=>mo,cmdInitNewWorkspace:()=>wo,cmdInitPhaseOp:()=>yo,cmdInitPlanPhase:()=>uo,cmdInitProgress:()=>vo,cmdInitQuick:()=>fo,cmdInitRemoveWorkspace:()=>Po,cmdInitResume:()=>go,cmdInitTodos:()=>xo,cmdInitVerifyWork:()=>ho});function $r(t){let e=Te.default.join(ee(t),"MILESTONES.md");if(!G.default.existsSync(e))return null;try{let r=G.default.readFileSync(e,"utf-8").match(/^##\s+(v[\d.]+)\s+(.+?)\s+\(Shipped:/m);return r?{version:r[1],name:r[2].trim()}:null}catch{return null}}function ge(t,e){e.project_root=t,e.gsd_bin="dist/gsd-tools.js",e.gsd_root=".",e.gsd_harness_dir=".";let s=_t();return e.agents_installed=s.agents_installed,e.missing_agents=s.missing_agents,e}function lo(t,e,s){e||b("phase required for init execute-phase"),Ct(t);let r=Q(t),n=he(t,e),i=ce(t),o=dt(t,e);if(!n&&o?.found){let d=o.phase_name;n={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),c=a?a[1].replace(/[[\]]/g,"").split(",").map(d=>d.trim()).filter(Boolean).join(", "):null,l=ge(t,{executor_model:oe(t,"gsd-executor"),verifier_model:oe(t,"gsd-verifier"),commit_docs:r.commit_docs,sub_repos:r.sub_repos,parallelization:r.parallelization,context_window:r.context_window,branching_strategy:r.branching_strategy,phase_branch_template:r.phase_branch_template,milestone_branch_template:r.milestone_branch_template,verifier_enabled:r.verifier,phase_found:!!n,phase_dir:n?.directory??null,phase_number:n?.phase_number??null,phase_name:n?.phase_name??null,phase_slug:n?.phase_slug??null,phase_req_ids:c&&c!=="TBD"?c:null,plans:n?.plans??[],summaries:n?.summaries??[],incomplete_plans:n?.incomplete_plans??[],has_research:n?.has_research??!1,has_context:n?.has_context??!1,has_verification:n?.has_verification??!1,has_reviews:n?.has_reviews??!1,roadmap_goal:o?.goal??null,roadmap_section:o?.section??null,milestone_version:i.version,milestone_name:i.name});y(l,s)}function uo(t,e,s){e||b("phase required for init plan-phase");let r=Q(t),n=he(t,e),i=dt(t,e),o=ce(t),a=ge(t,{planner_model:oe(t,"gsd-planner"),researcher_model:oe(t,"gsd-phase-researcher"),synthesizer_model:oe(t,"gsd-research-synthesizer"),commit_docs:r.commit_docs,research_enabled:r.research,plan_checker_enabled:r.plan_checker,context_window:r.context_window,phase_found:!!n,phase_dir:n?.directory??null,phase_number:n?.phase_number??null,phase_name:n?.phase_name??null,roadmap_goal:i?.goal??null,roadmap_section:i?.section??null,milestone_version:o.version,milestone_name:o.name});y(a,s)}function mo(t,e){let s=Q(t),r=ee(t),n=ge(t,{planner_model:oe(t,"gsd-planner"),roadmapper_model:oe(t,"gsd-roadmapper"),commit_docs:s.commit_docs,context_window:s.context_window,planning_exists:G.default.existsSync(r),project_exists:G.default.existsSync(Te.default.join(r,"PROJECT.md")),config_exists:G.default.existsSync(Te.default.join(r,"config.json")),roadmap_exists:G.default.existsSync(Te.default.join(r,"ROADMAP.md")),state_exists:G.default.existsSync(Te.default.join(r,"STATE.md"))});y(n,e)}function po(t,e){let s=Q(t),r=ce(t),n=$r(t),i=ge(t,{roadmapper_model:oe(t,"gsd-roadmapper"),commit_docs:s.commit_docs,context_window:s.context_window,current_milestone:r,last_completed_milestone:n,roadmap_exists:G.default.existsSync(F(t).roadmap)});y(i,e)}function fo(t,e,s){let r=Q(t),n=ce(t),i=ge(t,{executor_model:oe(t,"gsd-executor"),commit_docs:r.commit_docs,context_window:r.context_window,branching_strategy:r.branching_strategy,quick_branch_template:r.quick_branch_template,description:e||null,milestone_version:n.version,milestone_name:n.name,state_exists:G.default.existsSync(F(t).state)});y(i,s)}function go(t,e){Ct(t);let s=Q(t),r=ce(t),n=G.default.existsSync(F(t).state),i="";if(n)try{i=G.default.readFileSync(F(t).state,"utf-8")}catch{}let o=ge(t,{executor_model:oe(t,"gsd-executor"),commit_docs:s.commit_docs,context_window:s.context_window,state_exists:n,state_raw:i,roadmap_exists:G.default.existsSync(F(t).roadmap),config_exists:G.default.existsSync(F(t).config),milestone_version:r.version,milestone_name:r.name});y(o,e)}function ho(t,e,s){e||b("phase required for init verify-work");let r=Q(t),n=he(t,e),i=dt(t,e),o=ge(t,{verifier_model:oe(t,"gsd-verifier"),nyquist_model:oe(t,"gsd-nyquist-auditor"),commit_docs:r.commit_docs,nyquist_validation:r.nyquist_validation,context_window:r.context_window,phase_found:!!n,phase_dir:n?.directory??null,phase_number:n?.phase_number??null,phase_name:n?.phase_name??null,plans:n?.plans??[],summaries:n?.summaries??[],roadmap_goal:i?.goal??null});y(o,s)}function yo(t,e,s){let r=Q(t),n=e?he(t,e):null,i=ce(t),o=ge(t,{planner_model:oe(t,"gsd-planner"),commit_docs:r.commit_docs,context_window:r.context_window,phase_found:!!n,phase_dir:n?.directory??null,phase_number:n?.phase_number??null,phase_name:n?.phase_name??null,milestone_version:i.version,milestone_name:i.name});y(o,s)}function xo(t,e,s){let r=Q(t),n=Te.default.join(W(t),"todos","pending"),i=[];if(G.default.existsSync(n))try{for(let a of G.default.readdirSync(n).filter(c=>c.endsWith(".md")))try{let c=G.default.readFileSync(Te.default.join(n,a),"utf-8"),l=c.match(/^title:\s*(.+)$/m),d=c.match(/^area:\s*(.+)$/m),u=d?d[1].trim():"general";if(e&&u!==e)continue;i.push({file:a,title:l?l[1].trim():"Untitled",area:u})}catch{}}catch{}let o=ge(t,{executor_model:oe(t,"gsd-executor"),commit_docs:r.commit_docs,todos:i,todo_count:i.length,area:e??null});y(o,s)}function So(t,e){let s=Q(t),r=ce(t),n=$r(t),i=ge(t,{planner_model:oe(t,"gsd-planner"),commit_docs:s.commit_docs,context_window:s.context_window,milestone_version:r.version,milestone_name:r.name,last_completed_milestone:n,roadmap_exists:G.default.existsSync(F(t).roadmap),state_exists:G.default.existsSync(F(t).state)});y(i,e)}function bo(t,e){let s=Q(t),r=ge(t,{mapper_model:oe(t,"gsd-codebase-mapper"),commit_docs:s.commit_docs,search_gitignored:s.search_gitignored,context_window:s.context_window,project_exists:G.default.existsSync(Te.default.join(ee(t),"PROJECT.md"))});y(r,e)}function vo(t,e){Ct(t);let s=Q(t),r=ce(t),n=ke(t),i=F(t).phases,o=0,a=0,c=0;if(G.default.existsSync(i))try{let d=G.default.readdirSync(i,{withFileTypes:!0}).filter(u=>u.isDirectory()).map(u=>u.name).filter(n);c=d.length;for(let u of d){let m=G.default.readdirSync(Te.default.join(i,u));o+=m.filter(p=>p.match(/-PLAN\.md$/i)).length,a+=m.filter(p=>p.match(/-SUMMARY\.md$/i)).length}}catch{}let l=ge(t,{commit_docs:s.commit_docs,context_window:s.context_window,milestone_version:r.version,milestone_name:r.name,phase_count:c,total_plans:o,total_summaries:a,percent:o>0?Math.min(100,Math.round(a/o*100)):0});y(l,e)}function _o(t,e){let s=Q(t),r=ce(t),n=ge(t,{planner_model:oe(t,"gsd-planner"),roadmapper_model:oe(t,"gsd-roadmapper"),commit_docs:s.commit_docs,context_window:s.context_window,milestone_version:r.version,milestone_name:r.name,state_exists:G.default.existsSync(F(t).state),roadmap_exists:G.default.existsSync(F(t).roadmap)});y(n,e)}function wo(t,e){let s=Q(t),r=Te.default.join(ee(t),"workstreams"),n=ge(t,{commit_docs:s.commit_docs,context_window:s.context_window,workstream_mode:G.default.existsSync(r),workstreams:G.default.existsSync(r)?G.default.readdirSync(r,{withFileTypes:!0}).filter(i=>i.isDirectory()).map(i=>i.name):[]});y(n,e)}function ko(t,e){let s=Te.default.join(ee(t),"workstreams");if(!G.default.existsSync(s)){y(ge(t,{mode:"flat",workstreams:[],count:0}),e);return}let r=G.default.readdirSync(s,{withFileTypes:!0}).filter(n=>n.isDirectory()).map(n=>n.name);y(ge(t,{mode:"workstream",workstreams:r,count:r.length}),e)}function Po(t,e,s){e||b("workstream name required for init remove-workspace");let r=Te.default.join(ee(t),"workstreams",e);if(!G.default.existsSync(r)){y(ge(t,{removed:!1,reason:"not_found",workstream:e}),s);return}try{G.default.rmSync(r,{recursive:!0,force:!0})}catch(n){y(ge(t,{removed:!1,reason:n.message,workstream:e}),s);return}y(ge(t,{removed:!0,workstream:e}),s)}function $o(t,e,s){e||b("agent-type required");let n=Q(t).agent_skills[e]??{};y({agent:e,skills:n},s,JSON.stringify(n))}var G,Te,bn=L(()=>{"use strict";G=U(require("fs")),Te=U(require("path"));ye();$e()});var vn,_n,Cr=L(()=>{"use strict";vn=require("@oclif/core");je();_n=class t extends w{static description="Initialise a GSD workflow context";static args={workflow:vn.Args.string({required:!0}),phase:vn.Args.string({required:!1}),rest:vn.Args.string({required:!1})};static flags={...w.baseFlags};static strict=!1;async run(){let{flags:e,argv:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e),i=s,o=i[0],a=await Promise.resolve().then(()=>(bn(),Sn)),{gsdError:c}=await Promise.resolve().then(()=>(ye(),Sr));switch(o){case"execute-phase":return a.cmdInitExecutePhase(r,i[1],n);case"plan-phase":return a.cmdInitPlanPhase(r,i[1],n);case"new-project":return a.cmdInitNewProject(r,n);case"new-milestone":return a.cmdInitNewMilestone(r,n);case"quick":return a.cmdInitQuick(r,i.slice(1).join(" "),n);case"resume":return a.cmdInitResume(r,n);case"verify-work":return a.cmdInitVerifyWork(r,i[1],n);case"phase-op":return a.cmdInitPhaseOp(r,i[1],n);case"todos":return a.cmdInitTodos(r,i[1],n);case"milestone-op":return a.cmdInitMilestoneOp(r,n);case"map-codebase":return a.cmdInitMapCodebase(r,n);case"progress":return a.cmdInitProgress(r,n);case"manager":return a.cmdInitManager(r,n);case"new-workspace":return a.cmdInitNewWorkspace(r,n);case"list-workspaces":return a.cmdInitListWorkspaces(r,n);case"remove-workspace":return a.cmdInitRemoveWorkspace(r,i[1],n);default:c(`Unknown init workflow: ${o}`)}}}});var wn={};xe(wn,{cmdRoadmapAnalyze:()=>Ao,cmdRoadmapGetPhase:()=>Co,cmdRoadmapUpdatePlanProgress:()=>jo});function Co(t,e,s){let r=F(t).roadmap;if(!Be.default.existsSync(r)){y({found:!1,error:"ROADMAP.md not found"},s,"");return}try{let n=we(Be.default.readFileSync(r,"utf-8"),t),i=ie(e??""),o=new RegExp(`#{2,4}\\s*Phase\\s+${i}:\\s*([^\\n]+)`,"i"),a=n.match(o);if(!a){let x=new RegExp(`-\\s*\\[[ x]\\]\\s*\\*\\*Phase\\s+${i}:\\s*([^*]+)\\*\\*`,"i"),S=n.match(x);if(S){y({found:!1,phase_number:e,phase_name:S[1].trim(),error:"malformed_roadmap",message:`Phase ${e} exists in summary list but missing detail section.`},s,"");return}y({found:!1,phase_number:e},s,"");return}let c=a[1].trim(),l=a.index,u=n.slice(l).match(/\n#{2,4}\s+Phase\s+\d/i),m=u?l+u.index:n.length,p=n.slice(l,m).trim(),f=p.match(/\*\*Goal(?::\*\*|\*\*:)\s*([^\n]+)/i),g=p.match(/\*\*Success Criteria\*\*[^\n]*:\s*\n((?:\s*\d+\.\s*[^\n]+\n?)+)/i),h=g?g[1].trim().split(`
|
|
183
|
-
`).map(x=>x.replace(/^\s*\d+\.\s*/,"").trim()).filter(Boolean):[];y({found:!0,phase_number:e,phase_name:c,goal:f?f[1].trim():null,success_criteria:h,section:p},s,p)}catch(n){b("Failed to read ROADMAP.md: "+n.message)}}function Ao(t,e){let s=F(t).roadmap;if(!Be.default.existsSync(s)){y({error:"ROADMAP.md not found",milestones:[],phases:[],current_phase:null},e);return}let r=Be.default.readFileSync(s,"utf-8"),n=we(r,t),i=F(t).phases,o=/#{2,4}\s*Phase\s+(\d+[A-Z]?(?:\.\d+)*)\s*:\s*([^\n]+)/gi,a=[],c;for(;(c=o.exec(n))!==null;){let $=c[1],T=c[2].replace(/\(INSERTED\)/i,"").trim(),k=c.index,j=n.slice(k).match(/\n#{2,4}\s+Phase\s+\d/i),R=j?k+j.index:n.length,E=n.slice(k,R),V=E.match(/\*\*Goal(?::\*\*|\*\*:)\s*([^\n]+)/i),H=E.match(/\*\*Depends on(?::\*\*|\*\*:)\s*([^\n]+)/i),ae=pe($),X="no_directory",Z=0,Ae=0,qe=!1,Dt=!1;try{let nn=Be.default.readdirSync(i,{withFileTypes:!0}).filter(Ee=>Ee.isDirectory()).map(Ee=>Ee.name).find(Ee=>Ee.startsWith(ae+"-")||Ee===ae);if(nn){let Ee=Be.default.readdirSync(Ar.default.join(i,nn));Z=Ee.filter(Fe=>Fe.endsWith("-PLAN.md")||Fe==="PLAN.md").length,Ae=Ee.filter(Fe=>Fe.endsWith("-SUMMARY.md")||Fe==="SUMMARY.md").length,qe=Ee.some(Fe=>Fe.endsWith("-CONTEXT.md")||Fe==="CONTEXT.md"),Dt=Ee.some(Fe=>Fe.endsWith("-RESEARCH.md")||Fe==="RESEARCH.md"),Ae>=Z&&Z>0?X="complete":Ae>0?X="partial":Z>0?X="planned":Dt?X="researched":qe?X="discussed":X="empty"}}catch{}let js=new RegExp(`-\\s*\\[(x| )\\]\\s*.*Phase\\s+${ie($)}[:\\s]`,"i"),en=n.match(js),tn=en?en[1]==="x":!1;tn&&X!=="complete"&&(X="complete"),a.push({number:$,name:T,goal:V?V[1].trim():null,depends_on:H?H[1].trim():null,plan_count:Z,summary_count:Ae,has_context:qe,has_research:Dt,disk_status:X,roadmap_complete:tn})}let l=[],d=/##\s*(.*v(\d+(?:\.\d+)+)[^(\n]*)/gi,u;for(;(u=d.exec(n))!==null;)l.push({heading:u[1].trim(),version:"v"+u[2]});let m=a.find($=>$.disk_status==="planned"||$.disk_status==="partial")??null,p=a.find($=>["empty","no_directory","discussed","researched"].includes($.disk_status))??null,f=a.reduce(($,T)=>$+T.plan_count,0),g=a.reduce(($,T)=>$+T.summary_count,0),h=a.filter($=>$.disk_status==="complete").length,x=/-\s*\[[ x]\]\s*\*\*Phase\s+(\d+[A-Z]?(?:\.\d+)*)/gi,S=new Set,v;for(;(v=x.exec(n))!==null;)S.add(v[1]);let C=new Set(a.map($=>$.number)),P=[...S].filter($=>!C.has($));y({milestones:l,phases:a,phase_count:a.length,completed_phases:h,total_plans:f,total_summaries:g,progress_percent:f>0?Math.min(100,Math.round(g/f*100)):0,current_phase:m?m.number:null,next_phase:p?p.number:null,missing_phase_details:P.length>0?P:null},e)}function jo(t,e,s){e||b("phase number required for roadmap update-plan-progress");let r=F(t).roadmap,n=he(t,e);n||b(`Phase ${e} not found`);let i=n.plans.length,o=n.summaries.length;if(i===0){y({updated:!1,reason:"No plans found",plan_count:0,summary_count:0},s,"no plans");return}let a=o>=i,c=a?"Complete":o>0?"In Progress":"Planned",l=new Date().toISOString().split("T")[0];if(!Be.default.existsSync(r)){y({updated:!1,reason:"ROADMAP.md not found",plan_count:i,summary_count:o},s,"no roadmap");return}let d=Be.default.readFileSync(r,"utf-8"),u=ie(e),m=new RegExp(`^(\\|\\s*${u}\\.?\\s[^|]*(?:\\|[^\\n]*))$`,"im"),p=a?` ${l} `:" ";d=d.replace(m,g=>{let h=g.split("|").slice(1,-1);return h.length===5?(h[2]=` ${o}/${i} `,h[3]=` ${c.padEnd(11)}`,h[4]=p):h.length===4&&(h[1]=` ${o}/${i} `,h[2]=` ${c.padEnd(11)}`,h[3]=p),"|"+h.join("|")+"|"});let f=new RegExp(`(#{2,4}\\s*Phase\\s+${u}[\\s\\S]*?\\*\\*Plans:\\*\\*\\s*)[^\\n]+`,"i");if(d=
|
|
182
|
+
`),"utf-8"),n++,i++,o++,k.complete=!0,c.push(`Phase ${k.phaseNum}: absorbed (0 plans, later phase complete) \u2014 created stubs`)}if(A.default.existsSync(e.roadmap)){let k=A.default.readFileSync(e.roadmap,"utf-8"),j=!1;for(let R of d){if(!R.complete)continue;let E=R.phaseNum.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),V=new RegExp(`(-\\s*\\[)[ ](\\]\\s*(?:\\*\\*)?\\s*Phase\\s+${E}[^\\n]*)`,"i");if(V.test(k)){k=k.replace(V,"$1x$2"),j=!0;continue}let H=new RegExp(`(\\|\\s*${E}\\.?\\s+[^|]*(?:\\|[^|]*)*\\|[^|]*)\\b(?:Pending|In Progress|Planning|Executing|Verifying|Discussed|Researched|Empty)\\b`,"i");H.test(k)&&(k=k.replace(H,"$1Complete"),j=!0)}j&&(A.default.writeFileSync(e.roadmap,k,"utf-8"),c.push("ROADMAP.md updated to match disk completion status"))}let u=A.default.readFileSync(e.state,"utf-8"),m=n>0?Math.min(100,Math.round(i/n*100)):0,p=Math.round(m/100*10),f=`${"\u2588".repeat(p)}${"\u2591".repeat(10-p)}] ${m}%`,g=/(\*\*Progress:\*\*\s*).*/i,h=/^(Progress:\s*).*/im;g.test(u)?u=u.replace(g,(k,j)=>`${j}[${f}`):h.test(u)&&(u=u.replace(h,(k,j)=>`${j}[${f}`));let x=[...d].sort((k,j)=>Se(k.phaseNum,j.phaseNum)),S=x.find(k=>k.plans>0&&k.summaries<k.plans),v=x.find(k=>k.plans===0&&!k.complete),C=x.length>0&&x.every(k=>k.complete),P=null,$="",T="";if(S){P=S;let k=S.summaries+1;$=`Executing Phase ${S.phaseNum}`,T=`${k} of ${S.plans}`}else if(C)if(v)P=v,$="Ready to plan",T="Not started";else{let k=x[x.length-1];P=k,$="Milestone complete",T=`${k.plans} of ${k.plans}`}else{let k=x.find(j=>!j.complete);k&&(P=k,k.plans>0?($="Ready to execute",T=`1 of ${k.plans}`):($="Ready to plan",T="Not started"))}if(P){let k=z(u,"Current Phase"),j=z(u,"Status"),R=k?.match(/^(\d+(?:\.\d+)?)/)?.[1]??null,E=P.phaseNum,V=R===E,H=!V||j&&!j.toLowerCase().includes($.toLowerCase().split(" ")[0]);if(!V){let Z=P.dir.replace(/^\d+(?:\.\d+)?-?/,"").replace(/-/g," "),Ae=a>0?`${E} of ${a}${Z?` (${Z})`:""}`:E;u=ue(u,"Current Phase","Phase",Ae),Z&&(u=ue(u,"Current Phase Name",null,Z)),c.push(`Current Phase: ${R??"(unset)"} \u2192 ${E}`)}H&&(u=ue(u,"Status",null,$),c.push(`Status: ${j??"(unset)"} \u2192 ${$}`));let ae=z(u,"Current Plan")??z(u,"Plan");ae!==T&&(u=ue(u,"Current Plan","Plan",T),c.push(`Plan: ${ae??"(unset)"} \u2192 ${T}`));let X=z(u,"Total Phases");X&&parseInt(X,10)!==a&&(u=be(u,"Total Phases",String(a))??u,c.push(`Total Phases: ${X} \u2192 ${a}`)),u=Us(u,{status:$,plan:T})}return ne(e.state,u,t),{reconciled:!0,changes:c,phases_complete:o,phases_total:a,plans_complete:i,plans_total:n,percent:m}}function co(t,e){let s=F(t);if(!A.default.existsSync(s.state)){y({reconciled:!1,reason:"no STATE.md"},e,"false");return}if(!A.default.existsSync(s.phases)){y({reconciled:!1,reason:"no phases dir"},e,"false");return}let r=Ct(t);y(r,e,r.changes.length>0?`Reconciled: ${r.changes.join("; ")}`:`State consistent (${r.phases_complete}/${r.phases_total} phases, ${r.plans_complete}/${r.plans_total} plans)`)}var A,Re,$e=L(()=>{"use strict";A=U(require("fs")),Re=U(require("path"));ye();Ve();dn()});var pt,un,mn,pn,fn,gn,hn,yn,xn,Pr=L(()=>{"use strict";pt=require("@oclif/core");je();un=class t extends w{static description="Output GSD state as JSON";static flags={...w.baseFlags};async run(){let{flags:e}=await this.parse(t),{cwd:s,raw:r}=this.resolveContext(e);(await Promise.resolve().then(()=>($e(),ze))).cmdStateJson(s,r)}},mn=class t extends w{static description="Get a specific state field";static args={field:pt.Args.string({required:!0})};static flags={...w.baseFlags};async run(){let{flags:e,args:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e);(await Promise.resolve().then(()=>($e(),ze))).cmdStateGet(r,s.field,n)}},pn=class t extends w{static description="Update a state field";static args={field:pt.Args.string({required:!0}),value:pt.Args.string({required:!0})};static flags={...w.baseFlags};async run(){let{flags:e,args:s}=await this.parse(t),{cwd:r}=this.resolveContext(e);(await Promise.resolve().then(()=>($e(),ze))).cmdStateUpdate(r,s.field,s.value)}},fn=class t extends w{static description="Patch multiple state fields";static args={pairs:pt.Args.string({required:!1})};static flags={...w.baseFlags,field:pt.Flags.string({multiple:!0,description:"field=value pair"})};async run(){let{flags:e,argv:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e),i=await Promise.resolve().then(()=>($e(),ze)),o={},a=s.filter(c=>!c.startsWith("--"));for(let c=0;c<a.length;c+=2){let l=a[c].replace(/^--/,"");l&&a[c+1]!==void 0&&(o[l]=a[c+1])}i.cmdStatePatch(r,o,n)}},gn=class t extends w{static description="Advance to next plan";static flags={...w.baseFlags};async run(){let{flags:e}=await this.parse(t),{cwd:s,raw:r}=this.resolveContext(e);(await Promise.resolve().then(()=>($e(),ze))).cmdStateAdvancePlan(s,r)}},hn=class t extends w{static description="Load and display state";static flags={...w.baseFlags};async run(){let{flags:e}=await this.parse(t),{cwd:s,raw:r}=this.resolveContext(e);(await Promise.resolve().then(()=>($e(),ze))).cmdStateLoad(s,r)}},yn=class t extends w{static description="Update progress counters";static flags={...w.baseFlags};async run(){let{flags:e}=await this.parse(t),{cwd:s,raw:r}=this.resolveContext(e);(await Promise.resolve().then(()=>($e(),ze))).cmdStateUpdateProgress(s,r)}},xn=class t extends w{static description="Reconcile STATE.md with disk truth";static flags={...w.baseFlags};async run(){let{flags:e}=await this.parse(t),{cwd:s,raw:r}=this.resolveContext(e);(await Promise.resolve().then(()=>($e(),ze))).cmdStateReconcile(s,r)}}});var Sn={};xe(Sn,{cmdAgentSkills:()=>$o,cmdInitExecutePhase:()=>lo,cmdInitListWorkspaces:()=>ko,cmdInitManager:()=>_o,cmdInitMapCodebase:()=>bo,cmdInitMilestoneOp:()=>So,cmdInitNewMilestone:()=>po,cmdInitNewProject:()=>mo,cmdInitNewWorkspace:()=>wo,cmdInitPhaseOp:()=>yo,cmdInitPlanPhase:()=>uo,cmdInitProgress:()=>vo,cmdInitQuick:()=>fo,cmdInitRemoveWorkspace:()=>Po,cmdInitResume:()=>go,cmdInitTodos:()=>xo,cmdInitVerifyWork:()=>ho});function $r(t){let e=Te.default.join(ee(t),"MILESTONES.md");if(!G.default.existsSync(e))return null;try{let r=G.default.readFileSync(e,"utf-8").match(/^##\s+(v[\d.]+)\s+(.+?)\s+\(Shipped:/m);return r?{version:r[1],name:r[2].trim()}:null}catch{return null}}function ge(t,e){e.project_root=t,e.gsd_bin="dist/gsd-tools.js",e.gsd_root=".",e.gsd_harness_dir=".";let s=_t();return e.agents_installed=s.agents_installed,e.missing_agents=s.missing_agents,e}function lo(t,e,s){e||b("phase required for init execute-phase"),Ct(t);let r=Q(t),n=he(t,e),i=ce(t),o=ut(t,e);if(!n&&o?.found){let d=o.phase_name;n={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),c=a?a[1].replace(/[[\]]/g,"").split(",").map(d=>d.trim()).filter(Boolean).join(", "):null,l=ge(t,{executor_model:oe(t,"gsd-executor"),verifier_model:oe(t,"gsd-verifier"),commit_docs:r.commit_docs,sub_repos:r.sub_repos,parallelization:r.parallelization,context_window:r.context_window,branching_strategy:r.branching_strategy,phase_branch_template:r.phase_branch_template,milestone_branch_template:r.milestone_branch_template,verifier_enabled:r.verifier,phase_found:!!n,phase_dir:n?.directory??null,phase_number:n?.phase_number??null,phase_name:n?.phase_name??null,phase_slug:n?.phase_slug??null,phase_req_ids:c&&c!=="TBD"?c:null,plans:n?.plans??[],summaries:n?.summaries??[],incomplete_plans:n?.incomplete_plans??[],has_research:n?.has_research??!1,has_context:n?.has_context??!1,has_verification:n?.has_verification??!1,has_reviews:n?.has_reviews??!1,roadmap_goal:o?.goal??null,roadmap_section:o?.section??null,milestone_version:i.version,milestone_name:i.name});y(l,s)}function uo(t,e,s){e||b("phase required for init plan-phase");let r=Q(t),n=he(t,e),i=ut(t,e),o=ce(t),a=ge(t,{planner_model:oe(t,"gsd-planner"),researcher_model:oe(t,"gsd-phase-researcher"),synthesizer_model:oe(t,"gsd-research-synthesizer"),commit_docs:r.commit_docs,research_enabled:r.research,plan_checker_enabled:r.plan_checker,context_window:r.context_window,phase_found:!!n,phase_dir:n?.directory??null,phase_number:n?.phase_number??null,phase_name:n?.phase_name??null,roadmap_goal:i?.goal??null,roadmap_section:i?.section??null,milestone_version:o.version,milestone_name:o.name});y(a,s)}function mo(t,e){let s=Q(t),r=ee(t),n=ge(t,{planner_model:oe(t,"gsd-planner"),roadmapper_model:oe(t,"gsd-roadmapper"),commit_docs:s.commit_docs,context_window:s.context_window,planning_exists:G.default.existsSync(r),project_exists:G.default.existsSync(Te.default.join(r,"PROJECT.md")),config_exists:G.default.existsSync(Te.default.join(r,"config.json")),roadmap_exists:G.default.existsSync(Te.default.join(r,"ROADMAP.md")),state_exists:G.default.existsSync(Te.default.join(r,"STATE.md"))});y(n,e)}function po(t,e){let s=Q(t),r=ce(t),n=$r(t),i=ge(t,{roadmapper_model:oe(t,"gsd-roadmapper"),commit_docs:s.commit_docs,context_window:s.context_window,current_milestone:r,last_completed_milestone:n,roadmap_exists:G.default.existsSync(F(t).roadmap)});y(i,e)}function fo(t,e,s){let r=Q(t),n=ce(t),i=ge(t,{executor_model:oe(t,"gsd-executor"),commit_docs:r.commit_docs,context_window:r.context_window,branching_strategy:r.branching_strategy,quick_branch_template:r.quick_branch_template,description:e||null,milestone_version:n.version,milestone_name:n.name,state_exists:G.default.existsSync(F(t).state)});y(i,s)}function go(t,e){Ct(t);let s=Q(t),r=ce(t),n=G.default.existsSync(F(t).state),i="";if(n)try{i=G.default.readFileSync(F(t).state,"utf-8")}catch{}let o=ge(t,{executor_model:oe(t,"gsd-executor"),commit_docs:s.commit_docs,context_window:s.context_window,state_exists:n,state_raw:i,roadmap_exists:G.default.existsSync(F(t).roadmap),config_exists:G.default.existsSync(F(t).config),milestone_version:r.version,milestone_name:r.name});y(o,e)}function ho(t,e,s){e||b("phase required for init verify-work");let r=Q(t),n=he(t,e),i=ut(t,e),o=ge(t,{verifier_model:oe(t,"gsd-verifier"),nyquist_model:oe(t,"gsd-nyquist-auditor"),commit_docs:r.commit_docs,nyquist_validation:r.nyquist_validation,context_window:r.context_window,phase_found:!!n,phase_dir:n?.directory??null,phase_number:n?.phase_number??null,phase_name:n?.phase_name??null,plans:n?.plans??[],summaries:n?.summaries??[],roadmap_goal:i?.goal??null});y(o,s)}function yo(t,e,s){let r=Q(t),n=e?he(t,e):null,i=ce(t),o=ge(t,{planner_model:oe(t,"gsd-planner"),commit_docs:r.commit_docs,context_window:r.context_window,phase_found:!!n,phase_dir:n?.directory??null,phase_number:n?.phase_number??null,phase_name:n?.phase_name??null,milestone_version:i.version,milestone_name:i.name});y(o,s)}function xo(t,e,s){let r=Q(t),n=Te.default.join(W(t),"todos","pending"),i=[];if(G.default.existsSync(n))try{for(let a of G.default.readdirSync(n).filter(c=>c.endsWith(".md")))try{let c=G.default.readFileSync(Te.default.join(n,a),"utf-8"),l=c.match(/^title:\s*(.+)$/m),d=c.match(/^area:\s*(.+)$/m),u=d?d[1].trim():"general";if(e&&u!==e)continue;i.push({file:a,title:l?l[1].trim():"Untitled",area:u})}catch{}}catch{}let o=ge(t,{executor_model:oe(t,"gsd-executor"),commit_docs:r.commit_docs,todos:i,todo_count:i.length,area:e??null});y(o,s)}function So(t,e){let s=Q(t),r=ce(t),n=$r(t),i=ge(t,{planner_model:oe(t,"gsd-planner"),commit_docs:s.commit_docs,context_window:s.context_window,milestone_version:r.version,milestone_name:r.name,last_completed_milestone:n,roadmap_exists:G.default.existsSync(F(t).roadmap),state_exists:G.default.existsSync(F(t).state)});y(i,e)}function bo(t,e){let s=Q(t),r=ge(t,{mapper_model:oe(t,"gsd-codebase-mapper"),commit_docs:s.commit_docs,search_gitignored:s.search_gitignored,context_window:s.context_window,project_exists:G.default.existsSync(Te.default.join(ee(t),"PROJECT.md"))});y(r,e)}function vo(t,e){Ct(t);let s=Q(t),r=ce(t),n=ke(t),i=F(t).phases,o=0,a=0,c=0;if(G.default.existsSync(i))try{let d=G.default.readdirSync(i,{withFileTypes:!0}).filter(u=>u.isDirectory()).map(u=>u.name).filter(n);c=d.length;for(let u of d){let m=G.default.readdirSync(Te.default.join(i,u));o+=m.filter(p=>p.match(/-PLAN\.md$/i)).length,a+=m.filter(p=>p.match(/-SUMMARY\.md$/i)).length}}catch{}let l=ge(t,{commit_docs:s.commit_docs,context_window:s.context_window,milestone_version:r.version,milestone_name:r.name,phase_count:c,total_plans:o,total_summaries:a,percent:o>0?Math.min(100,Math.round(a/o*100)):0});y(l,e)}function _o(t,e){let s=Q(t),r=ce(t),n=ge(t,{planner_model:oe(t,"gsd-planner"),roadmapper_model:oe(t,"gsd-roadmapper"),commit_docs:s.commit_docs,context_window:s.context_window,milestone_version:r.version,milestone_name:r.name,state_exists:G.default.existsSync(F(t).state),roadmap_exists:G.default.existsSync(F(t).roadmap)});y(n,e)}function wo(t,e){let s=Q(t),r=Te.default.join(ee(t),"workstreams"),n=ge(t,{commit_docs:s.commit_docs,context_window:s.context_window,workstream_mode:G.default.existsSync(r),workstreams:G.default.existsSync(r)?G.default.readdirSync(r,{withFileTypes:!0}).filter(i=>i.isDirectory()).map(i=>i.name):[]});y(n,e)}function ko(t,e){let s=Te.default.join(ee(t),"workstreams");if(!G.default.existsSync(s)){y(ge(t,{mode:"flat",workstreams:[],count:0}),e);return}let r=G.default.readdirSync(s,{withFileTypes:!0}).filter(n=>n.isDirectory()).map(n=>n.name);y(ge(t,{mode:"workstream",workstreams:r,count:r.length}),e)}function Po(t,e,s){e||b("workstream name required for init remove-workspace");let r=Te.default.join(ee(t),"workstreams",e);if(!G.default.existsSync(r)){y(ge(t,{removed:!1,reason:"not_found",workstream:e}),s);return}try{G.default.rmSync(r,{recursive:!0,force:!0})}catch(n){y(ge(t,{removed:!1,reason:n.message,workstream:e}),s);return}y(ge(t,{removed:!0,workstream:e}),s)}function $o(t,e,s){e||b("agent-type required");let n=Q(t).agent_skills[e]??{};y({agent:e,skills:n},s,JSON.stringify(n))}var G,Te,bn=L(()=>{"use strict";G=U(require("fs")),Te=U(require("path"));ye();$e()});var vn,_n,Cr=L(()=>{"use strict";vn=require("@oclif/core");je();_n=class t extends w{static description="Initialise a GSD workflow context";static args={workflow:vn.Args.string({required:!0}),phase:vn.Args.string({required:!1}),rest:vn.Args.string({required:!1})};static flags={...w.baseFlags};static strict=!1;async run(){let{flags:e,argv:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e),i=s,o=i[0],a=await Promise.resolve().then(()=>(bn(),Sn)),{gsdError:c}=await Promise.resolve().then(()=>(ye(),Sr));switch(o){case"execute-phase":return a.cmdInitExecutePhase(r,i[1],n);case"plan-phase":return a.cmdInitPlanPhase(r,i[1],n);case"new-project":return a.cmdInitNewProject(r,n);case"new-milestone":return a.cmdInitNewMilestone(r,n);case"quick":return a.cmdInitQuick(r,i.slice(1).join(" "),n);case"resume":return a.cmdInitResume(r,n);case"verify-work":return a.cmdInitVerifyWork(r,i[1],n);case"phase-op":return a.cmdInitPhaseOp(r,i[1],n);case"todos":return a.cmdInitTodos(r,i[1],n);case"milestone-op":return a.cmdInitMilestoneOp(r,n);case"map-codebase":return a.cmdInitMapCodebase(r,n);case"progress":return a.cmdInitProgress(r,n);case"manager":return a.cmdInitManager(r,n);case"new-workspace":return a.cmdInitNewWorkspace(r,n);case"list-workspaces":return a.cmdInitListWorkspaces(r,n);case"remove-workspace":return a.cmdInitRemoveWorkspace(r,i[1],n);default:c(`Unknown init workflow: ${o}`)}}}});var wn={};xe(wn,{cmdRoadmapAnalyze:()=>Ao,cmdRoadmapGetPhase:()=>Co,cmdRoadmapUpdatePlanProgress:()=>jo});function Co(t,e,s){let r=F(t).roadmap;if(!Be.default.existsSync(r)){y({found:!1,error:"ROADMAP.md not found"},s,"");return}try{let n=we(Be.default.readFileSync(r,"utf-8"),t),i=ie(e??""),o=new RegExp(`#{2,4}\\s*Phase\\s+${i}:\\s*([^\\n]+)`,"i"),a=n.match(o);if(!a){let x=new RegExp(`-\\s*\\[[ x]\\]\\s*\\*\\*Phase\\s+${i}:\\s*([^*]+)\\*\\*`,"i"),S=n.match(x);if(S){y({found:!1,phase_number:e,phase_name:S[1].trim(),error:"malformed_roadmap",message:`Phase ${e} exists in summary list but missing detail section.`},s,"");return}y({found:!1,phase_number:e},s,"");return}let c=a[1].trim(),l=a.index,u=n.slice(l).match(/\n#{2,4}\s+Phase\s+\d/i),m=u?l+u.index:n.length,p=n.slice(l,m).trim(),f=p.match(/\*\*Goal(?::\*\*|\*\*:)\s*([^\n]+)/i),g=p.match(/\*\*Success Criteria\*\*[^\n]*:\s*\n((?:\s*\d+\.\s*[^\n]+\n?)+)/i),h=g?g[1].trim().split(`
|
|
183
|
+
`).map(x=>x.replace(/^\s*\d+\.\s*/,"").trim()).filter(Boolean):[];y({found:!0,phase_number:e,phase_name:c,goal:f?f[1].trim():null,success_criteria:h,section:p},s,p)}catch(n){b("Failed to read ROADMAP.md: "+n.message)}}function Ao(t,e){let s=F(t).roadmap;if(!Be.default.existsSync(s)){y({error:"ROADMAP.md not found",milestones:[],phases:[],current_phase:null},e);return}let r=Be.default.readFileSync(s,"utf-8"),n=we(r,t),i=F(t).phases,o=/#{2,4}\s*Phase\s+(\d+[A-Z]?(?:\.\d+)*)\s*:\s*([^\n]+)/gi,a=[],c;for(;(c=o.exec(n))!==null;){let $=c[1],T=c[2].replace(/\(INSERTED\)/i,"").trim(),k=c.index,j=n.slice(k).match(/\n#{2,4}\s+Phase\s+\d/i),R=j?k+j.index:n.length,E=n.slice(k,R),V=E.match(/\*\*Goal(?::\*\*|\*\*:)\s*([^\n]+)/i),H=E.match(/\*\*Depends on(?::\*\*|\*\*:)\s*([^\n]+)/i),ae=pe($),X="no_directory",Z=0,Ae=0,qe=!1,Dt=!1;try{let nn=Be.default.readdirSync(i,{withFileTypes:!0}).filter(Ee=>Ee.isDirectory()).map(Ee=>Ee.name).find(Ee=>Ee.startsWith(ae+"-")||Ee===ae);if(nn){let Ee=Be.default.readdirSync(Ar.default.join(i,nn));Z=Ee.filter(Fe=>Fe.endsWith("-PLAN.md")||Fe==="PLAN.md").length,Ae=Ee.filter(Fe=>Fe.endsWith("-SUMMARY.md")||Fe==="SUMMARY.md").length,qe=Ee.some(Fe=>Fe.endsWith("-CONTEXT.md")||Fe==="CONTEXT.md"),Dt=Ee.some(Fe=>Fe.endsWith("-RESEARCH.md")||Fe==="RESEARCH.md"),Ae>=Z&&Z>0?X="complete":Ae>0?X="partial":Z>0?X="planned":Dt?X="researched":qe?X="discussed":X="empty"}}catch{}let js=new RegExp(`-\\s*\\[(x| )\\]\\s*.*Phase\\s+${ie($)}[:\\s]`,"i"),en=n.match(js),tn=en?en[1]==="x":!1;tn&&X!=="complete"&&(X="complete"),a.push({number:$,name:T,goal:V?V[1].trim():null,depends_on:H?H[1].trim():null,plan_count:Z,summary_count:Ae,has_context:qe,has_research:Dt,disk_status:X,roadmap_complete:tn})}let l=[],d=/##\s*(.*v(\d+(?:\.\d+)+)[^(\n]*)/gi,u;for(;(u=d.exec(n))!==null;)l.push({heading:u[1].trim(),version:"v"+u[2]});let m=a.find($=>$.disk_status==="planned"||$.disk_status==="partial")??null,p=a.find($=>["empty","no_directory","discussed","researched"].includes($.disk_status))??null,f=a.reduce(($,T)=>$+T.plan_count,0),g=a.reduce(($,T)=>$+T.summary_count,0),h=a.filter($=>$.disk_status==="complete").length,x=/-\s*\[[ x]\]\s*\*\*Phase\s+(\d+[A-Z]?(?:\.\d+)*)/gi,S=new Set,v;for(;(v=x.exec(n))!==null;)S.add(v[1]);let C=new Set(a.map($=>$.number)),P=[...S].filter($=>!C.has($));y({milestones:l,phases:a,phase_count:a.length,completed_phases:h,total_plans:f,total_summaries:g,progress_percent:f>0?Math.min(100,Math.round(g/f*100)):0,current_phase:m?m.number:null,next_phase:p?p.number:null,missing_phase_details:P.length>0?P:null},e)}function jo(t,e,s){e||b("phase number required for roadmap update-plan-progress");let r=F(t).roadmap,n=he(t,e);n||b(`Phase ${e} not found`);let i=n.plans.length,o=n.summaries.length;if(i===0){y({updated:!1,reason:"No plans found",plan_count:0,summary_count:0},s,"no plans");return}let a=o>=i,c=a?"Complete":o>0?"In Progress":"Planned",l=new Date().toISOString().split("T")[0];if(!Be.default.existsSync(r)){y({updated:!1,reason:"ROADMAP.md not found",plan_count:i,summary_count:o},s,"no roadmap");return}let d=Be.default.readFileSync(r,"utf-8"),u=ie(e),m=new RegExp(`^(\\|\\s*${u}\\.?\\s[^|]*(?:\\|[^\\n]*))$`,"im"),p=a?` ${l} `:" ";d=d.replace(m,g=>{let h=g.split("|").slice(1,-1);return h.length===5?(h[2]=` ${o}/${i} `,h[3]=` ${c.padEnd(11)}`,h[4]=p):h.length===4&&(h[1]=` ${o}/${i} `,h[2]=` ${c.padEnd(11)}`,h[3]=p),"|"+h.join("|")+"|"});let f=new RegExp(`(#{2,4}\\s*Phase\\s+${u}[\\s\\S]*?\\*\\*Plans:\\*\\*\\s*)[^\\n]+`,"i");if(d=dt(d,f,`$1${a?`${o}/${i} plans complete`:`${o}/${i} plans executed`}`),a){let g=new RegExp(`(-\\s*\\[)[ ](\\]\\s*.*Phase\\s+${u}[:\\s][^\\n]*)`,"i");d=dt(d,g,`$1x$2 (completed ${l})`)}for(let g of n.summaries){let h=g.replace("-SUMMARY.md","").replace("SUMMARY.md","");h&&(d=d.replace(new RegExp(`(-\\s*\\[) (\\]\\s*${ie(h)})`,"i"),"$1x$2"))}Be.default.writeFileSync(r,d,"utf-8"),y({updated:!0,phase:e,plan_count:i,summary_count:o,status:c,complete:a},s,`${o}/${i} ${c}`)}var Be,Ar,kn=L(()=>{"use strict";Be=U(require("fs")),Ar=U(require("path"));ye()});var Gs,Pn,$n,Cn,jr=L(()=>{"use strict";Gs=require("@oclif/core");je();Pn=class t extends w{static description="Analyze roadmap phases and status";static flags={...w.baseFlags};async run(){let{flags:e}=await this.parse(t),{cwd:s,raw:r}=this.resolveContext(e);(await Promise.resolve().then(()=>(kn(),wn))).cmdRoadmapAnalyze(s,r)}},$n=class t extends w{static description="Get details for a specific phase";static args={phase:Gs.Args.string({required:!0})};static flags={...w.baseFlags};async run(){let{flags:e,args:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e);(await Promise.resolve().then(()=>(kn(),wn))).cmdRoadmapGetPhase(r,s.phase,n)}},Cn=class t extends w{static description="Update plan progress in roadmap";static args={phase:Gs.Args.string({required:!0})};static flags={...w.baseFlags};async run(){let{flags:e,args:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e);(await Promise.resolve().then(()=>(kn(),wn))).cmdRoadmapUpdatePlanProgress(r,s.phase,n)}}});var At={};xe(At,{cmdConfigEnsureSection:()=>Io,cmdConfigGet:()=>Do,cmdConfigNewProject:()=>Mo,cmdConfigSet:()=>To,cmdConfigSetModelProfile:()=>Oo,ensureConfigFile:()=>Js,setConfigValue:()=>Ys});function Eo(t){return!!(Er.has(t)||/^agent_skills\.[a-zA-Z0-9_-]+$/.test(t))}function Fo(t){let e=Ro[t];e&&b(`Unknown config key: ${t}. Did you mean ${e}?`)}function Fr(t){let e=t||{},s=Rr.default.homedir(),r=et.default.join(s,".gsd","brave_api_key"),n=!!(process.env.BRAVE_API_KEY||me.default.existsSync(r)),i=et.default.join(s,".gsd","firecrawl_api_key"),o=!!(process.env.FIRECRAWL_API_KEY||me.default.existsSync(i)),a=et.default.join(s,".gsd","exa_api_key"),c=!!(process.env.EXA_API_KEY||me.default.existsSync(a)),l=et.default.join(s,".gsd","defaults.json"),d={};try{if(me.default.existsSync(l)&&(d=JSON.parse(me.default.readFileSync(l,"utf-8")),"depth"in d&&!("granularity"in d))){let m={quick:"coarse",standard:"standard",comprehensive:"fine"};d.granularity=m[d.depth]||d.depth,delete d.depth;try{me.default.writeFileSync(l,JSON.stringify(d,null,2),"utf-8")}catch{}}}catch{}let u={model_profile:"balanced",commit_docs:!0,parallelization:!0,search_gitignored:!1,brave_search:n,firecrawl:o,exa_search:c,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 Js(t){let e=ee(t),s=et.default.join(e,"config.json");try{me.default.existsSync(e)||me.default.mkdirSync(e,{recursive:!0})}catch(n){b("Failed to create .planning directory: "+n.message)}if(me.default.existsSync(s))return{created:!1,reason:"already_exists"};let r=Fr({});try{return me.default.writeFileSync(s,JSON.stringify(r,null,2),"utf-8"),{created:!0,path:".planning/config.json"}}catch(n){b("Failed to create config.json: "+n.message)}}function Ys(t,e,s){let r=et.default.join(ee(t),"config.json"),n={};try{me.default.existsSync(r)&&(n=JSON.parse(me.default.readFileSync(r,"utf-8")))}catch(c){b("Failed to read config.json: "+c.message)}let i=e.split("."),o=n;for(let c=0;c<i.length-1;c++){let l=i[c];(o[l]===void 0||typeof o[l]!="object")&&(o[l]={}),o=o[l]}let a=o[i[i.length-1]];o[i[i.length-1]]=s;try{return me.default.writeFileSync(r,JSON.stringify(n,null,2),"utf-8"),{updated:!0,key:e,value:s,previousValue:a}}catch(c){b("Failed to write config.json: "+c.message)}}function Mo(t,e,s){let r=ee(t),n=et.default.join(r,"config.json");if(me.default.existsSync(n)){y({created:!1,reason:"already_exists"},s,"exists");return}let i={};if(e&&e.trim())try{i=JSON.parse(e)}catch(a){b("Invalid JSON for config-new-project: "+a.message)}try{me.default.existsSync(r)||me.default.mkdirSync(r,{recursive:!0})}catch(a){b("Failed to create .planning directory: "+a.message)}let o=Fr(i);try{me.default.writeFileSync(n,JSON.stringify(o,null,2),"utf-8"),y({created:!0,path:".planning/config.json"},s,"created")}catch(a){b("Failed to write config.json: "+a.message)}}function Io(t,e){let s=Js(t);y(s,e,s?.created?"created":"exists")}function To(t,e,s,r){e||b("Usage: config-set <key.path> <value>"),Fo(e),Eo(e)||b(`Unknown config key: "${e}". Valid keys: ${[...Er].sort().join(", ")}, agent_skills.<agent-type>`);let n=s;if(s==="true")n=!0;else if(s==="false")n=!1;else if(s!==void 0&&!isNaN(Number(s))&&s!=="")n=Number(s);else if(typeof s=="string"&&(s.startsWith("[")||s.startsWith("{")))try{n=JSON.parse(s)}catch{}let i=Ys(t,e,n);y(i,r,`${e}=${n}`)}function Do(t,e,s){e||b("Usage: config-get <key.path>");let r=et.default.join(ee(t),"config.json"),n={};try{me.default.existsSync(r)?n=JSON.parse(me.default.readFileSync(r,"utf-8")):b("No config.json found at "+r)}catch(a){if(a.message.startsWith("Error:"))throw a;b("Failed to read config.json: "+a.message)}let i=e.split("."),o=n;for(let a of i)(o==null||typeof o!="object")&&b(`Key not found: ${e}`),o=o[a];o===void 0&&b(`Key not found: ${e}`),y(o,s,String(o))}function Oo(t,e,s){e||b(`Usage: config-set-model-profile <${vt.join("|")}>`);let r=e.toLowerCase().trim();vt.includes(r)||b(`Invalid profile '${e}'. Valid profiles: ${vt.join(", ")}`),Js(t);let i=Ys(t,"model_profile",r)?.previousValue||"balanced",o=Es(r),a=Fs(o),l=i!==r?`\u2713 Model profile set to: ${r} (was: ${i})
|
|
184
184
|
|
|
185
185
|
Agents will now use:
|
|
186
186
|
|
|
@@ -189,7 +189,7 @@ Next spawned agents will use the new profile.`:`\u2713 Model profile is already
|
|
|
189
189
|
|
|
190
190
|
Agents are using:
|
|
191
191
|
|
|
192
|
-
${a}`;y({updated:!0,profile:r,previousProfile:i,agentToModelMap:o},s,l)}var me,Rr,et,Er,Ro,jt=L(()=>{"use strict";me=U(require("fs")),Rr=U(require("os")),et=U(require("path"));ye();Ot();Er=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"]),Ro={"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
|
|
192
|
+
${a}`;y({updated:!0,profile:r,previousProfile:i,agentToModelMap:o},s,l)}var me,Rr,et,Er,Ro,jt=L(()=>{"use strict";me=U(require("fs")),Rr=U(require("os")),et=U(require("path"));ye();Ot();Er=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"]),Ro={"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 rt,An,jn,Rn,En,Fn,Mr=L(()=>{"use strict";rt=require("@oclif/core");je();An=class t extends w{static description="Get a config value";static args={key:rt.Args.string({required:!0})};static flags={...w.baseFlags};async run(){let{flags:e,args:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e),{cmdConfigGet:i}=await Promise.resolve().then(()=>(jt(),At));i(r,s.key,n)}},jn=class t extends w{static description="Set a config value";static args={key:rt.Args.string({required:!1}),value:rt.Args.string({required:!1})};static flags={...w.baseFlags};async run(){let{flags:e,args:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e),{cmdConfigSet:i}=await Promise.resolve().then(()=>(jt(),At));i(r,s.key,s.value,n)}},Rn=class t extends w{static description="Set the active model profile";static args={profile:rt.Args.string({required:!0})};static flags={...w.baseFlags};async run(){let{flags:e,args:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e),{cmdConfigSetModelProfile:i}=await Promise.resolve().then(()=>(jt(),At));i(r,s.profile,n)}},En=class t extends w{static description="Initialise a new project config";static args={choices:rt.Args.string({required:!1,description:"Choices JSON (positional)"})};static flags={...w.baseFlags,choices:rt.Flags.string({description:"Choices JSON"})};async run(){let{flags:e,args:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e),{cmdConfigNewProject:i}=await Promise.resolve().then(()=>(jt(),At));i(r,e.choices??s.choices,n)}},Fn=class t extends w{static description="Ensure a config section exists";static flags={...w.baseFlags};async run(){let{flags:e}=await this.parse(t),{cwd:s,raw:r}=this.resolveContext(e),{cmdConfigEnsureSection:n}=await Promise.resolve().then(()=>(jt(),At));n(s,r)}}});var Ge={};xe(Ge,{cmdFindPhase:()=>qo,cmdPhaseAdd:()=>Uo,cmdPhaseAddBatch:()=>Vo,cmdPhaseComplete:()=>Ho,cmdPhaseInsert:()=>zo,cmdPhaseNextDecimal:()=>Wo,cmdPhasePlanIndex:()=>Lo,cmdPhaseRemove:()=>Yo,cmdPhasesList:()=>No});function No(t,e,s){let r=q.default.join(W(t),"phases"),{type:n,phase:i,includeArchived:o}=e;if(!I.default.existsSync(r)){y(n?{files:[],count:0}:{directories:[],count:0},s,"");return}try{let a=I.default.readdirSync(r,{withFileTypes:!0}).filter(c=>c.isDirectory()).map(c=>c.name);if(o){let c=Ut(t);for(let l of c)a.push(`${l.name} [${l.milestone}]`)}if(a.sort((c,l)=>Se(c,l)),i){let c=pe(i),l=a.find(d=>d.startsWith(c));if(!l){y({files:[],count:0,phase_dir:null,error:"Phase not found"},s,"");return}a=[l]}if(n){let c=[];for(let l of a){let d=q.default.join(r,l),u=I.default.readdirSync(d),m;n==="plans"?m=u.filter(p=>p.endsWith("-PLAN.md")||p==="PLAN.md"):n==="summaries"?m=u.filter(p=>p.endsWith("-SUMMARY.md")||p==="SUMMARY.md"):m=u,c.push(...m.sort())}y({files:c,count:c.length,phase_dir:i?a[0]?.replace(/^\d+(?:\.\d+)*-?/,""):null},s,c.join(`
|
|
193
193
|
`));return}y({directories:a,count:a.length},s,a.join(`
|
|
194
194
|
`))}catch(a){b("Failed to list phases: "+a.message)}}function Wo(t,e,s){let r=q.default.join(W(t),"phases"),n=pe(e??"");if(!I.default.existsSync(r)){y({found:!1,base_phase:n,next:`${n}.1`,existing:[]},s,`${n}.1`);return}try{let i=I.default.readdirSync(r,{withFileTypes:!0}).filter(d=>d.isDirectory()).map(d=>d.name),o=i.some(d=>d.startsWith(n+"-")||d===n),a=new RegExp(`^${n}\\.(\\d+)`),c=i.map(d=>{let u=d.match(a);return u?`${n}.${u[1]}`:null}).filter(Boolean);c.sort((d,u)=>Se(d,u));let l=c.length===0?`${n}.1`:`${n}.${parseInt(c[c.length-1].split(".")[1],10)+1}`;y({found:o,base_phase:n,next:l,existing:c},s,l)}catch(i){b("Failed to calculate next decimal phase: "+i.message)}}function qo(t,e,s){e||b("phase identifier required");let r=q.default.join(W(t),"phases"),n=pe(e),i={found:!1,directory:null,phase_number:null,phase_name:null,plans:[],summaries:[]};try{let a=I.default.readdirSync(r,{withFileTypes:!0}).filter(g=>g.isDirectory()).map(g=>g.name).sort((g,h)=>Se(g,h)).find(g=>g.startsWith(n));if(!a){y(i,s,"");return}let c=a.match(/^(\d+[A-Z]?(?:\.\d+)*)-?(.*)/i),l=c?c[1]:n,d=c&&c[2]?c[2]:null,u=q.default.join(r,a),m=I.default.readdirSync(u),p=m.filter(g=>g.endsWith("-PLAN.md")||g==="PLAN.md").sort(),f=m.filter(g=>g.endsWith("-SUMMARY.md")||g==="SUMMARY.md").sort();y({found:!0,directory:J(q.default.join(q.default.relative(t,W(t)),"phases",a)),phase_number:l,phase_name:d,plans:p,summaries:f},s,J(q.default.join(q.default.relative(t,W(t)),"phases",a)))}catch{y(i,s,"")}}function Lo(t,e,s){e||b("phase required for phase-plan-index");let r=q.default.join(W(t),"phases"),n=pe(e),i=null;try{let g=I.default.readdirSync(r,{withFileTypes:!0}).filter(h=>h.isDirectory()).map(h=>h.name).sort((h,x)=>Se(h,x)).find(h=>h.startsWith(n));g&&(i=q.default.join(r,g))}catch{}if(!i){y({phase:n,error:"Phase not found",plans:[],waves:{},incomplete:[],has_checkpoints:!1},s);return}let o=I.default.readdirSync(i),a=o.filter(f=>f.endsWith("-PLAN.md")||f==="PLAN.md").sort(),c=o.filter(f=>f.endsWith("-SUMMARY.md")||f==="SUMMARY.md"),l=new Set(c.map(f=>f.replace("-SUMMARY.md","").replace("SUMMARY.md",""))),d=[],u={},m=[],p=!1;for(let f of a){let g=f.replace("-PLAN.md","").replace("PLAN.md",""),h=I.default.readFileSync(q.default.join(i,f),"utf-8"),x=le(h),S=h.match(/<task[\s>]/gi)||[],v=h.match(/##\s*Task\s*\d+/gi)||[],C=S.length||v.length,P=parseInt(String(x.wave),10)||1,$=!0;x.autonomous!==void 0&&($=x.autonomous==="true"||x.autonomous===!0),$||(p=!0);let T=[],k=x.files_modified??x["files-modified"];if(k){let E=Pe(k);T=E?E.map(V=>fe(V)??String(V)):[fe(k)??String(k)]}let j=l.has(g);j||m.push(g),d.push({id:g,wave:P,autonomous:$,objective:h.match(/<objective>\s*\n?\s*(.+)/)?.[1]?.trim()??fe(x.objective)??null,files_modified:T,task_count:C,has_summary:j});let R=String(P);u[R]||(u[R]=[]),u[R].push(g)}y({phase:n,plans:d,waves:u,incomplete:m,has_checkpoints:p},s)}function Ir(t,e,s){let r=Q(t),n=q.default.join(W(t),"ROADMAP.md");I.default.existsSync(n)||b("ROADMAP.md not found");let i=I.default.readFileSync(n,"utf-8"),o=we(i,t),a=Le(e),c,l;if(s||r.phase_naming==="custom")c=s||a.toUpperCase().replace(/-/g,"-"),c||b('--id required when phase_naming is "custom"'),l=`${c}-${a}`;else{let g=/#{2,4}\s*Phase\s+(\d+)[A-Z]?(?:\.\d+)*:/gi,h=0,x;for(;(x=g.exec(o))!==null;){let v=parseInt(x[1],10);v>h&&(h=v)}c=h+1,l=`${String(c).padStart(2,"0")}-${a}`}let d=q.default.join(W(t),"phases",l);I.default.mkdirSync(d,{recursive:!0}),I.default.writeFileSync(q.default.join(d,".gitkeep"),"");let u=r.phase_naming==="custom"?"":`
|
|
195
195
|
**Depends on:** Phase ${typeof c=="number"?c-1:"TBD"}`,m=`
|
|
@@ -212,7 +212,7 @@ Plans:
|
|
|
212
212
|
|
|
213
213
|
Plans:
|
|
214
214
|
- [ ] TBD (run /gsd-plan-phase ${h} to break down)
|
|
215
|
-
`,C=new RegExp(`(#{2,4}\\s*Phase\\s+0*${d}:[^\\n]*\\n)`,"i"),P=i.match(C);P||b(`Could not find Phase ${e} header`);let $=i.indexOf(P[0]),k=i.slice($+P[0].length).match(/\n#{2,4}\s+Phase\s+\d/i),j=k?$+P[0].length+k.index:i.length;I.default.writeFileSync(n,i.slice(0,j)+v+i.slice(j),"utf-8"),y({phase_number:h,after_phase:e,name:s,slug:a,directory:J(q.default.join(q.default.relative(t,W(t)),"phases",x))},r,h)}function Bo(t,e,s){let r=[],n=[],i=new RegExp(`^${e}\\.(\\d+)-(.+)$`),o=Ue(t,!0).map(a=>{let c=a.match(i);return c?{dir:a,oldDecimal:parseInt(c[1],10),slug:c[2]}:null}).filter(a=>a!==null&&a.oldDecimal>s).sort((a,c)=>c.oldDecimal-a.oldDecimal);for(let a of o){let c=a.oldDecimal-1,l=`${e}.${a.oldDecimal}`,d=`${e}.${c}`,u=`${e}.${c}-${a.slug}`;I.default.renameSync(q.default.join(t,a.dir),q.default.join(t,u)),r.push({from:a.dir,to:u});for(let m of I.default.readdirSync(q.default.join(t,u)))if(m.includes(l)){let p=m.replace(l,d);I.default.renameSync(q.default.join(t,u,m),q.default.join(t,u,p)),n.push({from:m,to:p})}}return{renamedDirs:r,renamedFiles:n}}function Go(t,e){let s=[],r=[],n=Ue(t,!0).map(i=>{let o=i.match(/^(\d+)([A-Z])?(?:\.(\d+))?-(.+)$/i);if(!o)return null;let a=parseInt(o[1],10);return a>e?{dir:i,oldInt:a,letter:o[2]?o[2].toUpperCase():"",decimal:o[3]?parseInt(o[3],10):null,slug:o[4]}:null}).filter(i=>i!==null).sort((i,o)=>i.oldInt!==o.oldInt?o.oldInt-i.oldInt:(o.decimal||0)-(i.decimal||0));for(let i of n){let o=i.oldInt-1,a=String(o).padStart(2,"0"),c=String(i.oldInt).padStart(2,"0"),l=i.letter||"",d=i.decimal!==null?`.${i.decimal}`:"",u=`${c}${l}${d}`,m=`${a}${l}${d}`,p=`${m}-${i.slug}`;I.default.renameSync(q.default.join(t,i.dir),q.default.join(t,p)),s.push({from:i.dir,to:p});for(let f of I.default.readdirSync(q.default.join(t,p)))if(f.startsWith(u)){let g=m+f.slice(u.length);I.default.renameSync(q.default.join(t,p,f),q.default.join(t,p,g)),r.push({from:f,to:g})}}return{renamedDirs:s,renamedFiles:r}}function Jo(t,e,s,r){let n=I.default.readFileSync(t,"utf-8"),i=ie(e);if(n=n.replace(new RegExp(`\\n?#{2,4}\\s*Phase\\s+${i}\\s*:[\\s\\S]*?(?=\\n#{2,4}\\s+Phase\\s+\\d|$)`,"i"),""),n=n.replace(new RegExp(`\\n?-\\s*\\[[ x]\\]\\s*.*Phase\\s+${i}[:\\s][^\\n]*`,"gi"),""),n=n.replace(new RegExp(`\\n?\\|\\s*${i}\\.?\\s[^|]*\\|[^\\n]*`,"gi"),""),!s)for(let o=99;o>r;o--){let a=o-1,c=String(o),l=String(a),d=c.padStart(2,"0"),u=l.padStart(2,"0");n=n.replace(new RegExp(`(#{2,4}\\s*Phase\\s+)${c}(\\s*:)`,"gi"),`$1${l}$2`),n=n.replace(new RegExp(`(Phase\\s+)${c}([:\\s])`,"g"),`$1${l}$2`),n=n.replace(new RegExp(`${d}-(\\d{2})`,"g"),`${u}-$1`),n=n.replace(new RegExp(`(\\|\\s*)${c}\\.\\s`,"g"),`$1${l}. `),n=n.replace(new RegExp(`(Depends on:\\*\\*\\s*Phase\\s+)${c}\\b`,"gi"),`$1${l}`)}I.default.writeFileSync(t,n,"utf-8")}function Yo(t,e,s,r){e||b("phase number required for phase remove");let n=q.default.join(W(t),"ROADMAP.md"),i=q.default.join(W(t),"phases");I.default.existsSync(n)||b("ROADMAP.md not found");let o=pe(e),a=e.includes("."),c=s.force||!1,l=Ue(i,!0).find(p=>p.startsWith(o+"-")||p===o)||null;if(l&&!c){let p=I.default.readdirSync(q.default.join(i,l)).filter(f=>f.endsWith("-SUMMARY.md")||f==="SUMMARY.md");p.length>0&&b(`Phase ${e} has ${p.length} executed plan(s). Use --force to remove anyway.`)}l&&I.default.rmSync(q.default.join(i,l),{recursive:!0,force:!0});let d=[],u=[];try{let p=a?Bo(i,o.split(".")[0],parseInt(o.split(".")[1],10)):Go(i,parseInt(o,10));d=p.renamedDirs,u=p.renamedFiles}catch{}Jo(n,e,a,parseInt(o,10));let m=q.default.join(W(t),"STATE.md");if(I.default.existsSync(m)){let p=I.default.readFileSync(m,"utf-8"),f=z(p,"Total Phases");f&&(p=be(p,"Total Phases",String(parseInt(f,10)-1))??p);let g=p.match(/(\bof\s+)(\d+)(\s*(?:\(|phases?))/i);g&&(p=p.replace(/(\bof\s+)(\d+)(\s*(?:\(|phases?))/i,`$1${parseInt(g[2],10)-1}$3`)),ne(m,p,t)}y({removed:e,directory_deleted:l,renamed_directories:d,renamed_files:u,roadmap_updated:!0,state_updated:I.default.existsSync(m)},r)}function Ho(t,e,s){e||b("phase number required for phase complete");let r=q.default.join(W(t),"ROADMAP.md"),n=q.default.join(W(t),"STATE.md"),i=q.default.join(W(t),"phases"),o=pe(e),a=new Date().toISOString().split("T")[0],c=he(t,e);c||b(`Phase ${e} not found`);let l=c.plans.length,d=c.summaries.length,u=!1,m=[];try{let h=q.default.join(t,c.directory),x=I.default.readdirSync(h);for(let S of x.filter(v=>v.includes("-UAT")&&v.endsWith(".md"))){let v=I.default.readFileSync(q.default.join(h,S),"utf-8");/result: pending/.test(v)&&m.push(`${S}: has pending tests`),/result: blocked/.test(v)&&m.push(`${S}: has blocked tests`),/status: partial/.test(v)&&m.push(`${S}: testing incomplete (partial)`),/status: diagnosed/.test(v)&&m.push(`${S}: has diagnosed gaps`)}for(let S of x.filter(v=>v.includes("-VERIFICATION")&&v.endsWith(".md"))){let v=I.default.readFileSync(q.default.join(h,S),"utf-8");/status: human_needed/.test(v)&&m.push(`${S}: needs human verification`),/status: gaps_found/.test(v)&&m.push(`${S}: has unresolved gaps`)}}catch{}if(I.default.existsSync(r)){let h=I.default.readFileSync(r,"utf-8"),x=new RegExp(`(-\\s*\\[)[ ](\\]\\s*.*Phase\\s+${ie(e)}[:\\s][^\\n]*)`,"i");h=lt(h,x,`$1x$2 (completed ${a})`);let S=ie(e);h=h.replace(new RegExp(`^(\\|\\s*${S}\\.?\\s[^|]*(?:\\|[^\\n]*))$`,"im"),C=>{let P=C.split("|").slice(1,-1);return P.length===5?(P[3]=" Complete ",P[4]=` ${a} `):P.length===4&&(P[2]=" Complete ",P[3]=` ${a} `),"|"+P.join("|")+"|"}),h=lt(h,new RegExp(`(#{2,4}\\s*Phase\\s+${S}[\\s\\S]*?\\*\\*Plans:\\*\\*\\s*)[^\\n]+`,"i"),`$1${d}/${l} plans complete`),I.default.writeFileSync(r,h,"utf-8");let v=q.default.join(W(t),"REQUIREMENTS.md");if(I.default.existsSync(v)){let P=we(h,t).match(new RegExp(`(#{2,4}\\s*Phase\\s+${ie(e)}[:\\s][\\s\\S]*?)(?=#{2,4}\\s*Phase\\s+|$)`,"i")),T=(P?P[1]:"").match(/\*\*Requirements:\*\*\s*([^\n]+)/i);if(T){let k=T[1].replace(/[[\]]/g,"").split(/[,\s]+/).map(R=>R.trim()).filter(Boolean),j=I.default.readFileSync(v,"utf-8");for(let R of k){let E=ie(R);j=j.replace(new RegExp(`(-\\s*\\[)[ ](\\]\\s*\\*\\*${E}\\*\\*)`,"gi"),"$1x$2"),j=j.replace(new RegExp(`(\\|\\s*${E}\\s*\\|[^|]+\\|)\\s*(?:Pending|In Progress)\\s*(\\|)`,"gi"),"$1 Complete $2")}I.default.writeFileSync(v,j,"utf-8"),u=!0}}}let p=null,f=null,g=!0;try{let h=ke(t),x=I.default.readdirSync(i,{withFileTypes:!0}).filter(S=>S.isDirectory()).map(S=>S.name).filter(h).sort((S,v)=>Se(S,v));for(let S of x){let v=S.match(/^(\d+[A-Z]?(?:\.\d+)*)-?(.*)/i);if(v&&Se(v[1],e)>0){p=v[1],f=v[2]||null,g=!1;break}}}catch{}if(g&&I.default.existsSync(r))try{let h=we(I.default.readFileSync(r,"utf-8"),t),x=/#{2,4}\s*Phase\s+(\d+[A-Z]?(?:\.\d+)*)\s*:\s*([^\n]+)/gi,S;for(;(S=x.exec(h))!==null;)if(Se(S[1],e)>0){p=S[1],f=S[2].replace(/\(INSERTED\)/i,"").trim().toLowerCase().replace(/\s+/g,"-"),g=!1;break}}catch{}if(I.default.existsSync(n)){let h=I.default.readFileSync(n,"utf-8"),x=p||e,S=z(h,"Current Phase")||z(h,"Phase"),v=String(x);if(S){let P=S.match(/of\s+(\d+)/),$=S.match(/\(([^)]+)\)/);if(P){let T=f?` (${f.replace(/-/g," ")})`:$?` (${$[1]})`:"";v=`${x} of ${P[1]}${T}`}}h=ue(h,"Current Phase","Phase",v),f&&(h=ue(h,"Current Phase Name",null,f.replace(/-/g," "))),h=ue(h,"Status",null,g?"Milestone complete":"Ready to plan"),h=ue(h,"Current Plan","Plan","Not started"),h=ue(h,"Last Activity","Last activity",a),h=ue(h,"Last Activity Description",null,`Phase ${e} complete${p?`, transitioned to Phase ${p}`:""}`);let C=z(h,"Completed Phases");if(C){let P=parseInt(C,10)+1;h=be(h,"Completed Phases",String(P))??h;let $=z(h,"Total Phases");if($){let T=parseInt($,10);if(T>0){let k=Math.round(P/T*100);h=be(h,"Progress",`${k}%`)??h,h=h.replace(/(percent:\s*)\d+/,`$1${k}`)}}}ne(n,h,t)}y({completed_phase:e,phase_name:c.phase_name,plans_executed:`${d}/${l}`,next_phase:p,next_phase_name:f,is_last_phase:g,date:a,roadmap_updated:I.default.existsSync(r),state_updated:I.default.existsSync(n),requirements_updated:u,warnings:m,has_warnings:m.length>0},s)}var I,q,Je=L(()=>{"use strict";I=U(require("fs")),q=U(require("path"));ye();Ve();$e()});var Ye,Mn,In,Tn,Dn,On,Nn,Wn,Tr=L(()=>{"use strict";Ye=require("@oclif/core");je();Mn=class t extends w{static description="Get next decimal phase number";static args={phase:Ye.Args.string({required:!0})};static flags={...w.baseFlags};async run(){let{flags:e,args:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e);(await Promise.resolve().then(()=>(Je(),Ge))).cmdPhaseNextDecimal(r,s.phase,n)}},In=class t extends w{static description="Add a new phase";static flags={...w.baseFlags,id:Ye.Flags.string({description:"Custom phase ID"})};static strict=!1;async run(){let{flags:e,argv:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e),i=await Promise.resolve().then(()=>(Je(),Ge)),o=s.join(" ");i.cmdPhaseAdd(r,o,n,e.id??null)}},Tn=class t extends w{static description="Add one or more phases from a description string. Multiple phases may be separated by ' + '.";static strict=!1;static flags={...w.baseFlags};async run(){let{flags:e,argv:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e),i=await Promise.resolve().then(()=>(Je(),Ge)),o=s.join(" ");i.cmdPhaseAddBatch(r,o,n)}},Dn=class t extends w{static description="Insert a phase at position";static args={position:Ye.Args.string({required:!0}),description:Ye.Args.string({required:!1})};static flags={...w.baseFlags};static strict=!1;async run(){let{flags:e,argv:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e),i=s;(await Promise.resolve().then(()=>(Je(),Ge))).cmdPhaseInsert(r,i[0],i.slice(1).join(" "),n)}},On=class t extends w{static description="Remove a phase";static args={phase:Ye.Args.string({required:!0})};static flags={...w.baseFlags,force:Ye.Flags.boolean({description:"Force removal",default:!1})};async run(){let{flags:e,args:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e);(await Promise.resolve().then(()=>(Je(),Ge))).cmdPhaseRemove(r,s.phase,{force:e.force},n)}},Nn=class t extends w{static description="Mark a phase as complete";static args={phase:Ye.Args.string({required:!0})};static flags={...w.baseFlags};async run(){let{flags:e,args:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e);(await Promise.resolve().then(()=>(Je(),Ge))).cmdPhaseComplete(r,s.phase,n)}},Wn=class t extends w{static description="Get phase plan index";static args={phase:Ye.Args.string({required:!0})};static flags={...w.baseFlags};async run(){let{flags:e,args:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e),{cmdPhasePlanIndex:i}=await Promise.resolve().then(()=>(Je(),Ge));i(r,s.phase,n)}}});var qn={};xe(qn,{cmdMilestoneComplete:()=>Zo,cmdRequirementsMarkComplete:()=>Xo});function Xo(t,e,s){(!e||e.length===0)&&b("requirement IDs required.");let r=e.join(" ").replace(/[[\]]/g,"").split(/[,\s]+/).map(l=>l.trim()).filter(Boolean);r.length===0&&b("no valid requirement IDs found");let n=F(t).requirements;if(!Y.default.existsSync(n)){y({updated:!1,reason:"REQUIREMENTS.md not found",ids:r},s,"no requirements file");return}let i=Y.default.readFileSync(n,"utf-8"),o=[],a=[],c=[];for(let l of r){let d=!1,u=ie(l);new RegExp(`(-\\s*\\[)[ ](\\]\\s*\\*\\*${u}\\*\\*)`,"gi").test(i)&&(i=i.replace(new RegExp(`(-\\s*\\[)[ ](\\]\\s*\\*\\*${u}\\*\\*)`,"gi"),"$1x$2"),d=!0),new RegExp(`(\\|\\s*${u}\\s*\\|[^|]+\\|)\\s*Pending\\s*(\\|)`,"gi").test(i)&&(i=i.replace(new RegExp(`(\\|\\s*${u}\\s*\\|[^|]+\\|)\\s*Pending\\s*(\\|)`,"gi"),"$1 Complete $2"),d=!0),d?o.push(l):new RegExp(`-\\s*\\[x\\]\\s*\\*\\*${u}\\*\\*`,"gi").test(i)||new RegExp(`\\|\\s*${u}\\s*\\|[^|]+\\|\\s*Complete\\s*\\|`,"gi").test(i)?a.push(l):c.push(l)}o.length>0&&Y.default.writeFileSync(n,i,"utf-8"),y({updated:o.length>0,marked_complete:o,already_complete:a,not_found:c,total:r.length},s,`${o.length}/${r.length} requirements marked complete`)}function Zo(t,e,s,r){e||b("version required for milestone complete (e.g., v1.0)");let n=F(t).roadmap,i=F(t).requirements,o=F(t).state,a=Ce.default.join(t,".planning","MILESTONES.md"),c=Ce.default.join(t,".planning","milestones"),l=F(t).phases,d=new Date().toISOString().split("T")[0],u=s.name||e;Y.default.mkdirSync(c,{recursive:!0});let m=ke(t),p=0,f=0,g=0,h=[];try{let P=Y.default.readdirSync(l,{withFileTypes:!0}).filter($=>$.isDirectory()).map($=>$.name).sort();for(let $ of P){if(!m($))continue;p++;let T=Y.default.readdirSync(Ce.default.join(l,$)),k=T.filter(R=>R.endsWith("-PLAN.md")||R==="PLAN.md"),j=T.filter(R=>R.endsWith("-SUMMARY.md")||R==="SUMMARY.md");f+=k.length;for(let R of j)try{let E=Y.default.readFileSync(Ce.default.join(l,$,R),"utf-8"),V=le(E),H=fe(V["one-liner"])??Vt(E);H&&h.push(H);let ae=E.match(/\*\*Tasks:\*\*\s*(\d+)/);if(ae)g+=parseInt(ae[1],10);else{let X=E.match(/<task[\s>]/gi)||[],Z=E.match(/##\s*Task\s*\d+/gi)||[];g+=X.length||Z.length}}catch{}}}catch{}Y.default.existsSync(n)&&Y.default.writeFileSync(Ce.default.join(c,`${e}-ROADMAP.md`),Y.default.readFileSync(n,"utf-8"),"utf-8"),Y.default.existsSync(i)&&Y.default.writeFileSync(Ce.default.join(c,`${e}-REQUIREMENTS.md`),`# Requirements Archive: ${e} ${u}
|
|
215
|
+
`,C=new RegExp(`(#{2,4}\\s*Phase\\s+0*${d}:[^\\n]*\\n)`,"i"),P=i.match(C);P||b(`Could not find Phase ${e} header`);let $=i.indexOf(P[0]),k=i.slice($+P[0].length).match(/\n#{2,4}\s+Phase\s+\d/i),j=k?$+P[0].length+k.index:i.length;I.default.writeFileSync(n,i.slice(0,j)+v+i.slice(j),"utf-8"),y({phase_number:h,after_phase:e,name:s,slug:a,directory:J(q.default.join(q.default.relative(t,W(t)),"phases",x))},r,h)}function Bo(t,e,s){let r=[],n=[],i=new RegExp(`^${e}\\.(\\d+)-(.+)$`),o=Ue(t,!0).map(a=>{let c=a.match(i);return c?{dir:a,oldDecimal:parseInt(c[1],10),slug:c[2]}:null}).filter(a=>a!==null&&a.oldDecimal>s).sort((a,c)=>c.oldDecimal-a.oldDecimal);for(let a of o){let c=a.oldDecimal-1,l=`${e}.${a.oldDecimal}`,d=`${e}.${c}`,u=`${e}.${c}-${a.slug}`;I.default.renameSync(q.default.join(t,a.dir),q.default.join(t,u)),r.push({from:a.dir,to:u});for(let m of I.default.readdirSync(q.default.join(t,u)))if(m.includes(l)){let p=m.replace(l,d);I.default.renameSync(q.default.join(t,u,m),q.default.join(t,u,p)),n.push({from:m,to:p})}}return{renamedDirs:r,renamedFiles:n}}function Go(t,e){let s=[],r=[],n=Ue(t,!0).map(i=>{let o=i.match(/^(\d+)([A-Z])?(?:\.(\d+))?-(.+)$/i);if(!o)return null;let a=parseInt(o[1],10);return a>e?{dir:i,oldInt:a,letter:o[2]?o[2].toUpperCase():"",decimal:o[3]?parseInt(o[3],10):null,slug:o[4]}:null}).filter(i=>i!==null).sort((i,o)=>i.oldInt!==o.oldInt?o.oldInt-i.oldInt:(o.decimal||0)-(i.decimal||0));for(let i of n){let o=i.oldInt-1,a=String(o).padStart(2,"0"),c=String(i.oldInt).padStart(2,"0"),l=i.letter||"",d=i.decimal!==null?`.${i.decimal}`:"",u=`${c}${l}${d}`,m=`${a}${l}${d}`,p=`${m}-${i.slug}`;I.default.renameSync(q.default.join(t,i.dir),q.default.join(t,p)),s.push({from:i.dir,to:p});for(let f of I.default.readdirSync(q.default.join(t,p)))if(f.startsWith(u)){let g=m+f.slice(u.length);I.default.renameSync(q.default.join(t,p,f),q.default.join(t,p,g)),r.push({from:f,to:g})}}return{renamedDirs:s,renamedFiles:r}}function Jo(t,e,s,r){let n=I.default.readFileSync(t,"utf-8"),i=ie(e);if(n=n.replace(new RegExp(`\\n?#{2,4}\\s*Phase\\s+${i}\\s*:[\\s\\S]*?(?=\\n#{2,4}\\s+Phase\\s+\\d|$)`,"i"),""),n=n.replace(new RegExp(`\\n?-\\s*\\[[ x]\\]\\s*.*Phase\\s+${i}[:\\s][^\\n]*`,"gi"),""),n=n.replace(new RegExp(`\\n?\\|\\s*${i}\\.?\\s[^|]*\\|[^\\n]*`,"gi"),""),!s)for(let o=99;o>r;o--){let a=o-1,c=String(o),l=String(a),d=c.padStart(2,"0"),u=l.padStart(2,"0");n=n.replace(new RegExp(`(#{2,4}\\s*Phase\\s+)${c}(\\s*:)`,"gi"),`$1${l}$2`),n=n.replace(new RegExp(`(Phase\\s+)${c}([:\\s])`,"g"),`$1${l}$2`),n=n.replace(new RegExp(`${d}-(\\d{2})`,"g"),`${u}-$1`),n=n.replace(new RegExp(`(\\|\\s*)${c}\\.\\s`,"g"),`$1${l}. `),n=n.replace(new RegExp(`(Depends on:\\*\\*\\s*Phase\\s+)${c}\\b`,"gi"),`$1${l}`)}I.default.writeFileSync(t,n,"utf-8")}function Yo(t,e,s,r){e||b("phase number required for phase remove");let n=q.default.join(W(t),"ROADMAP.md"),i=q.default.join(W(t),"phases");I.default.existsSync(n)||b("ROADMAP.md not found");let o=pe(e),a=e.includes("."),c=s.force||!1,l=Ue(i,!0).find(p=>p.startsWith(o+"-")||p===o)||null;if(l&&!c){let p=I.default.readdirSync(q.default.join(i,l)).filter(f=>f.endsWith("-SUMMARY.md")||f==="SUMMARY.md");p.length>0&&b(`Phase ${e} has ${p.length} executed plan(s). Use --force to remove anyway.`)}l&&I.default.rmSync(q.default.join(i,l),{recursive:!0,force:!0});let d=[],u=[];try{let p=a?Bo(i,o.split(".")[0],parseInt(o.split(".")[1],10)):Go(i,parseInt(o,10));d=p.renamedDirs,u=p.renamedFiles}catch{}Jo(n,e,a,parseInt(o,10));let m=q.default.join(W(t),"STATE.md");if(I.default.existsSync(m)){let p=I.default.readFileSync(m,"utf-8"),f=z(p,"Total Phases");f&&(p=be(p,"Total Phases",String(parseInt(f,10)-1))??p);let g=p.match(/(\bof\s+)(\d+)(\s*(?:\(|phases?))/i);g&&(p=p.replace(/(\bof\s+)(\d+)(\s*(?:\(|phases?))/i,`$1${parseInt(g[2],10)-1}$3`)),ne(m,p,t)}y({removed:e,directory_deleted:l,renamed_directories:d,renamed_files:u,roadmap_updated:!0,state_updated:I.default.existsSync(m)},r)}function Ho(t,e,s){e||b("phase number required for phase complete");let r=q.default.join(W(t),"ROADMAP.md"),n=q.default.join(W(t),"STATE.md"),i=q.default.join(W(t),"phases"),o=pe(e),a=new Date().toISOString().split("T")[0],c=he(t,e);c||b(`Phase ${e} not found`);let l=c.plans.length,d=c.summaries.length,u=!1,m=[];try{let h=q.default.join(t,c.directory),x=I.default.readdirSync(h);for(let S of x.filter(v=>v.includes("-UAT")&&v.endsWith(".md"))){let v=I.default.readFileSync(q.default.join(h,S),"utf-8");/result: pending/.test(v)&&m.push(`${S}: has pending tests`),/result: blocked/.test(v)&&m.push(`${S}: has blocked tests`),/status: partial/.test(v)&&m.push(`${S}: testing incomplete (partial)`),/status: diagnosed/.test(v)&&m.push(`${S}: has diagnosed gaps`)}for(let S of x.filter(v=>v.includes("-VERIFICATION")&&v.endsWith(".md"))){let v=I.default.readFileSync(q.default.join(h,S),"utf-8");/status: human_needed/.test(v)&&m.push(`${S}: needs human verification`),/status: gaps_found/.test(v)&&m.push(`${S}: has unresolved gaps`)}}catch{}if(I.default.existsSync(r)){let h=I.default.readFileSync(r,"utf-8"),x=new RegExp(`(-\\s*\\[)[ ](\\]\\s*.*Phase\\s+${ie(e)}[:\\s][^\\n]*)`,"i");h=dt(h,x,`$1x$2 (completed ${a})`);let S=ie(e);h=h.replace(new RegExp(`^(\\|\\s*${S}\\.?\\s[^|]*(?:\\|[^\\n]*))$`,"im"),C=>{let P=C.split("|").slice(1,-1);return P.length===5?(P[3]=" Complete ",P[4]=` ${a} `):P.length===4&&(P[2]=" Complete ",P[3]=` ${a} `),"|"+P.join("|")+"|"}),h=dt(h,new RegExp(`(#{2,4}\\s*Phase\\s+${S}[\\s\\S]*?\\*\\*Plans:\\*\\*\\s*)[^\\n]+`,"i"),`$1${d}/${l} plans complete`),I.default.writeFileSync(r,h,"utf-8");let v=q.default.join(W(t),"REQUIREMENTS.md");if(I.default.existsSync(v)){let P=we(h,t).match(new RegExp(`(#{2,4}\\s*Phase\\s+${ie(e)}[:\\s][\\s\\S]*?)(?=#{2,4}\\s*Phase\\s+|$)`,"i")),T=(P?P[1]:"").match(/\*\*Requirements:\*\*\s*([^\n]+)/i);if(T){let k=T[1].replace(/[[\]]/g,"").split(/[,\s]+/).map(R=>R.trim()).filter(Boolean),j=I.default.readFileSync(v,"utf-8");for(let R of k){let E=ie(R);j=j.replace(new RegExp(`(-\\s*\\[)[ ](\\]\\s*\\*\\*${E}\\*\\*)`,"gi"),"$1x$2"),j=j.replace(new RegExp(`(\\|\\s*${E}\\s*\\|[^|]+\\|)\\s*(?:Pending|In Progress)\\s*(\\|)`,"gi"),"$1 Complete $2")}I.default.writeFileSync(v,j,"utf-8"),u=!0}}}let p=null,f=null,g=!0;try{let h=ke(t),x=I.default.readdirSync(i,{withFileTypes:!0}).filter(S=>S.isDirectory()).map(S=>S.name).filter(h).sort((S,v)=>Se(S,v));for(let S of x){let v=S.match(/^(\d+[A-Z]?(?:\.\d+)*)-?(.*)/i);if(v&&Se(v[1],e)>0){p=v[1],f=v[2]||null,g=!1;break}}}catch{}if(g&&I.default.existsSync(r))try{let h=we(I.default.readFileSync(r,"utf-8"),t),x=/#{2,4}\s*Phase\s+(\d+[A-Z]?(?:\.\d+)*)\s*:\s*([^\n]+)/gi,S;for(;(S=x.exec(h))!==null;)if(Se(S[1],e)>0){p=S[1],f=S[2].replace(/\(INSERTED\)/i,"").trim().toLowerCase().replace(/\s+/g,"-"),g=!1;break}}catch{}if(I.default.existsSync(n)){let h=I.default.readFileSync(n,"utf-8"),x=p||e,S=z(h,"Current Phase")||z(h,"Phase"),v=String(x);if(S){let P=S.match(/of\s+(\d+)/),$=S.match(/\(([^)]+)\)/);if(P){let T=f?` (${f.replace(/-/g," ")})`:$?` (${$[1]})`:"";v=`${x} of ${P[1]}${T}`}}h=ue(h,"Current Phase","Phase",v),f&&(h=ue(h,"Current Phase Name",null,f.replace(/-/g," "))),h=ue(h,"Status",null,g?"Milestone complete":"Ready to plan"),h=ue(h,"Current Plan","Plan","Not started"),h=ue(h,"Last Activity","Last activity",a),h=ue(h,"Last Activity Description",null,`Phase ${e} complete${p?`, transitioned to Phase ${p}`:""}`);let C=z(h,"Completed Phases");if(C){let P=parseInt(C,10)+1;h=be(h,"Completed Phases",String(P))??h;let $=z(h,"Total Phases");if($){let T=parseInt($,10);if(T>0){let k=Math.round(P/T*100);h=be(h,"Progress",`${k}%`)??h,h=h.replace(/(percent:\s*)\d+/,`$1${k}`)}}}ne(n,h,t)}y({completed_phase:e,phase_name:c.phase_name,plans_executed:`${d}/${l}`,next_phase:p,next_phase_name:f,is_last_phase:g,date:a,roadmap_updated:I.default.existsSync(r),state_updated:I.default.existsSync(n),requirements_updated:u,warnings:m,has_warnings:m.length>0},s)}var I,q,Je=L(()=>{"use strict";I=U(require("fs")),q=U(require("path"));ye();Ve();$e()});var Ye,Mn,In,Tn,Dn,On,Nn,Wn,Tr=L(()=>{"use strict";Ye=require("@oclif/core");je();Mn=class t extends w{static description="Get next decimal phase number";static args={phase:Ye.Args.string({required:!0})};static flags={...w.baseFlags};async run(){let{flags:e,args:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e);(await Promise.resolve().then(()=>(Je(),Ge))).cmdPhaseNextDecimal(r,s.phase,n)}},In=class t extends w{static description="Add a new phase";static flags={...w.baseFlags,id:Ye.Flags.string({description:"Custom phase ID"})};static strict=!1;async run(){let{flags:e,argv:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e),i=await Promise.resolve().then(()=>(Je(),Ge)),o=s.join(" ");i.cmdPhaseAdd(r,o,n,e.id??null)}},Tn=class t extends w{static description="Add one or more phases from a description string. Multiple phases may be separated by ' + '.";static strict=!1;static flags={...w.baseFlags};async run(){let{flags:e,argv:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e),i=await Promise.resolve().then(()=>(Je(),Ge)),o=s.join(" ");i.cmdPhaseAddBatch(r,o,n)}},Dn=class t extends w{static description="Insert a phase at position";static args={position:Ye.Args.string({required:!0}),description:Ye.Args.string({required:!1})};static flags={...w.baseFlags};static strict=!1;async run(){let{flags:e,argv:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e),i=s;(await Promise.resolve().then(()=>(Je(),Ge))).cmdPhaseInsert(r,i[0],i.slice(1).join(" "),n)}},On=class t extends w{static description="Remove a phase";static args={phase:Ye.Args.string({required:!0})};static flags={...w.baseFlags,force:Ye.Flags.boolean({description:"Force removal",default:!1})};async run(){let{flags:e,args:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e);(await Promise.resolve().then(()=>(Je(),Ge))).cmdPhaseRemove(r,s.phase,{force:e.force},n)}},Nn=class t extends w{static description="Mark a phase as complete";static args={phase:Ye.Args.string({required:!0})};static flags={...w.baseFlags};async run(){let{flags:e,args:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e);(await Promise.resolve().then(()=>(Je(),Ge))).cmdPhaseComplete(r,s.phase,n)}},Wn=class t extends w{static description="Get phase plan index";static args={phase:Ye.Args.string({required:!0})};static flags={...w.baseFlags};async run(){let{flags:e,args:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e),{cmdPhasePlanIndex:i}=await Promise.resolve().then(()=>(Je(),Ge));i(r,s.phase,n)}}});var qn={};xe(qn,{cmdMilestoneComplete:()=>Zo,cmdRequirementsMarkComplete:()=>Xo});function Xo(t,e,s){(!e||e.length===0)&&b("requirement IDs required.");let r=e.join(" ").replace(/[[\]]/g,"").split(/[,\s]+/).map(l=>l.trim()).filter(Boolean);r.length===0&&b("no valid requirement IDs found");let n=F(t).requirements;if(!Y.default.existsSync(n)){y({updated:!1,reason:"REQUIREMENTS.md not found",ids:r},s,"no requirements file");return}let i=Y.default.readFileSync(n,"utf-8"),o=[],a=[],c=[];for(let l of r){let d=!1,u=ie(l);new RegExp(`(-\\s*\\[)[ ](\\]\\s*\\*\\*${u}\\*\\*)`,"gi").test(i)&&(i=i.replace(new RegExp(`(-\\s*\\[)[ ](\\]\\s*\\*\\*${u}\\*\\*)`,"gi"),"$1x$2"),d=!0),new RegExp(`(\\|\\s*${u}\\s*\\|[^|]+\\|)\\s*Pending\\s*(\\|)`,"gi").test(i)&&(i=i.replace(new RegExp(`(\\|\\s*${u}\\s*\\|[^|]+\\|)\\s*Pending\\s*(\\|)`,"gi"),"$1 Complete $2"),d=!0),d?o.push(l):new RegExp(`-\\s*\\[x\\]\\s*\\*\\*${u}\\*\\*`,"gi").test(i)||new RegExp(`\\|\\s*${u}\\s*\\|[^|]+\\|\\s*Complete\\s*\\|`,"gi").test(i)?a.push(l):c.push(l)}o.length>0&&Y.default.writeFileSync(n,i,"utf-8"),y({updated:o.length>0,marked_complete:o,already_complete:a,not_found:c,total:r.length},s,`${o.length}/${r.length} requirements marked complete`)}function Zo(t,e,s,r){e||b("version required for milestone complete (e.g., v1.0)");let n=F(t).roadmap,i=F(t).requirements,o=F(t).state,a=Ce.default.join(t,".planning","MILESTONES.md"),c=Ce.default.join(t,".planning","milestones"),l=F(t).phases,d=new Date().toISOString().split("T")[0],u=s.name||e;Y.default.mkdirSync(c,{recursive:!0});let m=ke(t),p=0,f=0,g=0,h=[];try{let P=Y.default.readdirSync(l,{withFileTypes:!0}).filter($=>$.isDirectory()).map($=>$.name).sort();for(let $ of P){if(!m($))continue;p++;let T=Y.default.readdirSync(Ce.default.join(l,$)),k=T.filter(R=>R.endsWith("-PLAN.md")||R==="PLAN.md"),j=T.filter(R=>R.endsWith("-SUMMARY.md")||R==="SUMMARY.md");f+=k.length;for(let R of j)try{let E=Y.default.readFileSync(Ce.default.join(l,$,R),"utf-8"),V=le(E),H=fe(V["one-liner"])??Vt(E);H&&h.push(H);let ae=E.match(/\*\*Tasks:\*\*\s*(\d+)/);if(ae)g+=parseInt(ae[1],10);else{let X=E.match(/<task[\s>]/gi)||[],Z=E.match(/##\s*Task\s*\d+/gi)||[];g+=X.length||Z.length}}catch{}}}catch{}Y.default.existsSync(n)&&Y.default.writeFileSync(Ce.default.join(c,`${e}-ROADMAP.md`),Y.default.readFileSync(n,"utf-8"),"utf-8"),Y.default.existsSync(i)&&Y.default.writeFileSync(Ce.default.join(c,`${e}-REQUIREMENTS.md`),`# Requirements Archive: ${e} ${u}
|
|
216
216
|
|
|
217
217
|
**Archived:** ${d}
|
|
218
218
|
**Status:** SHIPPED
|
|
@@ -249,13 +249,13 @@ See: .planning/PROJECT.md
|
|
|
249
249
|
## Session Log
|
|
250
250
|
|
|
251
251
|
- ${new Date().toISOString().split("T")[0]}: STATE.md regenerated by /gsd-health --repair
|
|
252
|
-
`,t),h.push({action:S,success:!0,path:"STATE.md"})}}catch(v){h.push({action:S,success:!1,error:v.message})}let x=u.length>0?"broken":m.length>0?"degraded":"healthy";y({status:x,errors:u,warnings:m,info:p,repairable_count:u.filter(S=>S.repairable).length+m.filter(S=>S.repairable).length,repairs_performed:h.length>0?h:void 0},s)}function ma(t,e){let s=_t();y({agents_dir:s.agents_dir,agents_found:s.agents_installed,installed:s.installed_agents,missing:s.missing_agents,expected:Object.keys(Me)},e)}var se,Wr,te,Et=L(()=>{"use strict";se=U(require("fs")),Wr=U(require("os")),te=U(require("path"));ye();Ve();Nr();$e()});var Hs={};xe(Hs,{buildCheckpoint:()=>Lr,cmdAuditUat:()=>pa,cmdRenderCheckpoint:()=>fa,parseCurrentTest:()=>qr});function pa(t,e){let s=He.default.join(W(t),"phases");
|
|
252
|
+
`,t),h.push({action:S,success:!0,path:"STATE.md"})}}catch(v){h.push({action:S,success:!1,error:v.message})}let x=u.length>0?"broken":m.length>0?"degraded":"healthy";y({status:x,errors:u,warnings:m,info:p,repairable_count:u.filter(S=>S.repairable).length+m.filter(S=>S.repairable).length,repairs_performed:h.length>0?h:void 0},s)}function ma(t,e){let s=_t();y({agents_dir:s.agents_dir,agents_found:s.agents_installed,installed:s.installed_agents,missing:s.missing_agents,expected:Object.keys(Me)},e)}var se,Wr,te,Et=L(()=>{"use strict";se=U(require("fs")),Wr=U(require("os")),te=U(require("path"));ye();Ve();Nr();$e()});var Hs={};xe(Hs,{buildCheckpoint:()=>Lr,cmdAuditUat:()=>pa,cmdRenderCheckpoint:()=>fa,parseCurrentTest:()=>qr});function pa(t,e){let s=He.default.join(W(t),"phases");it.default.existsSync(s)||b("No phases directory found in planning directory");let r=ke(t),n=[],i=it.default.readdirSync(s,{withFileTypes:!0}).filter(a=>a.isDirectory()).map(a=>a.name).filter(r).sort();for(let a of i){let c=a.match(/^(\d+[A-Z]?(?:\.\d+)*)/i),l=c?c[1]:a,d=He.default.join(s,a),u=it.default.readdirSync(d);for(let m of u.filter(p=>p.includes("-UAT")&&p.endsWith(".md"))){let p=it.default.readFileSync(He.default.join(d,m),"utf-8"),f=ga(p);f.length>0&&n.push({phase:l,phase_dir:a,file:m,file_path:J(He.default.relative(t,He.default.join(d,m))),type:"uat",status:le(p).status||"unknown",items:f})}for(let m of u.filter(p=>p.includes("-VERIFICATION")&&p.endsWith(".md"))){let p=it.default.readFileSync(He.default.join(d,m),"utf-8"),f=le(p).status||"unknown";if(f==="human_needed"||f==="gaps_found"){let g=ha(p,f);g.length>0&&n.push({phase:l,phase_dir:a,file:m,file_path:J(He.default.relative(t,He.default.join(d,m))),type:"verification",status:f,items:g})}}}let o={total_files:n.length,total_items:n.reduce((a,c)=>a+c.items.length,0),by_category:{},by_phase:{}};for(let a of n){o.by_phase[a.phase]||(o.by_phase[a.phase]=0);for(let c of a.items)o.by_phase[a.phase]++,o.by_category[c.category]=(o.by_category[c.category]||0)+1}y({results:n,summary:o},e)}function fa(t,e,s){let r=e.file;r||b("UAT file required: use uat render-checkpoint --file <path>");let n=wr(r,t,"UAT file",{allowAbsolute:!0});it.default.existsSync(n)||b(`UAT file not found: ${r}`);let i=it.default.readFileSync(n,"utf-8"),o=qr(i);o.complete&&b("UAT session is already complete; no pending checkpoint to render");let a=Lr(o);y({file_path:J(He.default.relative(t,n)),test_number:o.number,test_name:o.name,checkpoint:a},s,a)}function qr(t){let e=t.match(/##\s*Current Test\s*(?:\n<!--[\s\S]*?-->)?\n([\s\S]*?)(?=\n##\s|$)/i);e||b("UAT file is missing a Current Test section");let s=e[1].trimEnd();if(s.trim()||b("Current Test section is empty"),/\[testing complete\]/i.test(s))return{complete:!0};let r=s.match(/^number:\s*(\d+)\s*$/m),n=s.match(/^name:\s*(.+)\s*$/m),i=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);(!r||!n||!i&&!o)&&b("Current Test section is malformed");let a;return i?a=i[1].split(`
|
|
253
253
|
`).map(c=>c.replace(/^ {2}/,"")).join(`
|
|
254
254
|
`).trim():a=o[1].trim(),{complete:!1,number:parseInt(r[1],10),name:qs(n[1].trim()),expected:qs(a)}}function Lr(t){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 ${t.number}: ${t.name}**`,"",t.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(`
|
|
255
255
|
`)}function ga(t){let e=[],s=/###\s*(\d+)\.\s*([^\n]+)\nexpected:\s*([^\n]+)\nresult:\s*(\w+)(?:\n(?:reported|reason|blocked_by):\s*[^\n]*)?/g,r;for(;(r=s.exec(t))!==null;){let[,n,i,o,a]=r;if(a==="pending"||a==="skipped"||a==="blocked"){let c=t.slice(r.index),l=c.indexOf(`
|
|
256
256
|
###`,1),d=l>0?c.slice(0,l):c,u=d.match(/reason:\s*(.+)/),m=d.match(/blocked_by:\s*(.+)/),p={test:parseInt(n,10),name:i.trim(),expected:o.trim(),result:a,category:ya(a,u?.[1],m?.[1])};u&&(p.reason=u[1].trim()),m&&(p.blocked_by=m[1].trim()),e.push(p)}}return e}function ha(t,e){let s=[];if(e==="human_needed"){let r=t.match(/##\s*Human Verification.*?\n([\s\S]*?)(?=\n##\s|\n---\s|$)/i);if(r)for(let n of r[1].split(`
|
|
257
|
-
`)){let i=n.match(/\|\s*(\d+)\s*\|\s*([^|]+)/),o=n.match(/^[-*]\s+(.+)/),a=n.match(/^(\d+)\.\s+(.+)/);i?s.push({test:parseInt(i[1],10),name:i[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 ya(t,e,s){if(t==="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 t==="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":t==="pending"?"pending":t==="human_needed"?"human_uat":"unknown"}var
|
|
258
|
-
`),m=O.default.join(a,"STATE.md");D.default.existsSync(m)||D.default.writeFileSync(m,u,"utf-8"),ct(t,n);let p=J(O.default.relative(t,a));y({created:!0,workstream:n,path:p,state_path:p+"/STATE.md",phases_path:p+"/phases",migration:l??null,active:!0},r)}function ba(t,e){let s=O.default.join(ee(t),"workstreams");if(!D.default.existsSync(s)){y({mode:"flat",workstreams:[],message:"No workstreams - operating in flat mode"},e);return}let r=[];for(let n of D.default.readdirSync(s,{withFileTypes:!0}).filter(i=>i.isDirectory())){let i=O.default.join(s,n.name),o=O.default.join(i,"phases"),a=Ue(o),c=0;for(let u of a)try{let m=D.default.readdirSync(O.default.join(o,u)),p=wt(m),f=kt(m);p.length>0&&f.length>=p.length&&c++}catch{}let l="unknown",d=null;try{let u=D.default.readFileSync(O.default.join(i,"STATE.md"),"utf-8");l=z(u,"Status")||"unknown",d=z(u,"Current Phase")}catch{}r.push({name:n.name,path:J(O.default.relative(t,i)),has_roadmap:D.default.existsSync(O.default.join(i,"ROADMAP.md")),has_state:D.default.existsSync(O.default.join(i,"STATE.md")),status:l,current_phase:d,phase_count:a.length,completed_phases:c})}y({mode:"workstream",workstreams:r,count:r.length},e)}function va(t,e,s){e||b("workstream name required. Usage: workstream status <name>"),(/[/\\]/.test(e)||e==="."||e==="..")&&b("Invalid workstream name");let r=O.default.join(ee(t),"workstreams",e);if(!D.default.existsSync(r)){y({found:!1,workstream:e},s);return}let n=F(t,e),i={roadmap:D.default.existsSync(n.roadmap),state:D.default.existsSync(n.state),requirements:D.default.existsSync(n.requirements)},o=[];for(let c of Ue(n.phases).sort())try{let l=D.default.readdirSync(O.default.join(n.phases,c)),d=wt(l),u=kt(l);o.push({directory:c,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 c=D.default.readFileSync(n.state,"utf-8");a={status:z(c,"Status")||"unknown",current_phase:z(c,"Current Phase"),last_activity:z(c,"Last Activity")}}catch{}y({found:!0,workstream:e,path:J(O.default.relative(t,r)),files:i,phases:o,phase_count:o.length,completed_phases:o.filter(c=>c.status==="complete").length,...a},s)}function _a(t,e,s,r){e||b("workstream name required. Usage: workstream complete <name>"),(/[/\\]/.test(e)||e==="."||e==="..")&&b("Invalid workstream name");let n=ee(t),i=O.default.join(n,"workstreams"),o=O.default.join(i,e);if(!D.default.existsSync(o)){y({completed:!1,error:"not_found",workstream:e},r);return}let a=Ke(t);a===e&&ct(t,null);let c=O.default.join(n,"milestones"),l=new Date().toISOString().split("T")[0],d=O.default.join(c,`ws-${e}-${l}`),u=1;for(;D.default.existsSync(d);)d=O.default.join(c,`ws-${e}-${l}-${u++}`);D.default.mkdirSync(d,{recursive:!0});let m=[];try{for(let f of D.default.readdirSync(o,{withFileTypes:!0}))D.default.renameSync(O.default.join(o,f.name),O.default.join(d,f.name)),m.push(f.name)}catch(f){for(let g of m)try{D.default.renameSync(O.default.join(d,g),O.default.join(o,g))}catch{}try{D.default.rmSync(d,{recursive:!0})}catch{}a===e&&ct(t,e),y({completed:!1,error:"archive_failed",message:f.message,workstream:e},r);return}try{D.default.rmdirSync(o)}catch{}let p=0;try{p=D.default.readdirSync(i,{withFileTypes:!0}).filter(f=>f.isDirectory()).length,p===0&&D.default.rmdirSync(i)}catch{}y({completed:!0,workstream:e,archived_to:J(O.default.relative(t,d)),remaining_workstreams:p,reverted_to_flat:p===0},r)}function wa(t,e,s){if(!e){ct(t,null),y({active:null,cleared:!0},s);return}if(!/^[a-zA-Z0-9_-]+$/.test(e)){y({active:null,error:"invalid_name",message:"Workstream name must be alphanumeric, hyphens, and underscores only"},s);return}let r=O.default.join(ee(t),"workstreams",e);if(!D.default.existsSync(r)){y({active:null,error:"not_found",workstream:e},s);return}ct(t,e),y({active:e,set:!0},s,e)}function ka(t,e){let s=Ke(t),r=O.default.join(ee(t),"workstreams");y({active:s,mode:D.default.existsSync(r)?"workstream":"flat"},e,s||"none")}function Pa(t,e){let s=ee(t),r=O.default.join(s,"workstreams");if(!D.default.existsSync(r)){y({mode:"flat",workstreams:[],message:"No workstreams - operating in flat mode"},e);return}let n=Ke(t),i=[];for(let o of D.default.readdirSync(r,{withFileTypes:!0}).filter(a=>a.isDirectory())){let a=O.default.join(r,o.name),c=O.default.join(a,"phases"),l=Ue(c),d=0,u=0,m=0;for(let h of l)try{let x=D.default.readdirSync(O.default.join(c,h)),S=wt(x),v=kt(x);u+=S.length,m+=Math.min(v.length,S.length),S.length>0&&v.length>=S.length&&d++}catch{}let p=l.length;try{let x=D.default.readFileSync(O.default.join(a,"ROADMAP.md"),"utf-8").match(/^###?\s+Phase\s+\d/gm);x&&(p=x.length)}catch{}let f="unknown",g=null;try{let h=D.default.readFileSync(O.default.join(a,"STATE.md"),"utf-8");f=z(h,"Status")||"unknown",g=z(h,"Current Phase")}catch{}i.push({name:o.name,active:o.name===n,status:f,current_phase:g,phases:`${d}/${p}`,plans:`${m}/${u}`,progress_percent:p>0?Math.round(d/p*100):0})}y({mode:"workstream",active:n,workstreams:i,count:i.length},e)}var D,O,ot=L(()=>{"use strict";D=U(require("fs")),O=U(require("path"));ye();$e()});var at,Xn,Zn,Kn,Qn,es,ts,ns,Vr=L(()=>{"use strict";at=require("@oclif/core");je();Xn=class t extends w{static description="Create a new workstream";static args={name:at.Args.string({required:!0})};static flags={...w.baseFlags,"no-migrate":at.Flags.boolean({description:"Skip migration",default:!1}),"migrate-name":at.Flags.string({description:"Migration name"})};async run(){let{flags:e,args:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e);(await Promise.resolve().then(()=>(ot(),it))).cmdWorkstreamCreate(r,s.name,{migrate:!e["no-migrate"],migrateName:e["migrate-name"]??null},n)}},Zn=class t extends w{static description="List workstreams";static flags={...w.baseFlags};async run(){let{flags:e}=await this.parse(t),{cwd:s,raw:r}=this.resolveContext(e);(await Promise.resolve().then(()=>(ot(),it))).cmdWorkstreamList(s,r)}},Kn=class t extends w{static description="Show workstream status";static args={name:at.Args.string({required:!0})};static flags={...w.baseFlags};async run(){let{flags:e,args:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e);(await Promise.resolve().then(()=>(ot(),it))).cmdWorkstreamStatus(r,s.name,n)}},Qn=class t extends w{static description="Complete a workstream";static args={name:at.Args.string({required:!0})};static flags={...w.baseFlags};async run(){let{flags:e,args:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e);(await Promise.resolve().then(()=>(ot(),it))).cmdWorkstreamComplete(r,s.name,{},n)}},es=class t extends w{static description="Set active workstream";static args={name:at.Args.string({required:!0})};static flags={...w.baseFlags};async run(){let{flags:e,args:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e);(await Promise.resolve().then(()=>(ot(),it))).cmdWorkstreamSet(r,s.name,n)}},ts=class t extends w{static description="Get active workstream";static flags={...w.baseFlags};async run(){let{flags:e}=await this.parse(t),{cwd:s,raw:r}=this.resolveContext(e);(await Promise.resolve().then(()=>(ot(),it))).cmdWorkstreamGet(s,r)}},ns=class t extends w{static description="Show workstream progress";static flags={...w.baseFlags};async run(){let{flags:e}=await this.parse(t),{cwd:s,raw:r}=this.resolveContext(e);(await Promise.resolve().then(()=>(ot(),it))).cmdWorkstreamProgress(s,r)}}});var ve={};xe(ve,{cmdCommit:()=>Fa,cmdCommitToSubrepo:()=>Ma,cmdCurrentTimestamp:()=>Ca,cmdGenerateSlug:()=>$a,cmdHistoryDigest:()=>Ra,cmdListTodos:()=>Aa,cmdProgressRender:()=>Da,cmdResolveModel:()=>Ea,cmdScaffold:()=>Wa,cmdStats:()=>qa,cmdSummaryExtract:()=>Ia,cmdTodoComplete:()=>Oa,cmdTodoMatchPhase:()=>Na,cmdVerifyPathExists:()=>ja,cmdWebsearch:()=>Ta});function $a(t,e){t||b("text required for slug generation");let s=t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");y({slug:s},e,s)}function Ca(t,e){let s=new Date,r;t==="date"?r=s.toISOString().split("T")[0]:t==="filename"?r=s.toISOString().replace(/:/g,"-").replace(/\..+/,""):r=s.toISOString(),y({timestamp:r},e,r)}function Aa(t,e,s){let r=K.default.join(W(t),"todos","pending"),n=0,i=[];try{let o=B.default.readdirSync(r).filter(a=>a.endsWith(".md"));for(let a of o)try{let c=B.default.readFileSync(K.default.join(r,a),"utf-8"),l=c.match(/^created:\s*(.+)$/m),d=c.match(/^title:\s*(.+)$/m),u=c.match(/^area:\s*(.+)$/m),m=u?u[1].trim():"general";if(e&&m!==e)continue;n++,i.push({file:a,created:l?l[1].trim():"unknown",title:d?d[1].trim():"Untitled",area:m,path:J(K.default.relative(t,K.default.join(r,a)))})}catch{}}catch{}y({count:n,todos:i},s,n.toString())}function ja(t,e,s){e||b("path required for verification"),e.includes("\0")&&b("path contains null bytes");let r=K.default.isAbsolute(e)?e:K.default.join(t,e);try{let n=B.default.statSync(r);y({exists:!0,type:n.isDirectory()?"directory":n.isFile()?"file":"other"},s,"true")}catch{y({exists:!1,type:null},s,"false")}}function Ra(t,e){let s=F(t).phases,r={phases:{},decisions:[],tech_stack:new Set},n=[];for(let i of Ut(t))n.push({name:i.name,fullPath:i.fullPath,milestone:i.milestone});if(B.default.existsSync(s))try{for(let i of B.default.readdirSync(s,{withFileTypes:!0}).filter(o=>o.isDirectory()).map(o=>o.name).sort())n.push({name:i,fullPath:K.default.join(s,i),milestone:null})}catch{}if(n.length===0){y({phases:{},decisions:[],tech_stack:[]},e);return}try{for(let{name:o,fullPath:a}of n){let c=B.default.readdirSync(a).filter(l=>l.endsWith("-SUMMARY.md")||l==="SUMMARY.md");for(let l of c)try{let d=B.default.readFileSync(K.default.join(a,l),"utf-8"),u=le(d),m=fe(u.phase)??o.split("-")[0];r.phases[m]||(r.phases[m]={name:fe(u.name)??o.split("-").slice(1).join(" ")??"Unknown",provides:new Set,affects:new Set,patterns:new Set});let p=Pt(u["dependency-graph"]);p?.provides?Pe(p.provides)?.forEach(g=>r.phases[m].provides.add(fe(g)??String(g))):u.provides&&Pe(u.provides)?.forEach(g=>r.phases[m].provides.add(fe(g)??String(g))),p?.affects&&Pe(p.affects)?.forEach(g=>r.phases[m].affects.add(fe(g)??String(g))),u["patterns-established"]&&Pe(u["patterns-established"])?.forEach(g=>r.phases[m].patterns.add(fe(g)??String(g))),u["key-decisions"]&&Pe(u["key-decisions"])?.forEach(g=>r.decisions.push({phase:m,decision:fe(g)??String(g)}));let f=Pt(u["tech-stack"]);f?.added&&Pe(f.added)?.forEach(g=>{let h=fe(g);if(h)r.tech_stack.add(h);else{let x=Pt(g);x&&r.tech_stack.add(fe(x.name)??"")}})}catch{}}let i={phases:Object.fromEntries(Object.entries(r.phases).map(([o,a])=>[o,{name:a.name,provides:[...a.provides],affects:[...a.affects],patterns:[...a.patterns]}])),decisions:r.decisions,tech_stack:[...r.tech_stack]};y(i,e)}catch(i){b("Failed to generate history digest: "+i.message)}}function Ea(t,e,s){e||b("agent-type required");let r=Q(t),n=oe(t,e),i=Me[e];y(i?{model:n,profile:r.model_profile}:{model:n,profile:r.model_profile,unknown_agent:!0},s,n)}function Fa(t,e,s,r,n=!1,i=!1){!e&&!n&&b("commit message required");let o=e;o&&(o=_r(o));let a=Q(t);if(!a.commit_docs){y({committed:!1,hash:null,reason:"skipped_commit_docs_false"},r,"skipped");return}if(rn(t,".planning")){y({committed:!1,hash:null,reason:"skipped_gitignored"},r,"skipped");return}if(a.branching_strategy&&a.branching_strategy!=="none"){let p=null;if(a.branching_strategy==="phase"){let f=(s||[]).join(" ").match(/(\d+)-/);if(f){let g=he(t,f[1]);g&&(p=a.phase_branch_template.replace("{phase}",g.phase_number).replace("{slug}",g.phase_slug||"phase"))}}else if(a.branching_strategy==="milestone"){let f=ce(t);f?.version&&(p=a.milestone_branch_template.replace("{milestone}",f.version).replace("{slug}",Le(f.name)||"milestone"))}if(p){let f=de(t,["rev-parse","--abbrev-ref","HEAD"]);f.exitCode===0&&f.stdout.trim()!==p&&de(t,["checkout","-b",p]).exitCode!==0&&de(t,["checkout",p])}}let c=s&&s.length>0?s:[".planning/"];for(let p of c){let f=K.default.join(t,p);B.default.existsSync(f)?de(t,["add",p]):de(t,["rm","--cached","--ignore-unmatch",p])}let l=n?["commit","--amend","--no-edit"]:["commit","-m",o];i&&l.push("--no-verify");let d=de(t,l);if(d.exitCode!==0){if(d.stdout.includes("nothing to commit")||d.stderr.includes("nothing to commit")){y({committed:!1,hash:null,reason:"nothing_to_commit"},r,"nothing");return}y({committed:!1,hash:null,reason:"nothing_to_commit",error:d.stderr},r,"nothing");return}let u=de(t,["rev-parse","--short","HEAD"]),m=u.exitCode===0?u.stdout:null;y({committed:!0,hash:m,reason:"committed"},r,m||"committed")}function Ma(t,e,s,r){e||b("commit message required");let i=Q(t).sub_repos;(!i||i.length===0)&&b("no sub_repos configured in .planning/config.json"),(!s||s.length===0)&&b("--files required for commit-to-subrepo");let o={},a=[];for(let l of s){let d=i.find(u=>l.startsWith(u+"/"));d?(o[d]||(o[d]=[]),o[d].push(l)):a.push(l)}a.length>0&&process.stderr.write(`Warning: ${a.length} file(s) did not match any sub-repo prefix: ${a.join(", ")}
|
|
257
|
+
`)){let i=n.match(/\|\s*(\d+)\s*\|\s*([^|]+)/),o=n.match(/^[-*]\s+(.+)/),a=n.match(/^(\d+)\.\s+(.+)/);i?s.push({test:parseInt(i[1],10),name:i[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 ya(t,e,s){if(t==="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 t==="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":t==="pending"?"pending":t==="human_needed"?"human_uat":"unknown"}var it,He,Xs=L(()=>{"use strict";it=U(require("fs")),He=U(require("path"));ye();Ve();dn()});var Bt,Bn,Gn,Jn,Yn,Hn,Ur=L(()=>{"use strict";Bt=require("@oclif/core");je();Bn=class t extends w{static description="Validate planning consistency";static flags={...w.baseFlags};async run(){let{flags:e}=await this.parse(t),{cwd:s,raw:r}=this.resolveContext(e);(await Promise.resolve().then(()=>(Et(),Rt))).cmdValidateConsistency(s,r)}},Gn=class t extends w{static description="Check .planning/ health";static flags={...w.baseFlags,repair:Bt.Flags.boolean({description:"Auto-repair issues",default:!1})};async run(){let{flags:e}=await this.parse(t),{cwd:s,raw:r}=this.resolveContext(e);(await Promise.resolve().then(()=>(Et(),Rt))).cmdValidateHealth(s,{repair:e.repair},r)}},Jn=class t extends w{static description="Validate agent configurations";static flags={...w.baseFlags};async run(){let{flags:e}=await this.parse(t),{cwd:s,raw:r}=this.resolveContext(e);(await Promise.resolve().then(()=>(Et(),Rt))).cmdValidateAgents(s,r)}},Yn=class t extends w{static description="Run UAT verification";static args={phase:Bt.Args.string({required:!1})};static flags={...w.baseFlags,plan:Bt.Flags.string({description:"Plan to verify"})};async run(){let{flags:e,args:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e);(await Promise.resolve().then(()=>(Et(),Rt))).cmdValidateConsistency(r,n)}},Hn=class t extends w{static description="Audit UAT results";static flags={...w.baseFlags};async run(){let{flags:e}=await this.parse(t),{cwd:s,raw:r}=this.resolveContext(e),{cmdAuditUat:n}=await Promise.resolve().then(()=>(Xs(),Hs));n(s,r)}}});var ot={};xe(ot,{cmdWorkstreamComplete:()=>_a,cmdWorkstreamCreate:()=>Sa,cmdWorkstreamGet:()=>ka,cmdWorkstreamList:()=>ba,cmdWorkstreamProgress:()=>Pa,cmdWorkstreamSet:()=>wa,cmdWorkstreamStatus:()=>va});function xa(t,e){if(!e||/[/\\]/.test(e)||e==="."||e==="..")throw new Error("Invalid workstream name for migration");let s=ee(t),r=O.default.join(s,"workstreams",e);if(D.default.existsSync(O.default.join(s,"workstreams")))throw new Error("Already in workstream mode - .planning/workstreams/ exists");let n=[{name:"ROADMAP.md",type:"file"},{name:"STATE.md",type:"file"},{name:"REQUIREMENTS.md",type:"file"},{name:"phases",type:"dir"}];D.default.mkdirSync(r,{recursive:!0});let i=[];try{for(let o of n){let a=O.default.join(s,o.name);D.default.existsSync(a)&&(D.default.renameSync(a,O.default.join(r,o.name)),i.push(o.name))}}catch(o){for(let a of i)try{D.default.renameSync(O.default.join(r,a),O.default.join(s,a))}catch{}try{D.default.rmSync(r,{recursive:!0})}catch{}try{D.default.rmdirSync(O.default.join(s,"workstreams"))}catch{}throw o}return{migrated:!0,workstream:e,files_moved:i}}function Sa(t,e,s,r){e||b("workstream name required. Usage: workstream create <name>");let n=e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");n||b("Invalid workstream name - must contain at least one alphanumeric character");let i=ee(t);D.default.existsSync(i)||b(".planning/ directory not found - run /gsd-new-project first");let o=O.default.join(i,"workstreams"),a=O.default.join(o,n);if(D.default.existsSync(a)&&D.default.existsSync(O.default.join(a,"STATE.md"))){y({created:!1,error:"already_exists",workstream:n,path:J(O.default.relative(t,a))},r);return}let c=!D.default.existsSync(o),l=null;if(c&&s.migrate!==!1)if(D.default.existsSync(O.default.join(i,"ROADMAP.md"))||D.default.existsSync(O.default.join(i,"STATE.md"))||D.default.existsSync(O.default.join(i,"phases"))){let g=s.migrateName??null,h;if(g)h=g;else try{let x=ce(t);h=Le(x.name)||"default"}catch{h="default"}try{l=xa(t,h)}catch(x){y({created:!1,error:"migration_failed",message:x.message},r);return}}else D.default.mkdirSync(o,{recursive:!0});D.default.mkdirSync(a,{recursive:!0}),D.default.mkdirSync(O.default.join(a,"phases"),{recursive:!0});let d=new Date().toISOString().split("T")[0],u=["---",`workstream: ${n}`,`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(`
|
|
258
|
+
`),m=O.default.join(a,"STATE.md");D.default.existsSync(m)||D.default.writeFileSync(m,u,"utf-8"),lt(t,n);let p=J(O.default.relative(t,a));y({created:!0,workstream:n,path:p,state_path:p+"/STATE.md",phases_path:p+"/phases",migration:l??null,active:!0},r)}function ba(t,e){let s=O.default.join(ee(t),"workstreams");if(!D.default.existsSync(s)){y({mode:"flat",workstreams:[],message:"No workstreams - operating in flat mode"},e);return}let r=[];for(let n of D.default.readdirSync(s,{withFileTypes:!0}).filter(i=>i.isDirectory())){let i=O.default.join(s,n.name),o=O.default.join(i,"phases"),a=Ue(o),c=0;for(let u of a)try{let m=D.default.readdirSync(O.default.join(o,u)),p=wt(m),f=kt(m);p.length>0&&f.length>=p.length&&c++}catch{}let l="unknown",d=null;try{let u=D.default.readFileSync(O.default.join(i,"STATE.md"),"utf-8");l=z(u,"Status")||"unknown",d=z(u,"Current Phase")}catch{}r.push({name:n.name,path:J(O.default.relative(t,i)),has_roadmap:D.default.existsSync(O.default.join(i,"ROADMAP.md")),has_state:D.default.existsSync(O.default.join(i,"STATE.md")),status:l,current_phase:d,phase_count:a.length,completed_phases:c})}y({mode:"workstream",workstreams:r,count:r.length},e)}function va(t,e,s){e||b("workstream name required. Usage: workstream status <name>"),(/[/\\]/.test(e)||e==="."||e==="..")&&b("Invalid workstream name");let r=O.default.join(ee(t),"workstreams",e);if(!D.default.existsSync(r)){y({found:!1,workstream:e},s);return}let n=F(t,e),i={roadmap:D.default.existsSync(n.roadmap),state:D.default.existsSync(n.state),requirements:D.default.existsSync(n.requirements)},o=[];for(let c of Ue(n.phases).sort())try{let l=D.default.readdirSync(O.default.join(n.phases,c)),d=wt(l),u=kt(l);o.push({directory:c,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 c=D.default.readFileSync(n.state,"utf-8");a={status:z(c,"Status")||"unknown",current_phase:z(c,"Current Phase"),last_activity:z(c,"Last Activity")}}catch{}y({found:!0,workstream:e,path:J(O.default.relative(t,r)),files:i,phases:o,phase_count:o.length,completed_phases:o.filter(c=>c.status==="complete").length,...a},s)}function _a(t,e,s,r){e||b("workstream name required. Usage: workstream complete <name>"),(/[/\\]/.test(e)||e==="."||e==="..")&&b("Invalid workstream name");let n=ee(t),i=O.default.join(n,"workstreams"),o=O.default.join(i,e);if(!D.default.existsSync(o)){y({completed:!1,error:"not_found",workstream:e},r);return}let a=Ke(t);a===e&<(t,null);let c=O.default.join(n,"milestones"),l=new Date().toISOString().split("T")[0],d=O.default.join(c,`ws-${e}-${l}`),u=1;for(;D.default.existsSync(d);)d=O.default.join(c,`ws-${e}-${l}-${u++}`);D.default.mkdirSync(d,{recursive:!0});let m=[];try{for(let f of D.default.readdirSync(o,{withFileTypes:!0}))D.default.renameSync(O.default.join(o,f.name),O.default.join(d,f.name)),m.push(f.name)}catch(f){for(let g of m)try{D.default.renameSync(O.default.join(d,g),O.default.join(o,g))}catch{}try{D.default.rmSync(d,{recursive:!0})}catch{}a===e&<(t,e),y({completed:!1,error:"archive_failed",message:f.message,workstream:e},r);return}try{D.default.rmdirSync(o)}catch{}let p=0;try{p=D.default.readdirSync(i,{withFileTypes:!0}).filter(f=>f.isDirectory()).length,p===0&&D.default.rmdirSync(i)}catch{}y({completed:!0,workstream:e,archived_to:J(O.default.relative(t,d)),remaining_workstreams:p,reverted_to_flat:p===0},r)}function wa(t,e,s){if(!e){lt(t,null),y({active:null,cleared:!0},s);return}if(!/^[a-zA-Z0-9_-]+$/.test(e)){y({active:null,error:"invalid_name",message:"Workstream name must be alphanumeric, hyphens, and underscores only"},s);return}let r=O.default.join(ee(t),"workstreams",e);if(!D.default.existsSync(r)){y({active:null,error:"not_found",workstream:e},s);return}lt(t,e),y({active:e,set:!0},s,e)}function ka(t,e){let s=Ke(t),r=O.default.join(ee(t),"workstreams");y({active:s,mode:D.default.existsSync(r)?"workstream":"flat"},e,s||"none")}function Pa(t,e){let s=ee(t),r=O.default.join(s,"workstreams");if(!D.default.existsSync(r)){y({mode:"flat",workstreams:[],message:"No workstreams - operating in flat mode"},e);return}let n=Ke(t),i=[];for(let o of D.default.readdirSync(r,{withFileTypes:!0}).filter(a=>a.isDirectory())){let a=O.default.join(r,o.name),c=O.default.join(a,"phases"),l=Ue(c),d=0,u=0,m=0;for(let h of l)try{let x=D.default.readdirSync(O.default.join(c,h)),S=wt(x),v=kt(x);u+=S.length,m+=Math.min(v.length,S.length),S.length>0&&v.length>=S.length&&d++}catch{}let p=l.length;try{let x=D.default.readFileSync(O.default.join(a,"ROADMAP.md"),"utf-8").match(/^###?\s+Phase\s+\d/gm);x&&(p=x.length)}catch{}let f="unknown",g=null;try{let h=D.default.readFileSync(O.default.join(a,"STATE.md"),"utf-8");f=z(h,"Status")||"unknown",g=z(h,"Current Phase")}catch{}i.push({name:o.name,active:o.name===n,status:f,current_phase:g,phases:`${d}/${p}`,plans:`${m}/${u}`,progress_percent:p>0?Math.round(d/p*100):0})}y({mode:"workstream",active:n,workstreams:i,count:i.length},e)}var D,O,at=L(()=>{"use strict";D=U(require("fs")),O=U(require("path"));ye();$e()});var ct,Xn,Zn,Kn,Qn,es,ts,ns,Vr=L(()=>{"use strict";ct=require("@oclif/core");je();Xn=class t extends w{static description="Create a new workstream";static args={name:ct.Args.string({required:!0})};static flags={...w.baseFlags,"no-migrate":ct.Flags.boolean({description:"Skip migration",default:!1}),"migrate-name":ct.Flags.string({description:"Migration name"})};async run(){let{flags:e,args:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e);(await Promise.resolve().then(()=>(at(),ot))).cmdWorkstreamCreate(r,s.name,{migrate:!e["no-migrate"],migrateName:e["migrate-name"]??null},n)}},Zn=class t extends w{static description="List workstreams";static flags={...w.baseFlags};async run(){let{flags:e}=await this.parse(t),{cwd:s,raw:r}=this.resolveContext(e);(await Promise.resolve().then(()=>(at(),ot))).cmdWorkstreamList(s,r)}},Kn=class t extends w{static description="Show workstream status";static args={name:ct.Args.string({required:!0})};static flags={...w.baseFlags};async run(){let{flags:e,args:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e);(await Promise.resolve().then(()=>(at(),ot))).cmdWorkstreamStatus(r,s.name,n)}},Qn=class t extends w{static description="Complete a workstream";static args={name:ct.Args.string({required:!0})};static flags={...w.baseFlags};async run(){let{flags:e,args:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e);(await Promise.resolve().then(()=>(at(),ot))).cmdWorkstreamComplete(r,s.name,{},n)}},es=class t extends w{static description="Set active workstream";static args={name:ct.Args.string({required:!0})};static flags={...w.baseFlags};async run(){let{flags:e,args:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e);(await Promise.resolve().then(()=>(at(),ot))).cmdWorkstreamSet(r,s.name,n)}},ts=class t extends w{static description="Get active workstream";static flags={...w.baseFlags};async run(){let{flags:e}=await this.parse(t),{cwd:s,raw:r}=this.resolveContext(e);(await Promise.resolve().then(()=>(at(),ot))).cmdWorkstreamGet(s,r)}},ns=class t extends w{static description="Show workstream progress";static flags={...w.baseFlags};async run(){let{flags:e}=await this.parse(t),{cwd:s,raw:r}=this.resolveContext(e);(await Promise.resolve().then(()=>(at(),ot))).cmdWorkstreamProgress(s,r)}}});var ve={};xe(ve,{cmdCommit:()=>Fa,cmdCommitToSubrepo:()=>Ma,cmdCurrentTimestamp:()=>Ca,cmdGenerateSlug:()=>$a,cmdHistoryDigest:()=>Ra,cmdListTodos:()=>Aa,cmdProgressRender:()=>Da,cmdResolveModel:()=>Ea,cmdScaffold:()=>Wa,cmdStats:()=>qa,cmdSummaryExtract:()=>Ia,cmdTodoComplete:()=>Oa,cmdTodoMatchPhase:()=>Na,cmdVerifyPathExists:()=>ja,cmdWebsearch:()=>Ta});function $a(t,e){t||b("text required for slug generation");let s=t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");y({slug:s},e,s)}function Ca(t,e){let s=new Date,r;t==="date"?r=s.toISOString().split("T")[0]:t==="filename"?r=s.toISOString().replace(/:/g,"-").replace(/\..+/,""):r=s.toISOString(),y({timestamp:r},e,r)}function Aa(t,e,s){let r=K.default.join(W(t),"todos","pending"),n=0,i=[];try{let o=B.default.readdirSync(r).filter(a=>a.endsWith(".md"));for(let a of o)try{let c=B.default.readFileSync(K.default.join(r,a),"utf-8"),l=c.match(/^created:\s*(.+)$/m),d=c.match(/^title:\s*(.+)$/m),u=c.match(/^area:\s*(.+)$/m),m=u?u[1].trim():"general";if(e&&m!==e)continue;n++,i.push({file:a,created:l?l[1].trim():"unknown",title:d?d[1].trim():"Untitled",area:m,path:J(K.default.relative(t,K.default.join(r,a)))})}catch{}}catch{}y({count:n,todos:i},s,n.toString())}function ja(t,e,s){e||b("path required for verification"),e.includes("\0")&&b("path contains null bytes");let r=K.default.isAbsolute(e)?e:K.default.join(t,e);try{let n=B.default.statSync(r);y({exists:!0,type:n.isDirectory()?"directory":n.isFile()?"file":"other"},s,"true")}catch{y({exists:!1,type:null},s,"false")}}function Ra(t,e){let s=F(t).phases,r={phases:{},decisions:[],tech_stack:new Set},n=[];for(let i of Ut(t))n.push({name:i.name,fullPath:i.fullPath,milestone:i.milestone});if(B.default.existsSync(s))try{for(let i of B.default.readdirSync(s,{withFileTypes:!0}).filter(o=>o.isDirectory()).map(o=>o.name).sort())n.push({name:i,fullPath:K.default.join(s,i),milestone:null})}catch{}if(n.length===0){y({phases:{},decisions:[],tech_stack:[]},e);return}try{for(let{name:o,fullPath:a}of n){let c=B.default.readdirSync(a).filter(l=>l.endsWith("-SUMMARY.md")||l==="SUMMARY.md");for(let l of c)try{let d=B.default.readFileSync(K.default.join(a,l),"utf-8"),u=le(d),m=fe(u.phase)??o.split("-")[0];r.phases[m]||(r.phases[m]={name:fe(u.name)??o.split("-").slice(1).join(" ")??"Unknown",provides:new Set,affects:new Set,patterns:new Set});let p=Pt(u["dependency-graph"]);p?.provides?Pe(p.provides)?.forEach(g=>r.phases[m].provides.add(fe(g)??String(g))):u.provides&&Pe(u.provides)?.forEach(g=>r.phases[m].provides.add(fe(g)??String(g))),p?.affects&&Pe(p.affects)?.forEach(g=>r.phases[m].affects.add(fe(g)??String(g))),u["patterns-established"]&&Pe(u["patterns-established"])?.forEach(g=>r.phases[m].patterns.add(fe(g)??String(g))),u["key-decisions"]&&Pe(u["key-decisions"])?.forEach(g=>r.decisions.push({phase:m,decision:fe(g)??String(g)}));let f=Pt(u["tech-stack"]);f?.added&&Pe(f.added)?.forEach(g=>{let h=fe(g);if(h)r.tech_stack.add(h);else{let x=Pt(g);x&&r.tech_stack.add(fe(x.name)??"")}})}catch{}}let i={phases:Object.fromEntries(Object.entries(r.phases).map(([o,a])=>[o,{name:a.name,provides:[...a.provides],affects:[...a.affects],patterns:[...a.patterns]}])),decisions:r.decisions,tech_stack:[...r.tech_stack]};y(i,e)}catch(i){b("Failed to generate history digest: "+i.message)}}function Ea(t,e,s){e||b("agent-type required");let r=Q(t),n=oe(t,e),i=Me[e];y(i?{model:n,profile:r.model_profile}:{model:n,profile:r.model_profile,unknown_agent:!0},s,n)}function Fa(t,e,s,r,n=!1,i=!1){!e&&!n&&b("commit message required");let o=e;o&&(o=_r(o));let a=Q(t);if(!a.commit_docs){y({committed:!1,hash:null,reason:"skipped_commit_docs_false"},r,"skipped");return}if(rn(t,".planning")){y({committed:!1,hash:null,reason:"skipped_gitignored"},r,"skipped");return}if(a.branching_strategy&&a.branching_strategy!=="none"){let p=null;if(a.branching_strategy==="phase"){let f=(s||[]).join(" ").match(/(\d+)-/);if(f){let g=he(t,f[1]);g&&(p=a.phase_branch_template.replace("{phase}",g.phase_number).replace("{slug}",g.phase_slug||"phase"))}}else if(a.branching_strategy==="milestone"){let f=ce(t);f?.version&&(p=a.milestone_branch_template.replace("{milestone}",f.version).replace("{slug}",Le(f.name)||"milestone"))}if(p){let f=de(t,["rev-parse","--abbrev-ref","HEAD"]);f.exitCode===0&&f.stdout.trim()!==p&&de(t,["checkout","-b",p]).exitCode!==0&&de(t,["checkout",p])}}let c=s&&s.length>0?s:[".planning/"];for(let p of c){let f=K.default.join(t,p);B.default.existsSync(f)?de(t,["add",p]):de(t,["rm","--cached","--ignore-unmatch",p])}let l=n?["commit","--amend","--no-edit"]:["commit","-m",o];i&&l.push("--no-verify");let d=de(t,l);if(d.exitCode!==0){if(d.stdout.includes("nothing to commit")||d.stderr.includes("nothing to commit")){y({committed:!1,hash:null,reason:"nothing_to_commit"},r,"nothing");return}y({committed:!1,hash:null,reason:"nothing_to_commit",error:d.stderr},r,"nothing");return}let u=de(t,["rev-parse","--short","HEAD"]),m=u.exitCode===0?u.stdout:null;y({committed:!0,hash:m,reason:"committed"},r,m||"committed")}function Ma(t,e,s,r){e||b("commit message required");let i=Q(t).sub_repos;(!i||i.length===0)&&b("no sub_repos configured in .planning/config.json"),(!s||s.length===0)&&b("--files required for commit-to-subrepo");let o={},a=[];for(let l of s){let d=i.find(u=>l.startsWith(u+"/"));d?(o[d]||(o[d]=[]),o[d].push(l)):a.push(l)}a.length>0&&process.stderr.write(`Warning: ${a.length} file(s) did not match any sub-repo prefix: ${a.join(", ")}
|
|
259
259
|
`);let c={};for(let[l,d]of Object.entries(o)){let u=K.default.join(t,l);for(let f of d)de(u,["add",f.slice(l.length+1)]);let m=de(u,["commit","-m",e]);if(m.exitCode!==0){c[l]={committed:!1,hash:null,files:d,reason:m.stdout.includes("nothing to commit")?"nothing_to_commit":"error",error:m.stderr};continue}let p=de(u,["rev-parse","--short","HEAD"]);c[l]={committed:!0,hash:p.exitCode===0?p.stdout:null,files:d}}y({committed:Object.values(c).some(l=>l.committed),repos:c,unmatched:a.length>0?a:void 0},r,Object.entries(c).map(([l,d])=>`${l}:${d.hash||"skip"}`).join(" "))}function Ia(t,e,s,r){e||b("summary-path required for summary-extract");let n=K.default.join(t,e);if(!B.default.existsSync(n)){y({error:"File not found",path:e},r);return}let i=B.default.readFileSync(n,"utf-8"),o=le(i),a=l=>(l||[]).map(d=>{let u=fe(d)??String(d),m=u.indexOf(":");return m>0?{summary:u.substring(0,m).trim(),rationale:u.substring(m+1).trim()}:{summary:u,rationale:null}}),c={path:e,one_liner:fe(o["one-liner"])??Vt(i)??null,key_files:Pe(o["key-files"])??[],tech_added:Pe(Pt(o["tech-stack"])?.added)??[],patterns:Pe(o["patterns-established"])??[],decisions:a(Pe(o["key-decisions"])),requirements_completed:Pe(o["requirements-completed"])??[]};if(s&&s.length>0){let l={path:e};for(let d of s)c[d]!==void 0&&(l[d]=c[d]);y(l,r);return}y(c,r)}async function Ta(t,e,s){let r=process.env.BRAVE_API_KEY;if(!r){y({available:!1,reason:"BRAVE_API_KEY not set"},s,"");return}if(!t){y({available:!1,error:"Query required"},s,"");return}let n=new URLSearchParams({q:t,count:String(e.limit||10),country:"us",search_lang:"en",text_decorations:"false"});e.freshness&&n.set("freshness",e.freshness);try{let i=await fetch(`https://api.search.brave.com/res/v1/web/search?${n}`,{headers:{Accept:"application/json","X-Subscription-Token":r}});if(!i.ok){y({available:!1,error:`API error: ${i.status}`},s,"");return}let a=((await i.json()).web?.results||[]).map(c=>({title:c.title,url:c.url,description:c.description,age:c.age||null}));y({available:!0,query:t,count:a.length,results:a},s,a.map(c=>`${c.title}
|
|
260
260
|
${c.url}
|
|
261
261
|
${c.description}`).join(`
|
|
@@ -268,7 +268,7 @@ ${c.description}`).join(`
|
|
|
268
268
|
|-------|------|-------|--------|
|
|
269
269
|
`;for(let f of o)p+=`| ${f.number} | ${f.name} | ${f.summaries}/${f.plans} | ${f.status} |
|
|
270
270
|
`;y({rendered:p},s,p)}else if(e==="bar"){let u=Math.round(l/100*20),p=`[${"\u2588".repeat(u)+"\u2591".repeat(20-u)}] ${c}/${a} plans (${l}%)`;y({bar:p,percent:l,completed:c,total:a},s,p)}else y({milestone_version:i.version,milestone_name:i.name,phases:o,total_plans:a,total_summaries:c,percent:l},s)}function Oa(t,e,s){e||b("filename required for todo complete");let r=K.default.join(W(t),"todos","pending"),n=K.default.join(W(t),"todos","completed"),i=K.default.join(r,e);B.default.existsSync(i)||b(`Todo not found: ${e}`),B.default.mkdirSync(n,{recursive:!0});let o=B.default.readFileSync(i,"utf-8"),a=new Date().toISOString().split("T")[0];o=`completed: ${a}
|
|
271
|
-
`+o,B.default.writeFileSync(K.default.join(n,e),o,"utf-8"),B.default.unlinkSync(i),y({completed:!0,file:e,date:a},s,"completed")}function Na(t,e,s){e||b("phase required for todo match-phase");let r=K.default.join(W(t),"todos","pending"),n=[];try{for(let m of B.default.readdirSync(r).filter(p=>p.endsWith(".md")))try{let p=B.default.readFileSync(K.default.join(r,m),"utf-8"),f=p.match(/^title:\s*(.+)$/m),g=p.match(/^area:\s*(.+)$/m),h=p.match(/^files:\s*(.+)$/m),x=p.replace(/^(title|area|files|created|priority):.*$/gm,"").trim();n.push({file:m,title:f?f[1].trim():"Untitled",area:g?g[1].trim():"general",files:h?h[1].trim().split(/[,\s]+/).filter(Boolean):[],body:x.slice(0,200)})}catch{}}catch{}if(n.length===0){y({phase:e,matches:[],todo_count:0},s);return}let i=
|
|
271
|
+
`+o,B.default.writeFileSync(K.default.join(n,e),o,"utf-8"),B.default.unlinkSync(i),y({completed:!0,file:e,date:a},s,"completed")}function Na(t,e,s){e||b("phase required for todo match-phase");let r=K.default.join(W(t),"todos","pending"),n=[];try{for(let m of B.default.readdirSync(r).filter(p=>p.endsWith(".md")))try{let p=B.default.readFileSync(K.default.join(r,m),"utf-8"),f=p.match(/^title:\s*(.+)$/m),g=p.match(/^area:\s*(.+)$/m),h=p.match(/^files:\s*(.+)$/m),x=p.replace(/^(title|area|files|created|priority):.*$/gm,"").trim();n.push({file:m,title:f?f[1].trim():"Untitled",area:g?g[1].trim():"general",files:h?h[1].trim().split(/[,\s]+/).filter(Boolean):[],body:x.slice(0,200)})}catch{}}catch{}if(n.length===0){y({phase:e,matches:[],todo_count:0},s);return}let i=ut(t,e),o=`${i?.phase_name??""} ${i?.goal??""} ${i?.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"]),c=new Set(o.split(/[\s\-_/.,;:()[\]{}|]+/).map(m=>m.replace(/[^a-z0-9]/g,"")).filter(m=>m.length>2&&!a.has(m))),l=he(t,e),d=[];if(l?.found)try{let m=K.default.join(t,l.directory);for(let p of B.default.readdirSync(m).filter(f=>f.endsWith("-PLAN.md")))try{let g=B.default.readFileSync(K.default.join(m,p),"utf-8").match(/files_modified:\s*\[([^\]]*)\]/);g&&d.push(...g[1].split(",").map(h=>h.trim().replace(/['"]/g,"")).filter(Boolean))}catch{}}catch{}let u=[];for(let m of n){let p=0,f=[],h=`${m.title} ${m.body}`.toLowerCase().split(/[\s\-_/.,;:()[\]{}|]+/).map(x=>x.replace(/[^a-z0-9]/g,"")).filter(x=>x.length>2&&!a.has(x)).filter(x=>c.has(x));if(h.length>0&&(p+=Math.min(h.length*.2,.6),f.push(`keywords: ${[...new Set(h)].slice(0,5).join(", ")}`)),m.area!=="general"&&o.includes(m.area.toLowerCase())&&(p+=.3,f.push(`area: ${m.area}`)),m.files.length>0&&d.length>0){let x=m.files.filter(S=>d.some(v=>v.includes(S)||S.includes(v)));x.length>0&&(p+=.4,f.push(`files: ${x.slice(0,3).join(", ")}`))}p>0&&u.push({file:m.file,title:m.title,area:m.area,score:Math.round(p*100)/100,reasons:f})}u.sort((m,p)=>p.score-m.score),y({phase:e,matches:u,todo_count:n.length},s)}function Wa(t,e,s,r){let{phase:n,name:i}=s,o=n?pe(n):"00",a=new Date().toISOString().split("T")[0],c=n?he(t,n):null,l=c?K.default.join(t,c.directory):null;n&&!l&&e!=="phase-dir"&&b(`Phase ${n} directory not found`);let d,u;switch(e){case"context":d=K.default.join(l,`${o}-CONTEXT.md`),u=`---
|
|
272
272
|
phase: "${o}"
|
|
273
273
|
name: "${i||c?.phase_name||"Unnamed"}"
|
|
274
274
|
created: ${a}
|
|
@@ -350,7 +350,7 @@ ${p}
|
|
|
350
350
|
`,h=Jt.default.join(t,n.directory,f);if(ls.default.existsSync(h)){y({error:"File already exists",path:J(Jt.default.relative(t,h))},r);return}ls.default.writeFileSync(h,Ie(g),"utf-8");let x=J(Jt.default.relative(t,h));y({created:!0,path:x,template:e},r,x)}var ls,Jt,Ks=L(()=>{"use strict";ls=U(require("fs")),Jt=U(require("path"));ye();Ve()});var Xe,ds,us,Jr=L(()=>{"use strict";Xe=require("@oclif/core");je();ds=class t extends w{static description="Select a workflow template";static args={type:Xe.Args.string({required:!0})};static flags={...w.baseFlags};async run(){let{flags:e,args:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e),{cmdTemplateSelect:i}=await Promise.resolve().then(()=>(Ks(),Zs));i(r,s.type,n)}},us=class t extends w{static description="Fill a template with values";static args={type:Xe.Args.string({required:!0})};static flags={...w.baseFlags,phase:Xe.Flags.string(),plan:Xe.Flags.string(),name:Xe.Flags.string(),type:Xe.Flags.string({char:"t"}),wave:Xe.Flags.string(),fields:Xe.Flags.string({description:"JSON fields"})};async run(){let{flags:e,args:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e),{cmdTemplateFill:i}=await Promise.resolve().then(()=>(Ks(),Zs)),o={};if(e.fields)try{o=JSON.parse(e.fields)}catch{}i(r,s.type,{phase:e.phase??void 0,plan:e.plan??void 0,name:e.name??void 0,type:e.type??void 0,wave:e.wave??void 0,...o},n)}}});var Ft,ms,ps,fs,gs,hs,Yr=L(()=>{"use strict";Ft=require("@oclif/core");je();ms=class t extends w{static description="Show project progress";static args={format:Ft.Args.string({default:"json"})};static flags={...w.baseFlags};async run(){let{flags:e,args:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e),{cmdProgressRender:i}=await Promise.resolve().then(()=>(_e(),ve));i(r,s.format,n)}},ps=class t extends w{static description="Show project statistics";static args={format:Ft.Args.string({default:"json"})};static flags={...w.baseFlags};async run(){let{flags:e,args:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e),{cmdStats:i}=await Promise.resolve().then(()=>(_e(),ve));i(r,s.format,n)}},fs=class t extends w{static description="Mark a todo as complete";static args={id:Ft.Args.string({required:!0})};static flags={...w.baseFlags};async run(){let{flags:e,args:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e),{cmdTodoComplete:i}=await Promise.resolve().then(()=>(_e(),ve));i(r,s.id,n)}},gs=class t extends w{static description="Match todos to phase";static args={phase:Ft.Args.string({required:!0})};static flags={...w.baseFlags};async run(){let{flags:e,args:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e),{cmdTodoMatchPhase:i}=await Promise.resolve().then(()=>(_e(),ve));i(r,s.phase,n)}},hs=class t extends w{static description="Extract fields from summary files";static args={phase:Ft.Args.string({required:!0})};static flags={...w.baseFlags,fields:w.baseFlags.pick};async run(){let{flags:e,args:s}=await this.parse(t),{cwd:r,raw:n}=this.resolveContext(e),{cmdSummaryExtract:i}=await Promise.resolve().then(()=>(_e(),ve)),o=e.fields?e.fields.split(","):null;i(r,s.phase,o,n)}}});function ft(t){let e=[],s=/^```[^\n]*\n[\s\S]*?^```/gm,r;for(;(r=s.exec(t))!==null;)e.push([r.index,r.index+r[0].length]);return e}function gt(t,e){return e.some(([s,r])=>t>=s&&t<r)}function Va(t){let e={},s=/([a-zA-Z0-9_:-]+)(?:=(?:"([^"]*)"|'([^']*)'|([^\s/>]*)))?/g,r;for(;(r=s.exec(t))!==null;){let n=r[1],i=r[2]??r[3]??r[4]??"";e[n]=i}return e}function Hr(t,e){if(t[e]!=="<")return null;let s=/^<([a-zA-Z0-9_:-]+)((?:\s+[a-zA-Z0-9_:-]+(?:=(?:"[^"]*"|'[^']*'|[^\s/>]*))?)*)?\s*(\/??>)/,r=t.slice(e),n=s.exec(r);if(!n)return null;let i=n[1],o=(n[2]??"").trim(),a=n[3],c=Va(o);if(a==="/>")return{node:{tag:i,attrs:c,children:[],selfClosing:!0},end:e+n[0].length};let l=e+n[0].length,d=[],u=`</${i}>`;for(;l<t.length;){let m=t.indexOf("<",l);if(m===-1)break;if(t.startsWith(u,m))return{node:{tag:i,attrs:c,children:d,selfClosing:!1},end:m+u.length};if(t.startsWith("<!--",m)){let f=t.indexOf("-->",m+4);l=f!==-1?f+3:t.length;continue}let p=Hr(t,m);p?(d.push(p.node),l=p.end):l=m+1}return{node:{tag:i,attrs:c,children:d,selfClosing:!1},end:l}}function Yt(t){let e=ft(t),s=[],r=/<(gsd-[a-zA-Z0-9_-]+)/g,n;for(;(n=r.exec(t))!==null;){let i=n.index;if(gt(i,e))continue;let o=n[1];if(!za.has(o))continue;let a=Hr(t,i);a&&(s.push({node:a.node,start:i,end:a.end}),r.lastIndex=a.end)}return s}function ys(t,e,s,r){return t.slice(0,e)+r+t.slice(s)}var za,Qs=L(()=>{"use strict";za=new Set(["gsd-execute","gsd-arguments","gsd-paste","gsd-include","gsd-version"])});function Xr(){let t=new Map,e=new Map,s=r=>{let n=t.get(r)?.value;if(n!==void 0)return n;let i=r.indexOf(".");if(i===-1)return;let o=r.slice(0,i),a=r.slice(i+1),c=t.get(o)?.value;if(c!==void 0)try{let l=JSON.parse(c);for(let d of a.split(".")){if(l===null||typeof l!="object")return;l=l[d]}return l==null?void 0:String(l)}catch{return}};return{set(r,n,i){let o=t.get(r);o?.owner&&i&&o.owner!==i?(t.delete(r),t.set(`${o.owner}:${r}`,{name:`${o.owner}:${r}`,value:o.value,owner:o.owner}),t.set(`${i}:${r}`,{name:`${i}:${r}`,value:n,owner:i})):t.set(r,{name:r,value:n,owner:i})},get(r){return t.get(r)?.value},resolve(r){return s(r)},setArray(r,n,i){e.set(r,n),t.set(r,{name:r,value:JSON.stringify(n),owner:i})},getArray(r){if(e.has(r))return e.get(r);let n=t.get(r)?.value;if(n)try{let i=JSON.parse(n);if(Array.isArray(i))return i.map(o=>typeof o=="string"?o:JSON.stringify(o))}catch{}},has(r){return t.has(r)||e.has(r)},entries(){return t.entries()},snapshot(){let r={};for(let[n,i]of t)r[n]=i.value;return r}}}var Zr=L(()=>{"use strict"});function Kr(t,e,s){let r=t.children.find(g=>g.tag==="settings"),n=r?.children.some(g=>g.tag==="keep-extra-args")??!1,i=r?.children.some(g=>g.tag==="strict-args")??!1,a=r?.children.find(g=>g.tag==="delimiters")?.children.find(g=>g.tag==="delimiter"),c;if(a){let g=a.attrs.value??"",h=g==="\\n"?`
|
|
351
351
|
`:g;c=e.split(h).map(x=>x.trim()).filter(Boolean)}else c=e.trim().split(/\s+/).filter(Boolean);let l=t.children.filter(g=>g.tag==="arg"),d=new Set;for(let g of l.filter(h=>h.attrs.type==="flag")){let h=g.attrs.flag??`--${g.attrs.name}`,x=c.indexOf(h),S=g.attrs.name;S&&(x===-1?s.set(S,"false",void 0):(s.set(S,"true",void 0),d.add(x)))}let u=l.filter(g=>g.attrs.type!=="flag"),m=c.filter((g,h)=>!d.has(h)),p=0;for(let g=0;g<u.length;g++){let h=u[g],x=h.attrs.name,S=h.attrs.type??"string",v=g===u.length-1;if(x){if(p>=m.length){if(!("optional"in h.attrs))throw new ht(`Missing required argument '${x}' (type: ${S})`);s.set(x,"",void 0);continue}if(S==="string"&&v)s.set(x,m.slice(p).join(" "),void 0),p=m.length;else if(S==="number"){let C=m[p++],P=Number(C);if(isNaN(P))throw new ht(`Argument '${x}' expected a number, got '${C}'`);s.set(x,String(P),void 0)}else if(S==="boolean"){let C=m[p++].toLowerCase();if(C!=="true"&&C!=="false")throw new ht(`Argument '${x}' expected true/false, got '${C}'`);s.set(x,C,void 0)}else s.set(x,m[p++]??"",void 0)}}let f=m.slice(p).join(" ");if(f){if(i)throw new ht(`Unexpected extra arguments: '${f}'`);n&&s.set("_extra",f,void 0)}}var ht,er=L(()=>{"use strict";ht=class extends Error{constructor(e){super(e),this.name="WxpArgumentsError"}}});function xs(t,e,s){switch(t.position){case"project":return Ze.default.resolve(e,t.path);case"pkg":return Ze.default.resolve(s,t.path);case"absolute":return Ze.default.resolve(t.path)}}function tr(t,e,s,r){let n=Ze.default.resolve(t),i=`${Ze.default.sep}.planning`;if(n.includes(`${i}${Ze.default.sep}`)||n.endsWith(i))return{ok:!1,reason:".planning/ files are never processed by WXP (hard security invariant)"};for(let o of e.untrustedPaths){let a=xs(o,s,r);if(n.startsWith(a+Ze.default.sep)||n===a)return{ok:!1,reason:`File '${t}' is in an explicitly untrusted path: ${a}`}}for(let o of e.trustedPaths){let a=xs(o,s,r);if(n.startsWith(a+Ze.default.sep)||n===a)return{ok:!0}}return{ok:!1,reason:`File '${t}' is not in a trusted WXP path.`}}function ei(t,e){let s=Ze.default.basename(t);return e.shellBanlist.includes(s)?{ok:!1,reason:`Command '${s}' is explicitly banned by WXP security config.`}:e.shellAllowlist.includes(s)?{ok:!0}:{ok:!1,reason:`Command '${s}' is not in the WXP shell allowlist. Allowed: ${e.shellAllowlist.join(", ")}`}}var Ze,Qr,Ht=L(()=>{"use strict";Ze=U(require("path")),Qr=["pi-gsd-tools","git","node","cat","ls","echo","find"]});function Ss(t,e){if(t.attrs.string!==void 0)return t.attrs.string;if(t.attrs.name!==void 0){let s=e.resolve(t.attrs.name)??"",r=t.attrs.wrap;return r?`${r}${s}${r}`:s}return t.attrs.value!==void 0?t.attrs.value:""}function ni(t,e,s){let r=t.attrs.command??"",n=ei(r,s);if(!n.ok)throw new yt(r,"",e.snapshot(),n.reason);let i=t.children.find(u=>u.tag==="args"),o=t.children.find(u=>u.tag==="outs"),a=i?i.children.filter(u=>u.tag==="arg").map(u=>Ss(u,e)):[],c=o?o.children.some(u=>u.tag==="suppress-errors"):!1,l=o?o.children.filter(u=>u.tag==="out"&&u.attrs.name).map(u=>u.attrs.name):[],d="";try{d=(0,ti.execFileSync)(r,a,{encoding:"utf8",timeout:s.shellTimeoutMs,windowsHide:!0}).trim()}catch(u){if(c){for(let f of l)e.set(f,"",void 0);return}let m=u,p=(m.stderr??m.message??String(u)).trim();throw new yt(r,p,e.snapshot(),`Shell '${r} ${a.join(" ")}' failed: ${p}`)}l.length>0&&e.set(l[0],d,void 0)}var ti,yt,bs=L(()=>{"use strict";ti=require("child_process");Ht();yt=class extends Error{constructor(s,r,n,i){super(i);this.command=s;this.stderr=r;this.variableSnapshot=n;this.name="WxpShellError"}command;stderr;variableSnapshot}});function si(t,e){if(t.attrs.op!=="split")throw new xt('<string-op> only op="split" is supported in v1');let r=t.children.find(m=>m.tag==="args"),n=t.children.find(m=>m.tag==="outs");if(!r||!n)throw new xt("<string-op> requires <args> and <outs>");let i=r.children.filter(m=>m.tag==="arg"),o=n.children.filter(m=>m.tag==="out"),a=i[0],c=i[1];if(!a)throw new xt('<string-op op="split"> requires at least 2 <arg> children');let l=Ss(a,e);if(a.attrs.name&&e.get(a.attrs.name)===void 0)throw new xt(`string-op split: source variable '${a.attrs.name}' is not defined`);let d=c?Ss(c,e):"",u=l.split(d);o.forEach((m,p)=>{let f=m.attrs.name;f&&e.set(f,u[p+1]??u[p]??"",void 0)})}var xt,nr=L(()=>{"use strict";bs();xt=class extends Error{constructor(e){super(e),this.name="WxpStringOpError"}}});function vs(t,e){return t.attrs.name?e.resolve(t.attrs.name)??"":t.attrs.value!==void 0?t.attrs.value:""}function ri(t){return t.attrs.type==="number"}function Ga(t,e){let s=t.children.find(a=>a.tag==="left"),r=t.children.find(a=>a.tag==="right");if(!s||!r)return!1;if(ri(s)||ri(r)){let a=Number(vs(s,e)),c=Number(vs(r,e));switch(t.tag){case"equals":return a===c;case"not-equals":return a!==c;case"less-than":return a<c;case"greater-than":return a>c;case"less-than-or-equal":return a<=c;case"greater-than-or-equal":return a>=c;default:return!1}}let i=vs(s,e),o=vs(r,e);switch(t.tag){case"equals":return i===o;case"not-equals":return i!==o;case"starts-with":return i.startsWith(o);case"contains":return i.includes(o);case"less-than":return Number(i)<Number(o);case"greater-than":return Number(i)>Number(o);case"less-than-or-equal":return Number(i)<=Number(o);case"greater-than-or-equal":return Number(i)>=Number(o);default:return!1}}function Zt(t,e){return t.tag==="and"?t.children.filter(s=>Xt.has(s.tag)).every(s=>Zt(s,e)):t.tag==="or"?t.children.filter(s=>Xt.has(s.tag)).some(s=>Zt(s,e)):Ga(t,e)}function ii(t,e){let s=t.children.find(n=>n.tag==="condition");if(!s)return!1;let r=s.children.find(n=>Xt.has(n.tag));return r?Zt(r,e):!1}function oi(t,e){let s=t.children.find(r=>Xt.has(r.tag));return s?Zt(s,e):!0}var Ba,Xt,ai=L(()=>{"use strict";Ba=new Set(["equals","not-equals","starts-with","contains","less-than","greater-than","less-than-or-equal","greater-than-or-equal"]),Xt=new Set([...Ba,"and","or"])});function Ja(t,e,s){let r=(t.attrs.msg??"").replace(/\{([^}]+)\}/g,(i,o)=>e.resolve(o)??""),n=t.attrs.level;s.onDisplay(r,n==="warning"||n==="error"?n:"info")}function Ya(t,e){let s=t.attrs.src??"",r=t.attrs.out??"",n=t.attrs.path,i=e.get(s);if(i===void 0)throw new Error(`<json-parse>: source variable '${s}' is not defined`);let o;try{o=JSON.parse(i)}catch{throw new Error(`<json-parse>: '${s}' does not contain valid JSON`)}if(n){let a=n.replace(/^\$\.?/,"").split("."),c=o;for(let l of a){if(c===null||typeof c!="object")throw new Error(`<json-parse>: path '${n}' not found`);c=c[l]}o=c}Array.isArray(o)?e.setArray(r,o.map(a=>typeof a=="string"?a:JSON.stringify(a))):o!==null&&typeof o=="object"?e.set(r,JSON.stringify(o),void 0):e.set(r,o==null?"":String(o),void 0)}function Ha(t,e){let s=t.attrs.path??"",r=t.attrs.out??"",n=Kt.default.readFileSync(Qt.default.resolve(s),"utf8");e.set(r,n,void 0)}function Xa(t,e,s){let r=t.attrs.path??"",n=t.attrs.src??"",i=Qt.default.resolve(r);if(Kt.default.existsSync(i))throw new Error(`<write-file>: '${r}' already exists (create-only, never overwrites)`);for(let a of s.config.trustedPaths){let c=xs(a,s.projectRoot,s.pkgRoot);if(i.startsWith(c+Qt.default.sep)||i===c)throw new Error(`<write-file>: cannot write to trusted harness path '${r}'`)}let o=e.get(n)??"";Kt.default.mkdirSync(Qt.default.dirname(i),{recursive:!0}),Kt.default.writeFileSync(i,o,"utf8")}function Za(t,e,s){let r=t.attrs.var??"",n=t.attrs.item??"",i=t.children.find(l=>l.tag==="where"),o=t.children.find(l=>l.tag==="sort-by"),a=t.children.filter(l=>l.tag!=="where"&&l.tag!=="sort-by"),c=e.getArray(r);if(c){if(i&&(c=c.filter(l=>(e.set(n,l,void 0),oi(i,e)))),o){let l=o.attrs.key??"",d=o.attrs.type??"string",u=o.attrs.order??"asc";c=[...c].sort((m,p)=>{e.set(n,m,void 0);let f=e.resolve(`${n}.${l}`)??e.resolve(l)??"";e.set(n,p,void 0);let g=e.resolve(`${n}.${l}`)??e.resolve(l)??"",h=d==="number"?Number(f)-Number(g):f.localeCompare(g);return u==="desc"?-h:h})}for(let l of c){e.set(n,l,void 0);for(let d of a)sr(d,e,s)}}}function sr(t,e,s){switch(t.tag){case"shell":ni(t,e,s.config);break;case"string-op":si(t,e);break;case"json-parse":Ya(t,e);break;case"read-file":Ha(t,e);break;case"write-file":Xa(t,e,s);break;case"display":Ja(t,e,s);break;case"for-each":Za(t,e,s);break;case"if":{let r=ii(t,e),n=t.children.find(a=>a.tag==="then"),i=t.children.find(a=>a.tag==="else"),o=r?n:i;if(o)for(let a of o.children)sr(a,e,s);break}case"gsd-execute":rr(t,e,s);break;default:break}}function rr(t,e,s){try{for(let r of t.children)sr(r,e,s)}catch(r){throw r instanceof yt||r instanceof Error?new _s(r,e.snapshot(),`Execution failed: ${r.message}`):r}}var Kt,Qt,_s,ir=L(()=>{"use strict";Kt=U(require("fs")),Qt=U(require("path"));bs();nr();ai();Ht();_s=class extends Error{constructor(s,r,n){super(n);this.cause=s;this.variableSnapshot=r;this.name="WxpExecutionError"}cause;variableSnapshot}});function ci(t,e){let s=ft(t),r=/<gsd-paste\s+name="([^"]+)"\s*\/>/g,n=[],i;for(;(i=r.exec(t))!==null;)gt(i.index,s)||n.push({index:i.index,full:i[0],name:i[1]});for(let a of n)if(e.get(a.name)===void 0)throw new ws(a.name,e.snapshot());let o=t;for(let a=n.length-1;a>=0;a--){let c=n[a],l=e.get(c.name);o=o.slice(0,c.index)+l+o.slice(c.index+c.full.length)}return o}var ws,or=L(()=>{"use strict";Qs();ws=class extends Error{constructor(s,r){super(`<gsd-paste name="${s}" /> references undefined variable '${s}'`);this.variableName=s;this.variableSnapshot=r;this.name="WxpPasteError"}variableName;variableSnapshot}});function li(t,e,s,r,n,i="",o=Qa){let a=tr(e,s,r,n);if(!a.ok)throw new St(e,new Error(a.reason),{},[],[]);return ec(t,e,s,r,n,i,o)}function ec(t,e,s,r,n,i,o){let a=Xr(),c=[],l=t,d={config:s,projectRoot:r,pkgRoot:n,onDisplay:o};for(let u=0;u<Ka;u++){let p=Yt(l).filter(g=>g.node.tag!=="gsd-version");if(p.length===0)break;let f=p.map(g=>g.node.tag);try{let g=!1;for(let x of Yt(l)){if(x.node.tag!=="gsd-include"||gt(x.start,ft(l)))continue;let S=x.node.attrs.path;if(!S)continue;let v=ks.default.resolve(r,S);if(!ar.default.existsSync(v))throw new Error(`Include not found: ${S}`);let C=tr(v,s,r,n);if(!C.ok)throw new Error(`Include rejected: ${C.reason}`);let P=ar.default.readFileSync(v,"utf8"),$=ks.default.basename(v,ks.default.extname(v));for(let k of x.node.children)if(k.tag==="gsd-arguments")for(let j of k.children.filter(R=>R.tag==="arg")){let R=j.attrs.name,E=j.attrs.as;if(R&&E){let V=a.get(R);V!==void 0&&a.set(E,V,$)}}let T="include-arguments"in x.node.attrs?`
|
|
352
352
|
${i}`:"";l=ys(l,x.start,x.end,P+T),c.push("gsd-include"),g=!0;break}if(g)continue;for(let x of Yt(l))if(x.node.tag==="gsd-arguments"&&!gt(x.start,ft(l))){Kr(x.node,i,a),l=ys(l,x.start,x.end,""),c.push("gsd-arguments"),g=!0;break}if(g)continue;for(let x of Yt(l))if(x.node.tag==="gsd-execute"&&!gt(x.start,ft(l))){rr(x.node,a,d),l=ys(l,x.start,x.end,""),c.push("gsd-execute"),g=!0;break}if(g)continue;let h=ci(l,a);if(h!==l){l=h,c.push("gsd-paste");continue}break}catch(g){if(g instanceof St)throw g;let h=g instanceof Error?g:new Error(String(g));throw new St(e,h,a.snapshot(),f,c)}}return l}var ar,ks,Ka,Qa,St,di=L(()=>{"use strict";ar=U(require("fs")),ks=U(require("path"));Qs();Zr();er();ir();or();Ht();ir();bs();or();nr();er();Ka=50,Qa=()=>{},St=class extends Error{constructor(s,r,n,i,o){super(["WXP Processing Error",`File: ${s}`,`Error: ${r.message}`,`Variable Namespace: ${JSON.stringify(n,null,2)}`,`Pending Operations: [${i.join(", ")}]`,`Completed Operations: [${o.join(", ")}]`].join(`
|
|
353
|
-
`));this.filePath=s;this.cause=r;this.variableSnapshot=n;this.pendingOperations=i;this.completedOperations=o;this.name="WxpProcessingError"}filePath;cause;variableSnapshot;pendingOperations;completedOperations}});var bt,ui,cr,Ps,mi=L(()=>{"use strict";bt=require("@oclif/core"),ui=require("@oclif/core"),cr=U(require("path"));di();Ht();Ps=class t extends ui.Command{static description="Process WXP tags in a workflow file";static args={file:bt.Args.string({description:"File to process",required:!1})};static flags={input:bt.Flags.string({description:"Input content string (alternative to file)"}),arguments:bt.Flags.string({description:"Raw $ARGUMENTS string",default:""}),"project-root":bt.Flags.string({description:"Project root directory",default:process.cwd()}),"pkg-root":bt.Flags.string({description:"Package root directory",default:process.cwd()})};async run(){let{flags:e,args:s}=await this.parse(t),r,n;if(e.input!==void 0)r=e.input,n=cr.default.join(e["project-root"],".pi","gsd","workflows","_inline.md");else if(s.file){let o=await import("fs");n=cr.default.resolve(s.file),r=o.default.readFileSync(n,"utf8")}else{this.error("Provide a file argument or --input string");return}let i={trustedPaths:[{position:"project",path:".pi/gsd"},{position:"pkg",path:"gsd"}],untrustedPaths:[],shellAllowlist:[...Qr],shellBanlist:[],shellTimeoutMs:3e4};try{let o=li(r,n,i,e["project-root"],e["pkg-root"],e.arguments);process.stdout.write(o)}catch(o){throw o instanceof St&&this.error(o.message,{exit:1}),o}}}});var pi={};xe(pi,{AuditUatCommand:()=>Hn,CommitCommand:()=>is,ConfigEnsureSectionCommand:()=>Fn,ConfigGetCommand:()=>An,ConfigNewProjectCommand:()=>En,ConfigSetCommand:()=>jn,ConfigSetModelProfileCommand:()=>Rn,FrontmatterGetCommand:()=>os,FrontmatterMergeCommand:()=>cs,FrontmatterSetCommand:()=>as,InitCommand:()=>_n,MilestoneCompleteCommand:()=>Un,PhaseAddBatchCommand:()=>Tn,PhaseAddCommand:()=>In,PhaseCompleteCommand:()=>Nn,PhaseInsertCommand:()=>Dn,PhaseNextDecimalCommand:()=>Mn,PhasePlanIndexCommand:()=>Wn,PhaseRemoveCommand:()=>On,ProgressCommand:()=>ms,RequirementsMarkCompleteCommand:()=>Vn,RoadmapAnalyzeCommand:()=>Pn,RoadmapGetPhaseCommand:()=>$n,RoadmapUpdatePlanProgressCommand:()=>Cn,ScaffoldCommand:()=>ss,StateAdvancePlanCommand:()=>gn,StateGetCommand:()=>mn,StateJsonCommand:()=>un,StateLoadCommand:()=>hn,StatePatchCommand:()=>fn,StateReconcileCommand:()=>xn,StateUpdateCommand:()=>pn,StateUpdateProgressCommand:()=>yn,StatsCommand:()=>ps,SummaryExtractCommand:()=>hs,TemplateFillCommand:()=>us,TemplateSelectCommand:()=>ds,TodoCompleteCommand:()=>fs,TodoMatchPhaseCommand:()=>gs,ValidateAgentsCommand:()=>Jn,ValidateConsistencyCommand:()=>Bn,ValidateHealthCommand:()=>Gn,VerifyCommand:()=>Yn,WorkstreamCompleteCommand:()=>Qn,WorkstreamCreateCommand:()=>Xn,WorkstreamGetCommand:()=>ts,WorkstreamListCommand:()=>Zn,WorkstreamProgressCommand:()=>ns,WorkstreamSetCommand:()=>es,WorkstreamStatusCommand:()=>Kn,WxpProcessCommand:()=>Ps});var fi=L(()=>{"use strict";Pr();Cr();jr();Mr();Tr();Dr();Ur();Vr();zr();Br();Gr();Jr();Yr();mi()});var gi=Ei((Od,tc)=>{tc.exports={name:"pi-gsd",version:"2.1.
|
|
353
|
+
`));this.filePath=s;this.cause=r;this.variableSnapshot=n;this.pendingOperations=i;this.completedOperations=o;this.name="WxpProcessingError"}filePath;cause;variableSnapshot;pendingOperations;completedOperations}});var bt,ui,cr,Ps,mi=L(()=>{"use strict";bt=require("@oclif/core"),ui=require("@oclif/core"),cr=U(require("path"));di();Ht();Ps=class t extends ui.Command{static description="Process WXP tags in a workflow file";static args={file:bt.Args.string({description:"File to process",required:!1})};static flags={input:bt.Flags.string({description:"Input content string (alternative to file)"}),arguments:bt.Flags.string({description:"Raw $ARGUMENTS string",default:""}),"project-root":bt.Flags.string({description:"Project root directory",default:process.cwd()}),"pkg-root":bt.Flags.string({description:"Package root directory",default:process.cwd()})};async run(){let{flags:e,args:s}=await this.parse(t),r,n;if(e.input!==void 0)r=e.input,n=cr.default.join(e["project-root"],".pi","gsd","workflows","_inline.md");else if(s.file){let o=await import("fs");n=cr.default.resolve(s.file),r=o.default.readFileSync(n,"utf8")}else{this.error("Provide a file argument or --input string");return}let i={trustedPaths:[{position:"project",path:".pi/gsd"},{position:"pkg",path:"gsd"}],untrustedPaths:[],shellAllowlist:[...Qr],shellBanlist:[],shellTimeoutMs:3e4};try{let o=li(r,n,i,e["project-root"],e["pkg-root"],e.arguments);process.stdout.write(o)}catch(o){throw o instanceof St&&this.error(o.message,{exit:1}),o}}}});var pi={};xe(pi,{AuditUatCommand:()=>Hn,CommitCommand:()=>is,ConfigEnsureSectionCommand:()=>Fn,ConfigGetCommand:()=>An,ConfigNewProjectCommand:()=>En,ConfigSetCommand:()=>jn,ConfigSetModelProfileCommand:()=>Rn,FrontmatterGetCommand:()=>os,FrontmatterMergeCommand:()=>cs,FrontmatterSetCommand:()=>as,InitCommand:()=>_n,MilestoneCompleteCommand:()=>Un,PhaseAddBatchCommand:()=>Tn,PhaseAddCommand:()=>In,PhaseCompleteCommand:()=>Nn,PhaseInsertCommand:()=>Dn,PhaseNextDecimalCommand:()=>Mn,PhasePlanIndexCommand:()=>Wn,PhaseRemoveCommand:()=>On,ProgressCommand:()=>ms,RequirementsMarkCompleteCommand:()=>Vn,RoadmapAnalyzeCommand:()=>Pn,RoadmapGetPhaseCommand:()=>$n,RoadmapUpdatePlanProgressCommand:()=>Cn,ScaffoldCommand:()=>ss,StateAdvancePlanCommand:()=>gn,StateGetCommand:()=>mn,StateJsonCommand:()=>un,StateLoadCommand:()=>hn,StatePatchCommand:()=>fn,StateReconcileCommand:()=>xn,StateUpdateCommand:()=>pn,StateUpdateProgressCommand:()=>yn,StatsCommand:()=>ps,SummaryExtractCommand:()=>hs,TemplateFillCommand:()=>us,TemplateSelectCommand:()=>ds,TodoCompleteCommand:()=>fs,TodoMatchPhaseCommand:()=>gs,ValidateAgentsCommand:()=>Jn,ValidateConsistencyCommand:()=>Bn,ValidateHealthCommand:()=>Gn,VerifyCommand:()=>Yn,WorkstreamCompleteCommand:()=>Qn,WorkstreamCreateCommand:()=>Xn,WorkstreamGetCommand:()=>ts,WorkstreamListCommand:()=>Zn,WorkstreamProgressCommand:()=>ns,WorkstreamSetCommand:()=>es,WorkstreamStatusCommand:()=>Kn,WxpProcessCommand:()=>Ps});var fi=L(()=>{"use strict";Pr();Cr();jr();Mr();Tr();Dr();Ur();Vr();zr();Br();Gr();Jr();Yr();mi()});var gi=Ei((Od,tc)=>{tc.exports={name:"pi-gsd",version:"2.1.2",description:"Get Shit Done - Unofficial port of the renowned AI-native project-planning spec-driven toolkit",main:"dist/pi-gsd-tools.js",bin:{"pi-gsd-tools":"./dist/pi-gsd-tools.js","pi-gsd":"./dist/pi-gsd-tools.js"},scripts:{build:"tsup",dev:"tsup src/cli.ts --format cjs --out-dir dist --watch",typecheck:"tsc --noEmit",check:"tsc --noEmit && npm run build",postinstall:"node scripts/postinstall.js",prepublishOnly:"npm run build",test:"vitest run","test:unit":"vitest run src/wxp/__tests__ --ignore src/wxp/__tests__/integration.test.ts","test:integration":"vitest run src/wxp/__tests__/integration.test.ts",lint:"eslint src/ --ext .ts"},files:["gsd","dist","scripts/postinstall.js","README.md","LICENSE"],engines:{node:">=18.0.0"},keywords:["ai","agent","planning","cli","workflow","get-shit-done","gsd","productivity","project-management","milestones","phases","spec","pi-package"],author:"Alessio Corsi",license:"MIT",repository:{type:"git",url:"https://github.com/fulgidus/pi-gsd.git"},bugs:{url:"https://github.com/fulgidus/pi-gsd/issues"},homepage:"https://github.com/fulgidus/pi-gsd#readme",publishConfig:{access:"public",registry:"https://registry.npmjs.org/"},pi:{extensions:["./dist/pi-gsd-hooks.js"],prompts:["./gsd/prompts"]},dependencies:{"@oclif/core":"^4.10.5","@toon-format/toon":"^2.1.0","jsonpath-plus":"^10.4.0",zod:"^3.25.76"},devDependencies:{"@mariozechner/pi-coding-agent":"^0.65.0","@types/node":"^22.0.0","@typescript-eslint/eslint-plugin":"^8.58.0","@typescript-eslint/parser":"^8.58.0",eslint:"^10.2.0",tsup:"^8.5.1",typescript:"^5.0.0",vitest:"^4.1.2"}}});var $s={};xe($s,{cmdExtractMessages:()=>oc,cmdProfileSample:()=>ac,cmdScanSessions:()=>ic});function lr(t){if(t)return t;let e=process.env.HOME??"",s=De.join(e,".agent","projects");return re.existsSync(s)?s:De.join(e,".claude","projects")}function dr(){let t=process.env.HOME??"";return De.join(t,".pi","agent","sessions")}function ur(t){return t.startsWith("--")&&t.endsWith("--")?"/"+t.slice(2,-2).replace(/-/g,"/"):t}function nc(t){try{let e=re.readFileSync(t,"utf-8").split(`
|
|
354
354
|
`).find(r=>r.trim().length>0);if(!e)return!1;let s=JSON.parse(e);return s.type==="session"&&"version"in s}catch{return!1}}function sc(t){return typeof t=="string"?t:Array.isArray(t)?t.filter(e=>e!==null&&typeof e=="object"&&e.type==="text").map(e=>String(e.text??"")).join(" "):""}function rc(t){try{let e=re.readFileSync(t,"utf-8").split(`
|
|
355
355
|
`).filter(Boolean),s=[];for(let r of e)try{let n=JSON.parse(r);n.type==="message"&&n.message&&s.push(n)}catch{}return s}catch{return[]}}async function ic(t,e,s){let n=(e.harness??null)==="pi",i=dr(),o=re.existsSync(i),a=[];if(o)try{let m=re.readdirSync(i,{withFileTypes:!0}).filter(p=>p.isDirectory());for(let p of m){let f=De.join(i,p.name),g=re.readdirSync(f).filter(h=>h.endsWith(".jsonl"));a.push({name:p.name,sessions:g.length,path:f,source:"pi",cwd:ur(p.name)})}}catch{}let c=lr(n&&!t?null:t),l=!n||t?re.existsSync(c):!1,d=[];if(l&&(!n||t))try{let m=re.readdirSync(c,{withFileTypes:!0}).filter(p=>p.isDirectory());for(let p of m){let f=De.join(c,p.name),g=re.readdirSync(f).filter(h=>h.endsWith(".jsonl")||h.endsWith(".json"));d.push({name:p.name,sessions:g.length,path:f,source:"claude"})}}catch{}let u=n?[...a,...d]:[...d,...a];if(u.length===0){let m=[];o?m.push(i):m.push(i+" (not found)"),n||m.push(l?c:c+" (not found)"),y({available:!1,reason:`No sessions found. Searched: ${m.join(", ")}`,projects:[],count:0},s);return}y({available:!0,pi_base:o?i:null,claude_base:l?c:null,projects:u,count:u.length},s)}async function oc(t,e,s,r){let n=dr(),i=null,o="claude";if(re.existsSync(n)){let d=De.join(n,t);if(re.existsSync(d))i=d,o="pi";else try{let u=re.readdirSync(n,{withFileTypes:!0}).filter(m=>m.isDirectory());for(let m of u){let p=ur(m.name);if(p.endsWith("/"+t)||p===t||m.name===t){i=De.join(n,m.name),o="pi";break}}}catch{}}if(!i){let d=lr(r),u=De.join(d,t);re.existsSync(u)&&(i=u,o="claude")}if(!i){y({error:`Project not found: ${t}`,available_projects:[]},s);return}let a=[],c=re.readdirSync(i).filter(d=>d.endsWith(".jsonl")),l=e.limit??null;for(let d of c){if(e.sessionId&&!d.includes(e.sessionId))continue;let u=De.join(i,d);if(o==="pi"||nc(u))try{let m=re.readFileSync(u,"utf-8").split(`
|
|
356
356
|
`).filter(Boolean);for(let p of m)try{let f=JSON.parse(p);if(f.type==="message"&&f.message&&(a.push(f.message),l&&a.length>=l))break}catch{}}catch{}else try{let m=re.readFileSync(u,"utf-8").split(`
|
|
@@ -224,7 +224,7 @@ Create `.planning/config.json` with all settings (CLI fills in remaining default
|
|
|
224
224
|
|
|
225
225
|
```bash
|
|
226
226
|
mkdir -p .planning
|
|
227
|
-
pi-gsd-tools config-new-project '{"mode":"yolo","granularity":"[selected]","parallelization":true|false,"commit_docs":true|false,"model_profile":"quality|balanced|budget|inherit","workflow":{"research":true|false,"plan_check":true|false,"verifier":true|false,"nyquist_validation":true|false,"auto_advance":true}}'
|
|
227
|
+
pi-gsd-tools config-new-project --choices '{"mode":"yolo","granularity":"[selected]","parallelization":true|false,"commit_docs":true|false,"model_profile":"quality|balanced|budget|inherit","workflow":{"research":true|false,"plan_check":true|false,"verifier":true|false,"nyquist_validation":true|false,"auto_advance":true}}'
|
|
228
228
|
```
|
|
229
229
|
|
|
230
230
|
**If commit_docs = No:** Add `.planning/` to `.gitignore`.
|
|
@@ -544,7 +544,7 @@ Create `.planning/config.json` with all settings (CLI fills in remaining default
|
|
|
544
544
|
|
|
545
545
|
```bash
|
|
546
546
|
mkdir -p .planning
|
|
547
|
-
pi-gsd-tools config-new-project '{"mode":"[yolo|interactive]","granularity":"[selected]","parallelization":true|false,"commit_docs":true|false,"model_profile":"quality|balanced|budget|inherit","workflow":{"research":true|false,"plan_check":true|false,"verifier":true|false,"nyquist_validation":[false if granularity=coarse, true otherwise]}}'
|
|
547
|
+
pi-gsd-tools config-new-project --choices '{"mode":"[yolo|interactive]","granularity":"[selected]","parallelization":true|false,"commit_docs":true|false,"model_profile":"quality|balanced|budget|inherit","workflow":{"research":true|false,"plan_check":true|false,"verifier":true|false,"nyquist_validation":[false if granularity=coarse, true otherwise]}}'
|
|
548
548
|
```
|
|
549
549
|
|
|
550
550
|
**Note:** Run `/gsd-settings` anytime to update model profile, workflow agents, branching strategy, and other preferences.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-gsd",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.2",
|
|
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": {
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
"@typescript-eslint/eslint-plugin": "^8.58.0",
|
|
79
79
|
"@typescript-eslint/parser": "^8.58.0",
|
|
80
80
|
"eslint": "^10.2.0",
|
|
81
|
-
"tsup": "^8.
|
|
81
|
+
"tsup": "^8.5.1",
|
|
82
82
|
"typescript": "^5.0.0",
|
|
83
83
|
"vitest": "^4.1.2"
|
|
84
84
|
}
|