prjct-cli 2.16.0 → 2.17.0

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.
@@ -5,13 +5,13 @@ import { dirname as __pathDirname } from 'path';
5
5
  var require = __createRequire(import.meta.url);
6
6
  var __filename = __fileURLToPath(import.meta.url);
7
7
  var __dirname = __pathDirname(__filename);
8
- var wt=Object.defineProperty;var Pn=Object.getOwnPropertyDescriptor;var Rn=Object.getOwnPropertyNames;var An=Object.prototype.hasOwnProperty;var c=(r,t)=>wt(r,"name",{value:t,configurable:!0}),ze=(r=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(r,{get:(t,e)=>(typeof require<"u"?require:t)[e]}):r)(function(r){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+r+'" is not supported')});var w=(r,t)=>()=>(r&&(t=r(r=0)),t);var lt=(r,t)=>{for(var e in t)wt(r,e,{get:t[e],enumerable:!0})},Cn=(r,t,e,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of Rn(t))!An.call(r,n)&&n!==e&&wt(r,n,{get:()=>t[n],enumerable:!(s=Pn(t,n))||s.enumerable});return r};var Ht=r=>Cn(wt({},"__esModule",{value:!0}),r);var Ke,Ve,Qe,qt=w(()=>{"use strict";Ke=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"]),Ve=["",".ts",".tsx",".js",".jsx","/index.ts","/index.js"],Qe=/(?:import|from)\s+['"]([^'"]+)['"]/g});import{formatDistanceToNowStrict as Io}from"date-fns";function Ze(r){return{year:r.getFullYear().toString(),month:(r.getMonth()+1).toString().padStart(2,"0"),day:r.getDate().toString().padStart(2,"0")}}function g(){return new Date().toISOString()}function ts(r){let t=new Date;return t.setDate(t.getDate()-r),t}var A=w(()=>{"use strict";c(Ze,"getYearMonthDay");c(g,"getTimestamp");c(ts,"getDaysAgo")});function In(r){return r instanceof Error&&"code"in r}function D(r){return In(r)&&r.code==="ENOENT"}function es(r){return r instanceof Error?r.message:typeof r=="string"?r:"Unknown error"}var K=w(()=>{"use strict";c(In,"isNodeError");c(D,"isNotFoundError");c(es,"getErrorMessage")});import ns from"node:fs/promises";async function is(r,t){let e;try{e=await ns.readFile(r,"utf-8")}catch(i){if(D(i))return null;throw i}let s;try{s=JSON.parse(e)}catch{return await ss(r,e),rs(r,"Malformed JSON"),null}let n=t.safeParse(s);return n.success?s:(await ss(r,e),rs(r,Dn(n.error)),null)}async function ss(r,t){let e=`${r}.backup`;try{await ns.writeFile(e,t,"utf-8")}catch{}}function rs(r,t){console.error(`[prjct] Warning: Corrupted storage file: ${r}`),console.error(`[prjct] Reason: ${t}`),console.error("[prjct] A .backup file has been created. Returning defaults.")}function Dn(r){return r.issues.slice(0,3).map(t=>`${t.path.join(".")}: ${t.message}`).join("; ")}var os=w(()=>{"use strict";K();c(is,"safeRead");c(ss,"createBackup");c(rs,"logCorruption");c(Dn,"formatZodError")});import V from"node:fs/promises";import Gt from"node:path";async function as(r,t={}){let e=[],s=t.maxFiles??1/0,n=t.dotfileAllowlist?new Set(t.dotfileAllowlist):null;async function i(o){if(e.length>=s)return;let a=await V.readdir(o,{withFileTypes:!0}).catch(()=>[]);for(let u of a){if(e.length>=s)break;let p=String(u.name);if(Ke.has(p)||t.skipDotfiles&&p.startsWith(".")&&(!n||!n.has(p)))continue;let m=Gt.join(o,p);u.isDirectory()?await i(m):u.isFile()&&e.push(Gt.relative(r,m))}}return c(i,"walk"),await i(r),e}async function cs(r,t,e){let s=[];for(let n=0;n<r.length;n+=t){let i=await Promise.all(r.slice(n,n+t).map(e));for(let o of i)o!==null&&s.push(o)}return s}async function bt(r,t=null,e){if(e)return await is(r,e)??t;try{let s=await V.readFile(r,"utf-8");return JSON.parse(s)}catch(s){if(D(s))return t;throw s}}async function M(r,t,e=2){let s=Gt.dirname(r);await V.mkdir(s,{recursive:!0});let n=`${JSON.stringify(t,null,e)}
9
- `;await V.writeFile(r,n,"utf-8")}async function R(r){try{return await V.access(r),!0}catch(t){if(D(t))return!1;throw t}}async function Yt(r){try{return(await V.stat(r)).isDirectory()}catch(t){if(D(t))return!1;throw t}}async function F(r){await V.mkdir(r,{recursive:!0})}var U=w(()=>{"use strict";qt();os();K();c(as,"walkDir");c(cs,"batchProcess");c(bt,"readJson");c(M,"writeJson");c(R,"fileExists");c(Yt,"dirExists");c(F,"ensureDir")});import tt from"node:fs/promises";import N from"node:path";import{globSync as Ln}from"glob";async function Jt(r){let t={isMonorepo:!1,type:null,rootPath:r,packages:[]},e=[{file:"pnpm-workspace.yaml",type:"pnpm"},{file:"lerna.json",type:"lerna"},{file:"nx.json",type:"nx"},{file:"rush.json",type:"rush"},{file:"turbo.json",type:"turborepo"}];for(let s of e)if(await R(N.join(r,s.file))){t.isMonorepo=!0,t.type=s.type;break}if(!t.isMonorepo){let s=N.join(r,"package.json");if(await R(s))try{JSON.parse(await tt.readFile(s,"utf-8")).workspaces&&(t.isMonorepo=!0,t.type="npm")}catch{}}return t.isMonorepo&&(t.packages=await zt(r,t.type)),t}async function zt(r,t){let e=[],s=[];try{if(t==="pnpm"){let i=(await tt.readFile(N.join(r,"pnpm-workspace.yaml"),"utf-8")).match(/packages:\s*\n((?:\s*-\s*.+\n?)+)/);i&&(s=i[1].split(`
10
- `).map(o=>o.replace(/^\s*-\s*['"]?|['"]?\s*$/g,"")).filter(Boolean))}else if(t==="npm"||t==="lerna"){let n=N.join(r,"package.json"),i=JSON.parse(await tt.readFile(n,"utf-8"));if(Array.isArray(i.workspaces)?s=i.workspaces:i.workspaces?.packages&&(s=i.workspaces.packages),t==="lerna"){let o=N.join(r,"lerna.json");if(await R(o)){let a=JSON.parse(await tt.readFile(o,"utf-8"));a.packages&&(s=a.packages)}}}else if(t==="nx")s=["apps/*","libs/*","packages/*"];else if(t==="turborepo"){let n=N.join(r,"package.json"),i=JSON.parse(await tt.readFile(n,"utf-8"));Array.isArray(i.workspaces)&&(s=i.workspaces)}s.length===0&&(s=["packages/*","apps/*","libs/*"]);for(let n of s){if(n.startsWith("!"))continue;let i=Ln(n,{cwd:r,absolute:!1});for(let o of i){let a=N.join(r,o),u=N.join(a,"package.json");if(await R(u))try{let p=JSON.parse(await tt.readFile(u,"utf-8")),m=N.join(a,"PRJCT.md");e.push({name:p.name||N.basename(o),path:a,relativePath:o,hasPrjctMd:await R(m)})}catch{}}}}catch{}return e}async function us(r,t){if(!t.isMonorepo)return null;let e=N.resolve(r);for(let s of t.packages){let n=N.resolve(s.path);if(e.startsWith(n))return s}return null}async function ls(r){let t=N.resolve(r),e=N.parse(t).root;for(;t!==e;){if((await Jt(t)).isMonorepo)return t;t=N.dirname(t)}return null}var ps=w(()=>{"use strict";U();c(Jt,"detectMonorepo");c(zt,"discoverMonorepoPackages");c(us,"findContainingPackage");c(ls,"findMonorepoRoot")});import{exec as On,execFile as jn}from"node:child_process";import{promisify as ds}from"node:util";var b,Zo,et=w(()=>{"use strict";b=ds(On),Zo=ds(jn)});var Qt={};lt(Qt,{default:()=>Mn,worktreeService:()=>gs});import Kt from"node:fs/promises";import X from"node:path";var ms,Vt,gs,Mn,Zt=w(()=>{"use strict";et();U();ms=".worktrees",Vt=class{static{c(this,"WorktreeService")}async create(t,e,s={}){let n=await this.getMainWorktree(t),i=X.join(n,ms,e),o=s.branch||`feat/${e}`;await Kt.mkdir(X.join(n,ms),{recursive:!0});let a=s.baseBranch?` ${s.baseBranch}`:"";await b(`git worktree add "${i}" -b "${o}"${a}`,{cwd:n});let{stdout:u}=await b("git rev-parse HEAD",{cwd:i});return{path:i,branch:o,commit:u.trim(),isMain:!1,slug:e}}async remove(t,e=!1){let s=await this.getMainWorktree(t),n;if(e)try{let{stdout:i}=await b("git rev-parse --abbrev-ref HEAD",{cwd:t});n=i.trim()}catch{}if(await b(`git worktree remove "${t}" --force`,{cwd:s}),e&&n&&n!=="main"&&n!=="master")try{await b(`git branch -D "${n}"`,{cwd:s})}catch{}}async list(t){let e=await this.getMainWorktree(t),{stdout:s}=await b("git worktree list --porcelain",{cwd:e});return this.parsePorcelainOutput(s,e)}async detect(t){try{let{stdout:e}=await b("git rev-parse --git-common-dir",{cwd:t}),{stdout:s}=await b("git rev-parse --git-dir",{cwd:t}),n=X.resolve(t,e.trim()),i=X.resolve(t,s.trim());if(n!==i){let{stdout:o}=await b("git rev-parse --abbrev-ref HEAD",{cwd:t}),{stdout:a}=await b("git rev-parse HEAD",{cwd:t}),{stdout:u}=await b("git rev-parse --show-toplevel",{cwd:t}),p=u.trim(),m=X.basename(p);return{path:p,branch:o.trim(),commit:a.trim(),isMain:!1,slug:m}}return null}catch{return null}}async getMainWorktree(t){try{let{stdout:s}=await b("git worktree list --porcelain",{cwd:t}),n=s.split(`
11
- `)[0];if(n?.startsWith("worktree "))return n.replace("worktree ","").trim()}catch{}let{stdout:e}=await b("git rev-parse --show-toplevel",{cwd:t});return e.trim()}async setup(t,e){let s=X.join(e,".env");await R(s)&&await Kt.copyFile(s,X.join(t,".env"));let n=X.join(e,".prjct"),i=X.join(t,".prjct");await R(n)&&!await R(i)&&await Kt.symlink(n,i,"dir")}async teardown(t){}async clean(t){let e=await this.list(t),s=[],n=await this.getMainWorktree(t);await b("git worktree prune",{cwd:n});for(let i of e)i.isMain||await R(i.path)||s.push(i.slug);return s}parsePorcelainOutput(t,e){let s=[],n=t.trim().split(`
8
+ var _t=Object.defineProperty;var Mn=Object.getOwnPropertyDescriptor;var Fn=Object.getOwnPropertyNames;var Un=Object.prototype.hasOwnProperty;var c=(r,t)=>_t(r,"name",{value:t,configurable:!0}),ts=(r=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(r,{get:(t,e)=>(typeof require<"u"?require:t)[e]}):r)(function(r){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+r+'" is not supported')});var k=(r,t)=>()=>(r&&(t=r(r=0)),t);var tt=(r,t)=>{for(var e in t)_t(r,e,{get:t[e],enumerable:!0})},Xn=(r,t,e,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of Fn(t))!Un.call(r,n)&&n!==e&&_t(r,n,{get:()=>t[n],enumerable:!(s=Mn(t,n))||s.enumerable});return r};var Jt=r=>Xn(_t({},"__esModule",{value:!0}),r);var es,ss,rs,zt=k(()=>{"use strict";es=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"]),ss=["",".ts",".tsx",".js",".jsx","/index.ts","/index.js"],rs=/(?:import|from)\s+['"]([^'"]+)['"]/g});import{formatDistanceToNowStrict as Qo}from"date-fns";function ns(r){return{year:r.getFullYear().toString(),month:(r.getMonth()+1).toString().padStart(2,"0"),day:r.getDate().toString().padStart(2,"0")}}function g(){return new Date().toISOString()}function is(r){let t=new Date;return t.setDate(t.getDate()-r),t}var A=k(()=>{"use strict";c(ns,"getYearMonthDay");c(g,"getTimestamp");c(is,"getDaysAgo")});function Wn(r){return r instanceof Error&&"code"in r}function L(r){return Wn(r)&&r.code==="ENOENT"}function os(r){return r instanceof Error?r.message:typeof r=="string"?r:"Unknown error"}var K=k(()=>{"use strict";c(Wn,"isNodeError");c(L,"isNotFoundError");c(os,"getErrorMessage")});import us from"node:fs/promises";async function ls(r,t){let e;try{e=await us.readFile(r,"utf-8")}catch(i){if(L(i))return null;throw i}let s;try{s=JSON.parse(e)}catch{return await as(r,e),cs(r,"Malformed JSON"),null}let n=t.safeParse(s);return n.success?s:(await as(r,e),cs(r,Bn(n.error)),null)}async function as(r,t){let e=`${r}.backup`;try{await us.writeFile(e,t,"utf-8")}catch{}}function cs(r,t){console.error(`[prjct] Warning: Corrupted storage file: ${r}`),console.error(`[prjct] Reason: ${t}`),console.error("[prjct] A .backup file has been created. Returning defaults.")}function Bn(r){return r.issues.slice(0,3).map(t=>`${t.path.join(".")}: ${t.message}`).join("; ")}var ps=k(()=>{"use strict";K();c(ls,"safeRead");c(as,"createBackup");c(cs,"logCorruption");c(Bn,"formatZodError")});import V from"node:fs/promises";import Kt from"node:path";async function ds(r,t={}){let e=[],s=t.maxFiles??1/0,n=t.dotfileAllowlist?new Set(t.dotfileAllowlist):null;async function i(o){if(e.length>=s)return;let a=await V.readdir(o,{withFileTypes:!0}).catch(()=>[]);for(let u of a){if(e.length>=s)break;let p=String(u.name);if(es.has(p)||t.skipDotfiles&&p.startsWith(".")&&(!n||!n.has(p)))continue;let m=Kt.join(o,p);u.isDirectory()?await i(m):u.isFile()&&e.push(Kt.relative(r,m))}}return c(i,"walk"),await i(r),e}async function ms(r,t,e){let s=[];for(let n=0;n<r.length;n+=t){let i=await Promise.all(r.slice(n,n+t).map(e));for(let o of i)o!==null&&s.push(o)}return s}async function vt(r,t=null,e){if(e)return await ls(r,e)??t;try{let s=await V.readFile(r,"utf-8");return JSON.parse(s)}catch(s){if(L(s))return t;throw s}}async function F(r,t,e=2){let s=Kt.dirname(r);await V.mkdir(s,{recursive:!0});let n=`${JSON.stringify(t,null,e)}
9
+ `;await V.writeFile(r,n,"utf-8")}async function R(r){try{return await V.access(r),!0}catch(t){if(L(t))return!1;throw t}}async function Vt(r){try{return(await V.stat(r)).isDirectory()}catch(t){if(L(t))return!1;throw t}}async function U(r){await V.mkdir(r,{recursive:!0})}var X=k(()=>{"use strict";zt();ps();K();c(ds,"walkDir");c(ms,"batchProcess");c(vt,"readJson");c(F,"writeJson");c(R,"fileExists");c(Vt,"dirExists");c(U,"ensureDir")});import et from"node:fs/promises";import N from"node:path";import{globSync as Hn}from"glob";async function Qt(r){let t={isMonorepo:!1,type:null,rootPath:r,packages:[]},e=[{file:"pnpm-workspace.yaml",type:"pnpm"},{file:"lerna.json",type:"lerna"},{file:"nx.json",type:"nx"},{file:"rush.json",type:"rush"},{file:"turbo.json",type:"turborepo"}];for(let s of e)if(await R(N.join(r,s.file))){t.isMonorepo=!0,t.type=s.type;break}if(!t.isMonorepo){let s=N.join(r,"package.json");if(await R(s))try{JSON.parse(await et.readFile(s,"utf-8")).workspaces&&(t.isMonorepo=!0,t.type="npm")}catch{}}return t.isMonorepo&&(t.packages=await Zt(r,t.type)),t}async function Zt(r,t){let e=[],s=[];try{if(t==="pnpm"){let i=(await et.readFile(N.join(r,"pnpm-workspace.yaml"),"utf-8")).match(/packages:\s*\n((?:\s*-\s*.+\n?)+)/);i&&(s=i[1].split(`
10
+ `).map(o=>o.replace(/^\s*-\s*['"]?|['"]?\s*$/g,"")).filter(Boolean))}else if(t==="npm"||t==="lerna"){let n=N.join(r,"package.json"),i=JSON.parse(await et.readFile(n,"utf-8"));if(Array.isArray(i.workspaces)?s=i.workspaces:i.workspaces?.packages&&(s=i.workspaces.packages),t==="lerna"){let o=N.join(r,"lerna.json");if(await R(o)){let a=JSON.parse(await et.readFile(o,"utf-8"));a.packages&&(s=a.packages)}}}else if(t==="nx")s=["apps/*","libs/*","packages/*"];else if(t==="turborepo"){let n=N.join(r,"package.json"),i=JSON.parse(await et.readFile(n,"utf-8"));Array.isArray(i.workspaces)&&(s=i.workspaces)}s.length===0&&(s=["packages/*","apps/*","libs/*"]);for(let n of s){if(n.startsWith("!"))continue;let i=Hn(n,{cwd:r,absolute:!1});for(let o of i){let a=N.join(r,o),u=N.join(a,"package.json");if(await R(u))try{let p=JSON.parse(await et.readFile(u,"utf-8")),m=N.join(a,"PRJCT.md");e.push({name:p.name||N.basename(o),path:a,relativePath:o,hasPrjctMd:await R(m)})}catch{}}}}catch{}return e}async function gs(r,t){if(!t.isMonorepo)return null;let e=N.resolve(r);for(let s of t.packages){let n=N.resolve(s.path);if(e.startsWith(n))return s}return null}async function fs(r){let t=N.resolve(r),e=N.parse(t).root;for(;t!==e;){if((await Qt(t)).isMonorepo)return t;t=N.dirname(t)}return null}var hs=k(()=>{"use strict";X();c(Qt,"detectMonorepo");c(Zt,"discoverMonorepoPackages");c(gs,"findContainingPackage");c(fs,"findMonorepoRoot")});import{exec as qn,execFile as Gn}from"node:child_process";import{promisify as ys}from"node:util";var b,ka,st=k(()=>{"use strict";b=ys(qn),ka=ys(Gn)});var se={};tt(se,{default:()=>Yn,worktreeService:()=>ks});import te from"node:fs/promises";import $ from"node:path";var Ts,ee,ks,Yn,re=k(()=>{"use strict";st();X();Ts=".worktrees",ee=class{static{c(this,"WorktreeService")}async create(t,e,s={}){let n=await this.getMainWorktree(t),i=$.join(n,Ts,e),o=s.branch||`feat/${e}`;await te.mkdir($.join(n,Ts),{recursive:!0});let a=s.baseBranch?` ${s.baseBranch}`:"";await b(`git worktree add "${i}" -b "${o}"${a}`,{cwd:n});let{stdout:u}=await b("git rev-parse HEAD",{cwd:i});return{path:i,branch:o,commit:u.trim(),isMain:!1,slug:e}}async remove(t,e=!1){let s=await this.getMainWorktree(t),n;if(e)try{let{stdout:i}=await b("git rev-parse --abbrev-ref HEAD",{cwd:t});n=i.trim()}catch{}if(await b(`git worktree remove "${t}" --force`,{cwd:s}),e&&n&&n!=="main"&&n!=="master")try{await b(`git branch -D "${n}"`,{cwd:s})}catch{}}async list(t){let e=await this.getMainWorktree(t),{stdout:s}=await b("git worktree list --porcelain",{cwd:e});return this.parsePorcelainOutput(s,e)}async detect(t){try{let{stdout:e}=await b("git rev-parse --git-common-dir",{cwd:t}),{stdout:s}=await b("git rev-parse --git-dir",{cwd:t}),n=$.resolve(t,e.trim()),i=$.resolve(t,s.trim());if(n!==i){let{stdout:o}=await b("git rev-parse --abbrev-ref HEAD",{cwd:t}),{stdout:a}=await b("git rev-parse HEAD",{cwd:t}),{stdout:u}=await b("git rev-parse --show-toplevel",{cwd:t}),p=u.trim(),m=$.basename(p);return{path:p,branch:o.trim(),commit:a.trim(),isMain:!1,slug:m}}return null}catch{return null}}async getMainWorktree(t){try{let{stdout:s}=await b("git worktree list --porcelain",{cwd:t}),n=s.split(`
11
+ `)[0];if(n?.startsWith("worktree "))return n.replace("worktree ","").trim()}catch{}let{stdout:e}=await b("git rev-parse --show-toplevel",{cwd:t});return e.trim()}async setup(t,e){let s=$.join(e,".env");await R(s)&&await te.copyFile(s,$.join(t,".env"));let n=$.join(e,".prjct"),i=$.join(t,".prjct");await R(n)&&!await R(i)&&await te.symlink(n,i,"dir")}async teardown(t){}async clean(t){let e=await this.list(t),s=[],n=await this.getMainWorktree(t);await b("git worktree prune",{cwd:n});for(let i of e)i.isMain||await R(i.path)||s.push(i.slug);return s}parsePorcelainOutput(t,e){let s=[],n=t.trim().split(`
12
12
 
13
13
  `);for(let i of n){if(!i.trim())continue;let o=i.trim().split(`
14
- `),a="",u="",p="",m=!1;for(let d of o)d.startsWith("worktree ")?a=d.replace("worktree ","").trim():d.startsWith("HEAD ")?u=d.replace("HEAD ","").trim():d.startsWith("branch ")?p=d.replace("branch refs/heads/","").trim():d==="bare"?m=!0:d==="detached"&&(p="(detached)");if(a){let d=a===e||m;s.push({path:a,branch:p,commit:u,isMain:d,slug:d?"main":X.basename(a)})}}return s}},gs=new Vt,Mn=gs});import te from"node:os";import $ from"node:path";async function fs(r,t){if(t&&t.trim().length>0)return Un(r,t);let e=await Fn(r),n=$.basename($.resolve(e)).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"project";return $.join(te.homedir(),"Documents","prjct",n)}function hs(r,t){let s=$.basename($.resolve(r)).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"project",n=t.replace(/-/g,"").slice(0,8);return $.join(te.homedir(),"Documents","prjct",`${s}-${n}`)}function ys(r){return $.join(r,".prjct","wiki")}async function Fn(r){try{let{worktreeService:t}=await Promise.resolve().then(()=>(Zt(),Qt));return await t.detect(r)&&await t.getMainWorktree(r)||r}catch{return r}}function Un(r,t){let e=t.trim();return(e.startsWith("~/")||e==="~")&&(e=$.join(te.homedir(),e.slice(1))),$.isAbsolute(e)||(e=$.resolve(r,e)),e}var Ts=w(()=>{"use strict";c(fs,"getWikiPath");c(hs,"getWikiPathWithProjectHash");c(ys,"getLegacyWikiPath");c(Fn,"resolveProjectRootPath");c(Un,"resolveVaultOverride")});var ks=w(()=>{"use strict"});import{z as pt}from"zod";function Es(r,t){let e=r.split(".").map(Number),s=t.split(".").map(Number);for(let n=0;n<3;n++){let i=e[n]??0,o=s[n]??0;if(i<o)return-1;if(i>o)return 1}return 0}var ee,se=w(()=>{"use strict";ee=pt.object({provider:pt.string(),model:pt.string(),cliVersion:pt.string().optional(),recordedAt:pt.string()});c(Es,"compareSemver")});function Ss(r,t){let e=typeof r=="string"?new Date(r).getTime():r;return Date.now()-e>t}var vt,re=w(()=>{"use strict";c(Ss,"isExpired");vt=class{static{c(this,"TTLCache")}cache=new Map;ttl;maxSize;constructor(t={}){this.ttl=t.ttl??5e3,this.maxSize=t.maxSize??50}isValid(t){let e=this.cache.get(t);return e?Date.now()-e.timestamp<this.ttl:!1}get(t){let e=this.cache.get(t);return e?this.isValid(t)?e.data:(this.cache.delete(t),null):null}set(t,e){this.cache.set(t,{data:e,timestamp:Date.now()}),this.evictOldEntries()}delete(t){this.cache.delete(t)}clear(){this.cache.clear()}has(t){return this.cache.has(t)}get size(){return this.cache.size}evictOldEntries(){if(this.cache.size<=this.maxSize)return;let e=Array.from(this.cache.entries()).sort((s,n)=>s[1].timestamp-n[1].timestamp).slice(0,this.cache.size-this.maxSize);for(let[s]of e)this.cache.delete(s)}stats(){return{size:this.cache.size,maxSize:this.maxSize,ttl:this.ttl}}prune(){let t=0;for(let e of this.cache.keys())this.isValid(e)||(this.cache.delete(e),t++);return t}}});import Xn from"node:fs/promises";import $n from"node:os";import ws from"node:path";async function _s(){try{let r=await Xn.readFile(bs,"utf-8"),t=JSON.parse(r);return!t.timestamp||!t.detection||!t.detection.claude||!t.detection.gemini||!t.detection.codex||Ss(t.timestamp,Bn)?null:t.detection}catch{return null}}async function vs(r){let t={timestamp:new Date().toISOString(),detection:r};await M(bs,t)}var Wn,bs,Bn,xs=w(()=>{"use strict";re();U();Wn=ws.join($n.homedir(),".prjct-cli","cache"),bs=ws.join(Wn,"providers.json"),Bn=10*60*1e3;c(_s,"readProviderCache");c(vs,"writeProviderCache")});var Pt={};lt(Pt,{ClaudeProvider:()=>xt,CursorProvider:()=>As,GeminiProvider:()=>ie,Providers:()=>dt,detectAllProviders:()=>oe,detectAntigravity:()=>Jn,detectCodex:()=>Ds,detectProvider:()=>ne,getActiveProvider:()=>Gn,getProviderBranding:()=>Yn,selectProvider:()=>zn,validateCliVersion:()=>Is});import J from"node:os";import W from"node:path";async function Ns(r){try{let{stdout:t}=await b(`which ${r}`,{timeout:2e3});return t.trim()}catch{return null}}async function qn(r){try{let{stdout:t}=await b(`${r} --version`,{timeout:2e3}),e=t.match(/\d+\.\d+\.\d+/);return e?e[0]:t.trim()}catch{return null}}async function ne(r){let t=dt[r];if(!t.cliCommand)return{installed:!1};let e=await Ns(t.cliCommand);if(!e)return{installed:!1};let s=await qn(t.cliCommand),n=Is(r,s||void 0);return{installed:!0,version:s||void 0,path:e,versionWarning:n||void 0}}function Is(r,t){let e=dt[r];return!e.minCliVersion||!t?null:Es(t,e.minCliVersion)<0?`\u26A0\uFE0F ${e.displayName} v${t} is below minimum v${e.minCliVersion}. Some features may not work correctly.`:null}async function oe(r=!1){if(!r){let o=await _s();if(o)return o}let[t,e,s]=await Promise.all([ne("claude"),ne("gemini"),Ds()]),n={installed:s.installed},i={claude:t,gemini:e,codex:n};return await vs(i).catch(()=>{}),i}async function Gn(r){if(r&&dt[r])return dt[r];let t=await oe();return t.claude.installed&&!t.gemini.installed?xt:t.gemini.installed&&!t.claude.installed?ie:xt}function Yn(r){return{commitFooter:"Generated with [p/](https://www.prjct.app/)",signature:{claude:"\u26A1 prjct + Claude",gemini:"\u26A1 prjct + Gemini",cursor:"\u26A1 prjct + Cursor",antigravity:"\u26A1 prjct + Antigravity",windsurf:"\u26A1 prjct + Windsurf",codex:"\u26A1 prjct + Codex"}[r]||"\u26A1 prjct"}}async function Jn(){let r=Rs.configDir;if(!r)return{installed:!1,skillInstalled:!1};let t=W.join(r,"skills","prjct","SKILL.md"),[e,s]=await Promise.all([R(r),R(t)]);return{installed:e,skillInstalled:s,configPath:e?r:void 0}}async function Ds(){let r=Cs.configDir;if(!r)return{installed:!1,skillInstalled:!1};let t=await Ns("codex"),e=W.join(r,"skills","prjct","SKILL.md"),s=await R(e),n=!!t;return{installed:n,skillInstalled:s,configPath:n?r:void 0}}async function zn(){let r=await oe(),t=r.claude.installed,e=r.gemini.installed;return!t&&!e?{provider:"claude",userSelected:!1,detection:r}:t&&!e?{provider:"claude",userSelected:!1,detection:r}:e&&!t?{provider:"gemini",userSelected:!1,detection:r}:{provider:"claude",userSelected:!0,detection:r}}var xt,ie,Rs,As,Hn,Cs,dt,Rt=w(()=>{"use strict";ks();se();et();U();xs();xt={name:"claude",displayName:"Claude Code",cliCommand:"claude",configDir:W.join(J.homedir(),".claude"),contextFile:"CLAUDE.md",skillsDir:W.join(J.homedir(),".claude","skills"),commandsDir:".claude/commands",commandFormat:"md",settingsFile:"settings.json",projectSettingsFile:"settings.local.json",ignoreFile:".claudeignore",websiteUrl:"https://www.anthropic.com/claude",docsUrl:"https://docs.anthropic.com/claude-code",defaultModel:"sonnet",supportedModels:["opus","sonnet","haiku"],minCliVersion:"1.0.0",capabilityTier:"full"},ie={name:"gemini",displayName:"Gemini CLI",cliCommand:"gemini",configDir:W.join(J.homedir(),".gemini"),contextFile:"GEMINI.md",skillsDir:W.join(J.homedir(),".gemini","skills"),commandsDir:".gemini/commands",commandFormat:"toml",settingsFile:"settings.json",projectSettingsFile:"settings.json",ignoreFile:".geminiignore",websiteUrl:"https://geminicli.com",docsUrl:"https://geminicli.com/docs",defaultModel:"2.5-flash",supportedModels:["2.5-pro","2.5-flash","2.0-flash"],minCliVersion:"1.0.0",capabilityTier:"standard"},Rs={name:"antigravity",displayName:"Google Antigravity",cliCommand:null,configDir:W.join(J.homedir(),".gemini","antigravity"),contextFile:"ANTIGRAVITY.md",skillsDir:W.join(J.homedir(),".gemini","antigravity","global_skills"),commandsDir:".agent/skills",commandFormat:"md",settingsFile:"mcp_config.json",projectSettingsFile:null,ignoreFile:".agentignore",websiteUrl:"https://gemini.google.com/app/antigravity",docsUrl:"https://gemini.google.com/app/antigravity",defaultModel:null,supportedModels:[],minCliVersion:null,capabilityTier:"basic"},As={name:"cursor",displayName:"Cursor IDE",cliCommand:null,configDir:null,contextFile:"prjct.mdc",skillsDir:null,commandsDir:".cursor/commands",rulesDir:".cursor/rules",commandFormat:"md",settingsFile:null,projectSettingsFile:null,ignoreFile:".cursorignore",isProjectLevel:!0,websiteUrl:"https://cursor.com",docsUrl:"https://cursor.com/docs",defaultModel:null,supportedModels:[],minCliVersion:null,capabilityTier:"basic"},Hn={name:"windsurf",displayName:"Windsurf IDE",cliCommand:null,configDir:null,contextFile:"prjct.md",skillsDir:null,commandsDir:".windsurf/workflows",rulesDir:".windsurf/rules",commandFormat:"md",settingsFile:null,projectSettingsFile:null,ignoreFile:".windsurfignore",isProjectLevel:!0,websiteUrl:"https://windsurf.com",docsUrl:"https://docs.windsurf.com",defaultModel:null,supportedModels:[],minCliVersion:null,capabilityTier:"basic"},Cs={name:"codex",displayName:"OpenAI Codex",cliCommand:"codex",configDir:W.join(J.homedir(),".codex"),contextFile:"AGENTS.md",skillsDir:W.join(J.homedir(),".codex","skills"),commandsDir:".agents/skills",commandFormat:"md",settingsFile:null,projectSettingsFile:null,ignoreFile:".codexignore",websiteUrl:"https://openai.com/codex",docsUrl:"https://github.com/openai/codex",defaultModel:null,supportedModels:[],minCliVersion:null,capabilityTier:"basic"},dt={claude:xt,gemini:ie,cursor:As,antigravity:Rs,windsurf:Hn,codex:Cs};c(Ns,"whichCommand");c(qn,"getCliVersion");c(ne,"detectProvider");c(Is,"validateCliVersion");c(oe,"detectAllProviders");c(Gn,"getActiveProvider");c(Yn,"getProviderBranding");c(Jn,"detectAntigravity");c(Ds,"detectCodex");c(zn,"selectProvider")});import Kn from"node:crypto";import At from"node:fs/promises";import ae from"node:os";import S from"node:path";var ce,Vn,v,mt=w(()=>{"use strict";A();U();ps();Ts();ce=class{static{c(this,"PathManager")}globalBaseDir;globalProjectsDir;globalConfigDir;constructor(){let t=process.env.PRJCT_CLI_HOME?.trim();this.globalBaseDir=t?S.resolve(t):S.join(ae.homedir(),".prjct-cli"),this.globalProjectsDir=S.join(this.globalBaseDir,"projects"),this.globalConfigDir=S.join(this.globalBaseDir,"config")}setGlobalBaseDir(t){this.globalBaseDir=S.resolve(t),this.globalProjectsDir=S.join(this.globalBaseDir,"projects"),this.globalConfigDir=S.join(this.globalBaseDir,"config")}generateProjectId(t){return Kn.randomUUID()}getGlobalBasePath(){return this.globalBaseDir}getGlobalProjectPath(t){return S.join(this.globalProjectsDir,t)}getLocalConfigPath(t){return S.join(t,".prjct","prjct.config.json")}getGlobalProjectConfigPath(t){return S.join(this.getGlobalProjectPath(t),"project.json")}getLegacyPrjctPath(t){return S.join(t,".prjct")}async hasLegacyStructure(t){return await Yt(this.getLegacyPrjctPath(t))}async hasConfig(t){return await R(this.getLocalConfigPath(t))}async ensureGlobalStructure(){await F(this.globalBaseDir),await F(this.globalProjectsDir),await F(this.globalConfigDir)}async ensureProjectStructure(t){await this.ensureGlobalStructure();let e=this.getGlobalProjectPath(t),s=["core","progress","planning","analysis","memory"];for(let n of s)await F(S.join(e,n));return await F(S.join(e,"planning","tasks")),await F(S.join(e,"sessions")),e}getSessionPath(t,e=new Date){let{year:s,month:n,day:i}=Ze(e);return S.join(this.getGlobalProjectPath(t),"sessions",s,n,i)}getCurrentSessionPath(t){return this.getSessionPath(t,new Date)}async ensureSessionPath(t,e=new Date){let s=this.getSessionPath(t,e);return await F(s),s}async listSessions(t,e=null,s=null){let n=S.join(this.getGlobalProjectPath(t),"sessions"),i=[];try{let o=await At.readdir(n,{withFileTypes:!0});for(let a of o){if(!a.isDirectory()||e&&a.name!==e.toString())continue;let u=S.join(n,a.name),p=await At.readdir(u,{withFileTypes:!0});for(let m of p){if(!m.isDirectory()||s&&m.name!==s.toString().padStart(2,"0"))continue;let d=S.join(u,m.name),h=await At.readdir(d,{withFileTypes:!0});for(let y of h)y.isDirectory()&&i.push({year:a.name,month:m.name,day:y.name,path:S.join(d,y.name),date:new Date(`${a.name}-${m.name}-${y.name}`)})}}return i.sort((a,u)=>u.date.getTime()-a.date.getTime()),i}catch{return[]}}async getSessionsInRange(t,e,s=new Date){return(await this.listSessions(t)).filter(i=>i.date>=e&&i.date<=s)}getFilePath(t,e,s){return S.join(this.getGlobalProjectPath(t),e,s)}async listProjects(){try{return await this.ensureGlobalStructure(),(await At.readdir(this.globalProjectsDir,{withFileTypes:!0})).filter(e=>e.isDirectory()).map(e=>e.name)}catch{return[]}}async projectExists(t){return await Yt(this.getGlobalProjectPath(t))}getDisplayPath(t){let e=ae.homedir();return t.startsWith(e)?t.replace(e,"~"):t}getAuthConfigPath(){return S.join(this.globalConfigDir,"auth.json")}getSyncPendingPath(t){return S.join(this.getGlobalProjectPath(t),"sync","pending.json")}getLastSyncPath(t){return S.join(this.getGlobalProjectPath(t),"sync","last-sync.json")}getRunningStatusPath(){return S.join(this.globalBaseDir,".running")}getDocsPath(){return S.join(this.globalBaseDir,"docs")}async getAgentDir(){return(await(Rt(),Ht(Pt)).getActiveProvider()).configDir}async getAgentSettingsPath(){let t=await(Rt(),Ht(Pt)).getActiveProvider();return(Rt(),Ht(Pt)).getGlobalSettingsPath(t.name)}getClaudeDir(){return S.join(ae.homedir(),".claude")}getClaudeSettingsPath(){return S.join(this.getClaudeDir(),"settings.json")}getStoragePath(t,e){return S.join(this.getGlobalProjectPath(t),"storage",e)}getContextPath(t){return S.join(this.getGlobalProjectPath(t),"context")}async getWikiPath(t,e){return fs(t,e)}getWikiPathWithProjectHash(t,e){return hs(t,e)}getLegacyWikiPath(t){return ys(t)}async detectMonorepo(t){return Jt(t)}async discoverMonorepoPackages(t,e){return zt(t,e)}async findContainingPackage(t,e){return us(t,e)}async findMonorepoRoot(t){return ls(t)}},Vn=new ce,v=Vn});var Ls,Os=w(()=>{"use strict";Ls=`
14
+ `),a="",u="",p="",m=!1;for(let d of o)d.startsWith("worktree ")?a=d.replace("worktree ","").trim():d.startsWith("HEAD ")?u=d.replace("HEAD ","").trim():d.startsWith("branch ")?p=d.replace("branch refs/heads/","").trim():d==="bare"?m=!0:d==="detached"&&(p="(detached)");if(a){let d=a===e||m;s.push({path:a,branch:p,commit:u,isMain:d,slug:d?"main":$.basename(a)})}}return s}},ks=new ee,Yn=ks});import ne from"node:os";import W from"node:path";async function Es(r,t){if(t&&t.trim().length>0)return zn(r,t);let e=await Jn(r),n=W.basename(W.resolve(e)).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"project";return W.join(ne.homedir(),"Documents","prjct",n)}function Ss(r,t){let s=W.basename(W.resolve(r)).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"project",n=t.replace(/-/g,"").slice(0,8);return W.join(ne.homedir(),"Documents","prjct",`${s}-${n}`)}function ws(r){return W.join(r,".prjct","wiki")}async function Jn(r){try{let{worktreeService:t}=await Promise.resolve().then(()=>(re(),se));return await t.detect(r)&&await t.getMainWorktree(r)||r}catch{return r}}function zn(r,t){let e=t.trim();return(e.startsWith("~/")||e==="~")&&(e=W.join(ne.homedir(),e.slice(1))),W.isAbsolute(e)||(e=W.resolve(r,e)),e}var bs=k(()=>{"use strict";c(Es,"getWikiPath");c(Ss,"getWikiPathWithProjectHash");c(ws,"getLegacyWikiPath");c(Jn,"resolveProjectRootPath");c(zn,"resolveVaultOverride")});var _s=k(()=>{"use strict"});import{z as pt}from"zod";function vs(r,t){let e=r.split(".").map(Number),s=t.split(".").map(Number);for(let n=0;n<3;n++){let i=e[n]??0,o=s[n]??0;if(i<o)return-1;if(i>o)return 1}return 0}var ie,oe=k(()=>{"use strict";ie=pt.object({provider:pt.string(),model:pt.string(),cliVersion:pt.string().optional(),recordedAt:pt.string()});c(vs,"compareSemver")});function xs(r,t){let e=typeof r=="string"?new Date(r).getTime():r;return Date.now()-e>t}var Pt,ae=k(()=>{"use strict";c(xs,"isExpired");Pt=class{static{c(this,"TTLCache")}cache=new Map;ttl;maxSize;constructor(t={}){this.ttl=t.ttl??5e3,this.maxSize=t.maxSize??50}isValid(t){let e=this.cache.get(t);return e?Date.now()-e.timestamp<this.ttl:!1}get(t){let e=this.cache.get(t);return e?this.isValid(t)?e.data:(this.cache.delete(t),null):null}set(t,e){this.cache.set(t,{data:e,timestamp:Date.now()}),this.evictOldEntries()}delete(t){this.cache.delete(t)}clear(){this.cache.clear()}has(t){return this.cache.has(t)}get size(){return this.cache.size}evictOldEntries(){if(this.cache.size<=this.maxSize)return;let e=Array.from(this.cache.entries()).sort((s,n)=>s[1].timestamp-n[1].timestamp).slice(0,this.cache.size-this.maxSize);for(let[s]of e)this.cache.delete(s)}stats(){return{size:this.cache.size,maxSize:this.maxSize,ttl:this.ttl}}prune(){let t=0;for(let e of this.cache.keys())this.isValid(e)||(this.cache.delete(e),t++);return t}}});import Kn from"node:fs/promises";import Vn from"node:os";import Ps from"node:path";async function As(){try{let r=await Kn.readFile(Rs,"utf-8"),t=JSON.parse(r);return!t.timestamp||!t.detection||!t.detection.claude||!t.detection.gemini||!t.detection.codex||xs(t.timestamp,Zn)?null:t.detection}catch{return null}}async function Cs(r){let t={timestamp:new Date().toISOString(),detection:r};await F(Rs,t)}var Qn,Rs,Zn,Ns=k(()=>{"use strict";ae();X();Qn=Ps.join(Vn.homedir(),".prjct-cli","cache"),Rs=Ps.join(Qn,"providers.json"),Zn=10*60*1e3;c(As,"readProviderCache");c(Cs,"writeProviderCache")});var At={};tt(At,{ClaudeProvider:()=>Rt,CursorProvider:()=>Ls,GeminiProvider:()=>ue,Providers:()=>dt,detectAllProviders:()=>le,detectAntigravity:()=>ni,detectCodex:()=>Fs,detectProvider:()=>ce,getActiveProvider:()=>si,getProviderBranding:()=>ri,selectProvider:()=>ii,validateCliVersion:()=>Ms});import J from"node:os";import B from"node:path";async function js(r){try{let{stdout:t}=await b(`which ${r}`,{timeout:2e3});return t.trim()}catch{return null}}async function ei(r){try{let{stdout:t}=await b(`${r} --version`,{timeout:2e3}),e=t.match(/\d+\.\d+\.\d+/);return e?e[0]:t.trim()}catch{return null}}async function ce(r){let t=dt[r];if(!t.cliCommand)return{installed:!1};let e=await js(t.cliCommand);if(!e)return{installed:!1};let s=await ei(t.cliCommand),n=Ms(r,s||void 0);return{installed:!0,version:s||void 0,path:e,versionWarning:n||void 0}}function Ms(r,t){let e=dt[r];return!e.minCliVersion||!t?null:vs(t,e.minCliVersion)<0?`\u26A0\uFE0F ${e.displayName} v${t} is below minimum v${e.minCliVersion}. Some features may not work correctly.`:null}async function le(r=!1){if(!r){let o=await As();if(o)return o}let[t,e,s]=await Promise.all([ce("claude"),ce("gemini"),Fs()]),n={installed:s.installed},i={claude:t,gemini:e,codex:n};return await Cs(i).catch(()=>{}),i}async function si(r){if(r&&dt[r])return dt[r];let t=await le();return t.claude.installed&&!t.gemini.installed?Rt:t.gemini.installed&&!t.claude.installed?ue:Rt}function ri(r){return{commitFooter:"Generated with [p/](https://www.prjct.app/)",signature:{claude:"\u26A1 prjct + Claude",gemini:"\u26A1 prjct + Gemini",cursor:"\u26A1 prjct + Cursor",antigravity:"\u26A1 prjct + Antigravity",windsurf:"\u26A1 prjct + Windsurf",codex:"\u26A1 prjct + Codex"}[r]||"\u26A1 prjct"}}async function ni(){let r=Ds.configDir;if(!r)return{installed:!1,skillInstalled:!1};let t=B.join(r,"skills","prjct","SKILL.md"),[e,s]=await Promise.all([R(r),R(t)]);return{installed:e,skillInstalled:s,configPath:e?r:void 0}}async function Fs(){let r=Os.configDir;if(!r)return{installed:!1,skillInstalled:!1};let t=await js("codex"),e=B.join(r,"skills","prjct","SKILL.md"),s=await R(e),n=!!t;return{installed:n,skillInstalled:s,configPath:n?r:void 0}}async function ii(){let r=await le(),t=r.claude.installed,e=r.gemini.installed;return!t&&!e?{provider:"claude",userSelected:!1,detection:r}:t&&!e?{provider:"claude",userSelected:!1,detection:r}:e&&!t?{provider:"gemini",userSelected:!1,detection:r}:{provider:"claude",userSelected:!0,detection:r}}var Rt,ue,Ds,Ls,ti,Os,dt,Ct=k(()=>{"use strict";_s();oe();st();X();Ns();Rt={name:"claude",displayName:"Claude Code",cliCommand:"claude",configDir:B.join(J.homedir(),".claude"),contextFile:"CLAUDE.md",skillsDir:B.join(J.homedir(),".claude","skills"),commandsDir:".claude/commands",commandFormat:"md",settingsFile:"settings.json",projectSettingsFile:"settings.local.json",ignoreFile:".claudeignore",websiteUrl:"https://www.anthropic.com/claude",docsUrl:"https://docs.anthropic.com/claude-code",defaultModel:"sonnet",supportedModels:["opus","sonnet","haiku"],minCliVersion:"1.0.0",capabilityTier:"full"},ue={name:"gemini",displayName:"Gemini CLI",cliCommand:"gemini",configDir:B.join(J.homedir(),".gemini"),contextFile:"GEMINI.md",skillsDir:B.join(J.homedir(),".gemini","skills"),commandsDir:".gemini/commands",commandFormat:"toml",settingsFile:"settings.json",projectSettingsFile:"settings.json",ignoreFile:".geminiignore",websiteUrl:"https://geminicli.com",docsUrl:"https://geminicli.com/docs",defaultModel:"2.5-flash",supportedModels:["2.5-pro","2.5-flash","2.0-flash"],minCliVersion:"1.0.0",capabilityTier:"standard"},Ds={name:"antigravity",displayName:"Google Antigravity",cliCommand:null,configDir:B.join(J.homedir(),".gemini","antigravity"),contextFile:"ANTIGRAVITY.md",skillsDir:B.join(J.homedir(),".gemini","antigravity","global_skills"),commandsDir:".agent/skills",commandFormat:"md",settingsFile:"mcp_config.json",projectSettingsFile:null,ignoreFile:".agentignore",websiteUrl:"https://gemini.google.com/app/antigravity",docsUrl:"https://gemini.google.com/app/antigravity",defaultModel:null,supportedModels:[],minCliVersion:null,capabilityTier:"basic"},Ls={name:"cursor",displayName:"Cursor IDE",cliCommand:null,configDir:null,contextFile:"prjct.mdc",skillsDir:null,commandsDir:".cursor/commands",rulesDir:".cursor/rules",commandFormat:"md",settingsFile:null,projectSettingsFile:null,ignoreFile:".cursorignore",isProjectLevel:!0,websiteUrl:"https://cursor.com",docsUrl:"https://cursor.com/docs",defaultModel:null,supportedModels:[],minCliVersion:null,capabilityTier:"basic"},ti={name:"windsurf",displayName:"Windsurf IDE",cliCommand:null,configDir:null,contextFile:"prjct.md",skillsDir:null,commandsDir:".windsurf/workflows",rulesDir:".windsurf/rules",commandFormat:"md",settingsFile:null,projectSettingsFile:null,ignoreFile:".windsurfignore",isProjectLevel:!0,websiteUrl:"https://windsurf.com",docsUrl:"https://docs.windsurf.com",defaultModel:null,supportedModels:[],minCliVersion:null,capabilityTier:"basic"},Os={name:"codex",displayName:"OpenAI Codex",cliCommand:"codex",configDir:B.join(J.homedir(),".codex"),contextFile:"AGENTS.md",skillsDir:B.join(J.homedir(),".codex","skills"),commandsDir:".agents/skills",commandFormat:"md",settingsFile:null,projectSettingsFile:null,ignoreFile:".codexignore",websiteUrl:"https://openai.com/codex",docsUrl:"https://github.com/openai/codex",defaultModel:null,supportedModels:[],minCliVersion:null,capabilityTier:"basic"},dt={claude:Rt,gemini:ue,cursor:Ls,antigravity:Ds,windsurf:ti,codex:Os};c(js,"whichCommand");c(ei,"getCliVersion");c(ce,"detectProvider");c(Ms,"validateCliVersion");c(le,"detectAllProviders");c(si,"getActiveProvider");c(ri,"getProviderBranding");c(ni,"detectAntigravity");c(Fs,"detectCodex");c(ii,"selectProvider")});import oi from"node:crypto";import Nt from"node:fs/promises";import pe from"node:os";import w from"node:path";var de,ai,v,mt=k(()=>{"use strict";A();X();hs();bs();de=class{static{c(this,"PathManager")}globalBaseDir;globalProjectsDir;globalConfigDir;constructor(){let t=process.env.PRJCT_CLI_HOME?.trim();this.globalBaseDir=t?w.resolve(t):w.join(pe.homedir(),".prjct-cli"),this.globalProjectsDir=w.join(this.globalBaseDir,"projects"),this.globalConfigDir=w.join(this.globalBaseDir,"config")}setGlobalBaseDir(t){this.globalBaseDir=w.resolve(t),this.globalProjectsDir=w.join(this.globalBaseDir,"projects"),this.globalConfigDir=w.join(this.globalBaseDir,"config")}generateProjectId(t){return oi.randomUUID()}getGlobalBasePath(){return this.globalBaseDir}getGlobalProjectPath(t){return w.join(this.globalProjectsDir,t)}getLocalConfigPath(t){return w.join(t,".prjct","prjct.config.json")}getGlobalProjectConfigPath(t){return w.join(this.getGlobalProjectPath(t),"project.json")}getLegacyPrjctPath(t){return w.join(t,".prjct")}async hasLegacyStructure(t){return await Vt(this.getLegacyPrjctPath(t))}async hasConfig(t){return await R(this.getLocalConfigPath(t))}async ensureGlobalStructure(){await U(this.globalBaseDir),await U(this.globalProjectsDir),await U(this.globalConfigDir)}async ensureProjectStructure(t){await this.ensureGlobalStructure();let e=this.getGlobalProjectPath(t),s=["core","progress","planning","analysis","memory"];for(let n of s)await U(w.join(e,n));return await U(w.join(e,"planning","tasks")),await U(w.join(e,"sessions")),e}getSessionPath(t,e=new Date){let{year:s,month:n,day:i}=ns(e);return w.join(this.getGlobalProjectPath(t),"sessions",s,n,i)}getCurrentSessionPath(t){return this.getSessionPath(t,new Date)}async ensureSessionPath(t,e=new Date){let s=this.getSessionPath(t,e);return await U(s),s}async listSessions(t,e=null,s=null){let n=w.join(this.getGlobalProjectPath(t),"sessions"),i=[];try{let o=await Nt.readdir(n,{withFileTypes:!0});for(let a of o){if(!a.isDirectory()||e&&a.name!==e.toString())continue;let u=w.join(n,a.name),p=await Nt.readdir(u,{withFileTypes:!0});for(let m of p){if(!m.isDirectory()||s&&m.name!==s.toString().padStart(2,"0"))continue;let d=w.join(u,m.name),h=await Nt.readdir(d,{withFileTypes:!0});for(let y of h)y.isDirectory()&&i.push({year:a.name,month:m.name,day:y.name,path:w.join(d,y.name),date:new Date(`${a.name}-${m.name}-${y.name}`)})}}return i.sort((a,u)=>u.date.getTime()-a.date.getTime()),i}catch{return[]}}async getSessionsInRange(t,e,s=new Date){return(await this.listSessions(t)).filter(i=>i.date>=e&&i.date<=s)}getFilePath(t,e,s){return w.join(this.getGlobalProjectPath(t),e,s)}async listProjects(){try{return await this.ensureGlobalStructure(),(await Nt.readdir(this.globalProjectsDir,{withFileTypes:!0})).filter(e=>e.isDirectory()).map(e=>e.name)}catch{return[]}}async projectExists(t){return await Vt(this.getGlobalProjectPath(t))}getDisplayPath(t){let e=pe.homedir();return t.startsWith(e)?t.replace(e,"~"):t}getAuthConfigPath(){return w.join(this.globalConfigDir,"auth.json")}getSyncPendingPath(t){return w.join(this.getGlobalProjectPath(t),"sync","pending.json")}getLastSyncPath(t){return w.join(this.getGlobalProjectPath(t),"sync","last-sync.json")}getRunningStatusPath(){return w.join(this.globalBaseDir,".running")}getDocsPath(){return w.join(this.globalBaseDir,"docs")}async getAgentDir(){return(await(Ct(),Jt(At)).getActiveProvider()).configDir}async getAgentSettingsPath(){let t=await(Ct(),Jt(At)).getActiveProvider();return(Ct(),Jt(At)).getGlobalSettingsPath(t.name)}getClaudeDir(){return w.join(pe.homedir(),".claude")}getClaudeSettingsPath(){return w.join(this.getClaudeDir(),"settings.json")}getStoragePath(t,e){return w.join(this.getGlobalProjectPath(t),"storage",e)}getContextPath(t){return w.join(this.getGlobalProjectPath(t),"context")}async getWikiPath(t,e){return Es(t,e)}getWikiPathWithProjectHash(t,e){return Ss(t,e)}getLegacyWikiPath(t){return ws(t)}async detectMonorepo(t){return Qt(t)}async discoverMonorepoPackages(t,e){return Zt(t,e)}async findContainingPackage(t,e){return gs(t,e)}async findMonorepoRoot(t){return fs(t)}},ai=new de,v=ai});var Us,Xs=k(()=>{"use strict";Us=`
15
15
  -- =======================================================================
16
16
  -- Document storage (backward-compatible with JSON file pattern)
17
17
  -- =======================================================================
@@ -225,7 +225,7 @@ CREATE TABLE velocity_sprints (
225
225
  started_at TEXT,
226
226
  ended_at TEXT
227
227
  );
228
- `});var js,Ms=w(()=>{"use strict";Os();js=[{version:1,name:"initial-schema",up:c(r=>{r.run(Ls)},"up")},{version:2,name:"archives-table",up:c(r=>{r.run(`
228
+ `});var $s,Ws=k(()=>{"use strict";Xs();$s=[{version:1,name:"initial-schema",up:c(r=>{r.run(Us)},"up")},{version:2,name:"archives-table",up:c(r=>{r.run(`
229
229
  -- =======================================================================
230
230
  -- Archives: Stale data moved out of active storage (PRJ-267)
231
231
  -- =======================================================================
@@ -523,84 +523,86 @@ CREATE TABLE velocity_sprints (
523
523
  );
524
524
 
525
525
  CREATE INDEX IF NOT EXISTS idx_sync_cursors_project ON sync_cursors(project_id);
526
- `)},"up")}]});function Qn(){return typeof globalThis<"u"&&"Bun"in globalThis?"bun":"node"}function Fs(){return Qn()==="bun"}var Us=w(()=>{"use strict";c(Qn,"detectRuntime");c(Fs,"isBun")});function Xs(r){if(Fs()){let{Database:n}=ze("bun:sqlite");return new n(r,{create:!0})}let t=ze("better-sqlite3"),e=new t(r),s=e.exec.bind(e);return e.run=n=>s(n),e}var $s=w(()=>{"use strict";Us();c(Xs,"openDatabase")});import ue from"node:fs";import Ws from"node:path";var Zn,le,k,T,O=w(()=>{"use strict";mt();Ms();$s();Zn=3,le=class{static{c(this,"PrjctDatabase")}connections=new Map;accessOrder=[];statementCache=new WeakMap;prepareCached(t,e){let s=this.statementCache.get(t);s||(s=new Map,this.statementCache.set(t,s));let n=s.get(e);if(n)return n;let i=t.prepare(e);return s.set(e,i),i}getDbPath(t){return Ws.join(v.getGlobalProjectPath(t),"prjct.db")}getDb(t){let e=this.connections.get(t);if(e)return this.touchAccessOrder(t),e;this.connections.size>=Zn&&this.evictLru();let s=this.getDbPath(t),n=Ws.dirname(s);ue.existsSync(n)||ue.mkdirSync(n,{recursive:!0});let i=Xs(s);return i.run("PRAGMA journal_mode = WAL"),i.run("PRAGMA synchronous = NORMAL"),i.run("PRAGMA cache_size = -2000"),i.run("PRAGMA temp_store = MEMORY"),i.run("PRAGMA mmap_size = 33554432"),this.runMigrations(i),this.connections.set(t,i),this.touchAccessOrder(t),i}close(t){if(t){let e=this.connections.get(t);e&&(e.close(),this.connections.delete(t),this.accessOrder=this.accessOrder.filter(s=>s!==t))}else this.connections.forEach(e=>{e.close()}),this.connections.clear(),this.accessOrder=[]}touchAccessOrder(t){this.accessOrder=this.accessOrder.filter(e=>e!==t),this.accessOrder.push(t)}evictLru(){if(this.accessOrder.length===0)return;let t=this.accessOrder.shift(),e=this.connections.get(t);e&&(e.close(),this.connections.delete(t))}checkpointAll(){for(let[t,e]of this.connections)try{e.run("PRAGMA wal_checkpoint(TRUNCATE)")}catch{}}exists(t){return ue.existsSync(this.getDbPath(t))}getDoc(t,e){let s=this.getDb(t),n=this.prepareCached(s,"SELECT data FROM kv_store WHERE key = ?").get(e);return n?JSON.parse(n.data):null}setDoc(t,e,s){let n=this.getDb(t),i=JSON.stringify(s),o=new Date().toISOString();this.prepareCached(n,"INSERT OR REPLACE INTO kv_store (key, data, updated_at) VALUES (?, ?, ?)").run(e,i,o)}deleteDoc(t,e){let s=this.getDb(t);this.prepareCached(s,"DELETE FROM kv_store WHERE key = ?").run(e)}hasDoc(t,e){let s=this.getDb(t);return this.prepareCached(s,"SELECT 1 FROM kv_store WHERE key = ?").get(e)!==null}appendEvent(t,e,s,n){let i=this.getDb(t),o=new Date().toISOString();this.prepareCached(i,"INSERT INTO events (type, task_id, data, timestamp) VALUES (?, ?, ?, ?)").run(e,n??null,JSON.stringify(s),o)}getEvents(t,e,s=100){let n=this.getDb(t);return e?this.prepareCached(n,"SELECT * FROM events WHERE type = ? ORDER BY id DESC LIMIT ?").all(e,s):this.prepareCached(n,"SELECT * FROM events ORDER BY id DESC LIMIT ?").all(s)}query(t,e,...s){let n=this.getDb(t);return this.prepareCached(n,e).all(...s)}run(t,e,...s){let n=this.getDb(t);this.prepareCached(n,e).run(...s)}get(t,e,...s){let n=this.getDb(t);return this.prepareCached(n,e).get(...s)??null}transaction(t,e){let s=this.getDb(t);return s.transaction(e)(s)}runMigrations(t){t.run(`
526
+ `)},"up")},{version:18,name:"specs-shipped-sha",up:c(r=>{try{r.run("ALTER TABLE specs ADD COLUMN shipped_sha TEXT")}catch{}},"up")}]});function ci(){return typeof globalThis<"u"&&"Bun"in globalThis?"bun":"node"}function Bs(){return ci()==="bun"}var Hs=k(()=>{"use strict";c(ci,"detectRuntime");c(Bs,"isBun")});function qs(r){if(Bs()){let{Database:n}=ts("bun:sqlite");return new n(r,{create:!0})}let t=ts("better-sqlite3"),e=new t(r),s=e.exec.bind(e);return e.run=n=>s(n),e}var Gs=k(()=>{"use strict";Hs();c(qs,"openDatabase")});import me from"node:fs";import Ys from"node:path";var ui,ge,E,T,O=k(()=>{"use strict";mt();Ws();Gs();ui=3,ge=class{static{c(this,"PrjctDatabase")}connections=new Map;accessOrder=[];statementCache=new WeakMap;prepareCached(t,e){let s=this.statementCache.get(t);s||(s=new Map,this.statementCache.set(t,s));let n=s.get(e);if(n)return n;let i=t.prepare(e);return s.set(e,i),i}getDbPath(t){return Ys.join(v.getGlobalProjectPath(t),"prjct.db")}getDb(t){let e=this.connections.get(t);if(e)return this.touchAccessOrder(t),e;this.connections.size>=ui&&this.evictLru();let s=this.getDbPath(t),n=Ys.dirname(s);me.existsSync(n)||me.mkdirSync(n,{recursive:!0});let i=qs(s);return i.run("PRAGMA journal_mode = WAL"),i.run("PRAGMA synchronous = NORMAL"),i.run("PRAGMA cache_size = -2000"),i.run("PRAGMA temp_store = MEMORY"),i.run("PRAGMA mmap_size = 33554432"),this.runMigrations(i),this.connections.set(t,i),this.touchAccessOrder(t),i}close(t){if(t){let e=this.connections.get(t);e&&(e.close(),this.connections.delete(t),this.accessOrder=this.accessOrder.filter(s=>s!==t))}else this.connections.forEach(e=>{e.close()}),this.connections.clear(),this.accessOrder=[]}touchAccessOrder(t){this.accessOrder=this.accessOrder.filter(e=>e!==t),this.accessOrder.push(t)}evictLru(){if(this.accessOrder.length===0)return;let t=this.accessOrder.shift(),e=this.connections.get(t);e&&(e.close(),this.connections.delete(t))}checkpointAll(){for(let[t,e]of this.connections)try{e.run("PRAGMA wal_checkpoint(TRUNCATE)")}catch{}}exists(t){return me.existsSync(this.getDbPath(t))}getDoc(t,e){let s=this.getDb(t),n=this.prepareCached(s,"SELECT data FROM kv_store WHERE key = ?").get(e);return n?JSON.parse(n.data):null}setDoc(t,e,s){let n=this.getDb(t),i=JSON.stringify(s),o=new Date().toISOString();this.prepareCached(n,"INSERT OR REPLACE INTO kv_store (key, data, updated_at) VALUES (?, ?, ?)").run(e,i,o)}deleteDoc(t,e){let s=this.getDb(t);this.prepareCached(s,"DELETE FROM kv_store WHERE key = ?").run(e)}hasDoc(t,e){let s=this.getDb(t);return this.prepareCached(s,"SELECT 1 FROM kv_store WHERE key = ?").get(e)!==null}appendEvent(t,e,s,n){let i=this.getDb(t),o=new Date().toISOString();this.prepareCached(i,"INSERT INTO events (type, task_id, data, timestamp) VALUES (?, ?, ?, ?)").run(e,n??null,JSON.stringify(s),o)}getEvents(t,e,s=100){let n=this.getDb(t);return e?this.prepareCached(n,"SELECT * FROM events WHERE type = ? ORDER BY id DESC LIMIT ?").all(e,s):this.prepareCached(n,"SELECT * FROM events ORDER BY id DESC LIMIT ?").all(s)}query(t,e,...s){let n=this.getDb(t);return this.prepareCached(n,e).all(...s)}run(t,e,...s){let n=this.getDb(t);this.prepareCached(n,e).run(...s)}get(t,e,...s){let n=this.getDb(t);return this.prepareCached(n,e).get(...s)??null}transaction(t,e){let s=this.getDb(t);return s.transaction(e)(s)}runMigrations(t){t.run(`
527
527
  CREATE TABLE IF NOT EXISTS _migrations (
528
528
  version INTEGER PRIMARY KEY,
529
529
  name TEXT NOT NULL,
530
530
  applied_at TEXT NOT NULL
531
531
  )
532
- `);let e=new Set(t.prepare("SELECT version FROM _migrations").all().map(s=>s.version));for(let s of js)e.has(s.version)||t.transaction(()=>{s.up(t),t.prepare("INSERT INTO _migrations (version, name, applied_at) VALUES (?, ?, ?)").run(s.version,s.name,new Date().toISOString())})()}getMigrations(t){return this.getDb(t).prepare("SELECT * FROM _migrations ORDER BY version").all()}getSchemaVersion(t){return this.getDb(t).prepare("SELECT MAX(version) as version FROM _migrations").get()?.version??0}},k=new le,T=k});function li(r){return r instanceof fe}function he(r){return li(r)||r instanceof Error?r.message:typeof r=="string"?r:"Unknown error"}var fe,Vs=w(()=>{"use strict";fe=class extends Error{static{c(this,"PrjctError")}code;isOperational;constructor(t,e="PRJCT_ERROR"){super(t),this.name="PrjctError",this.code=e,this.isOperational=!0,Error.captureStackTrace?.(this,this.constructor)}};c(li,"isPrjctError");c(he,"getErrorMessage")});import ye from"node:fs";import It from"node:path";function Qs(){if(ft)return ft;let r=__dirname;for(let t=0;t<5;t++){let e=It.join(r,"package.json");if(ye.existsSync(e))try{if(JSON.parse(ye.readFileSync(e,"utf-8")).name==="prjct-cli")return ft=r,r}catch{}r=It.dirname(r)}return ft=It.join(__dirname,"..","..",".."),ft}function pi(){if(rt)return rt;let r=process.env.PRJCT_VERSION;if(r&&/^\d+\.\d+\.\d+/.test(r))return rt=r,rt;try{let t=It.join(Qs(),"package.json");return rt=JSON.parse(ye.readFileSync(t,"utf-8")).version,rt}catch(t){return process.env.PRJCT_DEBUG==="1"&&console.error("Failed to read version from package.json:",es(t)),"0.0.0"}}var rt,ft,Te,wc,Zs=w(()=>{"use strict";K();rt=null,ft=null;c(Qs,"getPackageRoot");c(pi,"getVersion");Te=pi(),wc=Qs()});async function Dt(r){try{let{stdout:t}=await b(r,{timeout:5e3});return{success:!0,output:t.trim()}}catch{return{success:!1,output:""}}}async function di(){let r=await Dt("gh api user --jq .login");return r.success&&r.output||(r=await Dt("git config --global github.user"),r.success&&r.output)?r.output:null}async function mi(){let r=await Dt("git config user.name");return r.success&&r.output?r.output:null}async function gi(){let r=await Dt("git config user.email");return r.success&&r.output?r.output:null}async function tr(){let[r,t,e]=await Promise.all([di(),mi(),gi()]);return{github:r,email:e,name:t||r||"Unknown"}}var er=w(()=>{"use strict";et();c(Dt,"execCommand");c(di,"detectGitHubUsername");c(mi,"detectGitName");c(gi,"detectGitEmail");c(tr,"detect")});var rr={};lt(rr,{default:()=>B});import ke from"node:fs/promises";import hi from"node:path";import*as Lt from"jsonc-parser";function sr(r){let t=[],e=Lt.parse(r,t,{allowTrailingComma:!0,disallowComments:!1});if(t.length>0){let s=t[0];throw new SyntaxError(`JSON parse error at offset ${s.offset}: ${Lt.printParseErrorCode(s.error)}`)}return e}var Ee,yi,B,ht=w(()=>{"use strict";Vs();K();A();U();Zs();er();mt();c(sr,"parseJsonc");Ee=class{static{c(this,"ConfigManager")}async readConfig(t){try{let e=v.getLocalConfigPath(t),s=await ke.readFile(e,"utf-8");return sr(s)}catch(e){return D(e)||console.warn(`Warning: Could not read config at ${t}: ${he(e)}`),null}}async writeConfig(t,e){let s=v.getLocalConfigPath(t);await M(s,e)}async readGlobalConfig(t){try{let e=v.getGlobalProjectConfigPath(t),s=await ke.readFile(e,"utf-8");return sr(s)}catch(e){return D(e)||console.warn(`Warning: Could not read global config for ${t}: ${he(e)}`),null}}async writeGlobalConfig(t,e){let s=v.getGlobalProjectConfigPath(t);await M(s,e)}async ensureGlobalConfig(t){let e=await this.readGlobalConfig(t);if(!e){let s=g();e={projectId:t,authors:[],version:Te,lastSync:s},await this.writeGlobalConfig(t,e)}return e}async createConfig(t,e){let s=v.generateProjectId(t),n=v.getGlobalProjectPath(s),i=v.getDisplayPath(n),o=g(),a={projectId:s,dataPath:i,showMetrics:!0};await this.writeConfig(t,a);let u={projectId:s,authors:[{name:e.name||"Unknown",email:e.email||"",github:e.github||"",firstContribution:o,lastActivity:o}],version:Te,created:o,lastSync:o};return await this.writeGlobalConfig(s,u),a}async updateLastSync(t){let e=await this.getProjectId(t),s=await this.readGlobalConfig(e);s&&(s.lastSync=g(),await this.writeGlobalConfig(e,s))}validateConfig(t){return!(!t||!t.projectId||!t.dataPath)}async needsMigration(t){if(!await v.hasLegacyStructure(t))return!1;if(!await v.hasConfig(t))return!0;let n=await this.readConfig(t);if(!n||!n.projectId)return!0;let i=v.getGlobalProjectPath(n.projectId);try{return(await ke.readdir(hi.join(i,"core"))).length===0}catch(o){return D(o),!0}}async getProjectId(t){let e=await this.readConfig(t);if(e?.projectId)return e.projectId;try{let{worktreeService:s}=await Promise.resolve().then(()=>(Zt(),Qt));if(await s.detect(t)){let i=await s.getMainWorktree(t);if(i!==t){let o=await this.readConfig(i);if(o?.projectId)return o.projectId}}}catch{}return v.generateProjectId(t)}async findAuthor(t,e){let s=await this.readGlobalConfig(t);return!s||!s.authors?null:s.authors.find(n=>n.github===e)||null}async addAuthor(t,e){let s=await this.ensureGlobalConfig(t);if(s.authors.some(o=>o.github===e.github))return;let i=g();s.authors.push({name:e.name||"Unknown",email:e.email||"",github:e.github||"",firstContribution:i,lastActivity:i}),s.lastSync=i,await this.writeGlobalConfig(t,s)}async updateAuthorActivity(t,e){let s=await this.readGlobalConfig(t);if(!s||!s.authors)return;let n=s.authors.find(i=>i.github===e);n&&(n.lastActivity=g(),s.lastSync=n.lastActivity,await this.writeGlobalConfig(t,s))}async getCurrentAuthor(t){let e=await tr(),s=await this.getProjectId(t);return await this.addAuthor(s,{name:e.name??void 0,email:e.email??void 0,github:e.github??void 0}),e.github||e.name||"Unknown"}async isConfigured(t){let e=await this.readConfig(t);return this.validateConfig(e)}async getShowMetrics(t){return(await this.readConfig(t))?.showMetrics??!0}async setShowMetrics(t,e){let s=await this.readConfig(t);s&&(s.showMetrics=e,await this.writeConfig(t,s))}async getConfigWithDefaults(t){let e=await this.readConfig(t);if(e)return e;let s=v.generateProjectId(t);return{projectId:s,dataPath:v.getDisplayPath(v.getGlobalProjectPath(s))}}},yi=new Ee,B=yi});var _e,Q,dr=w(()=>{"use strict";A();O();_e=class{static{c(this,"SyncPendingStorage")}append(t,e){let s=g(),n=JSON.stringify(e);return e.entityType&&e.entityId&&e.contentHash&&T.run(t,`DELETE FROM sync_pending
532
+ `);let e=new Set(t.prepare("SELECT version FROM _migrations").all().map(s=>s.version));for(let s of $s)e.has(s.version)||t.transaction(()=>{s.up(t),t.prepare("INSERT INTO _migrations (version, name, applied_at) VALUES (?, ?, ?)").run(s.version,s.name,new Date().toISOString())})()}getMigrations(t){return this.getDb(t).prepare("SELECT * FROM _migrations ORDER BY version").all()}getSchemaVersion(t){return this.getDb(t).prepare("SELECT MAX(version) as version FROM _migrations").get()?.version??0}},E=new ge,T=E});function Ei(r){return r instanceof ke}function Ee(r){return Ei(r)||r instanceof Error?r.message:typeof r=="string"?r:"Unknown error"}var ke,sr=k(()=>{"use strict";ke=class extends Error{static{c(this,"PrjctError")}code;isOperational;constructor(t,e="PRJCT_ERROR"){super(t),this.name="PrjctError",this.code=e,this.isOperational=!0,Error.captureStackTrace?.(this,this.constructor)}};c(Ei,"isPrjctError");c(Ee,"getErrorMessage")});import Se from"node:fs";import Lt from"node:path";function rr(){if(ft)return ft;let r=__dirname;for(let t=0;t<5;t++){let e=Lt.join(r,"package.json");if(Se.existsSync(e))try{if(JSON.parse(Se.readFileSync(e,"utf-8")).name==="prjct-cli")return ft=r,r}catch{}r=Lt.dirname(r)}return ft=Lt.join(__dirname,"..","..",".."),ft}function Si(){if(nt)return nt;let r=process.env.PRJCT_VERSION;if(r&&/^\d+\.\d+\.\d+/.test(r))return nt=r,nt;try{let t=Lt.join(rr(),"package.json");return nt=JSON.parse(Se.readFileSync(t,"utf-8")).version,nt}catch(t){return process.env.PRJCT_DEBUG==="1"&&console.error("Failed to read version from package.json:",os(t)),"0.0.0"}}var nt,ft,we,Wc,nr=k(()=>{"use strict";K();nt=null,ft=null;c(rr,"getPackageRoot");c(Si,"getVersion");we=Si(),Wc=rr()});async function Ot(r){try{let{stdout:t}=await b(r,{timeout:5e3});return{success:!0,output:t.trim()}}catch{return{success:!1,output:""}}}async function wi(){let r=await Ot("gh api user --jq .login");return r.success&&r.output||(r=await Ot("git config --global github.user"),r.success&&r.output)?r.output:null}async function bi(){let r=await Ot("git config user.name");return r.success&&r.output?r.output:null}async function _i(){let r=await Ot("git config user.email");return r.success&&r.output?r.output:null}async function ir(){let[r,t,e]=await Promise.all([wi(),bi(),_i()]);return{github:r,email:e,name:t||r||"Unknown"}}var or=k(()=>{"use strict";st();c(Ot,"execCommand");c(wi,"detectGitHubUsername");c(bi,"detectGitName");c(_i,"detectGitEmail");c(ir,"detect")});var cr={};tt(cr,{default:()=>H});import be from"node:fs/promises";import xi from"node:path";import*as jt from"jsonc-parser";function ar(r){let t=[],e=jt.parse(r,t,{allowTrailingComma:!0,disallowComments:!1});if(t.length>0){let s=t[0];throw new SyntaxError(`JSON parse error at offset ${s.offset}: ${jt.printParseErrorCode(s.error)}`)}return e}var _e,Pi,H,ht=k(()=>{"use strict";sr();K();A();X();nr();or();mt();c(ar,"parseJsonc");_e=class{static{c(this,"ConfigManager")}async readConfig(t){try{let e=v.getLocalConfigPath(t),s=await be.readFile(e,"utf-8");return ar(s)}catch(e){return L(e)||console.warn(`Warning: Could not read config at ${t}: ${Ee(e)}`),null}}async writeConfig(t,e){let s=v.getLocalConfigPath(t);await F(s,e)}async readGlobalConfig(t){try{let e=v.getGlobalProjectConfigPath(t),s=await be.readFile(e,"utf-8");return ar(s)}catch(e){return L(e)||console.warn(`Warning: Could not read global config for ${t}: ${Ee(e)}`),null}}async writeGlobalConfig(t,e){let s=v.getGlobalProjectConfigPath(t);await F(s,e)}async ensureGlobalConfig(t){let e=await this.readGlobalConfig(t);if(!e){let s=g();e={projectId:t,authors:[],version:we,lastSync:s},await this.writeGlobalConfig(t,e)}return e}async createConfig(t,e){let s=v.generateProjectId(t),n=v.getGlobalProjectPath(s),i=v.getDisplayPath(n),o=g(),a={projectId:s,dataPath:i,showMetrics:!0};await this.writeConfig(t,a);let u={projectId:s,authors:[{name:e.name||"Unknown",email:e.email||"",github:e.github||"",firstContribution:o,lastActivity:o}],version:we,created:o,lastSync:o};return await this.writeGlobalConfig(s,u),a}async updateLastSync(t){let e=await this.getProjectId(t),s=await this.readGlobalConfig(e);s&&(s.lastSync=g(),await this.writeGlobalConfig(e,s))}validateConfig(t){return!(!t||!t.projectId||!t.dataPath)}async needsMigration(t){if(!await v.hasLegacyStructure(t))return!1;if(!await v.hasConfig(t))return!0;let n=await this.readConfig(t);if(!n||!n.projectId)return!0;let i=v.getGlobalProjectPath(n.projectId);try{return(await be.readdir(xi.join(i,"core"))).length===0}catch(o){return L(o),!0}}async getProjectId(t){let e=await this.readConfig(t);if(e?.projectId)return e.projectId;try{let{worktreeService:s}=await Promise.resolve().then(()=>(re(),se));if(await s.detect(t)){let i=await s.getMainWorktree(t);if(i!==t){let o=await this.readConfig(i);if(o?.projectId)return o.projectId}}}catch{}return v.generateProjectId(t)}async findAuthor(t,e){let s=await this.readGlobalConfig(t);return!s||!s.authors?null:s.authors.find(n=>n.github===e)||null}async addAuthor(t,e){let s=await this.ensureGlobalConfig(t);if(s.authors.some(o=>o.github===e.github))return;let i=g();s.authors.push({name:e.name||"Unknown",email:e.email||"",github:e.github||"",firstContribution:i,lastActivity:i}),s.lastSync=i,await this.writeGlobalConfig(t,s)}async updateAuthorActivity(t,e){let s=await this.readGlobalConfig(t);if(!s||!s.authors)return;let n=s.authors.find(i=>i.github===e);n&&(n.lastActivity=g(),s.lastSync=n.lastActivity,await this.writeGlobalConfig(t,s))}async getCurrentAuthor(t){let e=await ir(),s=await this.getProjectId(t);return await this.addAuthor(s,{name:e.name??void 0,email:e.email??void 0,github:e.github??void 0}),e.github||e.name||"Unknown"}async isConfigured(t){let e=await this.readConfig(t);return this.validateConfig(e)}async getShowMetrics(t){return(await this.readConfig(t))?.showMetrics??!0}async setShowMetrics(t,e){let s=await this.readConfig(t);s&&(s.showMetrics=e,await this.writeConfig(t,s))}async getConfigWithDefaults(t){let e=await this.readConfig(t);if(e)return e;let s=v.generateProjectId(t);return{projectId:s,dataPath:v.getDisplayPath(v.getGlobalProjectPath(s))}}},Pi=new _e,H=Pi});import ji from"node:crypto";function q(){return ji.randomUUID()}var Tt=k(()=>{"use strict";c(q,"generateUUID")});var Re,Q,yr=k(()=>{"use strict";A();O();Re=class{static{c(this,"SyncPendingStorage")}append(t,e){let s=g(),n=JSON.stringify(e);return e.entityType&&e.entityId&&e.contentHash&&T.run(t,`DELETE FROM sync_pending
533
533
  WHERE project_id = ?
534
534
  AND entity_type = ?
535
535
  AND entity_id = ?
536
536
  AND content_hash = ?`,t,e.entityType,e.entityId,e.contentHash),T.run(t,`INSERT INTO sync_pending
537
537
  (project_id, entity_type, entity_id, event_type, content_hash, payload, enqueued_at)
538
- VALUES (?, ?, ?, ?, ?, ?, ?)`,t,e.entityType??null,e.entityId??null,e.eventType??null,e.contentHash??null,n,s),{id:T.get(t,"SELECT last_insert_rowid() AS id")?.id??0,event:e,enqueuedAt:s}}list(t,e){let s=e?"SELECT * FROM sync_pending WHERE project_id = ? ORDER BY id ASC LIMIT ?":"SELECT * FROM sync_pending WHERE project_id = ? ORDER BY id ASC";return(e?T.query(t,s,t,e):T.query(t,s,t)).map(i=>this.rowToEntry(i))}count(t){return T.get(t,"SELECT COUNT(*) AS n FROM sync_pending WHERE project_id = ?",t)?.n??0}clearUpTo(t,e){if(e<=0)return 0;let s=this.count(t);return T.run(t,"DELETE FROM sync_pending WHERE project_id = ? AND id <= ?",t,e),s-this.count(t)}clearAll(t){T.run(t,"DELETE FROM sync_pending WHERE project_id = ?",t)}clearByIds(t,e){if(e.length===0)return;let s=e.map(()=>"?").join(",");T.run(t,`DELETE FROM sync_pending WHERE project_id = ? AND id IN (${s})`,t,...e)}rowToEntry(t){let e;try{e=JSON.parse(t.payload)}catch{e={type:"unknown.corrupt",path:[],data:null,timestamp:t.enqueued_at,projectId:t.project_id}}return{id:t.id,event:e,enqueuedAt:t.enqueued_at}}},Q=new _e});var ve,jt,xe=w(()=>{"use strict";mt();dr();A();U();ve=class{static{c(this,"SyncEventBus")}async publish(t){Q.append(t.projectId,t)}async getPending(t){return Q.list(t).map(e=>e.event)}async clearPending(t){Q.clearAll(t)}async getPendingEntries(t){return Q.list(t)}async clearPendingUpTo(t,e){return Q.clearUpTo(t,e)}async clearPendingByIds(t,e){Q.clearByIds(t,e)}async updateLastSync(t){let e=v.getLastSyncPath(t),s={timestamp:g(),success:!0};await M(e,s)}async getLastSync(t){let e=v.getLastSyncPath(t);return await bt(e,null)}},jt=new ve});var Re={};lt(Re,{default:()=>Ci});import Pi from"node:crypto";import mr from"node:fs/promises";import gr from"node:os";import Ri from"node:path";function hr(){return Pi.randomUUID()}var yr,fr,Pe,Ai,Ci,Ae=w(()=>{"use strict";mt();U();yr="https://api.prjct.app",fr={apiKey:null,apiUrl:yr,userId:null,email:null,lastAuth:null};c(hr,"freshDeviceId");Pe=class{static{c(this,"AuthConfigManager")}configPath;cachedConfig=null;constructor(){this.configPath=v.getAuthConfigPath()}getConfigPath(){return this.configPath}async read(){if(this.cachedConfig)return this.cachedConfig;let t=await bt(this.configPath),e=t??{...fr},s=!1;if(e.deviceId||(e.deviceId=hr(),s=!0),e.hostname||(e.hostname=gr.hostname(),s=!0),this.cachedConfig=e,s&&t)try{await M(this.configPath,this.cachedConfig),await mr.chmod(this.configPath,384)}catch{}return this.cachedConfig}async getDeviceId(){return(await this.read()).deviceId??hr()}async getHostname(){return(await this.read()).hostname??gr.hostname()}async write(t){let s={...await this.read(),...t,lastAuth:new Date().toISOString()};await F(Ri.dirname(this.configPath)),await M(this.configPath,s),await mr.chmod(this.configPath,384),this.cachedConfig=s}async hasAuth(){let t=await this.read();return t.apiKey!==null&&t.apiKey.length>0}async getApiKey(){return(await this.read()).apiKey}async getApiUrl(){return(await this.read()).apiUrl||yr}async saveAuth(t,e,s){await this.write({apiKey:t,userId:e,email:s})}async clearAuth(){this.cachedConfig={...fr},await M(this.configPath,this.cachedConfig)}async getStatus(){let t=await this.read();return{authenticated:t.apiKey!==null,email:t.email,apiKeyPrefix:t.apiKey?`${t.apiKey.substring(0,12)}...`:null,lastAuth:t.lastAuth}}clearCache(){this.cachedConfig=null}},Ai=new Pe,Ci=Ai});var kr={};lt(kr,{_resetPublishHelperCache:()=>ji,publishCRUD:()=>Tr,publishCRUDSync:()=>q});import Ni from"node:crypto";function Di(r){let t=r&&typeof r=="object"&&!Array.isArray(r)?JSON.stringify(Li(r)):JSON.stringify(r);return Ni.createHash("sha256").update(t).digest("hex")}function Li(r){let t={};for(let e of Object.keys(r).sort())t[e]=r[e];return t}async function Oi(){if(Mt)return Mt;try{let{default:r}=await Promise.resolve().then(()=>(Ae(),Re)),t=r;if(typeof t.getDeviceId=="function"){let e=await t.getDeviceId();return Mt=e,e}return"unknown-device"}catch{return"unknown-device"}}function ji(){Mt=null}async function Tr(r){try{let t=await Oi(),e=Di(r.data),s={type:`${r.entityType}.${Ii[r.eventType]}`,path:[r.entityType,r.entityId],data:r.data,timestamp:new Date().toISOString(),projectId:r.projectId,entityType:r.entityType,entityId:r.entityId,eventType:r.eventType,contentHash:e,deviceId:t,originDeviceId:r.originDeviceId??t,revisionCount:r.revisionCount??1};await jt.publish(s)}catch{}}function q(r){Tr(r)}var Ii,Mt,Tt=w(()=>{"use strict";xe();Ii={upsert:"updated",delete:"deleted"};c(Di,"hashPayload");c(Li,"sortKeys");Mt=null;c(Oi,"resolveDeviceId");c(ji,"_resetPublishHelperCache");c(Tr,"publishCRUD");c(q,"publishCRUDSync")});import{StdioServerTransport as xo}from"@modelcontextprotocol/sdk/server/stdio.js";import{McpServer as _o}from"@modelcontextprotocol/sdk/server/mcp.js";import{z as I}from"zod";qt();O();U();import Bs from"node:fs/promises";import st from"node:path";function ti(r){let t=[],e,s=new RegExp(Qe.source,"g");for(;(e=s.exec(r))!==null;){let n=e[1];(n.startsWith(".")||n.startsWith("@/"))&&t.push(n)}return t}c(ti,"extractImportSources");async function ei(r,t,e){let s;if(r.startsWith("@/"))s=st.join(e,"src",r.slice(2));else{let n=st.dirname(st.join(e,t));s=st.resolve(n,r)}for(let n of Ve){let i=s+n;try{if((await Bs.stat(i)).isFile())return st.relative(e,i)}catch{}}return null}c(ei,"resolveImport");async function si(r){let t=await as(r),e={},s={},n=0,i=await cs(t,50,async o=>{try{let a=await Bs.readFile(st.join(r,o),"utf-8"),u=ti(a),p=[];for(let m of u){let d=await ei(m,o,r);d&&d!==o&&p.push(d)}return p.length>0?{filePath:o,imports:p}:null}catch{return null}});for(let{filePath:o,imports:a}of i){e[o]=a,n+=a.length;for(let u of a)s[u]||(s[u]=[]),s[u].push(o)}return{forward:e,reverse:s,fileCount:t.length,edgeCount:n,builtAt:new Date().toISOString()}}c(si,"buildGraph");function Hs(r,t,e=2){let s=new Set(r),n=new Map,i=[];for(let o of r){let a=t.forward[o]||[],u=t.reverse[o]||[];for(let p of[...a,...u])s.has(p)||i.push({file:p,depth:1})}for(;i.length>0;){let{file:o,depth:a}=i.shift();if(a>e)continue;let u=1/(a+1),p=n.get(o);if(p){u>p.score&&n.set(o,{score:u,depth:a});continue}if(n.set(o,{score:u,depth:a}),a<e){let m=t.forward[o]||[],d=t.reverse[o]||[];for(let h of[...m,...d])!s.has(h)&&!n.has(h)&&i.push({file:h,depth:a+1})}}return Array.from(n.entries()).map(([o,{score:a,depth:u}])=>({path:o,score:a,depth:u})).sort((o,a)=>a.score-o.score)}c(Hs,"scoreFromSeeds");var pe="import-graph",Ct=new Map;function ri(r,t){T.setDoc(r,pe,t),Ct.delete(r)}c(ri,"saveGraph");function gt(r){let t=T.get(r,"SELECT updated_at FROM kv_store WHERE key = ?",pe);if(!t)return Ct.delete(r),null;let e=Ct.get(r);if(e&&e.updatedAt===t.updated_at)return e.graph;let s=T.getDoc(r,pe);return s&&Ct.set(r,{graph:s,updatedAt:t.updated_at}),s}c(gt,"loadGraph");async function qs(r,t){let e=await si(r);return ri(t,e),e}c(qs,"indexImports");function Gs(r,t){let e=[...r.added,...r.modified],s=new Set(e),n=new Set,i=gt(t);if(i)for(let u of e){let p=i.reverse[u];if(p)for(let m of p)s.has(m)||n.add(m)}let o=Array.from(n),a=[...e,...o];return{directlyChanged:e,affectedByImports:o,deleted:r.deleted,allAffected:a}}c(Gs,"propagateChanges");function Ys(r){let t=new Set;for(let e of r){let s=e.toLowerCase();(s.endsWith(".tsx")||s.endsWith(".jsx")||s.endsWith(".css")||s.endsWith(".scss")||s.endsWith(".vue")||s.endsWith(".svelte")||s.includes("/components/")||s.includes("/pages/")||s.includes("/app/"))&&(t.add("frontend"),t.add("uxui")),(s.includes(".test.")||s.includes(".spec.")||s.includes("__tests__")||s.includes("/test/"))&&t.add("testing"),(s.includes("dockerfile")||s.includes("docker-compose")||s.includes(".dockerignore")||s.includes(".github/")||s.includes("ci/")||s.includes("cd/"))&&t.add("devops"),(s.endsWith(".sql")||s.includes("prisma")||s.includes("drizzle")||s.includes("migration")||s.includes("/db/"))&&t.add("database"),(s.endsWith(".ts")||s.endsWith(".js"))&&!s.includes(".test.")&&!s.includes(".spec.")&&!s.endsWith(".d.ts")&&t.add("backend")}return t}c(Ys,"affectedDomains");O();et();async function ii(r,t=100){try{let{stdout:e}=await b(`git log --name-only --pretty=format:'---COMMIT---' -${t}`,{cwd:r,maxBuffer:10485760}),s=[],n=null;for(let i of e.split(`
539
- `)){let o=i.trim();o==="---COMMIT---"?(n&&n.size>0&&n.size<=30&&s.push(n),n=new Set):o&&n&&oi(o)&&n.add(o)}return n&&n.size>0&&n.size<=30&&s.push(n),s}catch{return[]}}c(ii,"parseGitLog");function oi(r){return/\.(ts|tsx|js|jsx|mjs|cjs|py|go|rs|java|cs|rb|php|vue|svelte)$/i.test(r)&&!r.includes("node_modules/")}c(oi,"isSourceFile");async function ai(r,t=100){let e=await ii(r,t),s=new Map,n=new Map;for(let o of e){let a=Array.from(o);for(let u of a)s.set(u,(s.get(u)||0)+1);for(let u=0;u<a.length;u++)for(let p=u+1;p<a.length;p++){let m=ci(a[u],a[p]);n.set(m,(n.get(m)||0)+1)}}let i={};for(let[o,a]of n){let[u,p]=o.split("\0"),m=s.get(u)||0,d=s.get(p)||0;if(m<2||d<2)continue;let h=m+d-a,y=h>0?a/h:0;y<.1||(i[u]||(i[u]={}),i[p]||(i[p]={}),i[u][p]=y,i[p][u]=y)}return{matrix:i,commitsAnalyzed:e.length,filesAnalyzed:s.size,builtAt:new Date().toISOString()}}c(ai,"buildMatrix");function ci(r,t){return r<t?`${r}\0${t}`:`${t}\0${r}`}c(ci,"pairKey");function me(r,t){let e=new Set(r),s=new Map;for(let n of r){let i=t.matrix[n];if(i)for(let[o,a]of Object.entries(i)){if(e.has(o))continue;let u=s.get(o)||0;a>u&&s.set(o,a)}}return Array.from(s.entries()).map(([n,i])=>({path:n,score:i})).sort((n,i)=>i.score-n.score)}c(me,"scoreFromSeeds");var de="cochange-index",Nt=new Map;function ui(r,t){T.setDoc(r,de,t),Nt.delete(r)}c(ui,"saveMatrix");function ge(r){let t=T.get(r,"SELECT updated_at FROM kv_store WHERE key = ?",de);if(!t)return Nt.delete(r),null;let e=Nt.get(r);if(e&&e.updatedAt===t.updated_at)return e.matrix;let s=T.getDoc(r,de);return s&&Nt.set(r,{matrix:s,updatedAt:t.updated_at}),s}c(ge,"loadMatrix");async function Ks(r,t,e=100){let s=await ai(r,e);return ui(t,s),s}c(Ks,"indexCoChanges");ht();async function x(r){return B.getProjectId(r)}c(x,"resolveProjectId");function E(r,t){return async e=>{try{return await t(e)}catch(s){return Ti(s,r)}}}c(E,"safeMcpCall");function Ti(r,t){let e=r instanceof Error?r.message:String(r);return{content:[{type:"text",text:`[${t}] Error: ${e}`}],isError:!0}}c(Ti,"mcpError");function nr(r){let t=r;t.tool("prjct_impact_analysis","Given changed files, find affected files via import graph + affected domains",{projectPath:I.string().describe("Project directory path"),changedFiles:I.array(I.string()).describe("List of changed file paths (relative to project root)")},E("prjct_impact_analysis",async e=>{let s=await x(e.projectPath),n={added:[],modified:e.changedFiles,deleted:[],unchanged:[]},i=Gs(n,s),o=Ys(i.allAffected),a=["## Impact Analysis"];a.push(`
538
+ VALUES (?, ?, ?, ?, ?, ?, ?)`,t,e.entityType??null,e.entityId??null,e.eventType??null,e.contentHash??null,n,s),{id:T.get(t,"SELECT last_insert_rowid() AS id")?.id??0,event:e,enqueuedAt:s}}list(t,e){let s=e?"SELECT * FROM sync_pending WHERE project_id = ? ORDER BY id ASC LIMIT ?":"SELECT * FROM sync_pending WHERE project_id = ? ORDER BY id ASC";return(e?T.query(t,s,t,e):T.query(t,s,t)).map(i=>this.rowToEntry(i))}count(t){return T.get(t,"SELECT COUNT(*) AS n FROM sync_pending WHERE project_id = ?",t)?.n??0}clearUpTo(t,e){if(e<=0)return 0;let s=this.count(t);return T.run(t,"DELETE FROM sync_pending WHERE project_id = ? AND id <= ?",t,e),s-this.count(t)}clearAll(t){T.run(t,"DELETE FROM sync_pending WHERE project_id = ?",t)}clearByIds(t,e){if(e.length===0)return;let s=e.map(()=>"?").join(",");T.run(t,`DELETE FROM sync_pending WHERE project_id = ? AND id IN (${s})`,t,...e)}rowToEntry(t){let e;try{e=JSON.parse(t.payload)}catch{e={type:"unknown.corrupt",path:[],data:null,timestamp:t.enqueued_at,projectId:t.project_id}}return{id:t.id,event:e,enqueuedAt:t.enqueued_at}}},Q=new Re});var Ae,Ft,Ce=k(()=>{"use strict";mt();yr();A();X();Ae=class{static{c(this,"SyncEventBus")}async publish(t){Q.append(t.projectId,t)}async getPending(t){return Q.list(t).map(e=>e.event)}async clearPending(t){Q.clearAll(t)}async getPendingEntries(t){return Q.list(t)}async clearPendingUpTo(t,e){return Q.clearUpTo(t,e)}async clearPendingByIds(t,e){Q.clearByIds(t,e)}async updateLastSync(t){let e=v.getLastSyncPath(t),s={timestamp:g(),success:!0};await F(e,s)}async getLastSync(t){let e=v.getLastSyncPath(t);return await vt(e,null)}},Ft=new Ae});var Ie={};tt(Ie,{default:()=>Xi});import Mi from"node:crypto";import Tr from"node:fs/promises";import kr from"node:os";import Fi from"node:path";function Sr(){return Mi.randomUUID()}var wr,Er,Ne,Ui,Xi,De=k(()=>{"use strict";mt();X();wr="https://api.prjct.app",Er={apiKey:null,apiUrl:wr,userId:null,email:null,lastAuth:null};c(Sr,"freshDeviceId");Ne=class{static{c(this,"AuthConfigManager")}configPath;cachedConfig=null;constructor(){this.configPath=v.getAuthConfigPath()}getConfigPath(){return this.configPath}async read(){if(this.cachedConfig)return this.cachedConfig;let t=await vt(this.configPath),e=t??{...Er},s=!1;if(e.deviceId||(e.deviceId=Sr(),s=!0),e.hostname||(e.hostname=kr.hostname(),s=!0),this.cachedConfig=e,s&&t)try{await F(this.configPath,this.cachedConfig),await Tr.chmod(this.configPath,384)}catch{}return this.cachedConfig}async getDeviceId(){return(await this.read()).deviceId??Sr()}async getHostname(){return(await this.read()).hostname??kr.hostname()}async write(t){let s={...await this.read(),...t,lastAuth:new Date().toISOString()};await U(Fi.dirname(this.configPath)),await F(this.configPath,s),await Tr.chmod(this.configPath,384),this.cachedConfig=s}async hasAuth(){let t=await this.read();return t.apiKey!==null&&t.apiKey.length>0}async getApiKey(){return(await this.read()).apiKey}async getApiUrl(){return(await this.read()).apiUrl||wr}async saveAuth(t,e,s){await this.write({apiKey:t,userId:e,email:s})}async clearAuth(){this.cachedConfig={...Er},await F(this.configPath,this.cachedConfig)}async getStatus(){let t=await this.read();return{authenticated:t.apiKey!==null,email:t.email,apiKeyPrefix:t.apiKey?`${t.apiKey.substring(0,12)}...`:null,lastAuth:t.lastAuth}}clearCache(){this.cachedConfig=null}},Ui=new Ne,Xi=Ui});var _r={};tt(_r,{_resetPublishHelperCache:()=>Gi,publishCRUD:()=>br,publishCRUDSync:()=>G});import $i from"node:crypto";function Bi(r){let t=r&&typeof r=="object"&&!Array.isArray(r)?JSON.stringify(Hi(r)):JSON.stringify(r);return $i.createHash("sha256").update(t).digest("hex")}function Hi(r){let t={};for(let e of Object.keys(r).sort())t[e]=r[e];return t}async function qi(){if(Ut)return Ut;try{let{default:r}=await Promise.resolve().then(()=>(De(),Ie)),t=r;if(typeof t.getDeviceId=="function"){let e=await t.getDeviceId();return Ut=e,e}return"unknown-device"}catch{return"unknown-device"}}function Gi(){Ut=null}async function br(r){try{let t=await qi(),e=Bi(r.data),s={type:`${r.entityType}.${Wi[r.eventType]}`,path:[r.entityType,r.entityId],data:r.data,timestamp:new Date().toISOString(),projectId:r.projectId,entityType:r.entityType,entityId:r.entityId,eventType:r.eventType,contentHash:e,deviceId:t,originDeviceId:r.originDeviceId??t,revisionCount:r.revisionCount??1};await Ft.publish(s)}catch{}}function G(r){br(r)}var Wi,Ut,kt=k(()=>{"use strict";Ce();Wi={upsert:"updated",delete:"deleted"};c(Bi,"hashPayload");c(Hi,"sortKeys");Ut=null;c(qi,"resolveDeviceId");c(Gi,"_resetPublishHelperCache");c(br,"publishCRUD");c(G,"publishCRUDSync")});var Et,Le,it,Xt=k(()=>{"use strict";Tt();kt();A();O();Et={SHIPPED_RETENTION_DAYS:90,IDEA_DORMANT_DAYS:180,QUEUE_COMPLETED_DAYS:7,PAUSED_TASK_DAYS:30,MEMORY_MAX_ENTRIES:500},Le=class{static{c(this,"ArchiveStorage")}archive(t,e){let s=q(),n=g();return E.run(t,"INSERT INTO archives (id, entity_type, entity_id, entity_data, summary, archived_at, reason) VALUES (?, ?, ?, ?, ?, ?, ?)",s,e.entityType,e.entityId,JSON.stringify(e.entityData),e.summary??null,n,e.reason),G({projectId:t,entityType:"archives",entityId:s,eventType:"upsert",data:{id:s,entity_type:e.entityType,entity_id:e.entityId,summary:e.summary??null,reason:e.reason,archived_at:n}}),s}archiveMany(t,e){if(e.length===0)return 0;let s=g();return E.transaction(t,n=>{let i=n.prepare("INSERT INTO archives (id, entity_type, entity_id, entity_data, summary, archived_at, reason) VALUES (?, ?, ?, ?, ?, ?, ?)");for(let o of e)i.run(q(),o.entityType,o.entityId,JSON.stringify(o.entityData),o.summary??null,s,o.reason)}),e.length}getArchived(t,e,s=50){return e?E.query(t,"SELECT * FROM archives WHERE entity_type = ? ORDER BY archived_at DESC LIMIT ?",e,s):E.query(t,"SELECT * FROM archives ORDER BY archived_at DESC LIMIT ?",s)}getStats(t){let e=E.query(t,"SELECT entity_type, COUNT(*) as count FROM archives GROUP BY entity_type"),s={shipped:0,idea:0,queue_task:0,paused_task:0,memory_entry:0,total:0};for(let n of e){let i=n.entity_type;i in s&&(s[i]=n.count),s.total+=n.count}return s}restore(t,e){let s=E.get(t,"SELECT * FROM archives WHERE id = ?",e);return s?(E.run(t,"DELETE FROM archives WHERE id = ?",e),JSON.parse(s.entity_data)):null}pruneOldArchives(t,e){let s=new Date(Date.now()-e*24*60*60*1e3).toISOString(),n=this.getTotalCount(t);E.run(t,"DELETE FROM archives WHERE archived_at < ?",s);let i=this.getTotalCount(t);return n-i}getTotalCount(t){return E.get(t,"SELECT COUNT(*) as count FROM archives")?.count??0}},it=new Le});var en,sn,rn,nn,on=k(()=>{"use strict";en={frontend:["component","page","view","ui","layout","style","css","scss","sass","hook","context","store","redux","zustand","react","vue","svelte","angular","next","nuxt","app","client"],backend:["api","route","controller","service","middleware","handler","resolver","schema","model","entity","repository","server","socket","graphql","rest","trpc"],database:["migration","seed","schema","model","entity","repository","prisma","drizzle","sequelize","typeorm","mongoose","knex","sql","db"],auth:["auth","login","logout","session","token","jwt","oauth","passport","credential","permission","role","user","account"],testing:["test","spec","e2e","integration","unit","mock","fixture","stub","jest","vitest","cypress","playwright"],config:["config","env","setting","constant","option","tsconfig","eslint","prettier","vite","webpack","rollup"],infra:["docker","compose","kubernetes","k8s","ci","cd","github","gitlab","jenkins","terraform","ansible","deploy"],util:["util","helper","lib","common","shared","core","base","abstract"]},sn=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".py",".go",".rs",".java",".kt",".swift",".rb",".php",".c",".cpp",".h",".hpp",".cs",".vue",".svelte"]),rn=new Set(["node_modules",".git","dist","build",".next",".nuxt",".output","coverage",".cache","__pycache__",".pytest_cache","vendor","target",".turbo",".vercel"]),nn=new Set(["a","an","the","and","or","but","is","are","was","were","be","been","being","have","has","had","do","does","did","will","would","could","should","may","might","must","shall","can","need","to","of","in","for","on","with","at","by","from","as","into","through","during","before","after","above","below","between","under","again","further","then","once","here","there","when","where","why","how","all","each","few","more","most","other","some","such","no","nor","not","only","own","same","so","than","too","very","just","add","create","make","implement","fix","update","change","modify","remove","delete","new"])});import ro from"node:fs/promises";import Wt from"node:path";async function Bt(r,t,e={}){let s=Date.now(),n=e.maxFiles??30,i=e.minScore??.1,o=e.includeTests??!1,a=no(r),u=await io(t),p=await oo(t),m=[];for(let h of u){if(!o&&co(h))continue;let y=ao(h,a,p,e.historicalBoosts);y.score>=i&&m.push(y)}m.sort((h,y)=>y.score-h.score);let d=m.slice(0,n);return{files:d,metrics:{filesScanned:u.length,filesReturned:d.length,scanDuration:Date.now()-s}}}function no(r){return r.toLowerCase().split(/[^a-z0-9]+/).filter(Boolean).filter(e=>!nn.has(e)&&e.length>2)}async function io(r){let t=[];async function e(s,n=""){try{let i=await ro.readdir(s,{withFileTypes:!0});for(let o of i){let a=Wt.join(s,o.name),u=Wt.join(n,o.name);if(o.isDirectory()){if(rn.has(o.name)||o.name.startsWith("."))continue;await e(a,u)}else if(o.isFile()){let p=Wt.extname(o.name).toLowerCase();sn.has(p)&&t.push(u)}}}catch(i){L(i)}}return c(e,"walk"),await e(r),t}async function oo(r){let t=new Map;try{let{stdout:e}=await b(`git log -30 --pretty=format:"%H %ct" --name-only | awk '
539
+ /^[a-f0-9]{40}/ { commit=$1; timestamp=$2; next }
540
+ NF { files[$0]++; if (!lastmod[$0]) lastmod[$0]=timestamp }
541
+ END { for (f in files) print files[f], lastmod[f], f }
542
+ '`,{cwd:r,maxBuffer:10485760}),s=Math.floor(Date.now()/1e3),n=e.trim().split(`
543
+ `).filter(Boolean);for(let i of n){let o=i.match(/^(\d+)\s+(\d+)\s+(.+)$/);if(o){let a=parseInt(o[1],10),u=parseInt(o[2],10),p=o[3],m=Math.floor((s-u)/86400);t.set(p,{commits:a,daysAgo:m})}}}catch{}return t}function ao(r,t,e,s){let n=[],i=0,o=0,a=0,u=0,p=0,m=r.toLowerCase(),d=m.split("/").join(" ").split(/[^a-z0-9]+/);for(let C of t){m.includes(C)&&(i+=.3,n.push(`keyword:${C}`));for(let lt of d)if(lt.includes(C)||C.includes(lt)){i+=.15;break}}i=Math.min(1,i);for(let[C,lt]of Object.entries(en))for(let jn of lt)if(m.includes(jn)&&t.some(Yt=>lt.includes(Yt)||Yt.includes(C)||C.includes(Yt))){o+=.4,n.push(`domain:${C}`);break}o=Math.min(1,o);let h=e.get(r);h&&(h.daysAgo<=1?(a=1,n.push("recent:1d")):h.daysAgo<=3?(a=.8,n.push("recent:3d")):h.daysAgo<=7?(a=.6,n.push("recent:1w")):h.daysAgo<=30&&(a=.3,n.push("recent:1m")),h.commits>=5&&(a=Math.min(1,a+.2)));let y=Wt.basename(r).toLowerCase();if((y.includes("index")||y.includes("main")||y.includes("app")||y.includes("entry"))&&(u=.5,n.push("import:0")),(m.includes("/core/")||m.includes("/shared/")||m.includes("/lib/"))&&(u=Math.max(u,.3),n.some(C=>C.startsWith("import:"))||n.push("import:1")),s){let C=s.get(r);C!==void 0&&(p=(C+1)/2,C>0?n.push("history:boosted"):C<0&&n.push("history:penalized"))}let bt=s&&s.size>0?i*.54+o*.18+a*.13+u*.05+p*.1:i*.6+o*.2+a*.15+u*.05;return{path:r,score:Math.min(1,bt),reasons:[...new Set(n)]}}function co(r){let t=r.toLowerCase();return t.includes(".test.")||t.includes(".spec.")||t.includes("__tests__")||t.includes("__mocks__")||t.includes("/tests/")||t.includes("/test/")||t.endsWith("_test.go")||t.endsWith("_test.py")}var Fe=k(()=>{"use strict";K();st();on();c(Bt,"findRelevantFiles");c(no,"extractKeywords");c(io,"getAllCodeFiles");c(oo,"getGitRecency");c(ao,"scoreFile");c(co,"isTestFile")});var Xe,gn,fn=k(()=>{"use strict";ht();Xt();O();Xe=class{static{c(this,"MemoryService")}async log(t,e,s,n){try{let i=await H.getProjectId(t);if(!i)return;T.appendEvent(i,`memory.${e}`,{...s,author:n})}catch(i){console.error(`Memory log error: ${i instanceof Error?i.message:String(i)}`)}}async getRecent(t,e=100){try{let s=await H.getProjectId(t);return s?T.query(s,"SELECT type, data, timestamp FROM events WHERE type LIKE 'memory.%' ORDER BY id DESC LIMIT ?",e).reverse().map(i=>{let o=JSON.parse(i.data),{author:a,...u}=o;return{timestamp:i.timestamp,action:i.type.replace("memory.",""),data:u,author:a}}):[]}catch(s){return console.error(`Memory read error: ${s instanceof Error?s.message:String(s)}`),[]}}async search(t,e,s=50){let n=await this.getRecent(t,1e3),i=e.toLowerCase();return n.filter(o=>{let a=o.action.toLowerCase().includes(i),u=JSON.stringify(o.data).toLowerCase().includes(i);return a||u}).slice(-s)}async getByAction(t,e,s=50){try{let n=await H.getProjectId(t);return n?T.query(n,"SELECT type, data, timestamp FROM events WHERE type = ? ORDER BY id DESC LIMIT ?",`memory.${e}`,s).reverse().map(o=>{let a=JSON.parse(o.data),{author:u,...p}=a;return{timestamp:o.timestamp,action:o.type.replace("memory.",""),data:p,author:u}}):[]}catch(n){return console.error(`Memory read error: ${n instanceof Error?n.message:String(n)}`),[]}}async clear(t){try{let e=await H.getProjectId(t);if(!e)return;T.run(e,"DELETE FROM events WHERE type LIKE 'memory.%'")}catch(e){console.error(`Memory clear error: ${e instanceof Error?e.message:String(e)}`)}}async getRecentEvents(t,e=100){try{return T.query(t,"SELECT type, data, timestamp FROM events WHERE type LIKE 'memory.%' ORDER BY id DESC LIMIT ?",e).reverse().map(n=>{let i=JSON.parse(n.data);return{timestamp:n.timestamp,action:n.type.replace("memory.",""),...i}})}catch(s){return console.error(`Memory read error: ${s instanceof Error?s.message:String(s)}`),[]}}async capEntries(t){try{let s=T.get(t,"SELECT COUNT(*) as cnt FROM events WHERE type LIKE 'memory.%'")?.cnt??0;if(s<=Et.MEMORY_MAX_ENTRIES)return 0;let n=s-Et.MEMORY_MAX_ENTRIES,i=T.query(t,"SELECT id, type, data, timestamp FROM events WHERE type LIKE 'memory.%' ORDER BY id ASC LIMIT ?",n);it.archiveMany(t,i.map((a,u)=>({entityType:"memory_entry",entityId:`memory-${a.timestamp||u}`,entityData:{type:a.type,data:JSON.parse(a.data),timestamp:a.timestamp},summary:a.type.replace("memory.",""),reason:"overflow"})));let o=i[i.length-1]?.id;return o!==void 0&&T.run(t,"DELETE FROM events WHERE type LIKE 'memory.%' AND id <= ?",o),n}catch(e){return console.error(`Memory cap error: ${e instanceof Error?e.message:String(e)}`),0}}},gn=new Xe});var hn,$e,We,zl,yn=k(()=>{"use strict";hn="memory.",$e="remember.",We=`${hn}${$e}`,zl=`${hn}task.tagged`});function kn(r,t){try{return JSON.parse(r)}catch{return t}}function vo(r){let t=r.type.slice(We.length),e=kn(r.data,{});return{id:`mem_${r.id}`,type:t,content:e.content??"",tags:e.tags??{},rememberedAt:r.timestamp,source:e.source,provenance:e.provenance??"declared"}}function xo(r){let t=r.data?kn(r.data,{}):{},e=t.tags??{};return r.type&&(e.type=r.type),{id:`ship_${r.id}`,type:"shipped",content:r.name,tags:e,rememberedAt:r.shipped_at,source:t.taskId,provenance:"extracted"}}function Po(r,t){let e=t.toLowerCase();if(r.content.toLowerCase().includes(e))return!0;for(let s of Object.values(r.tags))if(s.toLowerCase().includes(e))return!0;return!1}function Ro(r,t){for(let[e,s]of Object.entries(t))if(r.tags[e]!==s)return!1;return!0}function Ao(r){let t=new Set,e=[];for(let s of r){let n=s.tags.key;if(!n){e.push(s);continue}let i=`${s.type}::${n}`;t.has(i)||(t.add(i),e.push(s))}return e}function St(r){if(r.length===0)return"> No matching memory entries.";let t=new Map;for(let a of r){let u=t.get(a.type)??[];u.push(a),t.set(a.type,u)}let e=["decision","learning","anti-pattern","gotcha","pattern","fact","inbox","todo","idea","insight","question","source","person","shipped"],s=[],n={declared:"DECL",extracted:"EXTR",inferred:"INFR",ambiguous:"AMBG"},i=c((a,u)=>{if(u.length!==0){s.push(`### ${a.toUpperCase()}`);for(let p of u){let m=Object.entries(p.tags).map(([y,M])=>`${y}=${M}`).join(" "),d=m?` _(${m})_`:"",h=n[p.provenance];s.push(`- \`${h}\` [${p.id}] ${p.content}${d}`)}s.push("")}},"renderGroup"),o=new Set;for(let a of e){let u=t.get(a);!u||u.length===0||(i(a,u),o.add(a))}for(let[a,u]of t)o.has(a)||i(a,u);return s.join(`
544
+ `).trim()}var Tn,wo,bo,_o,j,wt=k(()=>{"use strict";fn();O();yn();Tn=["fact","decision","learning","gotcha","pattern","anti-pattern","shipped","inbox","todo","idea","insight","question","source","person","spec"],wo=25,bo=4,_o=100;c(kn,"safeJson");c(vo,"rowToEntry");c(xo,"shippedRowToEntry");c(Po,"matchesTopic");c(Ro,"matchesTags");c(Ao,"dedupeLatestByKey");j={async remember(r,t){await gn.log(r,`${$e}${t.type}`,{content:t.content,tags:t.tags??{},source:t.source,provenance:t.provenance??"declared"});try{let{default:e}=await Promise.resolve().then(()=>(ht(),cr)),n=(await e.readConfig(r))?.projectId;if(!n)return;let{publishCRUD:i}=await Promise.resolve().then(()=>(kt(),_r)),o=t.tags?.spec_id??t.tags?.task_id??t.tags?.id??t.source??`mem-${Date.now()}-${Math.random().toString(36).slice(2,8)}`;await i({projectId:n,entityType:"memories",entityId:o,eventType:"upsert",data:{id:o,type:t.type,content:t.content,tags:t.tags??{},source:t.source??null,provenance:t.provenance??"declared",rememberedAt:new Date().toISOString()}})}catch{}},recall(r,t={}){let e=t.limit??wo,s=Math.max(e*bo,_o),n=T.query(r,"SELECT id, type, data, timestamp FROM events WHERE type LIKE ? ORDER BY id DESC LIMIT ?",`${We}%`,s),i=T.query(r,"SELECT id, name, type, shipped_at, data FROM shipped_features ORDER BY shipped_at DESC LIMIT ?",s),o=[...n.map(vo),...i.map(xo)];if(t.types&&t.types.length>0){let a=new Set(t.types);o=o.filter(u=>a.has(u.type))}return t.tags&&(o=o.filter(a=>Ro(a,t.tags??{}))),t.topic&&(o=o.filter(a=>Po(a,t.topic))),o.sort((a,u)=>u.rememberedAt.localeCompare(a.rememberedAt)),t.dedupeByKey!==!1&&(o=Ao(o)),o.slice(0,e)},similar(r,t,e=10){let s=t.toLowerCase().split(/[^a-z0-9]+/).filter(o=>o.length>3);return s.length===0?[]:j.recall(r,{limit:200}).map(o=>{let a=`${o.content} ${Object.values(o.tags).join(" ")}`.toLowerCase(),u=s.reduce((p,m)=>a.includes(m)?p+1:p,0);return{entry:o,hits:u}}).filter(o=>o.hits>0).sort((o,a)=>a.hits-o.hits).slice(0,e).map(o=>o.entry)}};c(St,"formatMemoryMd")});var Nn={};tt(Nn,{inferSpecContext:()=>Lo,warnNoContextMatch:()=>Mo});async function Lo(r,t,e){let[s,n]=await Promise.all([Bt(r,e,{maxFiles:Cn*4,minScore:Do}).catch(()=>({files:[]})),Promise.resolve(j.recall(t,{topic:r,limit:Io})).catch(()=>[])]),i=Oo(s.files.map(u=>u.path),Cn);return i.length===0&&n.length===0?{notesBlock:"",paths:[],memoryHits:0,empty:!0}:{notesBlock:jo(r,i,n),paths:i,memoryHits:n.length,empty:!1}}function Oo(r,t){let e=new Set,s=[];for(let n of r){let i=n.split("/").slice(0,2).join("/");if(!e.has(i)&&(e.add(i),s.push(n),s.length>=t))break}return s}function jo(r,t,e){let s=[];if(s.push("<!-- auto-context:tentative -->"),s.push("## Existing context (auto-inferred)"),s.push(""),s.push(`_Inferred from title "${r}". Validate before audit \u2014 entries tagged tentative._`),s.push(""),t.length>0){s.push("### Likely paths");for(let n of t)s.push(`- \`${n}\``);s.push("")}if(e.length>0){s.push("### Relevant prior memory");for(let n of e){let i=n.content.length>140?`${n.content.slice(0,137)}\u2026`:n.content,o=Object.entries(n.tags).map(([a,u])=>`${a}:${u}`).join(" ");s.push(`- **${n.type}**${o?` _(${o})_`:""} \u2014 ${i}`)}s.push("")}return s.push("<!-- /auto-context -->"),s.join(`
545
+ `)}function Mo(r,t){let e={level:"warn",code:"no_context_match",message:`No codebase or memory context matched "${r}"`,suggestion:t??"Fill spec.notes manually or run with `--skip-context` next time."};process.stderr.write(`${JSON.stringify(e)}
546
+ `)}var Cn,Io,Do,In=k(()=>{"use strict";wt();Fe();Cn=5,Io=8,Do=.15;c(Lo,"inferSpecContext");c(Oo,"dedupeTopDirs");c(jo,"buildNotesBlock");c(Mo,"warnNoContextMatch")});import{StdioServerTransport as Go}from"@modelcontextprotocol/sdk/server/stdio.js";import{McpServer as Ho}from"@modelcontextprotocol/sdk/server/mcp.js";import{z as I}from"zod";zt();O();X();import Js from"node:fs/promises";import rt from"node:path";function li(r){let t=[],e,s=new RegExp(rs.source,"g");for(;(e=s.exec(r))!==null;){let n=e[1];(n.startsWith(".")||n.startsWith("@/"))&&t.push(n)}return t}c(li,"extractImportSources");async function pi(r,t,e){let s;if(r.startsWith("@/"))s=rt.join(e,"src",r.slice(2));else{let n=rt.dirname(rt.join(e,t));s=rt.resolve(n,r)}for(let n of ss){let i=s+n;try{if((await Js.stat(i)).isFile())return rt.relative(e,i)}catch{}}return null}c(pi,"resolveImport");async function di(r){let t=await ds(r),e={},s={},n=0,i=await ms(t,50,async o=>{try{let a=await Js.readFile(rt.join(r,o),"utf-8"),u=li(a),p=[];for(let m of u){let d=await pi(m,o,r);d&&d!==o&&p.push(d)}return p.length>0?{filePath:o,imports:p}:null}catch{return null}});for(let{filePath:o,imports:a}of i){e[o]=a,n+=a.length;for(let u of a)s[u]||(s[u]=[]),s[u].push(o)}return{forward:e,reverse:s,fileCount:t.length,edgeCount:n,builtAt:new Date().toISOString()}}c(di,"buildGraph");function zs(r,t,e=2){let s=new Set(r),n=new Map,i=[];for(let o of r){let a=t.forward[o]||[],u=t.reverse[o]||[];for(let p of[...a,...u])s.has(p)||i.push({file:p,depth:1})}for(;i.length>0;){let{file:o,depth:a}=i.shift();if(a>e)continue;let u=1/(a+1),p=n.get(o);if(p){u>p.score&&n.set(o,{score:u,depth:a});continue}if(n.set(o,{score:u,depth:a}),a<e){let m=t.forward[o]||[],d=t.reverse[o]||[];for(let h of[...m,...d])!s.has(h)&&!n.has(h)&&i.push({file:h,depth:a+1})}}return Array.from(n.entries()).map(([o,{score:a,depth:u}])=>({path:o,score:a,depth:u})).sort((o,a)=>a.score-o.score)}c(zs,"scoreFromSeeds");var fe="import-graph",It=new Map;function mi(r,t){T.setDoc(r,fe,t),It.delete(r)}c(mi,"saveGraph");function gt(r){let t=T.get(r,"SELECT updated_at FROM kv_store WHERE key = ?",fe);if(!t)return It.delete(r),null;let e=It.get(r);if(e&&e.updatedAt===t.updated_at)return e.graph;let s=T.getDoc(r,fe);return s&&It.set(r,{graph:s,updatedAt:t.updated_at}),s}c(gt,"loadGraph");async function Ks(r,t){let e=await di(r);return mi(t,e),e}c(Ks,"indexImports");function Vs(r,t){let e=[...r.added,...r.modified],s=new Set(e),n=new Set,i=gt(t);if(i)for(let u of e){let p=i.reverse[u];if(p)for(let m of p)s.has(m)||n.add(m)}let o=Array.from(n),a=[...e,...o];return{directlyChanged:e,affectedByImports:o,deleted:r.deleted,allAffected:a}}c(Vs,"propagateChanges");function Qs(r){let t=new Set;for(let e of r){let s=e.toLowerCase();(s.endsWith(".tsx")||s.endsWith(".jsx")||s.endsWith(".css")||s.endsWith(".scss")||s.endsWith(".vue")||s.endsWith(".svelte")||s.includes("/components/")||s.includes("/pages/")||s.includes("/app/"))&&(t.add("frontend"),t.add("uxui")),(s.includes(".test.")||s.includes(".spec.")||s.includes("__tests__")||s.includes("/test/"))&&t.add("testing"),(s.includes("dockerfile")||s.includes("docker-compose")||s.includes(".dockerignore")||s.includes(".github/")||s.includes("ci/")||s.includes("cd/"))&&t.add("devops"),(s.endsWith(".sql")||s.includes("prisma")||s.includes("drizzle")||s.includes("migration")||s.includes("/db/"))&&t.add("database"),(s.endsWith(".ts")||s.endsWith(".js"))&&!s.includes(".test.")&&!s.includes(".spec.")&&!s.endsWith(".d.ts")&&t.add("backend")}return t}c(Qs,"affectedDomains");O();st();async function fi(r,t=100){try{let{stdout:e}=await b(`git log --name-only --pretty=format:'---COMMIT---' -${t}`,{cwd:r,maxBuffer:10485760}),s=[],n=null;for(let i of e.split(`
547
+ `)){let o=i.trim();o==="---COMMIT---"?(n&&n.size>0&&n.size<=30&&s.push(n),n=new Set):o&&n&&hi(o)&&n.add(o)}return n&&n.size>0&&n.size<=30&&s.push(n),s}catch{return[]}}c(fi,"parseGitLog");function hi(r){return/\.(ts|tsx|js|jsx|mjs|cjs|py|go|rs|java|cs|rb|php|vue|svelte)$/i.test(r)&&!r.includes("node_modules/")}c(hi,"isSourceFile");async function yi(r,t=100){let e=await fi(r,t),s=new Map,n=new Map;for(let o of e){let a=Array.from(o);for(let u of a)s.set(u,(s.get(u)||0)+1);for(let u=0;u<a.length;u++)for(let p=u+1;p<a.length;p++){let m=Ti(a[u],a[p]);n.set(m,(n.get(m)||0)+1)}}let i={};for(let[o,a]of n){let[u,p]=o.split("\0"),m=s.get(u)||0,d=s.get(p)||0;if(m<2||d<2)continue;let h=m+d-a,y=h>0?a/h:0;y<.1||(i[u]||(i[u]={}),i[p]||(i[p]={}),i[u][p]=y,i[p][u]=y)}return{matrix:i,commitsAnalyzed:e.length,filesAnalyzed:s.size,builtAt:new Date().toISOString()}}c(yi,"buildMatrix");function Ti(r,t){return r<t?`${r}\0${t}`:`${t}\0${r}`}c(Ti,"pairKey");function ye(r,t){let e=new Set(r),s=new Map;for(let n of r){let i=t.matrix[n];if(i)for(let[o,a]of Object.entries(i)){if(e.has(o))continue;let u=s.get(o)||0;a>u&&s.set(o,a)}}return Array.from(s.entries()).map(([n,i])=>({path:n,score:i})).sort((n,i)=>i.score-n.score)}c(ye,"scoreFromSeeds");var he="cochange-index",Dt=new Map;function ki(r,t){T.setDoc(r,he,t),Dt.delete(r)}c(ki,"saveMatrix");function Te(r){let t=T.get(r,"SELECT updated_at FROM kv_store WHERE key = ?",he);if(!t)return Dt.delete(r),null;let e=Dt.get(r);if(e&&e.updatedAt===t.updated_at)return e.matrix;let s=T.getDoc(r,he);return s&&Dt.set(r,{matrix:s,updatedAt:t.updated_at}),s}c(Te,"loadMatrix");async function er(r,t,e=100){let s=await yi(r,e);return ki(t,s),s}c(er,"indexCoChanges");ht();async function x(r){return H.getProjectId(r)}c(x,"resolveProjectId");function S(r,t){return async e=>{try{return await t(e)}catch(s){return Ri(s,r)}}}c(S,"safeMcpCall");function Ri(r,t){let e=r instanceof Error?r.message:String(r);return{content:[{type:"text",text:`[${t}] Error: ${e}`}],isError:!0}}c(Ri,"mcpError");function ur(r){let t=r;t.tool("prjct_impact_analysis","Given changed files, find affected files via import graph + affected domains",{projectPath:I.string().describe("Project directory path"),changedFiles:I.array(I.string()).describe("List of changed file paths (relative to project root)")},S("prjct_impact_analysis",async e=>{let s=await x(e.projectPath),n={added:[],modified:e.changedFiles,deleted:[],unchanged:[]},i=Vs(n,s),o=Qs(i.allAffected),a=["## Impact Analysis"];a.push(`
540
548
  ### Directly Changed (${i.directlyChanged.length})`);for(let u of i.directlyChanged)a.push(`- ${u}`);if(i.affectedByImports.length>0){a.push(`
541
549
  ### Affected via Imports (${i.affectedByImports.length})`);for(let u of i.affectedByImports)a.push(`- ${u}`)}return a.push(`
542
550
  ### Affected Domains`),a.push(o.size>0?Array.from(o).join(", "):"none detected"),a.push(`
543
551
  Total affected: ${i.allAffected.length} files`),{content:[{type:"text",text:a.join(`
544
- `)}]}})),t.tool("prjct_import_graph","Import graph stats + file neighbors (imports/importers). Pass a file for its neighbors, omit for graph stats.",{projectPath:I.string().describe("Project directory path"),file:I.string().optional().describe("File path to get neighbors for (omit for graph stats)"),rebuild:I.boolean().optional().default(!1).describe("Force rebuild the import graph")},E("prjct_import_graph",async e=>{let s=await x(e.projectPath),n=e.rebuild?null:gt(s);if(n||(n=await qs(e.projectPath,s)),e.file){let o=n.forward[e.file]||[],a=n.reverse[e.file]||[];return{content:[{type:"text",text:[`## Import Neighbors: ${e.file}`,`
552
+ `)}]}})),t.tool("prjct_import_graph","Import graph stats + file neighbors (imports/importers). Pass a file for its neighbors, omit for graph stats.",{projectPath:I.string().describe("Project directory path"),file:I.string().optional().describe("File path to get neighbors for (omit for graph stats)"),rebuild:I.boolean().optional().default(!1).describe("Force rebuild the import graph")},S("prjct_import_graph",async e=>{let s=await x(e.projectPath),n=e.rebuild?null:gt(s);if(n||(n=await Ks(e.projectPath,s)),e.file){let o=n.forward[e.file]||[],a=n.reverse[e.file]||[];return{content:[{type:"text",text:[`## Import Neighbors: ${e.file}`,`
545
553
  ### Imports (${o.length})`,...o.map(p=>`- ${p}`),`
546
554
  ### Imported By (${a.length})`,...a.map(p=>`- ${p}`)].join(`
547
555
  `)}]}}return{content:[{type:"text",text:["## Import Graph Stats",`Files: ${n.fileCount}`,`Edges: ${n.edgeCount}`,`Built: ${n.builtAt}`].join(`
548
- `)}]}})),t.tool("prjct_cochange","Files that historically change together (Jaccard similarity from git history)",{projectPath:I.string().describe("Project directory path"),seedFiles:I.array(I.string()).describe("Seed files to find co-change partners for"),rebuild:I.boolean().optional().default(!1).describe("Force rebuild the co-change matrix"),maxResults:I.number().optional().default(10).describe("Max results (default 10)")},E("prjct_cochange",async e=>{let s=await x(e.projectPath),n=e.rebuild?null:ge(s);n||(n=await Ks(e.projectPath,s));let i=me(e.seedFiles,n).slice(0,e.maxResults);if(i.length===0)return{content:[{type:"text",text:"No co-change partners found."}]};let o=["## Co-Change Partners",`Seeds: ${e.seedFiles.join(", ")}`,`Commits analyzed: ${n.commitsAnalyzed}`,""];for(let a of i)o.push(`- ${a.path} (similarity: ${Math.round(a.score*100)}%)`);return{content:[{type:"text",text:o.join(`
549
- `)}]}})),t.tool("prjct_related_context","Combined: import neighbors + co-change partners for seed files",{projectPath:I.string().describe("Project directory path"),seedFiles:I.array(I.string()).describe("Seed files to find related context for"),maxResults:I.number().optional().default(15).describe("Max results (default 15)")},E("prjct_related_context",async e=>{let s=await x(e.projectPath),n=gt(s),i=n?Hs(e.seedFiles,n):[],o=ge(s),a=o?me(e.seedFiles,o):[],u=new Map;for(let d of i)u.set(d.path,{importScore:d.score,cochangeScore:0});for(let d of a){let h=u.get(d.path);h?h.cochangeScore=d.score:u.set(d.path,{importScore:0,cochangeScore:d.score})}let p=Array.from(u.entries()).map(([d,h])=>({path:d,combined:h.importScore*.6+h.cochangeScore*.4,importScore:h.importScore,cochangeScore:h.cochangeScore})).sort((d,h)=>h.combined-d.combined).slice(0,e.maxResults);if(p.length===0)return{content:[{type:"text",text:"No related files found. Run `prjct sync` to build indexes."}]};let m=["## Related Context",`Seeds: ${e.seedFiles.join(", ")}`,""];for(let d of p){let h=[];d.importScore>0&&h.push(`import: ${d.importScore.toFixed(2)}`),d.cochangeScore>0&&h.push(`cochange: ${Math.round(d.cochangeScore*100)}%`),m.push(`- ${d.path} (${h.join(", ")})`)}return{content:[{type:"text",text:m.join(`
550
- `)}]}}))}c(nr,"registerCodeIntelTools");import{z as Z}from"zod";se();import{z as l}from"zod";var ki=l.enum(["low","medium","high","critical"]),Ot=l.enum(["feature","bug","improvement","chore"]),Ei=l.enum(["active","backlog","previously_active"]),Si=l.enum(["pending","in_progress","completed","blocked","paused","failed","skipped"]),Se=l.object({title:l.string(),description:l.string(),filesChanged:l.array(l.object({path:l.string(),action:l.enum(["created","modified","deleted"])})),whatWasDone:l.array(l.string()).min(1),outputForNextAgent:l.string().min(1),notes:l.string().optional()}),or=l.object({output:l.string().min(1,"Subtask output is required"),summary:Se}),ar=l.object({id:l.string(),description:l.string(),domain:l.string(),agent:l.string(),status:Si,dependsOn:l.array(l.string()),startedAt:l.string().optional(),completedAt:l.string().optional(),output:l.string().optional(),summary:Se.optional(),skipReason:l.string().optional(),blockReason:l.string().optional(),estimatedPoints:l.number().optional(),estimatedMinutes:l.number().optional()}),cr=l.object({completed:l.number(),total:l.number(),percentage:l.number()}),ur=l.object({id:l.string(),description:l.string(),type:Ot.optional(),startedAt:l.string(),sessionId:l.string(),featureId:l.string().optional(),subtasks:l.array(ar).optional(),currentSubtaskIndex:l.number().optional(),subtaskProgress:cr.optional(),linearId:l.string().optional(),linearUuid:l.string().optional(),linkedSpecId:l.string().optional(),estimatedPoints:l.number().optional(),estimatedMinutes:l.number().optional(),modelMetadata:ee.optional(),tokensIn:l.number().optional(),tokensOut:l.number().optional(),parentDescription:l.string().optional(),branch:l.string().optional(),prUrl:l.string().optional()}),ir=l.object({id:l.string(),description:l.string(),status:l.literal("paused"),startedAt:l.string(),pausedAt:l.string(),pauseReason:l.string().optional(),type:Ot.optional(),sessionId:l.string().optional(),featureId:l.string().optional(),subtasks:l.array(ar).optional(),currentSubtaskIndex:l.number().optional(),subtaskProgress:cr.optional(),linearId:l.string().optional(),linearUuid:l.string().optional(),estimatedPoints:l.number().optional(),estimatedMinutes:l.number().optional(),modelMetadata:ee.optional(),tokensIn:l.number().optional(),tokensOut:l.number().optional()}),wi=l.object({stackConfirmed:l.array(l.string()).optional(),patternsDiscovered:l.array(l.string()).optional(),agentAccuracy:l.array(l.object({agent:l.string(),rating:l.enum(["helpful","neutral","inaccurate"]),note:l.string().optional()})).optional(),issuesEncountered:l.array(l.string()).optional()}),bi=l.object({taskId:l.string(),title:l.string(),classification:Ot,startedAt:l.string(),completedAt:l.string(),subtaskCount:l.number(),subtaskSummaries:l.array(Se),outcome:l.string(),branchName:l.string(),linearId:l.string().optional(),linearUuid:l.string().optional(),prUrl:l.string().optional(),feedback:wi.optional(),tokensIn:l.number().optional(),tokensOut:l.number().optional()}),_i=ur.extend({workspaceId:l.string(),worktreePath:l.string().optional(),agentSessionId:l.string().optional(),jiraId:l.string().optional(),jiraUuid:l.string().optional(),dispatchedFrom:l.string().optional()}),lr=l.object({currentTask:ur.nullable(),previousTask:ir.nullable().optional(),pausedTasks:l.array(ir).optional(),taskHistory:l.array(bi).optional(),activeTasks:l.array(_i).optional(),lastUpdated:l.string()}),vi=l.object({id:l.string(),description:l.string(),body:l.string().optional(),priority:ki,type:Ot,featureId:l.string().optional(),originFeature:l.string().optional(),completed:l.boolean(),completedAt:l.string().optional(),createdAt:l.string(),section:Ei,agent:l.string().optional(),groupName:l.string().optional(),groupId:l.string().optional()}),pr=l.object({tasks:l.array(vi),lastUpdated:l.string()});A();var yt={idle:{transitions:["task"],prompt:"prjct task <description> Start working",description:"No active task"},working:{transitions:["done","pause"],prompt:"prjct status done Complete task | prjct status paused Switch context",description:"Task in progress"},paused:{transitions:["resume","task","ship"],prompt:"prjct status active Continue | prjct task <new> Start different | prjct ship Ship directly",description:"Task paused"},completed:{transitions:["ship","task","pause","reopen"],prompt:"prjct ship Ship it | prjct task <next> Start next | prjct status active Reopen",description:"Task completed"},shipped:{transitions:["task"],prompt:"prjct task <description> Start new task",description:"Feature shipped"}},we=class{static{c(this,"WorkflowStateMachine")}getCurrentState(t,e){let s=null;if(e&&t?.activeTasks?.length&&(s=t.activeTasks.find(i=>i.workspaceId===e)),s||(s=t?.currentTask),!s)return(t?.pausedTasks?.length||0)>0||t?.previousTask?.status==="paused"?"paused":"idle";switch((typeof s.status=="string"?s.status:"").toLowerCase()){case"in_progress":case"working":return"working";case"paused":return"paused";case"completed":case"done":return"completed";case"shipped":return"shipped";default:return s?"working":"idle"}}canTransition(t,e){if(yt[t].transitions.includes(e))return{valid:!0};let n=this.formatNextSteps(t).join(" | ");return{valid:!1,error:`Cannot transition to '${e}' from '${t}' state`,suggestion:`Valid next steps: ${n}`}}getNextState(t,e){switch(e){case"task":return"working";case"done":return"completed";case"pause":return"paused";case"resume":return"working";case"ship":return"shipped";case"reopen":return"working";default:return t}}getStateInfo(t){return yt[t]}getPrompt(t){return yt[t].prompt}getValidCommands(t){return yt[t].transitions}formatNextSteps(t){return yt[t].transitions.map(s=>{switch(s){case"task":return"prjct task <desc> Start new task";case"done":return"prjct status done Complete current task";case"pause":return"prjct status paused Pause and switch context";case"resume":return"prjct status active Continue paused task";case"ship":return"prjct ship Ship the feature";case"reopen":return"prjct status active Reopen completed task";default:return`prjct ${s}`}})}},be=new we;import xi from"node:crypto";function H(){return xi.randomUUID()}c(H,"generateUUID");A();Tt();A();O();var kt={SHIPPED_RETENTION_DAYS:90,IDEA_DORMANT_DAYS:180,QUEUE_COMPLETED_DAYS:7,PAUSED_TASK_DAYS:30,MEMORY_MAX_ENTRIES:500},Ce=class{static{c(this,"ArchiveStorage")}archive(t,e){let s=H(),n=g();return k.run(t,"INSERT INTO archives (id, entity_type, entity_id, entity_data, summary, archived_at, reason) VALUES (?, ?, ?, ?, ?, ?, ?)",s,e.entityType,e.entityId,JSON.stringify(e.entityData),e.summary??null,n,e.reason),q({projectId:t,entityType:"archives",entityId:s,eventType:"upsert",data:{id:s,entity_type:e.entityType,entity_id:e.entityId,summary:e.summary??null,reason:e.reason,archived_at:n}}),s}archiveMany(t,e){if(e.length===0)return 0;let s=g();return k.transaction(t,n=>{let i=n.prepare("INSERT INTO archives (id, entity_type, entity_id, entity_data, summary, archived_at, reason) VALUES (?, ?, ?, ?, ?, ?, ?)");for(let o of e)i.run(H(),o.entityType,o.entityId,JSON.stringify(o.entityData),o.summary??null,s,o.reason)}),e.length}getArchived(t,e,s=50){return e?k.query(t,"SELECT * FROM archives WHERE entity_type = ? ORDER BY archived_at DESC LIMIT ?",e,s):k.query(t,"SELECT * FROM archives ORDER BY archived_at DESC LIMIT ?",s)}getStats(t){let e=k.query(t,"SELECT entity_type, COUNT(*) as count FROM archives GROUP BY entity_type"),s={shipped:0,idea:0,queue_task:0,paused_task:0,memory_entry:0,total:0};for(let n of e){let i=n.entity_type;i in s&&(s[i]=n.count),s.total+=n.count}return s}restore(t,e){let s=k.get(t,"SELECT * FROM archives WHERE id = ?",e);return s?(k.run(t,"DELETE FROM archives WHERE id = ?",e),JSON.parse(s.entity_data)):null}pruneOldArchives(t,e){let s=new Date(Date.now()-e*24*60*60*1e3).toISOString(),n=this.getTotalCount(t);k.run(t,"DELETE FROM archives WHERE archived_at < ?",s);let i=this.getTotalCount(t);return n-i}getTotalCount(t){return k.get(t,"SELECT COUNT(*) as count FROM archives")?.count??0}},nt=new Ce;async function Er(r,t,e){let s=await r.read(t);if(!s.currentTask)return null;r.validateTransition(s,"pause");let n={...s.currentTask,status:"paused",pausedAt:g(),pauseReason:e},i=r.getPausedTasksFromState(s),o=[n,...i].slice(0,r.maxPausedTasks);return await r.update(t,a=>({...a,currentTask:null,previousTask:null,pausedTasks:o,lastUpdated:g()})),await r.publish(t,"task.paused",{taskId:n.id,description:n.description,pausedAt:n.pausedAt,reason:e,pausedCount:o.length}),n}c(Er,"pauseTask");async function Sr(r,t,e){let s=await r.read(t),n=r.getPausedTasksFromState(s);if(n.length===0)return null;r.validateTransition(s,"resume");let i=0;if(e&&(i=n.findIndex(y=>y.id===e),i===-1))return null;let o=n[i],a=n.filter((y,j)=>j!==i),{status:u,pausedAt:p,pauseReason:m,...d}=o,h={...d,startedAt:g(),sessionId:o.sessionId??H()};return await r.update(t,y=>({...y,currentTask:h,previousTask:null,pausedTasks:a,lastUpdated:g()})),await r.publish(t,"task.resumed",{taskId:h.id,description:h.description,resumedAt:h.startedAt,remainingPaused:a.length}),h}c(Sr,"resumeTask");async function wr(r,t){let e=await r.read(t),s=r.getPausedTasksFromState(e),n=Date.now()-r.stalenessThresholdDays*24*60*60*1e3;return s.filter(i=>new Date(i.pausedAt).getTime()<n)}c(wr,"getStalePausedTasks");async function br(r,t){let e=await r.read(t),s=r.getPausedTasksFromState(e),n=Date.now()-r.stalenessThresholdDays*24*60*60*1e3,i=s.filter(a=>new Date(a.pausedAt).getTime()<n),o=s.filter(a=>new Date(a.pausedAt).getTime()>=n);if(i.length===0)return[];nt.archiveMany(t,i.map(a=>({entityType:"paused_task",entityId:a.id,entityData:a,summary:a.description,reason:"staleness"}))),await r.update(t,a=>({...a,pausedTasks:o,previousTask:null,lastUpdated:g()}));for(let a of i)await r.publish(t,"task.archived",{taskId:a.id,description:a.description,pausedAt:a.pausedAt,reason:"staleness"});return i}c(br,"archiveStalePausedTasks");A();async function _r(r,t){await r.update(t,()=>({currentTask:null,previousTask:null,pausedTasks:[],activeTasks:[],lastUpdated:g()}))}c(_r,"clearTask");async function vr(r,t){let e=await r.read(t),s=r.getPausedTasksFromState(e);return e.currentTask!==null||s.length>0}c(vr,"hasTask");async function xr(r,t){let e=await r.read(t);return r.getPausedTasksFromState(e)[0]||null}c(xr,"getPausedTask");async function Pr(r,t){let e=await r.read(t);return r.getPausedTasksFromState(e)}c(Pr,"getAllPausedTasks");async function Ne(r,t){let e=await r.read(t);return r.getTaskHistoryFromState(e)}c(Ne,"getTaskHistory");async function Rr(r,t){let e=await r.read(t);return r.getTaskHistoryFromState(e)[0]||null}c(Rr,"getMostRecentTask");async function Ar(r,t,e){let s=await r.read(t);return r.getTaskHistoryFromState(s).filter(i=>i.classification===e)}c(Ar,"getTaskHistoryByType");async function Cr(r,t){let s=(await Ne(r,t)).filter(h=>h.feedback),n=[],i=[],o=[],a=[];for(let h of s){let y=h.feedback;Array.isArray(y.stackConfirmed)&&n.push(...y.stackConfirmed),Array.isArray(y.patternsDiscovered)&&i.push(...y.patternsDiscovered),Array.isArray(y.agentAccuracy)&&o.push(...y.agentAccuracy),Array.isArray(y.issuesEncountered)&&a.push(...y.issuesEncountered)}let u=[...new Set(n)],p=[...new Set(i)],m=new Map;for(let h of a)m.set(h,(m.get(h)||0)+1);let d=[...m.entries()].filter(([h,y])=>y>=2).map(([h])=>h);return{stackConfirmed:u,patternsDiscovered:p,agentAccuracy:o,issuesEncountered:[...new Set(a)],knownGotchas:d}}c(Cr,"getAggregatedFeedback");A();async function Nr(r,t,e){let s=await r.read(t);if(!s.currentTask)return;let n=e.map((i,o)=>({...i,status:o===0?"in_progress":"pending",startedAt:o===0?g():void 0,dependsOn:i.dependsOn||[]}));await r.update(t,i=>({...i,currentTask:{...i.currentTask,subtasks:n,currentSubtaskIndex:0,subtaskProgress:{completed:0,total:n.length,percentage:0}},lastUpdated:g()})),await r.publish(t,"subtasks.created",{taskId:s.currentTask.id,subtaskCount:n.length,subtasks:n.map(i=>({id:i.id,description:i.description,domain:i.domain}))})}c(Nr,"createSubtasks");async function Ir(r,t,e){let s=or.safeParse(e);if(!s.success){let j=s.error.issues.map(St=>`${St.path.join(".")}: ${St.message}`);throw new Error(`Subtask completion requires handoff data:
551
- ${j.join(`
552
- `)}`)}let{output:n,summary:i}=s.data,o=await r.read(t);if(!o.currentTask?.subtasks)return null;let a=o.currentTask.currentSubtaskIndex||0,u=o.currentTask.subtasks[a];if(!u)return null;let p=[...o.currentTask.subtasks];p[a]={...u,status:"completed",completedAt:g(),output:n,summary:i};let m=p.filter(j=>j.status==="completed").length,d=p.length,h=Math.round(m/d*100),y=a+1;return y<p.length&&(p[y]={...p[y],status:"in_progress",startedAt:g()}),await r.update(t,j=>({...j,currentTask:{...j.currentTask,subtasks:p,currentSubtaskIndex:y<d?y:a,subtaskProgress:{completed:m,total:d,percentage:h}},lastUpdated:g()})),await r.publish(t,"subtask.completed",{taskId:o.currentTask.id,subtaskId:u.id,description:u.description,output:n,handoff:i.outputForNextAgent,filesChanged:i.filesChanged.length,progress:{completed:m,total:d,percentage:h}}),y<d?p[y]:null}c(Ir,"completeSubtask");async function Dr(r,t){let e=await r.read(t);if(!e.currentTask?.subtasks)return null;let s=e.currentTask.currentSubtaskIndex||0;return e.currentTask.subtasks[s]||null}c(Dr,"getCurrentSubtask");async function Lr(r,t){let e=await r.read(t);if(!e.currentTask?.subtasks)return null;let s=(e.currentTask.currentSubtaskIndex||0)+1;return e.currentTask.subtasks[s]||null}c(Lr,"getNextSubtask");async function Ie(r,t){let e=await r.read(t);if(!e.currentTask?.subtasks)return null;let s=(e.currentTask.currentSubtaskIndex||0)-1;return s<0?null:e.currentTask.subtasks[s]||null}c(Ie,"getPreviousSubtask");async function Or(r,t){let e=await Ie(r,t);return e?.summary?.outputForNextAgent?{fromSubtask:e.description,outputForNextAgent:e.summary.outputForNextAgent,filesChanged:e.summary.filesChanged,whatWasDone:e.summary.whatWasDone}:null}c(Or,"getPreviousHandoff");async function jr(r,t){return(await r.read(t)).currentTask?.subtasks||[]}c(jr,"getSubtasks");async function Mr(r,t){return(await r.read(t)).currentTask?.subtaskProgress||null}c(Mr,"getSubtaskProgress");async function Fr(r,t){return((await r.read(t)).currentTask?.subtasks?.length||0)>0}c(Fr,"hasSubtasks");async function Ur(r,t){let e=await r.read(t);return e.currentTask?.subtasks?e.currentTask.subtasks.every(s=>s.status==="completed"||s.status==="failed"||s.status==="skipped"):!0}c(Ur,"areAllSubtasksComplete");async function Xr(r,t,e){let s=await r.read(t);if(!s.currentTask?.subtasks)return null;let n=s.currentTask.currentSubtaskIndex||0,i=s.currentTask.subtasks[n];if(!i)return null;let o=[...s.currentTask.subtasks];o[n]={...i,status:"failed",completedAt:g(),output:`Failed: ${e}`};let a=n+1,u=o.length;a<u&&(o[a]={...o[a],status:"in_progress",startedAt:g()});let p=o.filter(d=>d.status==="completed"||d.status==="failed"||d.status==="skipped").length,m=Math.round(p/u*100);return await r.update(t,d=>({...d,currentTask:{...d.currentTask,subtasks:o,currentSubtaskIndex:a<u?a:n,subtaskProgress:{completed:p,total:u,percentage:m}},lastUpdated:g()})),await r.publish(t,"subtask.failed",{taskId:s.currentTask.id,subtaskId:i.id,description:i.description,error:e}),a<u?o[a]:null}c(Xr,"failSubtask");async function $r(r,t,e){let s=await r.read(t);if(!s.currentTask?.subtasks)return null;let n=s.currentTask.currentSubtaskIndex||0,i=s.currentTask.subtasks[n];if(!i)return null;let o=[...s.currentTask.subtasks];o[n]={...i,status:"skipped",completedAt:g(),output:`Skipped: ${e}`,skipReason:e};let a=n+1,u=o.length;a<u&&(o[a]={...o[a],status:"in_progress",startedAt:g()});let p=o.filter(d=>d.status==="completed"||d.status==="failed"||d.status==="skipped").length,m=Math.round(p/u*100);return await r.update(t,d=>({...d,currentTask:{...d.currentTask,subtasks:o,currentSubtaskIndex:a<u?a:n,subtaskProgress:{completed:p,total:u,percentage:m}},lastUpdated:g()})),await r.publish(t,"subtask.skipped",{taskId:s.currentTask.id,subtaskId:i.id,description:i.description,reason:e}),a<u?o[a]:null}c($r,"skipSubtask");async function Wr(r,t,e){let s=await r.read(t);if(!s.currentTask?.subtasks)return null;let n=s.currentTask.currentSubtaskIndex||0,i=s.currentTask.subtasks[n];if(!i)return null;let o=[...s.currentTask.subtasks];o[n]={...i,status:"blocked",output:`Blocked: ${e}`,blockReason:e};let a=n+1,u=o.length;return a<u&&(o[a]={...o[a],status:"in_progress",startedAt:g()}),await r.update(t,p=>({...p,currentTask:{...p.currentTask,subtasks:o,currentSubtaskIndex:a<u?a:n},lastUpdated:g()})),await r.publish(t,"subtask.blocked",{taskId:s.currentTask.id,subtaskId:i.id,description:i.description,blocker:e}),a<u?o[a]:null}c(Wr,"blockSubtask");A();async function Br(r,t,e,s){let n={...e,workspaceId:s,startedAt:g()};return await r.update(t,i=>({...i,activeTasks:[...i.activeTasks||[],n],lastUpdated:g()})),await r.publish(t,"task.started",{taskId:n.id,description:n.description,startedAt:n.startedAt,sessionId:n.sessionId,workspaceId:s}),n}c(Br,"startTaskInWorkspace");async function Hr(r,t,e){return((await r.read(t)).activeTasks||[]).find(n=>n.workspaceId===e)??null}c(Hr,"getCurrentTaskForWorkspace");async function qr(r,t,e,s){let n=await r.read(t),o=(n.activeTasks||[]).find(d=>d.workspaceId===e);if(!o)return null;let a=g(),u=r.createTaskHistoryEntry(o,a,s),p=r.getTaskHistoryFromState(n),m=[u,...p].slice(0,r.maxTaskHistory);return await r.update(t,d=>({...d,activeTasks:(d.activeTasks||[]).filter(h=>h.workspaceId!==e),taskHistory:m,lastUpdated:a})),await r.publish(t,"task.completed",{taskId:o.id,description:o.description,startedAt:o.startedAt,completedAt:a,workspaceId:e}),o}c(qr,"completeTaskInWorkspace");async function Gr(r,t){return(await r.read(t)).activeTasks||[]}c(Gr,"getActiveTasks");async function Yr(r,t){return((await r.read(t)).activeTasks||[]).length}c(Yr,"getActiveTaskCount");async function Jr(r,t,e,s){let i=(await r.read(t)).activeTasks||[],o=i.findIndex(u=>u.workspaceId===e);if(o===-1)return null;let a={...i[o],...s,workspaceId:e};return await r.update(t,u=>{let p=[...u.activeTasks||[]];return p[o]=a,{...u,activeTasks:p,lastUpdated:g()}}),a}c(Jr,"updateWorkspaceTask");async function zr(r,t,e,s){let n=await r.read(t);if(!n.currentTask)return null;let i=(n.currentTask.tokensIn||0)+e,o=(n.currentTask.tokensOut||0)+s;return await r.update(t,a=>({...a,currentTask:{...a.currentTask,tokensIn:i,tokensOut:o},lastUpdated:g()})),{tokensIn:i,tokensOut:o}}c(zr,"addTokens");xe();re();A();O();import $i from"node:crypto";function Wi(r){let[t,e]=r.split(".");return t?{entityType:t.endsWith("s")?t:`${t}s`,eventType:e==="deleted"||e==="archived"||e==="removed"?"delete":"upsert"}:{}}c(Wi,"deriveEntityShape");function Bi(r){if(!r||typeof r!="object")return;let t=r;for(let e of["taskId","task_id","id","feature_id","featureId","specId","spec_id"]){let s=t[e];if(typeof s=="string"&&s.length>0)return s}}c(Bi,"entityIdOf");function Hi(r){let t=r&&typeof r=="object"&&!Array.isArray(r)?JSON.stringify(qi(r)):JSON.stringify(r);return $i.createHash("sha256").update(t).digest("hex")}c(Hi,"hashPayload");function qi(r){let t={};for(let e of Object.keys(r).sort())t[e]=r[e];return t}c(qi,"sortKeys");var Ft=null;async function Gi(){if(Ft)return Ft;try{let{default:r}=await Promise.resolve().then(()=>(Ae(),Re)),t=r;return typeof t.getDeviceId=="function"?(Ft=await t.getDeviceId(),Ft):"unknown-device"}catch{return"unknown-device"}}c(Gi,"_resolveDeviceId");var it=class{static{c(this,"StorageManager")}filename;cache;constructor(t,e){this.filename=t,this.cache=new vt({ttl:5e3,maxSize:50})}getStoreKey(){return this.filename.replace(".json","")}async read(t){let e=this.cache.get(t);if(e!==null)return e;try{let s=k.getDoc(t,this.getStoreKey());if(s!==null)return this.cache.set(t,s),s}catch{}return this.getDefault()}async write(t,e){k.setDoc(t,this.getStoreKey(),e),this.cache.set(t,e)}async update(t,e){let s=await this.read(t),n=e(s);return await this.write(t,n),n}async publishEvent(t,e,s){let n=Wi(e),i={type:e,path:[this.filename.replace(".json","")],data:s,timestamp:g(),projectId:t,entityType:n.entityType,entityId:Bi(s),eventType:n.eventType,contentHash:Hi(s),deviceId:await Gi(),revisionCount:1};await jt.publish(i)}async publishEntityEvent(t,e,s,n){let i=`${e}.${s}`,o={...n,timestamp:g()};await this.publishEvent(t,i,o)}async exists(t){try{return k.hasDoc(t,this.getStoreKey())}catch{return!1}}clearCache(t){t?this.cache.delete(t):this.cache.clear()}getCacheStats(){return this.cache.stats()}};var De=class extends it{static{c(this,"StateStorage")}constructor(){super("state.json",lr)}getDefault(){return{currentTask:null,previousTask:null,pausedTasks:[],taskHistory:[],activeTasks:[],lastUpdated:""}}getEventType(t){return`state.${t}d`}validateTransition(t,e){let s=be.getCurrentState(t),n=be.canTransition(s,e);if(!n.valid)throw new Error(`${n.error}. ${n.suggestion||""}`.trim())}async getCurrentTask(t){return(await this.read(t)).currentTask}async getPausedTasks(t){let e=await this.read(t);return this.getPausedTasksFromState(e)}async startTask(t,e){let s=await this.read(t);this.validateTransition(s,"task");let n={...e,startedAt:g()};return await this.update(t,i=>({...i,currentTask:n,lastUpdated:g()})),await this.publishEvent(t,"task.started",{taskId:n.id,description:n.description,startedAt:n.startedAt,sessionId:n.sessionId}),n}async updateCurrentTask(t,e){let s=await this.read(t);if(!s.currentTask)return null;let n={...s.currentTask,...e};return await this.update(t,i=>({...i,currentTask:n,lastUpdated:g()})),n}async completeTask(t,e){let s=await this.read(t),n=s.currentTask;if(!n)return null;this.validateTransition(s,"done");let i=g(),o=this.createTaskHistoryEntry(n,i,e),a=this.getTaskHistoryFromState(s),u=[o,...a].slice(0,this.maxTaskHistory);return await this.update(t,p=>({...p,currentTask:null,previousTask:null,taskHistory:u,lastUpdated:i})),await this.publishEvent(t,"task.completed",{taskId:n.id,description:n.description,startedAt:n.startedAt,completedAt:i}),n}createTaskHistoryEntry(t,e,s){let n=(t.subtasks||[]).filter(a=>a.status==="completed"&&a.summary).map(a=>a.summary),i=n.length>0?n.map(a=>a.title).join(", "):"Task completed",o={taskId:t.id,title:t.parentDescription||t.description,classification:t.type||"improvement",startedAt:t.startedAt,completedAt:e,subtaskCount:t.subtasks?.length||0,subtaskSummaries:n,outcome:i,branchName:t.branch||"unknown",linearId:t.linearId,linearUuid:t.linearUuid,prUrl:t.prUrl};return s&&(o.feedback=s),t.tokensIn&&(o.tokensIn=t.tokensIn),t.tokensOut&&(o.tokensOut=t.tokensOut),o}maxPausedTasks=5;maxTaskHistory=20;stalenessThresholdDays=30;lifecycleBackend(){return{read:this.read.bind(this),update:this.update.bind(this),publish:this.publishEvent.bind(this),validateTransition:this.validateTransition.bind(this),getPausedTasksFromState:this.getPausedTasksFromState.bind(this),maxPausedTasks:this.maxPausedTasks,stalenessThresholdDays:this.stalenessThresholdDays}}async pauseTask(t,e){return Er(this.lifecycleBackend(),t,e)}async resumeTask(t,e){return Sr(this.lifecycleBackend(),t,e)}getPausedTasksFromState(t){return Array.isArray(t.pausedTasks)&&t.pausedTasks.length>0?t.pausedTasks:t.previousTask?[t.previousTask]:[]}getTaskHistoryFromState(t){return t.taskHistory||[]}async getStalePausedTasks(t){return wr(this.lifecycleBackend(),t)}async archiveStalePausedTasks(t){return br(this.lifecycleBackend(),t)}queryBackend(){return{read:this.read.bind(this),update:this.update.bind(this),getPausedTasksFromState:this.getPausedTasksFromState.bind(this),getTaskHistoryFromState:this.getTaskHistoryFromState.bind(this)}}async clearTask(t){return _r(this.queryBackend(),t)}async hasTask(t){return vr(this.queryBackend(),t)}async getPausedTask(t){return xr(this.queryBackend(),t)}async getAllPausedTasks(t){return Pr(this.queryBackend(),t)}async getTaskHistory(t){return Ne(this.queryBackend(),t)}async getMostRecentTask(t){return Rr(this.queryBackend(),t)}async getTaskHistoryByType(t,e){return Ar(this.queryBackend(),t,e)}async getAggregatedFeedback(t){return Cr(this.queryBackend(),t)}workspaceBackend(){return{read:this.read.bind(this),update:this.update.bind(this),publish:this.publishEvent.bind(this),createTaskHistoryEntry:this.createTaskHistoryEntry.bind(this),getTaskHistoryFromState:this.getTaskHistoryFromState.bind(this),maxTaskHistory:this.maxTaskHistory}}async startTaskInWorkspace(t,e,s){return Br(this.workspaceBackend(),t,e,s)}async getCurrentTaskForWorkspace(t,e){return Hr(this.workspaceBackend(),t,e)}async completeTaskInWorkspace(t,e,s){return qr(this.workspaceBackend(),t,e,s)}async getActiveTasks(t){return Gr(this.workspaceBackend(),t)}async getActiveTaskCount(t){return Yr(this.workspaceBackend(),t)}async updateWorkspaceTask(t,e,s){return Jr(this.workspaceBackend(),t,e,s)}async addTokens(t,e,s){return zr(this.workspaceBackend(),t,e,s)}subtaskBackend(){return{read:this.read.bind(this),update:this.update.bind(this),publish:this.publishEvent.bind(this)}}async createSubtasks(t,e){return Nr(this.subtaskBackend(),t,e)}async completeSubtask(t,e){return Ir(this.subtaskBackend(),t,e)}async getCurrentSubtask(t){return Dr(this.subtaskBackend(),t)}async getNextSubtask(t){return Lr(this.subtaskBackend(),t)}async getPreviousSubtask(t){return Ie(this.subtaskBackend(),t)}async getPreviousHandoff(t){return Or(this.subtaskBackend(),t)}async getSubtasks(t){return jr(this.subtaskBackend(),t)}async getSubtaskProgress(t){return Mr(this.subtaskBackend(),t)}async hasSubtasks(t){return Fr(this.subtaskBackend(),t)}async areAllSubtasksComplete(t){return Ur(this.subtaskBackend(),t)}async failSubtask(t,e){return Xr(this.subtaskBackend(),t,e)}async skipSubtask(t,e){return $r(this.subtaskBackend(),t,e)}async blockSubtask(t,e){return Wr(this.subtaskBackend(),t,e)}},ot=new De;K();et();import Yi from"node:fs/promises";import Ut from"node:path";var Kr={frontend:["component","page","view","ui","layout","style","css","scss","sass","hook","context","store","redux","zustand","react","vue","svelte","angular","next","nuxt","app","client"],backend:["api","route","controller","service","middleware","handler","resolver","schema","model","entity","repository","server","socket","graphql","rest","trpc"],database:["migration","seed","schema","model","entity","repository","prisma","drizzle","sequelize","typeorm","mongoose","knex","sql","db"],auth:["auth","login","logout","session","token","jwt","oauth","passport","credential","permission","role","user","account"],testing:["test","spec","e2e","integration","unit","mock","fixture","stub","jest","vitest","cypress","playwright"],config:["config","env","setting","constant","option","tsconfig","eslint","prettier","vite","webpack","rollup"],infra:["docker","compose","kubernetes","k8s","ci","cd","github","gitlab","jenkins","terraform","ansible","deploy"],util:["util","helper","lib","common","shared","core","base","abstract"]},Vr=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".py",".go",".rs",".java",".kt",".swift",".rb",".php",".c",".cpp",".h",".hpp",".cs",".vue",".svelte"]),Qr=new Set(["node_modules",".git","dist","build",".next",".nuxt",".output","coverage",".cache","__pycache__",".pytest_cache","vendor","target",".turbo",".vercel"]),Zr=new Set(["a","an","the","and","or","but","is","are","was","were","be","been","being","have","has","had","do","does","did","will","would","could","should","may","might","must","shall","can","need","to","of","in","for","on","with","at","by","from","as","into","through","during","before","after","above","below","between","under","again","further","then","once","here","there","when","where","why","how","all","each","few","more","most","other","some","such","no","nor","not","only","own","same","so","than","too","very","just","add","create","make","implement","fix","update","change","modify","remove","delete","new"]);async function tn(r,t,e={}){let s=Date.now(),n=e.maxFiles??30,i=e.minScore??.1,o=e.includeTests??!1,a=Ji(r),u=await zi(t),p=await Ki(t),m=[];for(let h of u){if(!o&&Qi(h))continue;let y=Vi(h,a,p,e.historicalBoosts);y.score>=i&&m.push(y)}m.sort((h,y)=>y.score-h.score);let d=m.slice(0,n);return{files:d,metrics:{filesScanned:u.length,filesReturned:d.length,scanDuration:Date.now()-s}}}c(tn,"findRelevantFiles");function Ji(r){return r.toLowerCase().split(/[^a-z0-9]+/).filter(Boolean).filter(e=>!Zr.has(e)&&e.length>2)}c(Ji,"extractKeywords");async function zi(r){let t=[];async function e(s,n=""){try{let i=await Yi.readdir(s,{withFileTypes:!0});for(let o of i){let a=Ut.join(s,o.name),u=Ut.join(n,o.name);if(o.isDirectory()){if(Qr.has(o.name)||o.name.startsWith("."))continue;await e(a,u)}else if(o.isFile()){let p=Ut.extname(o.name).toLowerCase();Vr.has(p)&&t.push(u)}}}catch(i){D(i)}}return c(e,"walk"),await e(r),t}c(zi,"getAllCodeFiles");async function Ki(r){let t=new Map;try{let{stdout:e}=await b(`git log -30 --pretty=format:"%H %ct" --name-only | awk '
553
- /^[a-f0-9]{40}/ { commit=$1; timestamp=$2; next }
554
- NF { files[$0]++; if (!lastmod[$0]) lastmod[$0]=timestamp }
555
- END { for (f in files) print files[f], lastmod[f], f }
556
- '`,{cwd:r,maxBuffer:10485760}),s=Math.floor(Date.now()/1e3),n=e.trim().split(`
557
- `).filter(Boolean);for(let i of n){let o=i.match(/^(\d+)\s+(\d+)\s+(.+)$/);if(o){let a=parseInt(o[1],10),u=parseInt(o[2],10),p=o[3],m=Math.floor((s-u)/86400);t.set(p,{commits:a,daysAgo:m})}}}catch{}return t}c(Ki,"getGitRecency");function Vi(r,t,e,s){let n=[],i=0,o=0,a=0,u=0,p=0,m=r.toLowerCase(),d=m.split("/").join(" ").split(/[^a-z0-9]+/);for(let C of t){m.includes(C)&&(i+=.3,n.push(`keyword:${C}`));for(let ut of d)if(ut.includes(C)||C.includes(ut)){i+=.15;break}}i=Math.min(1,i);for(let[C,ut]of Object.entries(Kr))for(let xn of ut)if(m.includes(xn)&&t.some(Bt=>ut.includes(Bt)||Bt.includes(C)||C.includes(Bt))){o+=.4,n.push(`domain:${C}`);break}o=Math.min(1,o);let h=e.get(r);h&&(h.daysAgo<=1?(a=1,n.push("recent:1d")):h.daysAgo<=3?(a=.8,n.push("recent:3d")):h.daysAgo<=7?(a=.6,n.push("recent:1w")):h.daysAgo<=30&&(a=.3,n.push("recent:1m")),h.commits>=5&&(a=Math.min(1,a+.2)));let y=Ut.basename(r).toLowerCase();if((y.includes("index")||y.includes("main")||y.includes("app")||y.includes("entry"))&&(u=.5,n.push("import:0")),(m.includes("/core/")||m.includes("/shared/")||m.includes("/lib/"))&&(u=Math.max(u,.3),n.some(C=>C.startsWith("import:"))||n.push("import:1")),s){let C=s.get(r);C!==void 0&&(p=(C+1)/2,C>0?n.push("history:boosted"):C<0&&n.push("history:penalized"))}let St=s&&s.size>0?i*.54+o*.18+a*.13+u*.05+p*.1:i*.6+o*.2+a*.15+u*.05;return{path:r,score:Math.min(1,St),reasons:[...new Set(n)]}}c(Vi,"scoreFile");function Qi(r){let t=r.toLowerCase();return t.includes(".test.")||t.includes(".spec.")||t.includes("__tests__")||t.includes("__mocks__")||t.includes("/tests/")||t.includes("/test/")||t.endsWith("_test.go")||t.endsWith("_test.py")}c(Qi,"isTestFile");K();import ro from"node:fs/promises";import at from"node:path";var to={"claude-opus-4.5":{input:.005,output:.025},"claude-sonnet-4.5":{input:.003,output:.015},"claude-haiku-4.5":{input:.001,output:.005},"claude-opus-4":{input:.015,output:.075},"claude-opus-4-6":{input:.015,output:.075},"gpt-4o":{input:.0025,output:.01},"gpt-4-turbo":{input:.01,output:.03},"gpt-4o-mini":{input:15e-5,output:6e-4},"gemini-1.5-pro":{input:.00125,output:.005},"gemini-1.5-flash":{input:75e-6,output:3e-4}},eo="claude-sonnet-4.5";function Le(r){return!r||r.length===0?0:Math.ceil(r.length/4)}c(Le,"countTokens");var sn=["claude-sonnet-4.5","claude-opus-4.5","claude-opus-4-6","gpt-4o","gemini-1.5-pro"];function en(r,t){let e=to[t],s=r/1e3*e.input,n=r/1e3*e.output*.3;return{inputSaved:s,outputPotential:n,total:s+n}}c(en,"calculateModelCost");function so(r){return r<.001?"<$0.01":r<.01?`$${r.toFixed(3)}`:`$${r.toFixed(2)}`}c(so,"formatCostSaved");function rn(r,t){let e=Le(r),s=Le(t),n=Math.max(0,e-s),i=e>0?(e-s)/e:0,o=en(n,eo),a=sn.map(u=>({model:u,...en(n,u)}));return{tokens:{original:e,filtered:s,saved:n},compression:Math.max(0,Math.min(1,i)),cost:{saved:o.total,formatted:so(o.total),byModel:a}}}c(rn,"measureCompression");function Xt(r){let t=Le(r);return{tokens:{original:t,filtered:t,saved:0},compression:0,cost:{saved:0,formatted:"$0.00",byModel:sn.map(e=>({model:e,inputSaved:0,outputPotential:0,total:0}))}}}c(Xt,"noCompression");var no={".ts":"typescript",".tsx":"typescript",".js":"javascript",".jsx":"javascript",".mjs":"javascript",".cjs":"javascript",".py":"python",".go":"go",".rs":"rust",".java":"java",".cs":"csharp",".php":"php",".rb":"ruby"},nn=[{type:"function",pattern:/^export\s+(?:async\s+)?function\s+(\w+)\s*(<[^>]*>)?\s*\(([^)]*)\)\s*(?::\s*([^{;]+))?/gm,nameIndex:1,exported:!0},{type:"function",pattern:/^export\s+const\s+(\w+)\s*(?::\s*[^=]+)?\s*=\s*(?:async\s+)?\([^)]*\)\s*(?::\s*[^=]+)?\s*=>/gm,nameIndex:1,exported:!0},{type:"function",pattern:/^(?:async\s+)?function\s+(\w+)\s*(<[^>]*>)?\s*\(([^)]*)\)\s*(?::\s*([^{;]+))?/gm,nameIndex:1},{type:"function",pattern:/^const\s+(\w+)\s*(?::\s*[^=]+)?\s*=\s*(?:async\s+)?\([^)]*\)\s*(?::\s*[^=]+)?\s*=>/gm,nameIndex:1},{type:"interface",pattern:/^export\s+interface\s+(\w+)(?:<[^>]+>)?\s*(?:extends\s+[^{]+)?\s*\{/gm,nameIndex:1,exported:!0},{type:"interface",pattern:/^interface\s+(\w+)(?:<[^>]+>)?\s*(?:extends\s+[^{]+)?\s*\{/gm,nameIndex:1},{type:"type",pattern:/^export\s+type\s+(\w+)(?:<[^>]+>)?\s*=/gm,nameIndex:1,exported:!0},{type:"type",pattern:/^type\s+(\w+)(?:<[^>]+>)?\s*=/gm,nameIndex:1},{type:"class",pattern:/^export\s+(?:abstract\s+)?class\s+(\w+)(?:<[^>]+>)?(?:\s+extends\s+[^{]+)?(?:\s+implements\s+[^{]+)?\s*\{/gm,nameIndex:1,exported:!0},{type:"class",pattern:/^(?:abstract\s+)?class\s+(\w+)(?:<[^>]+>)?(?:\s+extends\s+[^{]+)?(?:\s+implements\s+[^{]+)?\s*\{/gm,nameIndex:1},{type:"enum",pattern:/^export\s+enum\s+(\w+)\s*\{/gm,nameIndex:1,exported:!0},{type:"enum",pattern:/^enum\s+(\w+)\s*\{/gm,nameIndex:1},{type:"const",pattern:/^export\s+const\s+(\w+)\s*(?::\s*([^=]+))?\s*=/gm,nameIndex:1,exported:!0}],io=[{type:"function",pattern:/^def\s+(\w+)\s*\(([^)]*)\)\s*(?:->\s*([^:]+))?\s*:/gm,nameIndex:1},{type:"function",pattern:/^async\s+def\s+(\w+)\s*\(([^)]*)\)\s*(?:->\s*([^:]+))?\s*:/gm,nameIndex:1},{type:"class",pattern:/^class\s+(\w+)(?:\(([^)]*)\))?\s*:/gm,nameIndex:1}],oo=[{type:"function",pattern:/^func\s+(\w+)\s*\(([^)]*)\)\s*(?:\(([^)]*)\)|([^\s{]+))?\s*\{/gm,nameIndex:1},{type:"method",pattern:/^func\s+\([^)]+\)\s+(\w+)\s*\(([^)]*)\)\s*(?:\(([^)]*)\)|([^\s{]+))?\s*\{/gm,nameIndex:1},{type:"type",pattern:/^type\s+(\w+)\s+(?:struct|interface)\s*\{/gm,nameIndex:1}],ao=[{type:"function",pattern:/^pub\s+(?:async\s+)?fn\s+(\w+)(?:<[^>]+>)?\s*\(([^)]*)\)\s*(?:->\s*([^{]+))?\s*\{/gm,nameIndex:1,exported:!0},{type:"function",pattern:/^(?:async\s+)?fn\s+(\w+)(?:<[^>]+>)?\s*\(([^)]*)\)\s*(?:->\s*([^{]+))?\s*\{/gm,nameIndex:1},{type:"class",pattern:/^pub\s+struct\s+(\w+)(?:<[^>]+>)?\s*(?:\{|;)/gm,nameIndex:1,exported:!0},{type:"class",pattern:/^struct\s+(\w+)(?:<[^>]+>)?\s*(?:\{|;)/gm,nameIndex:1},{type:"interface",pattern:/^pub\s+trait\s+(\w+)(?:<[^>]+>)?\s*(?:\{|:)/gm,nameIndex:1,exported:!0},{type:"interface",pattern:/^trait\s+(\w+)(?:<[^>]+>)?\s*(?:\{|:)/gm,nameIndex:1},{type:"enum",pattern:/^pub\s+enum\s+(\w+)(?:<[^>]+>)?\s*\{/gm,nameIndex:1,exported:!0},{type:"enum",pattern:/^enum\s+(\w+)(?:<[^>]+>)?\s*\{/gm,nameIndex:1}],on=[{type:"class",pattern:/^(?:public\s+)?(?:abstract\s+)?(?:final\s+)?class\s+(\w+)(?:<[^>]+>)?(?:\s+extends\s+\w+)?(?:\s+implements\s+[^{]+)?\s*\{/gm,nameIndex:1,exported:!0},{type:"interface",pattern:/^(?:public\s+)?interface\s+(\w+)(?:<[^>]+>)?(?:\s+extends\s+[^{]+)?\s*\{/gm,nameIndex:1,exported:!0},{type:"method",pattern:/^\s+(?:public|private|protected)?\s*(?:static\s+)?(?:final\s+)?(?:synchronized\s+)?(?:<[^>]+>\s+)?(\w+(?:<[^>]+>)?)\s+(\w+)\s*\([^)]*\)\s*(?:throws\s+[^{]+)?\s*\{/gm,nameIndex:2}],co={typescript:nn,javascript:nn,python:io,go:oo,rust:ao,java:on,csharp:on,php:[],ruby:[],unknown:[]};async function an(r,t=process.cwd()){let e=at.isAbsolute(r)?r:at.join(t,r),s=at.resolve(t),n=at.resolve(e);if(!n.startsWith(s+at.sep)&&n!==s)return{file:r,language:"unknown",signatures:[],fallback:!0,fallbackReason:"Path traversal denied: file is outside project directory",metrics:Xt("")};let i;try{i=await ro.readFile(e,"utf-8")}catch(d){if(D(d))return{file:r,language:"unknown",signatures:[],fallback:!0,fallbackReason:"File not found",metrics:Xt("")};throw d}let o=at.extname(r).toLowerCase(),a=no[o]||"unknown",u=co[a];if(!u||u.length===0)return{file:r,language:a,signatures:[],fallback:!0,fallbackReason:`No extraction patterns for ${a}`,metrics:Xt(i)};let p=uo(i,u),m=p.map(d=>`${d.exported?"export ":""}${d.type} ${d.name}: ${d.signature}`).join(`
558
- `);return{file:r,language:a,signatures:p,fallback:!1,metrics:rn(i,m)}}c(an,"extractSignatures");function uo(r,t){let e=[],s=r.split(`
556
+ `)}]}})),t.tool("prjct_cochange","Files that historically change together (Jaccard similarity from git history)",{projectPath:I.string().describe("Project directory path"),seedFiles:I.array(I.string()).describe("Seed files to find co-change partners for"),rebuild:I.boolean().optional().default(!1).describe("Force rebuild the co-change matrix"),maxResults:I.number().optional().default(10).describe("Max results (default 10)")},S("prjct_cochange",async e=>{let s=await x(e.projectPath),n=e.rebuild?null:Te(s);n||(n=await er(e.projectPath,s));let i=ye(e.seedFiles,n).slice(0,e.maxResults);if(i.length===0)return{content:[{type:"text",text:"No co-change partners found."}]};let o=["## Co-Change Partners",`Seeds: ${e.seedFiles.join(", ")}`,`Commits analyzed: ${n.commitsAnalyzed}`,""];for(let a of i)o.push(`- ${a.path} (similarity: ${Math.round(a.score*100)}%)`);return{content:[{type:"text",text:o.join(`
557
+ `)}]}})),t.tool("prjct_related_context","Combined: import neighbors + co-change partners for seed files",{projectPath:I.string().describe("Project directory path"),seedFiles:I.array(I.string()).describe("Seed files to find related context for"),maxResults:I.number().optional().default(15).describe("Max results (default 15)")},S("prjct_related_context",async e=>{let s=await x(e.projectPath),n=gt(s),i=n?zs(e.seedFiles,n):[],o=Te(s),a=o?ye(e.seedFiles,o):[],u=new Map;for(let d of i)u.set(d.path,{importScore:d.score,cochangeScore:0});for(let d of a){let h=u.get(d.path);h?h.cochangeScore=d.score:u.set(d.path,{importScore:0,cochangeScore:d.score})}let p=Array.from(u.entries()).map(([d,h])=>({path:d,combined:h.importScore*.6+h.cochangeScore*.4,importScore:h.importScore,cochangeScore:h.cochangeScore})).sort((d,h)=>h.combined-d.combined).slice(0,e.maxResults);if(p.length===0)return{content:[{type:"text",text:"No related files found. Run `prjct sync` to build indexes."}]};let m=["## Related Context",`Seeds: ${e.seedFiles.join(", ")}`,""];for(let d of p){let h=[];d.importScore>0&&h.push(`import: ${d.importScore.toFixed(2)}`),d.cochangeScore>0&&h.push(`cochange: ${Math.round(d.cochangeScore*100)}%`),m.push(`- ${d.path} (${h.join(", ")})`)}return{content:[{type:"text",text:m.join(`
558
+ `)}]}}))}c(ur,"registerCodeIntelTools");import{z as Z}from"zod";oe();import{z as l}from"zod";var Ai=l.enum(["low","medium","high","critical"]),Mt=l.enum(["feature","bug","improvement","chore"]),Ci=l.enum(["active","backlog","previously_active"]),Ni=l.enum(["pending","in_progress","completed","blocked","paused","failed","skipped"]),ve=l.object({title:l.string(),description:l.string(),filesChanged:l.array(l.object({path:l.string(),action:l.enum(["created","modified","deleted"])})),whatWasDone:l.array(l.string()).min(1),outputForNextAgent:l.string().min(1),notes:l.string().optional()}),pr=l.object({output:l.string().min(1,"Subtask output is required"),summary:ve}),dr=l.object({id:l.string(),description:l.string(),domain:l.string(),agent:l.string(),status:Ni,dependsOn:l.array(l.string()),startedAt:l.string().optional(),completedAt:l.string().optional(),output:l.string().optional(),summary:ve.optional(),skipReason:l.string().optional(),blockReason:l.string().optional(),estimatedPoints:l.number().optional(),estimatedMinutes:l.number().optional()}),mr=l.object({completed:l.number(),total:l.number(),percentage:l.number()}),gr=l.object({id:l.string(),description:l.string(),type:Mt.optional(),startedAt:l.string(),sessionId:l.string(),featureId:l.string().optional(),subtasks:l.array(dr).optional(),currentSubtaskIndex:l.number().optional(),subtaskProgress:mr.optional(),linearId:l.string().optional(),linearUuid:l.string().optional(),linkedSpecId:l.string().optional(),estimatedPoints:l.number().optional(),estimatedMinutes:l.number().optional(),modelMetadata:ie.optional(),tokensIn:l.number().optional(),tokensOut:l.number().optional(),parentDescription:l.string().optional(),branch:l.string().optional(),prUrl:l.string().optional()}),lr=l.object({id:l.string(),description:l.string(),status:l.literal("paused"),startedAt:l.string(),pausedAt:l.string(),pauseReason:l.string().optional(),type:Mt.optional(),sessionId:l.string().optional(),featureId:l.string().optional(),subtasks:l.array(dr).optional(),currentSubtaskIndex:l.number().optional(),subtaskProgress:mr.optional(),linearId:l.string().optional(),linearUuid:l.string().optional(),estimatedPoints:l.number().optional(),estimatedMinutes:l.number().optional(),modelMetadata:ie.optional(),tokensIn:l.number().optional(),tokensOut:l.number().optional()}),Ii=l.object({stackConfirmed:l.array(l.string()).optional(),patternsDiscovered:l.array(l.string()).optional(),agentAccuracy:l.array(l.object({agent:l.string(),rating:l.enum(["helpful","neutral","inaccurate"]),note:l.string().optional()})).optional(),issuesEncountered:l.array(l.string()).optional()}),Di=l.object({taskId:l.string(),title:l.string(),classification:Mt,startedAt:l.string(),completedAt:l.string(),subtaskCount:l.number(),subtaskSummaries:l.array(ve),outcome:l.string(),branchName:l.string(),linearId:l.string().optional(),linearUuid:l.string().optional(),prUrl:l.string().optional(),feedback:Ii.optional(),tokensIn:l.number().optional(),tokensOut:l.number().optional()}),Li=gr.extend({workspaceId:l.string(),worktreePath:l.string().optional(),agentSessionId:l.string().optional(),jiraId:l.string().optional(),jiraUuid:l.string().optional(),dispatchedFrom:l.string().optional()}),fr=l.object({currentTask:gr.nullable(),previousTask:lr.nullable().optional(),pausedTasks:l.array(lr).optional(),taskHistory:l.array(Di).optional(),activeTasks:l.array(Li).optional(),lastUpdated:l.string()}),Oi=l.object({id:l.string(),description:l.string(),body:l.string().optional(),priority:Ai,type:Mt,featureId:l.string().optional(),originFeature:l.string().optional(),completed:l.boolean(),completedAt:l.string().optional(),createdAt:l.string(),section:Ci,agent:l.string().optional(),groupName:l.string().optional(),groupId:l.string().optional()}),hr=l.object({tasks:l.array(Oi),lastUpdated:l.string()});A();var yt={idle:{transitions:["task"],prompt:"prjct task <description> Start working",description:"No active task"},working:{transitions:["done","pause"],prompt:"prjct status done Complete task | prjct status paused Switch context",description:"Task in progress"},paused:{transitions:["resume","task","ship"],prompt:"prjct status active Continue | prjct task <new> Start different | prjct ship Ship directly",description:"Task paused"},completed:{transitions:["ship","task","pause","reopen"],prompt:"prjct ship Ship it | prjct task <next> Start next | prjct status active Reopen",description:"Task completed"},shipped:{transitions:["task"],prompt:"prjct task <description> Start new task",description:"Feature shipped"}},xe=class{static{c(this,"WorkflowStateMachine")}getCurrentState(t,e){let s=null;if(e&&t?.activeTasks?.length&&(s=t.activeTasks.find(i=>i.workspaceId===e)),s||(s=t?.currentTask),!s)return(t?.pausedTasks?.length||0)>0||t?.previousTask?.status==="paused"?"paused":"idle";switch((typeof s.status=="string"?s.status:"").toLowerCase()){case"in_progress":case"working":return"working";case"paused":return"paused";case"completed":case"done":return"completed";case"shipped":return"shipped";default:return s?"working":"idle"}}canTransition(t,e){if(yt[t].transitions.includes(e))return{valid:!0};let n=this.formatNextSteps(t).join(" | ");return{valid:!1,error:`Cannot transition to '${e}' from '${t}' state`,suggestion:`Valid next steps: ${n}`}}getNextState(t,e){switch(e){case"task":return"working";case"done":return"completed";case"pause":return"paused";case"resume":return"working";case"ship":return"shipped";case"reopen":return"working";default:return t}}getStateInfo(t){return yt[t]}getPrompt(t){return yt[t].prompt}getValidCommands(t){return yt[t].transitions}formatNextSteps(t){return yt[t].transitions.map(s=>{switch(s){case"task":return"prjct task <desc> Start new task";case"done":return"prjct status done Complete current task";case"pause":return"prjct status paused Pause and switch context";case"resume":return"prjct status active Continue paused task";case"ship":return"prjct ship Ship the feature";case"reopen":return"prjct status active Reopen completed task";default:return`prjct ${s}`}})}},Pe=new xe;Tt();A();Xt();async function vr(r,t,e){let s=await r.read(t);if(!s.currentTask)return null;r.validateTransition(s,"pause");let n={...s.currentTask,status:"paused",pausedAt:g(),pauseReason:e},i=r.getPausedTasksFromState(s),o=[n,...i].slice(0,r.maxPausedTasks);return await r.update(t,a=>({...a,currentTask:null,previousTask:null,pausedTasks:o,lastUpdated:g()})),await r.publish(t,"task.paused",{taskId:n.id,description:n.description,pausedAt:n.pausedAt,reason:e,pausedCount:o.length}),n}c(vr,"pauseTask");async function xr(r,t,e){let s=await r.read(t),n=r.getPausedTasksFromState(s);if(n.length===0)return null;r.validateTransition(s,"resume");let i=0;if(e&&(i=n.findIndex(y=>y.id===e),i===-1))return null;let o=n[i],a=n.filter((y,M)=>M!==i),{status:u,pausedAt:p,pauseReason:m,...d}=o,h={...d,startedAt:g(),sessionId:o.sessionId??q()};return await r.update(t,y=>({...y,currentTask:h,previousTask:null,pausedTasks:a,lastUpdated:g()})),await r.publish(t,"task.resumed",{taskId:h.id,description:h.description,resumedAt:h.startedAt,remainingPaused:a.length}),h}c(xr,"resumeTask");async function Pr(r,t){let e=await r.read(t),s=r.getPausedTasksFromState(e),n=Date.now()-r.stalenessThresholdDays*24*60*60*1e3;return s.filter(i=>new Date(i.pausedAt).getTime()<n)}c(Pr,"getStalePausedTasks");async function Rr(r,t){let e=await r.read(t),s=r.getPausedTasksFromState(e),n=Date.now()-r.stalenessThresholdDays*24*60*60*1e3,i=s.filter(a=>new Date(a.pausedAt).getTime()<n),o=s.filter(a=>new Date(a.pausedAt).getTime()>=n);if(i.length===0)return[];it.archiveMany(t,i.map(a=>({entityType:"paused_task",entityId:a.id,entityData:a,summary:a.description,reason:"staleness"}))),await r.update(t,a=>({...a,pausedTasks:o,previousTask:null,lastUpdated:g()}));for(let a of i)await r.publish(t,"task.archived",{taskId:a.id,description:a.description,pausedAt:a.pausedAt,reason:"staleness"});return i}c(Rr,"archiveStalePausedTasks");A();async function Ar(r,t){await r.update(t,()=>({currentTask:null,previousTask:null,pausedTasks:[],activeTasks:[],lastUpdated:g()}))}c(Ar,"clearTask");async function Cr(r,t){let e=await r.read(t),s=r.getPausedTasksFromState(e);return e.currentTask!==null||s.length>0}c(Cr,"hasTask");async function Nr(r,t){let e=await r.read(t);return r.getPausedTasksFromState(e)[0]||null}c(Nr,"getPausedTask");async function Ir(r,t){let e=await r.read(t);return r.getPausedTasksFromState(e)}c(Ir,"getAllPausedTasks");async function Oe(r,t){let e=await r.read(t);return r.getTaskHistoryFromState(e)}c(Oe,"getTaskHistory");async function Dr(r,t){let e=await r.read(t);return r.getTaskHistoryFromState(e)[0]||null}c(Dr,"getMostRecentTask");async function Lr(r,t,e){let s=await r.read(t);return r.getTaskHistoryFromState(s).filter(i=>i.classification===e)}c(Lr,"getTaskHistoryByType");async function Or(r,t){let s=(await Oe(r,t)).filter(h=>h.feedback),n=[],i=[],o=[],a=[];for(let h of s){let y=h.feedback;Array.isArray(y.stackConfirmed)&&n.push(...y.stackConfirmed),Array.isArray(y.patternsDiscovered)&&i.push(...y.patternsDiscovered),Array.isArray(y.agentAccuracy)&&o.push(...y.agentAccuracy),Array.isArray(y.issuesEncountered)&&a.push(...y.issuesEncountered)}let u=[...new Set(n)],p=[...new Set(i)],m=new Map;for(let h of a)m.set(h,(m.get(h)||0)+1);let d=[...m.entries()].filter(([h,y])=>y>=2).map(([h])=>h);return{stackConfirmed:u,patternsDiscovered:p,agentAccuracy:o,issuesEncountered:[...new Set(a)],knownGotchas:d}}c(Or,"getAggregatedFeedback");A();async function jr(r,t,e){let s=await r.read(t);if(!s.currentTask)return;let n=e.map((i,o)=>({...i,status:o===0?"in_progress":"pending",startedAt:o===0?g():void 0,dependsOn:i.dependsOn||[]}));await r.update(t,i=>({...i,currentTask:{...i.currentTask,subtasks:n,currentSubtaskIndex:0,subtaskProgress:{completed:0,total:n.length,percentage:0}},lastUpdated:g()})),await r.publish(t,"subtasks.created",{taskId:s.currentTask.id,subtaskCount:n.length,subtasks:n.map(i=>({id:i.id,description:i.description,domain:i.domain}))})}c(jr,"createSubtasks");async function Mr(r,t,e){let s=pr.safeParse(e);if(!s.success){let M=s.error.issues.map(bt=>`${bt.path.join(".")}: ${bt.message}`);throw new Error(`Subtask completion requires handoff data:
559
+ ${M.join(`
560
+ `)}`)}let{output:n,summary:i}=s.data,o=await r.read(t);if(!o.currentTask?.subtasks)return null;let a=o.currentTask.currentSubtaskIndex||0,u=o.currentTask.subtasks[a];if(!u)return null;let p=[...o.currentTask.subtasks];p[a]={...u,status:"completed",completedAt:g(),output:n,summary:i};let m=p.filter(M=>M.status==="completed").length,d=p.length,h=Math.round(m/d*100),y=a+1;return y<p.length&&(p[y]={...p[y],status:"in_progress",startedAt:g()}),await r.update(t,M=>({...M,currentTask:{...M.currentTask,subtasks:p,currentSubtaskIndex:y<d?y:a,subtaskProgress:{completed:m,total:d,percentage:h}},lastUpdated:g()})),await r.publish(t,"subtask.completed",{taskId:o.currentTask.id,subtaskId:u.id,description:u.description,output:n,handoff:i.outputForNextAgent,filesChanged:i.filesChanged.length,progress:{completed:m,total:d,percentage:h}}),y<d?p[y]:null}c(Mr,"completeSubtask");async function Fr(r,t){let e=await r.read(t);if(!e.currentTask?.subtasks)return null;let s=e.currentTask.currentSubtaskIndex||0;return e.currentTask.subtasks[s]||null}c(Fr,"getCurrentSubtask");async function Ur(r,t){let e=await r.read(t);if(!e.currentTask?.subtasks)return null;let s=(e.currentTask.currentSubtaskIndex||0)+1;return e.currentTask.subtasks[s]||null}c(Ur,"getNextSubtask");async function je(r,t){let e=await r.read(t);if(!e.currentTask?.subtasks)return null;let s=(e.currentTask.currentSubtaskIndex||0)-1;return s<0?null:e.currentTask.subtasks[s]||null}c(je,"getPreviousSubtask");async function Xr(r,t){let e=await je(r,t);return e?.summary?.outputForNextAgent?{fromSubtask:e.description,outputForNextAgent:e.summary.outputForNextAgent,filesChanged:e.summary.filesChanged,whatWasDone:e.summary.whatWasDone}:null}c(Xr,"getPreviousHandoff");async function $r(r,t){return(await r.read(t)).currentTask?.subtasks||[]}c($r,"getSubtasks");async function Wr(r,t){return(await r.read(t)).currentTask?.subtaskProgress||null}c(Wr,"getSubtaskProgress");async function Br(r,t){return((await r.read(t)).currentTask?.subtasks?.length||0)>0}c(Br,"hasSubtasks");async function Hr(r,t){let e=await r.read(t);return e.currentTask?.subtasks?e.currentTask.subtasks.every(s=>s.status==="completed"||s.status==="failed"||s.status==="skipped"):!0}c(Hr,"areAllSubtasksComplete");async function qr(r,t,e){let s=await r.read(t);if(!s.currentTask?.subtasks)return null;let n=s.currentTask.currentSubtaskIndex||0,i=s.currentTask.subtasks[n];if(!i)return null;let o=[...s.currentTask.subtasks];o[n]={...i,status:"failed",completedAt:g(),output:`Failed: ${e}`};let a=n+1,u=o.length;a<u&&(o[a]={...o[a],status:"in_progress",startedAt:g()});let p=o.filter(d=>d.status==="completed"||d.status==="failed"||d.status==="skipped").length,m=Math.round(p/u*100);return await r.update(t,d=>({...d,currentTask:{...d.currentTask,subtasks:o,currentSubtaskIndex:a<u?a:n,subtaskProgress:{completed:p,total:u,percentage:m}},lastUpdated:g()})),await r.publish(t,"subtask.failed",{taskId:s.currentTask.id,subtaskId:i.id,description:i.description,error:e}),a<u?o[a]:null}c(qr,"failSubtask");async function Gr(r,t,e){let s=await r.read(t);if(!s.currentTask?.subtasks)return null;let n=s.currentTask.currentSubtaskIndex||0,i=s.currentTask.subtasks[n];if(!i)return null;let o=[...s.currentTask.subtasks];o[n]={...i,status:"skipped",completedAt:g(),output:`Skipped: ${e}`,skipReason:e};let a=n+1,u=o.length;a<u&&(o[a]={...o[a],status:"in_progress",startedAt:g()});let p=o.filter(d=>d.status==="completed"||d.status==="failed"||d.status==="skipped").length,m=Math.round(p/u*100);return await r.update(t,d=>({...d,currentTask:{...d.currentTask,subtasks:o,currentSubtaskIndex:a<u?a:n,subtaskProgress:{completed:p,total:u,percentage:m}},lastUpdated:g()})),await r.publish(t,"subtask.skipped",{taskId:s.currentTask.id,subtaskId:i.id,description:i.description,reason:e}),a<u?o[a]:null}c(Gr,"skipSubtask");async function Yr(r,t,e){let s=await r.read(t);if(!s.currentTask?.subtasks)return null;let n=s.currentTask.currentSubtaskIndex||0,i=s.currentTask.subtasks[n];if(!i)return null;let o=[...s.currentTask.subtasks];o[n]={...i,status:"blocked",output:`Blocked: ${e}`,blockReason:e};let a=n+1,u=o.length;return a<u&&(o[a]={...o[a],status:"in_progress",startedAt:g()}),await r.update(t,p=>({...p,currentTask:{...p.currentTask,subtasks:o,currentSubtaskIndex:a<u?a:n},lastUpdated:g()})),await r.publish(t,"subtask.blocked",{taskId:s.currentTask.id,subtaskId:i.id,description:i.description,blocker:e}),a<u?o[a]:null}c(Yr,"blockSubtask");A();async function Jr(r,t,e,s){let n={...e,workspaceId:s,startedAt:g()};return await r.update(t,i=>({...i,activeTasks:[...i.activeTasks||[],n],lastUpdated:g()})),await r.publish(t,"task.started",{taskId:n.id,description:n.description,startedAt:n.startedAt,sessionId:n.sessionId,workspaceId:s}),n}c(Jr,"startTaskInWorkspace");async function zr(r,t,e){return((await r.read(t)).activeTasks||[]).find(n=>n.workspaceId===e)??null}c(zr,"getCurrentTaskForWorkspace");async function Kr(r,t,e,s){let n=await r.read(t),o=(n.activeTasks||[]).find(d=>d.workspaceId===e);if(!o)return null;let a=g(),u=r.createTaskHistoryEntry(o,a,s),p=r.getTaskHistoryFromState(n),m=[u,...p].slice(0,r.maxTaskHistory);return await r.update(t,d=>({...d,activeTasks:(d.activeTasks||[]).filter(h=>h.workspaceId!==e),taskHistory:m,lastUpdated:a})),await r.publish(t,"task.completed",{taskId:o.id,description:o.description,startedAt:o.startedAt,completedAt:a,workspaceId:e}),o}c(Kr,"completeTaskInWorkspace");async function Vr(r,t){return(await r.read(t)).activeTasks||[]}c(Vr,"getActiveTasks");async function Qr(r,t){return((await r.read(t)).activeTasks||[]).length}c(Qr,"getActiveTaskCount");async function Zr(r,t,e,s){let i=(await r.read(t)).activeTasks||[],o=i.findIndex(u=>u.workspaceId===e);if(o===-1)return null;let a={...i[o],...s,workspaceId:e};return await r.update(t,u=>{let p=[...u.activeTasks||[]];return p[o]=a,{...u,activeTasks:p,lastUpdated:g()}}),a}c(Zr,"updateWorkspaceTask");async function tn(r,t,e,s){let n=await r.read(t);if(!n.currentTask)return null;let i=(n.currentTask.tokensIn||0)+e,o=(n.currentTask.tokensOut||0)+s;return await r.update(t,a=>({...a,currentTask:{...a.currentTask,tokensIn:i,tokensOut:o},lastUpdated:g()})),{tokensIn:i,tokensOut:o}}c(tn,"addTokens");Ce();ae();A();O();import Vi from"node:crypto";function Qi(r){let[t,e]=r.split(".");return t?{entityType:t.endsWith("s")?t:`${t}s`,eventType:e==="deleted"||e==="archived"||e==="removed"?"delete":"upsert"}:{}}c(Qi,"deriveEntityShape");function Zi(r){if(!r||typeof r!="object")return;let t=r;for(let e of["taskId","task_id","id","feature_id","featureId","specId","spec_id"]){let s=t[e];if(typeof s=="string"&&s.length>0)return s}}c(Zi,"entityIdOf");function to(r){let t=r&&typeof r=="object"&&!Array.isArray(r)?JSON.stringify(eo(r)):JSON.stringify(r);return Vi.createHash("sha256").update(t).digest("hex")}c(to,"hashPayload");function eo(r){let t={};for(let e of Object.keys(r).sort())t[e]=r[e];return t}c(eo,"sortKeys");var $t=null;async function so(){if($t)return $t;try{let{default:r}=await Promise.resolve().then(()=>(De(),Ie)),t=r;return typeof t.getDeviceId=="function"?($t=await t.getDeviceId(),$t):"unknown-device"}catch{return"unknown-device"}}c(so,"_resolveDeviceId");var ot=class{static{c(this,"StorageManager")}filename;cache;constructor(t,e){this.filename=t,this.cache=new Pt({ttl:5e3,maxSize:50})}getStoreKey(){return this.filename.replace(".json","")}async read(t){let e=this.cache.get(t);if(e!==null)return e;try{let s=E.getDoc(t,this.getStoreKey());if(s!==null)return this.cache.set(t,s),s}catch{}return this.getDefault()}async write(t,e){E.setDoc(t,this.getStoreKey(),e),this.cache.set(t,e)}async update(t,e){let s=await this.read(t),n=e(s);return await this.write(t,n),n}async publishEvent(t,e,s){let n=Qi(e),i={type:e,path:[this.filename.replace(".json","")],data:s,timestamp:g(),projectId:t,entityType:n.entityType,entityId:Zi(s),eventType:n.eventType,contentHash:to(s),deviceId:await so(),revisionCount:1};await Ft.publish(i)}async publishEntityEvent(t,e,s,n){let i=`${e}.${s}`,o={...n,timestamp:g()};await this.publishEvent(t,i,o)}async exists(t){try{return E.hasDoc(t,this.getStoreKey())}catch{return!1}}clearCache(t){t?this.cache.delete(t):this.cache.clear()}getCacheStats(){return this.cache.stats()}};var Me=class extends ot{static{c(this,"StateStorage")}constructor(){super("state.json",fr)}getDefault(){return{currentTask:null,previousTask:null,pausedTasks:[],taskHistory:[],activeTasks:[],lastUpdated:""}}getEventType(t){return`state.${t}d`}validateTransition(t,e){let s=Pe.getCurrentState(t),n=Pe.canTransition(s,e);if(!n.valid)throw new Error(`${n.error}. ${n.suggestion||""}`.trim())}async getCurrentTask(t){return(await this.read(t)).currentTask}async getPausedTasks(t){let e=await this.read(t);return this.getPausedTasksFromState(e)}async startTask(t,e){let s=await this.read(t);this.validateTransition(s,"task");let n={...e,startedAt:g()};return await this.update(t,i=>({...i,currentTask:n,lastUpdated:g()})),await this.publishEvent(t,"task.started",{taskId:n.id,description:n.description,startedAt:n.startedAt,sessionId:n.sessionId}),n}async updateCurrentTask(t,e){let s=await this.read(t);if(!s.currentTask)return null;let n={...s.currentTask,...e};return await this.update(t,i=>({...i,currentTask:n,lastUpdated:g()})),n}async completeTask(t,e){let s=await this.read(t),n=s.currentTask;if(!n)return null;this.validateTransition(s,"done");let i=g(),o=this.createTaskHistoryEntry(n,i,e),a=this.getTaskHistoryFromState(s),u=[o,...a].slice(0,this.maxTaskHistory);return await this.update(t,p=>({...p,currentTask:null,previousTask:null,taskHistory:u,lastUpdated:i})),await this.publishEvent(t,"task.completed",{taskId:n.id,description:n.description,startedAt:n.startedAt,completedAt:i}),n}createTaskHistoryEntry(t,e,s){let n=(t.subtasks||[]).filter(a=>a.status==="completed"&&a.summary).map(a=>a.summary),i=n.length>0?n.map(a=>a.title).join(", "):"Task completed",o={taskId:t.id,title:t.parentDescription||t.description,classification:t.type||"improvement",startedAt:t.startedAt,completedAt:e,subtaskCount:t.subtasks?.length||0,subtaskSummaries:n,outcome:i,branchName:t.branch||"unknown",linearId:t.linearId,linearUuid:t.linearUuid,prUrl:t.prUrl};return s&&(o.feedback=s),t.tokensIn&&(o.tokensIn=t.tokensIn),t.tokensOut&&(o.tokensOut=t.tokensOut),o}maxPausedTasks=5;maxTaskHistory=20;stalenessThresholdDays=30;lifecycleBackend(){return{read:this.read.bind(this),update:this.update.bind(this),publish:this.publishEvent.bind(this),validateTransition:this.validateTransition.bind(this),getPausedTasksFromState:this.getPausedTasksFromState.bind(this),maxPausedTasks:this.maxPausedTasks,stalenessThresholdDays:this.stalenessThresholdDays}}async pauseTask(t,e){return vr(this.lifecycleBackend(),t,e)}async resumeTask(t,e){return xr(this.lifecycleBackend(),t,e)}getPausedTasksFromState(t){return Array.isArray(t.pausedTasks)&&t.pausedTasks.length>0?t.pausedTasks:t.previousTask?[t.previousTask]:[]}getTaskHistoryFromState(t){return t.taskHistory||[]}async getStalePausedTasks(t){return Pr(this.lifecycleBackend(),t)}async archiveStalePausedTasks(t){return Rr(this.lifecycleBackend(),t)}queryBackend(){return{read:this.read.bind(this),update:this.update.bind(this),getPausedTasksFromState:this.getPausedTasksFromState.bind(this),getTaskHistoryFromState:this.getTaskHistoryFromState.bind(this)}}async clearTask(t){return Ar(this.queryBackend(),t)}async hasTask(t){return Cr(this.queryBackend(),t)}async getPausedTask(t){return Nr(this.queryBackend(),t)}async getAllPausedTasks(t){return Ir(this.queryBackend(),t)}async getTaskHistory(t){return Oe(this.queryBackend(),t)}async getMostRecentTask(t){return Dr(this.queryBackend(),t)}async getTaskHistoryByType(t,e){return Lr(this.queryBackend(),t,e)}async getAggregatedFeedback(t){return Or(this.queryBackend(),t)}workspaceBackend(){return{read:this.read.bind(this),update:this.update.bind(this),publish:this.publishEvent.bind(this),createTaskHistoryEntry:this.createTaskHistoryEntry.bind(this),getTaskHistoryFromState:this.getTaskHistoryFromState.bind(this),maxTaskHistory:this.maxTaskHistory}}async startTaskInWorkspace(t,e,s){return Jr(this.workspaceBackend(),t,e,s)}async getCurrentTaskForWorkspace(t,e){return zr(this.workspaceBackend(),t,e)}async completeTaskInWorkspace(t,e,s){return Kr(this.workspaceBackend(),t,e,s)}async getActiveTasks(t){return Vr(this.workspaceBackend(),t)}async getActiveTaskCount(t){return Qr(this.workspaceBackend(),t)}async updateWorkspaceTask(t,e,s){return Zr(this.workspaceBackend(),t,e,s)}async addTokens(t,e,s){return tn(this.workspaceBackend(),t,e,s)}subtaskBackend(){return{read:this.read.bind(this),update:this.update.bind(this),publish:this.publishEvent.bind(this)}}async createSubtasks(t,e){return jr(this.subtaskBackend(),t,e)}async completeSubtask(t,e){return Mr(this.subtaskBackend(),t,e)}async getCurrentSubtask(t){return Fr(this.subtaskBackend(),t)}async getNextSubtask(t){return Ur(this.subtaskBackend(),t)}async getPreviousSubtask(t){return je(this.subtaskBackend(),t)}async getPreviousHandoff(t){return Xr(this.subtaskBackend(),t)}async getSubtasks(t){return $r(this.subtaskBackend(),t)}async getSubtaskProgress(t){return Wr(this.subtaskBackend(),t)}async hasSubtasks(t){return Br(this.subtaskBackend(),t)}async areAllSubtasksComplete(t){return Hr(this.subtaskBackend(),t)}async failSubtask(t,e){return qr(this.subtaskBackend(),t,e)}async skipSubtask(t,e){return Gr(this.subtaskBackend(),t,e)}async blockSubtask(t,e){return Yr(this.subtaskBackend(),t,e)}},at=new Me;Fe();K();import go from"node:fs/promises";import ct from"node:path";var lo={"claude-opus-4.5":{input:.005,output:.025},"claude-sonnet-4.5":{input:.003,output:.015},"claude-haiku-4.5":{input:.001,output:.005},"claude-opus-4":{input:.015,output:.075},"claude-opus-4-6":{input:.015,output:.075},"gpt-4o":{input:.0025,output:.01},"gpt-4-turbo":{input:.01,output:.03},"gpt-4o-mini":{input:15e-5,output:6e-4},"gemini-1.5-pro":{input:.00125,output:.005},"gemini-1.5-flash":{input:75e-6,output:3e-4}},po="claude-sonnet-4.5";function Ue(r){return!r||r.length===0?0:Math.ceil(r.length/4)}c(Ue,"countTokens");var cn=["claude-sonnet-4.5","claude-opus-4.5","claude-opus-4-6","gpt-4o","gemini-1.5-pro"];function an(r,t){let e=lo[t],s=r/1e3*e.input,n=r/1e3*e.output*.3;return{inputSaved:s,outputPotential:n,total:s+n}}c(an,"calculateModelCost");function mo(r){return r<.001?"<$0.01":r<.01?`$${r.toFixed(3)}`:`$${r.toFixed(2)}`}c(mo,"formatCostSaved");function un(r,t){let e=Ue(r),s=Ue(t),n=Math.max(0,e-s),i=e>0?(e-s)/e:0,o=an(n,po),a=cn.map(u=>({model:u,...an(n,u)}));return{tokens:{original:e,filtered:s,saved:n},compression:Math.max(0,Math.min(1,i)),cost:{saved:o.total,formatted:mo(o.total),byModel:a}}}c(un,"measureCompression");function Ht(r){let t=Ue(r);return{tokens:{original:t,filtered:t,saved:0},compression:0,cost:{saved:0,formatted:"$0.00",byModel:cn.map(e=>({model:e,inputSaved:0,outputPotential:0,total:0}))}}}c(Ht,"noCompression");var fo={".ts":"typescript",".tsx":"typescript",".js":"javascript",".jsx":"javascript",".mjs":"javascript",".cjs":"javascript",".py":"python",".go":"go",".rs":"rust",".java":"java",".cs":"csharp",".php":"php",".rb":"ruby"},ln=[{type:"function",pattern:/^export\s+(?:async\s+)?function\s+(\w+)\s*(<[^>]*>)?\s*\(([^)]*)\)\s*(?::\s*([^{;]+))?/gm,nameIndex:1,exported:!0},{type:"function",pattern:/^export\s+const\s+(\w+)\s*(?::\s*[^=]+)?\s*=\s*(?:async\s+)?\([^)]*\)\s*(?::\s*[^=]+)?\s*=>/gm,nameIndex:1,exported:!0},{type:"function",pattern:/^(?:async\s+)?function\s+(\w+)\s*(<[^>]*>)?\s*\(([^)]*)\)\s*(?::\s*([^{;]+))?/gm,nameIndex:1},{type:"function",pattern:/^const\s+(\w+)\s*(?::\s*[^=]+)?\s*=\s*(?:async\s+)?\([^)]*\)\s*(?::\s*[^=]+)?\s*=>/gm,nameIndex:1},{type:"interface",pattern:/^export\s+interface\s+(\w+)(?:<[^>]+>)?\s*(?:extends\s+[^{]+)?\s*\{/gm,nameIndex:1,exported:!0},{type:"interface",pattern:/^interface\s+(\w+)(?:<[^>]+>)?\s*(?:extends\s+[^{]+)?\s*\{/gm,nameIndex:1},{type:"type",pattern:/^export\s+type\s+(\w+)(?:<[^>]+>)?\s*=/gm,nameIndex:1,exported:!0},{type:"type",pattern:/^type\s+(\w+)(?:<[^>]+>)?\s*=/gm,nameIndex:1},{type:"class",pattern:/^export\s+(?:abstract\s+)?class\s+(\w+)(?:<[^>]+>)?(?:\s+extends\s+[^{]+)?(?:\s+implements\s+[^{]+)?\s*\{/gm,nameIndex:1,exported:!0},{type:"class",pattern:/^(?:abstract\s+)?class\s+(\w+)(?:<[^>]+>)?(?:\s+extends\s+[^{]+)?(?:\s+implements\s+[^{]+)?\s*\{/gm,nameIndex:1},{type:"enum",pattern:/^export\s+enum\s+(\w+)\s*\{/gm,nameIndex:1,exported:!0},{type:"enum",pattern:/^enum\s+(\w+)\s*\{/gm,nameIndex:1},{type:"const",pattern:/^export\s+const\s+(\w+)\s*(?::\s*([^=]+))?\s*=/gm,nameIndex:1,exported:!0}],ho=[{type:"function",pattern:/^def\s+(\w+)\s*\(([^)]*)\)\s*(?:->\s*([^:]+))?\s*:/gm,nameIndex:1},{type:"function",pattern:/^async\s+def\s+(\w+)\s*\(([^)]*)\)\s*(?:->\s*([^:]+))?\s*:/gm,nameIndex:1},{type:"class",pattern:/^class\s+(\w+)(?:\(([^)]*)\))?\s*:/gm,nameIndex:1}],yo=[{type:"function",pattern:/^func\s+(\w+)\s*\(([^)]*)\)\s*(?:\(([^)]*)\)|([^\s{]+))?\s*\{/gm,nameIndex:1},{type:"method",pattern:/^func\s+\([^)]+\)\s+(\w+)\s*\(([^)]*)\)\s*(?:\(([^)]*)\)|([^\s{]+))?\s*\{/gm,nameIndex:1},{type:"type",pattern:/^type\s+(\w+)\s+(?:struct|interface)\s*\{/gm,nameIndex:1}],To=[{type:"function",pattern:/^pub\s+(?:async\s+)?fn\s+(\w+)(?:<[^>]+>)?\s*\(([^)]*)\)\s*(?:->\s*([^{]+))?\s*\{/gm,nameIndex:1,exported:!0},{type:"function",pattern:/^(?:async\s+)?fn\s+(\w+)(?:<[^>]+>)?\s*\(([^)]*)\)\s*(?:->\s*([^{]+))?\s*\{/gm,nameIndex:1},{type:"class",pattern:/^pub\s+struct\s+(\w+)(?:<[^>]+>)?\s*(?:\{|;)/gm,nameIndex:1,exported:!0},{type:"class",pattern:/^struct\s+(\w+)(?:<[^>]+>)?\s*(?:\{|;)/gm,nameIndex:1},{type:"interface",pattern:/^pub\s+trait\s+(\w+)(?:<[^>]+>)?\s*(?:\{|:)/gm,nameIndex:1,exported:!0},{type:"interface",pattern:/^trait\s+(\w+)(?:<[^>]+>)?\s*(?:\{|:)/gm,nameIndex:1},{type:"enum",pattern:/^pub\s+enum\s+(\w+)(?:<[^>]+>)?\s*\{/gm,nameIndex:1,exported:!0},{type:"enum",pattern:/^enum\s+(\w+)(?:<[^>]+>)?\s*\{/gm,nameIndex:1}],pn=[{type:"class",pattern:/^(?:public\s+)?(?:abstract\s+)?(?:final\s+)?class\s+(\w+)(?:<[^>]+>)?(?:\s+extends\s+\w+)?(?:\s+implements\s+[^{]+)?\s*\{/gm,nameIndex:1,exported:!0},{type:"interface",pattern:/^(?:public\s+)?interface\s+(\w+)(?:<[^>]+>)?(?:\s+extends\s+[^{]+)?\s*\{/gm,nameIndex:1,exported:!0},{type:"method",pattern:/^\s+(?:public|private|protected)?\s*(?:static\s+)?(?:final\s+)?(?:synchronized\s+)?(?:<[^>]+>\s+)?(\w+(?:<[^>]+>)?)\s+(\w+)\s*\([^)]*\)\s*(?:throws\s+[^{]+)?\s*\{/gm,nameIndex:2}],ko={typescript:ln,javascript:ln,python:ho,go:yo,rust:To,java:pn,csharp:pn,php:[],ruby:[],unknown:[]};async function dn(r,t=process.cwd()){let e=ct.isAbsolute(r)?r:ct.join(t,r),s=ct.resolve(t),n=ct.resolve(e);if(!n.startsWith(s+ct.sep)&&n!==s)return{file:r,language:"unknown",signatures:[],fallback:!0,fallbackReason:"Path traversal denied: file is outside project directory",metrics:Ht("")};let i;try{i=await go.readFile(e,"utf-8")}catch(d){if(L(d))return{file:r,language:"unknown",signatures:[],fallback:!0,fallbackReason:"File not found",metrics:Ht("")};throw d}let o=ct.extname(r).toLowerCase(),a=fo[o]||"unknown",u=ko[a];if(!u||u.length===0)return{file:r,language:a,signatures:[],fallback:!0,fallbackReason:`No extraction patterns for ${a}`,metrics:Ht(i)};let p=Eo(i,u),m=p.map(d=>`${d.exported?"export ":""}${d.type} ${d.name}: ${d.signature}`).join(`
561
+ `);return{file:r,language:a,signatures:p,fallback:!1,metrics:un(i,m)}}c(dn,"extractSignatures");function Eo(r,t){let e=[],s=r.split(`
559
562
  `),n=new Set;for(let i of t){i.pattern.lastIndex=0;let o;for(;(o=i.pattern.exec(r))!==null;){let a=o[i.nameIndex];if(!a)continue;let u=`${i.type}:${a}`;if(n.has(u))continue;n.add(u);let p=o.index,m=r.substring(0,p).split(`
560
- `).length,d=o[0].trim(),h;if(m>1){let y=s[m-2]?.trim();(y?.startsWith("/**")||y?.startsWith("///")||y?.startsWith("#"))&&(h=y)}e.push({type:i.type,name:a,signature:lo(d),exported:i.exported||!1,line:m,docstring:h})}}return e.sort((i,o)=>i.line-o.line)}c(uo,"extractFromContent");function lo(r){return r.replace(/\{$/,"").replace(/\s+/g," ").trim()}c(lo,"cleanSignature");function cn(r){let t=r;t.tool("prjct_relevant_files","BM25-ranked files relevant to a query",{projectPath:Z.string().describe("Project directory path"),query:Z.string().describe("Task or query to find relevant files for"),maxFiles:Z.number().optional().default(10).describe("Max files to return")},E("prjct_relevant_files",async e=>{let s=await tn(e.query,e.projectPath,{maxFiles:e.maxFiles,minScore:.1});if(s.files.length===0)return{content:[{type:"text",text:"No relevant files found."}]};let n=s.files.map(o=>`- \`${o.path}\` (score: ${Math.round(o.score*100)}%) \u2014 ${o.reasons.join(", ")}`);return{content:[{type:"text",text:`## Relevant Files (${s.files.length}/${s.metrics.filesScanned} scanned)
563
+ `).length,d=o[0].trim(),h;if(m>1){let y=s[m-2]?.trim();(y?.startsWith("/**")||y?.startsWith("///")||y?.startsWith("#"))&&(h=y)}e.push({type:i.type,name:a,signature:So(d),exported:i.exported||!1,line:m,docstring:h})}}return e.sort((i,o)=>i.line-o.line)}c(Eo,"extractFromContent");function So(r){return r.replace(/\{$/,"").replace(/\s+/g," ").trim()}c(So,"cleanSignature");function mn(r){let t=r;t.tool("prjct_relevant_files","BM25-ranked files relevant to a query",{projectPath:Z.string().describe("Project directory path"),query:Z.string().describe("Task or query to find relevant files for"),maxFiles:Z.number().optional().default(10).describe("Max files to return")},S("prjct_relevant_files",async e=>{let s=await Bt(e.query,e.projectPath,{maxFiles:e.maxFiles,minScore:.1});if(s.files.length===0)return{content:[{type:"text",text:"No relevant files found."}]};let n=s.files.map(o=>`- \`${o.path}\` (score: ${Math.round(o.score*100)}%) \u2014 ${o.reasons.join(", ")}`);return{content:[{type:"text",text:`## Relevant Files (${s.files.length}/${s.metrics.filesScanned} scanned)
561
564
 
562
565
  ${n.join(`
563
- `)}`}]}})),t.tool("prjct_signatures","Code signatures from a file (90% token reduction vs full content)",{projectPath:Z.string().describe("Project directory path"),filePath:Z.string().describe("Relative file path to extract signatures from")},E("prjct_signatures",async e=>{let s=await an(e.filePath,e.projectPath);if(s.signatures.length===0)return{content:[{type:"text",text:s.fallback?`No signatures extracted: ${s.fallbackReason}`:"No signatures found."}]};let n=s.signatures.map(a=>`${a.exported?"export ":""}${a.type} ${a.name}: ${a.signature}${a.docstring?` // ${a.docstring}`:""}`),i=s.metrics?.compression?` (${Math.round(s.metrics.compression*100)}% reduction)`:"";return{content:[{type:"text",text:`## ${s.file} (${s.language})
566
+ `)}`}]}})),t.tool("prjct_signatures","Code signatures from a file (90% token reduction vs full content)",{projectPath:Z.string().describe("Project directory path"),filePath:Z.string().describe("Relative file path to extract signatures from")},S("prjct_signatures",async e=>{let s=await dn(e.filePath,e.projectPath);if(s.signatures.length===0)return{content:[{type:"text",text:s.fallback?`No signatures extracted: ${s.fallbackReason}`:"No signatures found."}]};let n=s.signatures.map(a=>`${a.exported?"export ":""}${a.type} ${a.name}: ${a.signature}${a.docstring?` // ${a.docstring}`:""}`),i=s.metrics?.compression?` (${Math.round(s.metrics.compression*100)}% reduction)`:"";return{content:[{type:"text",text:`## ${s.file} (${s.language})
564
567
  \`\`\`
565
568
  ${n.join(`
566
569
  `)}
567
- \`\`\`${i}`}]}})),t.tool("prjct_history","Recent completed tasks with outcomes",{projectPath:Z.string().describe("Project directory path"),limit:Z.number().optional().default(10).describe("Max results")},E("prjct_history",async e=>{let s=await x(e.projectPath),n=await ot.getTaskHistory(s);if(n.length===0)return{content:[{type:"text",text:"No task history."}]};let o=n.slice(-e.limit).reverse().map(u=>{let p=[`- **${u.title}**`];return u.completedAt&&p.push(`completed: ${u.completedAt}`),u.classification&&p.push(`type: ${u.classification}`),p.join(" | ")});return{content:[{type:"text",text:`## Task History (${n.length} total)
570
+ \`\`\`${i}`}]}})),t.tool("prjct_history","Recent completed tasks with outcomes",{projectPath:Z.string().describe("Project directory path"),limit:Z.number().optional().default(10).describe("Max results")},S("prjct_history",async e=>{let s=await x(e.projectPath),n=await at.getTaskHistory(s);if(n.length===0)return{content:[{type:"text",text:"No task history."}]};let o=n.slice(-e.limit).reverse().map(u=>{let p=[`- **${u.title}**`];return u.completedAt&&p.push(`completed: ${u.completedAt}`),u.classification&&p.push(`type: ${u.classification}`),p.join(" | ")});return{content:[{type:"text",text:`## Task History (${n.length} total)
568
571
 
569
572
  ${o.join(`
570
- `)}`}]}}))}c(cn,"registerFileTools");import{z as P}from"zod";ht();O();var Oe=class{static{c(this,"MemoryService")}async log(t,e,s,n){try{let i=await B.getProjectId(t);if(!i)return;T.appendEvent(i,`memory.${e}`,{...s,author:n})}catch(i){console.error(`Memory log error: ${i instanceof Error?i.message:String(i)}`)}}async getRecent(t,e=100){try{let s=await B.getProjectId(t);return s?T.query(s,"SELECT type, data, timestamp FROM events WHERE type LIKE 'memory.%' ORDER BY id DESC LIMIT ?",e).reverse().map(i=>{let o=JSON.parse(i.data),{author:a,...u}=o;return{timestamp:i.timestamp,action:i.type.replace("memory.",""),data:u,author:a}}):[]}catch(s){return console.error(`Memory read error: ${s instanceof Error?s.message:String(s)}`),[]}}async search(t,e,s=50){let n=await this.getRecent(t,1e3),i=e.toLowerCase();return n.filter(o=>{let a=o.action.toLowerCase().includes(i),u=JSON.stringify(o.data).toLowerCase().includes(i);return a||u}).slice(-s)}async getByAction(t,e,s=50){try{let n=await B.getProjectId(t);return n?T.query(n,"SELECT type, data, timestamp FROM events WHERE type = ? ORDER BY id DESC LIMIT ?",`memory.${e}`,s).reverse().map(o=>{let a=JSON.parse(o.data),{author:u,...p}=a;return{timestamp:o.timestamp,action:o.type.replace("memory.",""),data:p,author:u}}):[]}catch(n){return console.error(`Memory read error: ${n instanceof Error?n.message:String(n)}`),[]}}async clear(t){try{let e=await B.getProjectId(t);if(!e)return;T.run(e,"DELETE FROM events WHERE type LIKE 'memory.%'")}catch(e){console.error(`Memory clear error: ${e instanceof Error?e.message:String(e)}`)}}async getRecentEvents(t,e=100){try{return T.query(t,"SELECT type, data, timestamp FROM events WHERE type LIKE 'memory.%' ORDER BY id DESC LIMIT ?",e).reverse().map(n=>{let i=JSON.parse(n.data);return{timestamp:n.timestamp,action:n.type.replace("memory.",""),...i}})}catch(s){return console.error(`Memory read error: ${s instanceof Error?s.message:String(s)}`),[]}}async capEntries(t){try{let s=T.get(t,"SELECT COUNT(*) as cnt FROM events WHERE type LIKE 'memory.%'")?.cnt??0;if(s<=kt.MEMORY_MAX_ENTRIES)return 0;let n=s-kt.MEMORY_MAX_ENTRIES,i=T.query(t,"SELECT id, type, data, timestamp FROM events WHERE type LIKE 'memory.%' ORDER BY id ASC LIMIT ?",n);nt.archiveMany(t,i.map((a,u)=>({entityType:"memory_entry",entityId:`memory-${a.timestamp||u}`,entityData:{type:a.type,data:JSON.parse(a.data),timestamp:a.timestamp},summary:a.type.replace("memory.",""),reason:"overflow"})));let o=i[i.length-1]?.id;return o!==void 0&&T.run(t,"DELETE FROM events WHERE type LIKE 'memory.%' AND id <= ?",o),n}catch(e){return console.error(`Memory cap error: ${e instanceof Error?e.message:String(e)}`),0}}},un=new Oe;O();var ln="memory.",je="remember.",Me=`${ln}${je}`,Al=`${ln}task.tagged`;var pn=["fact","decision","learning","gotcha","pattern","anti-pattern","shipped","inbox","todo","idea","insight","question","source","person","spec"];var po=25,mo=4,go=100;function dn(r,t){try{return JSON.parse(r)}catch{return t}}c(dn,"safeJson");function fo(r){let t=r.type.slice(Me.length),e=dn(r.data,{});return{id:`mem_${r.id}`,type:t,content:e.content??"",tags:e.tags??{},rememberedAt:r.timestamp,source:e.source,provenance:e.provenance??"declared"}}c(fo,"rowToEntry");function ho(r){let t=r.data?dn(r.data,{}):{},e=t.tags??{};return r.type&&(e.type=r.type),{id:`ship_${r.id}`,type:"shipped",content:r.name,tags:e,rememberedAt:r.shipped_at,source:t.taskId,provenance:"extracted"}}c(ho,"shippedRowToEntry");function yo(r,t){let e=t.toLowerCase();if(r.content.toLowerCase().includes(e))return!0;for(let s of Object.values(r.tags))if(s.toLowerCase().includes(e))return!0;return!1}c(yo,"matchesTopic");function To(r,t){for(let[e,s]of Object.entries(t))if(r.tags[e]!==s)return!1;return!0}c(To,"matchesTags");function ko(r){let t=new Set,e=[];for(let s of r){let n=s.tags.key;if(!n){e.push(s);continue}let i=`${s.type}::${n}`;t.has(i)||(t.add(i),e.push(s))}return e}c(ko,"dedupeLatestByKey");var G={async remember(r,t){await un.log(r,`${je}${t.type}`,{content:t.content,tags:t.tags??{},source:t.source,provenance:t.provenance??"declared"});try{let{default:e}=await Promise.resolve().then(()=>(ht(),rr)),n=(await e.readConfig(r))?.projectId;if(!n)return;let{publishCRUD:i}=await Promise.resolve().then(()=>(Tt(),kr)),o=t.tags?.spec_id??t.tags?.task_id??t.tags?.id??t.source??`mem-${Date.now()}-${Math.random().toString(36).slice(2,8)}`;await i({projectId:n,entityType:"memories",entityId:o,eventType:"upsert",data:{id:o,type:t.type,content:t.content,tags:t.tags??{},source:t.source??null,provenance:t.provenance??"declared",rememberedAt:new Date().toISOString()}})}catch{}},recall(r,t={}){let e=t.limit??po,s=Math.max(e*mo,go),n=T.query(r,"SELECT id, type, data, timestamp FROM events WHERE type LIKE ? ORDER BY id DESC LIMIT ?",`${Me}%`,s),i=T.query(r,"SELECT id, name, type, shipped_at, data FROM shipped_features ORDER BY shipped_at DESC LIMIT ?",s),o=[...n.map(fo),...i.map(ho)];if(t.types&&t.types.length>0){let a=new Set(t.types);o=o.filter(u=>a.has(u.type))}return t.tags&&(o=o.filter(a=>To(a,t.tags??{}))),t.topic&&(o=o.filter(a=>yo(a,t.topic))),o.sort((a,u)=>u.rememberedAt.localeCompare(a.rememberedAt)),t.dedupeByKey!==!1&&(o=ko(o)),o.slice(0,e)},similar(r,t,e=10){let s=t.toLowerCase().split(/[^a-z0-9]+/).filter(o=>o.length>3);return s.length===0?[]:G.recall(r,{limit:200}).map(o=>{let a=`${o.content} ${Object.values(o.tags).join(" ")}`.toLowerCase(),u=s.reduce((p,m)=>a.includes(m)?p+1:p,0);return{entry:o,hits:u}}).filter(o=>o.hits>0).sort((o,a)=>a.hits-o.hits).slice(0,e).map(o=>o.entry)}};function Et(r){if(r.length===0)return"> No matching memory entries.";let t=new Map;for(let a of r){let u=t.get(a.type)??[];u.push(a),t.set(a.type,u)}let e=["decision","learning","anti-pattern","gotcha","pattern","fact","inbox","todo","idea","insight","question","source","person","shipped"],s=[],n={declared:"DECL",extracted:"EXTR",inferred:"INFR",ambiguous:"AMBG"},i=c((a,u)=>{if(u.length!==0){s.push(`### ${a.toUpperCase()}`);for(let p of u){let m=Object.entries(p.tags).map(([y,j])=>`${y}=${j}`).join(" "),d=m?` _(${m})_`:"",h=n[p.provenance];s.push(`- \`${h}\` [${p.id}] ${p.content}${d}`)}s.push("")}},"renderGroup"),o=new Set;for(let a of e){let u=t.get(a);!u||u.length===0||(i(a,u),o.add(a))}for(let[a,u]of t)o.has(a)||i(a,u);return s.join(`
571
- `).trim()}c(Et,"formatMemoryMd");var mn=[{name:"sk-\u2026 token",re:/\bsk-[A-Za-z0-9_-]{16,}/},{name:"GitHub PAT",re:/\bghp_[A-Za-z0-9]{30,}/},{name:"GitHub server PAT",re:/\bghs_[A-Za-z0-9]{30,}/},{name:"AWS access key",re:/\bAKIA[0-9A-Z]{16}\b/},{name:"Slack token",re:/\bxox[abps]-[A-Za-z0-9-]{10,}/},{name:"bearer JWT-ish",re:/\beyJ[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}\b/}],jl=mn.map(r=>r.name);function gn(r){let t=[];for(let{name:e,re:s}of mn)s.test(r)&&t.push(e);return t}c(gn,"scanForSecrets");var fn=`Base types: ${pn.join(", ")}. Any lowercase identifier is accepted (e.g. "recipe", "okr").`;function hn(r){let t=r;t.tool("prjct_mem_save",`Save a memory entry. ${fn} Secret-like content is refused unless force=true.`,{projectPath:P.string().describe("Project directory path"),type:P.string().describe("Memory type (fact/decision/learning/... or user-defined)"),content:P.string().describe("The memory content. Freeform text."),tags:P.record(P.string(),P.string()).optional().describe('Key:value tags (e.g. {domain: "auth"})'),source:P.string().optional().describe("Task id this memory came from, if any"),force:P.boolean().optional().describe("Bypass the secret-like-content refusal. Default false.")},E("prjct_mem_save",async e=>{await x(e.projectPath);let s=e.type.toLowerCase().trim();if(!s||!/^[a-z][a-z0-9-]*$/.test(s))return{content:[{type:"text",text:`Invalid type '${e.type}'. Lowercase letters + dashes only. ${fn}`}]};let n=gn(e.content);return n.length>0&&!e.force?{content:[{type:"text",text:`Refused \u2014 content looks like a secret (${n.join(", ")}). Re-call with force=true if intentional.`}]}:(await G.remember(e.projectPath,{type:s,content:e.content,tags:e.tags??{},source:e.source}),{content:[{type:"text",text:`Saved ${s}: ${e.content.slice(0,80)}`}]})})),t.tool("prjct_mem_list","Recall memory entries. Optional filters: topic (keyword across content + tag values), types, tags, limit.",{projectPath:P.string().describe("Project directory path"),topic:P.string().optional().describe("Keyword to match over content + tag values"),types:P.array(P.string()).optional().describe("Restrict to these types"),tags:P.record(P.string(),P.string()).optional().describe("Require exact match on these k:v pairs"),limit:P.number().optional().default(25).describe("Max entries (default 25)")},E("prjct_mem_list",async e=>{let s=await x(e.projectPath),n=G.recall(s,{topic:e.topic,types:e.types,tags:e.tags,limit:e.limit});return{content:[{type:"text",text:Et(n)}]}})),t.tool("prjct_mem_similar","Find memory entries similar to a free-text description. Keyword-based, best-effort.",{projectPath:P.string().describe("Project directory path"),description:P.string().describe("Free-text description to find similar memories for"),limit:P.number().optional().default(10).describe("Max results (default 10)")},E("prjct_mem_similar",async e=>{let s=await x(e.projectPath),n=G.similar(s,e.description,e.limit);return n.length===0?{content:[{type:"text",text:"No similar memories found."}]}:{content:[{type:"text",text:Et(n)}]}})),t.tool("prjct_mem_forget","Remove a memory entry by id. Ids are stable \u2014 pull them from `prjct_mem_list`.",{projectPath:P.string().describe("Project directory path"),id:P.string().describe('Memory id (e.g. "mem_42" or "ship_7")')},E("prjct_mem_forget",async e=>({content:[{type:"text",text:"Forget is not implemented in the projectMemory API yet. Entries persist event-sourced \u2014 filter them out client-side, or drop the underlying event manually."}]})))}c(hn,"registerMemoryTools");import{z as Xe}from"zod";A();O();var Fe=class{static{c(this,"LLMAnalysisStorage")}save(t,e){let s=k.getDb(t),n=g();s.transaction(()=>{s.prepare("UPDATE llm_analysis SET status = 'superseded', superseded_at = ? WHERE status = 'active'").run(n),s.prepare("INSERT INTO llm_analysis (commit_hash, status, analysis, analyzed_at) VALUES (?, ?, ?, ?)").run(e.commitHash??null,"active",JSON.stringify(e),e.analyzedAt)})()}getActive(t){let e=k.get(t,"SELECT analysis FROM llm_analysis WHERE status = 'active' LIMIT 1");return e?JSON.parse(e.analysis):null}getActiveSummary(t){let e=this.getActive(t);return e?{commitHash:e.commitHash,architectureStyle:e.architecture.style,patternCount:e.patterns.length,antiPatternCount:e.antiPatterns.length,analyzedAt:e.analyzedAt}:null}isCurrent(t,e){return e?k.get(t,"SELECT commit_hash FROM llm_analysis WHERE status = 'active' LIMIT 1")?.commit_hash===e:!1}getAllFull(t){return k.query(t,"SELECT id, commit_hash, status, analyzed_at, superseded_at, analysis FROM llm_analysis ORDER BY id DESC").map(s=>({id:s.id,status:s.status,commitHash:s.commit_hash,analyzedAt:s.analyzed_at,supersededAt:s.superseded_at,analysis:JSON.parse(s.analysis)}))}getHistory(t,e=10){return k.query(t,"SELECT id, commit_hash, status, analyzed_at, analysis FROM llm_analysis ORDER BY id DESC LIMIT ?",e).map(n=>{let i=JSON.parse(n.analysis);return{id:n.id,commitHash:n.commit_hash,status:n.status,analyzedAt:n.analyzed_at,patternCount:i.patterns.length}})}},Eo=new Fe,yn=Eo;var Tn={critical:0,high:1,medium:2,low:3},kn={active:0,previously_active:1,backlog:2};function En(r){return[...r].sort((t,e)=>{let s=kn[t.section]-kn[e.section];return s!==0?s:Tn[t.priority]-Tn[e.priority]})}c(En,"sortBySectionAndPriority");A();var Ue=class extends it{static{c(this,"QueueStorage")}constructor(){super("queue.json",pr)}getDefault(){return{tasks:[],lastUpdated:""}}getEventType(t){return`queue.${t}d`}async getTasks(t){return(await this.read(t)).tasks}async getActiveTasks(t){return(await this.read(t)).tasks.filter(s=>s.section==="active"&&!s.completed)}async getBacklog(t){return(await this.read(t)).tasks.filter(s=>s.section==="backlog"&&!s.completed)}async getNextTask(t){let e=await this.getActiveTasks(t);return En(e)[0]||null}async addTask(t,e){let s={...e,id:H(),createdAt:g(),completed:!1};return await this.update(t,n=>({tasks:[...n.tasks,s],lastUpdated:g()})),await this.publishEvent(t,"queue.task_added",{taskId:s.id,description:s.description,priority:s.priority,section:s.section}),s}async addTasks(t,e){let s=g(),n=e.map(i=>({...i,id:H(),createdAt:s,completed:!1}));return await this.update(t,i=>({tasks:[...i.tasks,...n],lastUpdated:s})),await this.publishEvent(t,"queue.tasks_added",{count:n.length,tasks:n.map(i=>({id:i.id,description:i.description}))}),n}async removeTask(t,e){await this.update(t,s=>({tasks:s.tasks.filter(n=>n.id!==e),lastUpdated:g()})),await this.publishEvent(t,"queue.task_removed",{taskId:e})}async completeTask(t,e){let s=null;if(await this.update(t,n=>({tasks:n.tasks.map(o=>o.id===e?(s={...o,completed:!0,completedAt:g()},s):o),lastUpdated:g()})),s){let n=s;await this.publishEvent(t,"queue.task_completed",{taskId:e,description:n.description,completedAt:n.completedAt})}return s}async moveToSection(t,e,s){await this.update(t,n=>({tasks:n.tasks.map(i=>i.id===e?{...i,section:s}:i),lastUpdated:g()}))}async setPriority(t,e,s){await this.update(t,n=>({tasks:n.tasks.map(i=>i.id===e?{...i,priority:s}:i),lastUpdated:g()}))}async getTask(t,e){return(await this.read(t)).tasks.find(n=>n.id===e)||null}async updateTask(t,e,s){let n=null;return await this.update(t,i=>({tasks:i.tasks.map(o=>o.id===e?(n={...o,...s},n):o),lastUpdated:g()})),n&&await this.publishEvent(t,"queue.task_updated",{taskId:e}),n}async clearCompleted(t){let s=(await this.read(t)).tasks.filter(n=>n.completed).length;return await this.update(t,n=>({tasks:n.tasks.filter(i=>!i.completed),lastUpdated:g()})),s}async removeStaleCompleted(t){let e=await this.read(t),s=ts(kt.QUEUE_COMPLETED_DAYS),n=e.tasks.filter(o=>o.completed&&o.completedAt&&new Date(o.completedAt)<s);if(n.length===0)return 0;nt.archiveMany(t,n.map(o=>({entityType:"queue_task",entityId:o.id,entityData:o,summary:o.description,reason:"age"})));let i=new Set(n.map(o=>o.id));return await this.update(t,o=>({tasks:o.tasks.filter(a=>!i.has(a.id)),lastUpdated:g()})),await this.publishEvent(t,"queue.stale_removed",{count:n.length}),n.length}},Sn=new Ue;function wn(r){let t=r;t.tool("prjct_task_status","Current task, duration, subtasks, and queue",{projectPath:Xe.string().describe("Project directory path")},E("prjct_task_status",async e=>{let s=await x(e.projectPath),n=await ot.getCurrentTask(s),i=await Sn.getActiveTasks(s),o=[];if(n?(o.push(`## Active Task
573
+ `)}`}]}}))}c(mn,"registerFileTools");wt();import{z as P}from"zod";var En=[{name:"sk-\u2026 token",re:/\bsk-[A-Za-z0-9_-]{16,}/},{name:"GitHub PAT",re:/\bghp_[A-Za-z0-9]{30,}/},{name:"GitHub server PAT",re:/\bghs_[A-Za-z0-9]{30,}/},{name:"AWS access key",re:/\bAKIA[0-9A-Z]{16}\b/},{name:"Slack token",re:/\bxox[abps]-[A-Za-z0-9-]{10,}/},{name:"bearer JWT-ish",re:/\beyJ[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}\b/}],sp=En.map(r=>r.name);function Sn(r){let t=[];for(let{name:e,re:s}of En)s.test(r)&&t.push(e);return t}c(Sn,"scanForSecrets");var wn=`Base types: ${Tn.join(", ")}. Any lowercase identifier is accepted (e.g. "recipe", "okr").`;function bn(r){let t=r;t.tool("prjct_mem_save",`Save a memory entry. ${wn} Secret-like content is refused unless force=true.`,{projectPath:P.string().describe("Project directory path"),type:P.string().describe("Memory type (fact/decision/learning/... or user-defined)"),content:P.string().describe("The memory content. Freeform text."),tags:P.record(P.string(),P.string()).optional().describe('Key:value tags (e.g. {domain: "auth"})'),source:P.string().optional().describe("Task id this memory came from, if any"),force:P.boolean().optional().describe("Bypass the secret-like-content refusal. Default false.")},S("prjct_mem_save",async e=>{await x(e.projectPath);let s=e.type.toLowerCase().trim();if(!s||!/^[a-z][a-z0-9-]*$/.test(s))return{content:[{type:"text",text:`Invalid type '${e.type}'. Lowercase letters + dashes only. ${wn}`}]};let n=Sn(e.content);return n.length>0&&!e.force?{content:[{type:"text",text:`Refused \u2014 content looks like a secret (${n.join(", ")}). Re-call with force=true if intentional.`}]}:(await j.remember(e.projectPath,{type:s,content:e.content,tags:e.tags??{},source:e.source}),{content:[{type:"text",text:`Saved ${s}: ${e.content.slice(0,80)}`}]})})),t.tool("prjct_mem_list","Recall memory entries. Optional filters: topic (keyword across content + tag values), types, tags, limit.",{projectPath:P.string().describe("Project directory path"),topic:P.string().optional().describe("Keyword to match over content + tag values"),types:P.array(P.string()).optional().describe("Restrict to these types"),tags:P.record(P.string(),P.string()).optional().describe("Require exact match on these k:v pairs"),limit:P.number().optional().default(25).describe("Max entries (default 25)")},S("prjct_mem_list",async e=>{let s=await x(e.projectPath),n=j.recall(s,{topic:e.topic,types:e.types,tags:e.tags,limit:e.limit});return{content:[{type:"text",text:St(n)}]}})),t.tool("prjct_mem_similar","Find memory entries similar to a free-text description. Keyword-based, best-effort.",{projectPath:P.string().describe("Project directory path"),description:P.string().describe("Free-text description to find similar memories for"),limit:P.number().optional().default(10).describe("Max results (default 10)")},S("prjct_mem_similar",async e=>{let s=await x(e.projectPath),n=j.similar(s,e.description,e.limit);return n.length===0?{content:[{type:"text",text:"No similar memories found."}]}:{content:[{type:"text",text:St(n)}]}})),t.tool("prjct_mem_forget","Remove a memory entry by id. Ids are stable \u2014 pull them from `prjct_mem_list`.",{projectPath:P.string().describe("Project directory path"),id:P.string().describe('Memory id (e.g. "mem_42" or "ship_7")')},S("prjct_mem_forget",async e=>({content:[{type:"text",text:"Forget is not implemented in the projectMemory API yet. Entries persist event-sourced \u2014 filter them out client-side, or drop the underlying event manually."}]})))}c(bn,"registerMemoryTools");wt();import{z as qe}from"zod";A();O();var Be=class{static{c(this,"LLMAnalysisStorage")}save(t,e){let s=E.getDb(t),n=g();s.transaction(()=>{s.prepare("UPDATE llm_analysis SET status = 'superseded', superseded_at = ? WHERE status = 'active'").run(n),s.prepare("INSERT INTO llm_analysis (commit_hash, status, analysis, analyzed_at) VALUES (?, ?, ?, ?)").run(e.commitHash??null,"active",JSON.stringify(e),e.analyzedAt)})()}getActive(t){let e=E.get(t,"SELECT analysis FROM llm_analysis WHERE status = 'active' LIMIT 1");return e?JSON.parse(e.analysis):null}getActiveSummary(t){let e=this.getActive(t);return e?{commitHash:e.commitHash,architectureStyle:e.architecture.style,patternCount:e.patterns.length,antiPatternCount:e.antiPatterns.length,analyzedAt:e.analyzedAt}:null}isCurrent(t,e){return e?E.get(t,"SELECT commit_hash FROM llm_analysis WHERE status = 'active' LIMIT 1")?.commit_hash===e:!1}getAllFull(t){return E.query(t,"SELECT id, commit_hash, status, analyzed_at, superseded_at, analysis FROM llm_analysis ORDER BY id DESC").map(s=>({id:s.id,status:s.status,commitHash:s.commit_hash,analyzedAt:s.analyzed_at,supersededAt:s.superseded_at,analysis:JSON.parse(s.analysis)}))}getHistory(t,e=10){return E.query(t,"SELECT id, commit_hash, status, analyzed_at, analysis FROM llm_analysis ORDER BY id DESC LIMIT ?",e).map(n=>{let i=JSON.parse(n.analysis);return{id:n.id,commitHash:n.commit_hash,status:n.status,analyzedAt:n.analyzed_at,patternCount:i.patterns.length}})}},Co=new Be,_n=Co;Tt();var vn={critical:0,high:1,medium:2,low:3},xn={active:0,previously_active:1,backlog:2};function Pn(r){return[...r].sort((t,e)=>{let s=xn[t.section]-xn[e.section];return s!==0?s:vn[t.priority]-vn[e.priority]})}c(Pn,"sortBySectionAndPriority");A();Xt();var He=class extends ot{static{c(this,"QueueStorage")}constructor(){super("queue.json",hr)}getDefault(){return{tasks:[],lastUpdated:""}}getEventType(t){return`queue.${t}d`}async getTasks(t){return(await this.read(t)).tasks}async getActiveTasks(t){return(await this.read(t)).tasks.filter(s=>s.section==="active"&&!s.completed)}async getBacklog(t){return(await this.read(t)).tasks.filter(s=>s.section==="backlog"&&!s.completed)}async getNextTask(t){let e=await this.getActiveTasks(t);return Pn(e)[0]||null}async addTask(t,e){let s={...e,id:q(),createdAt:g(),completed:!1};return await this.update(t,n=>({tasks:[...n.tasks,s],lastUpdated:g()})),await this.publishEvent(t,"queue.task_added",{taskId:s.id,description:s.description,priority:s.priority,section:s.section}),s}async addTasks(t,e){let s=g(),n=e.map(i=>({...i,id:q(),createdAt:s,completed:!1}));return await this.update(t,i=>({tasks:[...i.tasks,...n],lastUpdated:s})),await this.publishEvent(t,"queue.tasks_added",{count:n.length,tasks:n.map(i=>({id:i.id,description:i.description}))}),n}async removeTask(t,e){await this.update(t,s=>({tasks:s.tasks.filter(n=>n.id!==e),lastUpdated:g()})),await this.publishEvent(t,"queue.task_removed",{taskId:e})}async completeTask(t,e){let s=null;if(await this.update(t,n=>({tasks:n.tasks.map(o=>o.id===e?(s={...o,completed:!0,completedAt:g()},s):o),lastUpdated:g()})),s){let n=s;await this.publishEvent(t,"queue.task_completed",{taskId:e,description:n.description,completedAt:n.completedAt})}return s}async moveToSection(t,e,s){await this.update(t,n=>({tasks:n.tasks.map(i=>i.id===e?{...i,section:s}:i),lastUpdated:g()}))}async setPriority(t,e,s){await this.update(t,n=>({tasks:n.tasks.map(i=>i.id===e?{...i,priority:s}:i),lastUpdated:g()}))}async getTask(t,e){return(await this.read(t)).tasks.find(n=>n.id===e)||null}async updateTask(t,e,s){let n=null;return await this.update(t,i=>({tasks:i.tasks.map(o=>o.id===e?(n={...o,...s},n):o),lastUpdated:g()})),n&&await this.publishEvent(t,"queue.task_updated",{taskId:e}),n}async clearCompleted(t){let s=(await this.read(t)).tasks.filter(n=>n.completed).length;return await this.update(t,n=>({tasks:n.tasks.filter(i=>!i.completed),lastUpdated:g()})),s}async removeStaleCompleted(t){let e=await this.read(t),s=is(Et.QUEUE_COMPLETED_DAYS),n=e.tasks.filter(o=>o.completed&&o.completedAt&&new Date(o.completedAt)<s);if(n.length===0)return 0;it.archiveMany(t,n.map(o=>({entityType:"queue_task",entityId:o.id,entityData:o,summary:o.description,reason:"age"})));let i=new Set(n.map(o=>o.id));return await this.update(t,o=>({tasks:o.tasks.filter(a=>!i.has(a.id)),lastUpdated:g()})),await this.publishEvent(t,"queue.stale_removed",{count:n.length}),n.length}},Rn=new He;function An(r){let t=r;t.tool("prjct_task_status","Current task, duration, subtasks, and queue",{projectPath:qe.string().describe("Project directory path")},S("prjct_task_status",async e=>{let s=await x(e.projectPath),n=await at.getCurrentTask(s),i=await Rn.getActiveTasks(s),o=[];if(n?(o.push(`## Active Task
572
574
  **${n.description}**`),n.branch&&o.push(`Branch: ${n.branch}`),o.push(`Started: ${n.startedAt}`)):o.push("No active task."),i.length>0){o.push(`
573
575
  ## Queue (${i.length} tasks)`);for(let a of i.slice(0,10))o.push(`- ${a.description} [${a.priority||"medium"}]`)}return{content:[{type:"text",text:o.join(`
574
- `)}]}})),t.tool("prjct_analysis","LLM analysis: stack, patterns, anti-patterns, conventions",{projectPath:Xe.string().describe("Project directory path")},E("prjct_analysis",async e=>{let s=await x(e.projectPath),n=yn.getActive(s);if(!n)return{content:[{type:"text",text:"No analysis available. Run `prjct sync`."}]};let i=["## Project Analysis"];if(n.stack&&(i.push(`
576
+ `)}]}})),t.tool("prjct_analysis","LLM analysis: stack, patterns, anti-patterns, conventions",{projectPath:qe.string().describe("Project directory path")},S("prjct_analysis",async e=>{let s=await x(e.projectPath),n=_n.getActive(s);if(!n)return{content:[{type:"text",text:"No analysis available. Run `prjct sync`."}]};let i=["## Project Analysis"];if(n.stack&&(i.push(`
575
577
  ### Stack`),n.stack.languages?.length&&i.push(`Languages: ${n.stack.languages.join(", ")}`),n.stack.frameworks?.length&&i.push(`Frameworks: ${n.stack.frameworks.join(", ")}`),n.stack.packageManager&&i.push(`Package Manager: ${n.stack.packageManager}`)),n.patterns?.length){i.push(`
576
578
  ### Patterns (${n.patterns.length})`);for(let o of n.patterns)i.push(`- **${o.name}**: ${o.description}`)}if(n.antiPatterns?.length){i.push(`
577
579
  ### Anti-Patterns (${n.antiPatterns.length})`);for(let o of n.antiPatterns)i.push(`- **${o.issue}**: ${o.suggestion}`)}if(n.conventions?.length){i.push(`
578
580
  ### Conventions (${n.conventions.length})`);for(let o of n.conventions)i.push(`- [${o.category}] ${o.rule}`)}return{content:[{type:"text",text:i.join(`
579
- `)}]}})),t.tool("prjct_patterns","Project memory grouped by type (decision / pattern / anti-pattern / gotcha). Powered by projectMemory \u2014 same source the CLI memory verbs read.",{projectPath:Xe.string().describe("Project directory path")},E("prjct_patterns",async e=>{let s=await x(e.projectPath),n=G.recall(s,{types:["decision","pattern","anti-pattern","gotcha"],limit:50});return n.length===0?{content:[{type:"text",text:"No decisions or patterns captured yet."}]}:{content:[{type:"text",text:Et(n)}]}}))}c(wn,"registerProjectTools");import{z as f}from"zod";ht();import{z as _}from"zod";var ct=["draft","reviewed","in_progress","shipped","archived"],We=["strategic","architecture","design"],$e=_.object({verdict:_.enum(["pass","fail"]),notes:_.string(),ts:_.string()}),So=_.object({risk:_.string().min(1),mitigation:_.string().min(1)}),z=_.object({goal:_.string().min(1),eli10:_.string().default(""),stakes:_.string().default(""),acceptance_criteria:_.array(_.string().min(1)).default([]),scope:_.array(_.string()).default([]),out_of_scope:_.array(_.string()).default([]),risks:_.array(So).default([]),test_plan:_.array(_.string()).default([]),reviews:_.object({strategic:$e.optional(),architecture:$e.optional(),design:$e.optional()}).optional(),linked_tasks:_.array(_.string()).default([]),notes:_.string().default("")});A();O();var Be=class{static{c(this,"SpecStorage")}create(t,e){let s=H(),n=g(),i=z.parse(e.content);return T.run(t,`INSERT INTO specs (id, title, status, content, tags, created_at, updated_at)
580
- VALUES (?, ?, 'draft', ?, ?, ?, ?)`,s,e.title,JSON.stringify(i),e.tags?JSON.stringify(e.tags):null,n,n),{id:s,title:e.title,status:"draft",content:i,tags:e.tags??{},createdAt:n,updatedAt:n,shippedAt:null,shippedPr:null,archivedAt:null}}get(t,e){let s=T.get(t,"SELECT * FROM specs WHERE id = ?",e);return s?this.rowToSpec(s):null}list(t,e={}){let s="SELECT * FROM specs WHERE 1=1",n=[];return e.status&&(s+=" AND status = ?",n.push(e.status)),!e.includeArchived&&!e.status&&(s+=" AND status != 'archived'"),s+=" ORDER BY created_at DESC",T.query(t,s,...n).map(o=>this.rowToSpec(o))}search(t,e){let s=`%${e}%`;return T.query(t,"SELECT * FROM specs WHERE title LIKE ? OR content LIKE ? ORDER BY created_at DESC",s,s).map(i=>this.rowToSpec(i))}updateContent(t,e,s){let n=z.parse(s),i=g();return T.run(t,"UPDATE specs SET content = ?, updated_at = ? WHERE id = ?",JSON.stringify(n),i,e),this.get(t,e)}setStatus(t,e,s){if(!ct.includes(s))throw new Error(`invalid spec status: ${s}`);let n=g(),i=[],o=[s,n];s==="shipped"&&(i.push("shipped_at = ?"),o.push(n)),s==="archived"&&(i.push("archived_at = ?"),o.push(n));let a=["status = ?","updated_at = ?",...i].join(", ");return o.push(e),T.run(t,`UPDATE specs SET ${a} WHERE id = ?`,...o),this.get(t,e)}setShippedPr(t,e,s){return T.run(t,"UPDATE specs SET shipped_pr = ?, updated_at = ? WHERE id = ?",s,g(),e),this.get(t,e)}linkTask(t,e,s){let n=this.get(t,e);if(!n)return null;if(n.content.linked_tasks.includes(s))return n;let i={...n.content,linked_tasks:[...n.content.linked_tasks,s]};return this.updateContent(t,e,i)}delete(t,e){return this.get(t,e)?(T.run(t,"DELETE FROM specs WHERE id = ?",e),!0):!1}count(t){let e=T.query(t,"SELECT status, COUNT(*) AS n FROM specs GROUP BY status"),s={total:0,draft:0,shipped:0};for(let n of e)s.total+=n.n,n.status==="draft"&&(s.draft=n.n),n.status==="shipped"&&(s.shipped=n.n);return s}rowToSpec(t){return{id:t.id,title:t.title,status:ct.includes(t.status)?t.status:"draft",content:z.parse(JSON.parse(t.content)),tags:t.tags?JSON.parse(t.tags):{},createdAt:t.created_at,updatedAt:t.updated_at,shippedAt:t.shipped_at,shippedPr:t.shipped_pr,archivedAt:t.archived_at}}},L=new Be;A();var He=class{static{c(this,"SpecService")}async create(t,e){let s=await this.requireProjectId(t),n=z.parse({goal:e.content.goal,eli10:e.content.eli10??"",stakes:e.content.stakes??"",acceptance_criteria:e.content.acceptance_criteria??[],scope:e.content.scope??[],out_of_scope:e.content.out_of_scope??[],risks:e.content.risks??[],test_plan:e.content.test_plan??[],reviews:e.content.reviews,linked_tasks:e.content.linked_tasks??[],notes:e.content.notes??""}),i=L.create(s,{title:e.title,content:n,tags:e.tags});return await G.remember(t,{type:"spec",content:`${i.title}
581
+ `)}]}})),t.tool("prjct_patterns","Project memory grouped by type (decision / pattern / anti-pattern / gotcha). Powered by projectMemory \u2014 same source the CLI memory verbs read.",{projectPath:qe.string().describe("Project directory path")},S("prjct_patterns",async e=>{let s=await x(e.projectPath),n=j.recall(s,{types:["decision","pattern","anti-pattern","gotcha"],limit:50});return n.length===0?{content:[{type:"text",text:"No decisions or patterns captured yet."}]}:{content:[{type:"text",text:St(n)}]}}))}c(An,"registerProjectTools");import{z as f}from"zod";ht();wt();import{execFile as Fo}from"node:child_process";import{promisify as Uo}from"node:util";Tt();import{z as _}from"zod";var ut=["draft","reviewed","in_progress","shipped","archived"],Ye=["strategic","architecture","design"],Ge=_.object({verdict:_.enum(["pass","fail"]),notes:_.string(),ts:_.string()}),No=_.object({risk:_.string().min(1),mitigation:_.string().min(1)}),z=_.object({goal:_.string().min(1),eli10:_.string().default(""),stakes:_.string().default(""),acceptance_criteria:_.array(_.string().min(1)).default([]),scope:_.array(_.string()).default([]),out_of_scope:_.array(_.string()).default([]),risks:_.array(No).default([]),test_plan:_.array(_.string()).default([]),reviews:_.object({strategic:Ge.optional(),architecture:Ge.optional(),design:Ge.optional()}).optional(),linked_tasks:_.array(_.string()).default([]),notes:_.string().default("")});A();O();var Je=class{static{c(this,"SpecStorage")}create(t,e){let s=q(),n=g(),i=z.parse(e.content);return T.run(t,`INSERT INTO specs (id, title, status, content, tags, created_at, updated_at)
582
+ VALUES (?, ?, 'draft', ?, ?, ?, ?)`,s,e.title,JSON.stringify(i),e.tags?JSON.stringify(e.tags):null,n,n),{id:s,title:e.title,status:"draft",content:i,tags:e.tags??{},createdAt:n,updatedAt:n,shippedAt:null,shippedPr:null,shippedSha:null,archivedAt:null}}get(t,e){let s=T.get(t,"SELECT * FROM specs WHERE id = ?",e);return s?this.rowToSpec(s):null}list(t,e={}){let s="SELECT * FROM specs WHERE 1=1",n=[];return e.status&&(s+=" AND status = ?",n.push(e.status)),!e.includeArchived&&!e.status&&(s+=" AND status != 'archived'"),s+=" ORDER BY created_at DESC",T.query(t,s,...n).map(o=>this.rowToSpec(o))}search(t,e){let s=`%${e}%`;return T.query(t,"SELECT * FROM specs WHERE title LIKE ? OR content LIKE ? ORDER BY created_at DESC",s,s).map(i=>this.rowToSpec(i))}updateContent(t,e,s){let n=z.parse(s),i=g();return T.run(t,"UPDATE specs SET content = ?, updated_at = ? WHERE id = ?",JSON.stringify(n),i,e),this.get(t,e)}setStatus(t,e,s){if(!ut.includes(s))throw new Error(`invalid spec status: ${s}`);let n=g(),i=[],o=[s,n];s==="shipped"&&(i.push("shipped_at = ?"),o.push(n)),s==="archived"&&(i.push("archived_at = ?"),o.push(n));let a=["status = ?","updated_at = ?",...i].join(", ");return o.push(e),T.run(t,`UPDATE specs SET ${a} WHERE id = ?`,...o),this.get(t,e)}setShippedPr(t,e,s){return T.run(t,"UPDATE specs SET shipped_pr = ?, updated_at = ? WHERE id = ?",s,g(),e),this.get(t,e)}setShippedSha(t,e,s){return T.run(t,"UPDATE specs SET shipped_sha = ?, updated_at = ? WHERE id = ?",s,g(),e),this.get(t,e)}linkTask(t,e,s){let n=this.get(t,e);if(!n)return null;if(n.content.linked_tasks.includes(s))return n;let i={...n.content,linked_tasks:[...n.content.linked_tasks,s]};return this.updateContent(t,e,i)}delete(t,e){return this.get(t,e)?(T.run(t,"DELETE FROM specs WHERE id = ?",e),!0):!1}count(t){let e=T.query(t,"SELECT status, COUNT(*) AS n FROM specs GROUP BY status"),s={total:0,draft:0,shipped:0};for(let n of e)s.total+=n.n,n.status==="draft"&&(s.draft=n.n),n.status==="shipped"&&(s.shipped=n.n);return s}rowToSpec(t){return{id:t.id,title:t.title,status:ut.includes(t.status)?t.status:"draft",content:z.parse(JSON.parse(t.content)),tags:t.tags?JSON.parse(t.tags):{},createdAt:t.created_at,updatedAt:t.updated_at,shippedAt:t.shipped_at,shippedPr:t.shipped_pr,shippedSha:t.shipped_sha,archivedAt:t.archived_at}}},D=new Je;A();var Xo=Uo(Fo);async function $o(r){try{let{stdout:t}=await Xo("git",["rev-parse","HEAD"],{cwd:r}),e=t.trim();return/^[0-9a-f]{7,40}$/.test(e)?e:null}catch{return null}}c($o,"readGitHead");var ze=class{static{c(this,"SpecService")}async create(t,e){let s=await this.requireProjectId(t),n=e.content.notes??"";if(e.autoContext!==!1&&!n.trim()){let{inferSpecContext:u,warnNoContextMatch:p}=await Promise.resolve().then(()=>(In(),Nn)),m=await u(e.title,s,t);m.empty?p(e.title):n=m.notesBlock}let o=z.parse({goal:e.content.goal,eli10:e.content.eli10??"",stakes:e.content.stakes??"",acceptance_criteria:e.content.acceptance_criteria??[],scope:e.content.scope??[],out_of_scope:e.content.out_of_scope??[],risks:e.content.risks??[],test_plan:e.content.test_plan??[],reviews:e.content.reviews,linked_tasks:e.content.linked_tasks??[],notes:n}),a=D.create(s,{title:e.title,content:o,tags:e.tags});return await j.remember(t,{type:"spec",content:`${a.title}
581
583
 
582
- Goal: ${i.content.goal}`,tags:{...e.tags??{},spec_id:i.id,status:i.status},source:i.id,provenance:"declared"}),i}async get(t,e){let s=await this.requireProjectId(t);return L.get(s,e)}async list(t,e={}){let s=await this.requireProjectId(t);return L.list(s,e)}async setStatus(t,e,s){let n=await this.requireProjectId(t),i=L.setStatus(n,e,s);return i&&await G.remember(t,{type:"spec",content:`Spec status \u2192 ${s}: ${i.title}`,tags:{spec_id:e,status:s,event:"status_change"},source:e}),i}async update(t,e,s){let n=await this.requireProjectId(t);return L.updateContent(n,e,s)}async recordReview(t,e,s,n){let i=await this.requireProjectId(t),o=L.get(i,e);if(!o)return null;let a={...n,ts:g()},u={...o.content,reviews:{...o.content.reviews??{},[s]:a}},p=L.updateContent(i,e,u);return p&&this.allReviewsPass(p.content)&&p.status==="draft"?L.setStatus(i,e,"reviewed"):p}async linkTask(t,e,s){let n=await this.requireProjectId(t);return L.linkTask(n,e,s)}async ship(t,e,s){let n=await this.requireProjectId(t);return s!==void 0&&L.setShippedPr(n,e,s),L.setStatus(n,e,"shipped")}unmetCriteria(t,e=new Set){return t.content.acceptance_criteria.filter(s=>!e.has(s))}allReviewsPass(t){let e=t.reviews;return e?e.strategic?.verdict==="pass"&&e.architecture?.verdict==="pass"&&e.design?.verdict==="pass":!1}async requireProjectId(t){let e=await B.readConfig(t);if(!e?.projectId)throw new Error("not a prjct project (run `prjct init` first)");return e.projectId}},Y=new He;function bn(r){let t=r;t.tool("prjct_spec_create",'CALL THIS when the user describes a feature, fix, or initiative WITH goals or stakes attached (e.g. "we need rate limiting on auth", "fix onboarding", "let\'s build SDD"). Drafts a spec \u2014 Goal/ELI10/Stakes/Acceptance criteria/Scope/Out-of-scope/Risks/Test plan. The structured fields default to empty; populate them by calling `prjct_spec_update` once you have the answers. Skip this tool only for routine work (single-file fix, doc tweak, GTD capture) \u2014 for that, use `prjct_capture` or the matching memory tool.',{projectPath:f.string().describe("Project directory path"),title:f.string().describe("One-line title (what you'd say to a coworker walking by)"),goal:f.string().describe("What success looks like, 1-3 sentences. Concrete, observable."),eli10:f.string().optional().describe("Plain English a 16-year-old follows, 2-4 sentences"),stakes:f.string().optional().describe("What breaks if we ship the wrong thing"),acceptance_criteria:f.array(f.string()).optional().describe("Testable, observable list. Each item ends in a verifiable claim."),scope:f.array(f.string()).optional().describe("What's IN \u2014 file paths, modules, surfaces"),out_of_scope:f.array(f.string()).optional().describe("What's OUT \u2014 anti-creep shield"),risks:f.array(f.object({risk:f.string(),mitigation:f.string()})).optional().describe("Each risk has a mitigation; a risk without one is just a complaint"),test_plan:f.array(f.string()).optional().describe("How you prove acceptance criteria"),tags:f.record(f.string(),f.string()).optional().describe('Key:value tags (e.g. {domain: "auth", priority: "high"})')},E("prjct_spec_create",async e=>{let s=await Y.create(e.projectPath,{title:e.title,content:{goal:e.goal,eli10:e.eli10,stakes:e.stakes,acceptance_criteria:e.acceptance_criteria,scope:e.scope,out_of_scope:e.out_of_scope,risks:e.risks,test_plan:e.test_plan},tags:e.tags});return{content:[{type:"text",text:[`\u2713 spec drafted: ${s.title}`,"",`id: ${s.id}`,`status: ${s.status}`,`goal: ${s.content.goal}`,"","Next: `prjct_spec_audit` to dispatch the three review subagents (strategic / architecture / design) in parallel."].join(`
583
- `)}]}})),t.tool("prjct_spec_list","List specs in this project. Use to check what specs exist before drafting a new one (avoid duplicates) or to find the right spec to link a task to.",{projectPath:f.string().describe("Project directory path"),status:f.enum(ct).optional().describe("Filter by status: draft|reviewed|in_progress|shipped|archived"),includeArchived:f.boolean().optional().describe("Include archived specs (default: false)")},E("prjct_spec_list",async e=>{let s=await x(e.projectPath),n=L.list(s,{status:e.status,includeArchived:e.includeArchived});if(n.length===0)return{content:[{type:"text",text:"_No specs match. Start one with `prjct_spec_create`._"}]};let i=["# Specs",""];for(let o of n){let a=o.content.acceptance_criteria.length,u=o.content.linked_tasks.length;i.push(`## ${o.title}
584
+ Goal: ${a.content.goal}`,tags:{...e.tags??{},spec_id:a.id,status:a.status},source:a.id,provenance:"declared"}),a}async get(t,e){let s=await this.requireProjectId(t);return D.get(s,e)}async list(t,e={}){let s=await this.requireProjectId(t);return D.list(s,e)}async setStatus(t,e,s){let n=await this.requireProjectId(t),i=D.setStatus(n,e,s);return i&&await j.remember(t,{type:"spec",content:`Spec status \u2192 ${s}: ${i.title}`,tags:{spec_id:e,status:s,event:"status_change"},source:e}),i}async update(t,e,s){let n=await this.requireProjectId(t);return D.updateContent(n,e,s)}async recordReview(t,e,s,n){let i=await this.requireProjectId(t),o=D.get(i,e);if(!o)return null;let a={...n,ts:g()},u={...o.content,reviews:{...o.content.reviews??{},[s]:a}},p=D.updateContent(i,e,u);return p&&this.allReviewsPass(p.content)&&p.status==="draft"?D.setStatus(i,e,"reviewed"):p}async linkTask(t,e,s){let n=await this.requireProjectId(t);return D.linkTask(n,e,s)}async ship(t,e,s){let n=await this.requireProjectId(t);s!==void 0&&D.setShippedPr(n,e,s);let i=await $o(t);return i&&D.setShippedSha(n,e,i),D.setStatus(n,e,"shipped")}unmetCriteria(t,e=new Set){return t.content.acceptance_criteria.filter(s=>!e.has(s))}allReviewsPass(t){let e=t.reviews;return e?e.strategic?.verdict==="pass"&&e.architecture?.verdict==="pass"&&e.design?.verdict==="pass":!1}async requireProjectId(t){let e=await H.readConfig(t);if(!e?.projectId)throw new Error("not a prjct project (run `prjct init` first)");return e.projectId}},Y=new ze;function Dn(r){let t=r;t.tool("prjct_spec_create",'CALL THIS when the user describes a feature, fix, or initiative WITH goals or stakes attached (e.g. "we need rate limiting on auth", "fix onboarding", "let\'s build SDD"). Drafts a spec \u2014 Goal/ELI10/Stakes/Acceptance criteria/Scope/Out-of-scope/Risks/Test plan. The structured fields default to empty; populate them by calling `prjct_spec_update` once you have the answers. Skip this tool only for routine work (single-file fix, doc tweak, GTD capture) \u2014 for that, use `prjct_capture` or the matching memory tool.',{projectPath:f.string().describe("Project directory path"),title:f.string().describe("One-line title (what you'd say to a coworker walking by)"),goal:f.string().describe("What success looks like, 1-3 sentences. Concrete, observable."),eli10:f.string().optional().describe("Plain English a 16-year-old follows, 2-4 sentences"),stakes:f.string().optional().describe("What breaks if we ship the wrong thing"),acceptance_criteria:f.array(f.string()).optional().describe("Testable, observable list. Each item ends in a verifiable claim."),scope:f.array(f.string()).optional().describe("What's IN \u2014 file paths, modules, surfaces"),out_of_scope:f.array(f.string()).optional().describe("What's OUT \u2014 anti-creep shield"),risks:f.array(f.object({risk:f.string(),mitigation:f.string()})).optional().describe("Each risk has a mitigation; a risk without one is just a complaint"),test_plan:f.array(f.string()).optional().describe("How you prove acceptance criteria"),tags:f.record(f.string(),f.string()).optional().describe('Key:value tags (e.g. {domain: "auth", priority: "high"})')},S("prjct_spec_create",async e=>{let s=await Y.create(e.projectPath,{title:e.title,content:{goal:e.goal,eli10:e.eli10,stakes:e.stakes,acceptance_criteria:e.acceptance_criteria,scope:e.scope,out_of_scope:e.out_of_scope,risks:e.risks,test_plan:e.test_plan},tags:e.tags});return{content:[{type:"text",text:[`\u2713 spec drafted: ${s.title}`,"",`id: ${s.id}`,`status: ${s.status}`,`goal: ${s.content.goal}`,"","Next: `prjct_spec_audit` to dispatch the three review subagents (strategic / architecture / design) in parallel."].join(`
585
+ `)}]}})),t.tool("prjct_spec_list","List specs in this project. Use to check what specs exist before drafting a new one (avoid duplicates) or to find the right spec to link a task to.",{projectPath:f.string().describe("Project directory path"),status:f.enum(ut).optional().describe("Filter by status: draft|reviewed|in_progress|shipped|archived"),includeArchived:f.boolean().optional().describe("Include archived specs (default: false)")},S("prjct_spec_list",async e=>{let s=await x(e.projectPath),n=D.list(s,{status:e.status,includeArchived:e.includeArchived});if(n.length===0)return{content:[{type:"text",text:"_No specs match. Start one with `prjct_spec_create`._"}]};let i=["# Specs",""];for(let o of n){let a=o.content.acceptance_criteria.length,u=o.content.linked_tasks.length;i.push(`## ${o.title}
584
586
  - id: \`${o.id}\`
585
587
  - status: ${o.status}
586
588
  - acceptance criteria: ${a}
587
589
  - linked tasks: ${u}
588
590
  - created: ${o.createdAt}`),i.push("")}return{content:[{type:"text",text:i.join(`
589
- `)}]}})),t.tool("prjct_spec_get","Fetch one spec by id, including all structured fields (goal, acceptance criteria, scope, risks, reviews, linked tasks).",{projectPath:f.string().describe("Project directory path"),id:f.string().describe("Spec id")},E("prjct_spec_get",async e=>{let s=await Y.get(e.projectPath,e.id);return s?{content:[{type:"text",text:wo(s)}]}:{content:[{type:"text",text:`_Spec not found: ${e.id}_`}]}})),t.tool("prjct_spec_update","Replace a spec's structured content. Pass the FULL content object (this is a replace, not a merge) \u2014 when filling in acceptance_criteria for the first time, fetch with `prjct_spec_get` first and merge in your changes.",{projectPath:f.string().describe("Project directory path"),id:f.string().describe("Spec id"),content:f.object({goal:f.string(),eli10:f.string().optional(),stakes:f.string().optional(),acceptance_criteria:f.array(f.string()).optional(),scope:f.array(f.string()).optional(),out_of_scope:f.array(f.string()).optional(),risks:f.array(f.object({risk:f.string(),mitigation:f.string()})).optional(),test_plan:f.array(f.string()).optional(),notes:f.string().optional(),linked_tasks:f.array(f.string()).optional()}).describe("Full SpecContent shape \u2014 Zod-validated server-side")},E("prjct_spec_update",async e=>{let s=z.parse(e.content),n=await Y.update(e.projectPath,e.id,s);return n?{content:[{type:"text",text:`\u2713 spec updated: ${n.title}`}]}:{content:[{type:"text",text:`_Spec not found: ${e.id}_`}]}})),t.tool("prjct_spec_set_status","Promote / demote a spec lifecycle state. Reviewers passing is auto-promoting (draft \u2192 reviewed); use this tool to mark a spec `in_progress` when work starts, `archived` when superseded, or `shipped` (use `prjct_spec_ship` instead when shipping for the first time, since it also records the PR).",{projectPath:f.string().describe("Project directory path"),id:f.string().describe("Spec id"),status:f.enum(ct).describe("Target status")},E("prjct_spec_set_status",async e=>await Y.setStatus(e.projectPath,e.id,e.status)?{content:[{type:"text",text:`\u2713 spec ${e.id} \u2192 ${e.status}`}]}:{content:[{type:"text",text:`_Spec not found: ${e.id}_`}]})),t.tool("prjct_spec_audit","CALL THIS before any implementation work begins on a spec. Returns a dispatch prompt for THREE review subagents (strategic / architecture / design). RUN ALL THREE IN PARALLEL via your Agent / Task tool \u2014 one tool-use block per reviewer in the SAME message. Each returns a verdict (pass | fail) + notes. Persist each via `prjct_spec_record_review`. All three pass \u2192 the spec auto-promotes draft \u2192 reviewed and is safe to start a task against.",{projectPath:f.string().describe("Project directory path"),id:f.string().describe("Spec id to audit")},E("prjct_spec_audit",async e=>{let s=await Y.get(e.projectPath,e.id);return s?{content:[{type:"text",text:bo(s.id,s.title,s.content)}]}:{content:[{type:"text",text:`_Spec not found: ${e.id}_`}]}})),t.tool("prjct_spec_record_review","Persist one reviewer's verdict from `prjct_spec_audit` dispatch. Call once per reviewer (strategic, architecture, design). When all three are recorded with verdict=pass, the spec auto-promotes draft \u2192 reviewed.",{projectPath:f.string().describe("Project directory path"),id:f.string().describe("Spec id"),reviewer:f.enum(We).describe("Which reviewer"),verdict:f.enum(["pass","fail"]).describe("Verdict"),notes:f.string().describe("2-4 sentence notes from the subagent")},E("prjct_spec_record_review",async e=>{let s=await Y.recordReview(e.projectPath,e.id,e.reviewer,{verdict:e.verdict,notes:e.notes});if(!s)return{content:[{type:"text",text:`_Spec not found: ${e.id}_`}]};let n=s.status==="reviewed"?" (all reviewers passed \u2192 status: reviewed)":"";return{content:[{type:"text",text:`\u2713 ${e.reviewer} \u2192 ${e.verdict}${n}`}]}})),t.tool("prjct_spec_link_task","Link a task to its spec. Call this AFTER starting the task (when the user begins implementation) so `prjct_ship` later knows which spec to gate against. Idempotent \u2014 re-linking the same task is a no-op.",{projectPath:f.string().describe("Project directory path"),specId:f.string().describe("Spec id"),taskId:f.string().describe("Task id (from `prjct_session_start_task` or stateStorage)")},E("prjct_spec_link_task",async e=>await Y.linkTask(e.projectPath,e.specId,e.taskId)?{content:[{type:"text",text:`\u2713 linked task ${e.taskId} to spec ${e.specId}`}]}:{content:[{type:"text",text:`_Spec not found: ${e.specId}_`}]})),t.tool("prjct_spec_ship","Mark a spec as shipped (after the linked PR merges). Records the PR number on the spec for provenance.",{projectPath:f.string().describe("Project directory path"),id:f.string().describe("Spec id"),pr:f.number().optional().describe("PR / MR number that delivered the spec")},E("prjct_spec_ship",async e=>{let s=await Y.ship(e.projectPath,e.id,e.pr);return s?{content:[{type:"text",text:`\u2713 spec shipped: ${s.title}${e.pr?` (PR #${e.pr})`:""}`}]}:{content:[{type:"text",text:`_Spec not found: ${e.id}_`}]}}))}c(bn,"registerSpecTools");function wo(r){let t=r.content,e=[`# ${r.title}`,"",`**id:** \`${r.id}\` \xB7 **status:** ${r.status} \xB7 **created:** ${r.createdAt}`,"","## Goal",t.goal];if(t.eli10&&e.push("","## ELI10",t.eli10),t.stakes&&e.push("","## Stakes",t.stakes),t.acceptance_criteria.length>0){e.push("","## Acceptance criteria");for(let s of t.acceptance_criteria)e.push(`- [ ] ${s}`)}if(t.scope.length>0){e.push("","## Scope");for(let s of t.scope)e.push(`- ${s}`)}if(t.out_of_scope.length>0){e.push("","## Out of scope");for(let s of t.out_of_scope)e.push(`- ${s}`)}if(t.risks.length>0){e.push("","## Risks");for(let s of t.risks)e.push(`- **${s.risk}** \u2014 ${s.mitigation}`)}if(t.test_plan.length>0){e.push("","## Test plan");for(let s of t.test_plan)e.push(`- ${s}`)}if(t.reviews){e.push("","## Reviews");for(let s of We){let n=t.reviews[s];n&&e.push(`- **${s}:** ${n.verdict} \u2014 ${n.notes} _(${n.ts})_`)}}return t.linked_tasks.length>0&&e.push("","## Linked tasks",...t.linked_tasks.map(s=>`- ${s}`)),t.notes&&e.push("","## Notes",t.notes),e.join(`
590
- `)}c(wo,"renderSpecMarkdown");function bo(r,t,e){let s=JSON.stringify(e);return[`# audit-spec dispatch \u2014 ${t}`,"",`Spec id: \`${r}\``,"","Run three review subagents IN PARALLEL via your Agent / Task tool \u2014 one tool-use block per reviewer, all in the SAME message so they run concurrently. Each subagent reads the spec body and applies its rubric, then returns a structured verdict (pass | fail + 2-4 sentence notes).","","## Reviewer A \u2014 strategic (scope sanity)",'Subagent prompt: "Review this spec for strategic soundness. Does it solve a real problem? Is the goal worth the cost? Is out_of_scope coherent with goal? Is the spec OVER- or UNDER-scoped? Return verdict (pass|fail) and 2-4 sentence notes."',"","## Reviewer B \u2014 architecture (eng feasibility)",'Subagent prompt: "Review this spec for engineering feasibility. Can this be built? Is the data flow / state machine implicit in the acceptance criteria coherent? What failure modes / dependencies / edge cases are missing? Include a short ASCII diagram of the proposed architecture in notes if applicable. Return verdict (pass|fail) and 2-4 sentence notes."',"","## Reviewer C \u2014 design (UX/DX)",'Subagent prompt: "Review this spec for design quality. Rate 0-10 across {clarity, ergonomics, consistency, accessibility} for the user-facing or developer-facing surface this spec defines. Note the lowest-scoring dimension and why. Return verdict (pass if all dimensions \u22656, fail otherwise) and notes including the four scores."',"","## Spec body (verbatim, pass to each reviewer)","```json",s,"```","","## After dispatch","For each reviewer that returns:",` Call \`prjct_spec_record_review\` with id="${r}", reviewer=<strategic|architecture|design>, verdict=<pass|fail>, notes="<their notes>"`,"","When all three are recorded with verdict=pass, the spec auto-promotes from `draft` \u2192 `reviewed`."].join(`
591
- `)}c(bo,"renderAuditDispatch");import{z as Wt}from"zod";Tt();O();var qe=class{static{c(this,"CustomWorkflowStorage")}createWorkflow(t,e){let s=new Date().toISOString();T.run(t,`INSERT INTO custom_workflows (name, description, created_at, updated_at, is_builtin, enabled, metadata)
592
- VALUES (?, ?, ?, ?, 0, 1, ?)`,e.name,e.description??null,s,s,e.metadata?JSON.stringify(e.metadata):null);let n=T.get(t,"SELECT id FROM custom_workflows WHERE name = ?",e.name);if(!n)throw new Error(`Failed to create workflow: ${e.name}`);return q({projectId:t,entityType:"custom_workflows",entityId:String(n.id),eventType:"upsert",data:{id:n.id,name:e.name,description:e.description??null,metadata:e.metadata??null,created_at:s,updated_at:s,is_builtin:0,enabled:1}}),n.id}getWorkflow(t,e){let s=T.get(t,"SELECT * FROM custom_workflows WHERE name = ?",e);return s?this.rowToWorkflow(s):null}getAllWorkflows(t,e=!1){let s=e?"SELECT * FROM custom_workflows ORDER BY is_builtin DESC, name ASC":"SELECT * FROM custom_workflows WHERE enabled = 1 ORDER BY is_builtin DESC, name ASC";return T.query(t,s).map(i=>this.rowToWorkflow(i))}updateWorkflow(t,e,s){if(!this.getWorkflow(t,e))return!1;let i=new Date().toISOString(),o=[],a=[];if(s.description!==void 0&&(o.push("description = ?"),a.push(s.description)),s.enabled!==void 0&&(o.push("enabled = ?"),a.push(s.enabled?1:0)),s.metadata!==void 0&&(o.push("metadata = ?"),a.push(JSON.stringify(s.metadata))),o.length===0)return!1;o.push("updated_at = ?"),a.push(i),a.push(e),T.run(t,`UPDATE custom_workflows SET ${o.join(", ")} WHERE name = ?`,...a);let u=this.getWorkflow(t,e);return u&&q({projectId:t,entityType:"custom_workflows",entityId:String(u.id),eventType:"upsert",data:{id:u.id,name:u.name,description:u.description??null,enabled:u.enabled?1:0,metadata:u.metadata??null,updated_at:i}}),!0}deleteWorkflow(t,e){let s=this.getWorkflow(t,e);if(!s)return!1;if(s.isBuiltin)throw new Error(`Cannot delete built-in workflow: ${e}`);return T.run(t,"UPDATE custom_workflows SET enabled = 0 WHERE name = ?",e),q({projectId:t,entityType:"custom_workflows",entityId:String(s.id),eventType:"delete",data:{id:s.id,name:e}}),!0}isBuiltin(t,e){return this.getWorkflow(t,e)?.isBuiltin??!1}isReservedName(t){let e=["task","done","ship","sync"],s=["add","rm","gate","list","create","delete","run","help","reset","init"];return e.includes(t)||s.includes(t)}isValidName(t){return/^[a-z0-9-]+$/.test(t)}rowToWorkflow(t){return{id:t.id,name:t.name,description:t.description,createdAt:t.created_at,updatedAt:t.updated_at,isBuiltin:t.is_builtin===1,enabled:t.enabled===1,metadata:t.metadata?JSON.parse(t.metadata):null}}},$t=new qe;Tt();O();function Ge(r){let t=r.trust_source==="imported"?"imported":"local";return{id:r.id,type:r.type,command:r.command,position:r.position,action:r.action,description:r.description,enabled:r.enabled===1,timeoutMs:r.timeout_ms,createdAt:r.created_at,sortOrder:r.sort_order,whenExpr:r.when_expr??null,parallel:r.parallel===null?!0:r.parallel===1,trustSource:t}}c(Ge,"rowToRule");var Ye=class{static{c(this,"WorkflowRuleStorage")}addRule(t,e){let s=k.get(t,"SELECT MAX(sort_order) as m FROM workflow_rules WHERE command = ?",e.command),n=e.sortOrder||(s?.m??-1)+1;k.run(t,`INSERT INTO workflow_rules (type, command, position, action, description, enabled, timeout_ms, created_at, sort_order, when_expr, parallel, trust_source)
593
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,e.type,e.command,e.position,e.action,e.description??null,e.enabled?1:0,e.timeoutMs,e.createdAt,n,e.whenExpr??null,e.parallel===!1?0:1,e.trustSource??"local");let o=k.get(t,"SELECT last_insert_rowid() as id")?.id??0;return o>0&&q({projectId:t,entityType:"workflow_rules",entityId:String(o),eventType:"upsert",data:{id:o,type:e.type,command:e.command,position:e.position,action:e.action,description:e.description??null,enabled:e.enabled?1:0,timeout_ms:e.timeoutMs,sort_order:n,when_expr:e.whenExpr??null,parallel:e.parallel===!1?0:1,trust_source:e.trustSource??"local",created_at:e.createdAt}}),o}removeRule(t,e){return k.get(t,"SELECT id FROM workflow_rules WHERE id = ?",e)?(k.run(t,"DELETE FROM workflow_rules WHERE id = ?",e),q({projectId:t,entityType:"workflow_rules",entityId:String(e),eventType:"delete",data:{id:e}}),!0):!1}updateRule(t,e,s){if(!k.get(t,"SELECT id FROM workflow_rules WHERE id = ?",e))return!1;let i={type:{column:"type"},command:{column:"command"},position:{column:"position"},action:{column:"action"},description:{column:"description"},enabled:{column:"enabled",transform:c(u=>u?1:0,"transform")},timeoutMs:{column:"timeout_ms"},createdAt:{column:"created_at"},sortOrder:{column:"sort_order"},whenExpr:{column:"when_expr"},parallel:{column:"parallel",transform:c(u=>u===!1?0:1,"transform")},trustSource:{column:"trust_source"}},o=[],a=[];for(let[u,p]of Object.entries(s)){let m=i[u];if(!m)continue;o.push(`${m.column} = ?`);let d=p;a.push(m.transform?m.transform(d):d)}return o.length===0||(a.push(e),k.run(t,`UPDATE workflow_rules SET ${o.join(", ")} WHERE id = ?`,...a)),!0}getRuleById(t,e){let s=k.get(t,"SELECT * FROM workflow_rules WHERE id = ?",e);return s?Ge(s):null}getRulesForCommand(t,e){let s=$t.getWorkflow(t,e);return!s||!s.enabled?[]:k.query(t,"SELECT * FROM workflow_rules WHERE command = ? AND enabled = 1 ORDER BY sort_order ASC",e).map(Ge)}getAllRules(t){return k.query(t,"SELECT * FROM workflow_rules ORDER BY command ASC, sort_order ASC").map(Ge)}resetRules(t){let e=k.get(t,"SELECT COUNT(*) as c FROM workflow_rules");return k.run(t,"DELETE FROM workflow_rules"),e?.c??0}},Je=new Ye;function _n(r){let t=r;t.tool("prjct_workflow_rules","Get workflow rules for a command (gates, hooks, steps, instructions)",{projectPath:Wt.string().describe("Project directory path"),command:Wt.string().describe("Command name (task, done, ship, sync, etc.)")},E("prjct_workflow_rules",async e=>{let s=await x(e.projectPath),n=Je.getRulesForCommand(s,e.command);if(n.length===0)return{content:[{type:"text",text:`No workflow rules for \`${e.command}\`.`}]};let i={};for(let a of n){let u=`${a.type}:${a.position}`;i[u]||(i[u]=[]),i[u].push(a)}let o=[`## Workflow Rules for \`${e.command}\``];for(let[a,u]of Object.entries(i)){o.push(`
591
+ `)}]}})),t.tool("prjct_spec_get","Fetch one spec by id, including all structured fields (goal, acceptance criteria, scope, risks, reviews, linked tasks).",{projectPath:f.string().describe("Project directory path"),id:f.string().describe("Spec id")},S("prjct_spec_get",async e=>{let s=await Y.get(e.projectPath,e.id);return s?{content:[{type:"text",text:Wo(s)}]}:{content:[{type:"text",text:`_Spec not found: ${e.id}_`}]}})),t.tool("prjct_spec_update","Replace a spec's structured content. Pass the FULL content object (this is a replace, not a merge) \u2014 when filling in acceptance_criteria for the first time, fetch with `prjct_spec_get` first and merge in your changes.",{projectPath:f.string().describe("Project directory path"),id:f.string().describe("Spec id"),content:f.object({goal:f.string(),eli10:f.string().optional(),stakes:f.string().optional(),acceptance_criteria:f.array(f.string()).optional(),scope:f.array(f.string()).optional(),out_of_scope:f.array(f.string()).optional(),risks:f.array(f.object({risk:f.string(),mitigation:f.string()})).optional(),test_plan:f.array(f.string()).optional(),notes:f.string().optional(),linked_tasks:f.array(f.string()).optional()}).describe("Full SpecContent shape \u2014 Zod-validated server-side")},S("prjct_spec_update",async e=>{let s=z.parse(e.content),n=await Y.update(e.projectPath,e.id,s);return n?{content:[{type:"text",text:`\u2713 spec updated: ${n.title}`}]}:{content:[{type:"text",text:`_Spec not found: ${e.id}_`}]}})),t.tool("prjct_spec_set_status","Promote / demote a spec lifecycle state. Reviewers passing is auto-promoting (draft \u2192 reviewed); use this tool to mark a spec `in_progress` when work starts, `archived` when superseded, or `shipped` (use `prjct_spec_ship` instead when shipping for the first time, since it also records the PR).",{projectPath:f.string().describe("Project directory path"),id:f.string().describe("Spec id"),status:f.enum(ut).describe("Target status")},S("prjct_spec_set_status",async e=>await Y.setStatus(e.projectPath,e.id,e.status)?{content:[{type:"text",text:`\u2713 spec ${e.id} \u2192 ${e.status}`}]}:{content:[{type:"text",text:`_Spec not found: ${e.id}_`}]})),t.tool("prjct_spec_audit","CALL THIS before any implementation work begins on a spec. Returns a dispatch prompt for THREE review subagents (strategic / architecture / design). RUN ALL THREE IN PARALLEL via your Agent / Task tool \u2014 one tool-use block per reviewer in the SAME message. Each returns a verdict (pass | fail) + notes. Persist each via `prjct_spec_record_review`. All three pass \u2192 the spec auto-promotes draft \u2192 reviewed and is safe to start a task against.",{projectPath:f.string().describe("Project directory path"),id:f.string().describe("Spec id to audit")},S("prjct_spec_audit",async e=>{let s=await Y.get(e.projectPath,e.id);return s?{content:[{type:"text",text:Bo(s.id,s.title,s.content)}]}:{content:[{type:"text",text:`_Spec not found: ${e.id}_`}]}})),t.tool("prjct_spec_record_review","Persist one reviewer's verdict from `prjct_spec_audit` dispatch. Call once per reviewer (strategic, architecture, design). When all three are recorded with verdict=pass, the spec auto-promotes draft \u2192 reviewed.",{projectPath:f.string().describe("Project directory path"),id:f.string().describe("Spec id"),reviewer:f.enum(Ye).describe("Which reviewer"),verdict:f.enum(["pass","fail"]).describe("Verdict"),notes:f.string().describe("2-4 sentence notes from the subagent")},S("prjct_spec_record_review",async e=>{let s=await Y.recordReview(e.projectPath,e.id,e.reviewer,{verdict:e.verdict,notes:e.notes});if(!s)return{content:[{type:"text",text:`_Spec not found: ${e.id}_`}]};let n=s.status==="reviewed"?" (all reviewers passed \u2192 status: reviewed)":"";return{content:[{type:"text",text:`\u2713 ${e.reviewer} \u2192 ${e.verdict}${n}`}]}})),t.tool("prjct_spec_link_task","Link a task to its spec. Call this AFTER starting the task (when the user begins implementation) so `prjct_ship` later knows which spec to gate against. Idempotent \u2014 re-linking the same task is a no-op.",{projectPath:f.string().describe("Project directory path"),specId:f.string().describe("Spec id"),taskId:f.string().describe("Task id (from `prjct_session_start_task` or stateStorage)")},S("prjct_spec_link_task",async e=>await Y.linkTask(e.projectPath,e.specId,e.taskId)?{content:[{type:"text",text:`\u2713 linked task ${e.taskId} to spec ${e.specId}`}]}:{content:[{type:"text",text:`_Spec not found: ${e.specId}_`}]})),t.tool("prjct_spec_ship","Mark a spec as shipped (after the linked PR merges). Records the PR number on the spec for provenance.",{projectPath:f.string().describe("Project directory path"),id:f.string().describe("Spec id"),pr:f.number().optional().describe("PR / MR number that delivered the spec")},S("prjct_spec_ship",async e=>{let s=await Y.ship(e.projectPath,e.id,e.pr);return s?{content:[{type:"text",text:`\u2713 spec shipped: ${s.title}${e.pr?` (PR #${e.pr})`:""}`}]}:{content:[{type:"text",text:`_Spec not found: ${e.id}_`}]}}))}c(Dn,"registerSpecTools");function Wo(r){let t=r.content,e=[`# ${r.title}`,"",`**id:** \`${r.id}\` \xB7 **status:** ${r.status} \xB7 **created:** ${r.createdAt}`,"","## Goal",t.goal];if(t.eli10&&e.push("","## ELI10",t.eli10),t.stakes&&e.push("","## Stakes",t.stakes),t.acceptance_criteria.length>0){e.push("","## Acceptance criteria");for(let s of t.acceptance_criteria)e.push(`- [ ] ${s}`)}if(t.scope.length>0){e.push("","## Scope");for(let s of t.scope)e.push(`- ${s}`)}if(t.out_of_scope.length>0){e.push("","## Out of scope");for(let s of t.out_of_scope)e.push(`- ${s}`)}if(t.risks.length>0){e.push("","## Risks");for(let s of t.risks)e.push(`- **${s.risk}** \u2014 ${s.mitigation}`)}if(t.test_plan.length>0){e.push("","## Test plan");for(let s of t.test_plan)e.push(`- ${s}`)}if(t.reviews){e.push("","## Reviews");for(let s of Ye){let n=t.reviews[s];n&&e.push(`- **${s}:** ${n.verdict} \u2014 ${n.notes} _(${n.ts})_`)}}return t.linked_tasks.length>0&&e.push("","## Linked tasks",...t.linked_tasks.map(s=>`- ${s}`)),t.notes&&e.push("","## Notes",t.notes),e.join(`
592
+ `)}c(Wo,"renderSpecMarkdown");function Bo(r,t,e){let s=JSON.stringify(e);return[`# audit-spec dispatch \u2014 ${t}`,"",`Spec id: \`${r}\``,"","Run three review subagents IN PARALLEL via your Agent / Task tool \u2014 one tool-use block per reviewer, all in the SAME message so they run concurrently. Each subagent reads the spec body and applies its rubric, then returns a structured verdict (pass | fail + 2-4 sentence notes).","","## Reviewer A \u2014 strategic (scope sanity)",'Subagent prompt: "Review this spec for strategic soundness. Does it solve a real problem? Is the goal worth the cost? Is out_of_scope coherent with goal? Is the spec OVER- or UNDER-scoped? Return verdict (pass|fail) and 2-4 sentence notes."',"","## Reviewer B \u2014 architecture (eng feasibility)",'Subagent prompt: "Review this spec for engineering feasibility. Can this be built? Is the data flow / state machine implicit in the acceptance criteria coherent? What failure modes / dependencies / edge cases are missing? Include a short ASCII diagram of the proposed architecture in notes if applicable. Return verdict (pass|fail) and 2-4 sentence notes."',"","## Reviewer C \u2014 design (UX/DX)",'Subagent prompt: "Review this spec for design quality. Rate 0-10 across {clarity, ergonomics, consistency, accessibility} for the user-facing or developer-facing surface this spec defines. Note the lowest-scoring dimension and why. Return verdict (pass if all dimensions \u22656, fail otherwise) and notes including the four scores."',"","## Spec body (verbatim, pass to each reviewer)","```json",s,"```","","## After dispatch","For each reviewer that returns:",` Call \`prjct_spec_record_review\` with id="${r}", reviewer=<strategic|architecture|design>, verdict=<pass|fail>, notes="<their notes>"`,"","When all three are recorded with verdict=pass, the spec auto-promotes from `draft` \u2192 `reviewed`."].join(`
593
+ `)}c(Bo,"renderAuditDispatch");import{z as Gt}from"zod";kt();O();var Ke=class{static{c(this,"CustomWorkflowStorage")}createWorkflow(t,e){let s=new Date().toISOString();T.run(t,`INSERT INTO custom_workflows (name, description, created_at, updated_at, is_builtin, enabled, metadata)
594
+ VALUES (?, ?, ?, ?, 0, 1, ?)`,e.name,e.description??null,s,s,e.metadata?JSON.stringify(e.metadata):null);let n=T.get(t,"SELECT id FROM custom_workflows WHERE name = ?",e.name);if(!n)throw new Error(`Failed to create workflow: ${e.name}`);return G({projectId:t,entityType:"custom_workflows",entityId:String(n.id),eventType:"upsert",data:{id:n.id,name:e.name,description:e.description??null,metadata:e.metadata??null,created_at:s,updated_at:s,is_builtin:0,enabled:1}}),n.id}getWorkflow(t,e){let s=T.get(t,"SELECT * FROM custom_workflows WHERE name = ?",e);return s?this.rowToWorkflow(s):null}getAllWorkflows(t,e=!1){let s=e?"SELECT * FROM custom_workflows ORDER BY is_builtin DESC, name ASC":"SELECT * FROM custom_workflows WHERE enabled = 1 ORDER BY is_builtin DESC, name ASC";return T.query(t,s).map(i=>this.rowToWorkflow(i))}updateWorkflow(t,e,s){if(!this.getWorkflow(t,e))return!1;let i=new Date().toISOString(),o=[],a=[];if(s.description!==void 0&&(o.push("description = ?"),a.push(s.description)),s.enabled!==void 0&&(o.push("enabled = ?"),a.push(s.enabled?1:0)),s.metadata!==void 0&&(o.push("metadata = ?"),a.push(JSON.stringify(s.metadata))),o.length===0)return!1;o.push("updated_at = ?"),a.push(i),a.push(e),T.run(t,`UPDATE custom_workflows SET ${o.join(", ")} WHERE name = ?`,...a);let u=this.getWorkflow(t,e);return u&&G({projectId:t,entityType:"custom_workflows",entityId:String(u.id),eventType:"upsert",data:{id:u.id,name:u.name,description:u.description??null,enabled:u.enabled?1:0,metadata:u.metadata??null,updated_at:i}}),!0}deleteWorkflow(t,e){let s=this.getWorkflow(t,e);if(!s)return!1;if(s.isBuiltin)throw new Error(`Cannot delete built-in workflow: ${e}`);return T.run(t,"UPDATE custom_workflows SET enabled = 0 WHERE name = ?",e),G({projectId:t,entityType:"custom_workflows",entityId:String(s.id),eventType:"delete",data:{id:s.id,name:e}}),!0}isBuiltin(t,e){return this.getWorkflow(t,e)?.isBuiltin??!1}isReservedName(t){let e=["task","done","ship","sync"],s=["add","rm","gate","list","create","delete","run","help","reset","init"];return e.includes(t)||s.includes(t)}isValidName(t){return/^[a-z0-9-]+$/.test(t)}rowToWorkflow(t){return{id:t.id,name:t.name,description:t.description,createdAt:t.created_at,updatedAt:t.updated_at,isBuiltin:t.is_builtin===1,enabled:t.enabled===1,metadata:t.metadata?JSON.parse(t.metadata):null}}},qt=new Ke;kt();O();function Ve(r){let t=r.trust_source==="imported"?"imported":"local";return{id:r.id,type:r.type,command:r.command,position:r.position,action:r.action,description:r.description,enabled:r.enabled===1,timeoutMs:r.timeout_ms,createdAt:r.created_at,sortOrder:r.sort_order,whenExpr:r.when_expr??null,parallel:r.parallel===null?!0:r.parallel===1,trustSource:t}}c(Ve,"rowToRule");var Qe=class{static{c(this,"WorkflowRuleStorage")}addRule(t,e){let s=E.get(t,"SELECT MAX(sort_order) as m FROM workflow_rules WHERE command = ?",e.command),n=e.sortOrder||(s?.m??-1)+1;E.run(t,`INSERT INTO workflow_rules (type, command, position, action, description, enabled, timeout_ms, created_at, sort_order, when_expr, parallel, trust_source)
595
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,e.type,e.command,e.position,e.action,e.description??null,e.enabled?1:0,e.timeoutMs,e.createdAt,n,e.whenExpr??null,e.parallel===!1?0:1,e.trustSource??"local");let o=E.get(t,"SELECT last_insert_rowid() as id")?.id??0;return o>0&&G({projectId:t,entityType:"workflow_rules",entityId:String(o),eventType:"upsert",data:{id:o,type:e.type,command:e.command,position:e.position,action:e.action,description:e.description??null,enabled:e.enabled?1:0,timeout_ms:e.timeoutMs,sort_order:n,when_expr:e.whenExpr??null,parallel:e.parallel===!1?0:1,trust_source:e.trustSource??"local",created_at:e.createdAt}}),o}removeRule(t,e){return E.get(t,"SELECT id FROM workflow_rules WHERE id = ?",e)?(E.run(t,"DELETE FROM workflow_rules WHERE id = ?",e),G({projectId:t,entityType:"workflow_rules",entityId:String(e),eventType:"delete",data:{id:e}}),!0):!1}updateRule(t,e,s){if(!E.get(t,"SELECT id FROM workflow_rules WHERE id = ?",e))return!1;let i={type:{column:"type"},command:{column:"command"},position:{column:"position"},action:{column:"action"},description:{column:"description"},enabled:{column:"enabled",transform:c(u=>u?1:0,"transform")},timeoutMs:{column:"timeout_ms"},createdAt:{column:"created_at"},sortOrder:{column:"sort_order"},whenExpr:{column:"when_expr"},parallel:{column:"parallel",transform:c(u=>u===!1?0:1,"transform")},trustSource:{column:"trust_source"}},o=[],a=[];for(let[u,p]of Object.entries(s)){let m=i[u];if(!m)continue;o.push(`${m.column} = ?`);let d=p;a.push(m.transform?m.transform(d):d)}return o.length===0||(a.push(e),E.run(t,`UPDATE workflow_rules SET ${o.join(", ")} WHERE id = ?`,...a)),!0}getRuleById(t,e){let s=E.get(t,"SELECT * FROM workflow_rules WHERE id = ?",e);return s?Ve(s):null}getRulesForCommand(t,e){let s=qt.getWorkflow(t,e);return!s||!s.enabled?[]:E.query(t,"SELECT * FROM workflow_rules WHERE command = ? AND enabled = 1 ORDER BY sort_order ASC",e).map(Ve)}getAllRules(t){return E.query(t,"SELECT * FROM workflow_rules ORDER BY command ASC, sort_order ASC").map(Ve)}resetRules(t){let e=E.get(t,"SELECT COUNT(*) as c FROM workflow_rules");return E.run(t,"DELETE FROM workflow_rules"),e?.c??0}},Ze=new Qe;function Ln(r){let t=r;t.tool("prjct_workflow_rules","Get workflow rules for a command (gates, hooks, steps, instructions)",{projectPath:Gt.string().describe("Project directory path"),command:Gt.string().describe("Command name (task, done, ship, sync, etc.)")},S("prjct_workflow_rules",async e=>{let s=await x(e.projectPath),n=Ze.getRulesForCommand(s,e.command);if(n.length===0)return{content:[{type:"text",text:`No workflow rules for \`${e.command}\`.`}]};let i={};for(let a of n){let u=`${a.type}:${a.position}`;i[u]||(i[u]=[]),i[u].push(a)}let o=[`## Workflow Rules for \`${e.command}\``];for(let[a,u]of Object.entries(i)){o.push(`
594
596
  ### ${a}`);for(let p of u){let m=p.enabled?"":" (disabled)";o.push(`- ${p.action}${p.description?` \u2014 ${p.description}`:""}${m}`)}}return{content:[{type:"text",text:o.join(`
595
- `)}]}})),t.tool("prjct_workflow_list","List all workflows for this project (built-in + custom)",{projectPath:Wt.string().describe("Project directory path")},E("prjct_workflow_list",async e=>{let s=await x(e.projectPath),n=$t.getAllWorkflows(s);if(n.length===0)return{content:[{type:"text",text:"No workflows configured."}]};let i=n.map(o=>{let a=o.isBuiltin?"(built-in)":"(custom)",u=o.enabled?"":" [disabled]";return`- **${o.name}** ${a}${u}${o.description?`: ${o.description}`:""}`});return{content:[{type:"text",text:`## Workflows (${n.length})
597
+ `)}]}})),t.tool("prjct_workflow_list","List all workflows for this project (built-in + custom)",{projectPath:Gt.string().describe("Project directory path")},S("prjct_workflow_list",async e=>{let s=await x(e.projectPath),n=qt.getAllWorkflows(s);if(n.length===0)return{content:[{type:"text",text:"No workflows configured."}]};let i=n.map(o=>{let a=o.isBuiltin?"(built-in)":"(custom)",u=o.enabled?"":" [disabled]";return`- **${o.name}** ${a}${u}${o.description?`: ${o.description}`:""}`});return{content:[{type:"text",text:`## Workflows (${n.length})
596
598
 
597
599
  ${i.join(`
598
- `)}`}]}})),t.tool("prjct_workflow_status","Current workflow execution state + active rules",{projectPath:Wt.string().describe("Project directory path")},E("prjct_workflow_status",async e=>{let s=await x(e.projectPath),n=await ot.getCurrentTask(s),i=Je.getAllRules(s),o=["## Workflow Status"];n?(o.push(`
600
+ `)}`}]}})),t.tool("prjct_workflow_status","Current workflow execution state + active rules",{projectPath:Gt.string().describe("Project directory path")},S("prjct_workflow_status",async e=>{let s=await x(e.projectPath),n=await at.getCurrentTask(s),i=Ze.getAllRules(s),o=["## Workflow Status"];n?(o.push(`
599
601
  Active task: **${n.description}**`),o.push(`Started: ${n.startedAt}`)):o.push(`
600
602
  No active task.`);let a=i.filter(u=>u.enabled);if(a.length>0){o.push(`
601
603
  ### Active Rules (${a.length})`);for(let u of a)o.push(`- [${u.type}] ${u.command}:${u.position} \u2192 ${u.action}`)}else o.push(`
602
604
  No active workflow rules.`);return{content:[{type:"text",text:o.join(`
603
- `)}]}}))}c(_n,"registerWorkflowTools");var vo=`# prjct \u2014 Spec-Driven Development + project memory
605
+ `)}]}}))}c(Ln,"registerWorkflowTools");var qo=`# prjct \u2014 Spec-Driven Development + project memory
604
606
 
605
607
  Use when the user describes work, asks for project memory, or wants to run a registered workflow. **Recognize intent \u2014 don't wait for the user to type prjct commands.**
606
608
 
@@ -635,4 +637,4 @@ Skip the SDD flow only for: routine captures, single-file fixes, doc tweaks, con
635
637
  - Topic keys are free-form strings; don't invent new vocabularies when existing ones fit.
636
638
  - Not every project defines every memory type \u2014 if one is empty, that's fine.
637
639
  - Saving a secret-looking string is refused by default. Re-save with a scrubbed version.
638
- - A spec without acceptance_criteria is just an inbox item \u2014 fill them.`;function vn(){let r=new _o({name:"prjct",version:"1.0.0"},{instructions:vo});return hn(r),wn(r),cn(r),_n(r),nr(r),bn(r),r}c(vn,"createServer");async function Po(){let r=vn(),t=new xo;await r.connect(t)}c(Po,"main");Po().catch(r=>{console.error("prjct MCP server failed:",r),process.exit(1)});
640
+ - A spec without acceptance_criteria is just an inbox item \u2014 fill them.`;function On(){let r=new Ho({name:"prjct",version:"1.0.0"},{instructions:qo});return bn(r),An(r),mn(r),Ln(r),ur(r),Dn(r),r}c(On,"createServer");async function Yo(){let r=On(),t=new Go;await r.connect(t)}c(Yo,"main");Yo().catch(r=>{console.error("prjct MCP server failed:",r),process.exit(1)});