prjct-cli 2.28.0 → 2.29.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 At=Object.defineProperty;var Zn=Object.getOwnPropertyDescriptor;var ti=Object.getOwnPropertyNames;var ei=Object.prototype.hasOwnProperty;var c=(s,t)=>At(s,"name",{value:t,configurable:!0}),lr=(s=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(s,{get:(t,e)=>(typeof require<"u"?require:t)[e]}):s)(function(s){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+s+'" is not supported')});var E=(s,t)=>()=>(s&&(t=s(s=0)),t);var Q=(s,t)=>{for(var e in t)At(s,e,{get:t[e],enumerable:!0})},ri=(s,t,e,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of ti(t))!ei.call(s,n)&&n!==e&&At(s,n,{get:()=>t[n],enumerable:!(r=Zn(t,n))||r.enumerable});return s};var te=s=>ri(At({},"__esModule",{value:!0}),s);var pr,dr,mr,ee=E(()=>{"use strict";pr=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"]),dr=["",".ts",".tsx",".js",".jsx","/index.ts","/index.js"],mr=/(?:import|from)\s+['"]([^'"]+)['"]/g});import{formatDistanceToNowStrict as fa}from"date-fns";function gr(s){return{year:s.getFullYear().toString(),month:(s.getMonth()+1).toString().padStart(2,"0"),day:s.getDate().toString().padStart(2,"0")}}function g(){return new Date().toISOString()}function fr(s){let t=new Date;return t.setDate(t.getDate()-s),t}var N=E(()=>{"use strict";c(gr,"getYearMonthDay");c(g,"getTimestamp");c(fr,"getDaysAgo")});function ni(s){return s instanceof Error&&"code"in s}function O(s){return ni(s)&&s.code==="ENOENT"}function hr(s){return s instanceof Error?s.message:typeof s=="string"?s:"Unknown error"}var Z=E(()=>{"use strict";c(ni,"isNodeError");c(O,"isNotFoundError");c(hr,"getErrorMessage")});import Er from"node:fs/promises";async function kr(s,t){let e;try{e=await Er.readFile(s,"utf-8")}catch(i){if(O(i))return null;throw i}let r;try{r=JSON.parse(e)}catch{return await yr(s,e),Tr(s,"Malformed JSON"),null}let n=t.safeParse(r);return n.success?r:(await yr(s,e),Tr(s,ii(n.error)),null)}async function yr(s,t){let e=`${s}.backup`;try{await Er.writeFile(e,t,{encoding:"utf-8",flag:"wx"})}catch{}}function Tr(s,t){console.error(`[prjct] Warning: Corrupted storage file: ${s}`),console.error(`[prjct] Reason: ${t}`),console.error("[prjct] A .backup file has been created. Returning defaults.")}function ii(s){return s.issues.slice(0,3).map(t=>`${t.path.join(".")}: ${t.message}`).join("; ")}var Sr=E(()=>{"use strict";Z();c(kr,"safeRead");c(yr,"createBackup");c(Tr,"logCorruption");c(ii,"formatZodError")});import tt from"node:fs/promises";import re from"node:path";async function wr(s,t={}){let e=[],r=t.maxFiles??1/0,n=t.dotfileAllowlist?new Set(t.dotfileAllowlist):null;async function i(o){if(e.length>=r)return;let a=await tt.readdir(o,{withFileTypes:!0}).catch(()=>[]);for(let u of a){if(e.length>=r)break;let l=String(u.name);if(pr.has(l)||t.skipDotfiles&&l.startsWith(".")&&(!n||!n.has(l)))continue;let d=re.join(o,l);u.isDirectory()?await i(d):u.isFile()&&e.push(re.relative(s,d))}}return c(i,"walk"),await i(s),e}async function br(s,t,e){let r=[];for(let n=0;n<s.length;n+=t){let i=await Promise.all(s.slice(n,n+t).map(e));for(let o of i)o!==null&&r.push(o)}return r}async function Nt(s,t=null,e){if(e)return await kr(s,e)??t;try{let r=await tt.readFile(s,"utf-8");return JSON.parse(r)}catch(r){if(O(r))return t;throw r}}async function F(s,t,e=2){let r=re.dirname(s);await tt.mkdir(r,{recursive:!0});let n=`${JSON.stringify(t,null,e)}
9
- `;await tt.writeFile(s,n,"utf-8")}async function C(s){try{return await tt.access(s),!0}catch(t){if(O(t))return!1;throw t}}async function se(s){try{return(await tt.stat(s)).isDirectory()}catch(t){if(O(t))return!1;throw t}}async function G(s){await tt.mkdir(s,{recursive:!0})}var U=E(()=>{"use strict";ee();Sr();Z();c(wr,"walkDir");c(br,"batchProcess");c(Nt,"readJson");c(F,"writeJson");c(C,"fileExists");c(se,"dirExists");c(G,"ensureDir")});import nt from"node:fs/promises";import I from"node:path";import{globSync as oi}from"glob";async function ne(s){let t={isMonorepo:!1,type:null,rootPath:s,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 r of e)if(await C(I.join(s,r.file))){t.isMonorepo=!0,t.type=r.type;break}if(!t.isMonorepo){let r=I.join(s,"package.json");if(await C(r))try{JSON.parse(await nt.readFile(r,"utf-8")).workspaces&&(t.isMonorepo=!0,t.type="npm")}catch{}}return t.isMonorepo&&(t.packages=await ie(s,t.type)),t}async function ie(s,t){let e=[],r=[];try{if(t==="pnpm"){let i=(await nt.readFile(I.join(s,"pnpm-workspace.yaml"),"utf-8")).match(/packages:\s*\n((?:\s*-\s*.+\n?)+)/);i&&(r=i[1].split(`
10
- `).map(o=>o.replace(/^\s*-\s*['"]?|['"]?\s*$/g,"")).filter(Boolean))}else if(t==="npm"||t==="lerna"){let n=I.join(s,"package.json"),i=JSON.parse(await nt.readFile(n,"utf-8"));if(Array.isArray(i.workspaces)?r=i.workspaces:i.workspaces?.packages&&(r=i.workspaces.packages),t==="lerna"){let o=I.join(s,"lerna.json");if(await C(o)){let a=JSON.parse(await nt.readFile(o,"utf-8"));a.packages&&(r=a.packages)}}}else if(t==="nx")r=["apps/*","libs/*","packages/*"];else if(t==="turborepo"){let n=I.join(s,"package.json"),i=JSON.parse(await nt.readFile(n,"utf-8"));Array.isArray(i.workspaces)&&(r=i.workspaces)}r.length===0&&(r=["packages/*","apps/*","libs/*"]);for(let n of r){if(n.startsWith("!"))continue;let i=oi(n,{cwd:s,absolute:!1});for(let o of i){let a=I.join(s,o),u=I.join(a,"package.json");if(await C(u))try{let l=JSON.parse(await nt.readFile(u,"utf-8")),d=I.join(a,"PRJCT.md");e.push({name:l.name||I.basename(o),path:a,relativePath:o,hasPrjctMd:await C(d)})}catch{}}}}catch{}return e}async function _r(s,t){if(!t.isMonorepo)return null;let e=I.resolve(s);for(let r of t.packages){let n=I.resolve(r.path);if(e.startsWith(n))return r}return null}async function vr(s){let t=I.resolve(s),e=I.parse(t).root;for(;t!==e;){if((await ne(t)).isMonorepo)return t;t=I.dirname(t)}return null}var xr=E(()=>{"use strict";U();c(ne,"detectMonorepo");c(ie,"discoverMonorepoPackages");c(_r,"findContainingPackage");c(vr,"findMonorepoRoot")});import{exec as ai,execFile as ci}from"node:child_process";import{promisify as Rr}from"node:util";var _,Ma,it=E(()=>{"use strict";_=Rr(ai),Ma=Rr(ci)});var ce={};Q(ce,{default:()=>ui,worktreeService:()=>Ar});import oe from"node:fs/promises";import $ from"node:path";var Pr,ae,Ar,ui,ue=E(()=>{"use strict";it();U();Pr=".worktrees",ae=class{static{c(this,"WorktreeService")}async create(t,e,r={}){let n=await this.getMainWorktree(t),i=$.join(n,Pr,e),o=r.branch||`feat/${e}`;await oe.mkdir($.join(n,Pr),{recursive:!0});let a=r.baseBranch?` ${r.baseBranch}`:"";await _(`git worktree add "${i}" -b "${o}"${a}`,{cwd:n});let{stdout:u}=await _("git rev-parse HEAD",{cwd:i});return{path:i,branch:o,commit:u.trim(),isMain:!1,slug:e}}async remove(t,e=!1){let r=await this.getMainWorktree(t),n;if(e)try{let{stdout:i}=await _("git rev-parse --abbrev-ref HEAD",{cwd:t});n=i.trim()}catch{}if(await _(`git worktree remove "${t}" --force`,{cwd:r}),e&&n&&n!=="main"&&n!=="master")try{await _(`git branch -D "${n}"`,{cwd:r})}catch{}}async list(t){let e=await this.getMainWorktree(t),{stdout:r}=await _("git worktree list --porcelain",{cwd:e});return this.parsePorcelainOutput(r,e)}async detect(t){try{let{stdout:e}=await _("git rev-parse --git-common-dir",{cwd:t}),{stdout:r}=await _("git rev-parse --git-dir",{cwd:t}),n=$.resolve(t,e.trim()),i=$.resolve(t,r.trim());if(n!==i){let{stdout:o}=await _("git rev-parse --abbrev-ref HEAD",{cwd:t}),{stdout:a}=await _("git rev-parse HEAD",{cwd:t}),{stdout:u}=await _("git rev-parse --show-toplevel",{cwd:t}),l=u.trim(),d=$.basename(l);return{path:l,branch:o.trim(),commit:a.trim(),isMain:!1,slug:d}}return null}catch{return null}}async getMainWorktree(t){try{let{stdout:r}=await _("git worktree list --porcelain",{cwd:t}),n=r.split(`
8
+ var At=Object.defineProperty;var ni=Object.getOwnPropertyDescriptor;var ii=Object.getOwnPropertyNames;var oi=Object.prototype.hasOwnProperty;var c=(s,t)=>At(s,"name",{value:t,configurable:!0}),lr=(s=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(s,{get:(t,e)=>(typeof require<"u"?require:t)[e]}):s)(function(s){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+s+'" is not supported')});var E=(s,t)=>()=>(s&&(t=s(s=0)),t);var K=(s,t)=>{for(var e in t)At(s,e,{get:t[e],enumerable:!0})},ai=(s,t,e,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of ii(t))!oi.call(s,n)&&n!==e&&At(s,n,{get:()=>t[n],enumerable:!(r=ni(t,n))||r.enumerable});return s};var te=s=>ai(At({},"__esModule",{value:!0}),s);var pr,dr,mr,ee=E(()=>{"use strict";pr=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"]),dr=["",".ts",".tsx",".js",".jsx","/index.ts","/index.js"],mr=/(?:import|from)\s+['"]([^'"]+)['"]/g});import{formatDistanceToNowStrict as xa}from"date-fns";function gr(s){return{year:s.getFullYear().toString(),month:(s.getMonth()+1).toString().padStart(2,"0"),day:s.getDate().toString().padStart(2,"0")}}function g(){return new Date().toISOString()}function fr(s){let t=new Date;return t.setDate(t.getDate()-s),t}var N=E(()=>{"use strict";c(gr,"getYearMonthDay");c(g,"getTimestamp");c(fr,"getDaysAgo")});function ui(s){return s instanceof Error&&"code"in s}function O(s){return ui(s)&&s.code==="ENOENT"}function hr(s){return s instanceof Error?s.message:typeof s=="string"?s:"Unknown error"}var Z=E(()=>{"use strict";c(ui,"isNodeError");c(O,"isNotFoundError");c(hr,"getErrorMessage")});import Er from"node:fs/promises";async function kr(s,t){let e;try{e=await Er.readFile(s,"utf-8")}catch(i){if(O(i))return null;throw i}let r;try{r=JSON.parse(e)}catch{return await yr(s,e),Tr(s,"Malformed JSON"),null}let n=t.safeParse(r);return n.success?r:(await yr(s,e),Tr(s,li(n.error)),null)}async function yr(s,t){let e=`${s}.backup`;try{await Er.writeFile(e,t,{encoding:"utf-8",flag:"wx"})}catch{}}function Tr(s,t){console.error(`[prjct] Warning: Corrupted storage file: ${s}`),console.error(`[prjct] Reason: ${t}`),console.error("[prjct] A .backup file has been created. Returning defaults.")}function li(s){return s.issues.slice(0,3).map(t=>`${t.path.join(".")}: ${t.message}`).join("; ")}var Sr=E(()=>{"use strict";Z();c(kr,"safeRead");c(yr,"createBackup");c(Tr,"logCorruption");c(li,"formatZodError")});import tt from"node:fs/promises";import re from"node:path";async function wr(s,t={}){let e=[],r=t.maxFiles??1/0,n=t.dotfileAllowlist?new Set(t.dotfileAllowlist):null;async function i(o){if(e.length>=r)return;let a=await tt.readdir(o,{withFileTypes:!0}).catch(()=>[]);for(let u of a){if(e.length>=r)break;let l=String(u.name);if(pr.has(l)||t.skipDotfiles&&l.startsWith(".")&&(!n||!n.has(l)))continue;let d=re.join(o,l);u.isDirectory()?await i(d):u.isFile()&&e.push(re.relative(s,d))}}return c(i,"walk"),await i(s),e}async function br(s,t,e){let r=[];for(let n=0;n<s.length;n+=t){let i=await Promise.all(s.slice(n,n+t).map(e));for(let o of i)o!==null&&r.push(o)}return r}async function Nt(s,t=null,e){if(e)return await kr(s,e)??t;try{let r=await tt.readFile(s,"utf-8");return JSON.parse(r)}catch(r){if(O(r))return t;throw r}}async function F(s,t,e=2){let r=re.dirname(s);await tt.mkdir(r,{recursive:!0});let n=`${JSON.stringify(t,null,e)}
9
+ `;await tt.writeFile(s,n,"utf-8")}async function C(s){try{return await tt.access(s),!0}catch(t){if(O(t))return!1;throw t}}async function se(s){try{return(await tt.stat(s)).isDirectory()}catch(t){if(O(t))return!1;throw t}}async function G(s){await tt.mkdir(s,{recursive:!0})}var U=E(()=>{"use strict";ee();Sr();Z();c(wr,"walkDir");c(br,"batchProcess");c(Nt,"readJson");c(F,"writeJson");c(C,"fileExists");c(se,"dirExists");c(G,"ensureDir")});import nt from"node:fs/promises";import I from"node:path";import{globSync as pi}from"glob";async function ne(s){let t={isMonorepo:!1,type:null,rootPath:s,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 r of e)if(await C(I.join(s,r.file))){t.isMonorepo=!0,t.type=r.type;break}if(!t.isMonorepo){let r=I.join(s,"package.json");if(await C(r))try{JSON.parse(await nt.readFile(r,"utf-8")).workspaces&&(t.isMonorepo=!0,t.type="npm")}catch{}}return t.isMonorepo&&(t.packages=await ie(s,t.type)),t}async function ie(s,t){let e=[],r=[];try{if(t==="pnpm"){let i=(await nt.readFile(I.join(s,"pnpm-workspace.yaml"),"utf-8")).match(/packages:\s*\n((?:\s*-\s*.+\n?)+)/);i&&(r=i[1].split(`
10
+ `).map(o=>o.replace(/^\s*-\s*['"]?|['"]?\s*$/g,"")).filter(Boolean))}else if(t==="npm"||t==="lerna"){let n=I.join(s,"package.json"),i=JSON.parse(await nt.readFile(n,"utf-8"));if(Array.isArray(i.workspaces)?r=i.workspaces:i.workspaces?.packages&&(r=i.workspaces.packages),t==="lerna"){let o=I.join(s,"lerna.json");if(await C(o)){let a=JSON.parse(await nt.readFile(o,"utf-8"));a.packages&&(r=a.packages)}}}else if(t==="nx")r=["apps/*","libs/*","packages/*"];else if(t==="turborepo"){let n=I.join(s,"package.json"),i=JSON.parse(await nt.readFile(n,"utf-8"));Array.isArray(i.workspaces)&&(r=i.workspaces)}r.length===0&&(r=["packages/*","apps/*","libs/*"]);for(let n of r){if(n.startsWith("!"))continue;let i=pi(n,{cwd:s,absolute:!1});for(let o of i){let a=I.join(s,o),u=I.join(a,"package.json");if(await C(u))try{let l=JSON.parse(await nt.readFile(u,"utf-8")),d=I.join(a,"PRJCT.md");e.push({name:l.name||I.basename(o),path:a,relativePath:o,hasPrjctMd:await C(d)})}catch{}}}}catch{}return e}async function _r(s,t){if(!t.isMonorepo)return null;let e=I.resolve(s);for(let r of t.packages){let n=I.resolve(r.path);if(e.startsWith(n))return r}return null}async function vr(s){let t=I.resolve(s),e=I.parse(t).root;for(;t!==e;){if((await ne(t)).isMonorepo)return t;t=I.dirname(t)}return null}var xr=E(()=>{"use strict";U();c(ne,"detectMonorepo");c(ie,"discoverMonorepoPackages");c(_r,"findContainingPackage");c(vr,"findMonorepoRoot")});import{exec as di,execFile as mi}from"node:child_process";import{promisify as Rr}from"node:util";var _,Ya,it=E(()=>{"use strict";_=Rr(di),Ya=Rr(mi)});var ce={};K(ce,{default:()=>gi,worktreeService:()=>Ar});import oe from"node:fs/promises";import $ from"node:path";var Pr,ae,Ar,gi,ue=E(()=>{"use strict";it();U();Pr=".worktrees",ae=class{static{c(this,"WorktreeService")}async create(t,e,r={}){let n=await this.getMainWorktree(t),i=$.join(n,Pr,e),o=r.branch||`feat/${e}`;await oe.mkdir($.join(n,Pr),{recursive:!0});let a=r.baseBranch?` ${r.baseBranch}`:"";await _(`git worktree add "${i}" -b "${o}"${a}`,{cwd:n});let{stdout:u}=await _("git rev-parse HEAD",{cwd:i});return{path:i,branch:o,commit:u.trim(),isMain:!1,slug:e}}async remove(t,e=!1){let r=await this.getMainWorktree(t),n;if(e)try{let{stdout:i}=await _("git rev-parse --abbrev-ref HEAD",{cwd:t});n=i.trim()}catch{}if(await _(`git worktree remove "${t}" --force`,{cwd:r}),e&&n&&n!=="main"&&n!=="master")try{await _(`git branch -D "${n}"`,{cwd:r})}catch{}}async list(t){let e=await this.getMainWorktree(t),{stdout:r}=await _("git worktree list --porcelain",{cwd:e});return this.parsePorcelainOutput(r,e)}async detect(t){try{let{stdout:e}=await _("git rev-parse --git-common-dir",{cwd:t}),{stdout:r}=await _("git rev-parse --git-dir",{cwd:t}),n=$.resolve(t,e.trim()),i=$.resolve(t,r.trim());if(n!==i){let{stdout:o}=await _("git rev-parse --abbrev-ref HEAD",{cwd:t}),{stdout:a}=await _("git rev-parse HEAD",{cwd:t}),{stdout:u}=await _("git rev-parse --show-toplevel",{cwd:t}),l=u.trim(),d=$.basename(l);return{path:l,branch:o.trim(),commit:a.trim(),isMain:!1,slug:d}}return null}catch{return null}}async getMainWorktree(t){try{let{stdout:r}=await _("git worktree list --porcelain",{cwd:t}),n=r.split(`
11
11
  `)[0];if(n?.startsWith("worktree "))return n.replace("worktree ","").trim()}catch{}let{stdout:e}=await _("git rev-parse --show-toplevel",{cwd:t});return e.trim()}async setup(t,e){let r=$.join(e,".env");await C(r)&&await oe.copyFile(r,$.join(t,".env"));let n=$.join(e,".prjct"),i=$.join(t,".prjct");await C(n)&&!await C(i)&&await oe.symlink(n,i,"dir")}async teardown(t){}async clean(t){let e=await this.list(t),r=[],n=await this.getMainWorktree(t);await _("git worktree prune",{cwd:n});for(let i of e)i.isMain||await C(i.path)||r.push(i.slug);return r}parsePorcelainOutput(t,e){let r=[],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="",l="",d=!1;for(let m of o)m.startsWith("worktree ")?a=m.replace("worktree ","").trim():m.startsWith("HEAD ")?u=m.replace("HEAD ","").trim():m.startsWith("branch ")?l=m.replace("branch refs/heads/","").trim():m==="bare"?d=!0:m==="detached"&&(l="(detached)");if(a){let m=a===e||d;r.push({path:a,branch:l,commit:u,isMain:m,slug:m?"main":$.basename(a)})}}return r}},Ar=new ae,ui=Ar});import le from"node:os";import X from"node:path";async function Nr(s,t){if(t&&t.trim().length>0)return pi(s,t);let e=await li(s),n=X.basename(X.resolve(e)).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"project";return X.join(le.homedir(),"Documents","prjct",n)}function Cr(s,t){let r=X.basename(X.resolve(s)).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"project",n=t.replace(/-/g,"").slice(0,8);return X.join(le.homedir(),"Documents","prjct",`${r}-${n}`)}function Ir(s){return X.join(s,".prjct","wiki")}async function li(s){try{let{worktreeService:t}=await Promise.resolve().then(()=>(ue(),ce));return await t.detect(s)&&await t.getMainWorktree(s)||s}catch{return s}}function pi(s,t){let e=t.trim();return(e.startsWith("~/")||e==="~")&&(e=X.join(le.homedir(),e.slice(1))),X.isAbsolute(e)||(e=X.resolve(s,e)),e}var Dr=E(()=>{"use strict";c(Nr,"getWikiPath");c(Cr,"getWikiPathWithProjectHash");c(Ir,"getLegacyWikiPath");c(li,"resolveProjectRootPath");c(pi,"resolveVaultOverride")});var Lr=E(()=>{"use strict"});import{z as ft}from"zod";function Or(s,t){let e=s.split(".").map(Number),r=t.split(".").map(Number);for(let n=0;n<3;n++){let i=e[n]??0,o=r[n]??0;if(i<o)return-1;if(i>o)return 1}return 0}var pe,de=E(()=>{"use strict";pe=ft.object({provider:ft.string(),model:ft.string(),cliVersion:ft.string().optional(),recordedAt:ft.string()});c(Or,"compareSemver")});function Mr(s,t){let e=typeof s=="string"?new Date(s).getTime():s;return Date.now()-e>t}var It,me=E(()=>{"use strict";c(Mr,"isExpired");It=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((r,n)=>r[1].timestamp-n[1].timestamp).slice(0,this.cache.size-this.maxSize);for(let[r]of e)this.cache.delete(r)}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 di from"node:fs/promises";import mi from"node:path";async function Fr(){try{let s=await di.readFile(jr(),"utf-8"),t=JSON.parse(s);return!t.timestamp||!t.detection||!t.detection.claude||!t.detection.gemini||!t.detection.codex||Mr(t.timestamp,gi)?null:t.detection}catch{return null}}async function Ur(s){let t={timestamp:new Date().toISOString(),detection:s};await F(jr(),t)}var jr,gi,$r=E(()=>{"use strict";ot();me();U();jr=c(()=>mi.join(v.getCachePath(),"providers.json"),"cacheFile"),gi=10*60*1e3;c(Fr,"readProviderCache");c(Ur,"writeProviderCache")});var Lt={};Q(Lt,{ClaudeProvider:()=>Dt,CursorProvider:()=>Br,GeminiProvider:()=>fe,Providers:()=>ht,detectAllProviders:()=>he,detectAntigravity:()=>Ei,detectCodex:()=>Yr,detectProvider:()=>ge,getActiveProvider:()=>yi,getProviderBranding:()=>Ti,selectProvider:()=>ki,validateCliVersion:()=>Gr});import K from"node:os";import W from"node:path";async function qr(s){try{let{stdout:t}=await _(`which ${s}`,{timeout:2e3});return t.trim()}catch{return null}}async function hi(s){try{let{stdout:t}=await _(`${s} --version`,{timeout:2e3}),e=t.match(/\d+\.\d+\.\d+/);return e?e[0]:t.trim()}catch{return null}}async function ge(s){let t=ht[s];if(!t.cliCommand)return{installed:!1};let e=await qr(t.cliCommand);if(!e)return{installed:!1};let r=await hi(t.cliCommand),n=Gr(s,r||void 0);return{installed:!0,version:r||void 0,path:e,versionWarning:n||void 0}}function Gr(s,t){let e=ht[s];return!e.minCliVersion||!t?null:Or(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 he(s=!1){if(!s){let o=await Fr();if(o)return o}let[t,e,r]=await Promise.all([ge("claude"),ge("gemini"),Yr()]),n={installed:r.installed},i={claude:t,gemini:e,codex:n};return await Ur(i).catch(()=>{}),i}async function yi(s){if(s&&ht[s])return ht[s];let t=await he();return t.claude.installed&&!t.gemini.installed?Dt:t.gemini.installed&&!t.claude.installed?fe:Dt}function Ti(s){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"}[s]||"\u26A1 prjct"}}async function Ei(){let s=Wr.configDir;if(!s)return{installed:!1,skillInstalled:!1};let t=W.join(s,"skills","prjct","SKILL.md"),[e,r]=await Promise.all([C(s),C(t)]);return{installed:e,skillInstalled:r,configPath:e?s:void 0}}async function Yr(){let s=Hr.configDir;if(!s)return{installed:!1,skillInstalled:!1};let t=await qr("codex"),e=W.join(s,"skills","prjct","SKILL.md"),r=await C(e),n=!!t;return{installed:n,skillInstalled:r,configPath:n?s:void 0}}async function ki(){let s=await he(),t=s.claude.installed,e=s.gemini.installed;return!t&&!e?{provider:"claude",userSelected:!1,detection:s}:t&&!e?{provider:"claude",userSelected:!1,detection:s}:e&&!t?{provider:"gemini",userSelected:!1,detection:s}:{provider:"claude",userSelected:!0,detection:s}}var Dt,fe,Wr,Br,fi,Hr,ht,Ot=E(()=>{"use strict";Lr();de();it();U();$r();Dt={name:"claude",displayName:"Claude Code",cliCommand:"claude",configDir:W.join(K.homedir(),".claude"),contextFile:"CLAUDE.md",skillsDir:W.join(K.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"},fe={name:"gemini",displayName:"Gemini CLI",cliCommand:"gemini",configDir:W.join(K.homedir(),".gemini"),contextFile:"GEMINI.md",skillsDir:W.join(K.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"},Wr={name:"antigravity",displayName:"Google Antigravity",cliCommand:null,configDir:W.join(K.homedir(),".gemini","antigravity"),contextFile:"ANTIGRAVITY.md",skillsDir:W.join(K.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"},Br={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"},fi={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"},Hr={name:"codex",displayName:"OpenAI Codex",cliCommand:"codex",configDir:W.join(K.homedir(),".codex"),contextFile:"AGENTS.md",skillsDir:W.join(K.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"},ht={claude:Dt,gemini:fe,cursor:Br,antigravity:Wr,windsurf:fi,codex:Hr};c(qr,"whichCommand");c(hi,"getCliVersion");c(ge,"detectProvider");c(Gr,"validateCliVersion");c(he,"detectAllProviders");c(yi,"getActiveProvider");c(Ti,"getProviderBranding");c(Ei,"detectAntigravity");c(Yr,"detectCodex");c(ki,"selectProvider")});import Si from"node:crypto";import Mt from"node:fs/promises";import ye from"node:os";import w from"node:path";var Te,wi,v,ot=E(()=>{"use strict";N();U();xr();Dr();Te=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(ye.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 Si.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 se(this.getLegacyPrjctPath(t))}async hasConfig(t){return await C(this.getLocalConfigPath(t))}async ensureGlobalStructure(){await G(this.globalBaseDir),await G(this.globalProjectsDir),await G(this.globalConfigDir)}async ensureProjectStructure(t){await this.ensureGlobalStructure();let e=this.getGlobalProjectPath(t),r=["analysis","memory"];for(let n of r)await G(w.join(e,n));return await G(w.join(e,"sessions")),e}getSessionPath(t,e=new Date){let{year:r,month:n,day:i}=gr(e);return w.join(this.getGlobalProjectPath(t),"sessions",r,n,i)}getCurrentSessionPath(t){return this.getSessionPath(t,new Date)}async ensureSessionPath(t,e=new Date){let r=this.getSessionPath(t,e);return await G(r),r}async listSessions(t,e=null,r=null){let n=w.join(this.getGlobalProjectPath(t),"sessions"),i=[];try{let o=await Mt.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),l=await Mt.readdir(u,{withFileTypes:!0});for(let d of l){if(!d.isDirectory()||r&&d.name!==r.toString().padStart(2,"0"))continue;let m=w.join(u,d.name),f=await Mt.readdir(m,{withFileTypes:!0});for(let T of f)T.isDirectory()&&i.push({year:a.name,month:d.name,day:T.name,path:w.join(m,T.name),date:new Date(`${a.name}-${d.name}-${T.name}`)})}}return i.sort((a,u)=>u.date.getTime()-a.date.getTime()),i}catch{return[]}}async getSessionsInRange(t,e,r=new Date){return(await this.listSessions(t)).filter(i=>i.date>=e&&i.date<=r)}getFilePath(t,e,r){return w.join(this.getGlobalProjectPath(t),e,r)}async listProjects(){try{return await this.ensureGlobalStructure(),(await Mt.readdir(this.globalProjectsDir,{withFileTypes:!0})).filter(e=>e.isDirectory()).map(e=>e.name)}catch{return[]}}async projectExists(t){return await se(this.getGlobalProjectPath(t))}getDisplayPath(t){let e=ye.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")}getCachePath(){return w.join(this.globalBaseDir,"cache")}getStatePath(){return w.join(this.globalBaseDir,"state")}getStatusLinePath(){return w.join(this.globalBaseDir,"statusline")}async getAgentDir(){return(await(Ot(),te(Lt)).getActiveProvider()).configDir}async getAgentSettingsPath(){let t=await(Ot(),te(Lt)).getActiveProvider();return(Ot(),te(Lt)).getGlobalSettingsPath(t.name)}getClaudeDir(){return w.join(ye.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 Nr(t,e)}getWikiPathWithProjectHash(t,e){return Cr(t,e)}getLegacyWikiPath(t){return Ir(t)}async detectMonorepo(t){return ne(t)}async discoverMonorepoPackages(t,e){return ie(t,e)}async findContainingPackage(t,e){return _r(t,e)}async findMonorepoRoot(t){return vr(t)}},wi=new Te,v=wi});var Jr,zr=E(()=>{"use strict";Jr=`
14
+ `),a="",u="",l="",d=!1;for(let m of o)m.startsWith("worktree ")?a=m.replace("worktree ","").trim():m.startsWith("HEAD ")?u=m.replace("HEAD ","").trim():m.startsWith("branch ")?l=m.replace("branch refs/heads/","").trim():m==="bare"?d=!0:m==="detached"&&(l="(detached)");if(a){let m=a===e||d;r.push({path:a,branch:l,commit:u,isMain:m,slug:m?"main":$.basename(a)})}}return r}},Ar=new ae,gi=Ar});import le from"node:os";import X from"node:path";async function Nr(s,t){if(t&&t.trim().length>0)return hi(s,t);let e=await fi(s),n=X.basename(X.resolve(e)).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"project";return X.join(le.homedir(),"Documents","prjct",n)}function Cr(s,t){let r=X.basename(X.resolve(s)).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"project",n=t.replace(/-/g,"").slice(0,8);return X.join(le.homedir(),"Documents","prjct",`${r}-${n}`)}function Ir(s){return X.join(s,".prjct","wiki")}async function fi(s){try{let{worktreeService:t}=await Promise.resolve().then(()=>(ue(),ce));return await t.detect(s)&&await t.getMainWorktree(s)||s}catch{return s}}function hi(s,t){let e=t.trim();return(e.startsWith("~/")||e==="~")&&(e=X.join(le.homedir(),e.slice(1))),X.isAbsolute(e)||(e=X.resolve(s,e)),e}var Dr=E(()=>{"use strict";c(Nr,"getWikiPath");c(Cr,"getWikiPathWithProjectHash");c(Ir,"getLegacyWikiPath");c(fi,"resolveProjectRootPath");c(hi,"resolveVaultOverride")});var Lr=E(()=>{"use strict"});import{z as ft}from"zod";function Or(s,t){let e=s.split(".").map(Number),r=t.split(".").map(Number);for(let n=0;n<3;n++){let i=e[n]??0,o=r[n]??0;if(i<o)return-1;if(i>o)return 1}return 0}var pe,de=E(()=>{"use strict";pe=ft.object({provider:ft.string(),model:ft.string(),cliVersion:ft.string().optional(),recordedAt:ft.string()});c(Or,"compareSemver")});function Mr(s,t){let e=typeof s=="string"?new Date(s).getTime():s;return Date.now()-e>t}var It,me=E(()=>{"use strict";c(Mr,"isExpired");It=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((r,n)=>r[1].timestamp-n[1].timestamp).slice(0,this.cache.size-this.maxSize);for(let[r]of e)this.cache.delete(r)}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 yi from"node:fs/promises";import Ti from"node:path";async function Fr(){try{let s=await yi.readFile(jr(),"utf-8"),t=JSON.parse(s);return!t.timestamp||!t.detection||!t.detection.claude||!t.detection.gemini||!t.detection.codex||Mr(t.timestamp,Ei)?null:t.detection}catch{return null}}async function Ur(s){let t={timestamp:new Date().toISOString(),detection:s};await F(jr(),t)}var jr,Ei,$r=E(()=>{"use strict";ot();me();U();jr=c(()=>Ti.join(v.getCachePath(),"providers.json"),"cacheFile"),Ei=10*60*1e3;c(Fr,"readProviderCache");c(Ur,"writeProviderCache")});var Lt={};K(Lt,{ClaudeProvider:()=>Dt,CursorProvider:()=>Br,GeminiProvider:()=>fe,Providers:()=>ht,detectAllProviders:()=>he,detectAntigravity:()=>_i,detectCodex:()=>Yr,detectProvider:()=>ge,getActiveProvider:()=>wi,getProviderBranding:()=>bi,selectProvider:()=>vi,validateCliVersion:()=>Gr});import V from"node:os";import W from"node:path";async function qr(s){try{let{stdout:t}=await _(`which ${s}`,{timeout:2e3});return t.trim()}catch{return null}}async function Si(s){try{let{stdout:t}=await _(`${s} --version`,{timeout:2e3}),e=t.match(/\d+\.\d+\.\d+/);return e?e[0]:t.trim()}catch{return null}}async function ge(s){let t=ht[s];if(!t.cliCommand)return{installed:!1};let e=await qr(t.cliCommand);if(!e)return{installed:!1};let r=await Si(t.cliCommand),n=Gr(s,r||void 0);return{installed:!0,version:r||void 0,path:e,versionWarning:n||void 0}}function Gr(s,t){let e=ht[s];return!e.minCliVersion||!t?null:Or(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 he(s=!1){if(!s){let o=await Fr();if(o)return o}let[t,e,r]=await Promise.all([ge("claude"),ge("gemini"),Yr()]),n={installed:r.installed},i={claude:t,gemini:e,codex:n};return await Ur(i).catch(()=>{}),i}async function wi(s){if(s&&ht[s])return ht[s];let t=await he();return t.claude.installed&&!t.gemini.installed?Dt:t.gemini.installed&&!t.claude.installed?fe:Dt}function bi(s){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"}[s]||"\u26A1 prjct"}}async function _i(){let s=Wr.configDir;if(!s)return{installed:!1,skillInstalled:!1};let t=W.join(s,"skills","prjct","SKILL.md"),[e,r]=await Promise.all([C(s),C(t)]);return{installed:e,skillInstalled:r,configPath:e?s:void 0}}async function Yr(){let s=Hr.configDir;if(!s)return{installed:!1,skillInstalled:!1};let t=await qr("codex"),e=W.join(s,"skills","prjct","SKILL.md"),r=await C(e),n=!!t;return{installed:n,skillInstalled:r,configPath:n?s:void 0}}async function vi(){let s=await he(),t=s.claude.installed,e=s.gemini.installed;return!t&&!e?{provider:"claude",userSelected:!1,detection:s}:t&&!e?{provider:"claude",userSelected:!1,detection:s}:e&&!t?{provider:"gemini",userSelected:!1,detection:s}:{provider:"claude",userSelected:!0,detection:s}}var Dt,fe,Wr,Br,ki,Hr,ht,Ot=E(()=>{"use strict";Lr();de();it();U();$r();Dt={name:"claude",displayName:"Claude Code",cliCommand:"claude",configDir:W.join(V.homedir(),".claude"),contextFile:"CLAUDE.md",skillsDir:W.join(V.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"},fe={name:"gemini",displayName:"Gemini CLI",cliCommand:"gemini",configDir:W.join(V.homedir(),".gemini"),contextFile:"GEMINI.md",skillsDir:W.join(V.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"},Wr={name:"antigravity",displayName:"Google Antigravity",cliCommand:null,configDir:W.join(V.homedir(),".gemini","antigravity"),contextFile:"ANTIGRAVITY.md",skillsDir:W.join(V.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"},Br={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"},ki={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"},Hr={name:"codex",displayName:"OpenAI Codex",cliCommand:"codex",configDir:W.join(V.homedir(),".codex"),contextFile:"AGENTS.md",skillsDir:W.join(V.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"},ht={claude:Dt,gemini:fe,cursor:Br,antigravity:Wr,windsurf:ki,codex:Hr};c(qr,"whichCommand");c(Si,"getCliVersion");c(ge,"detectProvider");c(Gr,"validateCliVersion");c(he,"detectAllProviders");c(wi,"getActiveProvider");c(bi,"getProviderBranding");c(_i,"detectAntigravity");c(Yr,"detectCodex");c(vi,"selectProvider")});import xi from"node:crypto";import Mt from"node:fs/promises";import ye from"node:os";import w from"node:path";var Te,Ri,v,ot=E(()=>{"use strict";N();U();xr();Dr();Te=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(ye.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 xi.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 se(this.getLegacyPrjctPath(t))}async hasConfig(t){return await C(this.getLocalConfigPath(t))}async ensureGlobalStructure(){await G(this.globalBaseDir),await G(this.globalProjectsDir),await G(this.globalConfigDir)}async ensureProjectStructure(t){await this.ensureGlobalStructure();let e=this.getGlobalProjectPath(t),r=["analysis","memory"];for(let n of r)await G(w.join(e,n));return await G(w.join(e,"sessions")),e}getSessionPath(t,e=new Date){let{year:r,month:n,day:i}=gr(e);return w.join(this.getGlobalProjectPath(t),"sessions",r,n,i)}getCurrentSessionPath(t){return this.getSessionPath(t,new Date)}async ensureSessionPath(t,e=new Date){let r=this.getSessionPath(t,e);return await G(r),r}async listSessions(t,e=null,r=null){let n=w.join(this.getGlobalProjectPath(t),"sessions"),i=[];try{let o=await Mt.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),l=await Mt.readdir(u,{withFileTypes:!0});for(let d of l){if(!d.isDirectory()||r&&d.name!==r.toString().padStart(2,"0"))continue;let m=w.join(u,d.name),f=await Mt.readdir(m,{withFileTypes:!0});for(let T of f)T.isDirectory()&&i.push({year:a.name,month:d.name,day:T.name,path:w.join(m,T.name),date:new Date(`${a.name}-${d.name}-${T.name}`)})}}return i.sort((a,u)=>u.date.getTime()-a.date.getTime()),i}catch{return[]}}async getSessionsInRange(t,e,r=new Date){return(await this.listSessions(t)).filter(i=>i.date>=e&&i.date<=r)}getFilePath(t,e,r){return w.join(this.getGlobalProjectPath(t),e,r)}async listProjects(){try{return await this.ensureGlobalStructure(),(await Mt.readdir(this.globalProjectsDir,{withFileTypes:!0})).filter(e=>e.isDirectory()).map(e=>e.name)}catch{return[]}}async projectExists(t){return await se(this.getGlobalProjectPath(t))}getDisplayPath(t){let e=ye.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")}getCachePath(){return w.join(this.globalBaseDir,"cache")}getStatePath(){return w.join(this.globalBaseDir,"state")}getStatusLinePath(){return w.join(this.globalBaseDir,"statusline")}async getAgentDir(){return(await(Ot(),te(Lt)).getActiveProvider()).configDir}async getAgentSettingsPath(){let t=await(Ot(),te(Lt)).getActiveProvider();return(Ot(),te(Lt)).getGlobalSettingsPath(t.name)}getClaudeDir(){return w.join(ye.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 Nr(t,e)}getWikiPathWithProjectHash(t,e){return Cr(t,e)}getLegacyWikiPath(t){return Ir(t)}async detectMonorepo(t){return ne(t)}async discoverMonorepoPackages(t,e){return ie(t,e)}async findContainingPackage(t,e){return _r(t,e)}async findMonorepoRoot(t){return vr(t)}},Ri=new Te,v=Ri});var Jr,zr=E(()=>{"use strict";Jr=`
15
15
  -- =======================================================================
16
16
  -- Document storage (backward-compatible with JSON file pattern)
17
17
  -- =======================================================================
@@ -557,39 +557,50 @@ CREATE TABLE velocity_sprints (
557
557
  dims INTEGER NOT NULL,
558
558
  created_at TEXT NOT NULL
559
559
  )
560
- `)},"up")}]});function bi(){return typeof globalThis<"u"&&"Bun"in globalThis?"bun":"node"}function Qr(){return bi()==="bun"}var Zr=E(()=>{"use strict";c(bi,"detectRuntime");c(Qr,"isBun")});function ts(s){let t=_i(s);return t.run("PRAGMA journal_mode = WAL"),t.run("PRAGMA busy_timeout = 5000"),t}function _i(s){if(Qr()){let{Database:n}=lr("bun:sqlite");return new n(s,{create:!0})}let t=lr("better-sqlite3"),e=new t(s),r=e.exec.bind(e);return e.run=n=>r(n),e}var es=E(()=>{"use strict";Zr();c(ts,"openDatabase");c(_i,"openRaw")});import yt from"node:fs";import rs from"node:path";function ss(s,t){let e=s.transaction(t);return typeof e.immediate=="function"?e.immediate(s):e(s)}var vi,Ee,k,y,j=E(()=>{"use strict";ot();Vr();es();c(ss,"runImmediate");vi=3,Ee=class{static{c(this,"PrjctDatabase")}connections=new Map;accessOrder=[];statementCache=new WeakMap;prepareCached(t,e){let r=this.statementCache.get(t);r||(r=new Map,this.statementCache.set(t,r));let n=r.get(e);if(n)return n;let i=t.prepare(e);return r.set(e,i),i}getDbPath(t){return rs.join(v.getGlobalProjectPath(t),"prjct.db")}getDb(t){let e=this.connections.get(t);if(e)return this.touchAccessOrder(t),e;this.connections.size>=vi&&this.evictLru();let r=this.getDbPath(t),n=rs.dirname(r);yt.existsSync(n)||yt.mkdirSync(n,{recursive:!0});let i=ts(r);return 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,r),this.connections.set(t,i),this.touchAccessOrder(t),i}close(t){if(t){let e=this.connections.get(t);e&&(this.statementCache.delete(e),e.close(),this.connections.delete(t),this.accessOrder=this.accessOrder.filter(r=>r!==t))}else this.connections.forEach(e=>{this.statementCache.delete(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&&(this.statementCache.delete(e),e.close(),this.connections.delete(t))}checkpointAll(){for(let[t,e]of this.connections)try{this.prepareCached(e,"PRAGMA wal_checkpoint(PASSIVE)").get()}catch{}}exists(t){return yt.existsSync(this.getDbPath(t))}getDoc(t,e){let r=this.getDb(t),n=this.prepareCached(r,"SELECT data FROM kv_store WHERE key = ?").get(e);return n?JSON.parse(n.data):null}setDoc(t,e,r){let n=this.getDb(t),i=JSON.stringify(r),o=new Date().toISOString();this.prepareCached(n,"INSERT OR REPLACE INTO kv_store (key, data, updated_at) VALUES (?, ?, ?)").run(e,i,o)}getDocWithStamp(t,e){let r=this.getDb(t),n=this.prepareCached(r,"SELECT data, updated_at FROM kv_store WHERE key = ?").get(e);return n?{data:JSON.parse(n.data),updatedAt:n.updated_at}:null}nextKvStamp(t,e){let r=this.prepareCached(t,"SELECT updated_at FROM kv_store WHERE key = ?").get(e),n=new Date().toISOString(),i=r?.updated_at;return!i||n>i?n:new Date(new Date(i).getTime()+1).toISOString()}casSetDoc(t,e,r,n){let i=this.getDb(t),o=JSON.stringify(r),a=this.nextKvStamp(i,e);return n===null?this.prepareCached(i,"INSERT INTO kv_store (key, data, updated_at) VALUES (?, ?, ?) ON CONFLICT(key) DO NOTHING").run(e,o,a).changes===1:this.prepareCached(i,"UPDATE kv_store SET data = ?, updated_at = ? WHERE key = ? AND updated_at = ?").run(o,a,e,n).changes===1}deleteDoc(t,e){let r=this.getDb(t);this.prepareCached(r,"DELETE FROM kv_store WHERE key = ?").run(e)}hasDoc(t,e){let r=this.getDb(t);return this.prepareCached(r,"SELECT 1 FROM kv_store WHERE key = ?").get(e)!==null}listDocsByPrefix(t,e){let r=this.getDb(t);return this.prepareCached(r,"SELECT key, data FROM kv_store WHERE key LIKE ? || '%' ORDER BY key").all(e).map(i=>({key:i.key,data:JSON.parse(i.data)}))}appendEvent(t,e,r,n){let i=this.getDb(t),o=new Date().toISOString(),u=this.prepareCached(i,"INSERT INTO events (type, task_id, data, timestamp) VALUES (?, ?, ?, ?)").run(e,n??null,JSON.stringify(r),o).lastInsertRowid;return typeof u=="bigint"?Number(u):u??null}getEvents(t,e,r=100){let n=this.getDb(t);return e?this.prepareCached(n,"SELECT * FROM events WHERE type = ? ORDER BY id DESC LIMIT ?").all(e,r):this.prepareCached(n,"SELECT * FROM events ORDER BY id DESC LIMIT ?").all(r)}query(t,e,...r){let n=this.getDb(t);return this.prepareCached(n,e).all(...r)}run(t,e,...r){let n=this.getDb(t);return this.prepareCached(n,e).run(...r)}get(t,e,...r){let n=this.getDb(t);return this.prepareCached(n,e).get(...r)??null}transaction(t,e){let r=this.getDb(t);return ss(r,e)}runMigrations(t,e){t.run(`
560
+ `)},"up")},{version:23,name:"memory-usefulness-ledger",up:c(s=>{s.run(`
561
+ CREATE TABLE IF NOT EXISTS memory_usefulness (
562
+ memory_id TEXT PRIMARY KEY,
563
+ score REAL NOT NULL DEFAULT 0,
564
+ ref_count INTEGER NOT NULL DEFAULT 0,
565
+ fetch_count INTEGER NOT NULL DEFAULT 0,
566
+ last_used_at TEXT NOT NULL
567
+ )
568
+ `)},"up")}]});function Pi(){return typeof globalThis<"u"&&"Bun"in globalThis?"bun":"node"}function Qr(){return Pi()==="bun"}var Zr=E(()=>{"use strict";c(Pi,"detectRuntime");c(Qr,"isBun")});function ts(s){let t=Ai(s);return t.run("PRAGMA journal_mode = WAL"),t.run("PRAGMA busy_timeout = 5000"),t}function Ai(s){if(Qr()){let{Database:n}=lr("bun:sqlite");return new n(s,{create:!0})}let t=lr("better-sqlite3"),e=new t(s),r=e.exec.bind(e);return e.run=n=>r(n),e}var es=E(()=>{"use strict";Zr();c(ts,"openDatabase");c(Ai,"openRaw")});import yt from"node:fs";import rs from"node:path";function ss(s,t){let e=s.transaction(t);return typeof e.immediate=="function"?e.immediate(s):e(s)}var Ni,Ee,k,y,M=E(()=>{"use strict";ot();Vr();es();c(ss,"runImmediate");Ni=3,Ee=class{static{c(this,"PrjctDatabase")}connections=new Map;accessOrder=[];statementCache=new WeakMap;prepareCached(t,e){let r=this.statementCache.get(t);r||(r=new Map,this.statementCache.set(t,r));let n=r.get(e);if(n)return n;let i=t.prepare(e);return r.set(e,i),i}getDbPath(t){return rs.join(v.getGlobalProjectPath(t),"prjct.db")}getDb(t){let e=this.connections.get(t);if(e)return this.touchAccessOrder(t),e;this.connections.size>=Ni&&this.evictLru();let r=this.getDbPath(t),n=rs.dirname(r);yt.existsSync(n)||yt.mkdirSync(n,{recursive:!0});let i=ts(r);return 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,r),this.connections.set(t,i),this.touchAccessOrder(t),i}close(t){if(t){let e=this.connections.get(t);e&&(this.statementCache.delete(e),e.close(),this.connections.delete(t),this.accessOrder=this.accessOrder.filter(r=>r!==t))}else this.connections.forEach(e=>{this.statementCache.delete(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&&(this.statementCache.delete(e),e.close(),this.connections.delete(t))}checkpointAll(){for(let[t,e]of this.connections)try{this.prepareCached(e,"PRAGMA wal_checkpoint(PASSIVE)").get()}catch{}}exists(t){return yt.existsSync(this.getDbPath(t))}getDoc(t,e){let r=this.getDb(t),n=this.prepareCached(r,"SELECT data FROM kv_store WHERE key = ?").get(e);return n?JSON.parse(n.data):null}setDoc(t,e,r){let n=this.getDb(t),i=JSON.stringify(r),o=new Date().toISOString();this.prepareCached(n,"INSERT OR REPLACE INTO kv_store (key, data, updated_at) VALUES (?, ?, ?)").run(e,i,o)}getDocWithStamp(t,e){let r=this.getDb(t),n=this.prepareCached(r,"SELECT data, updated_at FROM kv_store WHERE key = ?").get(e);return n?{data:JSON.parse(n.data),updatedAt:n.updated_at}:null}nextKvStamp(t,e){let r=this.prepareCached(t,"SELECT updated_at FROM kv_store WHERE key = ?").get(e),n=new Date().toISOString(),i=r?.updated_at;return!i||n>i?n:new Date(new Date(i).getTime()+1).toISOString()}casSetDoc(t,e,r,n){let i=this.getDb(t),o=JSON.stringify(r),a=this.nextKvStamp(i,e);return n===null?this.prepareCached(i,"INSERT INTO kv_store (key, data, updated_at) VALUES (?, ?, ?) ON CONFLICT(key) DO NOTHING").run(e,o,a).changes===1:this.prepareCached(i,"UPDATE kv_store SET data = ?, updated_at = ? WHERE key = ? AND updated_at = ?").run(o,a,e,n).changes===1}deleteDoc(t,e){let r=this.getDb(t);this.prepareCached(r,"DELETE FROM kv_store WHERE key = ?").run(e)}hasDoc(t,e){let r=this.getDb(t);return this.prepareCached(r,"SELECT 1 FROM kv_store WHERE key = ?").get(e)!==null}listDocsByPrefix(t,e){let r=this.getDb(t);return this.prepareCached(r,"SELECT key, data FROM kv_store WHERE key LIKE ? || '%' ORDER BY key").all(e).map(i=>({key:i.key,data:JSON.parse(i.data)}))}appendEvent(t,e,r,n){let i=this.getDb(t),o=new Date().toISOString(),u=this.prepareCached(i,"INSERT INTO events (type, task_id, data, timestamp) VALUES (?, ?, ?, ?)").run(e,n??null,JSON.stringify(r),o).lastInsertRowid;return typeof u=="bigint"?Number(u):u??null}getEvents(t,e,r=100){let n=this.getDb(t);return e?this.prepareCached(n,"SELECT * FROM events WHERE type = ? ORDER BY id DESC LIMIT ?").all(e,r):this.prepareCached(n,"SELECT * FROM events ORDER BY id DESC LIMIT ?").all(r)}query(t,e,...r){let n=this.getDb(t);return this.prepareCached(n,e).all(...r)}run(t,e,...r){let n=this.getDb(t);return this.prepareCached(n,e).run(...r)}get(t,e,...r){let n=this.getDb(t);return this.prepareCached(n,e).get(...r)??null}transaction(t,e){let r=this.getDb(t);return ss(r,e)}runMigrations(t,e){t.run(`
561
569
  CREATE TABLE IF NOT EXISTS _migrations (
562
570
  version INTEGER PRIMARY KEY,
563
571
  name TEXT NOT NULL,
564
572
  applied_at TEXT NOT NULL
565
573
  )
566
- `);let r=new Set(t.prepare("SELECT version FROM _migrations").all().map(i=>i.version)),n=Kr.filter(i=>!r.has(i.version));if(n.length!==0){if(e&&r.size>0)try{let i=`${e}.pre-migrate.bak`;yt.existsSync(i)&&yt.rmSync(i,{force:!0}),t.prepare("VACUUM INTO ?").run(i)}catch(i){console.warn(`prjct: pre-migration backup failed (continuing): ${i?.message??i}`)}for(let i of n)ss(t,()=>{i.up(t),t.prepare("INSERT INTO _migrations (version, name, applied_at) VALUES (?, ?, ?)").run(i.version,i.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 Ee,y=k});function Mi(s){return s instanceof _e}function ve(s){return Mi(s)||s instanceof Error?s.message:typeof s=="string"?s:"Unknown error"}var _e,ds=E(()=>{"use strict";_e=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(Mi,"isPrjctError");c(ve,"getErrorMessage")});import xe from"node:fs";import Ut from"node:path";function ms(){if(Et)return Et;let s=__dirname;for(let t=0;t<5;t++){let e=Ut.join(s,"package.json");if(xe.existsSync(e))try{if(JSON.parse(xe.readFileSync(e,"utf-8")).name==="prjct-cli")return Et=s,s}catch{}s=Ut.dirname(s)}return Et=Ut.join(__dirname,"..","..",".."),Et}function ji(){if(ct)return ct;let s=process.env.PRJCT_VERSION;if(s&&/^\d+\.\d+\.\d+/.test(s))return ct=s,ct;try{let t=Ut.join(ms(),"package.json");return ct=JSON.parse(xe.readFileSync(t,"utf-8")).version,ct}catch(t){return process.env.PRJCT_DEBUG==="1"&&console.error("Failed to read version from package.json:",hr(t)),"0.0.0"}}var ct,Et,Re,iu,gs=E(()=>{"use strict";Z();ct=null,Et=null;c(ms,"getPackageRoot");c(ji,"getVersion");Re=ji(),iu=ms()});async function $t(s){try{let{stdout:t}=await _(s,{timeout:5e3});return{success:!0,output:t.trim()}}catch{return{success:!1,output:""}}}async function Fi(){let s=await $t("gh api user --jq .login");return s.success&&s.output||(s=await $t("git config --global github.user"),s.success&&s.output)?s.output:null}async function Ui(){let s=await $t("git config user.name");return s.success&&s.output?s.output:null}async function $i(){let s=await $t("git config user.email");return s.success&&s.output?s.output:null}async function fs(){let[s,t,e]=await Promise.all([Fi(),Ui(),$i()]);return{github:s,email:e,name:t||s||"Unknown"}}var hs=E(()=>{"use strict";it();c($t,"execCommand");c(Fi,"detectGitHubUsername");c(Ui,"detectGitName");c($i,"detectGitEmail");c(fs,"detect")});var Ts={};Q(Ts,{default:()=>B});import Pe from"node:fs/promises";import Wi from"node:path";import*as Xt from"jsonc-parser";function ys(s){let t=[],e=Xt.parse(s,t,{allowTrailingComma:!0,disallowComments:!1});if(t.length>0){let r=t[0];throw new SyntaxError(`JSON parse error at offset ${r.offset}: ${Xt.printParseErrorCode(r.error)}`)}return e}var Ae,Bi,B,kt=E(()=>{"use strict";ds();Z();N();U();gs();hs();ot();c(ys,"parseJsonc");Ae=class{static{c(this,"ConfigManager")}async readConfig(t){try{let e=v.getLocalConfigPath(t),r=await Pe.readFile(e,"utf-8");return ys(r)}catch(e){return O(e)||console.warn(`Warning: Could not read config at ${t}: ${ve(e)}`),null}}async writeConfig(t,e){let r=v.getLocalConfigPath(t);await F(r,e)}async readGlobalConfig(t){try{let e=v.getGlobalProjectConfigPath(t),r=await Pe.readFile(e,"utf-8");return ys(r)}catch(e){return O(e)||console.warn(`Warning: Could not read global config for ${t}: ${ve(e)}`),null}}async writeGlobalConfig(t,e){let r=v.getGlobalProjectConfigPath(t);await F(r,e)}async ensureGlobalConfig(t){let e=await this.readGlobalConfig(t);if(!e){let r=g();e={projectId:t,authors:[],version:Re,lastSync:r},await this.writeGlobalConfig(t,e)}return e}async createConfig(t,e){let r=v.generateProjectId(t),n=v.getGlobalProjectPath(r),i=v.getDisplayPath(n),o=g(),a={projectId:r,dataPath:i,showMetrics:!0};await this.writeConfig(t,a);let u={projectId:r,authors:[{name:e.name||"Unknown",email:e.email||"",github:e.github||"",firstContribution:o,lastActivity:o}],version:Re,created:o,lastSync:o};return await this.writeGlobalConfig(r,u),a}async updateLastSync(t){let e=await this.getProjectId(t),r=await this.readGlobalConfig(e);r&&(r.lastSync=g(),await this.writeGlobalConfig(e,r))}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 Pe.readdir(Wi.join(i,"core"))).length===0}catch(o){return O(o),!0}}async getProjectId(t){let e=await this.readConfig(t);if(e?.projectId)return e.projectId;try{let{worktreeService:r}=await Promise.resolve().then(()=>(ue(),ce));if(await r.detect(t)){let i=await r.getMainWorktree(t);if(i!==t){let o=await this.readConfig(i);if(o?.projectId)return o.projectId}}}catch{}return""}async findAuthor(t,e){let r=await this.readGlobalConfig(t);return!r||!r.authors?null:r.authors.find(n=>n.github===e)||null}async addAuthor(t,e){let r=await this.ensureGlobalConfig(t);if(r.authors.some(o=>o.github===e.github))return;let i=g();r.authors.push({name:e.name||"Unknown",email:e.email||"",github:e.github||"",firstContribution:i,lastActivity:i}),r.lastSync=i,await this.writeGlobalConfig(t,r)}async updateAuthorActivity(t,e){let r=await this.readGlobalConfig(t);if(!r||!r.authors)return;let n=r.authors.find(i=>i.github===e);n&&(n.lastActivity=g(),r.lastSync=n.lastActivity,await this.writeGlobalConfig(t,r))}async getCurrentAuthor(t){let e=await fs(),r=await this.getProjectId(t);return await this.addAuthor(r,{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 r=await this.readConfig(t);r&&(r.showMetrics=e,await this.writeConfig(t,r))}async getConfigWithDefaults(t){let e=await this.readConfig(t);if(e)return e;let r=v.generateProjectId(t);return{projectId:r,dataPath:v.getDisplayPath(v.getGlobalProjectPath(r))}}},Bi=new Ae,B=Bi});import{z as p}from"zod";var qi,Wt,Gi,Yi,Ne,Ss,ws,bs,_s,ks,Ji,zi,Ki,vs,Vi,xs,Bt=E(()=>{"use strict";de();qi=p.enum(["low","medium","high","critical"]),Wt=p.enum(["feature","bug","improvement","chore"]),Gi=p.enum(["active","backlog","previously_active"]),Yi=p.enum(["pending","in_progress","completed","blocked","paused","failed","skipped"]),Ne=p.object({title:p.string(),description:p.string(),filesChanged:p.array(p.object({path:p.string(),action:p.enum(["created","modified","deleted"])})),whatWasDone:p.array(p.string()).min(1),outputForNextAgent:p.string().min(1),notes:p.string().optional()}),Ss=p.object({output:p.string().min(1,"Subtask output is required"),summary:Ne}),ws=p.object({id:p.string(),description:p.string(),domain:p.string(),agent:p.string(),status:Yi,dependsOn:p.array(p.string()),startedAt:p.string().optional(),completedAt:p.string().optional(),output:p.string().optional(),summary:Ne.optional(),skipReason:p.string().optional(),blockReason:p.string().optional(),estimatedPoints:p.number().optional(),estimatedMinutes:p.number().optional()}),bs=p.object({completed:p.number(),total:p.number(),percentage:p.number()}),_s=p.object({id:p.string(),description:p.string(),type:Wt.optional(),startedAt:p.string(),sessionId:p.string(),featureId:p.string().optional(),subtasks:p.array(ws).optional(),currentSubtaskIndex:p.number().optional(),subtaskProgress:bs.optional(),linearId:p.string().optional(),linearUuid:p.string().optional(),linkedSpecId:p.string().optional(),estimatedPoints:p.number().optional(),estimatedMinutes:p.number().optional(),modelMetadata:pe.optional(),tokensIn:p.number().optional(),tokensOut:p.number().optional(),parentDescription:p.string().optional(),branch:p.string().optional(),prUrl:p.string().optional()}),ks=p.object({id:p.string(),description:p.string(),status:p.literal("paused"),startedAt:p.string(),pausedAt:p.string(),pauseReason:p.string().optional(),type:Wt.optional(),sessionId:p.string().optional(),featureId:p.string().optional(),subtasks:p.array(ws).optional(),currentSubtaskIndex:p.number().optional(),subtaskProgress:bs.optional(),linearId:p.string().optional(),linearUuid:p.string().optional(),estimatedPoints:p.number().optional(),estimatedMinutes:p.number().optional(),modelMetadata:pe.optional(),tokensIn:p.number().optional(),tokensOut:p.number().optional()}),Ji=p.object({stackConfirmed:p.array(p.string()).optional(),patternsDiscovered:p.array(p.string()).optional(),agentAccuracy:p.array(p.object({agent:p.string(),rating:p.enum(["helpful","neutral","inaccurate"]),note:p.string().optional()})).optional(),issuesEncountered:p.array(p.string()).optional()}),zi=p.object({taskId:p.string(),title:p.string(),classification:Wt,startedAt:p.string(),completedAt:p.string(),subtaskCount:p.number(),subtaskSummaries:p.array(Ne),outcome:p.string(),branchName:p.string(),linearId:p.string().optional(),linearUuid:p.string().optional(),prUrl:p.string().optional(),feedback:Ji.optional(),tokensIn:p.number().optional(),tokensOut:p.number().optional()}),Ki=_s.extend({workspaceId:p.string(),worktreePath:p.string().optional(),agentSessionId:p.string().optional(),jiraId:p.string().optional(),jiraUuid:p.string().optional(),dispatchedFrom:p.string().optional()}),vs=p.object({currentTask:_s.nullable(),previousTask:ks.nullable().optional(),pausedTasks:p.array(ks).optional(),taskHistory:p.array(zi).optional(),activeTasks:p.array(Ki).optional(),lastUpdated:p.string()}),Vi=p.object({id:p.string(),description:p.string(),body:p.string().optional(),priority:qi,type:Wt,featureId:p.string().optional(),originFeature:p.string().optional(),completed:p.boolean(),completedAt:p.string().optional(),createdAt:p.string(),section:Gi,agent:p.string().optional(),groupName:p.string().optional(),groupId:p.string().optional()}),xs=p.object({tasks:p.array(Vi),lastUpdated:p.string()})});import Qi from"node:crypto";function H(){return Qi.randomUUID()}var wt=E(()=>{"use strict";c(H,"generateUUID")});var De,et,Rs=E(()=>{"use strict";N();j();De=class{static{c(this,"SyncPendingStorage")}append(t,e){let r=g(),n=JSON.stringify(e);return e.entityType&&e.entityId&&e.contentHash&&y.run(t,`DELETE FROM sync_pending
574
+ `);let r=new Set(t.prepare("SELECT version FROM _migrations").all().map(i=>i.version)),n=Kr.filter(i=>!r.has(i.version));if(n.length!==0){if(e&&r.size>0)try{let i=`${e}.pre-migrate.bak`;yt.existsSync(i)&&yt.rmSync(i,{force:!0}),t.prepare("VACUUM INTO ?").run(i)}catch(i){console.warn(`prjct: pre-migration backup failed (continuing): ${i?.message??i}`)}for(let i of n)ss(t,()=>{i.up(t),t.prepare("INSERT INTO _migrations (version, name, applied_at) VALUES (?, ?, ?)").run(i.version,i.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 Ee,y=k});function Xi(s){return s instanceof _e}function ve(s){return Xi(s)||s instanceof Error?s.message:typeof s=="string"?s:"Unknown error"}var _e,ds=E(()=>{"use strict";_e=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(Xi,"isPrjctError");c(ve,"getErrorMessage")});import xe from"node:fs";import Ut from"node:path";function ms(){if(Et)return Et;let s=__dirname;for(let t=0;t<5;t++){let e=Ut.join(s,"package.json");if(xe.existsSync(e))try{if(JSON.parse(xe.readFileSync(e,"utf-8")).name==="prjct-cli")return Et=s,s}catch{}s=Ut.dirname(s)}return Et=Ut.join(__dirname,"..","..",".."),Et}function Wi(){if(ct)return ct;let s=process.env.PRJCT_VERSION;if(s&&/^\d+\.\d+\.\d+/.test(s))return ct=s,ct;try{let t=Ut.join(ms(),"package.json");return ct=JSON.parse(xe.readFileSync(t,"utf-8")).version,ct}catch(t){return process.env.PRJCT_DEBUG==="1"&&console.error("Failed to read version from package.json:",hr(t)),"0.0.0"}}var ct,Et,Re,hu,gs=E(()=>{"use strict";Z();ct=null,Et=null;c(ms,"getPackageRoot");c(Wi,"getVersion");Re=Wi(),hu=ms()});async function $t(s){try{let{stdout:t}=await _(s,{timeout:5e3});return{success:!0,output:t.trim()}}catch{return{success:!1,output:""}}}async function Bi(){let s=await $t("gh api user --jq .login");return s.success&&s.output||(s=await $t("git config --global github.user"),s.success&&s.output)?s.output:null}async function Hi(){let s=await $t("git config user.name");return s.success&&s.output?s.output:null}async function qi(){let s=await $t("git config user.email");return s.success&&s.output?s.output:null}async function fs(){let[s,t,e]=await Promise.all([Bi(),Hi(),qi()]);return{github:s,email:e,name:t||s||"Unknown"}}var hs=E(()=>{"use strict";it();c($t,"execCommand");c(Bi,"detectGitHubUsername");c(Hi,"detectGitName");c(qi,"detectGitEmail");c(fs,"detect")});var Ts={};K(Ts,{default:()=>B});import Pe from"node:fs/promises";import Yi from"node:path";import*as Xt from"jsonc-parser";function ys(s){let t=[],e=Xt.parse(s,t,{allowTrailingComma:!0,disallowComments:!1});if(t.length>0){let r=t[0];throw new SyntaxError(`JSON parse error at offset ${r.offset}: ${Xt.printParseErrorCode(r.error)}`)}return e}var Ae,Ji,B,kt=E(()=>{"use strict";ds();Z();N();U();gs();hs();ot();c(ys,"parseJsonc");Ae=class{static{c(this,"ConfigManager")}async readConfig(t){try{let e=v.getLocalConfigPath(t),r=await Pe.readFile(e,"utf-8");return ys(r)}catch(e){return O(e)||console.warn(`Warning: Could not read config at ${t}: ${ve(e)}`),null}}async writeConfig(t,e){let r=v.getLocalConfigPath(t);await F(r,e)}async readGlobalConfig(t){try{let e=v.getGlobalProjectConfigPath(t),r=await Pe.readFile(e,"utf-8");return ys(r)}catch(e){return O(e)||console.warn(`Warning: Could not read global config for ${t}: ${ve(e)}`),null}}async writeGlobalConfig(t,e){let r=v.getGlobalProjectConfigPath(t);await F(r,e)}async ensureGlobalConfig(t){let e=await this.readGlobalConfig(t);if(!e){let r=g();e={projectId:t,authors:[],version:Re,lastSync:r},await this.writeGlobalConfig(t,e)}return e}async createConfig(t,e){let r=v.generateProjectId(t),n=v.getGlobalProjectPath(r),i=v.getDisplayPath(n),o=g(),a={projectId:r,dataPath:i,showMetrics:!0};await this.writeConfig(t,a);let u={projectId:r,authors:[{name:e.name||"Unknown",email:e.email||"",github:e.github||"",firstContribution:o,lastActivity:o}],version:Re,created:o,lastSync:o};return await this.writeGlobalConfig(r,u),a}async updateLastSync(t){let e=await this.getProjectId(t),r=await this.readGlobalConfig(e);r&&(r.lastSync=g(),await this.writeGlobalConfig(e,r))}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 Pe.readdir(Yi.join(i,"core"))).length===0}catch(o){return O(o),!0}}async getProjectId(t){let e=await this.readConfig(t);if(e?.projectId)return e.projectId;try{let{worktreeService:r}=await Promise.resolve().then(()=>(ue(),ce));if(await r.detect(t)){let i=await r.getMainWorktree(t);if(i!==t){let o=await this.readConfig(i);if(o?.projectId)return o.projectId}}}catch{}return""}async findAuthor(t,e){let r=await this.readGlobalConfig(t);return!r||!r.authors?null:r.authors.find(n=>n.github===e)||null}async addAuthor(t,e){let r=await this.ensureGlobalConfig(t);if(r.authors.some(o=>o.github===e.github))return;let i=g();r.authors.push({name:e.name||"Unknown",email:e.email||"",github:e.github||"",firstContribution:i,lastActivity:i}),r.lastSync=i,await this.writeGlobalConfig(t,r)}async updateAuthorActivity(t,e){let r=await this.readGlobalConfig(t);if(!r||!r.authors)return;let n=r.authors.find(i=>i.github===e);n&&(n.lastActivity=g(),r.lastSync=n.lastActivity,await this.writeGlobalConfig(t,r))}async getCurrentAuthor(t){let e=await fs(),r=await this.getProjectId(t);return await this.addAuthor(r,{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 r=await this.readConfig(t);r&&(r.showMetrics=e,await this.writeConfig(t,r))}async getConfigWithDefaults(t){let e=await this.readConfig(t);if(e)return e;let r=v.generateProjectId(t);return{projectId:r,dataPath:v.getDisplayPath(v.getGlobalProjectPath(r))}}},Ji=new Ae,B=Ji});import{z as p}from"zod";var Ki,Wt,Vi,Qi,Ne,Ss,ws,bs,_s,ks,Zi,to,eo,vs,ro,xs,Bt=E(()=>{"use strict";de();Ki=p.enum(["low","medium","high","critical"]),Wt=p.enum(["feature","bug","improvement","chore"]),Vi=p.enum(["active","backlog","previously_active"]),Qi=p.enum(["pending","in_progress","completed","blocked","paused","failed","skipped"]),Ne=p.object({title:p.string(),description:p.string(),filesChanged:p.array(p.object({path:p.string(),action:p.enum(["created","modified","deleted"])})),whatWasDone:p.array(p.string()).min(1),outputForNextAgent:p.string().min(1),notes:p.string().optional()}),Ss=p.object({output:p.string().min(1,"Subtask output is required"),summary:Ne}),ws=p.object({id:p.string(),description:p.string(),domain:p.string(),agent:p.string(),status:Qi,dependsOn:p.array(p.string()),startedAt:p.string().optional(),completedAt:p.string().optional(),output:p.string().optional(),summary:Ne.optional(),skipReason:p.string().optional(),blockReason:p.string().optional(),estimatedPoints:p.number().optional(),estimatedMinutes:p.number().optional()}),bs=p.object({completed:p.number(),total:p.number(),percentage:p.number()}),_s=p.object({id:p.string(),description:p.string(),type:Wt.optional(),startedAt:p.string(),sessionId:p.string(),featureId:p.string().optional(),subtasks:p.array(ws).optional(),currentSubtaskIndex:p.number().optional(),subtaskProgress:bs.optional(),linearId:p.string().optional(),linearUuid:p.string().optional(),linkedSpecId:p.string().optional(),estimatedPoints:p.number().optional(),estimatedMinutes:p.number().optional(),modelMetadata:pe.optional(),tokensIn:p.number().optional(),tokensOut:p.number().optional(),parentDescription:p.string().optional(),branch:p.string().optional(),prUrl:p.string().optional()}),ks=p.object({id:p.string(),description:p.string(),status:p.literal("paused"),startedAt:p.string(),pausedAt:p.string(),pauseReason:p.string().optional(),type:Wt.optional(),sessionId:p.string().optional(),featureId:p.string().optional(),subtasks:p.array(ws).optional(),currentSubtaskIndex:p.number().optional(),subtaskProgress:bs.optional(),linearId:p.string().optional(),linearUuid:p.string().optional(),estimatedPoints:p.number().optional(),estimatedMinutes:p.number().optional(),modelMetadata:pe.optional(),tokensIn:p.number().optional(),tokensOut:p.number().optional()}),Zi=p.object({stackConfirmed:p.array(p.string()).optional(),patternsDiscovered:p.array(p.string()).optional(),agentAccuracy:p.array(p.object({agent:p.string(),rating:p.enum(["helpful","neutral","inaccurate"]),note:p.string().optional()})).optional(),issuesEncountered:p.array(p.string()).optional()}),to=p.object({taskId:p.string(),title:p.string(),classification:Wt,startedAt:p.string(),completedAt:p.string(),subtaskCount:p.number(),subtaskSummaries:p.array(Ne),outcome:p.string(),branchName:p.string(),linearId:p.string().optional(),linearUuid:p.string().optional(),prUrl:p.string().optional(),feedback:Zi.optional(),tokensIn:p.number().optional(),tokensOut:p.number().optional()}),eo=_s.extend({workspaceId:p.string(),worktreePath:p.string().optional(),agentSessionId:p.string().optional(),jiraId:p.string().optional(),jiraUuid:p.string().optional(),dispatchedFrom:p.string().optional()}),vs=p.object({currentTask:_s.nullable(),previousTask:ks.nullable().optional(),pausedTasks:p.array(ks).optional(),taskHistory:p.array(to).optional(),activeTasks:p.array(eo).optional(),lastUpdated:p.string()}),ro=p.object({id:p.string(),description:p.string(),body:p.string().optional(),priority:Ki,type:Wt,featureId:p.string().optional(),originFeature:p.string().optional(),completed:p.boolean(),completedAt:p.string().optional(),createdAt:p.string(),section:Vi,agent:p.string().optional(),groupName:p.string().optional(),groupId:p.string().optional()}),xs=p.object({tasks:p.array(ro),lastUpdated:p.string()})});import so from"node:crypto";function H(){return so.randomUUID()}var wt=E(()=>{"use strict";c(H,"generateUUID")});var De,et,Rs=E(()=>{"use strict";N();M();De=class{static{c(this,"SyncPendingStorage")}append(t,e){let r=g(),n=JSON.stringify(e);return e.entityType&&e.entityId&&e.contentHash&&y.run(t,`DELETE FROM sync_pending
567
575
  WHERE project_id = ?
568
576
  AND entity_type = ?
569
577
  AND entity_id = ?
570
578
  AND content_hash = ?`,t,e.entityType,e.entityId,e.contentHash),y.run(t,`INSERT INTO sync_pending
571
579
  (project_id, entity_type, entity_id, event_type, content_hash, payload, enqueued_at)
572
- VALUES (?, ?, ?, ?, ?, ?, ?)`,t,e.entityType??null,e.entityId??null,e.eventType??null,e.contentHash??null,n,r),{id:y.get(t,"SELECT last_insert_rowid() AS id")?.id??0,event:e,enqueuedAt:r}}list(t,e){let r=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?y.query(t,r,t,e):y.query(t,r,t)).map(i=>this.rowToEntry(i))}count(t){return y.get(t,"SELECT COUNT(*) AS n FROM sync_pending WHERE project_id = ?",t)?.n??0}clearUpTo(t,e){if(e<=0)return 0;let r=this.count(t);return y.run(t,"DELETE FROM sync_pending WHERE project_id = ? AND id <= ?",t,e),r-this.count(t)}clearAll(t){y.run(t,"DELETE FROM sync_pending WHERE project_id = ?",t)}clearByIds(t,e){if(e.length===0)return;let r=e.map(()=>"?").join(",");y.run(t,`DELETE FROM sync_pending WHERE project_id = ? AND id IN (${r})`,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}}},et=new De});var Le,Ht,Oe=E(()=>{"use strict";ot();Rs();N();U();Le=class{static{c(this,"SyncEventBus")}async publish(t){et.append(t.projectId,t)}async getPending(t){return et.list(t).map(e=>e.event)}async clearPending(t){et.clearAll(t)}async getPendingEntries(t){return et.list(t)}async clearPendingUpTo(t,e){return et.clearUpTo(t,e)}async clearPendingByIds(t,e){et.clearByIds(t,e)}async updateLastSync(t){let e=v.getLastSyncPath(t),r={timestamp:g(),success:!0};await F(e,r)}async getLastSync(t){let e=v.getLastSyncPath(t);return await Nt(e,null)}},Ht=new Le});var je={};Q(je,{default:()=>ro});import Zi from"node:crypto";import Ps from"node:fs/promises";import As from"node:os";import to from"node:path";function Cs(){return Zi.randomUUID()}var Is,Ns,Me,eo,ro,Fe=E(()=>{"use strict";ot();U();Is="https://api.prjct.app",Ns={apiKey:null,apiUrl:Is,userId:null,email:null,lastAuth:null};c(Cs,"freshDeviceId");Me=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 Nt(this.configPath),e=t??{...Ns},r=!1;if(e.deviceId||(e.deviceId=Cs(),r=!0),e.hostname||(e.hostname=As.hostname(),r=!0),this.cachedConfig=e,r&&t)try{await F(this.configPath,this.cachedConfig),await Ps.chmod(this.configPath,384)}catch{}return this.cachedConfig}async getDeviceId(){return(await this.read()).deviceId??Cs()}async getHostname(){return(await this.read()).hostname??As.hostname()}async write(t){let r={...await this.read(),...t,lastAuth:new Date().toISOString()};await G(to.dirname(this.configPath)),await F(this.configPath,r),await Ps.chmod(this.configPath,384),this.cachedConfig=r}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||Is}async saveAuth(t,e,r){await this.write({apiKey:t,userId:e,email:r})}async clearAuth(){this.cachedConfig={...Ns},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}},eo=new Me,ro=eo});var Ls={};Q(Ls,{publishCRUD:()=>Ds,publishCRUDSync:()=>q});import so from"node:crypto";function io(s){let t=s&&typeof s=="object"&&!Array.isArray(s)?JSON.stringify(oo(s)):JSON.stringify(s);return so.createHash("sha256").update(t).digest("hex")}function oo(s){let t={};for(let e of Object.keys(s).sort())t[e]=s[e];return t}async function ao(){if(Ue)return Ue;try{let{default:s}=await Promise.resolve().then(()=>(Fe(),je)),t=s;if(typeof t.getDeviceId=="function"){let e=await t.getDeviceId();return Ue=e,e}return"unknown-device"}catch{return"unknown-device"}}async function Ds(s){try{let t=await ao(),e=io(s.data),r={type:`${s.entityType}.${no[s.eventType]}`,path:[s.entityType,s.entityId],data:s.data,timestamp:new Date().toISOString(),projectId:s.projectId,entityType:s.entityType,entityId:s.entityId,eventType:s.eventType,contentHash:e,deviceId:t,originDeviceId:s.originDeviceId??t,revisionCount:s.revisionCount??1};await Ht.publish(r)}catch{}}function q(s){Ds(s)}var no,Ue,bt=E(()=>{"use strict";Oe();no={upsert:"updated",delete:"deleted"};c(io,"hashPayload");c(oo,"sortKeys");Ue=null;c(ao,"resolveDeviceId");c(Ds,"publishCRUD");c(q,"publishCRUDSync")});var _t,$e,ut,qt=E(()=>{"use strict";wt();bt();N();j();_t={SHIPPED_RETENTION_DAYS:90,IDEA_DORMANT_DAYS:180,QUEUE_COMPLETED_DAYS:7,PAUSED_TASK_DAYS:30,MEMORY_MAX_ENTRIES:500},$e=class{static{c(this,"ArchiveStorage")}archive(t,e){let r=H(),n=g();return k.run(t,"INSERT INTO archives (id, entity_type, entity_id, entity_data, summary, archived_at, reason) VALUES (?, ?, ?, ?, ?, ?, ?)",r,e.entityType,e.entityId,JSON.stringify(e.entityData),e.summary??null,n,e.reason),q({projectId:t,entityType:"archives",entityId:r,eventType:"upsert",data:{id:r,entity_type:e.entityType,entity_id:e.entityId,summary:e.summary??null,reason:e.reason,archived_at:n}}),r}archiveMany(t,e){if(e.length===0)return 0;let r=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,r,o.reason)}),e.length}getArchived(t,e,r=50){return e?k.query(t,"SELECT * FROM archives WHERE entity_type = ? ORDER BY archived_at DESC LIMIT ?",e,r):k.query(t,"SELECT * FROM archives ORDER BY archived_at DESC LIMIT ?",r)}getStats(t){let e=k.query(t,"SELECT entity_type, COUNT(*) as count FROM archives GROUP BY entity_type"),r={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 r&&(r[i]=n.count),r.total+=n.count}return r}restore(t,e){let r=k.get(t,"SELECT * FROM archives WHERE id = ?",e);return r?(k.run(t,"DELETE FROM archives WHERE id = ?",e),JSON.parse(r.entity_data)):null}pruneOldArchives(t,e){let r=new Date(Date.now()-e*24*60*60*1e3).toISOString(),n=this.getTotalCount(t);k.run(t,"DELETE FROM archives WHERE archived_at < ?",r);let i=this.getTotalCount(t);return n-i}getTotalCount(t){return k.get(t,"SELECT COUNT(*) as count FROM archives")?.count??0}},ut=new $e});import mo from"node:crypto";function go(s){let[t,e]=s.split(".");return t?{entityType:t.endsWith("s")?t:`${t}s`,eventType:e==="deleted"||e==="archived"||e==="removed"?"delete":"upsert"}:{}}function fo(s){if(!s||typeof s!="object")return;let t=s;for(let e of["taskId","task_id","id","feature_id","featureId","specId","spec_id"]){let r=t[e];if(typeof r=="string"&&r.length>0)return r}}function ho(s){let t=s&&typeof s=="object"&&!Array.isArray(s)?JSON.stringify(yo(s)):JSON.stringify(s);return mo.createHash("sha256").update(t).digest("hex")}function yo(s){let t={};for(let e of Object.keys(s).sort())t[e]=s[e];return t}async function To(){if(Gt)return Gt;try{let{default:s}=await Promise.resolve().then(()=>(Fe(),je)),t=s;return typeof t.getDeviceId=="function"?(Gt=await t.getDeviceId(),Gt):"unknown-device"}catch{return"unknown-device"}}var Gt,lt,Be=E(()=>{"use strict";Oe();me();N();j();c(go,"deriveEntityShape");c(fo,"entityIdOf");c(ho,"hashPayload");c(yo,"sortKeys");Gt=null;c(To,"_resolveDeviceId");lt=class{static{c(this,"StorageManager")}filename;cache;constructor(t,e){this.filename=t,this.cache=new It({ttl:5e3,maxSize:50})}getStoreKey(){return this.filename.replace(".json","")}async read(t){if(!(process.env.PRJCT_IN_DAEMON==="1")){let r=this.cache.get(t);if(r!==null)return r}try{let r=k.getDoc(t,this.getStoreKey());if(r!==null)return this.cache.set(t,r),r}catch{}return this.getDefault()}async write(t,e){k.setDoc(t,this.getStoreKey(),e),this.cache.set(t,e)}async update(t,e){let r=this.getStoreKey(),n=8;for(let i=1;i<=n;i++){let o=k.getDocWithStamp(t,r),a=o?o.data:this.getDefault(),u=e(a);if(k.casSetDoc(t,r,u,o?.updatedAt??null))return this.cache.set(t,u),u}throw new Error(`StorageManager.update: unresolved write contention after ${n} attempts (key=${r})`)}async publishEvent(t,e,r){let n=go(e),i={type:e,path:[this.filename.replace(".json","")],data:r,timestamp:g(),projectId:t,entityType:n.entityType,entityId:fo(r),eventType:n.eventType,contentHash:ho(r),deviceId:await To(),revisionCount:1};await Ht.publish(i)}async publishEntityEvent(t,e,r,n){let i=`${e}.${r}`,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 dn,mn,gn,fn,hn=E(()=>{"use strict";dn={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"]},mn=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".py",".go",".rs",".java",".kt",".swift",".rb",".php",".c",".cpp",".h",".hpp",".cs",".vue",".svelte"]),gn=new Set(["node_modules",".git","dist","build",".next",".nuxt",".output","coverage",".cache","__pycache__",".pytest_cache","vendor","target",".turbo",".vercel"]),fn=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 Eo from"node:fs/promises";import Yt from"node:path";async function Jt(s,t,e={}){let r=Date.now(),n=e.maxFiles??30,i=e.minScore??.1,o=e.includeTests??!1,a=ko(s),u=await So(t),l=await wo(t),d=[];for(let f of u){if(!o&&_o(f))continue;let T=bo(f,a,l,e.historicalBoosts);T.score>=i&&d.push(T)}d.sort((f,T)=>T.score-f.score);let m=d.slice(0,n);return{files:m,metrics:{filesScanned:u.length,filesReturned:m.length,scanDuration:Date.now()-r}}}function ko(s){return s.toLowerCase().split(/[^a-z0-9]+/).filter(Boolean).filter(e=>!fn.has(e)&&e.length>2)}async function So(s){let t=[];async function e(r,n=""){try{let i=await Eo.readdir(r,{withFileTypes:!0});for(let o of i){let a=Yt.join(r,o.name),u=Yt.join(n,o.name);if(o.isDirectory()){if(gn.has(o.name)||o.name.startsWith("."))continue;await e(a,u)}else if(o.isFile()){let l=Yt.extname(o.name).toLowerCase();mn.has(l)&&t.push(u)}}}catch(i){O(i)}}return c(e,"walk"),await e(s),t}async function wo(s){let t=new Map;try{let{stdout:e}=await _(`git log -30 --pretty=format:"%H %ct" --name-only | awk '
580
+ VALUES (?, ?, ?, ?, ?, ?, ?)`,t,e.entityType??null,e.entityId??null,e.eventType??null,e.contentHash??null,n,r),{id:y.get(t,"SELECT last_insert_rowid() AS id")?.id??0,event:e,enqueuedAt:r}}list(t,e){let r=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?y.query(t,r,t,e):y.query(t,r,t)).map(i=>this.rowToEntry(i))}count(t){return y.get(t,"SELECT COUNT(*) AS n FROM sync_pending WHERE project_id = ?",t)?.n??0}clearUpTo(t,e){if(e<=0)return 0;let r=this.count(t);return y.run(t,"DELETE FROM sync_pending WHERE project_id = ? AND id <= ?",t,e),r-this.count(t)}clearAll(t){y.run(t,"DELETE FROM sync_pending WHERE project_id = ?",t)}clearByIds(t,e){if(e.length===0)return;let r=e.map(()=>"?").join(",");y.run(t,`DELETE FROM sync_pending WHERE project_id = ? AND id IN (${r})`,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}}},et=new De});var Le,Ht,Oe=E(()=>{"use strict";ot();Rs();N();U();Le=class{static{c(this,"SyncEventBus")}async publish(t){et.append(t.projectId,t)}async getPending(t){return et.list(t).map(e=>e.event)}async clearPending(t){et.clearAll(t)}async getPendingEntries(t){return et.list(t)}async clearPendingUpTo(t,e){return et.clearUpTo(t,e)}async clearPendingByIds(t,e){et.clearByIds(t,e)}async updateLastSync(t){let e=v.getLastSyncPath(t),r={timestamp:g(),success:!0};await F(e,r)}async getLastSync(t){let e=v.getLastSyncPath(t);return await Nt(e,null)}},Ht=new Le});var je={};K(je,{default:()=>ao});import no from"node:crypto";import Ps from"node:fs/promises";import As from"node:os";import io from"node:path";function Cs(){return no.randomUUID()}var Is,Ns,Me,oo,ao,Fe=E(()=>{"use strict";ot();U();Is="https://api.prjct.app",Ns={apiKey:null,apiUrl:Is,userId:null,email:null,lastAuth:null};c(Cs,"freshDeviceId");Me=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 Nt(this.configPath),e=t??{...Ns},r=!1;if(e.deviceId||(e.deviceId=Cs(),r=!0),e.hostname||(e.hostname=As.hostname(),r=!0),this.cachedConfig=e,r&&t)try{await F(this.configPath,this.cachedConfig),await Ps.chmod(this.configPath,384)}catch{}return this.cachedConfig}async getDeviceId(){return(await this.read()).deviceId??Cs()}async getHostname(){return(await this.read()).hostname??As.hostname()}async write(t){let r={...await this.read(),...t,lastAuth:new Date().toISOString()};await G(io.dirname(this.configPath)),await F(this.configPath,r),await Ps.chmod(this.configPath,384),this.cachedConfig=r}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||Is}async saveAuth(t,e,r){await this.write({apiKey:t,userId:e,email:r})}async clearAuth(){this.cachedConfig={...Ns},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}},oo=new Me,ao=oo});var Ls={};K(Ls,{publishCRUD:()=>Ds,publishCRUDSync:()=>q});import co from"node:crypto";function lo(s){let t=s&&typeof s=="object"&&!Array.isArray(s)?JSON.stringify(po(s)):JSON.stringify(s);return co.createHash("sha256").update(t).digest("hex")}function po(s){let t={};for(let e of Object.keys(s).sort())t[e]=s[e];return t}async function mo(){if(Ue)return Ue;try{let{default:s}=await Promise.resolve().then(()=>(Fe(),je)),t=s;if(typeof t.getDeviceId=="function"){let e=await t.getDeviceId();return Ue=e,e}return"unknown-device"}catch{return"unknown-device"}}async function Ds(s){try{let t=await mo(),e=lo(s.data),r={type:`${s.entityType}.${uo[s.eventType]}`,path:[s.entityType,s.entityId],data:s.data,timestamp:new Date().toISOString(),projectId:s.projectId,entityType:s.entityType,entityId:s.entityId,eventType:s.eventType,contentHash:e,deviceId:t,originDeviceId:s.originDeviceId??t,revisionCount:s.revisionCount??1};await Ht.publish(r)}catch{}}function q(s){Ds(s)}var uo,Ue,bt=E(()=>{"use strict";Oe();uo={upsert:"updated",delete:"deleted"};c(lo,"hashPayload");c(po,"sortKeys");Ue=null;c(mo,"resolveDeviceId");c(Ds,"publishCRUD");c(q,"publishCRUDSync")});var _t,$e,ut,qt=E(()=>{"use strict";wt();bt();N();M();_t={SHIPPED_RETENTION_DAYS:90,IDEA_DORMANT_DAYS:180,QUEUE_COMPLETED_DAYS:7,PAUSED_TASK_DAYS:30,MEMORY_MAX_ENTRIES:500},$e=class{static{c(this,"ArchiveStorage")}archive(t,e){let r=H(),n=g();return k.run(t,"INSERT INTO archives (id, entity_type, entity_id, entity_data, summary, archived_at, reason) VALUES (?, ?, ?, ?, ?, ?, ?)",r,e.entityType,e.entityId,JSON.stringify(e.entityData),e.summary??null,n,e.reason),q({projectId:t,entityType:"archives",entityId:r,eventType:"upsert",data:{id:r,entity_type:e.entityType,entity_id:e.entityId,summary:e.summary??null,reason:e.reason,archived_at:n}}),r}archiveMany(t,e){if(e.length===0)return 0;let r=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,r,o.reason)}),e.length}getArchived(t,e,r=50){return e?k.query(t,"SELECT * FROM archives WHERE entity_type = ? ORDER BY archived_at DESC LIMIT ?",e,r):k.query(t,"SELECT * FROM archives ORDER BY archived_at DESC LIMIT ?",r)}getStats(t){let e=k.query(t,"SELECT entity_type, COUNT(*) as count FROM archives GROUP BY entity_type"),r={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 r&&(r[i]=n.count),r.total+=n.count}return r}restore(t,e){let r=k.get(t,"SELECT * FROM archives WHERE id = ?",e);return r?(k.run(t,"DELETE FROM archives WHERE id = ?",e),JSON.parse(r.entity_data)):null}pruneOldArchives(t,e){let r=new Date(Date.now()-e*24*60*60*1e3).toISOString(),n=this.getTotalCount(t);k.run(t,"DELETE FROM archives WHERE archived_at < ?",r);let i=this.getTotalCount(t);return n-i}getTotalCount(t){return k.get(t,"SELECT COUNT(*) as count FROM archives")?.count??0}},ut=new $e});import To from"node:crypto";function Eo(s){let[t,e]=s.split(".");return t?{entityType:t.endsWith("s")?t:`${t}s`,eventType:e==="deleted"||e==="archived"||e==="removed"?"delete":"upsert"}:{}}function ko(s){if(!s||typeof s!="object")return;let t=s;for(let e of["taskId","task_id","id","feature_id","featureId","specId","spec_id"]){let r=t[e];if(typeof r=="string"&&r.length>0)return r}}function So(s){let t=s&&typeof s=="object"&&!Array.isArray(s)?JSON.stringify(wo(s)):JSON.stringify(s);return To.createHash("sha256").update(t).digest("hex")}function wo(s){let t={};for(let e of Object.keys(s).sort())t[e]=s[e];return t}async function bo(){if(Gt)return Gt;try{let{default:s}=await Promise.resolve().then(()=>(Fe(),je)),t=s;return typeof t.getDeviceId=="function"?(Gt=await t.getDeviceId(),Gt):"unknown-device"}catch{return"unknown-device"}}var Gt,lt,Be=E(()=>{"use strict";Oe();me();N();M();c(Eo,"deriveEntityShape");c(ko,"entityIdOf");c(So,"hashPayload");c(wo,"sortKeys");Gt=null;c(bo,"_resolveDeviceId");lt=class{static{c(this,"StorageManager")}filename;cache;constructor(t,e){this.filename=t,this.cache=new It({ttl:5e3,maxSize:50})}getStoreKey(){return this.filename.replace(".json","")}async read(t){if(!(process.env.PRJCT_IN_DAEMON==="1")){let r=this.cache.get(t);if(r!==null)return r}try{let r=k.getDoc(t,this.getStoreKey());if(r!==null)return this.cache.set(t,r),r}catch{}return this.getDefault()}async write(t,e){k.setDoc(t,this.getStoreKey(),e),this.cache.set(t,e)}async update(t,e){let r=this.getStoreKey(),n=8;for(let i=1;i<=n;i++){let o=k.getDocWithStamp(t,r),a=o?o.data:this.getDefault(),u=e(a);if(k.casSetDoc(t,r,u,o?.updatedAt??null))return this.cache.set(t,u),u}throw new Error(`StorageManager.update: unresolved write contention after ${n} attempts (key=${r})`)}async publishEvent(t,e,r){let n=Eo(e),i={type:e,path:[this.filename.replace(".json","")],data:r,timestamp:g(),projectId:t,entityType:n.entityType,entityId:ko(r),eventType:n.eventType,contentHash:So(r),deviceId:await bo(),revisionCount:1};await Ht.publish(i)}async publishEntityEvent(t,e,r,n){let i=`${e}.${r}`,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 dn,mn,gn,fn,hn=E(()=>{"use strict";dn={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"]},mn=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".py",".go",".rs",".java",".kt",".swift",".rb",".php",".c",".cpp",".h",".hpp",".cs",".vue",".svelte"]),gn=new Set(["node_modules",".git","dist","build",".next",".nuxt",".output","coverage",".cache","__pycache__",".pytest_cache","vendor","target",".turbo",".vercel"]),fn=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 _o from"node:fs/promises";import Yt from"node:path";async function Jt(s,t,e={}){let r=Date.now(),n=e.maxFiles??30,i=e.minScore??.1,o=e.includeTests??!1,a=vo(s),u=await xo(t),l=await Ro(t),d=[];for(let f of u){if(!o&&Ao(f))continue;let T=Po(f,a,l,e.historicalBoosts);T.score>=i&&d.push(T)}d.sort((f,T)=>T.score-f.score);let m=d.slice(0,n);return{files:m,metrics:{filesScanned:u.length,filesReturned:m.length,scanDuration:Date.now()-r}}}function vo(s){return s.toLowerCase().split(/[^a-z0-9]+/).filter(Boolean).filter(e=>!fn.has(e)&&e.length>2)}async function xo(s){let t=[];async function e(r,n=""){try{let i=await _o.readdir(r,{withFileTypes:!0});for(let o of i){let a=Yt.join(r,o.name),u=Yt.join(n,o.name);if(o.isDirectory()){if(gn.has(o.name)||o.name.startsWith("."))continue;await e(a,u)}else if(o.isFile()){let l=Yt.extname(o.name).toLowerCase();mn.has(l)&&t.push(u)}}}catch(i){O(i)}}return c(e,"walk"),await e(s),t}async function Ro(s){let t=new Map;try{let{stdout:e}=await _(`git log -30 --pretty=format:"%H %ct" --name-only | awk '
573
581
  /^[a-f0-9]{40}/ { commit=$1; timestamp=$2; next }
574
582
  NF { files[$0]++; if (!lastmod[$0]) lastmod[$0]=timestamp }
575
583
  END { for (f in files) print files[f], lastmod[f], f }
576
584
  '`,{cwd:s,maxBuffer:10485760}),r=Math.floor(Date.now()/1e3),n=e.trim().split(`
577
- `).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),l=o[3],d=Math.floor((r-u)/86400);t.set(l,{commits:a,daysAgo:d})}}}catch{}return t}function bo(s,t,e,r){let n=[],i=0,o=0,a=0,u=0,l=0,d=s.toLowerCase(),m=d.split("/").join(" ").split(/[^a-z0-9]+/);for(let A of t){d.includes(A)&&(i+=.3,n.push(`keyword:${A}`));for(let V of m)if(V.includes(A)||A.includes(V)){i+=.15;break}}i=Math.min(1,i);for(let[A,V]of Object.entries(dn))for(let Pt of V)if(d.includes(Pt)&&t.some(st=>V.includes(st)||st.includes(A)||A.includes(st))){o+=.4,n.push(`domain:${A}`);break}o=Math.min(1,o);let f=e.get(s);f&&(f.daysAgo<=1?(a=1,n.push("recent:1d")):f.daysAgo<=3?(a=.8,n.push("recent:3d")):f.daysAgo<=7?(a=.6,n.push("recent:1w")):f.daysAgo<=30&&(a=.3,n.push("recent:1m")),f.commits>=5&&(a=Math.min(1,a+.2)));let T=Yt.basename(s).toLowerCase();if((T.includes("index")||T.includes("main")||T.includes("app")||T.includes("entry"))&&(u=.5,n.push("import:0")),(d.includes("/core/")||d.includes("/shared/")||d.includes("/lib/"))&&(u=Math.max(u,.3),n.some(A=>A.startsWith("import:"))||n.push("import:1")),r){let A=r.get(s);A!==void 0&&(l=(A+1)/2,A>0?n.push("history:boosted"):A<0&&n.push("history:penalized"))}let z=r&&r.size>0?i*.54+o*.18+a*.13+u*.05+l*.1:i*.6+o*.2+a*.15+u*.05;return{path:s,score:Math.min(1,z),reasons:[...new Set(n)]}}function _o(s){let t=s.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 qe=E(()=>{"use strict";Z();it();hn();c(Jt,"findRelevantFiles");c(ko,"extractKeywords");c(So,"getAllCodeFiles");c(wo,"getGitRecency");c(bo,"scoreFile");c(_o,"isTestFile")});var Ye,_n,vn=E(()=>{"use strict";kt();qt();j();Ye=class{static{c(this,"MemoryService")}async log(t,e,r,n){try{let i=await B.getProjectId(t);return i?{eventId:y.appendEvent(i,`memory.${e}`,{...r,author:n}),projectId:i}:null}catch(i){return console.error(`Memory log error: ${i instanceof Error?i.message:String(i)}`),null}}async getRecent(t,e=100){try{let r=await B.getProjectId(t);return r?y.query(r,"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(r){return console.error(`Memory read error: ${r instanceof Error?r.message:String(r)}`),[]}}async search(t,e,r=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(-r)}async getByAction(t,e,r=50){try{let n=await B.getProjectId(t);return n?y.query(n,"SELECT type, data, timestamp FROM events WHERE type = ? ORDER BY id DESC LIMIT ?",`memory.${e}`,r).reverse().map(o=>{let a=JSON.parse(o.data),{author:u,...l}=a;return{timestamp:o.timestamp,action:o.type.replace("memory.",""),data:l,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;y.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 y.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(r){return console.error(`Memory read error: ${r instanceof Error?r.message:String(r)}`),[]}}async capEntries(t){try{let r=y.get(t,"SELECT COUNT(*) as cnt FROM events WHERE type LIKE 'memory.%'")?.cnt??0;if(r<=_t.MEMORY_MAX_ENTRIES)return 0;let n=r-_t.MEMORY_MAX_ENTRIES,i=y.query(t,"SELECT id, type, data, timestamp FROM events WHERE type LIKE 'memory.%' ORDER BY id ASC LIMIT ?",n);ut.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&&y.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}}},_n=new Ye});function Rn(s){let t=[];for(let{name:e,re:r}of xn)r.test(s)&&t.push(e);return t}function Pn(s){return s.replace(/[`*_[\](){}<>\\]/g,t=>`\\${t}`)}var xn,dp,Je=E(()=>{"use strict";xn=[{name:"instruction-override",re:/\b(ignore|disregard|override|forget)\b[^.]{0,40}\b(previous|prior|above|system|prompt|instructions?|rules?|constraints?)\b/i},{name:"role-play-injection",re:/\b(you\s+are\s+now|act\s+as|pretend\s+to\s+be|roleplay\s+as|assume\s+the\s+role)\b[^.]{0,40}\b(system|admin|root|developer|operator|jailbreak)\b/i},{name:"jailbreak-phrase",re:/\b(DAN\s+mode|do\s+anything\s+now|without\s+restrictions?|bypass\s+(?:safety|filters?|guidelines?)|jailbreak\s+mode)\b/i},{name:"fake-system-tag",re:/<\s*(?:system|assistant|tool[_-]?call|function[_-]?call)\s*>/i}],dp=xn.map(s=>s.name);c(Rn,"scanForPromptInjection");c(Pn,"escapeMarkdownInline")});var An,ze,vt,fp,Nn=E(()=>{"use strict";An="memory.",ze="remember.",vt=`${An}${ze}`,fp=`${An}task.tagged`});function Ln(s,t){try{return JSON.parse(s)}catch{return t}}function Ke(s){let t=s.type.slice(vt.length),e=Ln(s.data,{});return{id:`mem_${s.id}`,type:t,content:e.content??"",tags:e.tags??{},rememberedAt:s.timestamp,source:e.source,provenance:e.provenance??"declared"}}function Cn(s){let t=s.data?Ln(s.data,{}):{},e=t.tags??{};return s.type&&(e.type=s.type),{id:`ship_${s.id}`,type:"shipped",content:s.name,tags:e,rememberedAt:s.shipped_at,source:t.taskId,provenance:"extracted"}}function $o(s,t){let e=t.toLowerCase();if(s.content.toLowerCase().includes(e))return!0;for(let r of Object.values(s.tags))if(r.toLowerCase().includes(e))return!0;return!1}function Xo(s,t){for(let[e,r]of Object.entries(t))if(s.tags[e]!==r)return!1;return!0}function Wo(s){let t=new Set,e=[];for(let r of s){let n=r.tags.key;if(!n){e.push(r);continue}let i=`${r.type}::${n}`;t.has(i)||(t.add(i),e.push(r))}return e}function Ho(s){let t=new Set;for(let e of s){e.tags["superseded-by"]&&t.add(e.id);for(let r of["supersedes","duplicates"]){let n=e.tags[r];if(n)for(let i of String(n).matchAll(Bo))t.add(`mem_${i[1]}`)}}return t}function qo(s){return s.replace(/[[\]|]/g,"").replace(/\s+/g," ").trim()}function In(s,t){return s.replace(/\[\[(mem[_-]\d+)\]\]/gi,"$1").replace(/\bmem[_-](\d+)\b/g,(e,r)=>{let n=`mem_${r}`,i=t?.idTypeIndex?.get(n),o=t?.idTitleIndex?.get(n),a=t?.idSlugIndex?.get(n),u=o?qo(o):n;return a&&i&&t?.perEntryTypes?.has(i)?`[[${a}|${u}]]`:i?`[[${i}#^mem-${r}|${u}]]`:o?`[[${n}|${u}]]`:`\`${n}\``})}function xt(s,t){if(s.length===0)return"> No matching memory entries.";let e=new Map;for(let l of s){let d=e.get(l.type)??[];d.push(l),e.set(l.type,d)}let r=["decision","learning","anti-pattern","gotcha","pattern","fact","inbox","todo","idea","insight","question","source","person","shipped"],n=[],i={declared:"DECL",extracted:"EXTR",inferred:"INFR",ambiguous:"AMBG"},o=t?.boundary==="llm",a=c((l,d)=>{if(d.length!==0){n.push(`### ${l.toUpperCase()}`);for(let m of d){let f=Object.entries(m.tags).map(([ur,st])=>`${ur}=${o?Pn(st):st}`).join(" "),T=i[m.provenance],M=t?.vault?In(m.content,t):m.content,z=f?` _(${t?.vault?In(f,t):f})_`:"",A=m.id.replace(/^mem[_-]/,""),V=t?.vault?` ^mem-${A}`:"",Pt=`- \`${T}\` [${m.id} \xB7 ${m.type}] ${M}${z}${V}`;o?(n.push(`<user_content id="${m.id}" type="${m.type}">`),n.push(Pt),n.push("</user_content>")):n.push(Pt)}n.push("")}},"renderGroup"),u=new Set;for(let l of r){let d=e.get(l);!d||d.length===0||(a(l,d),u.add(l))}for(let[l,d]of e)u.has(l)||a(l,d);return n.join(`
578
- `).trim()}var Dn,jo,Fo,Uo,Bo,L,mt=E(()=>{"use strict";vn();j();Je();Nn();Dn=["fact","decision","learning","gotcha","pattern","anti-pattern","shipped","inbox","todo","idea","insight","question","source","person","spec"],jo=25,Fo=4,Uo=100;c(Ln,"safeJson");c(Ke,"rowToEntry");c(Cn,"shippedRowToEntry");c($o,"matchesTopic");c(Xo,"matchesTags");c(Wo,"dedupeLatestByKey");Bo=/\bmem[_-](\d+)\b/g;c(Ho,"collectSupersededIds");L={async remember(s,t){let e=t.tags??{},r=t.provenance??"declared",n=await _n.log(s,`${ze}${t.type}`,{content:t.content,tags:e,source:t.source,provenance:r});if(n?.eventId!=null)try{let i=`mem_${n.eventId}`,o=new Date().toISOString(),u=(t.content.split(`
585
+ `).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),l=o[3],d=Math.floor((r-u)/86400);t.set(l,{commits:a,daysAgo:d})}}}catch{}return t}function Po(s,t,e,r){let n=[],i=0,o=0,a=0,u=0,l=0,d=s.toLowerCase(),m=d.split("/").join(" ").split(/[^a-z0-9]+/);for(let A of t){d.includes(A)&&(i+=.3,n.push(`keyword:${A}`));for(let Q of m)if(Q.includes(A)||A.includes(Q)){i+=.15;break}}i=Math.min(1,i);for(let[A,Q]of Object.entries(dn))for(let Pt of Q)if(d.includes(Pt)&&t.some(st=>Q.includes(st)||st.includes(A)||A.includes(st))){o+=.4,n.push(`domain:${A}`);break}o=Math.min(1,o);let f=e.get(s);f&&(f.daysAgo<=1?(a=1,n.push("recent:1d")):f.daysAgo<=3?(a=.8,n.push("recent:3d")):f.daysAgo<=7?(a=.6,n.push("recent:1w")):f.daysAgo<=30&&(a=.3,n.push("recent:1m")),f.commits>=5&&(a=Math.min(1,a+.2)));let T=Yt.basename(s).toLowerCase();if((T.includes("index")||T.includes("main")||T.includes("app")||T.includes("entry"))&&(u=.5,n.push("import:0")),(d.includes("/core/")||d.includes("/shared/")||d.includes("/lib/"))&&(u=Math.max(u,.3),n.some(A=>A.startsWith("import:"))||n.push("import:1")),r){let A=r.get(s);A!==void 0&&(l=(A+1)/2,A>0?n.push("history:boosted"):A<0&&n.push("history:penalized"))}let z=r&&r.size>0?i*.54+o*.18+a*.13+u*.05+l*.1:i*.6+o*.2+a*.15+u*.05;return{path:s,score:Math.min(1,z),reasons:[...new Set(n)]}}function Ao(s){let t=s.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 qe=E(()=>{"use strict";Z();it();hn();c(Jt,"findRelevantFiles");c(vo,"extractKeywords");c(xo,"getAllCodeFiles");c(Ro,"getGitRecency");c(Po,"scoreFile");c(Ao,"isTestFile")});var Ye,_n,vn=E(()=>{"use strict";kt();qt();M();Ye=class{static{c(this,"MemoryService")}async log(t,e,r,n){try{let i=await B.getProjectId(t);return i?{eventId:y.appendEvent(i,`memory.${e}`,{...r,author:n}),projectId:i}:null}catch(i){return console.error(`Memory log error: ${i instanceof Error?i.message:String(i)}`),null}}async getRecent(t,e=100){try{let r=await B.getProjectId(t);return r?y.query(r,"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(r){return console.error(`Memory read error: ${r instanceof Error?r.message:String(r)}`),[]}}async search(t,e,r=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(-r)}async getByAction(t,e,r=50){try{let n=await B.getProjectId(t);return n?y.query(n,"SELECT type, data, timestamp FROM events WHERE type = ? ORDER BY id DESC LIMIT ?",`memory.${e}`,r).reverse().map(o=>{let a=JSON.parse(o.data),{author:u,...l}=a;return{timestamp:o.timestamp,action:o.type.replace("memory.",""),data:l,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;y.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 y.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(r){return console.error(`Memory read error: ${r instanceof Error?r.message:String(r)}`),[]}}async capEntries(t){try{let r=y.get(t,"SELECT COUNT(*) as cnt FROM events WHERE type LIKE 'memory.%'")?.cnt??0;if(r<=_t.MEMORY_MAX_ENTRIES)return 0;let n=r-_t.MEMORY_MAX_ENTRIES,i=y.query(t,"SELECT id, type, data, timestamp FROM events WHERE type LIKE 'memory.%' ORDER BY id ASC LIMIT ?",n);ut.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&&y.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}}},_n=new Ye});function Rn(s){let t=[];for(let{name:e,re:r}of xn)r.test(s)&&t.push(e);return t}function Pn(s){return s.replace(/[`*_[\](){}<>\\]/g,t=>`\\${t}`)}var xn,bp,Je=E(()=>{"use strict";xn=[{name:"instruction-override",re:/\b(ignore|disregard|override|forget)\b[^.]{0,40}\b(previous|prior|above|system|prompt|instructions?|rules?|constraints?)\b/i},{name:"role-play-injection",re:/\b(you\s+are\s+now|act\s+as|pretend\s+to\s+be|roleplay\s+as|assume\s+the\s+role)\b[^.]{0,40}\b(system|admin|root|developer|operator|jailbreak)\b/i},{name:"jailbreak-phrase",re:/\b(DAN\s+mode|do\s+anything\s+now|without\s+restrictions?|bypass\s+(?:safety|filters?|guidelines?)|jailbreak\s+mode)\b/i},{name:"fake-system-tag",re:/<\s*(?:system|assistant|tool[_-]?call|function[_-]?call)\s*>/i}],bp=xn.map(s=>s.name);c(Rn,"scanForPromptInjection");c(Pn,"escapeMarkdownInline")});var An,ze,vt,xp,Nn=E(()=>{"use strict";An="memory.",ze="remember.",vt=`${An}${ze}`,xp=`${An}task.tagged`});var Ln={};K(Ln,{extractRefIds:()=>Dn,usefulnessService:()=>Yo});function Dn(s,t){let e=new Set;for(let r of Go){let n=t[r];if(n)for(let i of String(n).matchAll(Cn))e.add(`mem_${i[1]}`)}for(let r of s.matchAll(Cn))e.add(`mem_${r[1]}`);return[...e]}function In(s,t,e,r,n){y.run(s,`INSERT INTO memory_usefulness (memory_id, score, ${r}, last_used_at)
586
+ VALUES (?, ?, 1, ?)
587
+ ON CONFLICT(memory_id) DO UPDATE SET
588
+ score = score + ?, ${r} = ${r} + 1, last_used_at = excluded.last_used_at`,t,e,n,e)}var Wo,Bo,Ho,qo,Go,Cn,Yo,On=E(()=>{"use strict";M();Wo=45,Bo=1,Ho=.4,qo=864e5,Go=["resolves","relates","supersedes","superseded-by","duplicates","spec"],Cn=/\bmem[_-](\d+)\b/g;c(Dn,"extractRefIds");c(In,"bump");Yo={recordReferences(s,t,e,r=new Date().toISOString()){try{for(let n of Dn(t,e))In(s,n,Bo,"ref_count",r)}catch{}},recordFetch(s,t,e=new Date().toISOString()){try{In(s,t,Ho,"fetch_count",e)}catch{}},decayedScores(s,t=Date.now()){let e=new Map,r;try{r=y.query(s,"SELECT memory_id, score, last_used_at FROM memory_usefulness")}catch{return e}for(let n of r){let i=Date.parse(n.last_used_at),o=Number.isNaN(i)?1:.5**(Math.max(0,t-i)/qo/Wo);e.set(n.memory_id,n.score*o)}return e},rerank(s,t,e=Date.now()){if(t.length<2)return t;let r;try{r=this.decayedScores(s,e)}catch{return t}if(r.size===0)return t;let n=Math.max(1,...r.values()),i=4,o=t.length,a=t.map((u,l)=>{let d=(r.get(u.id)??0)/n;return{entry:u,i:l,rankScore:o-l+i*d}});return a.sort((u,l)=>l.rankScore-u.rankScore||u.i-l.i),a.map(u=>u.entry)}}});function Un(s,t){try{return JSON.parse(s)}catch{return t}}function Ke(s){let t=s.type.slice(vt.length),e=Un(s.data,{});return{id:`mem_${s.id}`,type:t,content:e.content??"",tags:e.tags??{},rememberedAt:s.timestamp,source:e.source,provenance:e.provenance??"declared"}}function Mn(s){let t=s.data?Un(s.data,{}):{},e=t.tags??{};return s.type&&(e.type=s.type),{id:`ship_${s.id}`,type:"shipped",content:s.name,tags:e,rememberedAt:s.shipped_at,source:t.taskId,provenance:"extracted"}}function Vo(s,t){let e=t.toLowerCase();if(s.content.toLowerCase().includes(e))return!0;for(let r of Object.values(s.tags))if(r.toLowerCase().includes(e))return!0;return!1}function Qo(s,t){for(let[e,r]of Object.entries(t))if(s.tags[e]!==r)return!1;return!0}function Zo(s){let t=new Set,e=[];for(let r of s){let n=r.tags.key;if(!n){e.push(r);continue}let i=`${r.type}::${n}`;t.has(i)||(t.add(i),e.push(r))}return e}function ea(s){let t=new Set;for(let e of s){e.tags["superseded-by"]&&t.add(e.id);for(let r of["supersedes","duplicates"]){let n=e.tags[r];if(n)for(let i of String(n).matchAll(ta))t.add(`mem_${i[1]}`)}}return t}function ra(s){return s.replace(/[[\]|]/g,"").replace(/\s+/g," ").trim()}function jn(s,t){return s.replace(/\[\[(mem[_-]\d+)\]\]/gi,"$1").replace(/\bmem[_-](\d+)\b/g,(e,r)=>{let n=`mem_${r}`,i=t?.idTypeIndex?.get(n),o=t?.idTitleIndex?.get(n),a=t?.idSlugIndex?.get(n),u=o?ra(o):n;return a&&i&&t?.perEntryTypes?.has(i)?`[[${a}|${u}]]`:i?`[[${i}#^mem-${r}|${u}]]`:o?`[[${n}|${u}]]`:`\`${n}\``})}function xt(s,t){if(s.length===0)return"> No matching memory entries.";let e=new Map;for(let l of s){let d=e.get(l.type)??[];d.push(l),e.set(l.type,d)}let r=["decision","learning","anti-pattern","gotcha","pattern","fact","inbox","todo","idea","insight","question","source","person","shipped"],n=[],i={declared:"DECL",extracted:"EXTR",inferred:"INFR",ambiguous:"AMBG"},o=t?.boundary==="llm",a=c((l,d)=>{if(d.length!==0){n.push(`### ${l.toUpperCase()}`);for(let m of d){let f=Object.entries(m.tags).map(([ur,st])=>`${ur}=${o?Pn(st):st}`).join(" "),T=i[m.provenance],j=t?.vault?jn(m.content,t):m.content,z=f?` _(${t?.vault?jn(f,t):f})_`:"",A=m.id.replace(/^mem[_-]/,""),Q=t?.vault?` ^mem-${A}`:"",Pt=`- \`${T}\` [${m.id} \xB7 ${m.type}] ${j}${z}${Q}`;o?(n.push(`<user_content id="${m.id}" type="${m.type}">`),n.push(Pt),n.push("</user_content>")):n.push(Pt)}n.push("")}},"renderGroup"),u=new Set;for(let l of r){let d=e.get(l);!d||d.length===0||(a(l,d),u.add(l))}for(let[l,d]of e)u.has(l)||a(l,d);return n.join(`
589
+ `).trim()}var Fn,Jo,zo,Ko,ta,L,mt=E(()=>{"use strict";vn();M();Je();Nn();Fn=["fact","decision","learning","gotcha","pattern","anti-pattern","shipped","inbox","todo","idea","insight","question","source","person","spec"],Jo=25,zo=4,Ko=100;c(Un,"safeJson");c(Ke,"rowToEntry");c(Mn,"shippedRowToEntry");c(Vo,"matchesTopic");c(Qo,"matchesTags");c(Zo,"dedupeLatestByKey");ta=/\bmem[_-](\d+)\b/g;c(ea,"collectSupersededIds");L={async remember(s,t){let e=t.tags??{},r=t.provenance??"declared",n=await _n.log(s,`${ze}${t.type}`,{content:t.content,tags:e,source:t.source,provenance:r});if(n?.eventId!=null)try{let i=`mem_${n.eventId}`,o=new Date().toISOString(),u=(t.content.split(`
579
590
  `)[0]??t.content).slice(0,80);y.run(n.projectId,`INSERT OR IGNORE INTO memories
580
591
  (id, project_id, title, content, tags, type, provenance, user_triggered,
581
592
  created_at, updated_at)
582
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,i,n.projectId,u,t.content,JSON.stringify(e),t.type,r,0,o,o)}catch{}try{let{default:i}=await Promise.resolve().then(()=>(kt(),Ts)),a=(await i.readConfig(s))?.projectId;if(!a)return;let{publishCRUD:u}=await Promise.resolve().then(()=>(bt(),Ls)),l=t.tags?.spec_id??t.tags?.task_id??t.tags?.id??t.source??`mem-${Date.now()}-${Math.random().toString(36).slice(2,8)}`;await u({projectId:a,entityType:"memories",entityId:l,eventType:"upsert",data:{id:l,type:t.type,content:t.content,tags:t.tags??{},source:t.source??null,provenance:t.provenance??"declared",rememberedAt:new Date().toISOString()}})}catch{}},searchFts(s,t,e){if(t.length===0||e<=0)return[];let r=t.map(o=>o.replace(/[^a-z0-9-]/gi,"")).filter(o=>o.length>=2);if(r.length===0)return[];let n=r.map(o=>`"${o}"*`).join(" OR "),i;try{i=y.query(s,`SELECT m.id, m.title, m.content, m.tags, m.type, m.provenance, m.created_at
593
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,i,n.projectId,u,t.content,JSON.stringify(e),t.type,r,0,o,o)}catch{}if(n?.projectId)try{let{usefulnessService:i}=await Promise.resolve().then(()=>(On(),Ln));i.recordReferences(n.projectId,t.content,e)}catch{}try{let{default:i}=await Promise.resolve().then(()=>(kt(),Ts)),a=(await i.readConfig(s))?.projectId;if(!a)return;let{publishCRUD:u}=await Promise.resolve().then(()=>(bt(),Ls)),l=t.tags?.spec_id??t.tags?.task_id??t.tags?.id??t.source??`mem-${Date.now()}-${Math.random().toString(36).slice(2,8)}`;await u({projectId:a,entityType:"memories",entityId:l,eventType:"upsert",data:{id:l,type:t.type,content:t.content,tags:t.tags??{},source:t.source??null,provenance:t.provenance??"declared",rememberedAt:new Date().toISOString()}})}catch{}},searchFts(s,t,e){if(t.length===0||e<=0)return[];let r=t.map(o=>o.replace(/[^a-z0-9-]/gi,"")).filter(o=>o.length>=2);if(r.length===0)return[];let n=r.map(o=>`"${o}"*`).join(" OR "),i;try{i=y.query(s,`SELECT m.id, m.title, m.content, m.tags, m.type, m.provenance, m.created_at
583
594
  FROM memories_fts ft
584
595
  JOIN memories m ON m.rowid = ft.rowid
585
596
  WHERE memories_fts MATCH ?
586
597
  AND m.deleted_at IS NULL
587
598
  ORDER BY bm25(memories_fts) ASC, m.created_at DESC
588
- LIMIT ?`,n,e)}catch{return[]}return i.map(o=>{let a={};if(o.tags)try{let u=JSON.parse(o.tags);u&&typeof u=="object"&&(a=u)}catch{}return{id:o.id,type:o.type??"fact",content:o.content,tags:a,rememberedAt:o.created_at,provenance:o.provenance??"declared"}})},recall(s,t={}){let e=t.limit??jo,r=Math.max(e*Fo,Uo),n=t.types&&t.types.length>0?new Set(t.types):null,i=n?n.has("shipped"):!0,a=(n?[...n].some(d=>d!=="shipped"):!0)?y.query(s,"SELECT id, type, data, timestamp FROM events WHERE type LIKE ? ORDER BY id DESC LIMIT ?",`${vt}%`,r):[],u=i?y.query(s,"SELECT id, name, type, shipped_at, data FROM shipped_features ORDER BY shipped_at DESC LIMIT ?",r):[],l=[...a.map(Ke),...u.map(Cn)];if(n&&(l=l.filter(d=>n.has(d.type))),t.tags&&(l=l.filter(d=>Xo(d,t.tags??{}))),t.topic&&(l=l.filter(d=>$o(d,t.topic))),l.sort((d,m)=>m.rememberedAt.localeCompare(d.rememberedAt)),t.dedupeByKey!==!1&&(l=Wo(l)),t.pruneSuperseded!==!1){let d=Ho(l);d.size>0&&(l=l.filter(m=>!d.has(m.id)))}return l.slice(0,e)},getById(s,t){let e=String(t).trim().match(/^(?:mem[_-])?(\d+)$/i);if(!e)return null;let r=Number(e[1]);try{let n=y.get(s,"SELECT id, type, data, timestamp FROM events WHERE id = ? AND type LIKE ?",r,`${vt}%`);return n?Ke(n):null}catch{return null}},expandWithLinks(s,t,e=5){if(t.length===0||e<=0)return[];let r=/\bmem[_-](\d+)\b/g,n=["resolves","relates","supersedes","superseded-by","duplicates","spec"],i=new Set(t.map(a=>a.id)),o=[];for(let a of t){if(o.length>=e)break;let u=new Set;for(let l of n){let d=a.tags?.[l];if(d)for(let m of String(d).matchAll(r))u.add(`mem_${m[1]}`)}for(let l of a.content.matchAll(r))u.add(`mem_${l[1]}`);for(let l of u){if(o.length>=e)break;if(i.has(l))continue;i.add(l);let d=L.getById(s,l);d&&o.push(d)}}return o},allEntriesForIndex(s){try{let t=y.query(s,"SELECT id, type, data, timestamp FROM events WHERE type LIKE ? ORDER BY id DESC",`${vt}%`),e=y.query(s,"SELECT id, name, type, shipped_at, data FROM shipped_features ORDER BY shipped_at DESC");return[...t.map(Ke),...e.map(Cn)]}catch{return[]}},similar(s,t,e=10){let r=t.toLowerCase().split(/[^a-z0-9]+/).filter(o=>o.length>3);return r.length===0?[]:L.recall(s,{limit:200}).map(o=>{let a=`${o.content} ${Object.values(o.tags).join(" ")}`.toLowerCase(),u=r.reduce((l,d)=>a.includes(d)?l+1:l,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(qo,"linkLabel");c(In,"linkifyMemRefs");c(xt,"formatMemoryMd")});function Wn(s){return[...s].sort((t,e)=>{let r=Xn[t.section]-Xn[e.section];return r!==0?r:$n[t.priority]-$n[e.priority]})}var $n,Xn,Bn=E(()=>{"use strict";$n={critical:0,high:1,medium:2,low:3},Xn={active:0,previously_active:1,backlog:2};c(Wn,"sortBySectionAndPriority")});var Qe,Rt,Ze=E(()=>{"use strict";wt();Bt();Bn();N();qt();Be();Qe=class extends lt{static{c(this,"QueueStorage")}constructor(){super("queue.json",xs)}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(r=>r.section==="active"&&!r.completed)}async getBacklog(t){return(await this.read(t)).tasks.filter(r=>r.section==="backlog"&&!r.completed)}async getNextTask(t){let e=await this.getActiveTasks(t);return Wn(e)[0]||null}async addTask(t,e){let r={...e,id:H(),createdAt:g(),completed:!1};return await this.update(t,n=>({tasks:[...n.tasks,r],lastUpdated:g()})),await this.publishEvent(t,"queue.task_added",{taskId:r.id,description:r.description,priority:r.priority,section:r.section}),r}async addTasks(t,e){let r=g(),n=e.map(i=>({...i,id:H(),createdAt:r,completed:!1}));return await this.update(t,i=>({tasks:[...i.tasks,...n],lastUpdated:r})),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,r=>({tasks:r.tasks.filter(n=>n.id!==e),lastUpdated:g()})),await this.publishEvent(t,"queue.task_removed",{taskId:e})}async deleteByFeatureId(t,e){let r=0;return await this.update(t,n=>{let i=n.tasks.length,o=n.tasks.filter(a=>a.featureId!==e);return r=i-o.length,{tasks:o,lastUpdated:g()}}),r>0&&await this.publishEvent(t,"queue.tasks_removed_by_feature",{featureId:e,count:r}),r}async completeTask(t,e){let r=null;if(await this.update(t,n=>({tasks:n.tasks.map(o=>o.id===e?(r={...o,completed:!0,completedAt:g()},r):o),lastUpdated:g()})),r){let n=r;await this.publishEvent(t,"queue.task_completed",{taskId:e,description:n.description,completedAt:n.completedAt})}return r}async moveToSection(t,e,r){await this.update(t,n=>({tasks:n.tasks.map(i=>i.id===e?{...i,section:r}:i),lastUpdated:g()}))}async setPriority(t,e,r){await this.update(t,n=>({tasks:n.tasks.map(i=>i.id===e?{...i,priority:r}:i),lastUpdated:g()}))}async getTask(t,e){return(await this.read(t)).tasks.find(n=>n.id===e)||null}async updateTask(t,e,r){let n=null;return await this.update(t,i=>({tasks:i.tasks.map(o=>o.id===e?(n={...o,...r},n):o),lastUpdated:g()})),n&&await this.publishEvent(t,"queue.task_updated",{taskId:e}),n}async clearCompleted(t){let r=(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()})),r}async removeStaleCompleted(t){let e=await this.read(t),r=fr(_t.QUEUE_COMPLETED_DAYS),n=e.tasks.filter(o=>o.completed&&o.completedAt&&new Date(o.completedAt)<r);if(n.length===0)return 0;ut.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}},Rt=new Qe});import{z as b}from"zod";var gt,rr,er,Yo,Y,Kt=E(()=>{"use strict";gt=["draft","reviewed","in_progress","shipped","archived"],rr=["strategic","architecture","design"],er=b.object({verdict:b.enum(["pass","fail"]),notes:b.string(),ts:b.string()}),Yo=b.object({risk:b.string().min(1),mitigation:b.string().min(1)}),Y=b.object({goal:b.string().min(1),eli10:b.string().default(""),stakes:b.string().default(""),acceptance_criteria:b.array(b.string().min(1)).default([]),scope:b.array(b.string()).default([]),out_of_scope:b.array(b.string()).default([]),risks:b.array(Yo).default([]),test_plan:b.array(b.string()).default([]),reviews:b.object({strategic:er.optional(),architecture:er.optional(),design:er.optional()}).optional(),linked_tasks:b.array(b.string()).default([]),notes:b.string().default(""),tasks_created_at:b.string().nullable().default(null)})});var sr,x,Vt=E(()=>{"use strict";wt();Kt();N();j();sr=class{static{c(this,"SpecStorage")}nextUpdatedAt(t,e){let r=g(),i=y.get(t,"SELECT updated_at FROM specs WHERE id = ?",e)?.updated_at;return!i||r>i?r:new Date(new Date(i).getTime()+1).toISOString()}create(t,e){let r=H(),n=g(),i=Y.parse(e.content);return y.run(t,`INSERT INTO specs (id, title, status, content, tags, created_at, updated_at)
589
- VALUES (?, ?, 'draft', ?, ?, ?, ?)`,r,e.title,JSON.stringify(i),e.tags?JSON.stringify(e.tags):null,n,n),{id:r,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 r=y.get(t,"SELECT * FROM specs WHERE id = ?",e);return r?this.rowToSpec(r):null}list(t,e={}){let r="SELECT * FROM specs WHERE 1=1",n=[];return e.status&&(r+=" AND status = ?",n.push(e.status)),!e.includeArchived&&!e.status&&(r+=" AND status != 'archived'"),r+=" ORDER BY created_at DESC",y.query(t,r,...n).map(o=>this.rowToSpec(o))}search(t,e){let r=`%${e}%`;return y.query(t,"SELECT * FROM specs WHERE title LIKE ? OR content LIKE ? ORDER BY created_at DESC",r,r).map(i=>this.rowToSpec(i))}updateContent(t,e,r){let n=Y.parse(r),i=this.nextUpdatedAt(t,e);return y.run(t,"UPDATE specs SET content = ?, updated_at = ? WHERE id = ?",JSON.stringify(n),i,e),this.get(t,e)}casUpdate(t,e,r,n){let i=Y.parse(r),o=this.nextUpdatedAt(t,e);return y.run(t,"UPDATE specs SET content = ?, updated_at = ? WHERE id = ? AND updated_at = ?",JSON.stringify(i),o,e,n).changes===1}setStatus(t,e,r){if(!gt.includes(r))throw new Error(`invalid spec status: ${r}`);let n=this.nextUpdatedAt(t,e),i=[],o=[r,n];r==="shipped"&&(i.push("shipped_at = ?"),o.push(n)),r==="archived"&&(i.push("archived_at = ?"),o.push(n));let a=["status = ?","updated_at = ?",...i].join(", ");return o.push(e),y.run(t,`UPDATE specs SET ${a} WHERE id = ?`,...o),this.get(t,e)}setShippedPr(t,e,r){return y.run(t,"UPDATE specs SET shipped_pr = ?, updated_at = ? WHERE id = ?",r,this.nextUpdatedAt(t,e),e),this.get(t,e)}setShippedSha(t,e,r){return y.run(t,"UPDATE specs SET shipped_sha = ?, updated_at = ? WHERE id = ?",r,this.nextUpdatedAt(t,e),e),this.get(t,e)}linkTask(t,e,r){let n=this.get(t,e);if(!n)return null;if(n.content.linked_tasks.includes(r))return n;let i={...n.content,linked_tasks:[...n.content.linked_tasks,r]};return this.updateContent(t,e,i)}delete(t,e){return this.get(t,e)?(y.run(t,"DELETE FROM specs WHERE id = ?",e),!0):!1}count(t){let e=y.query(t,"SELECT status, COUNT(*) AS n FROM specs GROUP BY status"),r={total:0,draft:0,shipped:0};for(let n of e)r.total+=n.n,n.status==="draft"&&(r.draft=n.n),n.status==="shipped"&&(r.shipped=n.n);return r}rowToSpec(t){return{id:t.id,title:t.title,status:gt.includes(t.status)?t.status:"draft",content:Y.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}}},x=new sr});var Gn={};Q(Gn,{inferSpecContext:()=>Ko,warnNoContextMatch:()=>Zo});async function Ko(s,t,e){let[r,n]=await Promise.all([Jt(s,e,{maxFiles:qn*4,minScore:zo}).catch(()=>({files:[]})),Promise.resolve(L.recall(t,{topic:s,limit:Jo})).catch(()=>[])]),i=Vo(r.files.map(u=>u.path),qn);return i.length===0&&n.length===0?{notesBlock:"",paths:[],memoryHits:0,empty:!0}:{notesBlock:Qo(s,i,n),paths:i,memoryHits:n.length,empty:!1}}function Vo(s,t){let e=new Set,r=[];for(let n of s){let i=n.split("/").slice(0,2).join("/");if(!e.has(i)&&(e.add(i),r.push(n),r.length>=t))break}return r}function Qo(s,t,e){let r=[];if(r.push("<!-- auto-context:tentative -->"),r.push("## Existing context (auto-inferred)"),r.push(""),r.push(`_Inferred from title "${s}". Validate before audit \u2014 entries tagged tentative._`),r.push(""),t.length>0){r.push("### Likely paths");for(let n of t)r.push(`- \`${n}\``);r.push("")}if(e.length>0){r.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(" ");r.push(`- **${n.type}**${o?` _(${o})_`:""} \u2014 ${i}`)}r.push("")}return r.push("<!-- /auto-context -->"),r.join(`
590
- `)}function Zo(s,t){let e={level:"warn",code:"no_context_match",message:`No codebase or memory context matched "${s}"`,suggestion:t??"Fill spec.notes manually or run with `--skip-context` next time."};process.stderr.write(`${JSON.stringify(e)}
591
- `)}var qn,Jo,zo,Yn=E(()=>{"use strict";mt();qe();qn=5,Jo=8,zo=.15;c(Ko,"inferSpecContext");c(Vo,"dedupeTopDirs");c(Qo,"buildNotesBlock");c(Zo,"warnNoContextMatch")});var Jn={};Q(Jn,{breakdownSpecToTasks:()=>ta});async function ta(s,t,e){let r=e.content.acceptance_criteria;if(r.length===0)return{taskIds:[],skippedReason:"no_acceptance_criteria"};if(e.content.tasks_created_at!==null)return{taskIds:[],skippedReason:"already_broken_down"};let n=!1;if(e.content.linked_tasks.length>0){n=!0,await Rt.deleteByFeatureId(s,e.id);let a={...e.content,linked_tasks:[]};x.updateContent(s,e.id,a)}let i=await Rt.addTasks(s,r.map(a=>({description:ea(a),body:a,priority:"medium",type:"feature",section:"backlog",featureId:e.id,groupId:e.id,groupName:e.title})));for(let a of i)x.linkTask(s,e.id,a.id);let o=x.get(s,e.id);if(o){let a={...o.content,tasks_created_at:g()};x.updateContent(s,e.id,a)}return await L.remember(t,{type:"spec",content:`Auto-breakdown: ${i.length} tasks created from ${e.title}${n?" (recovered from partial)":""}`,tags:{spec_id:e.id,event:"auto_breakdown",task_count:String(i.length),...n?{recovered:"partial"}:{}},source:e.id}),{taskIds:i.map(a=>a.id),...n?{recoveredFromPartial:!0}:{}}}function ea(s){let t=s.replace(/\s+/g," ").trim();return t.length<=140?t:`${t.slice(0,137)}\u2026`}var zn=E(()=>{"use strict";mt();Ze();Vt();N();c(ta,"breakdownSpecToTasks");c(ea,"truncateForDescription")});import{StdioServerTransport as la}from"@modelcontextprotocol/sdk/server/stdio.js";import{McpServer as ca}from"@modelcontextprotocol/sdk/server/mcp.js";import{z as D}from"zod";ee();j();U();import ns from"node:fs/promises";import at from"node:path";function xi(s){let t=[],e,r=new RegExp(mr.source,"g");for(;(e=r.exec(s))!==null;){let n=e[1];(n.startsWith(".")||n.startsWith("@/"))&&t.push(n)}return t}c(xi,"extractImportSources");async function Ri(s,t,e){let r;if(s.startsWith("@/"))r=at.join(e,"src",s.slice(2));else{let n=at.dirname(at.join(e,t));r=at.resolve(n,s)}for(let n of dr){let i=r+n;try{if((await ns.stat(i)).isFile())return at.relative(e,i)}catch{}}return null}c(Ri,"resolveImport");async function Pi(s){let t=await wr(s),e={},r={},n=0,i=await br(t,50,async o=>{try{let a=await ns.readFile(at.join(s,o),"utf-8"),u=xi(a),l=[];for(let d of u){let m=await Ri(d,o,s);m&&m!==o&&l.push(m)}return l.length>0?{filePath:o,imports:l}:null}catch{return null}});for(let{filePath:o,imports:a}of i){e[o]=a,n+=a.length;for(let u of a)r[u]||(r[u]=[]),r[u].push(o)}return{forward:e,reverse:r,fileCount:t.length,edgeCount:n,builtAt:new Date().toISOString()}}c(Pi,"buildGraph");function is(s,t,e=2){let r=new Set(s),n=new Map,i=[];for(let o of s){let a=t.forward[o]||[],u=t.reverse[o]||[];for(let l of[...a,...u])r.has(l)||i.push({file:l,depth:1})}for(;i.length>0;){let{file:o,depth:a}=i.shift();if(a>e)continue;let u=1/(a+1),l=n.get(o);if(l){u>l.score&&n.set(o,{score:u,depth:a});continue}if(n.set(o,{score:u,depth:a}),a<e){let d=t.forward[o]||[],m=t.reverse[o]||[];for(let f of[...d,...m])!r.has(f)&&!n.has(f)&&i.push({file:f,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(is,"scoreFromSeeds");var ke="import-graph",jt=new Map;function Ai(s,t){y.setDoc(s,ke,t),jt.delete(s)}c(Ai,"saveGraph");function Tt(s){let t=y.get(s,"SELECT updated_at FROM kv_store WHERE key = ?",ke);if(!t)return jt.delete(s),null;let e=jt.get(s);if(e&&e.updatedAt===t.updated_at)return e.graph;let r=y.getDoc(s,ke);return r&&jt.set(s,{graph:r,updatedAt:t.updated_at}),r}c(Tt,"loadGraph");async function os(s,t){let e=await Pi(s);return Ai(t,e),e}c(os,"indexImports");function as(s,t){let e=[...s.added,...s.modified],r=new Set(e),n=new Set,i=Tt(t);if(i)for(let u of e){let l=i.reverse[u];if(l)for(let d of l)r.has(d)||n.add(d)}let o=Array.from(n),a=[...e,...o];return{directlyChanged:e,affectedByImports:o,deleted:s.deleted,allAffected:a}}c(as,"propagateChanges");function cs(s){let t=new Set;for(let e of s){let r=e.toLowerCase();(r.endsWith(".tsx")||r.endsWith(".jsx")||r.endsWith(".css")||r.endsWith(".scss")||r.endsWith(".vue")||r.endsWith(".svelte")||r.includes("/components/")||r.includes("/pages/")||r.includes("/app/"))&&(t.add("frontend"),t.add("uxui")),(r.includes(".test.")||r.includes(".spec.")||r.includes("__tests__")||r.includes("/test/"))&&t.add("testing"),(r.includes("dockerfile")||r.includes("docker-compose")||r.includes(".dockerignore")||r.includes(".github/")||r.includes("ci/")||r.includes("cd/"))&&t.add("devops"),(r.endsWith(".sql")||r.includes("prisma")||r.includes("drizzle")||r.includes("migration")||r.includes("/db/"))&&t.add("database"),(r.endsWith(".ts")||r.endsWith(".js"))&&!r.includes(".test.")&&!r.includes(".spec.")&&!r.endsWith(".d.ts")&&t.add("backend")}return t}c(cs,"affectedDomains");j();it();async function Ci(s,t=100){try{let{stdout:e}=await _(`git log --name-only --pretty=format:'---COMMIT---' -${t}`,{cwd:s,maxBuffer:10485760}),r=[],n=null;for(let i of e.split(`
592
- `)){let o=i.trim();o==="---COMMIT---"?(n&&n.size>0&&n.size<=30&&r.push(n),n=new Set):o&&n&&Ii(o)&&n.add(o)}return n&&n.size>0&&n.size<=30&&r.push(n),r}catch{return[]}}c(Ci,"parseGitLog");function Ii(s){return/\.(ts|tsx|js|jsx|mjs|cjs|py|go|rs|java|cs|rb|php|vue|svelte)$/i.test(s)&&!s.includes("node_modules/")}c(Ii,"isSourceFile");async function Di(s,t=100){let e=await Ci(s,t),r=new Map,n=new Map;for(let o of e){let a=Array.from(o);for(let u of a)r.set(u,(r.get(u)||0)+1);for(let u=0;u<a.length;u++)for(let l=u+1;l<a.length;l++){let d=Li(a[u],a[l]);n.set(d,(n.get(d)||0)+1)}}let i={};for(let[o,a]of n){let[u,l]=o.split("\0"),d=r.get(u)||0,m=r.get(l)||0;if(d<2||m<2)continue;let f=d+m-a,T=f>0?a/f:0;T<.1||(i[u]||(i[u]={}),i[l]||(i[l]={}),i[u][l]=T,i[l][u]=T)}return{matrix:i,commitsAnalyzed:e.length,filesAnalyzed:r.size,builtAt:new Date().toISOString()}}c(Di,"buildMatrix");function Li(s,t){return s<t?`${s}\0${t}`:`${t}\0${s}`}c(Li,"pairKey");function we(s,t){let e=new Set(s),r=new Map;for(let n of s){let i=t.matrix[n];if(i)for(let[o,a]of Object.entries(i)){if(e.has(o))continue;let u=r.get(o)||0;a>u&&r.set(o,a)}}return Array.from(r.entries()).map(([n,i])=>({path:n,score:i})).sort((n,i)=>i.score-n.score)}c(we,"scoreFromSeeds");var Se="cochange-index",Ft=new Map;function Oi(s,t){y.setDoc(s,Se,t),Ft.delete(s)}c(Oi,"saveMatrix");function be(s){let t=y.get(s,"SELECT updated_at FROM kv_store WHERE key = ?",Se);if(!t)return Ft.delete(s),null;let e=Ft.get(s);if(e&&e.updatedAt===t.updated_at)return e.matrix;let r=y.getDoc(s,Se);return r&&Ft.set(s,{matrix:r,updatedAt:t.updated_at}),r}c(be,"loadMatrix");async function ps(s,t,e=100){let r=await Di(s,e);return Oi(t,r),r}c(ps,"indexCoChanges");kt();async function R(s){return B.getProjectId(s)}c(R,"resolveProjectId");function S(s,t){return async e=>{try{return await t(e)}catch(r){return Hi(r,s)}}}c(S,"safeMcpCall");function Hi(s,t){let e=s instanceof Error?s.message:String(s);return{content:[{type:"text",text:`[${t}] Error: ${e}`}],isError:!0}}c(Hi,"mcpError");function Es(s){let t=s;t.tool("prjct_impact_analysis","Given changed files, find affected files via import graph + affected domains",{projectPath:D.string().describe("Project directory path"),changedFiles:D.array(D.string()).describe("List of changed file paths (relative to project root)")},S("prjct_impact_analysis",async e=>{let r=await R(e.projectPath),n={added:[],modified:e.changedFiles,deleted:[],unchanged:[]},i=as(n,r),o=cs(i.allAffected),a=["## Impact Analysis"];a.push(`
599
+ LIMIT ?`,n,e)}catch{return[]}return i.map(o=>{let a={};if(o.tags)try{let u=JSON.parse(o.tags);u&&typeof u=="object"&&(a=u)}catch{}return{id:o.id,type:o.type??"fact",content:o.content,tags:a,rememberedAt:o.created_at,provenance:o.provenance??"declared"}})},recall(s,t={}){let e=t.limit??Jo,r=Math.max(e*zo,Ko),n=t.types&&t.types.length>0?new Set(t.types):null,i=n?n.has("shipped"):!0,a=(n?[...n].some(d=>d!=="shipped"):!0)?y.query(s,"SELECT id, type, data, timestamp FROM events WHERE type LIKE ? ORDER BY id DESC LIMIT ?",`${vt}%`,r):[],u=i?y.query(s,"SELECT id, name, type, shipped_at, data FROM shipped_features ORDER BY shipped_at DESC LIMIT ?",r):[],l=[...a.map(Ke),...u.map(Mn)];if(n&&(l=l.filter(d=>n.has(d.type))),t.tags&&(l=l.filter(d=>Qo(d,t.tags??{}))),t.topic&&(l=l.filter(d=>Vo(d,t.topic))),l.sort((d,m)=>m.rememberedAt.localeCompare(d.rememberedAt)),t.dedupeByKey!==!1&&(l=Zo(l)),t.pruneSuperseded!==!1){let d=ea(l);d.size>0&&(l=l.filter(m=>!d.has(m.id)))}return l.slice(0,e)},getById(s,t){let e=String(t).trim().match(/^(?:mem[_-])?(\d+)$/i);if(!e)return null;let r=Number(e[1]);try{let n=y.get(s,"SELECT id, type, data, timestamp FROM events WHERE id = ? AND type LIKE ?",r,`${vt}%`);return n?Ke(n):null}catch{return null}},expandWithLinks(s,t,e=5){if(t.length===0||e<=0)return[];let r=/\bmem[_-](\d+)\b/g,n=["resolves","relates","supersedes","superseded-by","duplicates","spec"],i=new Set(t.map(a=>a.id)),o=[];for(let a of t){if(o.length>=e)break;let u=new Set;for(let l of n){let d=a.tags?.[l];if(d)for(let m of String(d).matchAll(r))u.add(`mem_${m[1]}`)}for(let l of a.content.matchAll(r))u.add(`mem_${l[1]}`);for(let l of u){if(o.length>=e)break;if(i.has(l))continue;i.add(l);let d=L.getById(s,l);d&&o.push(d)}}return o},allEntriesForIndex(s){try{let t=y.query(s,"SELECT id, type, data, timestamp FROM events WHERE type LIKE ? ORDER BY id DESC",`${vt}%`),e=y.query(s,"SELECT id, name, type, shipped_at, data FROM shipped_features ORDER BY shipped_at DESC");return[...t.map(Ke),...e.map(Mn)]}catch{return[]}},similar(s,t,e=10){let r=t.toLowerCase().split(/[^a-z0-9]+/).filter(o=>o.length>3);return r.length===0?[]:L.recall(s,{limit:200}).map(o=>{let a=`${o.content} ${Object.values(o.tags).join(" ")}`.toLowerCase(),u=r.reduce((l,d)=>a.includes(d)?l+1:l,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(ra,"linkLabel");c(jn,"linkifyMemRefs");c(xt,"formatMemoryMd")});function Yn(s){return[...s].sort((t,e)=>{let r=Gn[t.section]-Gn[e.section];return r!==0?r:qn[t.priority]-qn[e.priority]})}var qn,Gn,Jn=E(()=>{"use strict";qn={critical:0,high:1,medium:2,low:3},Gn={active:0,previously_active:1,backlog:2};c(Yn,"sortBySectionAndPriority")});var Qe,Rt,Ze=E(()=>{"use strict";wt();Bt();Jn();N();qt();Be();Qe=class extends lt{static{c(this,"QueueStorage")}constructor(){super("queue.json",xs)}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(r=>r.section==="active"&&!r.completed)}async getBacklog(t){return(await this.read(t)).tasks.filter(r=>r.section==="backlog"&&!r.completed)}async getNextTask(t){let e=await this.getActiveTasks(t);return Yn(e)[0]||null}async addTask(t,e){let r={...e,id:H(),createdAt:g(),completed:!1};return await this.update(t,n=>({tasks:[...n.tasks,r],lastUpdated:g()})),await this.publishEvent(t,"queue.task_added",{taskId:r.id,description:r.description,priority:r.priority,section:r.section}),r}async addTasks(t,e){let r=g(),n=e.map(i=>({...i,id:H(),createdAt:r,completed:!1}));return await this.update(t,i=>({tasks:[...i.tasks,...n],lastUpdated:r})),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,r=>({tasks:r.tasks.filter(n=>n.id!==e),lastUpdated:g()})),await this.publishEvent(t,"queue.task_removed",{taskId:e})}async deleteByFeatureId(t,e){let r=0;return await this.update(t,n=>{let i=n.tasks.length,o=n.tasks.filter(a=>a.featureId!==e);return r=i-o.length,{tasks:o,lastUpdated:g()}}),r>0&&await this.publishEvent(t,"queue.tasks_removed_by_feature",{featureId:e,count:r}),r}async completeTask(t,e){let r=null;if(await this.update(t,n=>({tasks:n.tasks.map(o=>o.id===e?(r={...o,completed:!0,completedAt:g()},r):o),lastUpdated:g()})),r){let n=r;await this.publishEvent(t,"queue.task_completed",{taskId:e,description:n.description,completedAt:n.completedAt})}return r}async moveToSection(t,e,r){await this.update(t,n=>({tasks:n.tasks.map(i=>i.id===e?{...i,section:r}:i),lastUpdated:g()}))}async setPriority(t,e,r){await this.update(t,n=>({tasks:n.tasks.map(i=>i.id===e?{...i,priority:r}:i),lastUpdated:g()}))}async getTask(t,e){return(await this.read(t)).tasks.find(n=>n.id===e)||null}async updateTask(t,e,r){let n=null;return await this.update(t,i=>({tasks:i.tasks.map(o=>o.id===e?(n={...o,...r},n):o),lastUpdated:g()})),n&&await this.publishEvent(t,"queue.task_updated",{taskId:e}),n}async clearCompleted(t){let r=(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()})),r}async removeStaleCompleted(t){let e=await this.read(t),r=fr(_t.QUEUE_COMPLETED_DAYS),n=e.tasks.filter(o=>o.completed&&o.completedAt&&new Date(o.completedAt)<r);if(n.length===0)return 0;ut.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}},Rt=new Qe});import{z as b}from"zod";var gt,rr,er,na,Y,Kt=E(()=>{"use strict";gt=["draft","reviewed","in_progress","shipped","archived"],rr=["strategic","architecture","design"],er=b.object({verdict:b.enum(["pass","fail"]),notes:b.string(),ts:b.string()}),na=b.object({risk:b.string().min(1),mitigation:b.string().min(1)}),Y=b.object({goal:b.string().min(1),eli10:b.string().default(""),stakes:b.string().default(""),acceptance_criteria:b.array(b.string().min(1)).default([]),scope:b.array(b.string()).default([]),out_of_scope:b.array(b.string()).default([]),risks:b.array(na).default([]),test_plan:b.array(b.string()).default([]),reviews:b.object({strategic:er.optional(),architecture:er.optional(),design:er.optional()}).optional(),linked_tasks:b.array(b.string()).default([]),notes:b.string().default(""),tasks_created_at:b.string().nullable().default(null)})});var sr,x,Vt=E(()=>{"use strict";wt();Kt();N();M();sr=class{static{c(this,"SpecStorage")}nextUpdatedAt(t,e){let r=g(),i=y.get(t,"SELECT updated_at FROM specs WHERE id = ?",e)?.updated_at;return!i||r>i?r:new Date(new Date(i).getTime()+1).toISOString()}create(t,e){let r=H(),n=g(),i=Y.parse(e.content);return y.run(t,`INSERT INTO specs (id, title, status, content, tags, created_at, updated_at)
600
+ VALUES (?, ?, 'draft', ?, ?, ?, ?)`,r,e.title,JSON.stringify(i),e.tags?JSON.stringify(e.tags):null,n,n),{id:r,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 r=y.get(t,"SELECT * FROM specs WHERE id = ?",e);return r?this.rowToSpec(r):null}list(t,e={}){let r="SELECT * FROM specs WHERE 1=1",n=[];return e.status&&(r+=" AND status = ?",n.push(e.status)),!e.includeArchived&&!e.status&&(r+=" AND status != 'archived'"),r+=" ORDER BY created_at DESC",y.query(t,r,...n).map(o=>this.rowToSpec(o))}search(t,e){let r=`%${e}%`;return y.query(t,"SELECT * FROM specs WHERE title LIKE ? OR content LIKE ? ORDER BY created_at DESC",r,r).map(i=>this.rowToSpec(i))}updateContent(t,e,r){let n=Y.parse(r),i=this.nextUpdatedAt(t,e);return y.run(t,"UPDATE specs SET content = ?, updated_at = ? WHERE id = ?",JSON.stringify(n),i,e),this.get(t,e)}casUpdate(t,e,r,n){let i=Y.parse(r),o=this.nextUpdatedAt(t,e);return y.run(t,"UPDATE specs SET content = ?, updated_at = ? WHERE id = ? AND updated_at = ?",JSON.stringify(i),o,e,n).changes===1}setStatus(t,e,r){if(!gt.includes(r))throw new Error(`invalid spec status: ${r}`);let n=this.nextUpdatedAt(t,e),i=[],o=[r,n];r==="shipped"&&(i.push("shipped_at = ?"),o.push(n)),r==="archived"&&(i.push("archived_at = ?"),o.push(n));let a=["status = ?","updated_at = ?",...i].join(", ");return o.push(e),y.run(t,`UPDATE specs SET ${a} WHERE id = ?`,...o),this.get(t,e)}setShippedPr(t,e,r){return y.run(t,"UPDATE specs SET shipped_pr = ?, updated_at = ? WHERE id = ?",r,this.nextUpdatedAt(t,e),e),this.get(t,e)}setShippedSha(t,e,r){return y.run(t,"UPDATE specs SET shipped_sha = ?, updated_at = ? WHERE id = ?",r,this.nextUpdatedAt(t,e),e),this.get(t,e)}linkTask(t,e,r){let n=this.get(t,e);if(!n)return null;if(n.content.linked_tasks.includes(r))return n;let i={...n.content,linked_tasks:[...n.content.linked_tasks,r]};return this.updateContent(t,e,i)}delete(t,e){return this.get(t,e)?(y.run(t,"DELETE FROM specs WHERE id = ?",e),!0):!1}count(t){let e=y.query(t,"SELECT status, COUNT(*) AS n FROM specs GROUP BY status"),r={total:0,draft:0,shipped:0};for(let n of e)r.total+=n.n,n.status==="draft"&&(r.draft=n.n),n.status==="shipped"&&(r.shipped=n.n);return r}rowToSpec(t){return{id:t.id,title:t.title,status:gt.includes(t.status)?t.status:"draft",content:Y.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}}},x=new sr});var Vn={};K(Vn,{inferSpecContext:()=>aa,warnNoContextMatch:()=>la});async function aa(s,t,e){let[r,n]=await Promise.all([Jt(s,e,{maxFiles:Kn*4,minScore:oa}).catch(()=>({files:[]})),Promise.resolve(L.recall(t,{topic:s,limit:ia})).catch(()=>[])]),i=ca(r.files.map(u=>u.path),Kn);return i.length===0&&n.length===0?{notesBlock:"",paths:[],memoryHits:0,empty:!0}:{notesBlock:ua(s,i,n),paths:i,memoryHits:n.length,empty:!1}}function ca(s,t){let e=new Set,r=[];for(let n of s){let i=n.split("/").slice(0,2).join("/");if(!e.has(i)&&(e.add(i),r.push(n),r.length>=t))break}return r}function ua(s,t,e){let r=[];if(r.push("<!-- auto-context:tentative -->"),r.push("## Existing context (auto-inferred)"),r.push(""),r.push(`_Inferred from title "${s}". Validate before audit \u2014 entries tagged tentative._`),r.push(""),t.length>0){r.push("### Likely paths");for(let n of t)r.push(`- \`${n}\``);r.push("")}if(e.length>0){r.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(" ");r.push(`- **${n.type}**${o?` _(${o})_`:""} \u2014 ${i}`)}r.push("")}return r.push("<!-- /auto-context -->"),r.join(`
601
+ `)}function la(s,t){let e={level:"warn",code:"no_context_match",message:`No codebase or memory context matched "${s}"`,suggestion:t??"Fill spec.notes manually or run with `--skip-context` next time."};process.stderr.write(`${JSON.stringify(e)}
602
+ `)}var Kn,ia,oa,Qn=E(()=>{"use strict";mt();qe();Kn=5,ia=8,oa=.15;c(aa,"inferSpecContext");c(ca,"dedupeTopDirs");c(ua,"buildNotesBlock");c(la,"warnNoContextMatch")});var Zn={};K(Zn,{breakdownSpecToTasks:()=>pa});async function pa(s,t,e){let r=e.content.acceptance_criteria;if(r.length===0)return{taskIds:[],skippedReason:"no_acceptance_criteria"};if(e.content.tasks_created_at!==null)return{taskIds:[],skippedReason:"already_broken_down"};let n=!1;if(e.content.linked_tasks.length>0){n=!0,await Rt.deleteByFeatureId(s,e.id);let a={...e.content,linked_tasks:[]};x.updateContent(s,e.id,a)}let i=await Rt.addTasks(s,r.map(a=>({description:da(a),body:a,priority:"medium",type:"feature",section:"backlog",featureId:e.id,groupId:e.id,groupName:e.title})));for(let a of i)x.linkTask(s,e.id,a.id);let o=x.get(s,e.id);if(o){let a={...o.content,tasks_created_at:g()};x.updateContent(s,e.id,a)}return await L.remember(t,{type:"spec",content:`Auto-breakdown: ${i.length} tasks created from ${e.title}${n?" (recovered from partial)":""}`,tags:{spec_id:e.id,event:"auto_breakdown",task_count:String(i.length),...n?{recovered:"partial"}:{}},source:e.id}),{taskIds:i.map(a=>a.id),...n?{recoveredFromPartial:!0}:{}}}function da(s){let t=s.replace(/\s+/g," ").trim();return t.length<=140?t:`${t.slice(0,137)}\u2026`}var ti=E(()=>{"use strict";mt();Ze();Vt();N();c(pa,"breakdownSpecToTasks");c(da,"truncateForDescription")});import{StdioServerTransport as Sa}from"@modelcontextprotocol/sdk/server/stdio.js";import{McpServer as Ea}from"@modelcontextprotocol/sdk/server/mcp.js";import{z as D}from"zod";ee();M();U();import ns from"node:fs/promises";import at from"node:path";function Ci(s){let t=[],e,r=new RegExp(mr.source,"g");for(;(e=r.exec(s))!==null;){let n=e[1];(n.startsWith(".")||n.startsWith("@/"))&&t.push(n)}return t}c(Ci,"extractImportSources");async function Ii(s,t,e){let r;if(s.startsWith("@/"))r=at.join(e,"src",s.slice(2));else{let n=at.dirname(at.join(e,t));r=at.resolve(n,s)}for(let n of dr){let i=r+n;try{if((await ns.stat(i)).isFile())return at.relative(e,i)}catch{}}return null}c(Ii,"resolveImport");async function Di(s){let t=await wr(s),e={},r={},n=0,i=await br(t,50,async o=>{try{let a=await ns.readFile(at.join(s,o),"utf-8"),u=Ci(a),l=[];for(let d of u){let m=await Ii(d,o,s);m&&m!==o&&l.push(m)}return l.length>0?{filePath:o,imports:l}:null}catch{return null}});for(let{filePath:o,imports:a}of i){e[o]=a,n+=a.length;for(let u of a)r[u]||(r[u]=[]),r[u].push(o)}return{forward:e,reverse:r,fileCount:t.length,edgeCount:n,builtAt:new Date().toISOString()}}c(Di,"buildGraph");function is(s,t,e=2){let r=new Set(s),n=new Map,i=[];for(let o of s){let a=t.forward[o]||[],u=t.reverse[o]||[];for(let l of[...a,...u])r.has(l)||i.push({file:l,depth:1})}for(;i.length>0;){let{file:o,depth:a}=i.shift();if(a>e)continue;let u=1/(a+1),l=n.get(o);if(l){u>l.score&&n.set(o,{score:u,depth:a});continue}if(n.set(o,{score:u,depth:a}),a<e){let d=t.forward[o]||[],m=t.reverse[o]||[];for(let f of[...d,...m])!r.has(f)&&!n.has(f)&&i.push({file:f,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(is,"scoreFromSeeds");var ke="import-graph",jt=new Map;function Li(s,t){y.setDoc(s,ke,t),jt.delete(s)}c(Li,"saveGraph");function Tt(s){let t=y.get(s,"SELECT updated_at FROM kv_store WHERE key = ?",ke);if(!t)return jt.delete(s),null;let e=jt.get(s);if(e&&e.updatedAt===t.updated_at)return e.graph;let r=y.getDoc(s,ke);return r&&jt.set(s,{graph:r,updatedAt:t.updated_at}),r}c(Tt,"loadGraph");async function os(s,t){let e=await Di(s);return Li(t,e),e}c(os,"indexImports");function as(s,t){let e=[...s.added,...s.modified],r=new Set(e),n=new Set,i=Tt(t);if(i)for(let u of e){let l=i.reverse[u];if(l)for(let d of l)r.has(d)||n.add(d)}let o=Array.from(n),a=[...e,...o];return{directlyChanged:e,affectedByImports:o,deleted:s.deleted,allAffected:a}}c(as,"propagateChanges");function cs(s){let t=new Set;for(let e of s){let r=e.toLowerCase();(r.endsWith(".tsx")||r.endsWith(".jsx")||r.endsWith(".css")||r.endsWith(".scss")||r.endsWith(".vue")||r.endsWith(".svelte")||r.includes("/components/")||r.includes("/pages/")||r.includes("/app/"))&&(t.add("frontend"),t.add("uxui")),(r.includes(".test.")||r.includes(".spec.")||r.includes("__tests__")||r.includes("/test/"))&&t.add("testing"),(r.includes("dockerfile")||r.includes("docker-compose")||r.includes(".dockerignore")||r.includes(".github/")||r.includes("ci/")||r.includes("cd/"))&&t.add("devops"),(r.endsWith(".sql")||r.includes("prisma")||r.includes("drizzle")||r.includes("migration")||r.includes("/db/"))&&t.add("database"),(r.endsWith(".ts")||r.endsWith(".js"))&&!r.includes(".test.")&&!r.includes(".spec.")&&!r.endsWith(".d.ts")&&t.add("backend")}return t}c(cs,"affectedDomains");M();it();async function Mi(s,t=100){try{let{stdout:e}=await _(`git log --name-only --pretty=format:'---COMMIT---' -${t}`,{cwd:s,maxBuffer:10485760}),r=[],n=null;for(let i of e.split(`
603
+ `)){let o=i.trim();o==="---COMMIT---"?(n&&n.size>0&&n.size<=30&&r.push(n),n=new Set):o&&n&&ji(o)&&n.add(o)}return n&&n.size>0&&n.size<=30&&r.push(n),r}catch{return[]}}c(Mi,"parseGitLog");function ji(s){return/\.(ts|tsx|js|jsx|mjs|cjs|py|go|rs|java|cs|rb|php|vue|svelte)$/i.test(s)&&!s.includes("node_modules/")}c(ji,"isSourceFile");async function Fi(s,t=100){let e=await Mi(s,t),r=new Map,n=new Map;for(let o of e){let a=Array.from(o);for(let u of a)r.set(u,(r.get(u)||0)+1);for(let u=0;u<a.length;u++)for(let l=u+1;l<a.length;l++){let d=Ui(a[u],a[l]);n.set(d,(n.get(d)||0)+1)}}let i={};for(let[o,a]of n){let[u,l]=o.split("\0"),d=r.get(u)||0,m=r.get(l)||0;if(d<2||m<2)continue;let f=d+m-a,T=f>0?a/f:0;T<.1||(i[u]||(i[u]={}),i[l]||(i[l]={}),i[u][l]=T,i[l][u]=T)}return{matrix:i,commitsAnalyzed:e.length,filesAnalyzed:r.size,builtAt:new Date().toISOString()}}c(Fi,"buildMatrix");function Ui(s,t){return s<t?`${s}\0${t}`:`${t}\0${s}`}c(Ui,"pairKey");function we(s,t){let e=new Set(s),r=new Map;for(let n of s){let i=t.matrix[n];if(i)for(let[o,a]of Object.entries(i)){if(e.has(o))continue;let u=r.get(o)||0;a>u&&r.set(o,a)}}return Array.from(r.entries()).map(([n,i])=>({path:n,score:i})).sort((n,i)=>i.score-n.score)}c(we,"scoreFromSeeds");var Se="cochange-index",Ft=new Map;function $i(s,t){y.setDoc(s,Se,t),Ft.delete(s)}c($i,"saveMatrix");function be(s){let t=y.get(s,"SELECT updated_at FROM kv_store WHERE key = ?",Se);if(!t)return Ft.delete(s),null;let e=Ft.get(s);if(e&&e.updatedAt===t.updated_at)return e.matrix;let r=y.getDoc(s,Se);return r&&Ft.set(s,{matrix:r,updatedAt:t.updated_at}),r}c(be,"loadMatrix");async function ps(s,t,e=100){let r=await Fi(s,e);return $i(t,r),r}c(ps,"indexCoChanges");kt();async function R(s){return B.getProjectId(s)}c(R,"resolveProjectId");function S(s,t){return async e=>{try{return await t(e)}catch(r){return zi(r,s)}}}c(S,"safeMcpCall");function zi(s,t){let e=s instanceof Error?s.message:String(s);return{content:[{type:"text",text:`[${t}] Error: ${e}`}],isError:!0}}c(zi,"mcpError");function Es(s){let t=s;t.tool("prjct_impact_analysis","Given changed files, find affected files via import graph + affected domains",{projectPath:D.string().describe("Project directory path"),changedFiles:D.array(D.string()).describe("List of changed file paths (relative to project root)")},S("prjct_impact_analysis",async e=>{let r=await R(e.projectPath),n={added:[],modified:e.changedFiles,deleted:[],unchanged:[]},i=as(n,r),o=cs(i.allAffected),a=["## Impact Analysis"];a.push(`
593
604
  ### Directly Changed (${i.directlyChanged.length})`);for(let u of i.directlyChanged)a.push(`- ${u}`);if(i.affectedByImports.length>0){a.push(`
594
605
  ### Affected via Imports (${i.affectedByImports.length})`);for(let u of i.affectedByImports)a.push(`- ${u}`)}return a.push(`
595
606
  ### Affected Domains`),a.push(o.size>0?Array.from(o).join(", "):"none detected"),a.push(`
@@ -600,12 +611,12 @@ Total affected: ${i.allAffected.length} files`),{content:[{type:"text",text:a.jo
600
611
  `)}]}}return{content:[{type:"text",text:["## Import Graph Stats",`Files: ${n.fileCount}`,`Edges: ${n.edgeCount}`,`Built: ${n.builtAt}`].join(`
601
612
  `)}]}})),t.tool("prjct_cochange","Files that historically change together (Jaccard similarity from git history)",{projectPath:D.string().describe("Project directory path"),seedFiles:D.array(D.string()).describe("Seed files to find co-change partners for"),rebuild:D.boolean().optional().default(!1).describe("Force rebuild the co-change matrix"),maxResults:D.number().optional().default(10).describe("Max results (default 10)")},S("prjct_cochange",async e=>{let r=await R(e.projectPath),n=e.rebuild?null:be(r);n||(n=await ps(e.projectPath,r));let i=we(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(`
602
613
  `)}]}})),t.tool("prjct_related_context","Combined: import neighbors + co-change partners for seed files",{projectPath:D.string().describe("Project directory path"),seedFiles:D.array(D.string()).describe("Seed files to find related context for"),maxResults:D.number().optional().default(15).describe("Max results (default 15)")},S("prjct_related_context",async e=>{let r=await R(e.projectPath),n=Tt(r),i=n?is(e.seedFiles,n):[],o=be(r),a=o?we(e.seedFiles,o):[],u=new Map;for(let m of i)u.set(m.path,{importScore:m.score,cochangeScore:0});for(let m of a){let f=u.get(m.path);f?f.cochangeScore=m.score:u.set(m.path,{importScore:0,cochangeScore:m.score})}let l=Array.from(u.entries()).map(([m,f])=>({path:m,combined:f.importScore*.6+f.cochangeScore*.4,importScore:f.importScore,cochangeScore:f.cochangeScore})).sort((m,f)=>f.combined-m.combined).slice(0,e.maxResults);if(l.length===0)return{content:[{type:"text",text:"No related files found. Run `prjct sync` to build indexes."}]};let d=["## Related Context",`Seeds: ${e.seedFiles.join(", ")}`,""];for(let m of l){let f=[];m.importScore>0&&f.push(`import: ${m.importScore.toFixed(2)}`),m.cochangeScore>0&&f.push(`cochange: ${Math.round(m.cochangeScore*100)}%`),d.push(`- ${m.path} (${f.join(", ")})`)}return{content:[{type:"text",text:d.join(`
603
- `)}]}}))}c(Es,"registerCodeIntelTools");import{z as rt}from"zod";Bt();N();var St={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"}},Ce=class{static{c(this,"WorkflowStateMachine")}getCurrentState(t,e){let r=null;if(e&&t?.activeTasks?.length&&(r=t.activeTasks.find(i=>i.workspaceId===e)),r||(r=t?.currentTask),!r)return(t?.pausedTasks?.length||0)>0||t?.previousTask?.status==="paused"?"paused":"idle";switch((typeof r.status=="string"?r.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 r?"working":"idle"}}canTransition(t,e){if(St[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 St[t]}getPrompt(t){return St[t].prompt}getValidCommands(t){return St[t].transitions}formatNextSteps(t){return St[t].transitions.map(r=>{switch(r){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 ${r}`}})}},Ie=new Ce;wt();N();qt();async function Os(s,t,e){let r=await s.read(t);if(!r.currentTask)return null;s.validateTransition(r,"pause");let n={...r.currentTask,status:"paused",pausedAt:g(),pauseReason:e},i=s.getPausedTasksFromState(r),o=[n,...i].slice(0,s.maxPausedTasks);return await s.update(t,a=>({...a,currentTask:null,previousTask:null,pausedTasks:o,lastUpdated:g()})),await s.publish(t,"task.paused",{taskId:n.id,description:n.description,pausedAt:n.pausedAt,reason:e,pausedCount:o.length}),n}c(Os,"pauseTask");async function Ms(s,t,e){let r=await s.read(t),n=s.getPausedTasksFromState(r);if(n.length===0)return null;s.validateTransition(r,"resume");let i=0;if(e&&(i=n.findIndex(T=>T.id===e),i===-1))return null;let o=n[i],a=n.filter((T,M)=>M!==i),{status:u,pausedAt:l,pauseReason:d,...m}=o,f={...m,startedAt:g(),sessionId:o.sessionId??H()};return await s.update(t,T=>({...T,currentTask:f,previousTask:null,pausedTasks:a,lastUpdated:g()})),await s.publish(t,"task.resumed",{taskId:f.id,description:f.description,resumedAt:f.startedAt,remainingPaused:a.length}),f}c(Ms,"resumeTask");async function js(s,t){let e=await s.read(t),r=s.getPausedTasksFromState(e),n=Date.now()-s.stalenessThresholdDays*24*60*60*1e3;return r.filter(i=>new Date(i.pausedAt).getTime()<n)}c(js,"getStalePausedTasks");async function Fs(s,t){let e=await s.read(t),r=s.getPausedTasksFromState(e),n=Date.now()-s.stalenessThresholdDays*24*60*60*1e3,i=r.filter(a=>new Date(a.pausedAt).getTime()<n),o=r.filter(a=>new Date(a.pausedAt).getTime()>=n);if(i.length===0)return[];ut.archiveMany(t,i.map(a=>({entityType:"paused_task",entityId:a.id,entityData:a,summary:a.description,reason:"staleness"}))),await s.update(t,a=>({...a,pausedTasks:o,previousTask:null,lastUpdated:g()}));for(let a of i)await s.publish(t,"task.archived",{taskId:a.id,description:a.description,pausedAt:a.pausedAt,reason:"staleness"});return i}c(Fs,"archiveStalePausedTasks");N();async function Us(s,t){await s.update(t,()=>({currentTask:null,previousTask:null,pausedTasks:[],activeTasks:[],lastUpdated:g()}))}c(Us,"clearTask");async function $s(s,t){let e=await s.read(t),r=s.getPausedTasksFromState(e);return e.currentTask!==null||r.length>0}c($s,"hasTask");async function Xs(s,t){let e=await s.read(t);return s.getPausedTasksFromState(e)[0]||null}c(Xs,"getPausedTask");async function Ws(s,t){let e=await s.read(t);return s.getPausedTasksFromState(e)}c(Ws,"getAllPausedTasks");async function Xe(s,t){let e=await s.read(t);return s.getTaskHistoryFromState(e)}c(Xe,"getTaskHistory");async function Bs(s,t){let e=await s.read(t);return s.getTaskHistoryFromState(e)[0]||null}c(Bs,"getMostRecentTask");async function Hs(s,t,e){let r=await s.read(t);return s.getTaskHistoryFromState(r).filter(i=>i.classification===e)}c(Hs,"getTaskHistoryByType");async function qs(s,t){let r=(await Xe(s,t)).filter(f=>f.feedback),n=[],i=[],o=[],a=[];for(let f of r){let T=f.feedback;Array.isArray(T.stackConfirmed)&&n.push(...T.stackConfirmed),Array.isArray(T.patternsDiscovered)&&i.push(...T.patternsDiscovered),Array.isArray(T.agentAccuracy)&&o.push(...T.agentAccuracy),Array.isArray(T.issuesEncountered)&&a.push(...T.issuesEncountered)}let u=[...new Set(n)],l=[...new Set(i)],d=new Map;for(let f of a)d.set(f,(d.get(f)||0)+1);let m=[...d.entries()].filter(([f,T])=>T>=2).map(([f])=>f);return{stackConfirmed:u,patternsDiscovered:l,agentAccuracy:o,issuesEncountered:[...new Set(a)],knownGotchas:m}}c(qs,"getAggregatedFeedback");Bt();N();async function Gs(s,t,e){let r=await s.read(t);if(!r.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 s.update(t,i=>({...i,currentTask:{...i.currentTask,subtasks:n,currentSubtaskIndex:0,subtaskProgress:{completed:0,total:n.length,percentage:0}},lastUpdated:g()})),await s.publish(t,"subtasks.created",{taskId:r.currentTask.id,subtaskCount:n.length,subtasks:n.map(i=>({id:i.id,description:i.description,domain:i.domain}))})}c(Gs,"createSubtasks");async function Ys(s,t,e){let r=Ss.safeParse(e);if(!r.success){let M=r.error.issues.map(z=>`${z.path.join(".")}: ${z.message}`);throw new Error(`Subtask completion requires handoff data:
604
- ${M.join(`
605
- `)}`)}let{output:n,summary:i}=r.data,o=await s.read(t);if(!o.currentTask?.subtasks)return null;let a=o.currentTask.currentSubtaskIndex||0,u=o.currentTask.subtasks[a];if(!u)return null;let l=[...o.currentTask.subtasks];l[a]={...u,status:"completed",completedAt:g(),output:n,summary:i};let d=l.filter(M=>M.status==="completed").length,m=l.length,f=Math.round(d/m*100),T=a+1;return T<l.length&&(l[T]={...l[T],status:"in_progress",startedAt:g()}),await s.update(t,M=>({...M,currentTask:{...M.currentTask,subtasks:l,currentSubtaskIndex:T<m?T:a,subtaskProgress:{completed:d,total:m,percentage:f}},lastUpdated:g()})),await s.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:d,total:m,percentage:f}}),T<m?l[T]:null}c(Ys,"completeSubtask");async function Js(s,t){let e=await s.read(t);if(!e.currentTask?.subtasks)return null;let r=e.currentTask.currentSubtaskIndex||0;return e.currentTask.subtasks[r]||null}c(Js,"getCurrentSubtask");async function zs(s,t){let e=await s.read(t);if(!e.currentTask?.subtasks)return null;let r=(e.currentTask.currentSubtaskIndex||0)+1;return e.currentTask.subtasks[r]||null}c(zs,"getNextSubtask");async function We(s,t){let e=await s.read(t);if(!e.currentTask?.subtasks)return null;let r=(e.currentTask.currentSubtaskIndex||0)-1;return r<0?null:e.currentTask.subtasks[r]||null}c(We,"getPreviousSubtask");async function Ks(s,t){let e=await We(s,t);return e?.summary?.outputForNextAgent?{fromSubtask:e.description,outputForNextAgent:e.summary.outputForNextAgent,filesChanged:e.summary.filesChanged,whatWasDone:e.summary.whatWasDone}:null}c(Ks,"getPreviousHandoff");async function Vs(s,t){return(await s.read(t)).currentTask?.subtasks||[]}c(Vs,"getSubtasks");async function Qs(s,t){return(await s.read(t)).currentTask?.subtaskProgress||null}c(Qs,"getSubtaskProgress");async function Zs(s,t){return((await s.read(t)).currentTask?.subtasks?.length||0)>0}c(Zs,"hasSubtasks");async function tn(s,t){let e=await s.read(t);return e.currentTask?.subtasks?e.currentTask.subtasks.every(r=>r.status==="completed"||r.status==="failed"||r.status==="skipped"):!0}c(tn,"areAllSubtasksComplete");async function en(s,t,e){let r=await s.read(t);if(!r.currentTask?.subtasks)return null;let n=r.currentTask.currentSubtaskIndex||0,i=r.currentTask.subtasks[n];if(!i)return null;let o=[...r.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 l=o.filter(m=>m.status==="completed"||m.status==="failed"||m.status==="skipped").length,d=Math.round(l/u*100);return await s.update(t,m=>({...m,currentTask:{...m.currentTask,subtasks:o,currentSubtaskIndex:a<u?a:n,subtaskProgress:{completed:l,total:u,percentage:d}},lastUpdated:g()})),await s.publish(t,"subtask.failed",{taskId:r.currentTask.id,subtaskId:i.id,description:i.description,error:e}),a<u?o[a]:null}c(en,"failSubtask");async function rn(s,t,e){let r=await s.read(t);if(!r.currentTask?.subtasks)return null;let n=r.currentTask.currentSubtaskIndex||0,i=r.currentTask.subtasks[n];if(!i)return null;let o=[...r.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 l=o.filter(m=>m.status==="completed"||m.status==="failed"||m.status==="skipped").length,d=Math.round(l/u*100);return await s.update(t,m=>({...m,currentTask:{...m.currentTask,subtasks:o,currentSubtaskIndex:a<u?a:n,subtaskProgress:{completed:l,total:u,percentage:d}},lastUpdated:g()})),await s.publish(t,"subtask.skipped",{taskId:r.currentTask.id,subtaskId:i.id,description:i.description,reason:e}),a<u?o[a]:null}c(rn,"skipSubtask");async function sn(s,t,e){let r=await s.read(t);if(!r.currentTask?.subtasks)return null;let n=r.currentTask.currentSubtaskIndex||0,i=r.currentTask.subtasks[n];if(!i)return null;let o=[...r.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 s.update(t,l=>({...l,currentTask:{...l.currentTask,subtasks:o,currentSubtaskIndex:a<u?a:n},lastUpdated:g()})),await s.publish(t,"subtask.blocked",{taskId:r.currentTask.id,subtaskId:i.id,description:i.description,blocker:e}),a<u?o[a]:null}c(sn,"blockSubtask");N();async function nn(s,t,e,r){let n={...e,workspaceId:r,startedAt:g()};return await s.update(t,i=>({...i,activeTasks:[...i.activeTasks||[],n],lastUpdated:g()})),await s.publish(t,"task.started",{taskId:n.id,description:n.description,startedAt:n.startedAt,sessionId:n.sessionId,workspaceId:r}),n}c(nn,"startTaskInWorkspace");async function on(s,t,e){return((await s.read(t)).activeTasks||[]).find(n=>n.workspaceId===e)??null}c(on,"getCurrentTaskForWorkspace");async function an(s,t,e,r){let n=await s.read(t),o=(n.activeTasks||[]).find(m=>m.workspaceId===e);if(!o)return null;let a=g(),u=s.createTaskHistoryEntry(o,a,r),l=s.getTaskHistoryFromState(n),d=[u,...l].slice(0,s.maxTaskHistory);return await s.update(t,m=>({...m,activeTasks:(m.activeTasks||[]).filter(f=>f.workspaceId!==e),taskHistory:d,lastUpdated:a})),await s.publish(t,"task.completed",{taskId:o.id,description:o.description,startedAt:o.startedAt,completedAt:a,workspaceId:e}),o}c(an,"completeTaskInWorkspace");async function cn(s,t){return(await s.read(t)).activeTasks||[]}c(cn,"getActiveTasks");async function un(s,t){return((await s.read(t)).activeTasks||[]).length}c(un,"getActiveTaskCount");async function ln(s,t,e,r){let i=(await s.read(t)).activeTasks||[],o=i.findIndex(u=>u.workspaceId===e);if(o===-1)return null;let a={...i[o],...r,workspaceId:e};return await s.update(t,u=>{let l=[...u.activeTasks||[]];return l[o]=a,{...u,activeTasks:l,lastUpdated:g()}}),a}c(ln,"updateWorkspaceTask");async function pn(s,t,e,r){let n=await s.read(t);if(!n.currentTask)return null;let i=(n.currentTask.tokensIn||0)+e,o=(n.currentTask.tokensOut||0)+r;return await s.update(t,a=>({...a,currentTask:{...a.currentTask,tokensIn:i,tokensOut:o},lastUpdated:g()})),{tokensIn:i,tokensOut:o}}c(pn,"addTokens");Be();var He=class extends lt{static{c(this,"StateStorage")}constructor(){super("state.json",vs)}getDefault(){return{currentTask:null,previousTask:null,pausedTasks:[],taskHistory:[],activeTasks:[],lastUpdated:""}}getEventType(t){return`state.${t}d`}validateTransition(t,e){let r=Ie.getCurrentState(t),n=Ie.canTransition(r,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 r=await this.read(t);this.validateTransition(r,"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 r=await this.read(t);if(!r.currentTask)return null;let n={...r.currentTask,...e};return await this.update(t,i=>({...i,currentTask:n,lastUpdated:g()})),n}async completeTask(t,e){let r=await this.read(t),n=r.currentTask;if(!n)return null;this.validateTransition(r,"done");let i=g(),o=this.createTaskHistoryEntry(n,i,e),a=this.getTaskHistoryFromState(r),u=[o,...a].slice(0,this.maxTaskHistory);return await this.update(t,l=>({...l,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,r){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 r&&(o.feedback=r),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 Os(this.lifecycleBackend(),t,e)}async resumeTask(t,e){return Ms(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 js(this.lifecycleBackend(),t)}async archiveStalePausedTasks(t){return Fs(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 Us(this.queryBackend(),t)}async hasTask(t){return $s(this.queryBackend(),t)}async getPausedTask(t){return Xs(this.queryBackend(),t)}async getAllPausedTasks(t){return Ws(this.queryBackend(),t)}async getTaskHistory(t){return Xe(this.queryBackend(),t)}async getMostRecentTask(t){return Bs(this.queryBackend(),t)}async getTaskHistoryByType(t,e){return Hs(this.queryBackend(),t,e)}async getAggregatedFeedback(t){return qs(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,r){return nn(this.workspaceBackend(),t,e,r)}async getCurrentTaskForWorkspace(t,e){return on(this.workspaceBackend(),t,e)}async completeTaskInWorkspace(t,e,r){return an(this.workspaceBackend(),t,e,r)}async getActiveTasks(t){return cn(this.workspaceBackend(),t)}async getActiveTaskCount(t){return un(this.workspaceBackend(),t)}async updateWorkspaceTask(t,e,r){return ln(this.workspaceBackend(),t,e,r)}async addTokens(t,e,r){return pn(this.workspaceBackend(),t,e,r)}subtaskBackend(){return{read:this.read.bind(this),update:this.update.bind(this),publish:this.publishEvent.bind(this)}}async createSubtasks(t,e){return Gs(this.subtaskBackend(),t,e)}async completeSubtask(t,e){return Ys(this.subtaskBackend(),t,e)}async getCurrentSubtask(t){return Js(this.subtaskBackend(),t)}async getNextSubtask(t){return zs(this.subtaskBackend(),t)}async getPreviousSubtask(t){return We(this.subtaskBackend(),t)}async getPreviousHandoff(t){return Ks(this.subtaskBackend(),t)}async getSubtasks(t){return Vs(this.subtaskBackend(),t)}async getSubtaskProgress(t){return Qs(this.subtaskBackend(),t)}async hasSubtasks(t){return Zs(this.subtaskBackend(),t)}async areAllSubtasksComplete(t){return tn(this.subtaskBackend(),t)}async failSubtask(t,e){return en(this.subtaskBackend(),t,e)}async skipSubtask(t,e){return rn(this.subtaskBackend(),t,e)}async blockSubtask(t,e){return sn(this.subtaskBackend(),t,e)}},pt=new He;qe();Z();import Ao from"node:fs/promises";import dt from"node:path";var xo={"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}},Ro="claude-sonnet-4.5";function Ge(s){return!s||s.length===0?0:Math.ceil(s.length/4)}c(Ge,"countTokens");var Tn=["claude-sonnet-4.5","claude-opus-4.5","claude-opus-4-6","gpt-4o","gemini-1.5-pro"];function yn(s,t){let e=xo[t],r=s/1e3*e.input,n=s/1e3*e.output*.3;return{inputSaved:r,outputPotential:n,total:r+n}}c(yn,"calculateModelCost");function Po(s){return s<.001?"<$0.01":s<.01?`$${s.toFixed(3)}`:`$${s.toFixed(2)}`}c(Po,"formatCostSaved");function En(s,t){let e=Ge(s),r=Ge(t),n=Math.max(0,e-r),i=e>0?(e-r)/e:0,o=yn(n,Ro),a=Tn.map(u=>({model:u,...yn(n,u)}));return{tokens:{original:e,filtered:r,saved:n},compression:Math.max(0,Math.min(1,i)),cost:{saved:o.total,formatted:Po(o.total),byModel:a}}}c(En,"measureCompression");function zt(s){let t=Ge(s);return{tokens:{original:t,filtered:t,saved:0},compression:0,cost:{saved:0,formatted:"$0.00",byModel:Tn.map(e=>({model:e,inputSaved:0,outputPotential:0,total:0}))}}}c(zt,"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"},kn=[{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}],Co=[{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}],Io=[{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}],Do=[{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}],Sn=[{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}],Lo={typescript:kn,javascript:kn,python:Co,go:Io,rust:Do,java:Sn,csharp:Sn,php:[],ruby:[],unknown:[]};async function wn(s,t=process.cwd()){let e=dt.isAbsolute(s)?s:dt.join(t,s),r=dt.resolve(t),n=dt.resolve(e);if(!n.startsWith(r+dt.sep)&&n!==r)return{file:s,language:"unknown",signatures:[],fallback:!0,fallbackReason:"Path traversal denied: file is outside project directory",metrics:zt("")};let i;try{i=await Ao.readFile(e,"utf-8")}catch(m){if(O(m))return{file:s,language:"unknown",signatures:[],fallback:!0,fallbackReason:"File not found",metrics:zt("")};throw m}let o=dt.extname(s).toLowerCase(),a=No[o]||"unknown",u=Lo[a];if(!u||u.length===0)return{file:s,language:a,signatures:[],fallback:!0,fallbackReason:`No extraction patterns for ${a}`,metrics:zt(i)};let l=Oo(i,u),d=l.map(m=>`${m.exported?"export ":""}${m.type} ${m.name}: ${m.signature}`).join(`
606
- `);return{file:s,language:a,signatures:l,fallback:!1,metrics:En(i,d)}}c(wn,"extractSignatures");function Oo(s,t){let e=[],r=s.split(`
614
+ `)}]}}))}c(Es,"registerCodeIntelTools");import{z as rt}from"zod";Bt();N();var St={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"}},Ce=class{static{c(this,"WorkflowStateMachine")}getCurrentState(t,e){let r=null;if(e&&t?.activeTasks?.length&&(r=t.activeTasks.find(i=>i.workspaceId===e)),r||(r=t?.currentTask),!r)return(t?.pausedTasks?.length||0)>0||t?.previousTask?.status==="paused"?"paused":"idle";switch((typeof r.status=="string"?r.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 r?"working":"idle"}}canTransition(t,e){if(St[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 St[t]}getPrompt(t){return St[t].prompt}getValidCommands(t){return St[t].transitions}formatNextSteps(t){return St[t].transitions.map(r=>{switch(r){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 ${r}`}})}},Ie=new Ce;wt();N();qt();async function Os(s,t,e){let r=await s.read(t);if(!r.currentTask)return null;s.validateTransition(r,"pause");let n={...r.currentTask,status:"paused",pausedAt:g(),pauseReason:e},i=s.getPausedTasksFromState(r),o=[n,...i].slice(0,s.maxPausedTasks);return await s.update(t,a=>({...a,currentTask:null,previousTask:null,pausedTasks:o,lastUpdated:g()})),await s.publish(t,"task.paused",{taskId:n.id,description:n.description,pausedAt:n.pausedAt,reason:e,pausedCount:o.length}),n}c(Os,"pauseTask");async function Ms(s,t,e){let r=await s.read(t),n=s.getPausedTasksFromState(r);if(n.length===0)return null;s.validateTransition(r,"resume");let i=0;if(e&&(i=n.findIndex(T=>T.id===e),i===-1))return null;let o=n[i],a=n.filter((T,j)=>j!==i),{status:u,pausedAt:l,pauseReason:d,...m}=o,f={...m,startedAt:g(),sessionId:o.sessionId??H()};return await s.update(t,T=>({...T,currentTask:f,previousTask:null,pausedTasks:a,lastUpdated:g()})),await s.publish(t,"task.resumed",{taskId:f.id,description:f.description,resumedAt:f.startedAt,remainingPaused:a.length}),f}c(Ms,"resumeTask");async function js(s,t){let e=await s.read(t),r=s.getPausedTasksFromState(e),n=Date.now()-s.stalenessThresholdDays*24*60*60*1e3;return r.filter(i=>new Date(i.pausedAt).getTime()<n)}c(js,"getStalePausedTasks");async function Fs(s,t){let e=await s.read(t),r=s.getPausedTasksFromState(e),n=Date.now()-s.stalenessThresholdDays*24*60*60*1e3,i=r.filter(a=>new Date(a.pausedAt).getTime()<n),o=r.filter(a=>new Date(a.pausedAt).getTime()>=n);if(i.length===0)return[];ut.archiveMany(t,i.map(a=>({entityType:"paused_task",entityId:a.id,entityData:a,summary:a.description,reason:"staleness"}))),await s.update(t,a=>({...a,pausedTasks:o,previousTask:null,lastUpdated:g()}));for(let a of i)await s.publish(t,"task.archived",{taskId:a.id,description:a.description,pausedAt:a.pausedAt,reason:"staleness"});return i}c(Fs,"archiveStalePausedTasks");N();async function Us(s,t){await s.update(t,()=>({currentTask:null,previousTask:null,pausedTasks:[],activeTasks:[],lastUpdated:g()}))}c(Us,"clearTask");async function $s(s,t){let e=await s.read(t),r=s.getPausedTasksFromState(e);return e.currentTask!==null||r.length>0}c($s,"hasTask");async function Xs(s,t){let e=await s.read(t);return s.getPausedTasksFromState(e)[0]||null}c(Xs,"getPausedTask");async function Ws(s,t){let e=await s.read(t);return s.getPausedTasksFromState(e)}c(Ws,"getAllPausedTasks");async function Xe(s,t){let e=await s.read(t);return s.getTaskHistoryFromState(e)}c(Xe,"getTaskHistory");async function Bs(s,t){let e=await s.read(t);return s.getTaskHistoryFromState(e)[0]||null}c(Bs,"getMostRecentTask");async function Hs(s,t,e){let r=await s.read(t);return s.getTaskHistoryFromState(r).filter(i=>i.classification===e)}c(Hs,"getTaskHistoryByType");async function qs(s,t){let r=(await Xe(s,t)).filter(f=>f.feedback),n=[],i=[],o=[],a=[];for(let f of r){let T=f.feedback;Array.isArray(T.stackConfirmed)&&n.push(...T.stackConfirmed),Array.isArray(T.patternsDiscovered)&&i.push(...T.patternsDiscovered),Array.isArray(T.agentAccuracy)&&o.push(...T.agentAccuracy),Array.isArray(T.issuesEncountered)&&a.push(...T.issuesEncountered)}let u=[...new Set(n)],l=[...new Set(i)],d=new Map;for(let f of a)d.set(f,(d.get(f)||0)+1);let m=[...d.entries()].filter(([f,T])=>T>=2).map(([f])=>f);return{stackConfirmed:u,patternsDiscovered:l,agentAccuracy:o,issuesEncountered:[...new Set(a)],knownGotchas:m}}c(qs,"getAggregatedFeedback");Bt();N();async function Gs(s,t,e){let r=await s.read(t);if(!r.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 s.update(t,i=>({...i,currentTask:{...i.currentTask,subtasks:n,currentSubtaskIndex:0,subtaskProgress:{completed:0,total:n.length,percentage:0}},lastUpdated:g()})),await s.publish(t,"subtasks.created",{taskId:r.currentTask.id,subtaskCount:n.length,subtasks:n.map(i=>({id:i.id,description:i.description,domain:i.domain}))})}c(Gs,"createSubtasks");async function Ys(s,t,e){let r=Ss.safeParse(e);if(!r.success){let j=r.error.issues.map(z=>`${z.path.join(".")}: ${z.message}`);throw new Error(`Subtask completion requires handoff data:
615
+ ${j.join(`
616
+ `)}`)}let{output:n,summary:i}=r.data,o=await s.read(t);if(!o.currentTask?.subtasks)return null;let a=o.currentTask.currentSubtaskIndex||0,u=o.currentTask.subtasks[a];if(!u)return null;let l=[...o.currentTask.subtasks];l[a]={...u,status:"completed",completedAt:g(),output:n,summary:i};let d=l.filter(j=>j.status==="completed").length,m=l.length,f=Math.round(d/m*100),T=a+1;return T<l.length&&(l[T]={...l[T],status:"in_progress",startedAt:g()}),await s.update(t,j=>({...j,currentTask:{...j.currentTask,subtasks:l,currentSubtaskIndex:T<m?T:a,subtaskProgress:{completed:d,total:m,percentage:f}},lastUpdated:g()})),await s.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:d,total:m,percentage:f}}),T<m?l[T]:null}c(Ys,"completeSubtask");async function Js(s,t){let e=await s.read(t);if(!e.currentTask?.subtasks)return null;let r=e.currentTask.currentSubtaskIndex||0;return e.currentTask.subtasks[r]||null}c(Js,"getCurrentSubtask");async function zs(s,t){let e=await s.read(t);if(!e.currentTask?.subtasks)return null;let r=(e.currentTask.currentSubtaskIndex||0)+1;return e.currentTask.subtasks[r]||null}c(zs,"getNextSubtask");async function We(s,t){let e=await s.read(t);if(!e.currentTask?.subtasks)return null;let r=(e.currentTask.currentSubtaskIndex||0)-1;return r<0?null:e.currentTask.subtasks[r]||null}c(We,"getPreviousSubtask");async function Ks(s,t){let e=await We(s,t);return e?.summary?.outputForNextAgent?{fromSubtask:e.description,outputForNextAgent:e.summary.outputForNextAgent,filesChanged:e.summary.filesChanged,whatWasDone:e.summary.whatWasDone}:null}c(Ks,"getPreviousHandoff");async function Vs(s,t){return(await s.read(t)).currentTask?.subtasks||[]}c(Vs,"getSubtasks");async function Qs(s,t){return(await s.read(t)).currentTask?.subtaskProgress||null}c(Qs,"getSubtaskProgress");async function Zs(s,t){return((await s.read(t)).currentTask?.subtasks?.length||0)>0}c(Zs,"hasSubtasks");async function tn(s,t){let e=await s.read(t);return e.currentTask?.subtasks?e.currentTask.subtasks.every(r=>r.status==="completed"||r.status==="failed"||r.status==="skipped"):!0}c(tn,"areAllSubtasksComplete");async function en(s,t,e){let r=await s.read(t);if(!r.currentTask?.subtasks)return null;let n=r.currentTask.currentSubtaskIndex||0,i=r.currentTask.subtasks[n];if(!i)return null;let o=[...r.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 l=o.filter(m=>m.status==="completed"||m.status==="failed"||m.status==="skipped").length,d=Math.round(l/u*100);return await s.update(t,m=>({...m,currentTask:{...m.currentTask,subtasks:o,currentSubtaskIndex:a<u?a:n,subtaskProgress:{completed:l,total:u,percentage:d}},lastUpdated:g()})),await s.publish(t,"subtask.failed",{taskId:r.currentTask.id,subtaskId:i.id,description:i.description,error:e}),a<u?o[a]:null}c(en,"failSubtask");async function rn(s,t,e){let r=await s.read(t);if(!r.currentTask?.subtasks)return null;let n=r.currentTask.currentSubtaskIndex||0,i=r.currentTask.subtasks[n];if(!i)return null;let o=[...r.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 l=o.filter(m=>m.status==="completed"||m.status==="failed"||m.status==="skipped").length,d=Math.round(l/u*100);return await s.update(t,m=>({...m,currentTask:{...m.currentTask,subtasks:o,currentSubtaskIndex:a<u?a:n,subtaskProgress:{completed:l,total:u,percentage:d}},lastUpdated:g()})),await s.publish(t,"subtask.skipped",{taskId:r.currentTask.id,subtaskId:i.id,description:i.description,reason:e}),a<u?o[a]:null}c(rn,"skipSubtask");async function sn(s,t,e){let r=await s.read(t);if(!r.currentTask?.subtasks)return null;let n=r.currentTask.currentSubtaskIndex||0,i=r.currentTask.subtasks[n];if(!i)return null;let o=[...r.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 s.update(t,l=>({...l,currentTask:{...l.currentTask,subtasks:o,currentSubtaskIndex:a<u?a:n},lastUpdated:g()})),await s.publish(t,"subtask.blocked",{taskId:r.currentTask.id,subtaskId:i.id,description:i.description,blocker:e}),a<u?o[a]:null}c(sn,"blockSubtask");N();async function nn(s,t,e,r){let n={...e,workspaceId:r,startedAt:g()};return await s.update(t,i=>({...i,activeTasks:[...i.activeTasks||[],n],lastUpdated:g()})),await s.publish(t,"task.started",{taskId:n.id,description:n.description,startedAt:n.startedAt,sessionId:n.sessionId,workspaceId:r}),n}c(nn,"startTaskInWorkspace");async function on(s,t,e){return((await s.read(t)).activeTasks||[]).find(n=>n.workspaceId===e)??null}c(on,"getCurrentTaskForWorkspace");async function an(s,t,e,r){let n=await s.read(t),o=(n.activeTasks||[]).find(m=>m.workspaceId===e);if(!o)return null;let a=g(),u=s.createTaskHistoryEntry(o,a,r),l=s.getTaskHistoryFromState(n),d=[u,...l].slice(0,s.maxTaskHistory);return await s.update(t,m=>({...m,activeTasks:(m.activeTasks||[]).filter(f=>f.workspaceId!==e),taskHistory:d,lastUpdated:a})),await s.publish(t,"task.completed",{taskId:o.id,description:o.description,startedAt:o.startedAt,completedAt:a,workspaceId:e}),o}c(an,"completeTaskInWorkspace");async function cn(s,t){return(await s.read(t)).activeTasks||[]}c(cn,"getActiveTasks");async function un(s,t){return((await s.read(t)).activeTasks||[]).length}c(un,"getActiveTaskCount");async function ln(s,t,e,r){let i=(await s.read(t)).activeTasks||[],o=i.findIndex(u=>u.workspaceId===e);if(o===-1)return null;let a={...i[o],...r,workspaceId:e};return await s.update(t,u=>{let l=[...u.activeTasks||[]];return l[o]=a,{...u,activeTasks:l,lastUpdated:g()}}),a}c(ln,"updateWorkspaceTask");async function pn(s,t,e,r){let n=await s.read(t);if(!n.currentTask)return null;let i=(n.currentTask.tokensIn||0)+e,o=(n.currentTask.tokensOut||0)+r;return await s.update(t,a=>({...a,currentTask:{...a.currentTask,tokensIn:i,tokensOut:o},lastUpdated:g()})),{tokensIn:i,tokensOut:o}}c(pn,"addTokens");Be();var He=class extends lt{static{c(this,"StateStorage")}constructor(){super("state.json",vs)}getDefault(){return{currentTask:null,previousTask:null,pausedTasks:[],taskHistory:[],activeTasks:[],lastUpdated:""}}getEventType(t){return`state.${t}d`}validateTransition(t,e){let r=Ie.getCurrentState(t),n=Ie.canTransition(r,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 r=await this.read(t);this.validateTransition(r,"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 r=await this.read(t);if(!r.currentTask)return null;let n={...r.currentTask,...e};return await this.update(t,i=>({...i,currentTask:n,lastUpdated:g()})),n}async completeTask(t,e){let r=await this.read(t),n=r.currentTask;if(!n)return null;this.validateTransition(r,"done");let i=g(),o=this.createTaskHistoryEntry(n,i,e),a=this.getTaskHistoryFromState(r),u=[o,...a].slice(0,this.maxTaskHistory);return await this.update(t,l=>({...l,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,r){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 r&&(o.feedback=r),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 Os(this.lifecycleBackend(),t,e)}async resumeTask(t,e){return Ms(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 js(this.lifecycleBackend(),t)}async archiveStalePausedTasks(t){return Fs(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 Us(this.queryBackend(),t)}async hasTask(t){return $s(this.queryBackend(),t)}async getPausedTask(t){return Xs(this.queryBackend(),t)}async getAllPausedTasks(t){return Ws(this.queryBackend(),t)}async getTaskHistory(t){return Xe(this.queryBackend(),t)}async getMostRecentTask(t){return Bs(this.queryBackend(),t)}async getTaskHistoryByType(t,e){return Hs(this.queryBackend(),t,e)}async getAggregatedFeedback(t){return qs(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,r){return nn(this.workspaceBackend(),t,e,r)}async getCurrentTaskForWorkspace(t,e){return on(this.workspaceBackend(),t,e)}async completeTaskInWorkspace(t,e,r){return an(this.workspaceBackend(),t,e,r)}async getActiveTasks(t){return cn(this.workspaceBackend(),t)}async getActiveTaskCount(t){return un(this.workspaceBackend(),t)}async updateWorkspaceTask(t,e,r){return ln(this.workspaceBackend(),t,e,r)}async addTokens(t,e,r){return pn(this.workspaceBackend(),t,e,r)}subtaskBackend(){return{read:this.read.bind(this),update:this.update.bind(this),publish:this.publishEvent.bind(this)}}async createSubtasks(t,e){return Gs(this.subtaskBackend(),t,e)}async completeSubtask(t,e){return Ys(this.subtaskBackend(),t,e)}async getCurrentSubtask(t){return Js(this.subtaskBackend(),t)}async getNextSubtask(t){return zs(this.subtaskBackend(),t)}async getPreviousSubtask(t){return We(this.subtaskBackend(),t)}async getPreviousHandoff(t){return Ks(this.subtaskBackend(),t)}async getSubtasks(t){return Vs(this.subtaskBackend(),t)}async getSubtaskProgress(t){return Qs(this.subtaskBackend(),t)}async hasSubtasks(t){return Zs(this.subtaskBackend(),t)}async areAllSubtasksComplete(t){return tn(this.subtaskBackend(),t)}async failSubtask(t,e){return en(this.subtaskBackend(),t,e)}async skipSubtask(t,e){return rn(this.subtaskBackend(),t,e)}async blockSubtask(t,e){return sn(this.subtaskBackend(),t,e)}},pt=new He;qe();Z();import Lo from"node:fs/promises";import dt from"node:path";var Co={"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}},Io="claude-sonnet-4.5";function Ge(s){return!s||s.length===0?0:Math.ceil(s.length/4)}c(Ge,"countTokens");var Tn=["claude-sonnet-4.5","claude-opus-4.5","claude-opus-4-6","gpt-4o","gemini-1.5-pro"];function yn(s,t){let e=Co[t],r=s/1e3*e.input,n=s/1e3*e.output*.3;return{inputSaved:r,outputPotential:n,total:r+n}}c(yn,"calculateModelCost");function Do(s){return s<.001?"<$0.01":s<.01?`$${s.toFixed(3)}`:`$${s.toFixed(2)}`}c(Do,"formatCostSaved");function En(s,t){let e=Ge(s),r=Ge(t),n=Math.max(0,e-r),i=e>0?(e-r)/e:0,o=yn(n,Io),a=Tn.map(u=>({model:u,...yn(n,u)}));return{tokens:{original:e,filtered:r,saved:n},compression:Math.max(0,Math.min(1,i)),cost:{saved:o.total,formatted:Do(o.total),byModel:a}}}c(En,"measureCompression");function zt(s){let t=Ge(s);return{tokens:{original:t,filtered:t,saved:0},compression:0,cost:{saved:0,formatted:"$0.00",byModel:Tn.map(e=>({model:e,inputSaved:0,outputPotential:0,total:0}))}}}c(zt,"noCompression");var Oo={".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"},kn=[{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}],Mo=[{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}],jo=[{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}],Fo=[{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}],Sn=[{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}],Uo={typescript:kn,javascript:kn,python:Mo,go:jo,rust:Fo,java:Sn,csharp:Sn,php:[],ruby:[],unknown:[]};async function wn(s,t=process.cwd()){let e=dt.isAbsolute(s)?s:dt.join(t,s),r=dt.resolve(t),n=dt.resolve(e);if(!n.startsWith(r+dt.sep)&&n!==r)return{file:s,language:"unknown",signatures:[],fallback:!0,fallbackReason:"Path traversal denied: file is outside project directory",metrics:zt("")};let i;try{i=await Lo.readFile(e,"utf-8")}catch(m){if(O(m))return{file:s,language:"unknown",signatures:[],fallback:!0,fallbackReason:"File not found",metrics:zt("")};throw m}let o=dt.extname(s).toLowerCase(),a=Oo[o]||"unknown",u=Uo[a];if(!u||u.length===0)return{file:s,language:a,signatures:[],fallback:!0,fallbackReason:`No extraction patterns for ${a}`,metrics:zt(i)};let l=$o(i,u),d=l.map(m=>`${m.exported?"export ":""}${m.type} ${m.name}: ${m.signature}`).join(`
617
+ `);return{file:s,language:a,signatures:l,fallback:!1,metrics:En(i,d)}}c(wn,"extractSignatures");function $o(s,t){let e=[],r=s.split(`
607
618
  `),n=new Set;for(let i of t){i.pattern.lastIndex=0;let o;for(;(o=i.pattern.exec(s))!==null;){let a=o[i.nameIndex];if(!a)continue;let u=`${i.type}:${a}`;if(n.has(u))continue;n.add(u);let l=o.index,d=s.substring(0,l).split(`
608
- `).length,m=o[0].trim(),f;if(d>1){let T=r[d-2]?.trim();(T?.startsWith("/**")||T?.startsWith("///")||T?.startsWith("#"))&&(f=T)}e.push({type:i.type,name:a,signature:Mo(m),exported:i.exported||!1,line:d,docstring:f})}}return e.sort((i,o)=>i.line-o.line)}c(Oo,"extractFromContent");function Mo(s){return s.replace(/\{$/,"").replace(/\s+/g," ").trim()}c(Mo,"cleanSignature");function bn(s){let t=s;t.tool("prjct_relevant_files","BM25-ranked files relevant to a query",{projectPath:rt.string().describe("Project directory path"),query:rt.string().describe("Task or query to find relevant files for"),maxFiles:rt.number().optional().default(10).describe("Max files to return")},S("prjct_relevant_files",async e=>{let r=await Jt(e.query,e.projectPath,{maxFiles:e.maxFiles,minScore:.1});if(r.files.length===0)return{content:[{type:"text",text:"No relevant files found."}]};let n=r.files.map(o=>`- \`${o.path}\` (score: ${Math.round(o.score*100)}%) \u2014 ${o.reasons.join(", ")}`);return{content:[{type:"text",text:`## Relevant Files (${r.files.length}/${r.metrics.filesScanned} scanned)
619
+ `).length,m=o[0].trim(),f;if(d>1){let T=r[d-2]?.trim();(T?.startsWith("/**")||T?.startsWith("///")||T?.startsWith("#"))&&(f=T)}e.push({type:i.type,name:a,signature:Xo(m),exported:i.exported||!1,line:d,docstring:f})}}return e.sort((i,o)=>i.line-o.line)}c($o,"extractFromContent");function Xo(s){return s.replace(/\{$/,"").replace(/\s+/g," ").trim()}c(Xo,"cleanSignature");function bn(s){let t=s;t.tool("prjct_relevant_files","BM25-ranked files relevant to a query",{projectPath:rt.string().describe("Project directory path"),query:rt.string().describe("Task or query to find relevant files for"),maxFiles:rt.number().optional().default(10).describe("Max files to return")},S("prjct_relevant_files",async e=>{let r=await Jt(e.query,e.projectPath,{maxFiles:e.maxFiles,minScore:.1});if(r.files.length===0)return{content:[{type:"text",text:"No relevant files found."}]};let n=r.files.map(o=>`- \`${o.path}\` (score: ${Math.round(o.score*100)}%) \u2014 ${o.reasons.join(", ")}`);return{content:[{type:"text",text:`## Relevant Files (${r.files.length}/${r.metrics.filesScanned} scanned)
609
620
 
610
621
  ${n.join(`
611
622
  `)}`}]}})),t.tool("prjct_signatures","Code signatures from a file (90% token reduction vs full content)",{projectPath:rt.string().describe("Project directory path"),filePath:rt.string().describe("Relative file path to extract signatures from")},S("prjct_signatures",async e=>{let r=await wn(e.filePath,e.projectPath);if(r.signatures.length===0)return{content:[{type:"text",text:r.fallback?`No signatures extracted: ${r.fallbackReason}`:"No signatures found."}]};let n=r.signatures.map(a=>`${a.exported?"export ":""}${a.type} ${a.name}: ${a.signature}${a.docstring?` // ${a.docstring}`:""}`),i=r.metrics?.compression?` (${Math.round(r.metrics.compression*100)}% reduction)`:"";return{content:[{type:"text",text:`## ${r.file} (${r.language})
@@ -615,28 +626,28 @@ ${n.join(`
615
626
  \`\`\`${i}`}]}})),t.tool("prjct_history","Recent completed tasks with outcomes",{projectPath:rt.string().describe("Project directory path"),limit:rt.number().optional().default(10).describe("Max results")},S("prjct_history",async e=>{let r=await R(e.projectPath),n=await pt.getTaskHistory(r);if(n.length===0)return{content:[{type:"text",text:"No task history."}]};let o=n.slice(-e.limit).reverse().map(u=>{let l=[`- **${u.title}**`];return u.completedAt&&l.push(`completed: ${u.completedAt}`),u.classification&&l.push(`type: ${u.classification}`),l.join(" | ")});return{content:[{type:"text",text:`## Task History (${n.length} total)
616
627
 
617
628
  ${o.join(`
618
- `)}`}]}}))}c(bn,"registerFileTools");mt();Je();import{z as P}from"zod";var On=[{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/}],bp=On.map(s=>s.name);function Mn(s){let t=[];for(let{name:e,re:r}of On)r.test(s)&&t.push(e);return t}c(Mn,"scanForSecrets");var jn=`Base types: ${Dn.join(", ")}. Any lowercase identifier is accepted (e.g. "recipe", "okr").`;function Fn(s){let t=s;t.tool("prjct_mem_save",`Save a memory entry. ${jn} 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 R(e.projectPath);let r=e.type.toLowerCase().trim();if(!r||!/^[a-z][a-z0-9-]*$/.test(r))return{content:[{type:"text",text:`Invalid type '${e.type}'. Lowercase letters + dashes only. ${jn}`}]};let n=Mn(e.content);if(n.length>0&&!e.force)return{content:[{type:"text",text:`Refused \u2014 content looks like a secret (${n.join(", ")}). Re-call with force=true if intentional.`}]};let i=Rn(e.content);return i.length>0&&!e.force?{content:[{type:"text",text:`Refused \u2014 content looks like prompt injection (${i.join(", ")}). Memory entries are inlined into LLM context. Re-call with force=true if intentional.`}]}:(await L.remember(e.projectPath,{type:r,content:e.content,tags:e.tags??{},source:e.source}),{content:[{type:"text",text:`Saved ${r}: ${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 r=await R(e.projectPath),n=L.recall(r,{topic:e.topic,types:e.types,tags:e.tags,limit:e.limit});return{content:[{type:"text",text:xt(n,{boundary:"llm"})}]}})),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 r=await R(e.projectPath),n=L.similar(r,e.description,e.limit);return n.length===0?{content:[{type:"text",text:"No similar memories found."}]}:{content:[{type:"text",text:xt(n,{boundary:"llm"})}]}})),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(Fn,"registerMemoryTools");mt();import{z as tr}from"zod";N();j();var Ve=class{static{c(this,"LLMAnalysisStorage")}save(t,e){let r=k.getDb(t),n=g();r.transaction(()=>{r.prepare("UPDATE llm_analysis SET status = 'superseded', superseded_at = ? WHERE status = 'active'").run(n),r.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(r=>({id:r.id,status:r.status,commitHash:r.commit_hash,analyzedAt:r.analyzed_at,supersededAt:r.superseded_at,analysis:JSON.parse(r.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}})}},Go=new Ve,Un=Go;Ze();function Hn(s){let t=s;t.tool("prjct_task_status","Current task, duration, subtasks, and queue",{projectPath:tr.string().describe("Project directory path")},S("prjct_task_status",async e=>{let r=await R(e.projectPath),n=await pt.getCurrentTask(r),i=await Rt.getActiveTasks(r),o=[];if(n?(o.push(`## Active Task
629
+ `)}`}]}}))}c(bn,"registerFileTools");mt();Je();import{z as P}from"zod";var $n=[{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/}],Mp=$n.map(s=>s.name);function Xn(s){let t=[];for(let{name:e,re:r}of $n)r.test(s)&&t.push(e);return t}c(Xn,"scanForSecrets");var Wn=`Base types: ${Fn.join(", ")}. Any lowercase identifier is accepted (e.g. "recipe", "okr").`;function Bn(s){let t=s;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 R(e.projectPath);let r=e.type.toLowerCase().trim();if(!r||!/^[a-z][a-z0-9-]*$/.test(r))return{content:[{type:"text",text:`Invalid type '${e.type}'. Lowercase letters + dashes only. ${Wn}`}]};let n=Xn(e.content);if(n.length>0&&!e.force)return{content:[{type:"text",text:`Refused \u2014 content looks like a secret (${n.join(", ")}). Re-call with force=true if intentional.`}]};let i=Rn(e.content);return i.length>0&&!e.force?{content:[{type:"text",text:`Refused \u2014 content looks like prompt injection (${i.join(", ")}). Memory entries are inlined into LLM context. Re-call with force=true if intentional.`}]}:(await L.remember(e.projectPath,{type:r,content:e.content,tags:e.tags??{},source:e.source}),{content:[{type:"text",text:`Saved ${r}: ${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 r=await R(e.projectPath),n=L.recall(r,{topic:e.topic,types:e.types,tags:e.tags,limit:e.limit});return{content:[{type:"text",text:xt(n,{boundary:"llm"})}]}})),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 r=await R(e.projectPath),n=L.similar(r,e.description,e.limit);return n.length===0?{content:[{type:"text",text:"No similar memories found."}]}:{content:[{type:"text",text:xt(n,{boundary:"llm"})}]}})),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");mt();import{z as tr}from"zod";N();M();var Ve=class{static{c(this,"LLMAnalysisStorage")}save(t,e){let r=k.getDb(t),n=g();r.transaction(()=>{r.prepare("UPDATE llm_analysis SET status = 'superseded', superseded_at = ? WHERE status = 'active'").run(n),r.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(r=>({id:r.id,status:r.status,commitHash:r.commit_hash,analyzedAt:r.analyzed_at,supersededAt:r.superseded_at,analysis:JSON.parse(r.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}})}},sa=new Ve,Hn=sa;Ze();function zn(s){let t=s;t.tool("prjct_task_status","Current task, duration, subtasks, and queue",{projectPath:tr.string().describe("Project directory path")},S("prjct_task_status",async e=>{let r=await R(e.projectPath),n=await pt.getCurrentTask(r),i=await Rt.getActiveTasks(r),o=[];if(n?(o.push(`## Active Task
619
630
  **${n.description}**`),n.branch&&o.push(`Branch: ${n.branch}`),o.push(`Started: ${n.startedAt}`)):o.push("No active task."),i.length>0){o.push(`
620
631
  ## 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(`
621
- `)}]}})),t.tool("prjct_analysis","LLM analysis: stack, patterns, anti-patterns, conventions",{projectPath:tr.string().describe("Project directory path")},S("prjct_analysis",async e=>{let r=await R(e.projectPath),n=Un.getActive(r);if(!n)return{content:[{type:"text",text:"No analysis available. Run `prjct sync`."}]};let i=["## Project Analysis"];if(n.stack&&(i.push(`
632
+ `)}]}})),t.tool("prjct_analysis","LLM analysis: stack, patterns, anti-patterns, conventions",{projectPath:tr.string().describe("Project directory path")},S("prjct_analysis",async e=>{let r=await R(e.projectPath),n=Hn.getActive(r);if(!n)return{content:[{type:"text",text:"No analysis available. Run `prjct sync`."}]};let i=["## Project Analysis"];if(n.stack&&(i.push(`
622
633
  ### 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(`
623
634
  ### Patterns (${n.patterns.length})`);for(let o of n.patterns)i.push(`- **${o.name}**: ${o.description}`)}if(n.antiPatterns?.length){i.push(`
624
635
  ### Anti-Patterns (${n.antiPatterns.length})`);for(let o of n.antiPatterns)i.push(`- **${o.issue}**: ${o.suggestion}`)}if(n.conventions?.length){i.push(`
625
636
  ### Conventions (${n.conventions.length})`);for(let o of n.conventions)i.push(`- [${o.category}] ${o.rule}`)}return{content:[{type:"text",text:i.join(`
626
- `)}]}})),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:tr.string().describe("Project directory path")},S("prjct_patterns",async e=>{let r=await R(e.projectPath),n=L.recall(r,{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:xt(n)}]}}))}c(Hn,"registerProjectTools");import{z as h}from"zod";kt();mt();Vt();Kt();N();import{execFile as ra}from"node:child_process";import{promisify as sa}from"node:util";var na=sa(ra);async function ia(s){try{let{stdout:t}=await na("git",["rev-parse","HEAD"],{cwd:s}),e=t.trim();return/^[0-9a-f]{7,40}$/.test(e)?e:null}catch{return null}}c(ia,"readGitHead");var nr=class{static{c(this,"SpecService")}async create(t,e){let r=await this.requireProjectId(t),n=e.content.notes??"";if(e.autoContext!==!1&&!n.trim()){let{inferSpecContext:u,warnNoContextMatch:l}=await Promise.resolve().then(()=>(Yn(),Gn)),d=await u(e.title,r,t);d.empty?l(e.title):n=d.notesBlock}let o=Y.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=x.create(r,{title:e.title,content:o,tags:e.tags});return await L.remember(t,{type:"spec",content:`${a.title}
637
+ `)}]}})),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:tr.string().describe("Project directory path")},S("prjct_patterns",async e=>{let r=await R(e.projectPath),n=L.recall(r,{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:xt(n)}]}}))}c(zn,"registerProjectTools");import{z as h}from"zod";kt();mt();Vt();Kt();N();import{execFile as ma}from"node:child_process";import{promisify as ga}from"node:util";var fa=ga(ma);async function ha(s){try{let{stdout:t}=await fa("git",["rev-parse","HEAD"],{cwd:s}),e=t.trim();return/^[0-9a-f]{7,40}$/.test(e)?e:null}catch{return null}}c(ha,"readGitHead");var nr=class{static{c(this,"SpecService")}async create(t,e){let r=await this.requireProjectId(t),n=e.content.notes??"";if(e.autoContext!==!1&&!n.trim()){let{inferSpecContext:u,warnNoContextMatch:l}=await Promise.resolve().then(()=>(Qn(),Vn)),d=await u(e.title,r,t);d.empty?l(e.title):n=d.notesBlock}let o=Y.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=x.create(r,{title:e.title,content:o,tags:e.tags});return await L.remember(t,{type:"spec",content:`${a.title}
627
638
 
628
- 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 r=await this.requireProjectId(t);return x.get(r,e)}async list(t,e={}){let r=await this.requireProjectId(t);return x.list(r,e)}async setStatus(t,e,r){let n=await this.requireProjectId(t),i=x.setStatus(n,e,r);return i&&await L.remember(t,{type:"spec",content:`Spec status \u2192 ${r}: ${i.title}`,tags:{spec_id:e,status:r,event:"status_change"},source:e}),i}async update(t,e,r){let n=await this.requireProjectId(t);return x.updateContent(n,e,r)}async recordReview(t,e,r,n){let i=await this.requireProjectId(t),o=3,a=50,u=0,l=!1,d=null;for(;u<o;){let m=x.get(i,e);if(!m)return null;let f={...n,ts:g()},T={...m.content,reviews:{...m.content.reviews??{},[r]:f}};if(x.casUpdate(i,e,T,m.updatedAt)){l=!0,d=x.get(i,e);break}u++,u<o&&await new Promise(z=>setTimeout(z,a))}if(!l)throw new Error(`SPEC_RECORD_REVIEW_CONFLICT_RETRY_EXHAUSTED: ${o} retries failed for spec ${e}`);if(d&&this.allReviewsPass(d.content)&&d.status==="draft"){let m=x.setStatus(i,e,"reviewed");if(m){let{breakdownSpecToTasks:f}=await Promise.resolve().then(()=>(zn(),Jn));return await f(i,t,m),x.get(i,e)}return m}return d}async linkTask(t,e,r){let n=await this.requireProjectId(t);return x.linkTask(n,e,r)}async ship(t,e,r){let n=await this.requireProjectId(t);r!==void 0&&x.setShippedPr(n,e,r);let i=await ia(t);return i&&x.setShippedSha(n,e,i),x.setStatus(n,e,"shipped")}unmetCriteria(t,e=new Set){return t.content.acceptance_criteria.filter(r=>!e.has(r))}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}},J=new nr;Vt();Kt();function Kn(s){let t=s;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:h.string().describe("Project directory path"),title:h.string().describe("One-line title (what you'd say to a coworker walking by)"),goal:h.string().describe("What success looks like, 1-3 sentences. Concrete, observable."),eli10:h.string().optional().describe("Plain English a 16-year-old follows, 2-4 sentences"),stakes:h.string().optional().describe("What breaks if we ship the wrong thing"),acceptance_criteria:h.array(h.string()).optional().describe("Testable, observable list. Each item ends in a verifiable claim."),scope:h.array(h.string()).optional().describe("What's IN \u2014 file paths, modules, surfaces"),out_of_scope:h.array(h.string()).optional().describe("What's OUT \u2014 anti-creep shield"),risks:h.array(h.object({risk:h.string(),mitigation:h.string()})).optional().describe("Each risk has a mitigation; a risk without one is just a complaint"),test_plan:h.array(h.string()).optional().describe("How you prove acceptance criteria"),tags:h.record(h.string(),h.string()).optional().describe('Key:value tags (e.g. {domain: "auth", priority: "high"})')},S("prjct_spec_create",async e=>{let r=await J.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: ${r.title}`,"",`id: ${r.id}`,`status: ${r.status}`,`goal: ${r.content.goal}`,"","Next: `prjct_spec_audit` to dispatch the three review subagents (strategic / architecture / design) in parallel."].join(`
639
+ 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 r=await this.requireProjectId(t);return x.get(r,e)}async list(t,e={}){let r=await this.requireProjectId(t);return x.list(r,e)}async setStatus(t,e,r){let n=await this.requireProjectId(t),i=x.setStatus(n,e,r);return i&&await L.remember(t,{type:"spec",content:`Spec status \u2192 ${r}: ${i.title}`,tags:{spec_id:e,status:r,event:"status_change"},source:e}),i}async update(t,e,r){let n=await this.requireProjectId(t);return x.updateContent(n,e,r)}async recordReview(t,e,r,n){let i=await this.requireProjectId(t),o=3,a=50,u=0,l=!1,d=null;for(;u<o;){let m=x.get(i,e);if(!m)return null;let f={...n,ts:g()},T={...m.content,reviews:{...m.content.reviews??{},[r]:f}};if(x.casUpdate(i,e,T,m.updatedAt)){l=!0,d=x.get(i,e);break}u++,u<o&&await new Promise(z=>setTimeout(z,a))}if(!l)throw new Error(`SPEC_RECORD_REVIEW_CONFLICT_RETRY_EXHAUSTED: ${o} retries failed for spec ${e}`);if(d&&this.allReviewsPass(d.content)&&d.status==="draft"){let m=x.setStatus(i,e,"reviewed");if(m){let{breakdownSpecToTasks:f}=await Promise.resolve().then(()=>(ti(),Zn));return await f(i,t,m),x.get(i,e)}return m}return d}async linkTask(t,e,r){let n=await this.requireProjectId(t);return x.linkTask(n,e,r)}async ship(t,e,r){let n=await this.requireProjectId(t);r!==void 0&&x.setShippedPr(n,e,r);let i=await ha(t);return i&&x.setShippedSha(n,e,i),x.setStatus(n,e,"shipped")}unmetCriteria(t,e=new Set){return t.content.acceptance_criteria.filter(r=>!e.has(r))}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}},J=new nr;Vt();Kt();function ei(s){let t=s;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:h.string().describe("Project directory path"),title:h.string().describe("One-line title (what you'd say to a coworker walking by)"),goal:h.string().describe("What success looks like, 1-3 sentences. Concrete, observable."),eli10:h.string().optional().describe("Plain English a 16-year-old follows, 2-4 sentences"),stakes:h.string().optional().describe("What breaks if we ship the wrong thing"),acceptance_criteria:h.array(h.string()).optional().describe("Testable, observable list. Each item ends in a verifiable claim."),scope:h.array(h.string()).optional().describe("What's IN \u2014 file paths, modules, surfaces"),out_of_scope:h.array(h.string()).optional().describe("What's OUT \u2014 anti-creep shield"),risks:h.array(h.object({risk:h.string(),mitigation:h.string()})).optional().describe("Each risk has a mitigation; a risk without one is just a complaint"),test_plan:h.array(h.string()).optional().describe("How you prove acceptance criteria"),tags:h.record(h.string(),h.string()).optional().describe('Key:value tags (e.g. {domain: "auth", priority: "high"})')},S("prjct_spec_create",async e=>{let r=await J.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: ${r.title}`,"",`id: ${r.id}`,`status: ${r.status}`,`goal: ${r.content.goal}`,"","Next: `prjct_spec_audit` to dispatch the three review subagents (strategic / architecture / design) in parallel."].join(`
629
640
  `)}]}})),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:h.string().describe("Project directory path"),status:h.enum(gt).optional().describe("Filter by status: draft|reviewed|in_progress|shipped|archived"),includeArchived:h.boolean().optional().describe("Include archived specs (default: false)")},S("prjct_spec_list",async e=>{let r=await R(e.projectPath),n=x.list(r,{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}
630
641
  - id: \`${o.id}\`
631
642
  - status: ${o.status}
632
643
  - acceptance criteria: ${a}
633
644
  - linked tasks: ${u}
634
645
  - created: ${o.createdAt}`),i.push("")}return{content:[{type:"text",text:i.join(`
635
- `)}]}})),t.tool("prjct_spec_get","Fetch one spec by id, including all structured fields (goal, acceptance criteria, scope, risks, reviews, linked tasks).",{projectPath:h.string().describe("Project directory path"),id:h.string().describe("Spec id")},S("prjct_spec_get",async e=>{let r=await J.get(e.projectPath,e.id);return r?{content:[{type:"text",text:oa(r)}]}:{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:h.string().describe("Project directory path"),id:h.string().describe("Spec id"),content:h.object({goal:h.string(),eli10:h.string().optional(),stakes:h.string().optional(),acceptance_criteria:h.array(h.string()).optional(),scope:h.array(h.string()).optional(),out_of_scope:h.array(h.string()).optional(),risks:h.array(h.object({risk:h.string(),mitigation:h.string()})).optional(),test_plan:h.array(h.string()).optional(),notes:h.string().optional(),linked_tasks:h.array(h.string()).optional()}).describe("Full SpecContent shape \u2014 Zod-validated server-side")},S("prjct_spec_update",async e=>{let r=Y.parse(e.content),n=await J.update(e.projectPath,e.id,r);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:h.string().describe("Project directory path"),id:h.string().describe("Spec id"),status:h.enum(gt).describe("Target status")},S("prjct_spec_set_status",async e=>await J.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:h.string().describe("Project directory path"),id:h.string().describe("Spec id to audit")},S("prjct_spec_audit",async e=>{let r=await J.get(e.projectPath,e.id);return r?{content:[{type:"text",text:aa(r.id,r.title,r.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:h.string().describe("Project directory path"),id:h.string().describe("Spec id"),reviewer:h.enum(rr).describe("Which reviewer"),verdict:h.enum(["pass","fail"]).describe("Verdict"),notes:h.string().describe("2-4 sentence notes from the subagent")},S("prjct_spec_record_review",async e=>{let r=await J.recordReview(e.projectPath,e.id,e.reviewer,{verdict:e.verdict,notes:e.notes});if(!r)return{content:[{type:"text",text:`_Spec not found: ${e.id}_`}]};let n=r.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:h.string().describe("Project directory path"),specId:h.string().describe("Spec id"),taskId:h.string().describe("Task id (from `prjct_session_start_task` or stateStorage)")},S("prjct_spec_link_task",async e=>await J.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:h.string().describe("Project directory path"),id:h.string().describe("Spec id"),pr:h.number().optional().describe("PR / MR number that delivered the spec")},S("prjct_spec_ship",async e=>{let r=await J.ship(e.projectPath,e.id,e.pr);return r?{content:[{type:"text",text:`\u2713 spec shipped: ${r.title}${e.pr?` (PR #${e.pr})`:""}`}]}:{content:[{type:"text",text:`_Spec not found: ${e.id}_`}]}}))}c(Kn,"registerSpecTools");function oa(s){let t=s.content,e=[`# ${s.title}`,"",`**id:** \`${s.id}\` \xB7 **status:** ${s.status} \xB7 **created:** ${s.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 r of t.acceptance_criteria)e.push(`- [ ] ${r}`)}if(t.scope.length>0){e.push("","## Scope");for(let r of t.scope)e.push(`- ${r}`)}if(t.out_of_scope.length>0){e.push("","## Out of scope");for(let r of t.out_of_scope)e.push(`- ${r}`)}if(t.risks.length>0){e.push("","## Risks");for(let r of t.risks)e.push(`- **${r.risk}** \u2014 ${r.mitigation}`)}if(t.test_plan.length>0){e.push("","## Test plan");for(let r of t.test_plan)e.push(`- ${r}`)}if(t.reviews){e.push("","## Reviews");for(let r of rr){let n=t.reviews[r];n&&e.push(`- **${r}:** ${n.verdict} \u2014 ${n.notes} _(${n.ts})_`)}}return t.linked_tasks.length>0&&e.push("","## Linked tasks",...t.linked_tasks.map(r=>`- ${r}`)),t.notes&&e.push("","## Notes",t.notes),e.join(`
636
- `)}c(oa,"renderSpecMarkdown");function aa(s,t,e){let r=JSON.stringify(e);return[`# audit-spec dispatch \u2014 ${t}`,"",`Spec id: \`${s}\``,"","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",r,"```","","## After dispatch","For each reviewer that returns:",` Call \`prjct_spec_record_review\` with id="${s}", 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(`
637
- `)}c(aa,"renderAuditDispatch");import{z as Zt}from"zod";bt();j();var ir=class{static{c(this,"CustomWorkflowStorage")}createWorkflow(t,e){let r=new Date().toISOString();y.run(t,`INSERT INTO custom_workflows (name, description, created_at, updated_at, is_builtin, enabled, metadata)
638
- VALUES (?, ?, ?, ?, 0, 1, ?)`,e.name,e.description??null,r,r,e.metadata?JSON.stringify(e.metadata):null);let n=y.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:r,updated_at:r,is_builtin:0,enabled:1}}),n.id}getWorkflow(t,e){let r=y.get(t,"SELECT * FROM custom_workflows WHERE name = ?",e);return r?this.rowToWorkflow(r):null}getAllWorkflows(t,e=!1){let r=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 y.query(t,r).map(i=>this.rowToWorkflow(i))}updateWorkflow(t,e,r){if(!this.getWorkflow(t,e))return!1;let i=new Date().toISOString(),o=[],a=[];if(r.description!==void 0&&(o.push("description = ?"),a.push(r.description)),r.enabled!==void 0&&(o.push("enabled = ?"),a.push(r.enabled?1:0)),r.metadata!==void 0&&(o.push("metadata = ?"),a.push(JSON.stringify(r.metadata))),o.length===0)return!1;o.push("updated_at = ?"),a.push(i),a.push(e),y.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 r=this.getWorkflow(t,e);if(!r)return!1;if(r.isBuiltin)throw new Error(`Cannot delete built-in workflow: ${e}`);return y.run(t,"UPDATE custom_workflows SET enabled = 0 WHERE name = ?",e),q({projectId:t,entityType:"custom_workflows",entityId:String(r.id),eventType:"delete",data:{id:r.id,name:e}}),!0}isBuiltin(t,e){return this.getWorkflow(t,e)?.isBuiltin??!1}isReservedName(t){let e=["task","done","ship","sync"],r=["add","rm","gate","list","create","delete","run","help","reset","init"];return e.includes(t)||r.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 ir;bt();j();function or(s){let t=s.trust_source==="imported"?"imported":"local";return{id:s.id,type:s.type,command:s.command,position:s.position,action:s.action,description:s.description,enabled:s.enabled===1,timeoutMs:s.timeout_ms,createdAt:s.created_at,sortOrder:s.sort_order,whenExpr:s.when_expr??null,parallel:s.parallel===null?!0:s.parallel===1,trustSource:t}}c(or,"rowToRule");var ar=class{static{c(this,"WorkflowRuleStorage")}addRule(t,e){let r=k.get(t,"SELECT MAX(sort_order) as m FROM workflow_rules WHERE command = ?",e.command),n=e.sortOrder||(r?.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)
639
- 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,r){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,l]of Object.entries(r)){let d=i[u];if(!d)continue;o.push(`${d.column} = ?`);let m=l;a.push(d.transform?d.transform(m):m)}return o.length===0||(a.push(e),k.run(t,`UPDATE workflow_rules SET ${o.join(", ")} WHERE id = ?`,...a)),!0}getRuleById(t,e){let r=k.get(t,"SELECT * FROM workflow_rules WHERE id = ?",e);return r?or(r):null}getRulesForCommand(t,e){let r=Qt.getWorkflow(t,e);return!r||!r.enabled?[]:k.query(t,"SELECT * FROM workflow_rules WHERE command = ? AND enabled = 1 ORDER BY sort_order ASC",e).map(or)}getAllRules(t){return k.query(t,"SELECT * FROM workflow_rules ORDER BY command ASC, sort_order ASC").map(or)}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}},cr=new ar;function Vn(s){let t=s;t.tool("prjct_workflow_rules","Get workflow rules for a command (gates, hooks, steps, instructions)",{projectPath:Zt.string().describe("Project directory path"),command:Zt.string().describe("Command name (task, done, ship, sync, etc.)")},S("prjct_workflow_rules",async e=>{let r=await R(e.projectPath),n=cr.getRulesForCommand(r,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(`
646
+ `)}]}})),t.tool("prjct_spec_get","Fetch one spec by id, including all structured fields (goal, acceptance criteria, scope, risks, reviews, linked tasks).",{projectPath:h.string().describe("Project directory path"),id:h.string().describe("Spec id")},S("prjct_spec_get",async e=>{let r=await J.get(e.projectPath,e.id);return r?{content:[{type:"text",text:ya(r)}]}:{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:h.string().describe("Project directory path"),id:h.string().describe("Spec id"),content:h.object({goal:h.string(),eli10:h.string().optional(),stakes:h.string().optional(),acceptance_criteria:h.array(h.string()).optional(),scope:h.array(h.string()).optional(),out_of_scope:h.array(h.string()).optional(),risks:h.array(h.object({risk:h.string(),mitigation:h.string()})).optional(),test_plan:h.array(h.string()).optional(),notes:h.string().optional(),linked_tasks:h.array(h.string()).optional()}).describe("Full SpecContent shape \u2014 Zod-validated server-side")},S("prjct_spec_update",async e=>{let r=Y.parse(e.content),n=await J.update(e.projectPath,e.id,r);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:h.string().describe("Project directory path"),id:h.string().describe("Spec id"),status:h.enum(gt).describe("Target status")},S("prjct_spec_set_status",async e=>await J.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:h.string().describe("Project directory path"),id:h.string().describe("Spec id to audit")},S("prjct_spec_audit",async e=>{let r=await J.get(e.projectPath,e.id);return r?{content:[{type:"text",text:Ta(r.id,r.title,r.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:h.string().describe("Project directory path"),id:h.string().describe("Spec id"),reviewer:h.enum(rr).describe("Which reviewer"),verdict:h.enum(["pass","fail"]).describe("Verdict"),notes:h.string().describe("2-4 sentence notes from the subagent")},S("prjct_spec_record_review",async e=>{let r=await J.recordReview(e.projectPath,e.id,e.reviewer,{verdict:e.verdict,notes:e.notes});if(!r)return{content:[{type:"text",text:`_Spec not found: ${e.id}_`}]};let n=r.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:h.string().describe("Project directory path"),specId:h.string().describe("Spec id"),taskId:h.string().describe("Task id (from `prjct_session_start_task` or stateStorage)")},S("prjct_spec_link_task",async e=>await J.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:h.string().describe("Project directory path"),id:h.string().describe("Spec id"),pr:h.number().optional().describe("PR / MR number that delivered the spec")},S("prjct_spec_ship",async e=>{let r=await J.ship(e.projectPath,e.id,e.pr);return r?{content:[{type:"text",text:`\u2713 spec shipped: ${r.title}${e.pr?` (PR #${e.pr})`:""}`}]}:{content:[{type:"text",text:`_Spec not found: ${e.id}_`}]}}))}c(ei,"registerSpecTools");function ya(s){let t=s.content,e=[`# ${s.title}`,"",`**id:** \`${s.id}\` \xB7 **status:** ${s.status} \xB7 **created:** ${s.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 r of t.acceptance_criteria)e.push(`- [ ] ${r}`)}if(t.scope.length>0){e.push("","## Scope");for(let r of t.scope)e.push(`- ${r}`)}if(t.out_of_scope.length>0){e.push("","## Out of scope");for(let r of t.out_of_scope)e.push(`- ${r}`)}if(t.risks.length>0){e.push("","## Risks");for(let r of t.risks)e.push(`- **${r.risk}** \u2014 ${r.mitigation}`)}if(t.test_plan.length>0){e.push("","## Test plan");for(let r of t.test_plan)e.push(`- ${r}`)}if(t.reviews){e.push("","## Reviews");for(let r of rr){let n=t.reviews[r];n&&e.push(`- **${r}:** ${n.verdict} \u2014 ${n.notes} _(${n.ts})_`)}}return t.linked_tasks.length>0&&e.push("","## Linked tasks",...t.linked_tasks.map(r=>`- ${r}`)),t.notes&&e.push("","## Notes",t.notes),e.join(`
647
+ `)}c(ya,"renderSpecMarkdown");function Ta(s,t,e){let r=JSON.stringify(e);return[`# audit-spec dispatch \u2014 ${t}`,"",`Spec id: \`${s}\``,"","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",r,"```","","## After dispatch","For each reviewer that returns:",` Call \`prjct_spec_record_review\` with id="${s}", 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(`
648
+ `)}c(Ta,"renderAuditDispatch");import{z as Zt}from"zod";bt();M();var ir=class{static{c(this,"CustomWorkflowStorage")}createWorkflow(t,e){let r=new Date().toISOString();y.run(t,`INSERT INTO custom_workflows (name, description, created_at, updated_at, is_builtin, enabled, metadata)
649
+ VALUES (?, ?, ?, ?, 0, 1, ?)`,e.name,e.description??null,r,r,e.metadata?JSON.stringify(e.metadata):null);let n=y.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:r,updated_at:r,is_builtin:0,enabled:1}}),n.id}getWorkflow(t,e){let r=y.get(t,"SELECT * FROM custom_workflows WHERE name = ?",e);return r?this.rowToWorkflow(r):null}getAllWorkflows(t,e=!1){let r=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 y.query(t,r).map(i=>this.rowToWorkflow(i))}updateWorkflow(t,e,r){if(!this.getWorkflow(t,e))return!1;let i=new Date().toISOString(),o=[],a=[];if(r.description!==void 0&&(o.push("description = ?"),a.push(r.description)),r.enabled!==void 0&&(o.push("enabled = ?"),a.push(r.enabled?1:0)),r.metadata!==void 0&&(o.push("metadata = ?"),a.push(JSON.stringify(r.metadata))),o.length===0)return!1;o.push("updated_at = ?"),a.push(i),a.push(e),y.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 r=this.getWorkflow(t,e);if(!r)return!1;if(r.isBuiltin)throw new Error(`Cannot delete built-in workflow: ${e}`);return y.run(t,"UPDATE custom_workflows SET enabled = 0 WHERE name = ?",e),q({projectId:t,entityType:"custom_workflows",entityId:String(r.id),eventType:"delete",data:{id:r.id,name:e}}),!0}isBuiltin(t,e){return this.getWorkflow(t,e)?.isBuiltin??!1}isReservedName(t){let e=["task","done","ship","sync"],r=["add","rm","gate","list","create","delete","run","help","reset","init"];return e.includes(t)||r.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 ir;bt();M();function or(s){let t=s.trust_source==="imported"?"imported":"local";return{id:s.id,type:s.type,command:s.command,position:s.position,action:s.action,description:s.description,enabled:s.enabled===1,timeoutMs:s.timeout_ms,createdAt:s.created_at,sortOrder:s.sort_order,whenExpr:s.when_expr??null,parallel:s.parallel===null?!0:s.parallel===1,trustSource:t}}c(or,"rowToRule");var ar=class{static{c(this,"WorkflowRuleStorage")}addRule(t,e){let r=k.get(t,"SELECT MAX(sort_order) as m FROM workflow_rules WHERE command = ?",e.command),n=e.sortOrder||(r?.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)
650
+ 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,r){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,l]of Object.entries(r)){let d=i[u];if(!d)continue;o.push(`${d.column} = ?`);let m=l;a.push(d.transform?d.transform(m):m)}return o.length===0||(a.push(e),k.run(t,`UPDATE workflow_rules SET ${o.join(", ")} WHERE id = ?`,...a)),!0}getRuleById(t,e){let r=k.get(t,"SELECT * FROM workflow_rules WHERE id = ?",e);return r?or(r):null}getRulesForCommand(t,e){let r=Qt.getWorkflow(t,e);return!r||!r.enabled?[]:k.query(t,"SELECT * FROM workflow_rules WHERE command = ? AND enabled = 1 ORDER BY sort_order ASC",e).map(or)}getAllRules(t){return k.query(t,"SELECT * FROM workflow_rules ORDER BY command ASC, sort_order ASC").map(or)}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}},cr=new ar;function ri(s){let t=s;t.tool("prjct_workflow_rules","Get workflow rules for a command (gates, hooks, steps, instructions)",{projectPath:Zt.string().describe("Project directory path"),command:Zt.string().describe("Command name (task, done, ship, sync, etc.)")},S("prjct_workflow_rules",async e=>{let r=await R(e.projectPath),n=cr.getRulesForCommand(r,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(`
640
651
  ### ${a}`);for(let l of u){let d=l.enabled?"":" (disabled)";o.push(`- ${l.action}${l.description?` \u2014 ${l.description}`:""}${d}`)}}return{content:[{type:"text",text:o.join(`
641
652
  `)}]}})),t.tool("prjct_workflow_list","List all workflows for this project (built-in + custom)",{projectPath:Zt.string().describe("Project directory path")},S("prjct_workflow_list",async e=>{let r=await R(e.projectPath),n=Qt.getAllWorkflows(r);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})
642
653
 
@@ -646,7 +657,7 @@ Active task: **${n.description}**`),o.push(`Started: ${n.startedAt}`)):o.push(`
646
657
  No active task.`);let a=i.filter(u=>u.enabled);if(a.length>0){o.push(`
647
658
  ### Active Rules (${a.length})`);for(let u of a)o.push(`- [${u.type}] ${u.command}:${u.position} \u2192 ${u.action}`)}else o.push(`
648
659
  No active workflow rules.`);return{content:[{type:"text",text:o.join(`
649
- `)}]}}))}c(Vn,"registerWorkflowTools");var ua=`# prjct \u2014 Spec-Driven Development + project memory
660
+ `)}]}}))}c(ri,"registerWorkflowTools");var ka=`# prjct \u2014 Spec-Driven Development + project memory
650
661
 
651
662
  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.**
652
663
 
@@ -681,4 +692,4 @@ Skip the SDD flow only for: routine captures, single-file fixes, doc tweaks, con
681
692
  - Topic keys are free-form strings; don't invent new vocabularies when existing ones fit.
682
693
  - Not every project defines every memory type \u2014 if one is empty, that's fine.
683
694
  - Saving a secret-looking string is refused by default. Re-save with a scrubbed version.
684
- - A spec without acceptance_criteria is just an inbox item \u2014 fill them.`;function Qn(){let s=new ca({name:"prjct",version:"1.0.0"},{instructions:ua});return Fn(s),Hn(s),bn(s),Vn(s),Es(s),Kn(s),s}c(Qn,"createServer");async function pa(){let s=Qn(),t=new la;await s.connect(t)}c(pa,"main");pa().catch(s=>{console.error("prjct MCP server failed:",s),process.exit(1)});
695
+ - A spec without acceptance_criteria is just an inbox item \u2014 fill them.`;function si(){let s=new Ea({name:"prjct",version:"1.0.0"},{instructions:ka});return Bn(s),zn(s),bn(s),ri(s),Es(s),ei(s),s}c(si,"createServer");async function wa(){let s=si(),t=new Sa;await s.connect(t)}c(wa,"main");wa().catch(s=>{console.error("prjct MCP server failed:",s),process.exit(1)});