prjct-cli 3.24.0 → 3.24.1

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/CHANGELOG.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [3.24.1] - 2026-07-03
6
+
7
+ ### Bug Fixes
8
+
9
+ - run packed versions via the production launcher with installed deps (#514)
10
+
11
+
5
12
  ## [3.24.0] - 2026-07-02
6
13
 
7
14
  ### Features
@@ -17,7 +17,7 @@ ${e}`,action:"appended"};let o=n.substring(0,n.indexOf(t)),i=n.substring(n.index
17
17
  `)}
18
18
  `}var qj,Vk,Xj,Vj,yn,Jk,zk,Qk,Zk,tE,nE,rE=h(()=>{"use strict";Ms();lc();qj=Ud.join("/"),Vk="Generated with [p/](https://www.prjct.app/)",Xj="<!-- prjct:start - DO NOT REMOVE THIS MARKER -->",Vj="<!-- prjct:end - DO NOT REMOVE THIS MARKER -->",yn={rag:"prjct is a RAG-backed project memory harness; do not preload project history.",entrypoint:'`prjct work "<intent>" --md` is the single entrypoint \u2014 recognize intent and run the verb yourself.',pull:"Pull only what surfaces: `prjct search` / `prjct context memory <topic>` / `prjct guard <file>` / MCP `prjct_*` \u2014 not something to load wholesale.",remember:'Save synthesized memory in English: `prjct remember <decision|learning|gotcha|context> "<text>"`.',kb:`KB facets (\`${qj}\`): \`prjct remember <facet>\` / \`prjct context memory <facet>\` \u2014 pulled on demand, never injected here.`,ship:"Ship only after the user OKs: `prjct ship --md`."};a(Kk,"buildCompactSkill");Jk=Kk,zk=Kk;a(Yk,"buildGlobalConfig");Qk=a(()=>Yk("Gemini"),"buildGeminiConfig"),Zk=a(()=>Yk("Antigravity"),"buildAntigravityConfig");a(eE,"buildIdePointer");tE=a(()=>eE(`description: "prjct \u2014 pull project memory + workflow on demand"
19
19
  alwaysApply: true`),"buildCursorRule"),nE=a(()=>eE(`trigger: always_on
20
- description: "prjct \u2014 pull project memory + workflow on demand"`),"buildWindsurfRule")});var Ws={};x(Ws,{PACKAGE_ROOT:()=>Kt,VERSION:()=>le,getPackageRoot:()=>Xd,getVersion:()=>Hr,resetPackageRoot:()=>Vd});import qd from"node:fs";import uc from"node:path";function Xd(){if(Hs)return Hs;let n=__dirname;for(let e=0;e<5;e++){let t=uc.join(n,"package.json");if(qd.existsSync(t))try{if(JSON.parse(qd.readFileSync(t,"utf-8")).name==="prjct-cli")return Hs=n,n}catch{}n=uc.dirname(n)}return Hs=uc.join(__dirname,"..","..",".."),Hs}function Hr(){if(Ur)return Ur;let n="3.24.0";if(n&&/^\d+\.\d+\.\d+/.test(n))return Ur=n,Ur;try{let e=uc.join(Xd(),"package.json");return Ur=JSON.parse(qd.readFileSync(e,"utf-8")).version,Ur}catch(e){return process.env.PRJCT_DEBUG==="1"&&console.error("Failed to read version from package.json:",y(e)),"0.0.0"}}function Vd(n){Hs=n,Ur=null}var Ur,Hs,le,Kt,Ue=h(()=>{"use strict";F();Ur=null,Hs=null;a(Xd,"getPackageRoot");a(Hr,"getVersion");a(Vd,"resetPackageRoot");le=Hr(),Kt=Xd()});var fc={};x(fc,{default:()=>nD,getTemplateContent:()=>Qe,listTemplates:()=>mc,resetBundle:()=>Zj});import Jd from"node:fs";import Kj from"node:fs/promises";import pc from"node:path";function zd(){if(Kd)return dc;Kd=!0;let n=pc.join(Kt,"dist","templates.json");try{let e=Jd.readFileSync(n,"utf-8");return dc=JSON.parse(e),dc}catch{return null}}function zj(n){let e=Wr.indexOf(n);e>-1&&Wr.splice(e,1),Wr.push(n)}function Yj(){for(;Gs.size>=Jj&&Wr.length>0;){let n=Wr.shift();n&&Gs.delete(n)}}function sE(n){let e=/^---\n([\s\S]+?)\n---\n([\s\S]*)$/,t=n.match(e);if(!t)return{frontmatter:{},content:n.trim()};let[,r,s]=t,o={};return r.split(`
20
+ description: "prjct \u2014 pull project memory + workflow on demand"`),"buildWindsurfRule")});var Ws={};x(Ws,{PACKAGE_ROOT:()=>Kt,VERSION:()=>le,getPackageRoot:()=>Xd,getVersion:()=>Hr,resetPackageRoot:()=>Vd});import qd from"node:fs";import uc from"node:path";function Xd(){if(Hs)return Hs;let n=__dirname;for(let e=0;e<5;e++){let t=uc.join(n,"package.json");if(qd.existsSync(t))try{if(JSON.parse(qd.readFileSync(t,"utf-8")).name==="prjct-cli")return Hs=n,n}catch{}n=uc.dirname(n)}return Hs=uc.join(__dirname,"..","..",".."),Hs}function Hr(){if(Ur)return Ur;let n="3.24.1";if(n&&/^\d+\.\d+\.\d+/.test(n))return Ur=n,Ur;try{let e=uc.join(Xd(),"package.json");return Ur=JSON.parse(qd.readFileSync(e,"utf-8")).version,Ur}catch(e){return process.env.PRJCT_DEBUG==="1"&&console.error("Failed to read version from package.json:",y(e)),"0.0.0"}}function Vd(n){Hs=n,Ur=null}var Ur,Hs,le,Kt,Ue=h(()=>{"use strict";F();Ur=null,Hs=null;a(Xd,"getPackageRoot");a(Hr,"getVersion");a(Vd,"resetPackageRoot");le=Hr(),Kt=Xd()});var fc={};x(fc,{default:()=>nD,getTemplateContent:()=>Qe,listTemplates:()=>mc,resetBundle:()=>Zj});import Jd from"node:fs";import Kj from"node:fs/promises";import pc from"node:path";function zd(){if(Kd)return dc;Kd=!0;let n=pc.join(Kt,"dist","templates.json");try{let e=Jd.readFileSync(n,"utf-8");return dc=JSON.parse(e),dc}catch{return null}}function zj(n){let e=Wr.indexOf(n);e>-1&&Wr.splice(e,1),Wr.push(n)}function Yj(){for(;Gs.size>=Jj&&Wr.length>0;){let n=Wr.shift();n&&Gs.delete(n)}}function sE(n){let e=/^---\n([\s\S]+?)\n---\n([\s\S]*)$/,t=n.match(e);if(!t)return{frontmatter:{},content:n.trim()};let[,r,s]=t,o={};return r.split(`
21
21
  `).forEach(i=>{let[c,...l]=i.split(":");if(c&&l.length>0){let u=l.join(":").trim();u.startsWith("[")&&u.endsWith("]")?o[c.trim()]=u.slice(1,-1).split(",").map(d=>d.trim()):o[c.trim()]=u.replace(/^["']|["']$/g,"")}}),{frontmatter:o,content:s.trim()}}async function oE(n){if(Gs.has(n))return zj(n),Gs.get(n);let e,t=zd();if(t){let s=`commands/${n}.md`;e=t[s]}if(!e){let s=pc.join(Kt,"templates","commands",`${n}.md`);try{e=await Kj.readFile(s,"utf-8")}catch{throw rc.notFound(n)}}let r=sE(e);return Yj(),Gs.set(n,r),Wr.push(n),r}async function Qj(n){return(await oE(n)).frontmatter["allowed-tools"]||[]}function iE(){Gs.clear(),Wr.length=0}function Zj(){dc=null,Kd=!1,iE()}function Qe(n){let e=zd();if(e?.[n])return e[n];let t=eD(n);if(t)return t;let r=pc.join(Kt,"templates",n);try{return Jd.readFileSync(r,"utf-8")}catch{return null}}function eD(n){switch(n){case"codex/SKILL.md":return Jk();case"antigravity/SKILL.md":return zk();case"global/GEMINI.md":return Qk();case"global/ANTIGRAVITY.md":return Zk();case"global/CURSOR.mdc":return tE();case"global/WINDSURF.md":return nE();default:return null}}function mc(n){let e=zd();if(e)return Object.keys(e).filter(r=>r.startsWith(n));let t=pc.join(Kt,"templates",n);try{return Jd.readdirSync(t).map(s=>`${n}${s}`)}catch{return[]}}var Jj,Gs,Wr,dc,Kd,tD,nD,sn=h(()=>{"use strict";Ln();rE();Ue();Jj=50,Gs=new Map,Wr=[],dc=null,Kd=!1;a(zd,"loadBundle");a(zj,"updateLruOrder");a(Yj,"evictLru");a(sE,"parseFrontmatter");a(oE,"load");a(Qj,"getAllowedTools");a(iE,"clearCache");a(Zj,"resetBundle");a(Qe,"getTemplateContent");a(eD,"getGeneratedTemplateContent");a(mc,"listTemplates");tD={load:oE,parseFrontmatter:sE,getAllowedTools:Qj,clearCache:iE,getTemplateContent:Qe,listTemplates:mc},nD=tD});var gc=h(()=>{"use strict"});var cE={};x(cE,{resolveUserHome:()=>ur,resolveUserPath:()=>Ae});import rD from"node:os";import aE from"node:path";function ur(){let n=process.env.HOME?.trim()||process.env.USERPROFILE?.trim();return n?aE.resolve(n):rD.homedir()}function Ae(...n){return aE.join(ur(),...n)}var dr=h(()=>{"use strict";a(ur,"resolveUserHome");a(Ae,"resolveUserPath")});var lE,uE,dE,Yd=h(()=>{"use strict";lE=new Set(["node_modules",".git","dist","build","out",".next",".nuxt","coverage",".cache",".turbo",".vercel",".parcel-cache","__pycache__",".pytest_cache","target","vendor",".venv","venv","eggs","*.egg-info",".prjct",".worktrees"]),uE=["",".ts",".tsx",".js",".jsx","/index.ts","/index.js"],dE=/(?:import|from)\s+['"]([^'"]+)['"]/g});import fE from"node:fs/promises";async function gE(n,e){let t;try{t=await fE.readFile(n,"utf-8")}catch(o){if(Y(o))return null;throw o}let r;try{r=JSON.parse(t)}catch{return await pE(n,t),mE(n,"Malformed JSON"),null}let s=e.safeParse(r);return s.success?r:(await pE(n,t),mE(n,sD(s.error)),null)}async function pE(n,e){let t=`${n}.backup`;try{await fE.writeFile(t,e,{encoding:"utf-8",flag:"wx"})}catch{}}function mE(n,e){console.error(`[prjct] Warning: Corrupted storage file: ${n}`),console.error(`[prjct] Reason: ${e}`),console.error("[prjct] A .backup file has been created. Returning defaults.")}function sD(n){return n.issues.slice(0,3).map(e=>`${e.path.join(".")}: ${e.message}`).join("; ")}var hE=h(()=>{"use strict";F();a(gE,"safeRead");a(pE,"createBackup");a(mE,"logCorruption");a(sD,"formatZodError")});var Jt={};x(Jt,{batchProcess:()=>Un,dirExists:()=>Ge,ensureDir:()=>At,fileExists:()=>v,listFiles:()=>Wn,readFile:()=>Mt,readJson:()=>xe,walkDir:()=>Fn,writeFile:()=>Hn,writeFileAtomic:()=>Gr,writeJson:()=>he});import _t from"node:fs/promises";import si from"node:path";async function Qd(n,e,t){try{return await t()}catch(r){throw Gd(r)||Wd(r)?new Error(Fs(r,n,e)):r}}async function Fn(n,e={}){let t=[],r=e.maxFiles??1/0,s=e.dotfileAllowlist?new Set(e.dotfileAllowlist):null;async function o(i){if(t.length>=r)return;let c=await _t.readdir(i,{withFileTypes:!0}).catch(()=>[]);for(let l of c){if(t.length>=r)break;let u=String(l.name);if(lE.has(u)||e.skipDotfiles&&u.startsWith(".")&&(!s||!s.has(u)))continue;let d=si.join(i,u);l.isDirectory()?await o(d):l.isFile()&&t.push(si.relative(n,d))}}return a(o,"walk"),await o(n),t}async function Un(n,e,t){let r=[];for(let s=0;s<n.length;s+=e){let o=await Promise.all(n.slice(s,s+e).map(t));for(let i of o)i!==null&&r.push(i)}return r}async function xe(n,e=null,t){if(t)return await gE(n,t)??e;try{let r=await _t.readFile(n,"utf-8");return JSON.parse(r)}catch(r){if(Y(r))return e;throw r}}async function he(n,e,t=2){await Qd(n,"config",async()=>{let r=si.dirname(n);await _t.mkdir(r,{recursive:!0});let s=`${JSON.stringify(e,null,t)}
22
22
  `;await _t.writeFile(n,s,"utf-8")})}async function Mt(n,e=""){try{return await _t.readFile(n,"utf-8")}catch(t){if(Y(t))return e;throw t}}async function Hn(n,e){await Qd(n,"file",async()=>{let t=si.dirname(n);await _t.mkdir(t,{recursive:!0}),await _t.writeFile(n,e,"utf-8")})}async function Gr(n,e){await Qd(n,"file",async()=>{let t=si.dirname(n);await _t.mkdir(t,{recursive:!0});let r=`${n}.tmp`;await _t.writeFile(r,e,"utf-8"),await _t.rename(r,n)})}async function v(n){try{return await _t.access(n),!0}catch(e){if(Y(e))return!1;throw e}}async function Ge(n){try{return(await _t.stat(n)).isDirectory()}catch(e){if(Y(e))return!1;throw e}}async function At(n){await _t.mkdir(n,{recursive:!0})}async function Wn(n,e={}){try{let r=await _t.readdir(n,{withFileTypes:!0});return e.filesOnly&&(r=r.filter(s=>s.isFile())),e.dirsOnly&&(r=r.filter(s=>s.isDirectory())),e.extension&&(r=r.filter(s=>s.name.endsWith(e.extension))),r.map(s=>s.name)}catch(t){if(Y(t))return[];throw t}}var Q=h(()=>{"use strict";Yd();hE();F();a(Qd,"withWriteErrorContext");a(Fn,"walkDir");a(Un,"batchProcess");a(xe,"readJson");a(he,"writeJson");a(Mt,"readFile");a(Hn,"writeFile");a(Gr,"writeFileAtomic");a(v,"fileExists");a(Ge,"dirExists");a(At,"ensureDir");a(Wn,"listFiles")});var Zd,yE=h(()=>{"use strict";Zd="mcp-remote@0.1.38"});import oD from"node:fs";import iD from"node:fs/promises";import wE from"node:os";import Gn from"node:path";function aD(){let n=cD();if(n)return{command:n,args:["mcp-server"],description:ep};try{let e=Gn.dirname($t.resolve("prjct-cli/package.json"));return{command:Gn.join(e,"bin","prjct"),args:["mcp-server"],description:ep}}catch{return{command:"npx",args:["-y","prjct-cli","mcp-server"],description:ep}}}function cD(){let n=process.argv[1],e=[n?Gn.resolve(Gn.dirname(n),"prjct"):"",n?Gn.resolve(Gn.dirname(n),"..","bin","prjct"):"",Gn.resolve(process.cwd(),"bin","prjct")].filter(Boolean);for(let t of e)if(oD.existsSync(t))return t;return null}function Bs(){return process.env.PRJCT_TEST_MODE==="1"?Gn.join(wE.tmpdir(),"prjct-context7-test","mcp.json"):Gn.join(wE.homedir(),".claude","mcp.json")}async function kE(n=Bs()){try{let e=await iD.readFile(n,"utf-8");return JSON.parse(e)}catch(e){let t=y(e).toLowerCase();if(t.includes("no such file")||t.includes("enoent"))return{};throw new Error(`Failed to read MCP config at ${n}: ${y(e)}`)}}async function lD(n,e=Bs()){await he(e,n)}async function oi(n,e,t=Bs()){let r=await kE(t),s={...r.mcpServers||{}},o=s[n];s[n]=e,r.mcpServers=s;let i=JSON.stringify(o)!==JSON.stringify(e);return await lD(r,t),{path:t,changed:i}}async function EE(n,e=Bs()){return!!(await kE(e)).mcpServers?.[n]}var ep,wn,ii=h(()=>{"use strict";F();Q();yE();ep="prjct: AI Agile OS with project memory, workflow gates, intent briefs, and performance context. Use prjct_task_start as the MCP entrypoint for a work cycle; prjct retrieves focused context, persists evidence stations, and keeps humans in the loop for risky gates. Agents resume from prjct_task_status/workflow output, create or link reviewed intent/spec briefs when required, and persist synthesized learning instead of raw transcript fragments.";a(aD,"getPrjctMcpConfig");a(cD,"resolveLocalPrjctBin");wn={context7:{command:"npx",args:["-y","@upstash/context7-mcp@latest"],description:"Library documentation lookup"},prjct:aD(),linear:{command:"npx",args:["-y",Zd,"https://mcp.linear.app/mcp"],description:"Linear MCP server (OAuth)"},jira:{command:"npx",args:["-y",Zd,"https://mcp.atlassian.com/v1/mcp"],description:"Atlassian MCP server for Jira (OAuth)"}};a(Bs,"getClaudeMcpConfigPath");a(kE,"readMcpConfig");a(lD,"writeMcpConfig");a(oi,"upsertMcpServer");a(EE,"hasMcpServer")});import Br from"node:fs/promises";import tp from"node:path";function ai(){return process.env.PRJCT_TEST_MODE==="1"?tp.join(Ae(".prjct-tests"),"codex","config.toml"):Ae(".codex","config.toml")}function hc(n){return`"${n.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`}function RE(n,e,t,r){let s=(e.args??[]).map(hc).join(", ");return[t,`[mcp_servers.${n}]`,`command = ${hc(e.command)}`,`args = [${s}]`,r,""].join(`
23
23
  `)}function uD(n=wn.prjct){return RE("prjct",n,SE,TE)}function dD(n=wn.context7){return RE("context7",n,vE,bE)}function _E(n,e,t,r,s){let o=n.indexOf(t),i=n.indexOf(r);if(o!==-1&&i!==-1&&i>o){let c=n.slice(0,o),l=n.slice(i+r.length);return l.startsWith(`
@@ -2530,7 +2530,7 @@ ${js.dim("Providers:")}`}var OX,Ek=h(()=>{"use strict";OX={ready:js.green("\u271
2530
2530
  ${s.dim("Run 'prjct start' to configure global/runtime adapters")}
2531
2531
  ${s.dim("Run 'prjct init' or 'prjct sync' to refresh AGENTS.md and project-level rules")}
2532
2532
  ${s.cyan("https://prjct.app")}
2533
- `)}else return!1;return!0}var tj=h(()=>{"use strict";a($X,"runBinCommand")});var nj=Sj((Uwe,MX)=>{MX.exports={name:"prjct-cli",version:"3.24.0",description:"Project memory and workflow context for AI coding agents.",main:"dist/bin/prjct.mjs",bin:{prjct:"bin/prjct.cjs"},publishConfig:{access:"public",registry:"https://registry.npmjs.org"},scripts:{build:"node scripts/build.js","build:node":"node scripts/build.js",release:"node scripts/release.js","release:patch":"node scripts/release.js patch","release:minor":"node scripts/release.js minor","release:major":"node scripts/release.js major",prepare:"lefthook install","update-commands":`bun -e "const installer = require('./core/infrastructure/command-installer'); installer.syncCommands().then(r => console.log('Commands updated:', r)).catch(e => console.error('Error:', e.message))"`,"install-global":"./scripts/install.sh",update:"./scripts/update.sh",test:"bun test","test:watch":"bun test --watch","test:coverage":"bun test --coverage",typecheck:"tsc --noEmit -p core/tsconfig.json","typecheck:watch":"tsc --noEmit -p core/tsconfig.json --watch",validate:"bun scripts/validate-commands.js",lint:"biome lint .","lint:fix":"biome lint --write .",knip:"knip","lint:meta":"bun core/cli/lint-meta-commentary.ts",format:"biome format --write .","format:check":"biome format .",check:"biome check .","check:fix":"biome check --write .","test:e2e":"bun test core/__tests__/e2e/","bench:ab":"bun scripts/bench-ab.ts"},keywords:["claude-code","gemini-cli","ai-agents","context-layer","developer-tools","ai-assistant","productivity","mcp","llm","coding-agents"],author:"prjct.app",license:"MIT",dependencies:{"@clack/prompts":"1.0.0","@modelcontextprotocol/sdk":"1.29.0",chalk:"4.1.2",chokidar:"5.0.0","jsonc-parser":"3.3.1",zod:"3.25.76"},overrides:{"path-to-regexp":"8.4.0","brace-expansion":"5.0.5","fast-uri":">=3.1.2",hono:"4.12.27","ip-address":">=10.1.1",qs:"6.15.2"},devDependencies:{"@biomejs/biome":"2.3.13","@types/bun":"latest","@types/chokidar":"2.1.7","@types/node":"^22",esbuild:"0.28.1",knip:"6.3.1",lefthook:"2.1.0",typescript:"5.9.3"},repository:{type:"git",url:"git+https://github.com/jlopezlira/prjct-cli.git"},bugs:{url:"https://github.com/jlopezlira/prjct-cli/issues"},homepage:"https://cli.prjct.app",packageManager:"bun@1.2.23",engines:{bun:">=1.0.0",node:">=22.5.0"},files:["assets/","bin/prjct","bin/prjct.cjs","dist/","templates/","scripts/install.sh","LICENSE","README.md","CHANGELOG.md"],prepublishOnly:"node scripts/build.js"}});var GX={};import rj from"node:os";import Nd from"node:path";import Ds from"chalk";async function LX(){let[n,...e]=process.argv.slice(2);if(["-v","--version","version"].includes(n)){let r=await Promise.resolve().then(()=>Tj(nj()));await HX(r.version),process.exit(0)}if(["-h","--help",void 0].includes(n)&&(WX(),process.exit(0)),n&&va(n)&&!Ve.getByName(n)){let r=Ta[n];r&&(g.failWithHint({message:`'prjct ${n}' was removed in v2. ${r.note}`,hint:`Use: ${r.replacement}`}),process.exit(1))}if(n&&!Ve.getByName(n)&&!(e.length===0&&La(n)!==null)){let s=[n,...e.filter(i=>!i.startsWith("-"))].join(" "),o=e.filter(i=>i.startsWith("-"));n="capture",e=[s,...o]}let t=e.includes("--md");t||g.start();try{let r=Ve.getByName(n);if(!r){let m=La(n),f=m?`Did you mean 'prjct ${m}'? Run 'prjct --help' for all commands`:"Run 'prjct --help' to see available commands";g.failWithHint(ui("UNKNOWN_COMMAND",{message:`Unknown command: ${n}`,hint:f})),t||g.end(),process.exit(1)}if(r.deprecated){let m=r.replacedBy?`Use 'prjct ${r.replacedBy}' instead`:"Run 'prjct --help' to see available commands";g.failWithHint({message:`Command '${n}' is deprecated`,hint:m}),t||g.end(),process.exit(1)}r.implemented||(g.failWithHint({message:`Command '${n}' is not yet implemented`,hint:"Run 'prjct --help' to see available commands",docs:"https://github.com/jlopezlira/prjct-cli"}),t||g.end(),process.exit(1));let{parsedArgs:s,options:o}=UX(r,e),i=!process.stdin.isTTY||o.md===!0||o.json===!0;r.requiresLlm&&!i&&(g.failWithHint({message:`'prjct ${n}' requires an AI agent to process its output`,hint:`Use 'p. ${n}' inside Claude/Cursor, or add --md flag`}),t||g.end(),process.exit(1));let c=FX(r,s);c&&(g.failWithHint(c),t||g.end(),process.exit(1));let l=null,u=Date.now();try{l=await _.getProjectId(process.cwd()),l&&(await Ts.expireIfStale(l),await Ts.touch(l))}catch{}let d=new _s,p;if(n==="analyze")p=await d.analyze(o);else if(n==="setup")p=await d.setup(o);else if(n==="update"||n==="upgrade")p=await d.update(o);else{let m=s.join(" ")||null,f=o.md===!0,k=Ve.getByName(n);if(k?.optionSchema)p=await Ve.executeWithOptions(n,m,process.cwd(),Rd(o,k.optionSchema));else{let T={spec:a(b=>Fa(d,(b??"").trim().split(/\s+/).filter(Boolean),o,process.cwd()),"spec"),intent:a(b=>Fa(d,(b??"").trim().split(/\s+/).filter(Boolean),o,process.cwd()),"intent"),"audit-spec":a(b=>b?d.specAudit(b,process.cwd(),{md:f,lenses:o.lenses?String(o.lenses):void 0}):Promise.resolve({success:!1,error:"audit-spec requires a spec id"}),"audit-spec"),init:a(b=>d.init({idea:b,yes:o.yes===!0,pack:o.pack?String(o.pack):void 0,persona:o.persona?String(o.persona):void 0}),"init"),sync:a(()=>d.sync(process.cwd(),{preview:o.preview===!0||o["dry-run"]===!0,yes:o.yes===!0,json:o.json===!0,md:f,package:o.package?String(o.package):void 0,full:o.full===!0}),"sync"),"analysis-save-llm":a(b=>b?d.saveLlmAnalysis(b,process.cwd(),{md:f}):Promise.resolve({success:!1,error:"analysis-save-llm requires analysis text, JSON, or a file path"}),"analysis-save-llm"),start:a(()=>d.start(),"start"),login:a(()=>d.login({md:f}),"login"),logout:a(()=>d.logout(),"logout"),auth:a(b=>d.auth(b,{md:f}),"auth")}[n];if(T)p=await T(m);else throw new Error(`Command '${n}' has no handler`)}}if(l){let m=Date.now()-u;try{await Ts.trackCommand(l,n,m)}catch{}try{await ba.recordTiming(l,"command_duration",m,{command:n});let f=globalThis.__perfStartNs;if(f){let k=Number(process.hrtime.bigint()-f)/1e6;await ba.recordTiming(l,"startup_time",k)}await ba.recordMemory(l,{command:n})}catch{}}p?.message?console.log(p.message):p?.error&&console.error(p.error),t||g.end(),process.exit(p?.success?0:1)}catch(r){console.error("Error:",y(r)),process.env.DEBUG&&console.error(Bd(r)),t||g.end(),process.exit(1)}}function FX(n,e){if(!n.params)return null;let r=n.params.replace(/\[[^\]]*\]/g,"").match(/<[^>]+>/g);if(!r||r.length===0)return null;if(e.length<r.length){let s=r.map(i=>i.slice(1,-1)).join(", "),o=n.usage.terminal||`prjct ${n.name} ${n.params}`;return ui("MISSING_PARAM",{message:`Missing required parameter: ${s}`,hint:`Usage: ${o}`})}return null}function UX(n,e){let t=[],r={};for(let s=0;s<e.length;s++){let o=e[s];if(o.startsWith("--")){let i=o.slice(2);s+1<e.length&&!e[s+1].startsWith("--")?r[i]=e[++s]:r[i]=!0}else t.push(o)}return{parsedArgs:t,options:r}}async function HX(n){let e=await Xr(),t=Nd.join(rj.homedir(),".claude","commands","p.md"),r=Nd.join(rj.homedir(),".gemini","commands","p.toml"),[s,o,i,c]=await Promise.all([v(t),v(r),v(Nd.join(process.cwd(),".cursor","commands","sync.md")),v(Nd.join(process.cwd(),".cursor"))]),l=await pi();console.log(kk(n)),console.log(Vo("Claude Code",e.claude.installed?s?"ready":"installed":"missing",e.claude.version?Ds.dim(` (v${e.claude.version})`):"")),console.log(Vo("Gemini CLI",e.gemini.installed?o?"ready":"installed":"missing",e.gemini.version?Ds.dim(` (v${e.gemini.version})`):"")),console.log(Vo("Antigravity",l.installed?l.skillInstalled?"ready":"detected":"missing",l.installed&&!l.skillInstalled?` ${Ds.dim("(run prjct start)")}`:"")),console.log(Vo("Cursor IDE",i?"ready":c?"detected":"missing",i?` ${Ds.dim("(use prjct router)")}`:c?` ${Ds.dim("(run prjct init)")}`:"","\u25CB no .cursor/ folder")),console.log(`
2533
+ `)}else return!1;return!0}var tj=h(()=>{"use strict";a($X,"runBinCommand")});var nj=Sj((Uwe,MX)=>{MX.exports={name:"prjct-cli",version:"3.24.1",description:"Project memory and workflow context for AI coding agents.",main:"dist/bin/prjct.mjs",bin:{prjct:"bin/prjct.cjs"},publishConfig:{access:"public",registry:"https://registry.npmjs.org"},scripts:{build:"node scripts/build.js","build:node":"node scripts/build.js",release:"node scripts/release.js","release:patch":"node scripts/release.js patch","release:minor":"node scripts/release.js minor","release:major":"node scripts/release.js major",prepare:"lefthook install","update-commands":`bun -e "const installer = require('./core/infrastructure/command-installer'); installer.syncCommands().then(r => console.log('Commands updated:', r)).catch(e => console.error('Error:', e.message))"`,"install-global":"./scripts/install.sh",update:"./scripts/update.sh",test:"bun test","test:watch":"bun test --watch","test:coverage":"bun test --coverage",typecheck:"tsc --noEmit -p core/tsconfig.json","typecheck:watch":"tsc --noEmit -p core/tsconfig.json --watch",validate:"bun scripts/validate-commands.js",lint:"biome lint .","lint:fix":"biome lint --write .",knip:"knip","lint:meta":"bun core/cli/lint-meta-commentary.ts",format:"biome format --write .","format:check":"biome format .",check:"biome check .","check:fix":"biome check --write .","test:e2e":"bun test core/__tests__/e2e/","bench:ab":"bun scripts/bench-ab.ts"},keywords:["claude-code","gemini-cli","ai-agents","context-layer","developer-tools","ai-assistant","productivity","mcp","llm","coding-agents"],author:"prjct.app",license:"MIT",dependencies:{"@clack/prompts":"1.0.0","@modelcontextprotocol/sdk":"1.29.0",chalk:"4.1.2",chokidar:"5.0.0","jsonc-parser":"3.3.1",zod:"3.25.76"},overrides:{"path-to-regexp":"8.4.0","brace-expansion":"5.0.5","fast-uri":">=3.1.2",hono:"4.12.27","ip-address":">=10.1.1",qs:"6.15.2"},devDependencies:{"@biomejs/biome":"2.3.13","@types/bun":"latest","@types/chokidar":"2.1.7","@types/node":"^22",esbuild:"0.28.1",knip:"6.3.1",lefthook:"2.1.0",typescript:"5.9.3"},repository:{type:"git",url:"git+https://github.com/jlopezlira/prjct-cli.git"},bugs:{url:"https://github.com/jlopezlira/prjct-cli/issues"},homepage:"https://cli.prjct.app",packageManager:"bun@1.2.23",engines:{bun:">=1.0.0",node:">=22.5.0"},files:["assets/","bin/prjct","bin/prjct.cjs","dist/","templates/","scripts/install.sh","LICENSE","README.md","CHANGELOG.md"],prepublishOnly:"node scripts/build.js"}});var GX={};import rj from"node:os";import Nd from"node:path";import Ds from"chalk";async function LX(){let[n,...e]=process.argv.slice(2);if(["-v","--version","version"].includes(n)){let r=await Promise.resolve().then(()=>Tj(nj()));await HX(r.version),process.exit(0)}if(["-h","--help",void 0].includes(n)&&(WX(),process.exit(0)),n&&va(n)&&!Ve.getByName(n)){let r=Ta[n];r&&(g.failWithHint({message:`'prjct ${n}' was removed in v2. ${r.note}`,hint:`Use: ${r.replacement}`}),process.exit(1))}if(n&&!Ve.getByName(n)&&!(e.length===0&&La(n)!==null)){let s=[n,...e.filter(i=>!i.startsWith("-"))].join(" "),o=e.filter(i=>i.startsWith("-"));n="capture",e=[s,...o]}let t=e.includes("--md");t||g.start();try{let r=Ve.getByName(n);if(!r){let m=La(n),f=m?`Did you mean 'prjct ${m}'? Run 'prjct --help' for all commands`:"Run 'prjct --help' to see available commands";g.failWithHint(ui("UNKNOWN_COMMAND",{message:`Unknown command: ${n}`,hint:f})),t||g.end(),process.exit(1)}if(r.deprecated){let m=r.replacedBy?`Use 'prjct ${r.replacedBy}' instead`:"Run 'prjct --help' to see available commands";g.failWithHint({message:`Command '${n}' is deprecated`,hint:m}),t||g.end(),process.exit(1)}r.implemented||(g.failWithHint({message:`Command '${n}' is not yet implemented`,hint:"Run 'prjct --help' to see available commands",docs:"https://github.com/jlopezlira/prjct-cli"}),t||g.end(),process.exit(1));let{parsedArgs:s,options:o}=UX(r,e),i=!process.stdin.isTTY||o.md===!0||o.json===!0;r.requiresLlm&&!i&&(g.failWithHint({message:`'prjct ${n}' requires an AI agent to process its output`,hint:`Use 'p. ${n}' inside Claude/Cursor, or add --md flag`}),t||g.end(),process.exit(1));let c=FX(r,s);c&&(g.failWithHint(c),t||g.end(),process.exit(1));let l=null,u=Date.now();try{l=await _.getProjectId(process.cwd()),l&&(await Ts.expireIfStale(l),await Ts.touch(l))}catch{}let d=new _s,p;if(n==="analyze")p=await d.analyze(o);else if(n==="setup")p=await d.setup(o);else if(n==="update"||n==="upgrade")p=await d.update(o);else{let m=s.join(" ")||null,f=o.md===!0,k=Ve.getByName(n);if(k?.optionSchema)p=await Ve.executeWithOptions(n,m,process.cwd(),Rd(o,k.optionSchema));else{let T={spec:a(b=>Fa(d,(b??"").trim().split(/\s+/).filter(Boolean),o,process.cwd()),"spec"),intent:a(b=>Fa(d,(b??"").trim().split(/\s+/).filter(Boolean),o,process.cwd()),"intent"),"audit-spec":a(b=>b?d.specAudit(b,process.cwd(),{md:f,lenses:o.lenses?String(o.lenses):void 0}):Promise.resolve({success:!1,error:"audit-spec requires a spec id"}),"audit-spec"),init:a(b=>d.init({idea:b,yes:o.yes===!0,pack:o.pack?String(o.pack):void 0,persona:o.persona?String(o.persona):void 0}),"init"),sync:a(()=>d.sync(process.cwd(),{preview:o.preview===!0||o["dry-run"]===!0,yes:o.yes===!0,json:o.json===!0,md:f,package:o.package?String(o.package):void 0,full:o.full===!0}),"sync"),"analysis-save-llm":a(b=>b?d.saveLlmAnalysis(b,process.cwd(),{md:f}):Promise.resolve({success:!1,error:"analysis-save-llm requires analysis text, JSON, or a file path"}),"analysis-save-llm"),start:a(()=>d.start(),"start"),login:a(()=>d.login({md:f}),"login"),logout:a(()=>d.logout(),"logout"),auth:a(b=>d.auth(b,{md:f}),"auth")}[n];if(T)p=await T(m);else throw new Error(`Command '${n}' has no handler`)}}if(l){let m=Date.now()-u;try{await Ts.trackCommand(l,n,m)}catch{}try{await ba.recordTiming(l,"command_duration",m,{command:n});let f=globalThis.__perfStartNs;if(f){let k=Number(process.hrtime.bigint()-f)/1e6;await ba.recordTiming(l,"startup_time",k)}await ba.recordMemory(l,{command:n})}catch{}}p?.message?console.log(p.message):p?.error&&console.error(p.error),t||g.end(),process.exit(p?.success?0:1)}catch(r){console.error("Error:",y(r)),process.env.DEBUG&&console.error(Bd(r)),t||g.end(),process.exit(1)}}function FX(n,e){if(!n.params)return null;let r=n.params.replace(/\[[^\]]*\]/g,"").match(/<[^>]+>/g);if(!r||r.length===0)return null;if(e.length<r.length){let s=r.map(i=>i.slice(1,-1)).join(", "),o=n.usage.terminal||`prjct ${n.name} ${n.params}`;return ui("MISSING_PARAM",{message:`Missing required parameter: ${s}`,hint:`Usage: ${o}`})}return null}function UX(n,e){let t=[],r={};for(let s=0;s<e.length;s++){let o=e[s];if(o.startsWith("--")){let i=o.slice(2);s+1<e.length&&!e[s+1].startsWith("--")?r[i]=e[++s]:r[i]=!0}else t.push(o)}return{parsedArgs:t,options:r}}async function HX(n){let e=await Xr(),t=Nd.join(rj.homedir(),".claude","commands","p.md"),r=Nd.join(rj.homedir(),".gemini","commands","p.toml"),[s,o,i,c]=await Promise.all([v(t),v(r),v(Nd.join(process.cwd(),".cursor","commands","sync.md")),v(Nd.join(process.cwd(),".cursor"))]),l=await pi();console.log(kk(n)),console.log(Vo("Claude Code",e.claude.installed?s?"ready":"installed":"missing",e.claude.version?Ds.dim(` (v${e.claude.version})`):"")),console.log(Vo("Gemini CLI",e.gemini.installed?o?"ready":"installed":"missing",e.gemini.version?Ds.dim(` (v${e.gemini.version})`):"")),console.log(Vo("Antigravity",l.installed?l.skillInstalled?"ready":"detected":"missing",l.installed&&!l.skillInstalled?` ${Ds.dim("(run prjct start)")}`:"")),console.log(Vo("Cursor IDE",i?"ready":c?"detected":"missing",i?` ${Ds.dim("(use prjct router)")}`:c?` ${Ds.dim("(run prjct init)")}`:"","\u25CB no .cursor/ folder")),console.log(`
2534
2534
  ${Ds.dim("Run 'prjct start' for Claude/Gemini, 'prjct init' for Cursor")}
2535
2535
  ${Ds.cyan("https://prjct.app")}
2536
2536
  `)}function WX(){console.log(`
@@ -1166,7 +1166,7 @@ CREATE TABLE velocity_sprints (
1166
1166
  name TEXT NOT NULL,
1167
1167
  applied_at TEXT NOT NULL
1168
1168
  )
1169
- `);let r=new Set(e.prepare("SELECT version FROM _migrations").all().map(i=>i.version)),s=oi.filter(i=>!r.has(i.version));if(s.length!==0){if(t&&r.size>0)try{let i=`${t}.pre-migrate.bak`;Kr.existsSync(i)&&Kr.rmSync(i,{force:!0}),e.prepare("VACUUM INTO ?").run(i)}catch(i){console.warn(`prjct: pre-migration backup failed (continuing): ${i?.message??i}`)}for(let i of s)Fa(e,()=>{i.up(e),e.prepare("INSERT INTO _migrations (version, name, applied_at) VALUES (?, ?, ?)").run(i.version,i.name,new Date().toISOString())})}}getMigrations(e){return this.getDb(e).prepare("SELECT * FROM _migrations ORDER BY version").all()}getSchemaVersion(e){return this.getDb(e).prepare("SELECT MAX(version) as version FROM _migrations").get()?.version??0}},y=new ai,h=y});function Rp(n){let e=n.toLowerCase();return e.includes("github")?"github":e.includes("gitlab")?"gitlab":e.includes("bitbucket")?"bitbucket":"other"}function $a(n){let e=n.trim();if(!e)return{};let t=e.match(/^[^/@]+@([^:/]+):(.+?)(?:\.git)?\/?$/);if(t)return{provider:Rp(t[1]),repoSlug:t[2]};try{let r=new URL(e),s=r.pathname.replace(/^\/+/,"").replace(/\.git$/,"").replace(/\/+$/,"");return!r.host||!s?{}:{provider:Rp(r.host),repoSlug:s}}catch{return{}}}async function BS(n){try{let{stdout:e}=await W("git",["remote","get-url","origin"],{cwd:n});return e.trim()||void 0}catch{return}}async function GS(n){try{let{stdout:e}=await W("git",["symbolic-ref","--short","refs/remotes/origin/HEAD"],{cwd:n});return e.trim().replace(/^origin\//,"")||void 0}catch{return}}function Tn(n){return typeof n=="string"&&n.length>0?n:void 0}function Cp(n){return typeof n=="number"&&Number.isFinite(n)?n:void 0}function XS(n){return Object.fromEntries(Object.entries(n).filter(([,e])=>e!==void 0))}async function Ap(n){let e=y.getDoc(n,"project")||{},t=Tn(e.repoPath),{provider:r,repoSlug:s}=t?$a(await BS(t)||""):{},i=t?await GS(t):void 0,o=Array.isArray(e.techStack)?e.techStack.filter(c=>typeof c=="string"):void 0;return XS({provider:r,repoSlug:s,currentBranch:Tn(e.currentBranch),defaultBranch:i,stack:Tn(e.stack),techStack:o&&o.length>0?o:void 0,version:Tn(e.version),commitCount:Cp(e.commitCount),fileCount:Cp(e.fileCount),lastCommit:Tn(e.lastSyncCommit),hasUncommitted:typeof e.hasUncommittedChanges=="boolean"?e.hasUncommittedChanges:void 0,cliVersion:Tn(e.cliVersion),syncedAt:Tn(e.lastSync)})}var Ua=g(()=>{"use strict";N();se();a(Rp,"providerForHost");a($a,"parseRemote");a(BS,"gitRemoteUrl");a(GS,"gitDefaultBranch");a(Tn,"str");a(Cp,"num");a(XS,"compact");a(Ap,"buildProjectMeta")});import{execFile as qS}from"node:child_process";import VS from"node:crypto";import{promisify as KS}from"node:util";function zS(n,e=JS){let t=Buffer.from(e.replace(/-/g,""),"hex"),s=VS.createHash("sha1").update(t).update(n,"utf8").digest().subarray(0,16);s[6]=s[6]&15|80,s[8]=s[8]&63|128;let i=s.toString("hex");return`${i.slice(0,8)}-${i.slice(8,12)}-${i.slice(12,16)}-${i.slice(16,20)}-${i.slice(20,32)}`}async function QS(n){let e;try{let{stdout:s}=await YS("git",["remote","get-url","origin"],{cwd:n});e=s.trim()||void 0}catch{return null}if(!e)return null;let{provider:t,repoSlug:r}=$a(e);return!t||!r?null:`${t}:${r}`.toLowerCase()}async function xp(n){let e=await QS(n);return e?zS(e):null}var YS,JS,Np=g(()=>{"use strict";Ua();YS=KS(qS),JS="6f9b2c1a-3d4e-5f60-8a7b-1c2d3e4f5a6b";a(zS,"uuidv5");a(QS,"repoKey");a(xp,"deriveProjectId")});var Ba={};M(Ba,{PACKAGE_ROOT:()=>Pt,VERSION:()=>Ae,getPackageRoot:()=>Wa,getVersion:()=>li,resetPackageRoot:()=>ZS});import Ha from"node:fs";import ci from"node:path";function Wa(){if(nr)return nr;let n=__dirname;for(let e=0;e<5;e++){let t=ci.join(n,"package.json");if(Ha.existsSync(t))try{if(JSON.parse(Ha.readFileSync(t,"utf-8")).name==="prjct-cli")return nr=n,n}catch{}n=ci.dirname(n)}return nr=ci.join(__dirname,"..","..",".."),nr}function li(){if(kn)return kn;let n="3.24.0";if(n&&/^\d+\.\d+\.\d+/.test(n))return kn=n,kn;try{let e=ci.join(Wa(),"package.json");return kn=JSON.parse(Ha.readFileSync(e,"utf-8")).version,kn}catch(e){return process.env.PRJCT_DEBUG==="1"&&console.error("Failed to read version from package.json:",S(e)),"0.0.0"}}function ZS(n){nr=n,kn=null}var kn,nr,Ae,Pt,it=g(()=>{"use strict";Y();kn=null,nr=null;a(Wa,"getPackageRoot");a(li,"getVersion");a(ZS,"resetPackageRoot");Ae=li(),Pt=Wa()});async function ui(n){try{let{stdout:e}=await I(n,{timeout:5e3});return{success:!0,output:e.trim()}}catch{return{success:!1,output:""}}}async function ev(){let n=await ui("gh api user --jq .login");return n.success&&n.output||(n=await ui("git config --global github.user"),n.success&&n.output)?n.output:null}async function tv(){let n=await ui("git config user.name");return n.success&&n.output?n.output:null}async function nv(){let n=await ui("git config user.email");return n.success&&n.output?n.output:null}async function rr(){let[n,e,t]=await Promise.all([ev(),tv(),nv()]);return{github:n,email:t,name:e||n||"Unknown"}}var di=g(()=>{"use strict";se();a(ui,"execCommand");a(ev,"detectGitHubUsername");a(tv,"detectGitName");a(nv,"detectGitEmail");a(rr,"detect")});var Va={};M(Va,{worktreeService:()=>rv});import Xa from"node:fs/promises";import yt from"node:path";var Ip,qa,rv,Ka=g(()=>{"use strict";se();X();Ip=".worktrees",qa=class{static{a(this,"WorktreeService")}async create(e,t,r={}){let s=await this.getMainWorktree(e),i=yt.join(s,Ip,t),o=r.branch||`feat/${t}`;await Xa.mkdir(yt.join(s,Ip),{recursive:!0});let c=r.baseBranch?` ${r.baseBranch}`:"";await I(`git worktree add "${i}" -b "${o}"${c}`,{cwd:s});let{stdout:l}=await I("git rev-parse HEAD",{cwd:i});return{path:i,branch:o,commit:l.trim(),isMain:!1,slug:t}}async remove(e,t=!1){let r=await this.getMainWorktree(e),s;if(t)try{let{stdout:i}=await I("git rev-parse --abbrev-ref HEAD",{cwd:e});s=i.trim()}catch{}if(await I(`git worktree remove "${e}" --force`,{cwd:r}),t&&s&&s!=="main"&&s!=="master")try{await I(`git branch -D "${s}"`,{cwd:r})}catch{}}async list(e){let t=await this.getMainWorktree(e),{stdout:r}=await I("git worktree list --porcelain",{cwd:t});return this.parsePorcelainOutput(r,t)}async detect(e){try{let{stdout:t}=await I("git rev-parse --git-common-dir",{cwd:e}),{stdout:r}=await I("git rev-parse --git-dir",{cwd:e}),s=yt.resolve(e,t.trim()),i=yt.resolve(e,r.trim());if(s!==i){let{stdout:o}=await I("git rev-parse --abbrev-ref HEAD",{cwd:e}),{stdout:c}=await I("git rev-parse HEAD",{cwd:e}),{stdout:l}=await I("git rev-parse --show-toplevel",{cwd:e}),u=l.trim(),d=yt.basename(u);return{path:u,branch:o.trim(),commit:c.trim(),isMain:!1,slug:d}}return null}catch{return null}}async getMainWorktree(e){try{let{stdout:r}=await I("git worktree list --porcelain",{cwd:e}),s=r.split(`
1169
+ `);let r=new Set(e.prepare("SELECT version FROM _migrations").all().map(i=>i.version)),s=oi.filter(i=>!r.has(i.version));if(s.length!==0){if(t&&r.size>0)try{let i=`${t}.pre-migrate.bak`;Kr.existsSync(i)&&Kr.rmSync(i,{force:!0}),e.prepare("VACUUM INTO ?").run(i)}catch(i){console.warn(`prjct: pre-migration backup failed (continuing): ${i?.message??i}`)}for(let i of s)Fa(e,()=>{i.up(e),e.prepare("INSERT INTO _migrations (version, name, applied_at) VALUES (?, ?, ?)").run(i.version,i.name,new Date().toISOString())})}}getMigrations(e){return this.getDb(e).prepare("SELECT * FROM _migrations ORDER BY version").all()}getSchemaVersion(e){return this.getDb(e).prepare("SELECT MAX(version) as version FROM _migrations").get()?.version??0}},y=new ai,h=y});function Rp(n){let e=n.toLowerCase();return e.includes("github")?"github":e.includes("gitlab")?"gitlab":e.includes("bitbucket")?"bitbucket":"other"}function $a(n){let e=n.trim();if(!e)return{};let t=e.match(/^[^/@]+@([^:/]+):(.+?)(?:\.git)?\/?$/);if(t)return{provider:Rp(t[1]),repoSlug:t[2]};try{let r=new URL(e),s=r.pathname.replace(/^\/+/,"").replace(/\.git$/,"").replace(/\/+$/,"");return!r.host||!s?{}:{provider:Rp(r.host),repoSlug:s}}catch{return{}}}async function BS(n){try{let{stdout:e}=await W("git",["remote","get-url","origin"],{cwd:n});return e.trim()||void 0}catch{return}}async function GS(n){try{let{stdout:e}=await W("git",["symbolic-ref","--short","refs/remotes/origin/HEAD"],{cwd:n});return e.trim().replace(/^origin\//,"")||void 0}catch{return}}function Tn(n){return typeof n=="string"&&n.length>0?n:void 0}function Cp(n){return typeof n=="number"&&Number.isFinite(n)?n:void 0}function XS(n){return Object.fromEntries(Object.entries(n).filter(([,e])=>e!==void 0))}async function Ap(n){let e=y.getDoc(n,"project")||{},t=Tn(e.repoPath),{provider:r,repoSlug:s}=t?$a(await BS(t)||""):{},i=t?await GS(t):void 0,o=Array.isArray(e.techStack)?e.techStack.filter(c=>typeof c=="string"):void 0;return XS({provider:r,repoSlug:s,currentBranch:Tn(e.currentBranch),defaultBranch:i,stack:Tn(e.stack),techStack:o&&o.length>0?o:void 0,version:Tn(e.version),commitCount:Cp(e.commitCount),fileCount:Cp(e.fileCount),lastCommit:Tn(e.lastSyncCommit),hasUncommitted:typeof e.hasUncommittedChanges=="boolean"?e.hasUncommittedChanges:void 0,cliVersion:Tn(e.cliVersion),syncedAt:Tn(e.lastSync)})}var Ua=g(()=>{"use strict";N();se();a(Rp,"providerForHost");a($a,"parseRemote");a(BS,"gitRemoteUrl");a(GS,"gitDefaultBranch");a(Tn,"str");a(Cp,"num");a(XS,"compact");a(Ap,"buildProjectMeta")});import{execFile as qS}from"node:child_process";import VS from"node:crypto";import{promisify as KS}from"node:util";function zS(n,e=JS){let t=Buffer.from(e.replace(/-/g,""),"hex"),s=VS.createHash("sha1").update(t).update(n,"utf8").digest().subarray(0,16);s[6]=s[6]&15|80,s[8]=s[8]&63|128;let i=s.toString("hex");return`${i.slice(0,8)}-${i.slice(8,12)}-${i.slice(12,16)}-${i.slice(16,20)}-${i.slice(20,32)}`}async function QS(n){let e;try{let{stdout:s}=await YS("git",["remote","get-url","origin"],{cwd:n});e=s.trim()||void 0}catch{return null}if(!e)return null;let{provider:t,repoSlug:r}=$a(e);return!t||!r?null:`${t}:${r}`.toLowerCase()}async function xp(n){let e=await QS(n);return e?zS(e):null}var YS,JS,Np=g(()=>{"use strict";Ua();YS=KS(qS),JS="6f9b2c1a-3d4e-5f60-8a7b-1c2d3e4f5a6b";a(zS,"uuidv5");a(QS,"repoKey");a(xp,"deriveProjectId")});var Ba={};M(Ba,{PACKAGE_ROOT:()=>Pt,VERSION:()=>Ae,getPackageRoot:()=>Wa,getVersion:()=>li,resetPackageRoot:()=>ZS});import Ha from"node:fs";import ci from"node:path";function Wa(){if(nr)return nr;let n=__dirname;for(let e=0;e<5;e++){let t=ci.join(n,"package.json");if(Ha.existsSync(t))try{if(JSON.parse(Ha.readFileSync(t,"utf-8")).name==="prjct-cli")return nr=n,n}catch{}n=ci.dirname(n)}return nr=ci.join(__dirname,"..","..",".."),nr}function li(){if(kn)return kn;let n="3.24.1";if(n&&/^\d+\.\d+\.\d+/.test(n))return kn=n,kn;try{let e=ci.join(Wa(),"package.json");return kn=JSON.parse(Ha.readFileSync(e,"utf-8")).version,kn}catch(e){return process.env.PRJCT_DEBUG==="1"&&console.error("Failed to read version from package.json:",S(e)),"0.0.0"}}function ZS(n){nr=n,kn=null}var kn,nr,Ae,Pt,it=g(()=>{"use strict";Y();kn=null,nr=null;a(Wa,"getPackageRoot");a(li,"getVersion");a(ZS,"resetPackageRoot");Ae=li(),Pt=Wa()});async function ui(n){try{let{stdout:e}=await I(n,{timeout:5e3});return{success:!0,output:e.trim()}}catch{return{success:!1,output:""}}}async function ev(){let n=await ui("gh api user --jq .login");return n.success&&n.output||(n=await ui("git config --global github.user"),n.success&&n.output)?n.output:null}async function tv(){let n=await ui("git config user.name");return n.success&&n.output?n.output:null}async function nv(){let n=await ui("git config user.email");return n.success&&n.output?n.output:null}async function rr(){let[n,e,t]=await Promise.all([ev(),tv(),nv()]);return{github:n,email:t,name:e||n||"Unknown"}}var di=g(()=>{"use strict";se();a(ui,"execCommand");a(ev,"detectGitHubUsername");a(tv,"detectGitName");a(nv,"detectGitEmail");a(rr,"detect")});var Va={};M(Va,{worktreeService:()=>rv});import Xa from"node:fs/promises";import yt from"node:path";var Ip,qa,rv,Ka=g(()=>{"use strict";se();X();Ip=".worktrees",qa=class{static{a(this,"WorktreeService")}async create(e,t,r={}){let s=await this.getMainWorktree(e),i=yt.join(s,Ip,t),o=r.branch||`feat/${t}`;await Xa.mkdir(yt.join(s,Ip),{recursive:!0});let c=r.baseBranch?` ${r.baseBranch}`:"";await I(`git worktree add "${i}" -b "${o}"${c}`,{cwd:s});let{stdout:l}=await I("git rev-parse HEAD",{cwd:i});return{path:i,branch:o,commit:l.trim(),isMain:!1,slug:t}}async remove(e,t=!1){let r=await this.getMainWorktree(e),s;if(t)try{let{stdout:i}=await I("git rev-parse --abbrev-ref HEAD",{cwd:e});s=i.trim()}catch{}if(await I(`git worktree remove "${e}" --force`,{cwd:r}),t&&s&&s!=="main"&&s!=="master")try{await I(`git branch -D "${s}"`,{cwd:r})}catch{}}async list(e){let t=await this.getMainWorktree(e),{stdout:r}=await I("git worktree list --porcelain",{cwd:t});return this.parsePorcelainOutput(r,t)}async detect(e){try{let{stdout:t}=await I("git rev-parse --git-common-dir",{cwd:e}),{stdout:r}=await I("git rev-parse --git-dir",{cwd:e}),s=yt.resolve(e,t.trim()),i=yt.resolve(e,r.trim());if(s!==i){let{stdout:o}=await I("git rev-parse --abbrev-ref HEAD",{cwd:e}),{stdout:c}=await I("git rev-parse HEAD",{cwd:e}),{stdout:l}=await I("git rev-parse --show-toplevel",{cwd:e}),u=l.trim(),d=yt.basename(u);return{path:u,branch:o.trim(),commit:c.trim(),isMain:!1,slug:d}}return null}catch{return null}}async getMainWorktree(e){try{let{stdout:r}=await I("git worktree list --porcelain",{cwd:e}),s=r.split(`
1170
1170
  `)[0];if(s?.startsWith("worktree "))return s.replace("worktree ","").trim()}catch{}let{stdout:t}=await I("git rev-parse --show-toplevel",{cwd:e});return t.trim()}async setup(e,t){let r=yt.join(t,".env");await v(r)&&await Xa.copyFile(r,yt.join(e,".env"));let s=yt.join(t,".prjct"),i=yt.join(e,".prjct");await v(s)&&!await v(i)&&await Xa.symlink(s,i,"dir")}async teardown(e){}async clean(e){let t=await this.list(e),r=[],s=await this.getMainWorktree(e);await I("git worktree prune",{cwd:s});for(let i of t)i.isMain||await v(i.path)||r.push(i.slug);return r}parsePorcelainOutput(e,t){let r=[],s=e.trim().split(`
1171
1171
 
1172
1172
  `);for(let i of s){if(!i.trim())continue;let o=i.trim().split(`
@@ -1318,7 +1318,7 @@ ${c.join(`
1318
1318
  `);e=d.trim(),t=p.trim(),r=m.trim(),s=g.trim()&&g.trim()!=="HEAD"?g.trim():void 0}catch{let u=await zw(n);return{workspaceId:Ze,worktreePath:u,shortId:Ze,isMain:!0,label:rd(Ze)}}let i=Jw.resolve(n,t)===Jw.resolve(n,r),o=await zw(e||n);if(i)return{workspaceId:Ze,worktreePath:o,shortId:Ze,branch:s,isMain:!0,label:rd(Ze,s)};let c=ga(o),l=c.slice(0,6);return{workspaceId:c,worktreePath:o,shortId:l,branch:s,isMain:!1,label:rd(l,s)}}var Ze,Yw,wI,sd=h(()=>{"use strict";ie();as();Ze="main";a(zw,"safeRealpath");a(rd,"buildLabel");Yw=new Map,wI=5e3;a(kr,"deriveWorkspace");a(EI,"computeWorkspace")});var fa={};O(fa,{collectActiveTasks:()=>gn,formatActiveTaskLine:()=>Zw,formatActiveTaskList:()=>kI});function Qw(n,e){let t=n===Ze?Ze:n.slice(0,6);return{shortId:t,label:`${t} \xB7 ${e??"(detached)"}`}}async function gn(n,e){let t=await kr(e),r=[],s=await X.getCurrentTask(n);if(s){let{shortId:o,label:c}=Qw(Ze,s.branch);r.push({id:s.id,description:s.description,workspaceId:Ze,shortId:o,label:c,branch:s.branch,linearId:s.linearId,harness:s.harness,startedAt:s.startedAt,isCurrent:t.workspaceId===Ze,pipeline:wi(n,s.id,Ze)??void 0})}for(let o of await X.getActiveTasks(n)){if(o.workspaceId===Ze)continue;let{shortId:c,label:l}=Qw(o.workspaceId,o.branch);r.push({id:o.id,description:o.description,workspaceId:o.workspaceId,shortId:c,label:l,branch:o.branch,linearId:o.linearId,harness:o.harness,startedAt:o.startedAt,isCurrent:t.workspaceId===o.workspaceId,pipeline:wi(n,o.id,o.workspaceId)??void 0})}return r.sort((o,c)=>Number(c.isCurrent)-Number(o.isCurrent)),{current:r.find(o=>o.isCurrent)??null,all:r}}function Zw(n){let e=n.isCurrent?"\u2192":" ",t=n.isCurrent?" (this worktree)":"";return`${e} ${n.label} ${n.description}${t}`}function kI(n){if(n.all.length===0)return"No active work cycle.";if(n.all.length===1&&n.current){let t=n.current,r=t.pipeline?`
1319
1319
  Pipeline: ${t.pipeline.station}`:"";return`Active: ${t.description}
1320
1320
  Workspace: ${t.label}${r}`}let e=[`Active work cycles (${n.all.length})`];for(let t of n.all)e.push(Zw(t));return e.join(`
1321
- `)}var Hn=h(()=>{"use strict";Qe();nd();sd();a(Qw,"labelFor");a(gn,"collectActiveTasks");a(Zw,"formatActiveTaskLine");a(kI,"formatActiveTaskList")});var eE,cs,TI,SI,id=h(()=>{"use strict";eE={core:{title:"AI Agile Loop",description:"Intent, context, execution, learning, and improvement",order:1},optional:{title:"Intelligence & Quality",description:"Project intelligence, quality proof, and advanced policies",order:2},setup:{title:"Setup & Infrastructure",description:"Installation, configuration, and integration plumbing",order:3},legacy:{title:"Compatibility",description:"v2 aliases kept for existing users and scripts",order:4}},cs=[{name:"intent",group:"core",surface:"ai-agile",routing:{group:"spec",method:"draft"},routingMode:"cold-only",optionSchema:{strings:["goal","tags"]},description:"Frame the work brief: objective, constraints, risks, and success signal",usage:{claude:'p. intent "<title>"',terminal:'prjct intent "<title>" [--goal "..."] [--tags k:v,...]'},params:'"<title>" [--goal] [--tags]',implemented:!0,hasTemplate:!1,requiresProject:!0,features:["v3 AI Agile replacement for ticket-style planning","Stores the durable brief in SQLite","Sub-verbs mirror spec for compatibility: list, show, update, audit, link-work, ship"]},{name:"work",group:"core",surface:"ai-agile",routing:{group:"workflow",method:"now"},optionSchema:{strings:["spec"],booleans:["extend"]},description:"Start or inspect an AI Agile work cycle with context and evidence",usage:{claude:'p. work "<intent>"',terminal:'prjct work "<intent>"'},params:"[intent]",implemented:!0,hasTemplate:!0,requiresProject:!0,features:["v3 name for the execution cycle formerly exposed as task","No arg \u2192 shows the active work cycle","Surfaces related context before planning/editing","Captures harness/evidence expectations for the cycle"]},{name:"init",group:"core",surface:"support",routing:{group:"planning",method:"init"},description:"Deep project analysis and initialization",usage:{claude:'p. init "[idea]"',terminal:'prjct init "[idea]"'},params:"[idea]",implemented:!0,hasTemplate:!0,requiresProject:!1,requiresLlm:!0,features:["Architect mode for blank projects","Auto tech stack recommendation","Analyzes existing codebases"]},{name:"task",group:"legacy",surface:"legacy",routing:{group:"workflow",method:"now"},optionSchema:{strings:["spec"],booleans:["extend"]},description:"Compatibility alias for `work`",usage:{claude:null,terminal:'prjct task "<description>"'},params:"[description]",implemented:!0,hasTemplate:!0,requiresProject:!0,features:["No arg \u2192 shows the active task (or none)","Deprecated public language: use `prjct work` for the v3 AI Agile cycle","Auto-harness classifies H0-H3 and stores expected evidence on the task","Writes to stateStorage; runs before/after workflow rules","Optional Linear issue link when the arg matches `[A-Z]+-\\d+`"]},{name:"ship",group:"core",surface:"ai-agile",routing:{group:"shipping",method:"ship"},optionSchema:{booleans:["skipHooks","noSpecGate","noTestGate"],strings:["intent"]},description:"Commit, push, and celebrate shipped feature",usage:{claude:'p. ship ["feature"]',terminal:'prjct ship ["feature"]'},params:"[feature]",implemented:!0,hasTemplate:!0,requiresProject:!0,requiresLlm:!0,features:["No arg \u2192 ships the active task description, or derives a summary from the branch"]},{name:"sync",group:"core",surface:"ai-agile",routing:{group:"analysis",method:"sync"},description:"Sync project state and update workflow agents",usage:{claude:"p. sync",terminal:"prjct sync [--package=<name>] [--full]"},implemented:!0,hasTemplate:!0,requiresProject:!0,requiresLlm:!0,features:["Incremental sync: only re-analyzes changed files (default)","Force full sync: --full bypasses incremental cache","Monorepo support: --package=<name> for single package sync","Nested PRJCT.md inheritance","Per-package CLAUDE.md generation"]},{name:"eval",group:"optional",surface:"support",routing:{group:"eval",method:"eval"},optionSchema:{booleans:["publish","dryRun","json"],strings:["baseline","candidate","source","target","file"]},description:"Run product evals, compare versions, and publish actionable results",usage:{claude:"p. eval run [--candidate <version>] [--publish]",terminal:"prjct eval <run|compare|report|publish> [--baseline <version>] [--candidate <version>] [--target cloud] [--dry-run]"},params:"[run|compare|report|publish]",implemented:!0,hasTemplate:!1,requiresProject:!1,requiresLlm:!1,features:["Deterministic local eval runs stored under PRJCT_CLI_HOME/evals","Version comparisons with regression/improvement actionables","Cloud publication for shared benchmark history with server-side ownership and subscription checks"]},{name:"status",group:"legacy",surface:"legacy",routing:{group:"primitives",method:"status"},optionSchema:{strings:["tokensIn","tokensOut"]},description:"Compatibility lifecycle escape hatch; prefer `work` outcomes",usage:{claude:null,terminal:"prjct status <value>"},params:"[value]",implemented:!0,hasTemplate:!1,requiresProject:!0,features:["No args \u2192 prints active task + current status","Workflows are the primary status-change mechanism; this is the escape"]},{name:"tag",group:"legacy",surface:"legacy",routing:{group:"primitives",method:"tag"},optionSchema:{},description:"Compatibility metadata escape hatch; prefer synthesized context tags",usage:{claude:null,terminal:"prjct tag type:bug domain:auth"},params:"<pairs...>",implemented:!0,hasTemplate:!1,requiresProject:!0,features:["Claude decides what to tag \u2014 no heuristic classifier","type:<feature|bug|improvement|chore> promotes to tasks.type"]},{name:"remember",group:"core",surface:"ai-agile",routing:{group:"primitives",method:"remember"},optionSchema:{strings:["tags"],booleans:["force","global"]},description:"Capture a project memory entry (fact, decision, learning, gotcha, \u2026)",usage:{claude:'p. remember learning "message"',terminal:'prjct remember learning "message" --tags domain:auth'},params:'<type> "<content>" [--tags k:v,...]',implemented:!0,hasTemplate:!1,requiresProject:!1,features:["Types: fact, decision, learning, gotcha, pattern, anti-pattern, shipped, inbox, todo, idea, insight, question, source, person \u2014 plus user-defined","Grows the project memory consumable via `prjct context memory`"]},{name:"forget",group:"core",surface:"ai-agile",routing:{group:"primitives",method:"forget"},optionSchema:{},description:"Delete a project memory entry by id (the delete half of `remember`)",usage:{claude:"p. forget mem_1234",terminal:"prjct forget mem_1234 [--md]"},params:"<id>",implemented:!0,hasTemplate:!1,requiresProject:!0,features:["Accepts `mem_1234`, `mem-1234`, or a bare `1234`","Hard-deletes the source event + drops the FTS mirror and any embedding \u2014 cannot resurface lexically or semantically"]},{name:"capture",group:"legacy",surface:"legacy",routing:{group:"capture",method:"capture"},optionSchema:{strings:["tags"],booleans:["force"]},description:"Compatibility inbox fallback; prefer synthesized `remember context`",usage:{claude:null,terminal:'prjct capture "call Ana re pricing" --tags domain:sales'},params:'"<content>" [--tags k:v,...]',implemented:!0,hasTemplate:!1,requiresProject:!0,features:["Writes memory type=inbox; Claude retypes later via a clarify workflow","No task id, no branch, no worktree \u2014 just persists",'Bare `prjct "<text>"` auto-routes to `capture`']},{name:"seed",group:"setup",surface:"support",routing:{group:"seed",method:"seed"},routingMode:"bin-only",optionSchema:{},description:"Manage declarative packs (persona, memory types, workflow slots, hook signals)",usage:{claude:"p. seed list",terminal:"prjct seed add pm,daily"},params:"[add|remove|list|suggest] [pack,pack,...]",implemented:!0,hasTemplate:!1,requiresProject:!0,features:["Packs declare signals only \u2014 no bash is written","Add or remove multi-persona contexts per project","Auto-detect suggestion from project stack"]},{name:"mcp",group:"setup",surface:"support",routing:{group:"mcp",method:"mcp"},routingMode:"bin-only",optionSchema:{},description:"Toggle MCP servers per-project \u2014 interactive multi-select in your terminal, list/deny/allow for scripts",usage:{claude:"p. mcp list",terminal:"prjct mcp"},params:"[list|status|deny|allow] [serverName]",implemented:!0,hasTemplate:!1,requiresProject:!1,features:["Interactive multi-select with live tool-cost delta (default UX in TTY)","Project-local \u2014 writes only to .claude/settings.local.json","Knows the well-known cloud MCPs from claude.ai (PostHog, Atlassian, etc.)","Headless list/deny/allow for LLM agents and scripts (--md flag)"]},{name:"install",group:"setup",surface:"support",routing:{group:"install",method:"install"},routingMode:"bin-only",optionSchema:{},description:"Install universal agent surfaces, Claude hooks, and Codex config",usage:{claude:"p. install",terminal:"prjct install"},params:"",implemented:!0,hasTemplate:!1,requiresProject:!1,features:["Inside a prjct project, refreshes AGENTS.md as the portable baseline","Writes Claude passive hooks: SessionStart, UserPromptSubmit, \u2026","Repairs detected Codex config.toml with prjct MCP and TUI status_line","Idempotent; existing non-prjct hooks stay intact","Audit agent support with `prjct agents doctor`"]},{name:"help",group:"setup",surface:"support",routingMode:"bin-only",description:"Contextual help and guidance",usage:{claude:"p. help [topic]",terminal:"prjct help [topic]"},params:"[topic]",implemented:!0,hasTemplate:!0,requiresProject:!1},{name:"analysis-save-llm",group:"optional",surface:"internal",routing:{group:"analysis",method:"saveLlmAnalysis"},description:"Persist analysis notes produced by an LLM run",usage:{claude:null,terminal:"prjct analysis-save-llm <file|text|json>"},params:"<file|text|json>",implemented:!0,hasTemplate:!1,requiresProject:!0,isOptional:!0},{name:"analyze",group:"legacy",surface:"legacy",routing:{group:"analysis",method:"analyze"},description:"Compatibility alias for sync analysis",usage:{claude:null,terminal:"prjct analyze"},implemented:!0,hasTemplate:!0,requiresProject:!0,isOptional:!0,requiresLlm:!0},{name:"lean",group:"optional",surface:"support",routing:{group:"lean",method:"lean"},optionSchema:{},description:"Anti-over-engineering: set intensity, review/audit/debt (read-only)",usage:{claude:"p. lean [review|audit|debt|off|lite|full|ultra]",terminal:"prjct lean [sub]"},params:"[review|audit|debt|off|lite|full|ultra]",implemented:!0,hasTemplate:!1,requiresProject:!0,isOptional:!0,features:["No arg \u2192 show active intensity mode + a one-screen summary","review/audit/debt are advisory \u2014 no gate, no source writes","off|lite|full|ultra sets the intensity (mirrors ponytail modes)"]},{name:"tdd",group:"optional",surface:"support",routing:{group:"tdd",method:"tdd"},optionSchema:{},description:"Test-Driven Development: set intensity, run the test command (check)",usage:{claude:"p. tdd [check|off|assist|strict]",terminal:"prjct tdd [sub]"},params:"[check|off|assist|strict]",implemented:!0,hasTemplate:!1,requiresProject:!0,isOptional:!0,features:["No arg \u2192 show mode + the auto-detected test command","off|assist|strict sets the intensity (opt-in, like lean)","check runs the detected test command now (red/green) \u2014 the real gate"]},{name:"sdd",group:"optional",surface:"support",routing:{group:"sdd",method:"sdd"},optionSchema:{},description:"Spec-Driven Development: gate the spec pipeline (off/advisory/strict)",usage:{claude:"p. sdd [off|advisory|strict]",terminal:"prjct sdd [sub]"},params:"[off|advisory|strict]",implemented:!0,hasTemplate:!1,requiresProject:!0,isOptional:!0,features:["No arg \u2192 show mode + the active task spec station (pipeline checklist)","off|advisory|strict sets the intensity (opt-in, like lean)","strict: every task needs a reviewed spec; ship blocks unspecced work"]},{name:"notify",group:"setup",surface:"support",routing:{group:"notify",method:"notify"},optionSchema:{},description:"Desktop notifications (default on): ping on Claude-waiting + subagent-finished",usage:{claude:"p. notify [on|off]",terminal:"prjct notify [on|off]"},params:"[on|off]",implemented:!0,hasTemplate:!1,requiresProject:!0,isOptional:!0,features:["Default ON \u2014 pings when Claude is waiting or a subagent finishes","No arg \u2192 show mode + what fires","off silences OS notifications (per-prompt work-state block stays)"]},{name:"agents",group:"setup",surface:"support",routing:{group:"agents",method:"agents"},optionSchema:{booleans:["fix"]},description:"Show the concrete compatibility matrix for AI coding agents",usage:{claude:"p. agents [doctor|doctor --fix]",terminal:"prjct agents [doctor|doctor --fix]"},params:"[doctor|status|list] [--fix]",implemented:!0,hasTemplate:!1,requiresProject:!1,isOptional:!0,features:["Derives support levels from the runtime registry","Reports AGENTS.md, MCP, skills, hooks, ACP, and project-rule support","doctor --fix refreshes repo-local agent surfaces when run inside a project",'Use this to audit claims like "works with Codex/Gemini/OpenCode/Cursor/Windsurf"']},{name:"value",group:"legacy",surface:"legacy",routing:{group:"product",method:"value"},optionSchema:{},description:"Compatibility alias for `insights value`",usage:{claude:null,terminal:"prjct value [--md]"},params:"",implemented:!0,hasTemplate:!1,requiresProject:!0,isOptional:!0,features:["Scores project continuity from real SQLite data","Counts durable memory, preventive guardrails, shipped work, sync metrics, and agent coverage","Designed as the paid-tier proof screen for humans and agents"]},{name:"memory-doctor",group:"legacy",surface:"legacy",routing:{group:"product",method:"memoryDoctor"},optionSchema:{},description:"Compatibility alias for `insights quality`",usage:{claude:null,terminal:"prjct memory-doctor [--md]"},params:"",implemented:!0,hasTemplate:!1,requiresProject:!0,isOptional:!0,features:["Finds duplicate groups, stale inbox entries, low-signal memories, and missing types","Read-only by default; recommends exact cleanup actions","Protects recall quality across Claude, Codex, Gemini, OpenCode, and future agents"]},{name:"report",group:"legacy",surface:"legacy",routing:{group:"product",method:"report"},optionSchema:{numbers:["days"]},description:"Compatibility alias for `insights report`",usage:{claude:null,terminal:"prjct report [days] [--md]"},params:"[days]",implemented:!0,hasTemplate:!1,requiresProject:!0,isOptional:!0,features:["Summarizes shipped features, completed tasks, active work, and carry-forward lessons","Uses real project state instead of a marketing changelog","Useful for founders, teams, and paid Cloud status emails"]},{name:"handoff",group:"legacy",surface:"legacy",routing:{group:"product",method:"handoff"},optionSchema:{},description:"Compatibility alias for `insights continue`",usage:{claude:null,terminal:"prjct handoff codex [--md]"},params:"[agent]",implemented:!0,hasTemplate:!1,requiresProject:!0,isOptional:!0,features:["Gives the next agent the active task, required prjct checks, and high-value memories","Works across Codex, Claude, Gemini, Cursor, OpenCode, Qwen, Kimi, and unknown future agents","Makes multi-agent continuity concrete instead of relying on private model memory"]},{name:"guardrails",group:"legacy",surface:"legacy",routing:{group:"product",method:"guardrails"},optionSchema:{},description:"Compatibility alias for `insights guardrails`",usage:{claude:null,terminal:"prjct guardrails [--md]"},params:"",implemented:!0,hasTemplate:!1,requiresProject:!0,isOptional:!0,features:["Checks changed files against preventive memory","Falls back to general project traps when no file-specific hit exists","Advisory only; no gate, no mutation"]},{name:"insights",group:"optional",surface:"ai-agile",routing:{group:"product",method:"insights"},optionSchema:{numbers:["days"]},description:"AI Agile intelligence: value, quality, reliability, token cost, reports, continuation, and guardrails",usage:{claude:"p. insights [value|quality|reliability|cost|report|continue|guardrails]",terminal:"prjct insights [value|quality|reliability|cost|report|continue|guardrails] [--md]"},params:"[value|quality|reliability|cost|report|continue|guardrails] [agent|days]",implemented:!0,hasTemplate:!1,requiresProject:!0,isOptional:!0,features:["v3 surface for project intelligence formerly spread across value/report/handoff/memory-doctor/guardrails","Default view summarizes whether the project is compounding","reliability/trust shows whether value, cost, and performance metrics are decision-ready","cost/spend/tokens shows subscription burn, token coverage, context reuse, and capture gaps","Subcommands remain read-only except where underlying compatibility commands already mutate nothing"]},{name:"performance",group:"optional",surface:"ai-agile",routing:{group:"product",method:"performance"},optionSchema:{numbers:["days"]},description:"Measure dev+LLM efficiency per work cycle: time, tokens, model/runtime, tools, friction",usage:{claude:"p. performance [7]",terminal:"prjct performance [days] [--md]"},params:"[days]",implemented:!0,hasTemplate:!1,requiresProject:!0,isOptional:!0,features:["Uses real task/session rows and available token columns","Stores unknown when a runtime does not expose exact model/token data","Designed to guide the next work cycle, not to create scrum velocity reports"]},{name:"cloud",group:"setup",surface:"support",routing:{group:"cloud",method:"cloud"},optionSchema:{},description:"Cloud sync (paid): link/unlink a project, sync/pull, pause/resume, status",usage:{claude:"p. cloud [link|unlink|sync|pull|pause|resume|status]",terminal:"prjct cloud [sub]"},params:"[link|unlink|sync|pull|pause|resume|status]",implemented:!0,hasTemplate:!1,requiresProject:!0,isOptional:!0,features:["Local-first: nothing leaves the machine until `prjct cloud link`","Token API only \u2014 no backend engine details, no client-side paywall","Auto-syncs on `prjct ship` and at session end once linked"]},{name:"workflow",group:"optional",surface:"support",routing:{group:"workflow",method:"workflow"},optionSchema:{},description:"Configure workflow hooks via natural language",usage:{claude:'p. workflow ["config"]',terminal:'prjct workflow ["config"]'},params:'["natural language config"]',implemented:!0,hasTemplate:!0,requiresProject:!0,isOptional:!0,requiresLlm:!0,features:["Natural language configuration","Before/after hooks for task, done, ship, sync","Permanent, session, or one-time preferences"]},{name:"start",group:"setup",surface:"support",routing:{group:"setup",method:"start"},routingMode:"bin-only",description:"First-time setup (install commands to editors)",usage:{claude:null,terminal:"prjct start"},implemented:!0,hasTemplate:!1,requiresProject:!1},{name:"setup",group:"setup",surface:"support",routing:{group:"setup",method:"setup"},routingMode:"bin-only",description:"Reconfigure editor installations and user-owned defaults",usage:{claude:"p. setup",terminal:"prjct setup"},params:"[--force] [--non-interactive]",implemented:!0,hasTemplate:!0,requiresProject:!1},{name:"login",group:"setup",surface:"support",routing:{group:"setup",method:"login"},description:"Authenticate with prjct cloud (opens browser)",usage:{claude:null,terminal:"prjct login"},params:"",implemented:!0,hasTemplate:!1,requiresProject:!1,routingMode:"bin-only"},{name:"logout",group:"setup",surface:"support",routing:{group:"setup",method:"logout"},description:"Sign out from prjct cloud",usage:{claude:null,terminal:"prjct logout"},implemented:!0,hasTemplate:!1,requiresProject:!1,routingMode:"bin-only"},{name:"auth",group:"setup",surface:"support",routing:{group:"setup",method:"auth"},description:"Manage cloud authentication",usage:{claude:"p. auth [action]",terminal:"prjct auth [action]"},params:"[logout|status]",implemented:!0,hasTemplate:!1,requiresProject:!1,routingMode:"bin-only"},{name:"context",group:"setup",surface:"support",routing:{group:"context",method:"context"},routingMode:"bin-only",optionSchema:{},description:"Smart context filtering tools for AI agents",usage:{claude:null,terminal:"prjct context <tool> [args]"},params:"<tool> [args]",implemented:!0,hasTemplate:!1,requiresProject:!0,features:["files - Find relevant files for a task","signatures - Extract code structure (~90% compression)","imports - Analyze dependency graphs","recent - Find hot files from git history","summary - Intelligent file summarization"]},{name:"search",group:"core",surface:"ai-agile",routing:{group:"context",method:"search"},optionSchema:{booleans:["global"]},description:"Search project memory (decisions, learnings, gotchas, ships\u2026) \u2014 BM25 + semantic + recall",usage:{claude:'p. search "<query>"',terminal:'prjct search "<query>" [--md]'},params:"<query>",implemented:!0,hasTemplate:!1,requiresProject:!1,features:["Blended retrieval: FTS5 BM25 + opt-in semantic + recency recall","Reranks by proven usefulness, expands one hop of the memory graph","`prjct search mem_1234` resolves a specific entry by id"]},{name:"update",group:"setup",surface:"support",routing:{group:"update",method:"update"},routingMode:"bin-only",description:"Update prjct system-wide: package + migrations + daemon restart",usage:{claude:null,terminal:"prjct update [--dry-run]"},params:"[--dry-run]",implemented:!0,hasTemplate:!1,requiresProject:!1,features:["Phase 1: npm update (migrates homebrew \u2192 npm if needed)","Phase 2: All projects \u2014 migrate, sweep, reinstall commands","Phase 3: Daemon stop + restart with new code","--dry-run to preview without changes"]},{name:"uninstall",group:"setup",surface:"support",routing:{group:"uninstall",method:"uninstall"},routingMode:"bin-only",description:"Complete system removal of prjct",usage:{claude:null,terminal:"prjct uninstall"},params:"[--force] [--backup] [--dry-run]",implemented:!0,hasTemplate:!1,requiresProject:!1,features:["Removes ~/.prjct-cli/ data","Cleans CLAUDE.md prjct section","Uninstalls Homebrew/npm packages","Backup option before deletion"]},{name:"team",group:"setup",surface:"support",routing:{group:"team",method:"team"},optionSchema:{booleans:["required","enforce"],strings:["minVersion"]},description:"Enroll this repo in prjct team mode \u2014 commits .prjct/team.json + .claude/CLAUDE.md so teammates pick up shared expectations",usage:{claude:"p. team",terminal:"prjct team [--required] [--min-version <semver>]"},params:"[--required] [--min-version <semver>]",implemented:!0,hasTemplate:!1,requiresProject:!0,features:["Writes .prjct/team.json with required/minVersion config","Adds prjct context block to .claude/CLAUDE.md (per-project)","Stages both files for the next commit (does NOT commit)","Teammates clone repo + install prjct \u2192 ready to go"]},{name:"embeddings",group:"setup",surface:"support",routing:{group:"embeddings",method:"embeddings"},optionSchema:{strings:["key","model","baseUrl","authHeader","authScheme","headers","query"]},description:"Configure the GLOBAL semantic-embeddings provider (BYOT) \u2014 one API key, stored securely, used by every project.",usage:{claude:"p. embeddings status",terminal:'prjct embeddings <set|status|test|clear> [--key <K>] [--model <M>] [--base-url <U>] [--auth-header <H>] [--auth-scheme <S|none>] [--headers "k=v,..."] [--query <qs>]'},params:"[set|status|test|clear]",implemented:!0,hasTemplate:!1,requiresProject:!1,features:["BYOT: bring your own embedding API key \u2014 ANY OpenAI-compatible provider","Zero-config: paste just --key, the base URL is auto-detected from its prefix","OpenAI, OpenRouter, Ollama, Together, Mistral, Voyage, Jina, LM Studio\u2026",'Non-Bearer providers too: --auth-header api-key --auth-scheme none --query "api-version=..." (Azure OpenAI)',"Key stored in the macOS Keychain (else a 0600 file), never in config","Global \u2014 applies to all projects; per-project config still overrides","Without a key, recall uses the always-on local subword embedder","Validate with: prjct embeddings test"]},{name:"changelog",group:"changelog",surface:"ai-agile",requiresProject:!0,implemented:!0,hasTemplate:!1,routing:{group:"changelog",method:"changelog"},optionSchema:{},description:"Release notes from the typed delivery record: what shipped (by version) + completed work cycles in the window. Zero LLM \u2014 pure data-plane render.",usage:{claude:"p. changelog 14",terminal:"prjct changelog [days]"}},{name:"workflows",group:"workflowsReference",surface:"ai-agile",requiresProject:!1,implemented:!0,hasTemplate:!1,routing:{group:"workflowsReference",method:"workflows"},optionSchema:{},description:"Print the quality methodology reference (subagent dispatch, model policy, review/judgment/security workflows) \u2014 the rig-agnostic pull of what Claude reads as workflows.md.",usage:{claude:"p. workflows",terminal:"prjct workflows --md"}},{name:"memory",group:"memoryExport",surface:"ai-agile",requiresProject:!0,implemented:!0,hasTemplate:!1,routing:{group:"memoryExport",method:"memory"},optionSchema:{},description:"Git-shareable project memory: `export` writes chunked JSONL to .prjct/memory-export/ (commit it); `import` replays a committed export with content-hash dedup \u2014 zero-server team onboarding.",usage:{claude:"p. memory export",terminal:"prjct memory export | prjct memory import"}},{name:"guard",group:"core",surface:"ai-agile",routing:{group:"guard",method:"guard"},optionSchema:{numbers:["limit"],strings:["diff"],booleans:["strict"]},description:"Surface preventive memory (gotchas, anti-patterns, recurring-bugs) recorded against a file BEFORE you edit it \u2014 anticipation, provider-agnostic.",usage:{claude:"p. guard <file>",terminal:"prjct guard <file> | prjct guard --diff <range> [--strict]"},params:"[file]",implemented:!0,hasTemplate:!1,requiresProject:!0,features:["Pillar 3 (anticipation): see the trap before you step in it","Pull, not push \u2014 also exposed as the prjct_guard MCP tool for Claude + Codex","Strict: only gotchas / anti-patterns / recurring-bugs \u2014 never plain decisions, so no noise",'Quiet by design: "clear to edit" when nothing preventive matches',"Matches absolute or repo-relative paths by exact / suffix / basename"]},{name:"config",group:"setup",surface:"support",routing:{group:"config",method:"config"},optionSchema:{},description:"Read/write global prjct config \u2014 auto-update opt-in, suggestions toggle, etc.",usage:{claude:"p. config list",terminal:"prjct config <list|get|set|unset> [key] [value]"},params:"<list|get|set|unset> [key] [value]",implemented:!0,hasTemplate:!1,requiresProject:!1,features:["Stored at ~/.prjct-cli/config/global.json","Opt into silent auto-update: prjct config set auto-update on","Toggle proactive suggestions: prjct config set suggestions off","Booleans accept on/off/true/false; numbers parsed automatically"]},{name:"spec",group:"legacy",surface:"legacy",routing:{group:"spec",method:"draft"},routingMode:"cold-only",description:"Compatibility alias for `intent` \u2014 Goal/Acceptance/Scope/Risks before work starts.",usage:{claude:null,terminal:'prjct spec "<title>" [--goal "..."] [--tags k:v,...]'},params:'"<title>" [--goal] [--tags]',implemented:!0,hasTemplate:!1,requiresProject:!0,features:['Drafting: `prjct spec "<title>"` IS the create action \u2014 there is no `draft` subverb (aliases `draft`/`new`/`create` are tolerated and stripped)',"Persists in `specs` SQLite table + memory event stream","Sub-verbs: list, show, update, set-status, record-review, link-task, ship, audit, inventory"]},{name:"audit-spec",group:"legacy",surface:"legacy",routing:{group:"spec",method:"audit"},routingMode:"cold-only",description:"Compatibility alias for `intent audit <id>`",usage:{claude:null,terminal:"prjct audit-spec <id>"},params:"<spec-id>",implemented:!0,hasTemplate:!1,requiresProject:!0,features:["Emits dispatch prompt \u2014 Claude runs three Agent calls in parallel","Each reviewer writes back via `prjct spec record-review`","All three pass \u2192 spec auto-promotes draft \u2192 reviewed"]},...[["daemon","Run the prjct daemon in the foreground"],["stop","Stop the running prjct daemon"],["restart","Restart the prjct daemon"],["upgrade","Alias of `prjct update`",{group:"update",method:"update"}],["hook","Run a Claude Code hook event (internal; called by the hook scripts)"],["hooks","Inspect or reinstall the Claude Code hooks"],["claude","Claude Code integration management (install/uninstall)"],["crew","Run a crew (multi-subagent) workflow"],["doctor","Diagnose the local prjct installation"],["watch","Watch project files and react to changes"],["version","Print the installed prjct version + provider status"],["prefs","Inspect or set workflow preferences"],["retro","Summarize what shipped over a time window"],["health","Codebase health snapshot"],["skill-adherence","Report how well sessions follow the prjct skill"],["review-risk","Risk-ranked review hints for the working tree"],["context-save","Save the current working context for later restore"],["context-restore","Restore a previously saved working context"]].map(([n,e,t])=>({name:n,group:"setup",description:e,routing:t,usage:{claude:null,terminal:`prjct ${n}`},implemented:!0,hasTemplate:!1,requiresProject:!1,routingMode:"bin-only"}))],TI={"-h":"help","--help":"help","-v":"version","--version":"version"},SI=new Set([...cs.filter(n=>n.routingMode==="bin-only").map(n=>n.name),...Object.entries(TI).filter(([,n])=>cs.some(e=>e.name===n&&e.routingMode==="bin-only")).map(([n])=>n)])});var tE,nE=h(()=>{"use strict";id();tE=new Set(cs.filter(n=>n.routing).map(n=>n.name))});function bI(n){return n instanceof ls}function Xe(n){return bI(n)||n instanceof Error?n.message:typeof n=="string"?n:"Unknown error"}var ls,ha,ya,ki,fn=h(()=>{"use strict";ls=class extends Error{static{a(this,"PrjctError")}code;isOperational;constructor(e,t="PRJCT_ERROR"){super(e),this.name="PrjctError",this.code=t,this.isOperational=!0,Error.captureStackTrace?.(this,this.constructor)}},ha=class n extends ls{static{a(this,"ProjectError")}constructor(e,t="PROJECT_ERROR"){super(e,t),this.name="ProjectError"}static notInitialized(){return new n("Project not initialized. Run p. init first.","PROJECT_NOT_INIT")}static notFound(e){return new n(`Project not found: ${e}`,"PROJECT_NOT_FOUND")}static invalidId(e){return new n(`Invalid project ID: ${e}`,"PROJECT_INVALID_ID")}},ya=class n extends ls{static{a(this,"TemplateError")}constructor(e,t="TEMPLATE_ERROR"){super(e,t),this.name="TemplateError"}static notFound(e){return new n(`Template not found: ${e}.md`,"TEMPLATE_NOT_FOUND")}static parseFailed(e){return new n(`Failed to parse template: ${e}`,"TEMPLATE_PARSE_ERROR")}},ki=class n extends ls{static{a(this,"AgentError")}constructor(e,t="AGENT_ERROR"){super(e,t),this.name="AgentError"}static notSupported(e){return new n(`Unsupported agent type: ${e}`,"AGENT_NOT_SUPPORTED")}static initFailed(e){return new n(`Agent initialization failed: ${e}`,"AGENT_INIT_FAILED")}};a(bI,"isPrjctError");a(Xe,"getErrorMessage")});function rE(n){let e=n.toLowerCase();return e.includes("github")?"github":e.includes("gitlab")?"gitlab":e.includes("bitbucket")?"bitbucket":"other"}function od(n){let e=n.trim();if(!e)return{};let t=e.match(/^[^/@]+@([^:/]+):(.+?)(?:\.git)?\/?$/);if(t)return{provider:rE(t[1]),repoSlug:t[2]};try{let r=new URL(e),s=r.pathname.replace(/^\/+/,"").replace(/\.git$/,"").replace(/\/+$/,"");return!r.host||!s?{}:{provider:rE(r.host),repoSlug:s}}catch{return{}}}async function vI(n){try{let{stdout:e}=await B("git",["remote","get-url","origin"],{cwd:n});return e.trim()||void 0}catch{return}}async function RI(n){try{let{stdout:e}=await B("git",["symbolic-ref","--short","refs/remotes/origin/HEAD"],{cwd:n});return e.trim().replace(/^origin\//,"")||void 0}catch{return}}function Tr(n){return typeof n=="string"&&n.length>0?n:void 0}function sE(n){return typeof n=="number"&&Number.isFinite(n)?n:void 0}function CI(n){return Object.fromEntries(Object.entries(n).filter(([,e])=>e!==void 0))}async function wa(n){let e=E.getDoc(n,"project")||{},t=Tr(e.repoPath),{provider:r,repoSlug:s}=t?od(await vI(t)||""):{},i=t?await RI(t):void 0,o=Array.isArray(e.techStack)?e.techStack.filter(c=>typeof c=="string"):void 0;return CI({provider:r,repoSlug:s,currentBranch:Tr(e.currentBranch),defaultBranch:i,stack:Tr(e.stack),techStack:o&&o.length>0?o:void 0,version:Tr(e.version),commitCount:sE(e.commitCount),fileCount:sE(e.fileCount),lastCommit:Tr(e.lastSyncCommit),hasUncommitted:typeof e.hasUncommittedChanges=="boolean"?e.hasUncommittedChanges:void 0,cliVersion:Tr(e.cliVersion),syncedAt:Tr(e.lastSync)})}var Ea=h(()=>{"use strict";$();ie();a(rE,"providerForHost");a(od,"parseRemote");a(vI,"gitRemoteUrl");a(RI,"gitDefaultBranch");a(Tr,"str");a(sE,"num");a(CI,"compact");a(wa,"buildProjectMeta")});import{execFile as _I}from"node:child_process";import AI from"node:crypto";import{promisify as xI}from"node:util";function PI(n,e=II){let t=Buffer.from(e.replace(/-/g,""),"hex"),s=AI.createHash("sha1").update(t).update(n,"utf8").digest().subarray(0,16);s[6]=s[6]&15|80,s[8]=s[8]&63|128;let i=s.toString("hex");return`${i.slice(0,8)}-${i.slice(8,12)}-${i.slice(12,16)}-${i.slice(16,20)}-${i.slice(20,32)}`}async function DI(n){let e;try{let{stdout:s}=await NI("git",["remote","get-url","origin"],{cwd:n});e=s.trim()||void 0}catch{return null}if(!e)return null;let{provider:t,repoSlug:r}=od(e);return!t||!r?null:`${t}:${r}`.toLowerCase()}async function iE(n){let e=await DI(n);return e?PI(e):null}var NI,II,oE=h(()=>{"use strict";Ea();NI=xI(_I),II="6f9b2c1a-3d4e-5f60-8a7b-1c2d3e4f5a6b";a(PI,"uuidv5");a(DI,"repoKey");a(iE,"deriveProjectId")});var ud={};O(ud,{PACKAGE_ROOT:()=>hn,VERSION:()=>je,getPackageRoot:()=>cd,getVersion:()=>br,resetPackageRoot:()=>ld});import ad from"node:fs";import ka from"node:path";function cd(){if(us)return us;let n=__dirname;for(let e=0;e<5;e++){let t=ka.join(n,"package.json");if(ad.existsSync(t))try{if(JSON.parse(ad.readFileSync(t,"utf-8")).name==="prjct-cli")return us=n,n}catch{}n=ka.dirname(n)}return us=ka.join(__dirname,"..","..",".."),us}function br(){if(Sr)return Sr;let n="3.24.0";if(n&&/^\d+\.\d+\.\d+/.test(n))return Sr=n,Sr;try{let e=ka.join(cd(),"package.json");return Sr=JSON.parse(ad.readFileSync(e,"utf-8")).version,Sr}catch(e){return process.env.PRJCT_DEBUG==="1"&&console.error("Failed to read version from package.json:",y(e)),"0.0.0"}}function ld(n){us=n,Sr=null}var Sr,us,je,hn,ct=h(()=>{"use strict";G();Sr=null,us=null;a(cd,"getPackageRoot");a(br,"getVersion");a(ld,"resetPackageRoot");je=br(),hn=cd()});async function Ta(n){try{let{stdout:e}=await U(n,{timeout:5e3});return{success:!0,output:e.trim()}}catch{return{success:!1,output:""}}}async function OI(){let n=await Ta("gh api user --jq .login");return n.success&&n.output||(n=await Ta("git config --global github.user"),n.success&&n.output)?n.output:null}async function jI(){let n=await Ta("git config user.name");return n.success&&n.output?n.output:null}async function MI(){let n=await Ta("git config user.email");return n.success&&n.output?n.output:null}async function ds(){let[n,e,t]=await Promise.all([OI(),jI(),MI()]);return{github:n,email:t,name:e||n||"Unknown"}}var Sa=h(()=>{"use strict";ie();a(Ta,"execCommand");a(OI,"detectGitHubUsername");a(jI,"detectGitName");a(MI,"detectGitEmail");a(ds,"detect")});var gd={};O(gd,{worktreeService:()=>LI});import pd from"node:fs/promises";import Zt from"node:path";var aE,md,LI,fd=h(()=>{"use strict";ie();Q();aE=".worktrees",md=class{static{a(this,"WorktreeService")}async create(e,t,r={}){let s=await this.getMainWorktree(e),i=Zt.join(s,aE,t),o=r.branch||`feat/${t}`;await pd.mkdir(Zt.join(s,aE),{recursive:!0});let c=r.baseBranch?` ${r.baseBranch}`:"";await U(`git worktree add "${i}" -b "${o}"${c}`,{cwd:s});let{stdout:l}=await U("git rev-parse HEAD",{cwd:i});return{path:i,branch:o,commit:l.trim(),isMain:!1,slug:t}}async remove(e,t=!1){let r=await this.getMainWorktree(e),s;if(t)try{let{stdout:i}=await U("git rev-parse --abbrev-ref HEAD",{cwd:e});s=i.trim()}catch{}if(await U(`git worktree remove "${e}" --force`,{cwd:r}),t&&s&&s!=="main"&&s!=="master")try{await U(`git branch -D "${s}"`,{cwd:r})}catch{}}async list(e){let t=await this.getMainWorktree(e),{stdout:r}=await U("git worktree list --porcelain",{cwd:t});return this.parsePorcelainOutput(r,t)}async detect(e){try{let{stdout:t}=await U("git rev-parse --git-common-dir",{cwd:e}),{stdout:r}=await U("git rev-parse --git-dir",{cwd:e}),s=Zt.resolve(e,t.trim()),i=Zt.resolve(e,r.trim());if(s!==i){let{stdout:o}=await U("git rev-parse --abbrev-ref HEAD",{cwd:e}),{stdout:c}=await U("git rev-parse HEAD",{cwd:e}),{stdout:l}=await U("git rev-parse --show-toplevel",{cwd:e}),u=l.trim(),d=Zt.basename(u);return{path:u,branch:o.trim(),commit:c.trim(),isMain:!1,slug:d}}return null}catch{return null}}async getMainWorktree(e){try{let{stdout:r}=await U("git worktree list --porcelain",{cwd:e}),s=r.split(`
1321
+ `)}var Hn=h(()=>{"use strict";Qe();nd();sd();a(Qw,"labelFor");a(gn,"collectActiveTasks");a(Zw,"formatActiveTaskLine");a(kI,"formatActiveTaskList")});var eE,cs,TI,SI,id=h(()=>{"use strict";eE={core:{title:"AI Agile Loop",description:"Intent, context, execution, learning, and improvement",order:1},optional:{title:"Intelligence & Quality",description:"Project intelligence, quality proof, and advanced policies",order:2},setup:{title:"Setup & Infrastructure",description:"Installation, configuration, and integration plumbing",order:3},legacy:{title:"Compatibility",description:"v2 aliases kept for existing users and scripts",order:4}},cs=[{name:"intent",group:"core",surface:"ai-agile",routing:{group:"spec",method:"draft"},routingMode:"cold-only",optionSchema:{strings:["goal","tags"]},description:"Frame the work brief: objective, constraints, risks, and success signal",usage:{claude:'p. intent "<title>"',terminal:'prjct intent "<title>" [--goal "..."] [--tags k:v,...]'},params:'"<title>" [--goal] [--tags]',implemented:!0,hasTemplate:!1,requiresProject:!0,features:["v3 AI Agile replacement for ticket-style planning","Stores the durable brief in SQLite","Sub-verbs mirror spec for compatibility: list, show, update, audit, link-work, ship"]},{name:"work",group:"core",surface:"ai-agile",routing:{group:"workflow",method:"now"},optionSchema:{strings:["spec"],booleans:["extend"]},description:"Start or inspect an AI Agile work cycle with context and evidence",usage:{claude:'p. work "<intent>"',terminal:'prjct work "<intent>"'},params:"[intent]",implemented:!0,hasTemplate:!0,requiresProject:!0,features:["v3 name for the execution cycle formerly exposed as task","No arg \u2192 shows the active work cycle","Surfaces related context before planning/editing","Captures harness/evidence expectations for the cycle"]},{name:"init",group:"core",surface:"support",routing:{group:"planning",method:"init"},description:"Deep project analysis and initialization",usage:{claude:'p. init "[idea]"',terminal:'prjct init "[idea]"'},params:"[idea]",implemented:!0,hasTemplate:!0,requiresProject:!1,requiresLlm:!0,features:["Architect mode for blank projects","Auto tech stack recommendation","Analyzes existing codebases"]},{name:"task",group:"legacy",surface:"legacy",routing:{group:"workflow",method:"now"},optionSchema:{strings:["spec"],booleans:["extend"]},description:"Compatibility alias for `work`",usage:{claude:null,terminal:'prjct task "<description>"'},params:"[description]",implemented:!0,hasTemplate:!0,requiresProject:!0,features:["No arg \u2192 shows the active task (or none)","Deprecated public language: use `prjct work` for the v3 AI Agile cycle","Auto-harness classifies H0-H3 and stores expected evidence on the task","Writes to stateStorage; runs before/after workflow rules","Optional Linear issue link when the arg matches `[A-Z]+-\\d+`"]},{name:"ship",group:"core",surface:"ai-agile",routing:{group:"shipping",method:"ship"},optionSchema:{booleans:["skipHooks","noSpecGate","noTestGate"],strings:["intent"]},description:"Commit, push, and celebrate shipped feature",usage:{claude:'p. ship ["feature"]',terminal:'prjct ship ["feature"]'},params:"[feature]",implemented:!0,hasTemplate:!0,requiresProject:!0,requiresLlm:!0,features:["No arg \u2192 ships the active task description, or derives a summary from the branch"]},{name:"sync",group:"core",surface:"ai-agile",routing:{group:"analysis",method:"sync"},description:"Sync project state and update workflow agents",usage:{claude:"p. sync",terminal:"prjct sync [--package=<name>] [--full]"},implemented:!0,hasTemplate:!0,requiresProject:!0,requiresLlm:!0,features:["Incremental sync: only re-analyzes changed files (default)","Force full sync: --full bypasses incremental cache","Monorepo support: --package=<name> for single package sync","Nested PRJCT.md inheritance","Per-package CLAUDE.md generation"]},{name:"eval",group:"optional",surface:"support",routing:{group:"eval",method:"eval"},optionSchema:{booleans:["publish","dryRun","json"],strings:["baseline","candidate","source","target","file"]},description:"Run product evals, compare versions, and publish actionable results",usage:{claude:"p. eval run [--candidate <version>] [--publish]",terminal:"prjct eval <run|compare|report|publish> [--baseline <version>] [--candidate <version>] [--target cloud] [--dry-run]"},params:"[run|compare|report|publish]",implemented:!0,hasTemplate:!1,requiresProject:!1,requiresLlm:!1,features:["Deterministic local eval runs stored under PRJCT_CLI_HOME/evals","Version comparisons with regression/improvement actionables","Cloud publication for shared benchmark history with server-side ownership and subscription checks"]},{name:"status",group:"legacy",surface:"legacy",routing:{group:"primitives",method:"status"},optionSchema:{strings:["tokensIn","tokensOut"]},description:"Compatibility lifecycle escape hatch; prefer `work` outcomes",usage:{claude:null,terminal:"prjct status <value>"},params:"[value]",implemented:!0,hasTemplate:!1,requiresProject:!0,features:["No args \u2192 prints active task + current status","Workflows are the primary status-change mechanism; this is the escape"]},{name:"tag",group:"legacy",surface:"legacy",routing:{group:"primitives",method:"tag"},optionSchema:{},description:"Compatibility metadata escape hatch; prefer synthesized context tags",usage:{claude:null,terminal:"prjct tag type:bug domain:auth"},params:"<pairs...>",implemented:!0,hasTemplate:!1,requiresProject:!0,features:["Claude decides what to tag \u2014 no heuristic classifier","type:<feature|bug|improvement|chore> promotes to tasks.type"]},{name:"remember",group:"core",surface:"ai-agile",routing:{group:"primitives",method:"remember"},optionSchema:{strings:["tags"],booleans:["force","global"]},description:"Capture a project memory entry (fact, decision, learning, gotcha, \u2026)",usage:{claude:'p. remember learning "message"',terminal:'prjct remember learning "message" --tags domain:auth'},params:'<type> "<content>" [--tags k:v,...]',implemented:!0,hasTemplate:!1,requiresProject:!1,features:["Types: fact, decision, learning, gotcha, pattern, anti-pattern, shipped, inbox, todo, idea, insight, question, source, person \u2014 plus user-defined","Grows the project memory consumable via `prjct context memory`"]},{name:"forget",group:"core",surface:"ai-agile",routing:{group:"primitives",method:"forget"},optionSchema:{},description:"Delete a project memory entry by id (the delete half of `remember`)",usage:{claude:"p. forget mem_1234",terminal:"prjct forget mem_1234 [--md]"},params:"<id>",implemented:!0,hasTemplate:!1,requiresProject:!0,features:["Accepts `mem_1234`, `mem-1234`, or a bare `1234`","Hard-deletes the source event + drops the FTS mirror and any embedding \u2014 cannot resurface lexically or semantically"]},{name:"capture",group:"legacy",surface:"legacy",routing:{group:"capture",method:"capture"},optionSchema:{strings:["tags"],booleans:["force"]},description:"Compatibility inbox fallback; prefer synthesized `remember context`",usage:{claude:null,terminal:'prjct capture "call Ana re pricing" --tags domain:sales'},params:'"<content>" [--tags k:v,...]',implemented:!0,hasTemplate:!1,requiresProject:!0,features:["Writes memory type=inbox; Claude retypes later via a clarify workflow","No task id, no branch, no worktree \u2014 just persists",'Bare `prjct "<text>"` auto-routes to `capture`']},{name:"seed",group:"setup",surface:"support",routing:{group:"seed",method:"seed"},routingMode:"bin-only",optionSchema:{},description:"Manage declarative packs (persona, memory types, workflow slots, hook signals)",usage:{claude:"p. seed list",terminal:"prjct seed add pm,daily"},params:"[add|remove|list|suggest] [pack,pack,...]",implemented:!0,hasTemplate:!1,requiresProject:!0,features:["Packs declare signals only \u2014 no bash is written","Add or remove multi-persona contexts per project","Auto-detect suggestion from project stack"]},{name:"mcp",group:"setup",surface:"support",routing:{group:"mcp",method:"mcp"},routingMode:"bin-only",optionSchema:{},description:"Toggle MCP servers per-project \u2014 interactive multi-select in your terminal, list/deny/allow for scripts",usage:{claude:"p. mcp list",terminal:"prjct mcp"},params:"[list|status|deny|allow] [serverName]",implemented:!0,hasTemplate:!1,requiresProject:!1,features:["Interactive multi-select with live tool-cost delta (default UX in TTY)","Project-local \u2014 writes only to .claude/settings.local.json","Knows the well-known cloud MCPs from claude.ai (PostHog, Atlassian, etc.)","Headless list/deny/allow for LLM agents and scripts (--md flag)"]},{name:"install",group:"setup",surface:"support",routing:{group:"install",method:"install"},routingMode:"bin-only",optionSchema:{},description:"Install universal agent surfaces, Claude hooks, and Codex config",usage:{claude:"p. install",terminal:"prjct install"},params:"",implemented:!0,hasTemplate:!1,requiresProject:!1,features:["Inside a prjct project, refreshes AGENTS.md as the portable baseline","Writes Claude passive hooks: SessionStart, UserPromptSubmit, \u2026","Repairs detected Codex config.toml with prjct MCP and TUI status_line","Idempotent; existing non-prjct hooks stay intact","Audit agent support with `prjct agents doctor`"]},{name:"help",group:"setup",surface:"support",routingMode:"bin-only",description:"Contextual help and guidance",usage:{claude:"p. help [topic]",terminal:"prjct help [topic]"},params:"[topic]",implemented:!0,hasTemplate:!0,requiresProject:!1},{name:"analysis-save-llm",group:"optional",surface:"internal",routing:{group:"analysis",method:"saveLlmAnalysis"},description:"Persist analysis notes produced by an LLM run",usage:{claude:null,terminal:"prjct analysis-save-llm <file|text|json>"},params:"<file|text|json>",implemented:!0,hasTemplate:!1,requiresProject:!0,isOptional:!0},{name:"analyze",group:"legacy",surface:"legacy",routing:{group:"analysis",method:"analyze"},description:"Compatibility alias for sync analysis",usage:{claude:null,terminal:"prjct analyze"},implemented:!0,hasTemplate:!0,requiresProject:!0,isOptional:!0,requiresLlm:!0},{name:"lean",group:"optional",surface:"support",routing:{group:"lean",method:"lean"},optionSchema:{},description:"Anti-over-engineering: set intensity, review/audit/debt (read-only)",usage:{claude:"p. lean [review|audit|debt|off|lite|full|ultra]",terminal:"prjct lean [sub]"},params:"[review|audit|debt|off|lite|full|ultra]",implemented:!0,hasTemplate:!1,requiresProject:!0,isOptional:!0,features:["No arg \u2192 show active intensity mode + a one-screen summary","review/audit/debt are advisory \u2014 no gate, no source writes","off|lite|full|ultra sets the intensity (mirrors ponytail modes)"]},{name:"tdd",group:"optional",surface:"support",routing:{group:"tdd",method:"tdd"},optionSchema:{},description:"Test-Driven Development: set intensity, run the test command (check)",usage:{claude:"p. tdd [check|off|assist|strict]",terminal:"prjct tdd [sub]"},params:"[check|off|assist|strict]",implemented:!0,hasTemplate:!1,requiresProject:!0,isOptional:!0,features:["No arg \u2192 show mode + the auto-detected test command","off|assist|strict sets the intensity (opt-in, like lean)","check runs the detected test command now (red/green) \u2014 the real gate"]},{name:"sdd",group:"optional",surface:"support",routing:{group:"sdd",method:"sdd"},optionSchema:{},description:"Spec-Driven Development: gate the spec pipeline (off/advisory/strict)",usage:{claude:"p. sdd [off|advisory|strict]",terminal:"prjct sdd [sub]"},params:"[off|advisory|strict]",implemented:!0,hasTemplate:!1,requiresProject:!0,isOptional:!0,features:["No arg \u2192 show mode + the active task spec station (pipeline checklist)","off|advisory|strict sets the intensity (opt-in, like lean)","strict: every task needs a reviewed spec; ship blocks unspecced work"]},{name:"notify",group:"setup",surface:"support",routing:{group:"notify",method:"notify"},optionSchema:{},description:"Desktop notifications (default on): ping on Claude-waiting + subagent-finished",usage:{claude:"p. notify [on|off]",terminal:"prjct notify [on|off]"},params:"[on|off]",implemented:!0,hasTemplate:!1,requiresProject:!0,isOptional:!0,features:["Default ON \u2014 pings when Claude is waiting or a subagent finishes","No arg \u2192 show mode + what fires","off silences OS notifications (per-prompt work-state block stays)"]},{name:"agents",group:"setup",surface:"support",routing:{group:"agents",method:"agents"},optionSchema:{booleans:["fix"]},description:"Show the concrete compatibility matrix for AI coding agents",usage:{claude:"p. agents [doctor|doctor --fix]",terminal:"prjct agents [doctor|doctor --fix]"},params:"[doctor|status|list] [--fix]",implemented:!0,hasTemplate:!1,requiresProject:!1,isOptional:!0,features:["Derives support levels from the runtime registry","Reports AGENTS.md, MCP, skills, hooks, ACP, and project-rule support","doctor --fix refreshes repo-local agent surfaces when run inside a project",'Use this to audit claims like "works with Codex/Gemini/OpenCode/Cursor/Windsurf"']},{name:"value",group:"legacy",surface:"legacy",routing:{group:"product",method:"value"},optionSchema:{},description:"Compatibility alias for `insights value`",usage:{claude:null,terminal:"prjct value [--md]"},params:"",implemented:!0,hasTemplate:!1,requiresProject:!0,isOptional:!0,features:["Scores project continuity from real SQLite data","Counts durable memory, preventive guardrails, shipped work, sync metrics, and agent coverage","Designed as the paid-tier proof screen for humans and agents"]},{name:"memory-doctor",group:"legacy",surface:"legacy",routing:{group:"product",method:"memoryDoctor"},optionSchema:{},description:"Compatibility alias for `insights quality`",usage:{claude:null,terminal:"prjct memory-doctor [--md]"},params:"",implemented:!0,hasTemplate:!1,requiresProject:!0,isOptional:!0,features:["Finds duplicate groups, stale inbox entries, low-signal memories, and missing types","Read-only by default; recommends exact cleanup actions","Protects recall quality across Claude, Codex, Gemini, OpenCode, and future agents"]},{name:"report",group:"legacy",surface:"legacy",routing:{group:"product",method:"report"},optionSchema:{numbers:["days"]},description:"Compatibility alias for `insights report`",usage:{claude:null,terminal:"prjct report [days] [--md]"},params:"[days]",implemented:!0,hasTemplate:!1,requiresProject:!0,isOptional:!0,features:["Summarizes shipped features, completed tasks, active work, and carry-forward lessons","Uses real project state instead of a marketing changelog","Useful for founders, teams, and paid Cloud status emails"]},{name:"handoff",group:"legacy",surface:"legacy",routing:{group:"product",method:"handoff"},optionSchema:{},description:"Compatibility alias for `insights continue`",usage:{claude:null,terminal:"prjct handoff codex [--md]"},params:"[agent]",implemented:!0,hasTemplate:!1,requiresProject:!0,isOptional:!0,features:["Gives the next agent the active task, required prjct checks, and high-value memories","Works across Codex, Claude, Gemini, Cursor, OpenCode, Qwen, Kimi, and unknown future agents","Makes multi-agent continuity concrete instead of relying on private model memory"]},{name:"guardrails",group:"legacy",surface:"legacy",routing:{group:"product",method:"guardrails"},optionSchema:{},description:"Compatibility alias for `insights guardrails`",usage:{claude:null,terminal:"prjct guardrails [--md]"},params:"",implemented:!0,hasTemplate:!1,requiresProject:!0,isOptional:!0,features:["Checks changed files against preventive memory","Falls back to general project traps when no file-specific hit exists","Advisory only; no gate, no mutation"]},{name:"insights",group:"optional",surface:"ai-agile",routing:{group:"product",method:"insights"},optionSchema:{numbers:["days"]},description:"AI Agile intelligence: value, quality, reliability, token cost, reports, continuation, and guardrails",usage:{claude:"p. insights [value|quality|reliability|cost|report|continue|guardrails]",terminal:"prjct insights [value|quality|reliability|cost|report|continue|guardrails] [--md]"},params:"[value|quality|reliability|cost|report|continue|guardrails] [agent|days]",implemented:!0,hasTemplate:!1,requiresProject:!0,isOptional:!0,features:["v3 surface for project intelligence formerly spread across value/report/handoff/memory-doctor/guardrails","Default view summarizes whether the project is compounding","reliability/trust shows whether value, cost, and performance metrics are decision-ready","cost/spend/tokens shows subscription burn, token coverage, context reuse, and capture gaps","Subcommands remain read-only except where underlying compatibility commands already mutate nothing"]},{name:"performance",group:"optional",surface:"ai-agile",routing:{group:"product",method:"performance"},optionSchema:{numbers:["days"]},description:"Measure dev+LLM efficiency per work cycle: time, tokens, model/runtime, tools, friction",usage:{claude:"p. performance [7]",terminal:"prjct performance [days] [--md]"},params:"[days]",implemented:!0,hasTemplate:!1,requiresProject:!0,isOptional:!0,features:["Uses real task/session rows and available token columns","Stores unknown when a runtime does not expose exact model/token data","Designed to guide the next work cycle, not to create scrum velocity reports"]},{name:"cloud",group:"setup",surface:"support",routing:{group:"cloud",method:"cloud"},optionSchema:{},description:"Cloud sync (paid): link/unlink a project, sync/pull, pause/resume, status",usage:{claude:"p. cloud [link|unlink|sync|pull|pause|resume|status]",terminal:"prjct cloud [sub]"},params:"[link|unlink|sync|pull|pause|resume|status]",implemented:!0,hasTemplate:!1,requiresProject:!0,isOptional:!0,features:["Local-first: nothing leaves the machine until `prjct cloud link`","Token API only \u2014 no backend engine details, no client-side paywall","Auto-syncs on `prjct ship` and at session end once linked"]},{name:"workflow",group:"optional",surface:"support",routing:{group:"workflow",method:"workflow"},optionSchema:{},description:"Configure workflow hooks via natural language",usage:{claude:'p. workflow ["config"]',terminal:'prjct workflow ["config"]'},params:'["natural language config"]',implemented:!0,hasTemplate:!0,requiresProject:!0,isOptional:!0,requiresLlm:!0,features:["Natural language configuration","Before/after hooks for task, done, ship, sync","Permanent, session, or one-time preferences"]},{name:"start",group:"setup",surface:"support",routing:{group:"setup",method:"start"},routingMode:"bin-only",description:"First-time setup (install commands to editors)",usage:{claude:null,terminal:"prjct start"},implemented:!0,hasTemplate:!1,requiresProject:!1},{name:"setup",group:"setup",surface:"support",routing:{group:"setup",method:"setup"},routingMode:"bin-only",description:"Reconfigure editor installations and user-owned defaults",usage:{claude:"p. setup",terminal:"prjct setup"},params:"[--force] [--non-interactive]",implemented:!0,hasTemplate:!0,requiresProject:!1},{name:"login",group:"setup",surface:"support",routing:{group:"setup",method:"login"},description:"Authenticate with prjct cloud (opens browser)",usage:{claude:null,terminal:"prjct login"},params:"",implemented:!0,hasTemplate:!1,requiresProject:!1,routingMode:"bin-only"},{name:"logout",group:"setup",surface:"support",routing:{group:"setup",method:"logout"},description:"Sign out from prjct cloud",usage:{claude:null,terminal:"prjct logout"},implemented:!0,hasTemplate:!1,requiresProject:!1,routingMode:"bin-only"},{name:"auth",group:"setup",surface:"support",routing:{group:"setup",method:"auth"},description:"Manage cloud authentication",usage:{claude:"p. auth [action]",terminal:"prjct auth [action]"},params:"[logout|status]",implemented:!0,hasTemplate:!1,requiresProject:!1,routingMode:"bin-only"},{name:"context",group:"setup",surface:"support",routing:{group:"context",method:"context"},routingMode:"bin-only",optionSchema:{},description:"Smart context filtering tools for AI agents",usage:{claude:null,terminal:"prjct context <tool> [args]"},params:"<tool> [args]",implemented:!0,hasTemplate:!1,requiresProject:!0,features:["files - Find relevant files for a task","signatures - Extract code structure (~90% compression)","imports - Analyze dependency graphs","recent - Find hot files from git history","summary - Intelligent file summarization"]},{name:"search",group:"core",surface:"ai-agile",routing:{group:"context",method:"search"},optionSchema:{booleans:["global"]},description:"Search project memory (decisions, learnings, gotchas, ships\u2026) \u2014 BM25 + semantic + recall",usage:{claude:'p. search "<query>"',terminal:'prjct search "<query>" [--md]'},params:"<query>",implemented:!0,hasTemplate:!1,requiresProject:!1,features:["Blended retrieval: FTS5 BM25 + opt-in semantic + recency recall","Reranks by proven usefulness, expands one hop of the memory graph","`prjct search mem_1234` resolves a specific entry by id"]},{name:"update",group:"setup",surface:"support",routing:{group:"update",method:"update"},routingMode:"bin-only",description:"Update prjct system-wide: package + migrations + daemon restart",usage:{claude:null,terminal:"prjct update [--dry-run]"},params:"[--dry-run]",implemented:!0,hasTemplate:!1,requiresProject:!1,features:["Phase 1: npm update (migrates homebrew \u2192 npm if needed)","Phase 2: All projects \u2014 migrate, sweep, reinstall commands","Phase 3: Daemon stop + restart with new code","--dry-run to preview without changes"]},{name:"uninstall",group:"setup",surface:"support",routing:{group:"uninstall",method:"uninstall"},routingMode:"bin-only",description:"Complete system removal of prjct",usage:{claude:null,terminal:"prjct uninstall"},params:"[--force] [--backup] [--dry-run]",implemented:!0,hasTemplate:!1,requiresProject:!1,features:["Removes ~/.prjct-cli/ data","Cleans CLAUDE.md prjct section","Uninstalls Homebrew/npm packages","Backup option before deletion"]},{name:"team",group:"setup",surface:"support",routing:{group:"team",method:"team"},optionSchema:{booleans:["required","enforce"],strings:["minVersion"]},description:"Enroll this repo in prjct team mode \u2014 commits .prjct/team.json + .claude/CLAUDE.md so teammates pick up shared expectations",usage:{claude:"p. team",terminal:"prjct team [--required] [--min-version <semver>]"},params:"[--required] [--min-version <semver>]",implemented:!0,hasTemplate:!1,requiresProject:!0,features:["Writes .prjct/team.json with required/minVersion config","Adds prjct context block to .claude/CLAUDE.md (per-project)","Stages both files for the next commit (does NOT commit)","Teammates clone repo + install prjct \u2192 ready to go"]},{name:"embeddings",group:"setup",surface:"support",routing:{group:"embeddings",method:"embeddings"},optionSchema:{strings:["key","model","baseUrl","authHeader","authScheme","headers","query"]},description:"Configure the GLOBAL semantic-embeddings provider (BYOT) \u2014 one API key, stored securely, used by every project.",usage:{claude:"p. embeddings status",terminal:'prjct embeddings <set|status|test|clear> [--key <K>] [--model <M>] [--base-url <U>] [--auth-header <H>] [--auth-scheme <S|none>] [--headers "k=v,..."] [--query <qs>]'},params:"[set|status|test|clear]",implemented:!0,hasTemplate:!1,requiresProject:!1,features:["BYOT: bring your own embedding API key \u2014 ANY OpenAI-compatible provider","Zero-config: paste just --key, the base URL is auto-detected from its prefix","OpenAI, OpenRouter, Ollama, Together, Mistral, Voyage, Jina, LM Studio\u2026",'Non-Bearer providers too: --auth-header api-key --auth-scheme none --query "api-version=..." (Azure OpenAI)',"Key stored in the macOS Keychain (else a 0600 file), never in config","Global \u2014 applies to all projects; per-project config still overrides","Without a key, recall uses the always-on local subword embedder","Validate with: prjct embeddings test"]},{name:"changelog",group:"changelog",surface:"ai-agile",requiresProject:!0,implemented:!0,hasTemplate:!1,routing:{group:"changelog",method:"changelog"},optionSchema:{},description:"Release notes from the typed delivery record: what shipped (by version) + completed work cycles in the window. Zero LLM \u2014 pure data-plane render.",usage:{claude:"p. changelog 14",terminal:"prjct changelog [days]"}},{name:"workflows",group:"workflowsReference",surface:"ai-agile",requiresProject:!1,implemented:!0,hasTemplate:!1,routing:{group:"workflowsReference",method:"workflows"},optionSchema:{},description:"Print the quality methodology reference (subagent dispatch, model policy, review/judgment/security workflows) \u2014 the rig-agnostic pull of what Claude reads as workflows.md.",usage:{claude:"p. workflows",terminal:"prjct workflows --md"}},{name:"memory",group:"memoryExport",surface:"ai-agile",requiresProject:!0,implemented:!0,hasTemplate:!1,routing:{group:"memoryExport",method:"memory"},optionSchema:{},description:"Git-shareable project memory: `export` writes chunked JSONL to .prjct/memory-export/ (commit it); `import` replays a committed export with content-hash dedup \u2014 zero-server team onboarding.",usage:{claude:"p. memory export",terminal:"prjct memory export | prjct memory import"}},{name:"guard",group:"core",surface:"ai-agile",routing:{group:"guard",method:"guard"},optionSchema:{numbers:["limit"],strings:["diff"],booleans:["strict"]},description:"Surface preventive memory (gotchas, anti-patterns, recurring-bugs) recorded against a file BEFORE you edit it \u2014 anticipation, provider-agnostic.",usage:{claude:"p. guard <file>",terminal:"prjct guard <file> | prjct guard --diff <range> [--strict]"},params:"[file]",implemented:!0,hasTemplate:!1,requiresProject:!0,features:["Pillar 3 (anticipation): see the trap before you step in it","Pull, not push \u2014 also exposed as the prjct_guard MCP tool for Claude + Codex","Strict: only gotchas / anti-patterns / recurring-bugs \u2014 never plain decisions, so no noise",'Quiet by design: "clear to edit" when nothing preventive matches',"Matches absolute or repo-relative paths by exact / suffix / basename"]},{name:"config",group:"setup",surface:"support",routing:{group:"config",method:"config"},optionSchema:{},description:"Read/write global prjct config \u2014 auto-update opt-in, suggestions toggle, etc.",usage:{claude:"p. config list",terminal:"prjct config <list|get|set|unset> [key] [value]"},params:"<list|get|set|unset> [key] [value]",implemented:!0,hasTemplate:!1,requiresProject:!1,features:["Stored at ~/.prjct-cli/config/global.json","Opt into silent auto-update: prjct config set auto-update on","Toggle proactive suggestions: prjct config set suggestions off","Booleans accept on/off/true/false; numbers parsed automatically"]},{name:"spec",group:"legacy",surface:"legacy",routing:{group:"spec",method:"draft"},routingMode:"cold-only",description:"Compatibility alias for `intent` \u2014 Goal/Acceptance/Scope/Risks before work starts.",usage:{claude:null,terminal:'prjct spec "<title>" [--goal "..."] [--tags k:v,...]'},params:'"<title>" [--goal] [--tags]',implemented:!0,hasTemplate:!1,requiresProject:!0,features:['Drafting: `prjct spec "<title>"` IS the create action \u2014 there is no `draft` subverb (aliases `draft`/`new`/`create` are tolerated and stripped)',"Persists in `specs` SQLite table + memory event stream","Sub-verbs: list, show, update, set-status, record-review, link-task, ship, audit, inventory"]},{name:"audit-spec",group:"legacy",surface:"legacy",routing:{group:"spec",method:"audit"},routingMode:"cold-only",description:"Compatibility alias for `intent audit <id>`",usage:{claude:null,terminal:"prjct audit-spec <id>"},params:"<spec-id>",implemented:!0,hasTemplate:!1,requiresProject:!0,features:["Emits dispatch prompt \u2014 Claude runs three Agent calls in parallel","Each reviewer writes back via `prjct spec record-review`","All three pass \u2192 spec auto-promotes draft \u2192 reviewed"]},...[["daemon","Run the prjct daemon in the foreground"],["stop","Stop the running prjct daemon"],["restart","Restart the prjct daemon"],["upgrade","Alias of `prjct update`",{group:"update",method:"update"}],["hook","Run a Claude Code hook event (internal; called by the hook scripts)"],["hooks","Inspect or reinstall the Claude Code hooks"],["claude","Claude Code integration management (install/uninstall)"],["crew","Run a crew (multi-subagent) workflow"],["doctor","Diagnose the local prjct installation"],["watch","Watch project files and react to changes"],["version","Print the installed prjct version + provider status"],["prefs","Inspect or set workflow preferences"],["retro","Summarize what shipped over a time window"],["health","Codebase health snapshot"],["skill-adherence","Report how well sessions follow the prjct skill"],["review-risk","Risk-ranked review hints for the working tree"],["context-save","Save the current working context for later restore"],["context-restore","Restore a previously saved working context"]].map(([n,e,t])=>({name:n,group:"setup",description:e,routing:t,usage:{claude:null,terminal:`prjct ${n}`},implemented:!0,hasTemplate:!1,requiresProject:!1,routingMode:"bin-only"}))],TI={"-h":"help","--help":"help","-v":"version","--version":"version"},SI=new Set([...cs.filter(n=>n.routingMode==="bin-only").map(n=>n.name),...Object.entries(TI).filter(([,n])=>cs.some(e=>e.name===n&&e.routingMode==="bin-only")).map(([n])=>n)])});var tE,nE=h(()=>{"use strict";id();tE=new Set(cs.filter(n=>n.routing).map(n=>n.name))});function bI(n){return n instanceof ls}function Xe(n){return bI(n)||n instanceof Error?n.message:typeof n=="string"?n:"Unknown error"}var ls,ha,ya,ki,fn=h(()=>{"use strict";ls=class extends Error{static{a(this,"PrjctError")}code;isOperational;constructor(e,t="PRJCT_ERROR"){super(e),this.name="PrjctError",this.code=t,this.isOperational=!0,Error.captureStackTrace?.(this,this.constructor)}},ha=class n extends ls{static{a(this,"ProjectError")}constructor(e,t="PROJECT_ERROR"){super(e,t),this.name="ProjectError"}static notInitialized(){return new n("Project not initialized. Run p. init first.","PROJECT_NOT_INIT")}static notFound(e){return new n(`Project not found: ${e}`,"PROJECT_NOT_FOUND")}static invalidId(e){return new n(`Invalid project ID: ${e}`,"PROJECT_INVALID_ID")}},ya=class n extends ls{static{a(this,"TemplateError")}constructor(e,t="TEMPLATE_ERROR"){super(e,t),this.name="TemplateError"}static notFound(e){return new n(`Template not found: ${e}.md`,"TEMPLATE_NOT_FOUND")}static parseFailed(e){return new n(`Failed to parse template: ${e}`,"TEMPLATE_PARSE_ERROR")}},ki=class n extends ls{static{a(this,"AgentError")}constructor(e,t="AGENT_ERROR"){super(e,t),this.name="AgentError"}static notSupported(e){return new n(`Unsupported agent type: ${e}`,"AGENT_NOT_SUPPORTED")}static initFailed(e){return new n(`Agent initialization failed: ${e}`,"AGENT_INIT_FAILED")}};a(bI,"isPrjctError");a(Xe,"getErrorMessage")});function rE(n){let e=n.toLowerCase();return e.includes("github")?"github":e.includes("gitlab")?"gitlab":e.includes("bitbucket")?"bitbucket":"other"}function od(n){let e=n.trim();if(!e)return{};let t=e.match(/^[^/@]+@([^:/]+):(.+?)(?:\.git)?\/?$/);if(t)return{provider:rE(t[1]),repoSlug:t[2]};try{let r=new URL(e),s=r.pathname.replace(/^\/+/,"").replace(/\.git$/,"").replace(/\/+$/,"");return!r.host||!s?{}:{provider:rE(r.host),repoSlug:s}}catch{return{}}}async function vI(n){try{let{stdout:e}=await B("git",["remote","get-url","origin"],{cwd:n});return e.trim()||void 0}catch{return}}async function RI(n){try{let{stdout:e}=await B("git",["symbolic-ref","--short","refs/remotes/origin/HEAD"],{cwd:n});return e.trim().replace(/^origin\//,"")||void 0}catch{return}}function Tr(n){return typeof n=="string"&&n.length>0?n:void 0}function sE(n){return typeof n=="number"&&Number.isFinite(n)?n:void 0}function CI(n){return Object.fromEntries(Object.entries(n).filter(([,e])=>e!==void 0))}async function wa(n){let e=E.getDoc(n,"project")||{},t=Tr(e.repoPath),{provider:r,repoSlug:s}=t?od(await vI(t)||""):{},i=t?await RI(t):void 0,o=Array.isArray(e.techStack)?e.techStack.filter(c=>typeof c=="string"):void 0;return CI({provider:r,repoSlug:s,currentBranch:Tr(e.currentBranch),defaultBranch:i,stack:Tr(e.stack),techStack:o&&o.length>0?o:void 0,version:Tr(e.version),commitCount:sE(e.commitCount),fileCount:sE(e.fileCount),lastCommit:Tr(e.lastSyncCommit),hasUncommitted:typeof e.hasUncommittedChanges=="boolean"?e.hasUncommittedChanges:void 0,cliVersion:Tr(e.cliVersion),syncedAt:Tr(e.lastSync)})}var Ea=h(()=>{"use strict";$();ie();a(rE,"providerForHost");a(od,"parseRemote");a(vI,"gitRemoteUrl");a(RI,"gitDefaultBranch");a(Tr,"str");a(sE,"num");a(CI,"compact");a(wa,"buildProjectMeta")});import{execFile as _I}from"node:child_process";import AI from"node:crypto";import{promisify as xI}from"node:util";function PI(n,e=II){let t=Buffer.from(e.replace(/-/g,""),"hex"),s=AI.createHash("sha1").update(t).update(n,"utf8").digest().subarray(0,16);s[6]=s[6]&15|80,s[8]=s[8]&63|128;let i=s.toString("hex");return`${i.slice(0,8)}-${i.slice(8,12)}-${i.slice(12,16)}-${i.slice(16,20)}-${i.slice(20,32)}`}async function DI(n){let e;try{let{stdout:s}=await NI("git",["remote","get-url","origin"],{cwd:n});e=s.trim()||void 0}catch{return null}if(!e)return null;let{provider:t,repoSlug:r}=od(e);return!t||!r?null:`${t}:${r}`.toLowerCase()}async function iE(n){let e=await DI(n);return e?PI(e):null}var NI,II,oE=h(()=>{"use strict";Ea();NI=xI(_I),II="6f9b2c1a-3d4e-5f60-8a7b-1c2d3e4f5a6b";a(PI,"uuidv5");a(DI,"repoKey");a(iE,"deriveProjectId")});var ud={};O(ud,{PACKAGE_ROOT:()=>hn,VERSION:()=>je,getPackageRoot:()=>cd,getVersion:()=>br,resetPackageRoot:()=>ld});import ad from"node:fs";import ka from"node:path";function cd(){if(us)return us;let n=__dirname;for(let e=0;e<5;e++){let t=ka.join(n,"package.json");if(ad.existsSync(t))try{if(JSON.parse(ad.readFileSync(t,"utf-8")).name==="prjct-cli")return us=n,n}catch{}n=ka.dirname(n)}return us=ka.join(__dirname,"..","..",".."),us}function br(){if(Sr)return Sr;let n="3.24.1";if(n&&/^\d+\.\d+\.\d+/.test(n))return Sr=n,Sr;try{let e=ka.join(cd(),"package.json");return Sr=JSON.parse(ad.readFileSync(e,"utf-8")).version,Sr}catch(e){return process.env.PRJCT_DEBUG==="1"&&console.error("Failed to read version from package.json:",y(e)),"0.0.0"}}function ld(n){us=n,Sr=null}var Sr,us,je,hn,ct=h(()=>{"use strict";G();Sr=null,us=null;a(cd,"getPackageRoot");a(br,"getVersion");a(ld,"resetPackageRoot");je=br(),hn=cd()});async function Ta(n){try{let{stdout:e}=await U(n,{timeout:5e3});return{success:!0,output:e.trim()}}catch{return{success:!1,output:""}}}async function OI(){let n=await Ta("gh api user --jq .login");return n.success&&n.output||(n=await Ta("git config --global github.user"),n.success&&n.output)?n.output:null}async function jI(){let n=await Ta("git config user.name");return n.success&&n.output?n.output:null}async function MI(){let n=await Ta("git config user.email");return n.success&&n.output?n.output:null}async function ds(){let[n,e,t]=await Promise.all([OI(),jI(),MI()]);return{github:n,email:t,name:e||n||"Unknown"}}var Sa=h(()=>{"use strict";ie();a(Ta,"execCommand");a(OI,"detectGitHubUsername");a(jI,"detectGitName");a(MI,"detectGitEmail");a(ds,"detect")});var gd={};O(gd,{worktreeService:()=>LI});import pd from"node:fs/promises";import Zt from"node:path";var aE,md,LI,fd=h(()=>{"use strict";ie();Q();aE=".worktrees",md=class{static{a(this,"WorktreeService")}async create(e,t,r={}){let s=await this.getMainWorktree(e),i=Zt.join(s,aE,t),o=r.branch||`feat/${t}`;await pd.mkdir(Zt.join(s,aE),{recursive:!0});let c=r.baseBranch?` ${r.baseBranch}`:"";await U(`git worktree add "${i}" -b "${o}"${c}`,{cwd:s});let{stdout:l}=await U("git rev-parse HEAD",{cwd:i});return{path:i,branch:o,commit:l.trim(),isMain:!1,slug:t}}async remove(e,t=!1){let r=await this.getMainWorktree(e),s;if(t)try{let{stdout:i}=await U("git rev-parse --abbrev-ref HEAD",{cwd:e});s=i.trim()}catch{}if(await U(`git worktree remove "${e}" --force`,{cwd:r}),t&&s&&s!=="main"&&s!=="master")try{await U(`git branch -D "${s}"`,{cwd:r})}catch{}}async list(e){let t=await this.getMainWorktree(e),{stdout:r}=await U("git worktree list --porcelain",{cwd:t});return this.parsePorcelainOutput(r,t)}async detect(e){try{let{stdout:t}=await U("git rev-parse --git-common-dir",{cwd:e}),{stdout:r}=await U("git rev-parse --git-dir",{cwd:e}),s=Zt.resolve(e,t.trim()),i=Zt.resolve(e,r.trim());if(s!==i){let{stdout:o}=await U("git rev-parse --abbrev-ref HEAD",{cwd:e}),{stdout:c}=await U("git rev-parse HEAD",{cwd:e}),{stdout:l}=await U("git rev-parse --show-toplevel",{cwd:e}),u=l.trim(),d=Zt.basename(u);return{path:u,branch:o.trim(),commit:c.trim(),isMain:!1,slug:d}}return null}catch{return null}}async getMainWorktree(e){try{let{stdout:r}=await U("git worktree list --porcelain",{cwd:e}),s=r.split(`
1322
1322
  `)[0];if(s?.startsWith("worktree "))return s.replace("worktree ","").trim()}catch{}let{stdout:t}=await U("git rev-parse --show-toplevel",{cwd:e});return t.trim()}async setup(e,t){let r=Zt.join(t,".env");await x(r)&&await pd.copyFile(r,Zt.join(e,".env"));let s=Zt.join(t,".prjct"),i=Zt.join(e,".prjct");await x(s)&&!await x(i)&&await pd.symlink(s,i,"dir")}async teardown(e){}async clean(e){let t=await this.list(e),r=[],s=await this.getMainWorktree(e);await U("git worktree prune",{cwd:s});for(let i of t)i.isMain||await x(i.path)||r.push(i.slug);return r}parsePorcelainOutput(e,t){let r=[],s=e.trim().split(`
1323
1323
 
1324
1324
  `);for(let i of s){if(!i.trim())continue;let o=i.trim().split(`
@@ -1169,7 +1169,7 @@ CREATE TABLE velocity_sprints (
1169
1169
  `);let n=new Set(e.prepare("SELECT version FROM _migrations").all().map(i=>i.version)),s=Us.filter(i=>!n.has(i.version));if(s.length!==0){if(t&&n.size>0)try{let i=`${t}.pre-migrate.bak`;On.existsSync(i)&&On.rmSync(i,{force:!0}),e.prepare("VACUUM INTO ?").run(i)}catch(i){console.warn(`prjct: pre-migration backup failed (continuing): ${i?.message??i}`)}for(let i of s)ea(e,()=>{i.up(e),e.prepare("INSERT INTO _migrations (version, name, applied_at) VALUES (?, ?, ?)").run(i.version,i.name,new Date().toISOString())})}}getMigrations(e){return this.getDb(e).prepare("SELECT * FROM _migrations ORDER BY version").all()}getSchemaVersion(e){return this.getDb(e).prepare("SELECT MAX(version) as version FROM _migrations").get()?.version??0}},y=new Hs,h=y});import ta from"node:fs/promises";import ir from"node:path";function Ld(r){let e=[],t,n=new RegExp(Ku.source,"g");for(;(t=n.exec(r))!==null;){let s=t[1];(s.startsWith(".")||s.startsWith("@/"))&&e.push(s)}return e}async function Md(r,e,t){let n;if(r.startsWith("@/"))n=ir.join(t,"src",r.slice(2));else{let s=ir.dirname(ir.join(t,e));n=ir.resolve(s,r)}for(let s of Vu){let i=n+s;try{if((await ta.stat(i)).isFile())return ir.relative(t,i)}catch{}}return null}async function $k(r){let e=await Ot(r),t={},n={},s=0,i=await jt(e,50,async o=>{try{let c=await ta.readFile(ir.join(r,o),"utf-8"),l=Ld(c),u=[];for(let d of l){let p=await Md(d,o,r);p&&p!==o&&u.push(p)}return u.length>0?{filePath:o,imports:u}:null}catch{return null}});for(let{filePath:o,imports:c}of i){t[o]=c,s+=c.length;for(let l of c)n[l]||(n[l]=[]),n[l].push(o)}return{forward:t,reverse:n,fileCount:e.length,edgeCount:s,builtAt:new Date().toISOString()}}function Gs(r,e,t=2){let n=new Set(r),s=new Map,i=[];for(let o of r){let c=e.forward[o]||[],l=e.reverse[o]||[];for(let u of[...c,...l])n.has(u)||i.push({file:u,depth:1})}for(let o=0;o<i.length;o++){let{file:c,depth:l}=i[o];if(l>t)continue;let u=1/(l+1),d=s.get(c);if(d){u>d.score&&s.set(c,{score:u,depth:l});continue}if(s.set(c,{score:u,depth:l}),l<t){let p=e.forward[c]||[],m=e.reverse[c]||[];for(let g of[...p,...m])!n.has(g)&&!s.has(g)&&i.push({file:g,depth:l+1})}}return Array.from(s.entries()).map(([o,{score:c,depth:l}])=>({path:o,score:c,depth:l})).sort((o,c)=>c.score-o.score)}function Uk(r){return Object.values(r).reduce((e,t)=>e+t.length,0)}function Hk(r,e){let t=r.forward[e]||[];delete r.forward[e];for(let n of t){let s=(r.reverse[n]||[]).filter(i=>i!==e);s.length===0?delete r.reverse[n]:r.reverse[n]=s}}function Wk(r,e){let t=r.reverse[e]||[];delete r.reverse[e];let n=[];for(let s of t){let i=(r.forward[s]||[]).filter(o=>o!==e);i.length===0?delete r.forward[s]:r.forward[s]=i,n.push(s)}return n}function Bk(r,e,t){if(t.length===0)return;let n=Array.from(new Set(t));r.forward[e]=n;for(let s of n)r.reverse[s]||(r.reverse[s]=[]),r.reverse[s].includes(e)||r.reverse[s].push(e)}async function Gk(r,e){try{let t=await ta.readFile(ir.join(r,e),"utf-8"),n=Ld(t),s=[];for(let i of n){let o=await Md(i,e,r);o&&o!==e&&s.push(o)}return{filePath:e,imports:s}}catch{return null}}function Fd(r){return{schemaVersion:2,fileCount:r.fileCount,edgeCount:r.edgeCount,builtAt:r.builtAt}}function Xk(r,e){try{h.transaction(r,t=>{t.prepare("DELETE FROM import_graph_edges").run();let n=t.prepare("INSERT INTO import_graph_edges (from_path, to_path, sort_order) VALUES (?, ?, ?)");for(let[s,i]of Object.entries(e.forward))for(let[o,c]of i.entries())n.run(s,c,o)})}catch{}}function qk(r,e,t,n){try{h.transaction(r,s=>{let i=s.prepare("DELETE FROM import_graph_edges WHERE from_path = ?"),o=s.prepare("INSERT INTO import_graph_edges (from_path, to_path, sort_order) VALUES (?, ?, ?)");for(let c of new Set([...t,...n]))i.run(c);for(let c of t){let l=e.forward[c]||[];for(let[u,d]of l.entries())o.run(c,d,u)}})}catch{}}function Vk(r,e,t){try{let n=h.query(r,"SELECT from_path, to_path FROM import_graph_edges ORDER BY from_path, sort_order, to_path");if(n.length===0){if(t?.edgeCount===0){let l={forward:{},reverse:{},fileCount:t.fileCount,edgeCount:0,builtAt:t.builtAt};return or.set(r,{graph:l,updatedAt:e}),l}return null}let s={},i={};for(let l of n)s[l.from_path]||(s[l.from_path]=[]),s[l.from_path].push(l.to_path),i[l.to_path]||(i[l.to_path]=[]),i[l.to_path].push(l.from_path);let o=new Set;for(let[l,u]of Object.entries(s)){o.add(l);for(let d of u)o.add(d)}let c={forward:s,reverse:i,fileCount:t?.fileCount??o.size,edgeCount:n.length,builtAt:t?.builtAt??e};return or.set(r,{graph:c,updatedAt:e}),c}catch{return null}}function Kk(r,e){h.setDoc(r,Bs,Fd(e)),Xk(r,e),or.delete(r)}function Yk(r,e,t,n){h.setDoc(r,Bs,Fd(e)),qk(r,e,t,n),or.delete(r)}function et(r){let e=h.get(r,"SELECT updated_at FROM kv_store WHERE key = ?",Bs);if(!e)return or.delete(r),null;let t=or.get(r);if(t&&t.updatedAt===e.updated_at)return t.graph;let n=h.getDoc(r,Bs),s=Vk(r,e.updated_at,n);if(s)return s;if(!n?.forward||!n?.reverse)return null;let i={forward:n.forward,reverse:n.reverse,fileCount:n.fileCount,edgeCount:n.edgeCount,builtAt:n.builtAt};return or.set(r,{graph:i,updatedAt:e.updated_at}),i}async function jn(r,e){let t=await $k(r);return Kk(e,t),t}async function $d(r,e,t,n=[]){let s=et(e);if(!s)return jn(r,e);let i=new Set([...t,...n]);for(let l of i)Hk(s,l);let o=new Set;for(let l of n)for(let u of Wk(s,l))o.add(u);let c=await jt(t,50,l=>Gk(r,l));for(let l of c)Bk(s,l.filePath,l.imports);return s.edgeCount=Uk(s.forward),s.builtAt=new Date().toISOString(),Yk(e,s,[...t,...o],n),s}var Bs,or,Hr=f(()=>{"use strict";Mo();I();J();a(Ld,"extractImportSources");a(Md,"resolveImport");a($k,"buildGraph");a(Gs,"scoreFromSeeds");Bs="import-graph",or=new Map;a(Uk,"countEdges");a(Hk,"removeOutgoingEdges");a(Wk,"removeIncomingEdges");a(Bk,"addEdges");a(Gk,"importsForFile");a(Fd,"graphMetadata");a(Xk,"replacePerFileEdges");a(qk,"updatePerFileEdges");a(Vk,"loadGraphFromPerFileEdges");a(Kk,"saveGraph");a(Yk,"saveGraphUpdate");a(et,"loadGraph");a(jn,"indexImports");a($d,"updateImportGraph")});function Xs(r,e){let t=[...r.added,...r.modified],n=new Set(t),s=new Set,i=et(e);if(i)for(let l of t){let u=i.reverse[l];if(u)for(let d of u)n.has(d)||s.add(d)}let o=Array.from(s),c=[...t,...o];return{directlyChanged:t,affectedByImports:o,deleted:r.deleted,allAffected:c}}function qs(r){let e=new Set;for(let t of r){let n=t.toLowerCase();(n.endsWith(".tsx")||n.endsWith(".jsx")||n.endsWith(".css")||n.endsWith(".scss")||n.endsWith(".vue")||n.endsWith(".svelte")||n.includes("/components/")||n.includes("/pages/")||n.includes("/app/"))&&(e.add("frontend"),e.add("uxui")),(n.includes(".test.")||n.includes(".spec.")||n.includes("__tests__")||n.includes("/test/"))&&e.add("testing"),(n.includes("dockerfile")||n.includes("docker-compose")||n.includes(".dockerignore")||n.includes(".github/")||n.includes("ci/")||n.includes("cd/"))&&e.add("devops"),(n.endsWith(".sql")||n.includes("prisma")||n.includes("drizzle")||n.includes("migration")||n.includes("/db/"))&&e.add("database"),(n.endsWith(".ts")||n.endsWith(".js"))&&!n.includes(".test.")&&!n.includes(".spec.")&&!n.endsWith(".d.ts")&&e.add("backend")}return e}var ra=f(()=>{"use strict";Hr();a(Xs,"propagateChanges");a(qs,"affectedDomains")});var na=f(()=>{"use strict"});async function Jk(r,e=100){try{let{stdout:t}=await N(`git log --name-only --pretty=format:'---COMMIT---' -${e}`,{cwd:r,maxBuffer:10485760}),n=[],s=null;for(let i of t.split(`
1170
1170
  `)){let o=i.trim();o==="---COMMIT---"?(s&&s.size>0&&s.size<=30&&n.push(s),s=new Set):o&&s&&Qk(o)&&s.add(o)}return s&&s.size>0&&s.size<=30&&n.push(s),n}catch{return[]}}function Qk(r){return/\.(ts|tsx|js|jsx|mjs|cjs|py|go|rs|java|cs|rb|php|vue|svelte)$/i.test(r)&&!r.includes("node_modules/")}async function Zk(r,e=100){let t=await Jk(r,e),n=new Map,s=new Map;for(let o of t){let c=Array.from(o);for(let l of c)n.set(l,(n.get(l)||0)+1);for(let l=0;l<c.length;l++)for(let u=l+1;u<c.length;u++){let d=ew(c[l],c[u]);s.set(d,(s.get(d)||0)+1)}}let i={};for(let[o,c]of s){let[l,u]=o.split("\0"),d=n.get(l)||0,p=n.get(u)||0;if(d<2||p<2)continue;let m=d+p-c,g=m>0?c/m:0;g<.1||(i[l]||(i[l]={}),i[u]||(i[u]={}),i[l][u]=g,i[u][l]=g)}return{matrix:i,commitsAnalyzed:t.length,filesAnalyzed:n.size,builtAt:new Date().toISOString()}}function ew(r,e){return r<e?`${r}\0${e}`:`${e}\0${r}`}function Ln(r,e){let t=new Set(r),n=new Map;for(let s of r){let i=e.matrix[s];if(i)for(let[o,c]of Object.entries(i)){if(t.has(o))continue;let l=n.get(o)||0;c>l&&n.set(o,c)}}return Array.from(n.entries()).map(([s,i])=>({path:s,score:i})).sort((s,i)=>i.score-s.score)}function tw(r,e){h.setDoc(r,sa,e),Vs.delete(r)}function St(r){let e=h.get(r,"SELECT updated_at FROM kv_store WHERE key = ?",sa);if(!e)return Vs.delete(r),null;let t=Vs.get(r);if(t&&t.updatedAt===e.updated_at)return t.matrix;let n=h.getDoc(r,sa);return n&&Vs.set(r,{matrix:n,updatedAt:e.updated_at}),n}async function rw(r,e){try{let{stdout:t}=await N(`git rev-list --max-count=${e} HEAD`,{cwd:r,maxBuffer:1048576}),n=t.split(`
1171
1171
  `).map(s=>s.trim()).filter(Boolean);return n.length>0?n.join(`
1172
- `):null}catch{return null}}async function Ks(r,e,t=100){let n=await rw(r,t),s=n?St(e):null;if(s?.historyFingerprint===n)return s;let i=await Zk(r,t);return n&&(i.historyFingerprint=n),tw(e,i),i}var sa,Vs,Mn=f(()=>{"use strict";na();I();le();a(Jk,"parseGitLog");a(Qk,"isSourceFile");a(Zk,"buildMatrix");a(ew,"pairKey");a(Ln,"scoreFromSeeds");sa="cochange-index",Vs=new Map;a(tw,"saveMatrix");a(St,"loadMatrix");a(rw,"recentHistoryFingerprint");a(Ks,"indexCoChanges")});function nw(r){return r instanceof Fn}function Ee(r){return nw(r)||r instanceof Error?r.message:typeof r=="string"?r:"Unknown error"}var Fn,Ys,$n,bt=f(()=>{"use strict";Fn=class extends Error{static{a(this,"PrjctError")}code;isOperational;constructor(e,t="PRJCT_ERROR"){super(e),this.name="PrjctError",this.code=t,this.isOperational=!0,Error.captureStackTrace?.(this,this.constructor)}},Ys=class r extends Fn{static{a(this,"ProjectError")}constructor(e,t="PROJECT_ERROR"){super(e,t),this.name="ProjectError"}static notInitialized(){return new r("Project not initialized. Run p. init first.","PROJECT_NOT_INIT")}static notFound(e){return new r(`Project not found: ${e}`,"PROJECT_NOT_FOUND")}static invalidId(e){return new r(`Invalid project ID: ${e}`,"PROJECT_INVALID_ID")}},$n=class r extends Fn{static{a(this,"AgentError")}constructor(e,t="AGENT_ERROR"){super(e,t),this.name="AgentError"}static notSupported(e){return new r(`Unsupported agent type: ${e}`,"AGENT_NOT_SUPPORTED")}static initFailed(e){return new r(`Agent initialization failed: ${e}`,"AGENT_INIT_FAILED")}};a(nw,"isPrjctError");a(Ee,"getErrorMessage")});function Wd(r){let e=r.toLowerCase();return e.includes("github")?"github":e.includes("gitlab")?"gitlab":e.includes("bitbucket")?"bitbucket":"other"}function ia(r){let e=r.trim();if(!e)return{};let t=e.match(/^[^/@]+@([^:/]+):(.+?)(?:\.git)?\/?$/);if(t)return{provider:Wd(t[1]),repoSlug:t[2]};try{let n=new URL(e),s=n.pathname.replace(/^\/+/,"").replace(/\.git$/,"").replace(/\/+$/,"");return!n.host||!s?{}:{provider:Wd(n.host),repoSlug:s}}catch{return{}}}async function sw(r){try{let{stdout:e}=await V("git",["remote","get-url","origin"],{cwd:r});return e.trim()||void 0}catch{return}}async function iw(r){try{let{stdout:e}=await V("git",["symbolic-ref","--short","refs/remotes/origin/HEAD"],{cwd:r});return e.trim().replace(/^origin\//,"")||void 0}catch{return}}function ar(r){return typeof r=="string"&&r.length>0?r:void 0}function Bd(r){return typeof r=="number"&&Number.isFinite(r)?r:void 0}function ow(r){return Object.fromEntries(Object.entries(r).filter(([,e])=>e!==void 0))}async function Gd(r){let e=y.getDoc(r,"project")||{},t=ar(e.repoPath),{provider:n,repoSlug:s}=t?ia(await sw(t)||""):{},i=t?await iw(t):void 0,o=Array.isArray(e.techStack)?e.techStack.filter(c=>typeof c=="string"):void 0;return ow({provider:n,repoSlug:s,currentBranch:ar(e.currentBranch),defaultBranch:i,stack:ar(e.stack),techStack:o&&o.length>0?o:void 0,version:ar(e.version),commitCount:Bd(e.commitCount),fileCount:Bd(e.fileCount),lastCommit:ar(e.lastSyncCommit),hasUncommitted:typeof e.hasUncommittedChanges=="boolean"?e.hasUncommittedChanges:void 0,cliVersion:ar(e.cliVersion),syncedAt:ar(e.lastSync)})}var oa=f(()=>{"use strict";I();le();a(Wd,"providerForHost");a(ia,"parseRemote");a(sw,"gitRemoteUrl");a(iw,"gitDefaultBranch");a(ar,"str");a(Bd,"num");a(ow,"compact");a(Gd,"buildProjectMeta")});import{execFile as aw}from"node:child_process";import cw from"node:crypto";import{promisify as lw}from"node:util";function pw(r,e=dw){let t=Buffer.from(e.replace(/-/g,""),"hex"),s=cw.createHash("sha1").update(t).update(r,"utf8").digest().subarray(0,16);s[6]=s[6]&15|80,s[8]=s[8]&63|128;let i=s.toString("hex");return`${i.slice(0,8)}-${i.slice(8,12)}-${i.slice(12,16)}-${i.slice(16,20)}-${i.slice(20,32)}`}async function mw(r){let e;try{let{stdout:s}=await uw("git",["remote","get-url","origin"],{cwd:r});e=s.trim()||void 0}catch{return null}if(!e)return null;let{provider:t,repoSlug:n}=ia(e);return!t||!n?null:`${t}:${n}`.toLowerCase()}async function Xd(r){let e=await mw(r);return e?pw(e):null}var uw,dw,qd=f(()=>{"use strict";oa();uw=lw(aw),dw="6f9b2c1a-3d4e-5f60-8a7b-1c2d3e4f5a6b";a(pw,"uuidv5");a(mw,"repoKey");a(Xd,"deriveProjectId")});var la={};Q(la,{PACKAGE_ROOT:()=>Bt,VERSION:()=>Wt,getPackageRoot:()=>ca,getVersion:()=>Js,resetPackageRoot:()=>gw});import aa from"node:fs";import zs from"node:path";function ca(){if(Wr)return Wr;let r=__dirname;for(let e=0;e<5;e++){let t=zs.join(r,"package.json");if(aa.existsSync(t))try{if(JSON.parse(aa.readFileSync(t,"utf-8")).name==="prjct-cli")return Wr=r,r}catch{}r=zs.dirname(r)}return Wr=zs.join(__dirname,"..","..",".."),Wr}function Js(){if(cr)return cr;let r="3.24.0";if(r&&/^\d+\.\d+\.\d+/.test(r))return cr=r,cr;try{let e=zs.join(ca(),"package.json");return cr=JSON.parse(aa.readFileSync(e,"utf-8")).version,cr}catch(e){return process.env.PRJCT_DEBUG==="1"&&console.error("Failed to read version from package.json:",w(e)),"0.0.0"}}function gw(r){Wr=r,cr=null}var cr,Wr,Wt,Bt,vt=f(()=>{"use strict";z();cr=null,Wr=null;a(ca,"getPackageRoot");a(Js,"getVersion");a(gw,"resetPackageRoot");Wt=Js(),Bt=ca()});async function Qs(r){try{let{stdout:e}=await N(r,{timeout:5e3});return{success:!0,output:e.trim()}}catch{return{success:!1,output:""}}}async function fw(){let r=await Qs("gh api user --jq .login");return r.success&&r.output||(r=await Qs("git config --global github.user"),r.success&&r.output)?r.output:null}async function hw(){let r=await Qs("git config user.name");return r.success&&r.output?r.output:null}async function yw(){let r=await Qs("git config user.email");return r.success&&r.output?r.output:null}async function Br(){let[r,e,t]=await Promise.all([fw(),hw(),yw()]);return{github:r,email:t,name:e||r||"Unknown"}}var Zs=f(()=>{"use strict";le();a(Qs,"execCommand");a(fw,"detectGitHubUsername");a(hw,"detectGitName");a(yw,"detectGitEmail");a(Br,"detect")});var ma={};Q(ma,{worktreeService:()=>Ew});import da from"node:fs/promises";import dt from"node:path";var Vd,pa,Ew,ga=f(()=>{"use strict";le();J();Vd=".worktrees",pa=class{static{a(this,"WorktreeService")}async create(e,t,n={}){let s=await this.getMainWorktree(e),i=dt.join(s,Vd,t),o=n.branch||`feat/${t}`;await da.mkdir(dt.join(s,Vd),{recursive:!0});let c=n.baseBranch?` ${n.baseBranch}`:"";await N(`git worktree add "${i}" -b "${o}"${c}`,{cwd:s});let{stdout:l}=await N("git rev-parse HEAD",{cwd:i});return{path:i,branch:o,commit:l.trim(),isMain:!1,slug:t}}async remove(e,t=!1){let n=await this.getMainWorktree(e),s;if(t)try{let{stdout:i}=await N("git rev-parse --abbrev-ref HEAD",{cwd:e});s=i.trim()}catch{}if(await N(`git worktree remove "${e}" --force`,{cwd:n}),t&&s&&s!=="main"&&s!=="master")try{await N(`git branch -D "${s}"`,{cwd:n})}catch{}}async list(e){let t=await this.getMainWorktree(e),{stdout:n}=await N("git worktree list --porcelain",{cwd:t});return this.parsePorcelainOutput(n,t)}async detect(e){try{let{stdout:t}=await N("git rev-parse --git-common-dir",{cwd:e}),{stdout:n}=await N("git rev-parse --git-dir",{cwd:e}),s=dt.resolve(e,t.trim()),i=dt.resolve(e,n.trim());if(s!==i){let{stdout:o}=await N("git rev-parse --abbrev-ref HEAD",{cwd:e}),{stdout:c}=await N("git rev-parse HEAD",{cwd:e}),{stdout:l}=await N("git rev-parse --show-toplevel",{cwd:e}),u=l.trim(),d=dt.basename(u);return{path:u,branch:o.trim(),commit:c.trim(),isMain:!1,slug:d}}return null}catch{return null}}async getMainWorktree(e){try{let{stdout:n}=await N("git worktree list --porcelain",{cwd:e}),s=n.split(`
1172
+ `):null}catch{return null}}async function Ks(r,e,t=100){let n=await rw(r,t),s=n?St(e):null;if(s?.historyFingerprint===n)return s;let i=await Zk(r,t);return n&&(i.historyFingerprint=n),tw(e,i),i}var sa,Vs,Mn=f(()=>{"use strict";na();I();le();a(Jk,"parseGitLog");a(Qk,"isSourceFile");a(Zk,"buildMatrix");a(ew,"pairKey");a(Ln,"scoreFromSeeds");sa="cochange-index",Vs=new Map;a(tw,"saveMatrix");a(St,"loadMatrix");a(rw,"recentHistoryFingerprint");a(Ks,"indexCoChanges")});function nw(r){return r instanceof Fn}function Ee(r){return nw(r)||r instanceof Error?r.message:typeof r=="string"?r:"Unknown error"}var Fn,Ys,$n,bt=f(()=>{"use strict";Fn=class extends Error{static{a(this,"PrjctError")}code;isOperational;constructor(e,t="PRJCT_ERROR"){super(e),this.name="PrjctError",this.code=t,this.isOperational=!0,Error.captureStackTrace?.(this,this.constructor)}},Ys=class r extends Fn{static{a(this,"ProjectError")}constructor(e,t="PROJECT_ERROR"){super(e,t),this.name="ProjectError"}static notInitialized(){return new r("Project not initialized. Run p. init first.","PROJECT_NOT_INIT")}static notFound(e){return new r(`Project not found: ${e}`,"PROJECT_NOT_FOUND")}static invalidId(e){return new r(`Invalid project ID: ${e}`,"PROJECT_INVALID_ID")}},$n=class r extends Fn{static{a(this,"AgentError")}constructor(e,t="AGENT_ERROR"){super(e,t),this.name="AgentError"}static notSupported(e){return new r(`Unsupported agent type: ${e}`,"AGENT_NOT_SUPPORTED")}static initFailed(e){return new r(`Agent initialization failed: ${e}`,"AGENT_INIT_FAILED")}};a(nw,"isPrjctError");a(Ee,"getErrorMessage")});function Wd(r){let e=r.toLowerCase();return e.includes("github")?"github":e.includes("gitlab")?"gitlab":e.includes("bitbucket")?"bitbucket":"other"}function ia(r){let e=r.trim();if(!e)return{};let t=e.match(/^[^/@]+@([^:/]+):(.+?)(?:\.git)?\/?$/);if(t)return{provider:Wd(t[1]),repoSlug:t[2]};try{let n=new URL(e),s=n.pathname.replace(/^\/+/,"").replace(/\.git$/,"").replace(/\/+$/,"");return!n.host||!s?{}:{provider:Wd(n.host),repoSlug:s}}catch{return{}}}async function sw(r){try{let{stdout:e}=await V("git",["remote","get-url","origin"],{cwd:r});return e.trim()||void 0}catch{return}}async function iw(r){try{let{stdout:e}=await V("git",["symbolic-ref","--short","refs/remotes/origin/HEAD"],{cwd:r});return e.trim().replace(/^origin\//,"")||void 0}catch{return}}function ar(r){return typeof r=="string"&&r.length>0?r:void 0}function Bd(r){return typeof r=="number"&&Number.isFinite(r)?r:void 0}function ow(r){return Object.fromEntries(Object.entries(r).filter(([,e])=>e!==void 0))}async function Gd(r){let e=y.getDoc(r,"project")||{},t=ar(e.repoPath),{provider:n,repoSlug:s}=t?ia(await sw(t)||""):{},i=t?await iw(t):void 0,o=Array.isArray(e.techStack)?e.techStack.filter(c=>typeof c=="string"):void 0;return ow({provider:n,repoSlug:s,currentBranch:ar(e.currentBranch),defaultBranch:i,stack:ar(e.stack),techStack:o&&o.length>0?o:void 0,version:ar(e.version),commitCount:Bd(e.commitCount),fileCount:Bd(e.fileCount),lastCommit:ar(e.lastSyncCommit),hasUncommitted:typeof e.hasUncommittedChanges=="boolean"?e.hasUncommittedChanges:void 0,cliVersion:ar(e.cliVersion),syncedAt:ar(e.lastSync)})}var oa=f(()=>{"use strict";I();le();a(Wd,"providerForHost");a(ia,"parseRemote");a(sw,"gitRemoteUrl");a(iw,"gitDefaultBranch");a(ar,"str");a(Bd,"num");a(ow,"compact");a(Gd,"buildProjectMeta")});import{execFile as aw}from"node:child_process";import cw from"node:crypto";import{promisify as lw}from"node:util";function pw(r,e=dw){let t=Buffer.from(e.replace(/-/g,""),"hex"),s=cw.createHash("sha1").update(t).update(r,"utf8").digest().subarray(0,16);s[6]=s[6]&15|80,s[8]=s[8]&63|128;let i=s.toString("hex");return`${i.slice(0,8)}-${i.slice(8,12)}-${i.slice(12,16)}-${i.slice(16,20)}-${i.slice(20,32)}`}async function mw(r){let e;try{let{stdout:s}=await uw("git",["remote","get-url","origin"],{cwd:r});e=s.trim()||void 0}catch{return null}if(!e)return null;let{provider:t,repoSlug:n}=ia(e);return!t||!n?null:`${t}:${n}`.toLowerCase()}async function Xd(r){let e=await mw(r);return e?pw(e):null}var uw,dw,qd=f(()=>{"use strict";oa();uw=lw(aw),dw="6f9b2c1a-3d4e-5f60-8a7b-1c2d3e4f5a6b";a(pw,"uuidv5");a(mw,"repoKey");a(Xd,"deriveProjectId")});var la={};Q(la,{PACKAGE_ROOT:()=>Bt,VERSION:()=>Wt,getPackageRoot:()=>ca,getVersion:()=>Js,resetPackageRoot:()=>gw});import aa from"node:fs";import zs from"node:path";function ca(){if(Wr)return Wr;let r=__dirname;for(let e=0;e<5;e++){let t=zs.join(r,"package.json");if(aa.existsSync(t))try{if(JSON.parse(aa.readFileSync(t,"utf-8")).name==="prjct-cli")return Wr=r,r}catch{}r=zs.dirname(r)}return Wr=zs.join(__dirname,"..","..",".."),Wr}function Js(){if(cr)return cr;let r="3.24.1";if(r&&/^\d+\.\d+\.\d+/.test(r))return cr=r,cr;try{let e=zs.join(ca(),"package.json");return cr=JSON.parse(aa.readFileSync(e,"utf-8")).version,cr}catch(e){return process.env.PRJCT_DEBUG==="1"&&console.error("Failed to read version from package.json:",w(e)),"0.0.0"}}function gw(r){Wr=r,cr=null}var cr,Wr,Wt,Bt,vt=f(()=>{"use strict";z();cr=null,Wr=null;a(ca,"getPackageRoot");a(Js,"getVersion");a(gw,"resetPackageRoot");Wt=Js(),Bt=ca()});async function Qs(r){try{let{stdout:e}=await N(r,{timeout:5e3});return{success:!0,output:e.trim()}}catch{return{success:!1,output:""}}}async function fw(){let r=await Qs("gh api user --jq .login");return r.success&&r.output||(r=await Qs("git config --global github.user"),r.success&&r.output)?r.output:null}async function hw(){let r=await Qs("git config user.name");return r.success&&r.output?r.output:null}async function yw(){let r=await Qs("git config user.email");return r.success&&r.output?r.output:null}async function Br(){let[r,e,t]=await Promise.all([fw(),hw(),yw()]);return{github:r,email:t,name:e||r||"Unknown"}}var Zs=f(()=>{"use strict";le();a(Qs,"execCommand");a(fw,"detectGitHubUsername");a(hw,"detectGitName");a(yw,"detectGitEmail");a(Br,"detect")});var ma={};Q(ma,{worktreeService:()=>Ew});import da from"node:fs/promises";import dt from"node:path";var Vd,pa,Ew,ga=f(()=>{"use strict";le();J();Vd=".worktrees",pa=class{static{a(this,"WorktreeService")}async create(e,t,n={}){let s=await this.getMainWorktree(e),i=dt.join(s,Vd,t),o=n.branch||`feat/${t}`;await da.mkdir(dt.join(s,Vd),{recursive:!0});let c=n.baseBranch?` ${n.baseBranch}`:"";await N(`git worktree add "${i}" -b "${o}"${c}`,{cwd:s});let{stdout:l}=await N("git rev-parse HEAD",{cwd:i});return{path:i,branch:o,commit:l.trim(),isMain:!1,slug:t}}async remove(e,t=!1){let n=await this.getMainWorktree(e),s;if(t)try{let{stdout:i}=await N("git rev-parse --abbrev-ref HEAD",{cwd:e});s=i.trim()}catch{}if(await N(`git worktree remove "${e}" --force`,{cwd:n}),t&&s&&s!=="main"&&s!=="master")try{await N(`git branch -D "${s}"`,{cwd:n})}catch{}}async list(e){let t=await this.getMainWorktree(e),{stdout:n}=await N("git worktree list --porcelain",{cwd:t});return this.parsePorcelainOutput(n,t)}async detect(e){try{let{stdout:t}=await N("git rev-parse --git-common-dir",{cwd:e}),{stdout:n}=await N("git rev-parse --git-dir",{cwd:e}),s=dt.resolve(e,t.trim()),i=dt.resolve(e,n.trim());if(s!==i){let{stdout:o}=await N("git rev-parse --abbrev-ref HEAD",{cwd:e}),{stdout:c}=await N("git rev-parse HEAD",{cwd:e}),{stdout:l}=await N("git rev-parse --show-toplevel",{cwd:e}),u=l.trim(),d=dt.basename(u);return{path:u,branch:o.trim(),commit:c.trim(),isMain:!1,slug:d}}return null}catch{return null}}async getMainWorktree(e){try{let{stdout:n}=await N("git worktree list --porcelain",{cwd:e}),s=n.split(`
1173
1173
  `)[0];if(s?.startsWith("worktree "))return s.replace("worktree ","").trim()}catch{}let{stdout:t}=await N("git rev-parse --show-toplevel",{cwd:e});return t.trim()}async setup(e,t){let n=dt.join(t,".env");await v(n)&&await da.copyFile(n,dt.join(e,".env"));let s=dt.join(t,".prjct"),i=dt.join(e,".prjct");await v(s)&&!await v(i)&&await da.symlink(s,i,"dir")}async teardown(e){}async clean(e){let t=await this.list(e),n=[],s=await this.getMainWorktree(e);await N("git worktree prune",{cwd:s});for(let i of t)i.isMain||await v(i.path)||n.push(i.slug);return n}parsePorcelainOutput(e,t){let n=[],s=e.trim().split(`
1174
1174
 
1175
1175
  `);for(let i of s){if(!i.trim())continue;let o=i.trim().split(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prjct-cli",
3
- "version": "3.24.0",
3
+ "version": "3.24.1",
4
4
  "description": "Project memory and workflow context for AI coding agents.",
5
5
  "main": "dist/bin/prjct.mjs",
6
6
  "bin": {