prjct-cli 2.1.2 → 2.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,12 +5,12 @@ 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 Br=Object.getOwnPropertyDescriptor;var Hr=Object.getOwnPropertyNames;var qr=Object.prototype.hasOwnProperty;var c=(n,t)=>at(n,"name",{value:t,configurable:!0}),me=(n=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(n,{get:(t,e)=>(typeof require<"u"?require:t)[e]}):n)(function(n){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+n+'" is not supported')});var C=(n,t)=>()=>(n&&(t=n(n=0)),t);var ge=(n,t)=>{for(var e in t)at(n,e,{get:t[e],enumerable:!0})},zr=(n,t,e,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of Hr(t))!qr.call(n,s)&&s!==e&&at(n,s,{get:()=>t[s],enumerable:!(r=Br(t,s))||r.enumerable});return n};var xt=n=>zr(at({},"__esModule",{value:!0}),n);var fe,he,ye,vt=C(()=>{"use strict";fe=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"]),he=["",".ts",".tsx",".js",".jsx","/index.ts","/index.js"],ye=/(?:import|from)\s+['"]([^'"]+)['"]/g});function Jr(n){return n instanceof Error&&"code"in n}function N(n){return Jr(n)&&n.code==="ENOENT"}function ke(n){return n instanceof Error?n.message:typeof n=="string"?n:"Unknown error"}var W=C(()=>{"use strict";c(Jr,"isNodeError");c(N,"isNotFoundError");c(ke,"getErrorMessage")});import Se from"node:fs/promises";async function xe(n,t){let e;try{e=await Se.readFile(n,"utf-8")}catch(o){if(N(o))return null;throw o}let r;try{r=JSON.parse(e)}catch{return await we(n,e),be(n,"Malformed JSON"),null}let s=t.safeParse(r);return s.success?r:(await we(n,e),be(n,Vr(s.error)),null)}async function we(n,t){let e=`${n}.backup`;try{await Se.writeFile(e,t,"utf-8")}catch{}}function be(n,t){console.error(`[prjct] Warning: Corrupted storage file: ${n}`),console.error(`[prjct] Reason: ${t}`),console.error("[prjct] A .backup file has been created. Returning defaults.")}function Vr(n){return n.issues.slice(0,3).map(t=>`${t.path.join(".")}: ${t.message}`).join("; ")}var ve=C(()=>{"use strict";W();c(xe,"safeRead");c(we,"createBackup");c(be,"logCorruption");c(Vr,"formatZodError")});import G from"node:fs/promises";import _t from"node:path";async function _e(n,t={}){let e=[],r=t.maxFiles??1/0,s=t.dotfileAllowlist?new Set(t.dotfileAllowlist):null;async function o(i){if(e.length>=r)return;let a=await G.readdir(i,{withFileTypes:!0}).catch(()=>[]);for(let u of a){if(e.length>=r)break;let p=String(u.name);if(fe.has(p)||t.skipDotfiles&&p.startsWith(".")&&(!s||!s.has(p)))continue;let m=_t.join(i,p);u.isDirectory()?await o(m):u.isFile()&&e.push(_t.relative(n,m))}}return c(o,"walk"),await o(n),e}async function Pe(n,t,e){let r=[];for(let s=0;s<n.length;s+=t){let o=await Promise.all(n.slice(s,s+t).map(e));for(let i of o)i!==null&&r.push(i)}return r}async function ct(n,t=null,e){if(e)return await xe(n,e)??t;try{let r=await G.readFile(n,"utf-8");return JSON.parse(r)}catch(r){if(N(r))return t;throw r}}async function M(n,t,e=2){let r=_t.dirname(n);await G.mkdir(r,{recursive:!0});let s=JSON.stringify(t,null,e);await G.writeFile(n,s,"utf-8")}async function x(n){try{return await G.access(n),!0}catch(t){if(N(t))return!1;throw t}}async function Pt(n){try{return(await G.stat(n)).isDirectory()}catch(t){if(N(t))return!1;throw t}}async function F(n){await G.mkdir(n,{recursive:!0})}var U=C(()=>{"use strict";vt();ve();W();c(_e,"walkDir");c(Pe,"batchProcess");c(ct,"readJson");c(M,"writeJson");c(x,"fileExists");c(Pt,"dirExists");c(F,"ensureDir")});var Ae=C(()=>{"use strict"});import{z as D}from"zod";function Ne(n,t){let e=n.split(".").map(Number),r=t.split(".").map(Number);for(let s=0;s<3;s++){let o=e[s]??0,i=r[s]??0;if(o<i)return-1;if(o>i)return 1}return 0}var oo,io,ao,ut,co,Rt=C(()=>{"use strict";oo=D.enum(["opus","sonnet","haiku"]),io=D.enum(["2.5-pro","2.5-flash","2.0-flash"]),ao=D.string().min(1),ut=D.object({provider:D.string(),model:D.string(),cliVersion:D.string().optional(),recordedAt:D.string()}),co=D.object({preferredModel:D.string().optional(),lastAnalysisModel:ut.optional()});c(Ne,"compareSemver")});import{exec as Kr,execFile as Qr}from"node:child_process";import{promisify as Ce}from"node:util";var k,go,z=C(()=>{"use strict";k=Ce(Kr),go=Ce(Qr)});function Ie(n,t){let e=typeof n=="string"?new Date(n).getTime():n;return Date.now()-e>t}var lt,At=C(()=>{"use strict";c(Ie,"isExpired");lt=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,s)=>r[1].timestamp-s[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 Zr from"node:fs/promises";import ts from"node:os";import De from"node:path";async function Oe(){try{let n=await Zr.readFile(Le,"utf-8"),t=JSON.parse(n);return!t.timestamp||!t.detection||!t.detection.claude||!t.detection.gemini||!t.detection.codex||Ie(t.timestamp,rs)?null:t.detection}catch{return null}}async function je(n){let t={timestamp:new Date().toISOString(),detection:n};await M(Le,t)}var es,Le,rs,Me=C(()=>{"use strict";At();U();es=De.join(ts.homedir(),".prjct-cli","cache"),Le=De.join(es,"providers.json"),rs=10*60*1e3;c(Oe,"readProviderCache");c(je,"writeProviderCache")});var dt={};ge(dt,{AntigravityProvider:()=>It,ClaudeProvider:()=>pt,CodexProvider:()=>Dt,CursorProvider:()=>Ue,GeminiProvider:()=>Ct,Providers:()=>I,WindsurfProvider:()=>Xe,detectAllProviders:()=>Lt,detectAntigravity:()=>ps,detectCodex:()=>He,detectCursorProject:()=>Ge,detectProvider:()=>Nt,detectWindsurfProject:()=>Be,getActiveProvider:()=>is,getCapabilities:()=>ns,getCommandsDir:()=>fs,getGlobalContextPath:()=>ds,getGlobalSettingsPath:()=>ms,getProjectCommandsPath:()=>hs,getProviderBranding:()=>cs,getSkillsPath:()=>gs,hasProviderConfig:()=>as,needsCursorRouterRegeneration:()=>us,needsWindsurfRouterRegeneration:()=>ls,selectProvider:()=>ys,validateCliVersion:()=>We});import X from"node:os";import _ from"node:path";function ns(n,t){return{...ss[n],...t}}async function $e(n){try{let{stdout:t}=await k(`which ${n}`,{timeout:2e3});return t.trim()}catch{return null}}async function os(n){try{let{stdout:t}=await k(`${n} --version`,{timeout:2e3}),e=t.match(/\d+\.\d+\.\d+/);return e?e[0]:t.trim()}catch{return null}}async function Nt(n){let t=I[n];if(!t.cliCommand)return{installed:!1};let e=await $e(t.cliCommand);if(!e)return{installed:!1};let r=await os(t.cliCommand),s=We(n,r||void 0);return{installed:!0,version:r||void 0,path:e,versionWarning:s||void 0}}function We(n,t){let e=I[n];return!e.minCliVersion||!t?null:Ne(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 Lt(n=!1){if(!n){let i=await Oe();if(i)return i}let[t,e,r]=await Promise.all([Nt("claude"),Nt("gemini"),He()]),s={installed:r.installed},o={claude:t,gemini:e,codex:s};return await je(o).catch(()=>{}),o}async function is(n){if(n&&I[n])return I[n];let t=await Lt();return t.claude.installed&&!t.gemini.installed?pt:t.gemini.installed&&!t.claude.installed?Ct:pt}async function as(n){let t=I[n];return t.configDir?x(t.configDir):!1}function cs(n){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"}[n]||"\u26A1 prjct"}}async function Ge(n){let t=_.join(n,".cursor"),e=_.join(t,"rules"),r=_.join(e,"prjct.mdc"),[s,o]=await Promise.all([x(t),x(r)]);return{detected:s,routerInstalled:o,projectRoot:s?n:void 0}}async function us(n){let t=await Ge(n);return t.detected&&!t.routerInstalled}async function Be(n){let t=_.join(n,".windsurf"),e=_.join(t,"rules"),r=_.join(e,"prjct.md"),[s,o]=await Promise.all([x(t),x(r)]);return{detected:s,routerInstalled:o,projectRoot:s?n:void 0}}async function ls(n){let t=await Be(n);return t.detected&&!t.routerInstalled}async function ps(){let n=It.configDir;if(!n)return{installed:!1,skillInstalled:!1};let t=_.join(n,"skills","prjct","SKILL.md"),[e,r]=await Promise.all([x(n),x(t)]);return{installed:e,skillInstalled:r,configPath:e?n:void 0}}async function He(){let n=Dt.configDir;if(!n)return{installed:!1,skillInstalled:!1};let t=await $e("codex"),e=_.join(n,"skills","prjct","SKILL.md"),r=await x(e),s=!!t;return{installed:s,skillInstalled:r,configPath:s?n:void 0}}function ds(n){let t=I[n];return t.configDir?_.join(t.configDir,t.contextFile):null}function ms(n){let t=I[n];return!t.configDir||!t.settingsFile?null:_.join(t.configDir,t.settingsFile)}function gs(n){return I[n].skillsDir}function fs(n){return I[n].commandsDir}function hs(n,t){let e=I[n];return _.join(t,e.commandsDir)}async function ys(){let n=await Lt(),t=n.claude.installed,e=n.gemini.installed;return!t&&!e?{provider:"claude",userSelected:!1,detection:n}:t&&!e?{provider:"claude",userSelected:!1,detection:n}:e&&!t?{provider:"gemini",userSelected:!1,detection:n}:{provider:"claude",userSelected:!0,detection:n}}var ss,pt,Ct,It,Ue,Xe,Dt,I,mt=C(()=>{"use strict";Ae();Rt();z();U();Me();ss={full:{shell:!0,fileRead:!0,fileWrite:!0,fileSearch:!0,structuredQuestions:!0,subagents:!0,webFetch:!0,todoTracking:!0},standard:{shell:!0,fileRead:!0,fileWrite:!0,fileSearch:!0,structuredQuestions:!0,subagents:!1,webFetch:!1,todoTracking:!1},basic:{shell:!0,fileRead:!0,fileWrite:!0,fileSearch:!0,structuredQuestions:!1,subagents:!1,webFetch:!1,todoTracking:!1}};c(ns,"getCapabilities");pt={name:"claude",displayName:"Claude Code",cliCommand:"claude",configDir:_.join(X.homedir(),".claude"),contextFile:"CLAUDE.md",skillsDir:_.join(X.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"},Ct={name:"gemini",displayName:"Gemini CLI",cliCommand:"gemini",configDir:_.join(X.homedir(),".gemini"),contextFile:"GEMINI.md",skillsDir:_.join(X.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"},It={name:"antigravity",displayName:"Google Antigravity",cliCommand:null,configDir:_.join(X.homedir(),".gemini","antigravity"),contextFile:"ANTIGRAVITY.md",skillsDir:_.join(X.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"},Ue={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"},Xe={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"},Dt={name:"codex",displayName:"OpenAI Codex",cliCommand:"codex",configDir:_.join(X.homedir(),".codex"),contextFile:"AGENTS.md",skillsDir:_.join(X.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"},I={claude:pt,gemini:Ct,cursor:Ue,antigravity:It,windsurf:Xe,codex:Dt};c($e,"whichCommand");c(os,"getCliVersion");c(Nt,"detectProvider");c(We,"validateCliVersion");c(Lt,"detectAllProviders");c(is,"getActiveProvider");c(as,"hasProviderConfig");c(cs,"getProviderBranding");c(Ge,"detectCursorProject");c(us,"needsCursorRouterRegeneration");c(Be,"detectWindsurfProject");c(ls,"needsWindsurfRouterRegeneration");c(ps,"detectAntigravity");c(He,"detectCodex");c(ds,"getGlobalContextPath");c(ms,"getGlobalSettingsPath");c(gs,"getSkillsPath");c(fs,"getCommandsDir");c(hs,"getProjectCommandsPath");c(ys,"selectProvider")});var cr={};ge(cr,{default:()=>Ws,worktreeService:()=>ar});import Ht from"node:fs/promises";import O from"node:path";var ir,qt,ar,Ws,ur=C(()=>{"use strict";z();U();ir=".worktrees",qt=class{static{c(this,"WorktreeService")}async create(t,e,r={}){let s=await this.getMainWorktree(t),o=O.join(s,ir,e),i=r.branch||`feat/${e}`;await Ht.mkdir(O.join(s,ir),{recursive:!0});let a=r.baseBranch?` ${r.baseBranch}`:"";await k(`git worktree add "${o}" -b "${i}"${a}`,{cwd:s});let{stdout:u}=await k("git rev-parse HEAD",{cwd:o});return{path:o,branch:i,commit:u.trim(),isMain:!1,slug:e}}async remove(t,e=!1){let r=await this.getMainWorktree(t),s;if(e)try{let{stdout:o}=await k("git rev-parse --abbrev-ref HEAD",{cwd:t});s=o.trim()}catch{}if(await k(`git worktree remove "${t}" --force`,{cwd:r}),e&&s&&s!=="main"&&s!=="master")try{await k(`git branch -D "${s}"`,{cwd:r})}catch{}}async list(t){let e=await this.getMainWorktree(t),{stdout:r}=await k("git worktree list --porcelain",{cwd:e});return this.parsePorcelainOutput(r,e)}async detect(t){try{let{stdout:e}=await k("git rev-parse --git-common-dir",{cwd:t}),{stdout:r}=await k("git rev-parse --git-dir",{cwd:t}),s=O.resolve(t,e.trim()),o=O.resolve(t,r.trim());if(s!==o){let{stdout:i}=await k("git rev-parse --abbrev-ref HEAD",{cwd:t}),{stdout:a}=await k("git rev-parse HEAD",{cwd:t}),{stdout:u}=await k("git rev-parse --show-toplevel",{cwd:t}),p=u.trim(),m=O.basename(p);return{path:p,branch:i.trim(),commit:a.trim(),isMain:!1,slug:m}}return null}catch{return null}}async getMainWorktree(t){try{let{stdout:r}=await k("git worktree list --porcelain",{cwd:t}),s=r.split(`
8
+ var ct=Object.defineProperty;var Br=Object.getOwnPropertyDescriptor;var Hr=Object.getOwnPropertyNames;var qr=Object.prototype.hasOwnProperty;var c=(n,t)=>ct(n,"name",{value:t,configurable:!0}),me=(n=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(n,{get:(t,e)=>(typeof require<"u"?require:t)[e]}):n)(function(n){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+n+'" is not supported')});var C=(n,t)=>()=>(n&&(t=n(n=0)),t);var ge=(n,t)=>{for(var e in t)ct(n,e,{get:t[e],enumerable:!0})},zr=(n,t,e,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of Hr(t))!qr.call(n,s)&&s!==e&&ct(n,s,{get:()=>t[s],enumerable:!(r=Br(t,s))||r.enumerable});return n};var vt=n=>zr(ct({},"__esModule",{value:!0}),n);var fe,he,ye,_t=C(()=>{"use strict";fe=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"]),he=["",".ts",".tsx",".js",".jsx","/index.ts","/index.js"],ye=/(?:import|from)\s+['"]([^'"]+)['"]/g});function Jr(n){return n instanceof Error&&"code"in n}function N(n){return Jr(n)&&n.code==="ENOENT"}function ke(n){return n instanceof Error?n.message:typeof n=="string"?n:"Unknown error"}var W=C(()=>{"use strict";c(Jr,"isNodeError");c(N,"isNotFoundError");c(ke,"getErrorMessage")});import Se from"node:fs/promises";async function xe(n,t){let e;try{e=await Se.readFile(n,"utf-8")}catch(o){if(N(o))return null;throw o}let r;try{r=JSON.parse(e)}catch{return await we(n,e),be(n,"Malformed JSON"),null}let s=t.safeParse(r);return s.success?r:(await we(n,e),be(n,Vr(s.error)),null)}async function we(n,t){let e=`${n}.backup`;try{await Se.writeFile(e,t,"utf-8")}catch{}}function be(n,t){console.error(`[prjct] Warning: Corrupted storage file: ${n}`),console.error(`[prjct] Reason: ${t}`),console.error("[prjct] A .backup file has been created. Returning defaults.")}function Vr(n){return n.issues.slice(0,3).map(t=>`${t.path.join(".")}: ${t.message}`).join("; ")}var ve=C(()=>{"use strict";W();c(xe,"safeRead");c(we,"createBackup");c(be,"logCorruption");c(Vr,"formatZodError")});import G from"node:fs/promises";import Pt from"node:path";async function _e(n,t={}){let e=[],r=t.maxFiles??1/0,s=t.dotfileAllowlist?new Set(t.dotfileAllowlist):null;async function o(i){if(e.length>=r)return;let a=await G.readdir(i,{withFileTypes:!0}).catch(()=>[]);for(let u of a){if(e.length>=r)break;let p=String(u.name);if(fe.has(p)||t.skipDotfiles&&p.startsWith(".")&&(!s||!s.has(p)))continue;let m=Pt.join(i,p);u.isDirectory()?await o(m):u.isFile()&&e.push(Pt.relative(n,m))}}return c(o,"walk"),await o(n),e}async function Pe(n,t,e){let r=[];for(let s=0;s<n.length;s+=t){let o=await Promise.all(n.slice(s,s+t).map(e));for(let i of o)i!==null&&r.push(i)}return r}async function ut(n,t=null,e){if(e)return await xe(n,e)??t;try{let r=await G.readFile(n,"utf-8");return JSON.parse(r)}catch(r){if(N(r))return t;throw r}}async function M(n,t,e=2){let r=Pt.dirname(n);await G.mkdir(r,{recursive:!0});let s=JSON.stringify(t,null,e);await G.writeFile(n,s,"utf-8")}async function x(n){try{return await G.access(n),!0}catch(t){if(N(t))return!1;throw t}}async function Rt(n){try{return(await G.stat(n)).isDirectory()}catch(t){if(N(t))return!1;throw t}}async function F(n){await G.mkdir(n,{recursive:!0})}var U=C(()=>{"use strict";_t();ve();W();c(_e,"walkDir");c(Pe,"batchProcess");c(ut,"readJson");c(M,"writeJson");c(x,"fileExists");c(Rt,"dirExists");c(F,"ensureDir")});var Ae=C(()=>{"use strict"});import{z as D}from"zod";function Ne(n,t){let e=n.split(".").map(Number),r=t.split(".").map(Number);for(let s=0;s<3;s++){let o=e[s]??0,i=r[s]??0;if(o<i)return-1;if(o>i)return 1}return 0}var oo,io,ao,lt,co,At=C(()=>{"use strict";oo=D.enum(["opus","sonnet","haiku"]),io=D.enum(["2.5-pro","2.5-flash","2.0-flash"]),ao=D.string().min(1),lt=D.object({provider:D.string(),model:D.string(),cliVersion:D.string().optional(),recordedAt:D.string()}),co=D.object({preferredModel:D.string().optional(),lastAnalysisModel:lt.optional()});c(Ne,"compareSemver")});import{exec as Kr,execFile as Qr}from"node:child_process";import{promisify as Ce}from"node:util";var k,go,z=C(()=>{"use strict";k=Ce(Kr),go=Ce(Qr)});function Ie(n,t){let e=typeof n=="string"?new Date(n).getTime():n;return Date.now()-e>t}var pt,Nt=C(()=>{"use strict";c(Ie,"isExpired");pt=class{static{c(this,"TTLCache")}cache=new Map;ttl;maxSize;constructor(t={}){this.ttl=t.ttl??5e3,this.maxSize=t.maxSize??50}isValid(t){let e=this.cache.get(t);return e?Date.now()-e.timestamp<this.ttl:!1}get(t){let e=this.cache.get(t);return e?this.isValid(t)?e.data:(this.cache.delete(t),null):null}set(t,e){this.cache.set(t,{data:e,timestamp:Date.now()}),this.evictOldEntries()}delete(t){this.cache.delete(t)}clear(){this.cache.clear()}has(t){return this.cache.has(t)}get size(){return this.cache.size}evictOldEntries(){if(this.cache.size<=this.maxSize)return;let e=Array.from(this.cache.entries()).sort((r,s)=>r[1].timestamp-s[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 Zr from"node:fs/promises";import ts from"node:os";import De from"node:path";async function Oe(){try{let n=await Zr.readFile(Le,"utf-8"),t=JSON.parse(n);return!t.timestamp||!t.detection||!t.detection.claude||!t.detection.gemini||!t.detection.codex||Ie(t.timestamp,rs)?null:t.detection}catch{return null}}async function je(n){let t={timestamp:new Date().toISOString(),detection:n};await M(Le,t)}var es,Le,rs,Me=C(()=>{"use strict";Nt();U();es=De.join(ts.homedir(),".prjct-cli","cache"),Le=De.join(es,"providers.json"),rs=10*60*1e3;c(Oe,"readProviderCache");c(je,"writeProviderCache")});var mt={};ge(mt,{AntigravityProvider:()=>Dt,ClaudeProvider:()=>dt,CodexProvider:()=>Lt,CursorProvider:()=>Ue,GeminiProvider:()=>It,Providers:()=>I,WindsurfProvider:()=>Xe,detectAllProviders:()=>Ot,detectAntigravity:()=>ps,detectCodex:()=>He,detectCursorProject:()=>Ge,detectProvider:()=>Ct,detectWindsurfProject:()=>Be,getActiveProvider:()=>is,getCapabilities:()=>ns,getCommandsDir:()=>fs,getGlobalContextPath:()=>ds,getGlobalSettingsPath:()=>ms,getProjectCommandsPath:()=>hs,getProviderBranding:()=>cs,getSkillsPath:()=>gs,hasProviderConfig:()=>as,needsCursorRouterRegeneration:()=>us,needsWindsurfRouterRegeneration:()=>ls,selectProvider:()=>ys,validateCliVersion:()=>We});import X from"node:os";import _ from"node:path";function ns(n,t){return{...ss[n],...t}}async function $e(n){try{let{stdout:t}=await k(`which ${n}`,{timeout:2e3});return t.trim()}catch{return null}}async function os(n){try{let{stdout:t}=await k(`${n} --version`,{timeout:2e3}),e=t.match(/\d+\.\d+\.\d+/);return e?e[0]:t.trim()}catch{return null}}async function Ct(n){let t=I[n];if(!t.cliCommand)return{installed:!1};let e=await $e(t.cliCommand);if(!e)return{installed:!1};let r=await os(t.cliCommand),s=We(n,r||void 0);return{installed:!0,version:r||void 0,path:e,versionWarning:s||void 0}}function We(n,t){let e=I[n];return!e.minCliVersion||!t?null:Ne(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 Ot(n=!1){if(!n){let i=await Oe();if(i)return i}let[t,e,r]=await Promise.all([Ct("claude"),Ct("gemini"),He()]),s={installed:r.installed},o={claude:t,gemini:e,codex:s};return await je(o).catch(()=>{}),o}async function is(n){if(n&&I[n])return I[n];let t=await Ot();return t.claude.installed&&!t.gemini.installed?dt:t.gemini.installed&&!t.claude.installed?It:dt}async function as(n){let t=I[n];return t.configDir?x(t.configDir):!1}function cs(n){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"}[n]||"\u26A1 prjct"}}async function Ge(n){let t=_.join(n,".cursor"),e=_.join(t,"rules"),r=_.join(e,"prjct.mdc"),[s,o]=await Promise.all([x(t),x(r)]);return{detected:s,routerInstalled:o,projectRoot:s?n:void 0}}async function us(n){let t=await Ge(n);return t.detected&&!t.routerInstalled}async function Be(n){let t=_.join(n,".windsurf"),e=_.join(t,"rules"),r=_.join(e,"prjct.md"),[s,o]=await Promise.all([x(t),x(r)]);return{detected:s,routerInstalled:o,projectRoot:s?n:void 0}}async function ls(n){let t=await Be(n);return t.detected&&!t.routerInstalled}async function ps(){let n=Dt.configDir;if(!n)return{installed:!1,skillInstalled:!1};let t=_.join(n,"skills","prjct","SKILL.md"),[e,r]=await Promise.all([x(n),x(t)]);return{installed:e,skillInstalled:r,configPath:e?n:void 0}}async function He(){let n=Lt.configDir;if(!n)return{installed:!1,skillInstalled:!1};let t=await $e("codex"),e=_.join(n,"skills","prjct","SKILL.md"),r=await x(e),s=!!t;return{installed:s,skillInstalled:r,configPath:s?n:void 0}}function ds(n){let t=I[n];return t.configDir?_.join(t.configDir,t.contextFile):null}function ms(n){let t=I[n];return!t.configDir||!t.settingsFile?null:_.join(t.configDir,t.settingsFile)}function gs(n){return I[n].skillsDir}function fs(n){return I[n].commandsDir}function hs(n,t){let e=I[n];return _.join(t,e.commandsDir)}async function ys(){let n=await Ot(),t=n.claude.installed,e=n.gemini.installed;return!t&&!e?{provider:"claude",userSelected:!1,detection:n}:t&&!e?{provider:"claude",userSelected:!1,detection:n}:e&&!t?{provider:"gemini",userSelected:!1,detection:n}:{provider:"claude",userSelected:!0,detection:n}}var ss,dt,It,Dt,Ue,Xe,Lt,I,gt=C(()=>{"use strict";Ae();At();z();U();Me();ss={full:{shell:!0,fileRead:!0,fileWrite:!0,fileSearch:!0,structuredQuestions:!0,subagents:!0,webFetch:!0,todoTracking:!0},standard:{shell:!0,fileRead:!0,fileWrite:!0,fileSearch:!0,structuredQuestions:!0,subagents:!1,webFetch:!1,todoTracking:!1},basic:{shell:!0,fileRead:!0,fileWrite:!0,fileSearch:!0,structuredQuestions:!1,subagents:!1,webFetch:!1,todoTracking:!1}};c(ns,"getCapabilities");dt={name:"claude",displayName:"Claude Code",cliCommand:"claude",configDir:_.join(X.homedir(),".claude"),contextFile:"CLAUDE.md",skillsDir:_.join(X.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"},It={name:"gemini",displayName:"Gemini CLI",cliCommand:"gemini",configDir:_.join(X.homedir(),".gemini"),contextFile:"GEMINI.md",skillsDir:_.join(X.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"},Dt={name:"antigravity",displayName:"Google Antigravity",cliCommand:null,configDir:_.join(X.homedir(),".gemini","antigravity"),contextFile:"ANTIGRAVITY.md",skillsDir:_.join(X.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"},Ue={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"},Xe={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"},Lt={name:"codex",displayName:"OpenAI Codex",cliCommand:"codex",configDir:_.join(X.homedir(),".codex"),contextFile:"AGENTS.md",skillsDir:_.join(X.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"},I={claude:dt,gemini:It,cursor:Ue,antigravity:Dt,windsurf:Xe,codex:Lt};c($e,"whichCommand");c(os,"getCliVersion");c(Ct,"detectProvider");c(We,"validateCliVersion");c(Ot,"detectAllProviders");c(is,"getActiveProvider");c(as,"hasProviderConfig");c(cs,"getProviderBranding");c(Ge,"detectCursorProject");c(us,"needsCursorRouterRegeneration");c(Be,"detectWindsurfProject");c(ls,"needsWindsurfRouterRegeneration");c(ps,"detectAntigravity");c(He,"detectCodex");c(ds,"getGlobalContextPath");c(ms,"getGlobalSettingsPath");c(gs,"getSkillsPath");c(fs,"getCommandsDir");c(hs,"getProjectCommandsPath");c(ys,"selectProvider")});var cr={};ge(cr,{default:()=>Ws,worktreeService:()=>ar});import Ht from"node:fs/promises";import O from"node:path";var ir,qt,ar,Ws,ur=C(()=>{"use strict";z();U();ir=".worktrees",qt=class{static{c(this,"WorktreeService")}async create(t,e,r={}){let s=await this.getMainWorktree(t),o=O.join(s,ir,e),i=r.branch||`feat/${e}`;await Ht.mkdir(O.join(s,ir),{recursive:!0});let a=r.baseBranch?` ${r.baseBranch}`:"";await k(`git worktree add "${o}" -b "${i}"${a}`,{cwd:s});let{stdout:u}=await k("git rev-parse HEAD",{cwd:o});return{path:o,branch:i,commit:u.trim(),isMain:!1,slug:e}}async remove(t,e=!1){let r=await this.getMainWorktree(t),s;if(e)try{let{stdout:o}=await k("git rev-parse --abbrev-ref HEAD",{cwd:t});s=o.trim()}catch{}if(await k(`git worktree remove "${t}" --force`,{cwd:r}),e&&s&&s!=="main"&&s!=="master")try{await k(`git branch -D "${s}"`,{cwd:r})}catch{}}async list(t){let e=await this.getMainWorktree(t),{stdout:r}=await k("git worktree list --porcelain",{cwd:e});return this.parsePorcelainOutput(r,e)}async detect(t){try{let{stdout:e}=await k("git rev-parse --git-common-dir",{cwd:t}),{stdout:r}=await k("git rev-parse --git-dir",{cwd:t}),s=O.resolve(t,e.trim()),o=O.resolve(t,r.trim());if(s!==o){let{stdout:i}=await k("git rev-parse --abbrev-ref HEAD",{cwd:t}),{stdout:a}=await k("git rev-parse HEAD",{cwd:t}),{stdout:u}=await k("git rev-parse --show-toplevel",{cwd:t}),p=u.trim(),m=O.basename(p);return{path:p,branch:i.trim(),commit:a.trim(),isMain:!1,slug:m}}return null}catch{return null}}async getMainWorktree(t){try{let{stdout:r}=await k("git worktree list --porcelain",{cwd:t}),s=r.split(`
9
9
  `)[0];if(s?.startsWith("worktree "))return s.replace("worktree ","").trim()}catch{}let{stdout:e}=await k("git rev-parse --show-toplevel",{cwd:t});return e.trim()}async setup(t,e){let r=O.join(e,".env");await x(r)&&await Ht.copyFile(r,O.join(t,".env"));let s=O.join(e,".prjct"),o=O.join(t,".prjct");await x(s)&&!await x(o)&&await Ht.symlink(s,o,"dir")}async teardown(t){}async clean(t){let e=await this.list(t),r=[],s=await this.getMainWorktree(t);await k("git worktree prune",{cwd:s});for(let o of e)o.isMain||await x(o.path)||r.push(o.slug);return r}parsePorcelainOutput(t,e){let r=[],s=t.trim().split(`
10
10
 
11
11
  `);for(let o of s){if(!o.trim())continue;let i=o.trim().split(`
12
- `),a="",u="",p="",m=!1;for(let d of i)d.startsWith("worktree ")?a=d.replace("worktree ","").trim():d.startsWith("HEAD ")?u=d.replace("HEAD ","").trim():d.startsWith("branch ")?p=d.replace("branch refs/heads/","").trim():d==="bare"?m=!0:d==="detached"&&(p="(detached)");if(a){let d=a===e||m;r.push({path:a,branch:p,commit:u,isMain:d,slug:d?"main":O.basename(a)})}}return r}},ar=new qt,Ws=ar});import{StdioServerTransport as Mn}from"@modelcontextprotocol/sdk/server/stdio.js";import{McpServer as On}from"@modelcontextprotocol/sdk/server/mcp.js";import{z as A}from"zod";vt();import Ye from"node:fs/promises";import Y from"node:path";import Mt from"node:fs";import ze from"node:path";import Ts from"node:crypto";import L from"node:fs/promises";import Ot from"node:os";import y from"node:path";import{globSync as Es}from"glob";import{formatDistanceToNowStrict as Gn}from"date-fns";function Te(n){return{year:n.getFullYear().toString(),month:(n.getMonth()+1).toString().padStart(2,"0"),day:n.getDate().toString().padStart(2,"0")}}c(Te,"getYearMonthDay");function f(){return new Date().toISOString()}c(f,"getTimestamp");function Ee(n){let t=new Date;return t.setDate(t.getDate()-n),t}c(Ee,"getDaysAgo");U();var jt=class{static{c(this,"PathManager")}globalBaseDir;globalProjectsDir;globalConfigDir;constructor(){let t=process.env.PRJCT_CLI_HOME?.trim();this.globalBaseDir=t?y.resolve(t):y.join(Ot.homedir(),".prjct-cli"),this.globalProjectsDir=y.join(this.globalBaseDir,"projects"),this.globalConfigDir=y.join(this.globalBaseDir,"config")}setGlobalBaseDir(t){this.globalBaseDir=y.resolve(t),this.globalProjectsDir=y.join(this.globalBaseDir,"projects"),this.globalConfigDir=y.join(this.globalBaseDir,"config")}generateProjectId(t){return Ts.randomUUID()}getGlobalBasePath(){return this.globalBaseDir}getGlobalProjectPath(t){return y.join(this.globalProjectsDir,t)}getLocalConfigPath(t){return y.join(t,".prjct","prjct.config.json")}getGlobalProjectConfigPath(t){return y.join(this.getGlobalProjectPath(t),"project.json")}getLegacyPrjctPath(t){return y.join(t,".prjct")}async hasLegacyStructure(t){let e=this.getLegacyPrjctPath(t);return await Pt(e)}async hasConfig(t){let e=this.getLocalConfigPath(t);return await x(e)}async ensureGlobalStructure(){await F(this.globalBaseDir),await F(this.globalProjectsDir),await F(this.globalConfigDir)}async ensureProjectStructure(t){await this.ensureGlobalStructure();let e=this.getGlobalProjectPath(t),r=["core","progress","planning","analysis","memory"];for(let s of r)await F(y.join(e,s));return await F(y.join(e,"planning","tasks")),await F(y.join(e,"sessions")),e}getSessionPath(t,e=new Date){let{year:r,month:s,day:o}=Te(e);return y.join(this.getGlobalProjectPath(t),"sessions",r,s,o)}getCurrentSessionPath(t){return this.getSessionPath(t,new Date)}async ensureSessionPath(t,e=new Date){let r=this.getSessionPath(t,e);return await F(r),r}async listSessions(t,e=null,r=null){let s=y.join(this.getGlobalProjectPath(t),"sessions"),o=[];try{let i=await L.readdir(s,{withFileTypes:!0});for(let a of i){if(!a.isDirectory()||e&&a.name!==e.toString())continue;let u=y.join(s,a.name),p=await L.readdir(u,{withFileTypes:!0});for(let m of p){if(!m.isDirectory()||r&&m.name!==r.toString().padStart(2,"0"))continue;let d=y.join(u,m.name),g=await L.readdir(d,{withFileTypes:!0});for(let h of g)h.isDirectory()&&o.push({year:a.name,month:m.name,day:h.name,path:y.join(d,h.name),date:new Date(`${a.name}-${m.name}-${h.name}`)})}}return o.sort((a,u)=>u.date.getTime()-a.date.getTime()),o}catch{return[]}}async getSessionsInRange(t,e,r=new Date){return(await this.listSessions(t)).filter(o=>o.date>=e&&o.date<=r)}getFilePath(t,e,r){return y.join(this.getGlobalProjectPath(t),e,r)}async listProjects(){try{return await this.ensureGlobalStructure(),(await L.readdir(this.globalProjectsDir,{withFileTypes:!0})).filter(e=>e.isDirectory()).map(e=>e.name)}catch{return[]}}async projectExists(t){let e=this.getGlobalProjectPath(t);return await Pt(e)}getDisplayPath(t){let e=Ot.homedir();return t.startsWith(e)?t.replace(e,"~"):t}getAuthConfigPath(){return y.join(this.globalConfigDir,"auth.json")}getSyncPendingPath(t){return y.join(this.getGlobalProjectPath(t),"sync","pending.json")}getLastSyncPath(t){return y.join(this.getGlobalProjectPath(t),"sync","last-sync.json")}getRunningStatusPath(){return y.join(this.globalBaseDir,".running")}getDocsPath(){return y.join(this.globalBaseDir,"docs")}async getAgentDir(){return(await(mt(),xt(dt)).getActiveProvider()).configDir}async getAgentSettingsPath(){let t=await(mt(),xt(dt)).getActiveProvider();return(mt(),xt(dt)).getGlobalSettingsPath(t.name)}getClaudeDir(){return y.join(Ot.homedir(),".claude")}getClaudeSettingsPath(){return y.join(this.getClaudeDir(),"settings.json")}getStoragePath(t,e){return y.join(this.getGlobalProjectPath(t),"storage",e)}getContextPath(t){return y.join(this.getGlobalProjectPath(t),"context")}async detectMonorepo(t){let e={isMonorepo:!1,type:null,rootPath:t,packages:[]},r=[{file:"pnpm-workspace.yaml",type:"pnpm"},{file:"lerna.json",type:"lerna"},{file:"nx.json",type:"nx"},{file:"rush.json",type:"rush"},{file:"turbo.json",type:"turborepo"}];for(let s of r){let o=y.join(t,s.file);if(await x(o)){e.isMonorepo=!0,e.type=s.type;break}}if(!e.isMonorepo){let s=y.join(t,"package.json");if(await x(s))try{let o=await L.readFile(s,"utf-8");JSON.parse(o).workspaces&&(e.isMonorepo=!0,e.type="npm")}catch{}}return e.isMonorepo&&(e.packages=await this.discoverMonorepoPackages(t,e.type)),e}async discoverMonorepoPackages(t,e){let r=[],s=[];try{if(e==="pnpm"){let i=(await L.readFile(y.join(t,"pnpm-workspace.yaml"),"utf-8")).match(/packages:\s*\n((?:\s*-\s*.+\n?)+)/);i&&(s=i[1].split(`
13
- `).map(a=>a.replace(/^\s*-\s*['"]?|['"]?\s*$/g,"")).filter(Boolean))}else if(e==="npm"||e==="lerna"){let o=y.join(t,"package.json"),i=await L.readFile(o,"utf-8"),a=JSON.parse(i);if(Array.isArray(a.workspaces)?s=a.workspaces:a.workspaces?.packages&&(s=a.workspaces.packages),e==="lerna"){let u=y.join(t,"lerna.json");if(await x(u)){let p=await L.readFile(u,"utf-8"),m=JSON.parse(p);m.packages&&(s=m.packages)}}}else if(e==="nx")s=["apps/*","libs/*","packages/*"];else if(e==="turborepo"){let o=y.join(t,"package.json"),i=await L.readFile(o,"utf-8"),a=JSON.parse(i);Array.isArray(a.workspaces)&&(s=a.workspaces)}s.length===0&&(s=["packages/*","apps/*","libs/*"]);for(let o of s){if(o.startsWith("!"))continue;let i=Es(o,{cwd:t,absolute:!1});for(let a of i){let u=y.join(t,a),p=y.join(u,"package.json");if(await x(p))try{let m=await L.readFile(p,"utf-8"),d=JSON.parse(m),g=y.join(u,"PRJCT.md");r.push({name:d.name||y.basename(a),path:u,relativePath:a,hasPrjctMd:await x(g)})}catch{}}}}catch{}return r}async findContainingPackage(t,e){if(!e.isMonorepo)return null;let r=y.resolve(t);for(let s of e.packages){let o=y.resolve(s.path);if(r.startsWith(o))return s}return null}async findMonorepoRoot(t){let e=y.resolve(t),r=y.parse(e).root;for(;e!==r;){if((await this.detectMonorepo(e)).isMonorepo)return e;e=y.dirname(e)}return null}},ks=new jt,b=ks;function ws(){return typeof globalThis<"u"&&"Bun"in globalThis?"bun":"node"}c(ws,"detectRuntime");function qe(){return ws()==="bun"}c(qe,"isBun");function bs(n){if(qe()){let{Database:s}=me("bun:sqlite");return new s(n,{create:!0})}let t=me("better-sqlite3"),e=new t(n),r=e.exec.bind(e);return e.run=s=>r(s),e}c(bs,"openDatabase");var Ss=[{version:1,name:"initial-schema",up:c(n=>{n.run(`
12
+ `),a="",u="",p="",m=!1;for(let d of i)d.startsWith("worktree ")?a=d.replace("worktree ","").trim():d.startsWith("HEAD ")?u=d.replace("HEAD ","").trim():d.startsWith("branch ")?p=d.replace("branch refs/heads/","").trim():d==="bare"?m=!0:d==="detached"&&(p="(detached)");if(a){let d=a===e||m;r.push({path:a,branch:p,commit:u,isMain:d,slug:d?"main":O.basename(a)})}}return r}},ar=new qt,Ws=ar});import{StdioServerTransport as Mn}from"@modelcontextprotocol/sdk/server/stdio.js";import{McpServer as On}from"@modelcontextprotocol/sdk/server/mcp.js";import{z as A}from"zod";_t();import Ye from"node:fs/promises";import J from"node:path";import Mt from"node:fs";import ze from"node:path";import Ts from"node:crypto";import L from"node:fs/promises";import Y from"node:os";import h from"node:path";import{globSync as Es}from"glob";import{formatDistanceToNowStrict as Gn}from"date-fns";function Te(n){return{year:n.getFullYear().toString(),month:(n.getMonth()+1).toString().padStart(2,"0"),day:n.getDate().toString().padStart(2,"0")}}c(Te,"getYearMonthDay");function f(){return new Date().toISOString()}c(f,"getTimestamp");function Ee(n){let t=new Date;return t.setDate(t.getDate()-n),t}c(Ee,"getDaysAgo");U();var jt=class{static{c(this,"PathManager")}globalBaseDir;globalProjectsDir;globalConfigDir;constructor(){let t=process.env.PRJCT_CLI_HOME?.trim();this.globalBaseDir=t?h.resolve(t):h.join(Y.homedir(),".prjct-cli"),this.globalProjectsDir=h.join(this.globalBaseDir,"projects"),this.globalConfigDir=h.join(this.globalBaseDir,"config")}setGlobalBaseDir(t){this.globalBaseDir=h.resolve(t),this.globalProjectsDir=h.join(this.globalBaseDir,"projects"),this.globalConfigDir=h.join(this.globalBaseDir,"config")}generateProjectId(t){return Ts.randomUUID()}getGlobalBasePath(){return this.globalBaseDir}getGlobalProjectPath(t){return h.join(this.globalProjectsDir,t)}getLocalConfigPath(t){return h.join(t,".prjct","prjct.config.json")}getGlobalProjectConfigPath(t){return h.join(this.getGlobalProjectPath(t),"project.json")}getLegacyPrjctPath(t){return h.join(t,".prjct")}async hasLegacyStructure(t){let e=this.getLegacyPrjctPath(t);return await Rt(e)}async hasConfig(t){let e=this.getLocalConfigPath(t);return await x(e)}async ensureGlobalStructure(){await F(this.globalBaseDir),await F(this.globalProjectsDir),await F(this.globalConfigDir)}async ensureProjectStructure(t){await this.ensureGlobalStructure();let e=this.getGlobalProjectPath(t),r=["core","progress","planning","analysis","memory"];for(let s of r)await F(h.join(e,s));return await F(h.join(e,"planning","tasks")),await F(h.join(e,"sessions")),e}getSessionPath(t,e=new Date){let{year:r,month:s,day:o}=Te(e);return h.join(this.getGlobalProjectPath(t),"sessions",r,s,o)}getCurrentSessionPath(t){return this.getSessionPath(t,new Date)}async ensureSessionPath(t,e=new Date){let r=this.getSessionPath(t,e);return await F(r),r}async listSessions(t,e=null,r=null){let s=h.join(this.getGlobalProjectPath(t),"sessions"),o=[];try{let i=await L.readdir(s,{withFileTypes:!0});for(let a of i){if(!a.isDirectory()||e&&a.name!==e.toString())continue;let u=h.join(s,a.name),p=await L.readdir(u,{withFileTypes:!0});for(let m of p){if(!m.isDirectory()||r&&m.name!==r.toString().padStart(2,"0"))continue;let d=h.join(u,m.name),g=await L.readdir(d,{withFileTypes:!0});for(let y of g)y.isDirectory()&&o.push({year:a.name,month:m.name,day:y.name,path:h.join(d,y.name),date:new Date(`${a.name}-${m.name}-${y.name}`)})}}return o.sort((a,u)=>u.date.getTime()-a.date.getTime()),o}catch{return[]}}async getSessionsInRange(t,e,r=new Date){return(await this.listSessions(t)).filter(o=>o.date>=e&&o.date<=r)}getFilePath(t,e,r){return h.join(this.getGlobalProjectPath(t),e,r)}async listProjects(){try{return await this.ensureGlobalStructure(),(await L.readdir(this.globalProjectsDir,{withFileTypes:!0})).filter(e=>e.isDirectory()).map(e=>e.name)}catch{return[]}}async projectExists(t){let e=this.getGlobalProjectPath(t);return await Rt(e)}getDisplayPath(t){let e=Y.homedir();return t.startsWith(e)?t.replace(e,"~"):t}getAuthConfigPath(){return h.join(this.globalConfigDir,"auth.json")}getSyncPendingPath(t){return h.join(this.getGlobalProjectPath(t),"sync","pending.json")}getLastSyncPath(t){return h.join(this.getGlobalProjectPath(t),"sync","last-sync.json")}getRunningStatusPath(){return h.join(this.globalBaseDir,".running")}getDocsPath(){return h.join(this.globalBaseDir,"docs")}async getAgentDir(){return(await(gt(),vt(mt)).getActiveProvider()).configDir}async getAgentSettingsPath(){let t=await(gt(),vt(mt)).getActiveProvider();return(gt(),vt(mt)).getGlobalSettingsPath(t.name)}getClaudeDir(){return h.join(Y.homedir(),".claude")}getClaudeSettingsPath(){return h.join(this.getClaudeDir(),"settings.json")}getStoragePath(t,e){return h.join(this.getGlobalProjectPath(t),"storage",e)}getContextPath(t){return h.join(this.getGlobalProjectPath(t),"context")}getWikiPath(t,e){if(e&&e.trim().length>0)return this.resolveVaultOverride(t,e);let s=h.basename(h.resolve(t)).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"project";return h.join(Y.homedir(),"Documents","prjct",s)}getWikiPathWithProjectHash(t,e){let s=h.basename(h.resolve(t)).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"project",o=e.replace(/-/g,"").slice(0,8);return h.join(Y.homedir(),"Documents","prjct",`${s}-${o}`)}getLegacyWikiPath(t){return h.join(t,".prjct","wiki")}resolveVaultOverride(t,e){let r=e.trim();return(r.startsWith("~/")||r==="~")&&(r=h.join(Y.homedir(),r.slice(1))),h.isAbsolute(r)||(r=h.resolve(t,r)),r}async detectMonorepo(t){let e={isMonorepo:!1,type:null,rootPath:t,packages:[]},r=[{file:"pnpm-workspace.yaml",type:"pnpm"},{file:"lerna.json",type:"lerna"},{file:"nx.json",type:"nx"},{file:"rush.json",type:"rush"},{file:"turbo.json",type:"turborepo"}];for(let s of r){let o=h.join(t,s.file);if(await x(o)){e.isMonorepo=!0,e.type=s.type;break}}if(!e.isMonorepo){let s=h.join(t,"package.json");if(await x(s))try{let o=await L.readFile(s,"utf-8");JSON.parse(o).workspaces&&(e.isMonorepo=!0,e.type="npm")}catch{}}return e.isMonorepo&&(e.packages=await this.discoverMonorepoPackages(t,e.type)),e}async discoverMonorepoPackages(t,e){let r=[],s=[];try{if(e==="pnpm"){let i=(await L.readFile(h.join(t,"pnpm-workspace.yaml"),"utf-8")).match(/packages:\s*\n((?:\s*-\s*.+\n?)+)/);i&&(s=i[1].split(`
13
+ `).map(a=>a.replace(/^\s*-\s*['"]?|['"]?\s*$/g,"")).filter(Boolean))}else if(e==="npm"||e==="lerna"){let o=h.join(t,"package.json"),i=await L.readFile(o,"utf-8"),a=JSON.parse(i);if(Array.isArray(a.workspaces)?s=a.workspaces:a.workspaces?.packages&&(s=a.workspaces.packages),e==="lerna"){let u=h.join(t,"lerna.json");if(await x(u)){let p=await L.readFile(u,"utf-8"),m=JSON.parse(p);m.packages&&(s=m.packages)}}}else if(e==="nx")s=["apps/*","libs/*","packages/*"];else if(e==="turborepo"){let o=h.join(t,"package.json"),i=await L.readFile(o,"utf-8"),a=JSON.parse(i);Array.isArray(a.workspaces)&&(s=a.workspaces)}s.length===0&&(s=["packages/*","apps/*","libs/*"]);for(let o of s){if(o.startsWith("!"))continue;let i=Es(o,{cwd:t,absolute:!1});for(let a of i){let u=h.join(t,a),p=h.join(u,"package.json");if(await x(p))try{let m=await L.readFile(p,"utf-8"),d=JSON.parse(m),g=h.join(u,"PRJCT.md");r.push({name:d.name||h.basename(a),path:u,relativePath:a,hasPrjctMd:await x(g)})}catch{}}}}catch{}return r}async findContainingPackage(t,e){if(!e.isMonorepo)return null;let r=h.resolve(t);for(let s of e.packages){let o=h.resolve(s.path);if(r.startsWith(o))return s}return null}async findMonorepoRoot(t){let e=h.resolve(t),r=h.parse(e).root;for(;e!==r;){if((await this.detectMonorepo(e)).isMonorepo)return e;e=h.dirname(e)}return null}},ks=new jt,b=ks;function ws(){return typeof globalThis<"u"&&"Bun"in globalThis?"bun":"node"}c(ws,"detectRuntime");function qe(){return ws()==="bun"}c(qe,"isBun");function bs(n){if(qe()){let{Database:s}=me("bun:sqlite");return new s(n,{create:!0})}let t=me("better-sqlite3"),e=new t(n),r=e.exec.bind(e);return e.run=s=>r(s),e}c(bs,"openDatabase");var Ss=[{version:1,name:"initial-schema",up:c(n=>{n.run(`
14
14
  -- =======================================================================
15
15
  -- Document storage (backward-compatible with JSON file pattern)
16
16
  -- =======================================================================
@@ -487,40 +487,40 @@ var at=Object.defineProperty;var Br=Object.getOwnPropertyDescriptor;var Hr=Objec
487
487
  name TEXT NOT NULL,
488
488
  applied_at TEXT NOT NULL
489
489
  )
490
- `);let e=new Set(t.prepare("SELECT version FROM _migrations").all().map(r=>r.version));for(let r of Ss)e.has(r.version)||t.transaction(()=>{r.up(t),t.prepare("INSERT INTO _migrations (version, name, applied_at) VALUES (?, ?, ?)").run(r.version,r.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}},T=new Ft,E=T;U();function vs(n){let t=[],e,r=new RegExp(ye.source,"g");for(;(e=r.exec(n))!==null;){let s=e[1];(s.startsWith(".")||s.startsWith("@/"))&&t.push(s)}return t}c(vs,"extractImportSources");async function _s(n,t,e){let r;if(n.startsWith("@/"))r=Y.join(e,"src",n.slice(2));else{let s=Y.dirname(Y.join(e,t));r=Y.resolve(s,n)}for(let s of he){let o=r+s;try{if((await Ye.stat(o)).isFile())return Y.relative(e,o)}catch{}}return null}c(_s,"resolveImport");async function Ps(n){let t=await _e(n),e={},r={},s=0,o=await Pe(t,50,async i=>{try{let a=await Ye.readFile(Y.join(n,i),"utf-8"),u=vs(a),p=[];for(let m of u){let d=await _s(m,i,n);d&&d!==i&&p.push(d)}return p.length>0?{filePath:i,imports:p}:null}catch{return null}});for(let{filePath:i,imports:a}of o){e[i]=a,s+=a.length;for(let u of a)r[u]||(r[u]=[]),r[u].push(i)}return{forward:e,reverse:r,fileCount:t.length,edgeCount:s,builtAt:new Date().toISOString()}}c(Ps,"buildGraph");function Je(n,t,e=2){let r=new Set(n),s=new Map,o=[];for(let i of n){let a=t.forward[i]||[],u=t.reverse[i]||[];for(let p of[...a,...u])r.has(p)||o.push({file:p,depth:1})}for(;o.length>0;){let{file:i,depth:a}=o.shift();if(a>e)continue;let u=1/(a+1),p=s.get(i);if(p){u>p.score&&s.set(i,{score:u,depth:a});continue}if(s.set(i,{score:u,depth:a}),a<e){let m=t.forward[i]||[],d=t.reverse[i]||[];for(let g of[...m,...d])!r.has(g)&&!s.has(g)&&o.push({file:g,depth:a+1})}}return Array.from(s.entries()).map(([i,{score:a,depth:u}])=>({path:i,score:a,depth:u})).sort((i,a)=>a.score-i.score)}c(Je,"scoreFromSeeds");var Ve="import-graph";function Rs(n,t){E.setDoc(n,Ve,t)}c(Rs,"saveGraph");function et(n){return E.getDoc(n,Ve)}c(et,"loadGraph");async function Ke(n,t){let e=await Ps(n);return Rs(t,e),e}c(Ke,"indexImports");function Qe(n,t){let e=[...n.added,...n.modified],r=new Set(e),s=new Set,o=et(t);if(o)for(let u of e){let p=o.reverse[u];if(p)for(let m of p)r.has(m)||s.add(m)}let i=Array.from(s),a=[...e,...i];return{directlyChanged:e,affectedByImports:i,deleted:n.deleted,allAffected:a}}c(Qe,"propagateChanges");function Ze(n){let t=new Set;for(let e of n){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(Ze,"affectedDomains");z();async function Ns(n,t=100){try{let{stdout:e}=await k(`git log --name-only --pretty=format:'---COMMIT---' -${t}`,{cwd:n,maxBuffer:10485760}),r=[],s=null;for(let o of e.split(`
491
- `)){let i=o.trim();i==="---COMMIT---"?(s&&s.size>0&&s.size<=30&&r.push(s),s=new Set):i&&s&&Cs(i)&&s.add(i)}return s&&s.size>0&&s.size<=30&&r.push(s),r}catch{return[]}}c(Ns,"parseGitLog");function Cs(n){return/\.(ts|tsx|js|jsx|mjs|cjs|py|go|rs|java|cs|rb|php|vue|svelte)$/i.test(n)&&!n.includes("node_modules/")}c(Cs,"isSourceFile");async function Is(n,t=100){let e=await Ns(n,t),r=new Map,s=new Map;for(let i of e){let a=Array.from(i);for(let u of a)r.set(u,(r.get(u)||0)+1);for(let u=0;u<a.length;u++)for(let p=u+1;p<a.length;p++){let m=Ds(a[u],a[p]);s.set(m,(s.get(m)||0)+1)}}let o={};for(let[i,a]of s){let[u,p]=i.split("\0"),m=r.get(u)||0,d=r.get(p)||0;if(m<2||d<2)continue;let g=m+d-a,h=g>0?a/g:0;h<.1||(o[u]||(o[u]={}),o[p]||(o[p]={}),o[u][p]=h,o[p][u]=h)}return{matrix:o,commitsAnalyzed:e.length,filesAnalyzed:r.size,builtAt:new Date().toISOString()}}c(Is,"buildMatrix");function Ds(n,t){return n<t?`${n}\0${t}`:`${t}\0${n}`}c(Ds,"pairKey");function Ut(n,t){let e=new Set(n),r=new Map;for(let s of n){let o=t.matrix[s];if(o)for(let[i,a]of Object.entries(o)){if(e.has(i))continue;let u=r.get(i)||0;a>u&&r.set(i,a)}}return Array.from(r.entries()).map(([s,o])=>({path:s,score:o})).sort((s,o)=>o.score-s.score)}c(Ut,"scoreFromSeeds");var rr="cochange-index";function Ls(n,t){E.setDoc(n,rr,t)}c(Ls,"saveMatrix");function Xt(n){return E.getDoc(n,rr)}c(Xt,"loadMatrix");async function sr(n,t,e=100){let r=await Is(n,e);return Ls(t,r),r}c(sr,"indexCoChanges");import zt from"node:fs/promises";import Gs from"node:path";import*as yt from"jsonc-parser";import{z as w}from"zod";var J={create(n,t){class e extends Error{static{c(this,"TypedError")}errorName;data;isOperational=!0;constructor(s){let o=t.parse(s);super(`${n}: ${JSON.stringify(o)}`),this.name=n,this.errorName=n,this.data=o,Error.captureStackTrace?.(this,this.constructor)}static throw(s){throw new e(s)}static is(s){return s instanceof e&&s.errorName===n}static create(s){return new e(s)}}return e}},pi=J.create("FileError",w.object({path:w.string(),operation:w.enum(["read","write","delete","create","copy"]),reason:w.string().optional()})),di=J.create("ValidationError",w.object({field:w.string(),expected:w.string(),received:w.string().optional(),message:w.string().optional()})),mi=J.create("PermissionError",w.object({action:w.string(),resource:w.string(),reason:w.string().optional()})),gi=J.create("TaskError",w.object({taskId:w.string().optional(),operation:w.enum(["create","update","complete","pause","resume","delete"]),reason:w.string()})),fi=J.create("SessionError",w.object({sessionId:w.string().optional(),reason:w.string()})),hi=J.create("SyncError",w.object({projectId:w.string().optional(),operation:w.enum(["push","pull","auth","connect"]),reason:w.string()})),$t=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)}};function Os(n){return n instanceof $t}c(Os,"isPrjctError");function Wt(n){return Os(n)||n instanceof Error?n.message:typeof n=="string"?n:"Unknown error"}c(Wt,"getErrorMessage");W();U();W();import Gt from"node:fs";import ft from"node:path";var gt=null,js=null,rt=null;function nr(){if(rt)return rt;let n=__dirname;for(let t=0;t<5;t++){let e=ft.join(n,"package.json");if(Gt.existsSync(e))try{if(JSON.parse(Gt.readFileSync(e,"utf-8")).name==="prjct-cli")return rt=n,n}catch{}n=ft.dirname(n)}return rt=ft.join(__dirname,"..","..",".."),rt}c(nr,"getPackageRoot");function Ms(){if(gt)return gt;try{let n=ft.join(nr(),"package.json"),t=JSON.parse(Gt.readFileSync(n,"utf-8"));return gt=t.version,js=t,gt}catch(n){return console.error("Failed to read version from package.json:",ke(n)),"0.0.0"}}c(Ms,"getVersion");var Bt=Ms(),bi=nr();z();async function ht(n){try{let{stdout:t}=await k(n,{timeout:5e3});return{success:!0,output:t.trim()}}catch{return{success:!1,output:""}}}c(ht,"execCommand");async function Fs(){let n=await ht("gh api user --jq .login");return n.success&&n.output||(n=await ht("git config --global github.user"),n.success&&n.output)?n.output:null}c(Fs,"detectGitHubUsername");async function Us(){let n=await ht("git config user.name");return n.success&&n.output?n.output:null}c(Us,"detectGitName");async function Xs(){let n=await ht("git config user.email");return n.success&&n.output?n.output:null}c(Xs,"detectGitEmail");async function or(){let[n,t,e]=await Promise.all([Fs(),Us(),Xs()]);return{github:n,email:e,name:t||n||"Unknown"}}c(or,"detect");function lr(n){let t=[],e=yt.parse(n,t,{allowTrailingComma:!0,disallowComments:!1});if(t.length>0){let r=t[0];throw new SyntaxError(`JSON parse error at offset ${r.offset}: ${yt.printParseErrorCode(r.error)}`)}return e}c(lr,"parseJsonc");var Yt=class{static{c(this,"ConfigManager")}async readConfig(t){try{let e=b.getLocalConfigPath(t),r=await zt.readFile(e,"utf-8");return lr(r)}catch(e){return N(e)||console.warn(`Warning: Could not read config at ${t}: ${Wt(e)}`),null}}async writeConfig(t,e){let r=b.getLocalConfigPath(t);await M(r,e)}async readGlobalConfig(t){try{let e=b.getGlobalProjectConfigPath(t),r=await zt.readFile(e,"utf-8");return lr(r)}catch(e){return N(e)||console.warn(`Warning: Could not read global config for ${t}: ${Wt(e)}`),null}}async writeGlobalConfig(t,e){let r=b.getGlobalProjectConfigPath(t);await M(r,e)}async ensureGlobalConfig(t){let e=await this.readGlobalConfig(t);if(!e){let r=f();e={projectId:t,authors:[],version:Bt,lastSync:r},await this.writeGlobalConfig(t,e)}return e}async createConfig(t,e){let r=b.generateProjectId(t),s=b.getGlobalProjectPath(r),o=b.getDisplayPath(s),i=f(),a={projectId:r,dataPath:o,showMetrics:!0};await this.writeConfig(t,a);let u={projectId:r,authors:[{name:e.name||"Unknown",email:e.email||"",github:e.github||"",firstContribution:i,lastActivity:i}],version:Bt,created:i,lastSync:i};return await this.writeGlobalConfig(r,u),a}async updateLastSync(t){let e=await this.getProjectId(t),r=await this.readGlobalConfig(e);r&&(r.lastSync=f(),await this.writeGlobalConfig(e,r))}validateConfig(t){return!(!t||!t.projectId||!t.dataPath)}async needsMigration(t){if(!await b.hasLegacyStructure(t))return!1;if(!await b.hasConfig(t))return!0;let s=await this.readConfig(t);if(!s||!s.projectId)return!0;let o=b.getGlobalProjectPath(s.projectId);try{return(await zt.readdir(Gs.join(o,"core"))).length===0}catch(i){return N(i),!0}}async getProjectId(t){let e=await this.readConfig(t);if(e?.projectId)return e.projectId;try{let{worktreeService:r}=await Promise.resolve().then(()=>(ur(),cr));if(await r.detect(t)){let o=await r.getMainWorktree(t);if(o!==t){let i=await this.readConfig(o);if(i?.projectId)return i.projectId}}}catch{}return b.generateProjectId(t)}async findAuthor(t,e){let r=await this.readGlobalConfig(t);return!r||!r.authors?null:r.authors.find(s=>s.github===e)||null}async addAuthor(t,e){let r=await this.ensureGlobalConfig(t);if(r.authors.some(i=>i.github===e.github))return;let o=f();r.authors.push({name:e.name||"Unknown",email:e.email||"",github:e.github||"",firstContribution:o,lastActivity:o}),r.lastSync=o,await this.writeGlobalConfig(t,r)}async updateAuthorActivity(t,e){let r=await this.readGlobalConfig(t);if(!r||!r.authors)return;let s=r.authors.find(o=>o.github===e);s&&(s.lastActivity=f(),r.lastSync=s.lastActivity,await this.writeGlobalConfig(t,r))}async getCurrentAuthor(t){let e=await or(),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=b.generateProjectId(t);return{projectId:r,dataPath:b.getDisplayPath(b.getGlobalProjectPath(r))}}},Bs=new Yt,B=Bs;async function P(n){return B.getProjectId(n)}c(P,"resolveProjectId");function S(n,t){return async e=>{try{return await t(e)}catch(r){return Hs(r,n)}}}c(S,"safeMcpCall");function Hs(n,t){let e=n instanceof Error?n.message:String(n);return{content:[{type:"text",text:`[${t}] Error: ${e}`}],isError:!0}}c(Hs,"mcpError");function pr(n){let t=n;t.tool("prjct_impact_analysis","Given changed files, find affected files via import graph + affected domains",{projectPath:A.string().describe("Project directory path"),changedFiles:A.array(A.string()).describe("List of changed file paths (relative to project root)")},S("prjct_impact_analysis",async e=>{let r=await P(e.projectPath),s={added:[],modified:e.changedFiles,deleted:[],unchanged:[]},o=Qe(s,r),i=Ze(o.allAffected),a=["## Impact Analysis"];a.push(`
490
+ `);let e=new Set(t.prepare("SELECT version FROM _migrations").all().map(r=>r.version));for(let r of Ss)e.has(r.version)||t.transaction(()=>{r.up(t),t.prepare("INSERT INTO _migrations (version, name, applied_at) VALUES (?, ?, ?)").run(r.version,r.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}},T=new Ft,E=T;U();function vs(n){let t=[],e,r=new RegExp(ye.source,"g");for(;(e=r.exec(n))!==null;){let s=e[1];(s.startsWith(".")||s.startsWith("@/"))&&t.push(s)}return t}c(vs,"extractImportSources");async function _s(n,t,e){let r;if(n.startsWith("@/"))r=J.join(e,"src",n.slice(2));else{let s=J.dirname(J.join(e,t));r=J.resolve(s,n)}for(let s of he){let o=r+s;try{if((await Ye.stat(o)).isFile())return J.relative(e,o)}catch{}}return null}c(_s,"resolveImport");async function Ps(n){let t=await _e(n),e={},r={},s=0,o=await Pe(t,50,async i=>{try{let a=await Ye.readFile(J.join(n,i),"utf-8"),u=vs(a),p=[];for(let m of u){let d=await _s(m,i,n);d&&d!==i&&p.push(d)}return p.length>0?{filePath:i,imports:p}:null}catch{return null}});for(let{filePath:i,imports:a}of o){e[i]=a,s+=a.length;for(let u of a)r[u]||(r[u]=[]),r[u].push(i)}return{forward:e,reverse:r,fileCount:t.length,edgeCount:s,builtAt:new Date().toISOString()}}c(Ps,"buildGraph");function Je(n,t,e=2){let r=new Set(n),s=new Map,o=[];for(let i of n){let a=t.forward[i]||[],u=t.reverse[i]||[];for(let p of[...a,...u])r.has(p)||o.push({file:p,depth:1})}for(;o.length>0;){let{file:i,depth:a}=o.shift();if(a>e)continue;let u=1/(a+1),p=s.get(i);if(p){u>p.score&&s.set(i,{score:u,depth:a});continue}if(s.set(i,{score:u,depth:a}),a<e){let m=t.forward[i]||[],d=t.reverse[i]||[];for(let g of[...m,...d])!r.has(g)&&!s.has(g)&&o.push({file:g,depth:a+1})}}return Array.from(s.entries()).map(([i,{score:a,depth:u}])=>({path:i,score:a,depth:u})).sort((i,a)=>a.score-i.score)}c(Je,"scoreFromSeeds");var Ve="import-graph";function Rs(n,t){E.setDoc(n,Ve,t)}c(Rs,"saveGraph");function rt(n){return E.getDoc(n,Ve)}c(rt,"loadGraph");async function Ke(n,t){let e=await Ps(n);return Rs(t,e),e}c(Ke,"indexImports");function Qe(n,t){let e=[...n.added,...n.modified],r=new Set(e),s=new Set,o=rt(t);if(o)for(let u of e){let p=o.reverse[u];if(p)for(let m of p)r.has(m)||s.add(m)}let i=Array.from(s),a=[...e,...i];return{directlyChanged:e,affectedByImports:i,deleted:n.deleted,allAffected:a}}c(Qe,"propagateChanges");function Ze(n){let t=new Set;for(let e of n){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(Ze,"affectedDomains");z();async function Ns(n,t=100){try{let{stdout:e}=await k(`git log --name-only --pretty=format:'---COMMIT---' -${t}`,{cwd:n,maxBuffer:10485760}),r=[],s=null;for(let o of e.split(`
491
+ `)){let i=o.trim();i==="---COMMIT---"?(s&&s.size>0&&s.size<=30&&r.push(s),s=new Set):i&&s&&Cs(i)&&s.add(i)}return s&&s.size>0&&s.size<=30&&r.push(s),r}catch{return[]}}c(Ns,"parseGitLog");function Cs(n){return/\.(ts|tsx|js|jsx|mjs|cjs|py|go|rs|java|cs|rb|php|vue|svelte)$/i.test(n)&&!n.includes("node_modules/")}c(Cs,"isSourceFile");async function Is(n,t=100){let e=await Ns(n,t),r=new Map,s=new Map;for(let i of e){let a=Array.from(i);for(let u of a)r.set(u,(r.get(u)||0)+1);for(let u=0;u<a.length;u++)for(let p=u+1;p<a.length;p++){let m=Ds(a[u],a[p]);s.set(m,(s.get(m)||0)+1)}}let o={};for(let[i,a]of s){let[u,p]=i.split("\0"),m=r.get(u)||0,d=r.get(p)||0;if(m<2||d<2)continue;let g=m+d-a,y=g>0?a/g:0;y<.1||(o[u]||(o[u]={}),o[p]||(o[p]={}),o[u][p]=y,o[p][u]=y)}return{matrix:o,commitsAnalyzed:e.length,filesAnalyzed:r.size,builtAt:new Date().toISOString()}}c(Is,"buildMatrix");function Ds(n,t){return n<t?`${n}\0${t}`:`${t}\0${n}`}c(Ds,"pairKey");function Ut(n,t){let e=new Set(n),r=new Map;for(let s of n){let o=t.matrix[s];if(o)for(let[i,a]of Object.entries(o)){if(e.has(i))continue;let u=r.get(i)||0;a>u&&r.set(i,a)}}return Array.from(r.entries()).map(([s,o])=>({path:s,score:o})).sort((s,o)=>o.score-s.score)}c(Ut,"scoreFromSeeds");var rr="cochange-index";function Ls(n,t){E.setDoc(n,rr,t)}c(Ls,"saveMatrix");function Xt(n){return E.getDoc(n,rr)}c(Xt,"loadMatrix");async function sr(n,t,e=100){let r=await Is(n,e);return Ls(t,r),r}c(sr,"indexCoChanges");import zt from"node:fs/promises";import Gs from"node:path";import*as Tt from"jsonc-parser";import{z as w}from"zod";var V={create(n,t){class e extends Error{static{c(this,"TypedError")}errorName;data;isOperational=!0;constructor(s){let o=t.parse(s);super(`${n}: ${JSON.stringify(o)}`),this.name=n,this.errorName=n,this.data=o,Error.captureStackTrace?.(this,this.constructor)}static throw(s){throw new e(s)}static is(s){return s instanceof e&&s.errorName===n}static create(s){return new e(s)}}return e}},pi=V.create("FileError",w.object({path:w.string(),operation:w.enum(["read","write","delete","create","copy"]),reason:w.string().optional()})),di=V.create("ValidationError",w.object({field:w.string(),expected:w.string(),received:w.string().optional(),message:w.string().optional()})),mi=V.create("PermissionError",w.object({action:w.string(),resource:w.string(),reason:w.string().optional()})),gi=V.create("TaskError",w.object({taskId:w.string().optional(),operation:w.enum(["create","update","complete","pause","resume","delete"]),reason:w.string()})),fi=V.create("SessionError",w.object({sessionId:w.string().optional(),reason:w.string()})),hi=V.create("SyncError",w.object({projectId:w.string().optional(),operation:w.enum(["push","pull","auth","connect"]),reason:w.string()})),$t=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)}};function Os(n){return n instanceof $t}c(Os,"isPrjctError");function Wt(n){return Os(n)||n instanceof Error?n.message:typeof n=="string"?n:"Unknown error"}c(Wt,"getErrorMessage");W();U();W();import Gt from"node:fs";import ht from"node:path";var ft=null,js=null,st=null;function nr(){if(st)return st;let n=__dirname;for(let t=0;t<5;t++){let e=ht.join(n,"package.json");if(Gt.existsSync(e))try{if(JSON.parse(Gt.readFileSync(e,"utf-8")).name==="prjct-cli")return st=n,n}catch{}n=ht.dirname(n)}return st=ht.join(__dirname,"..","..",".."),st}c(nr,"getPackageRoot");function Ms(){if(ft)return ft;try{let n=ht.join(nr(),"package.json"),t=JSON.parse(Gt.readFileSync(n,"utf-8"));return ft=t.version,js=t,ft}catch(n){return console.error("Failed to read version from package.json:",ke(n)),"0.0.0"}}c(Ms,"getVersion");var Bt=Ms(),bi=nr();z();async function yt(n){try{let{stdout:t}=await k(n,{timeout:5e3});return{success:!0,output:t.trim()}}catch{return{success:!1,output:""}}}c(yt,"execCommand");async function Fs(){let n=await yt("gh api user --jq .login");return n.success&&n.output||(n=await yt("git config --global github.user"),n.success&&n.output)?n.output:null}c(Fs,"detectGitHubUsername");async function Us(){let n=await yt("git config user.name");return n.success&&n.output?n.output:null}c(Us,"detectGitName");async function Xs(){let n=await yt("git config user.email");return n.success&&n.output?n.output:null}c(Xs,"detectGitEmail");async function or(){let[n,t,e]=await Promise.all([Fs(),Us(),Xs()]);return{github:n,email:e,name:t||n||"Unknown"}}c(or,"detect");function lr(n){let t=[],e=Tt.parse(n,t,{allowTrailingComma:!0,disallowComments:!1});if(t.length>0){let r=t[0];throw new SyntaxError(`JSON parse error at offset ${r.offset}: ${Tt.printParseErrorCode(r.error)}`)}return e}c(lr,"parseJsonc");var Yt=class{static{c(this,"ConfigManager")}async readConfig(t){try{let e=b.getLocalConfigPath(t),r=await zt.readFile(e,"utf-8");return lr(r)}catch(e){return N(e)||console.warn(`Warning: Could not read config at ${t}: ${Wt(e)}`),null}}async writeConfig(t,e){let r=b.getLocalConfigPath(t);await M(r,e)}async readGlobalConfig(t){try{let e=b.getGlobalProjectConfigPath(t),r=await zt.readFile(e,"utf-8");return lr(r)}catch(e){return N(e)||console.warn(`Warning: Could not read global config for ${t}: ${Wt(e)}`),null}}async writeGlobalConfig(t,e){let r=b.getGlobalProjectConfigPath(t);await M(r,e)}async ensureGlobalConfig(t){let e=await this.readGlobalConfig(t);if(!e){let r=f();e={projectId:t,authors:[],version:Bt,lastSync:r},await this.writeGlobalConfig(t,e)}return e}async createConfig(t,e){let r=b.generateProjectId(t),s=b.getGlobalProjectPath(r),o=b.getDisplayPath(s),i=f(),a={projectId:r,dataPath:o,showMetrics:!0};await this.writeConfig(t,a);let u={projectId:r,authors:[{name:e.name||"Unknown",email:e.email||"",github:e.github||"",firstContribution:i,lastActivity:i}],version:Bt,created:i,lastSync:i};return await this.writeGlobalConfig(r,u),a}async updateLastSync(t){let e=await this.getProjectId(t),r=await this.readGlobalConfig(e);r&&(r.lastSync=f(),await this.writeGlobalConfig(e,r))}validateConfig(t){return!(!t||!t.projectId||!t.dataPath)}async needsMigration(t){if(!await b.hasLegacyStructure(t))return!1;if(!await b.hasConfig(t))return!0;let s=await this.readConfig(t);if(!s||!s.projectId)return!0;let o=b.getGlobalProjectPath(s.projectId);try{return(await zt.readdir(Gs.join(o,"core"))).length===0}catch(i){return N(i),!0}}async getProjectId(t){let e=await this.readConfig(t);if(e?.projectId)return e.projectId;try{let{worktreeService:r}=await Promise.resolve().then(()=>(ur(),cr));if(await r.detect(t)){let o=await r.getMainWorktree(t);if(o!==t){let i=await this.readConfig(o);if(i?.projectId)return i.projectId}}}catch{}return b.generateProjectId(t)}async findAuthor(t,e){let r=await this.readGlobalConfig(t);return!r||!r.authors?null:r.authors.find(s=>s.github===e)||null}async addAuthor(t,e){let r=await this.ensureGlobalConfig(t);if(r.authors.some(i=>i.github===e.github))return;let o=f();r.authors.push({name:e.name||"Unknown",email:e.email||"",github:e.github||"",firstContribution:o,lastActivity:o}),r.lastSync=o,await this.writeGlobalConfig(t,r)}async updateAuthorActivity(t,e){let r=await this.readGlobalConfig(t);if(!r||!r.authors)return;let s=r.authors.find(o=>o.github===e);s&&(s.lastActivity=f(),r.lastSync=s.lastActivity,await this.writeGlobalConfig(t,r))}async getCurrentAuthor(t){let e=await or(),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=b.generateProjectId(t);return{projectId:r,dataPath:b.getDisplayPath(b.getGlobalProjectPath(r))}}},Bs=new Yt,B=Bs;async function P(n){return B.getProjectId(n)}c(P,"resolveProjectId");function S(n,t){return async e=>{try{return await t(e)}catch(r){return Hs(r,n)}}}c(S,"safeMcpCall");function Hs(n,t){let e=n instanceof Error?n.message:String(n);return{content:[{type:"text",text:`[${t}] Error: ${e}`}],isError:!0}}c(Hs,"mcpError");function pr(n){let t=n;t.tool("prjct_impact_analysis","Given changed files, find affected files via import graph + affected domains",{projectPath:A.string().describe("Project directory path"),changedFiles:A.array(A.string()).describe("List of changed file paths (relative to project root)")},S("prjct_impact_analysis",async e=>{let r=await P(e.projectPath),s={added:[],modified:e.changedFiles,deleted:[],unchanged:[]},o=Qe(s,r),i=Ze(o.allAffected),a=["## Impact Analysis"];a.push(`
492
492
  ### Directly Changed (${o.directlyChanged.length})`);for(let u of o.directlyChanged)a.push(`- ${u}`);if(o.affectedByImports.length>0){a.push(`
493
493
  ### Affected via Imports (${o.affectedByImports.length})`);for(let u of o.affectedByImports)a.push(`- ${u}`)}return a.push(`
494
494
  ### Affected Domains`),a.push(i.size>0?Array.from(i).join(", "):"none detected"),a.push(`
495
495
  Total affected: ${o.allAffected.length} files`),{content:[{type:"text",text:a.join(`
496
- `)}]}})),t.tool("prjct_import_graph","Import graph stats + file neighbors (imports/importers). Pass a file for its neighbors, omit for graph stats.",{projectPath:A.string().describe("Project directory path"),file:A.string().optional().describe("File path to get neighbors for (omit for graph stats)"),rebuild:A.boolean().optional().default(!1).describe("Force rebuild the import graph")},S("prjct_import_graph",async e=>{let r=await P(e.projectPath),s=e.rebuild?null:et(r);if(s||(s=await Ke(e.projectPath,r)),e.file){let i=s.forward[e.file]||[],a=s.reverse[e.file]||[];return{content:[{type:"text",text:[`## Import Neighbors: ${e.file}`,`
496
+ `)}]}})),t.tool("prjct_import_graph","Import graph stats + file neighbors (imports/importers). Pass a file for its neighbors, omit for graph stats.",{projectPath:A.string().describe("Project directory path"),file:A.string().optional().describe("File path to get neighbors for (omit for graph stats)"),rebuild:A.boolean().optional().default(!1).describe("Force rebuild the import graph")},S("prjct_import_graph",async e=>{let r=await P(e.projectPath),s=e.rebuild?null:rt(r);if(s||(s=await Ke(e.projectPath,r)),e.file){let i=s.forward[e.file]||[],a=s.reverse[e.file]||[];return{content:[{type:"text",text:[`## Import Neighbors: ${e.file}`,`
497
497
  ### Imports (${i.length})`,...i.map(p=>`- ${p}`),`
498
498
  ### Imported By (${a.length})`,...a.map(p=>`- ${p}`)].join(`
499
499
  `)}]}}return{content:[{type:"text",text:["## Import Graph Stats",`Files: ${s.fileCount}`,`Edges: ${s.edgeCount}`,`Built: ${s.builtAt}`].join(`
500
500
  `)}]}})),t.tool("prjct_cochange","Files that historically change together (Jaccard similarity from git history)",{projectPath:A.string().describe("Project directory path"),seedFiles:A.array(A.string()).describe("Seed files to find co-change partners for"),rebuild:A.boolean().optional().default(!1).describe("Force rebuild the co-change matrix"),maxResults:A.number().optional().default(10).describe("Max results (default 10)")},S("prjct_cochange",async e=>{let r=await P(e.projectPath),s=e.rebuild?null:Xt(r);s||(s=await sr(e.projectPath,r));let o=Ut(e.seedFiles,s).slice(0,e.maxResults);if(o.length===0)return{content:[{type:"text",text:"No co-change partners found."}]};let i=["## Co-Change Partners",`Seeds: ${e.seedFiles.join(", ")}`,`Commits analyzed: ${s.commitsAnalyzed}`,""];for(let a of o)i.push(`- ${a.path} (similarity: ${Math.round(a.score*100)}%)`);return{content:[{type:"text",text:i.join(`
501
- `)}]}})),t.tool("prjct_related_context","Combined: import neighbors + co-change partners for seed files",{projectPath:A.string().describe("Project directory path"),seedFiles:A.array(A.string()).describe("Seed files to find related context for"),maxResults:A.number().optional().default(15).describe("Max results (default 15)")},S("prjct_related_context",async e=>{let r=await P(e.projectPath),s=et(r),o=s?Je(e.seedFiles,s):[],i=Xt(r),a=i?Ut(e.seedFiles,i):[],u=new Map;for(let d of o)u.set(d.path,{importScore:d.score,cochangeScore:0});for(let d of a){let g=u.get(d.path);g?g.cochangeScore=d.score:u.set(d.path,{importScore:0,cochangeScore:d.score})}let p=Array.from(u.entries()).map(([d,g])=>({path:d,combined:g.importScore*.6+g.cochangeScore*.4,importScore:g.importScore,cochangeScore:g.cochangeScore})).sort((d,g)=>g.combined-d.combined).slice(0,e.maxResults);if(p.length===0)return{content:[{type:"text",text:"No related files found. Run `prjct sync` to build indexes."}]};let m=["## Related Context",`Seeds: ${e.seedFiles.join(", ")}`,""];for(let d of p){let g=[];d.importScore>0&&g.push(`import: ${d.importScore.toFixed(2)}`),d.cochangeScore>0&&g.push(`cochange: ${Math.round(d.cochangeScore*100)}%`),m.push(`- ${d.path} (${g.join(", ")})`)}return{content:[{type:"text",text:m.join(`
502
- `)}]}}))}c(pr,"registerCodeIntelTools");import{z as H}from"zod";import qs from"node:crypto";import{homedir as zs}from"node:os";import{join as Ys}from"node:path";function $(){return qs.randomUUID()}c($,"generateUUID");var na=Ys(zs(),".prjct-cli","projects");Rt();import{z as l}from"zod";var Js=l.enum(["low","medium","high","critical"]),Tt=l.enum(["feature","bug","improvement","chore"]),Vs=l.enum(["active","backlog","previously_active"]),Ks=l.enum(["pending","in_progress","completed","blocked","paused","failed","skipped"]),Qs=l.enum(["task_completed","feature_shipped","idea_captured","session_started"]),Jt=l.object({title:l.string(),description:l.string(),filesChanged:l.array(l.object({path:l.string(),action:l.enum(["created","modified","deleted"])})),whatWasDone:l.array(l.string()).min(1),outputForNextAgent:l.string().min(1),notes:l.string().optional()}),mr=l.object({output:l.string().min(1,"Subtask output is required"),summary:Jt}),gr=l.object({id:l.string(),description:l.string(),domain:l.string(),agent:l.string(),status:Ks,dependsOn:l.array(l.string()),startedAt:l.string().optional(),completedAt:l.string().optional(),output:l.string().optional(),summary:Jt.optional(),skipReason:l.string().optional(),blockReason:l.string().optional(),estimatedPoints:l.number().optional(),estimatedMinutes:l.number().optional()}),fr=l.object({completed:l.number(),total:l.number(),percentage:l.number()}),Vt=l.object({id:l.string(),description:l.string(),type:Tt.optional(),startedAt:l.string(),sessionId:l.string(),featureId:l.string().optional(),subtasks:l.array(gr).optional(),currentSubtaskIndex:l.number().optional(),subtaskProgress:fr.optional(),linearId:l.string().optional(),linearUuid:l.string().optional(),estimatedPoints:l.number().optional(),estimatedMinutes:l.number().optional(),modelMetadata:ut.optional(),tokensIn:l.number().optional(),tokensOut:l.number().optional(),parentDescription:l.string().optional(),branch:l.string().optional(),prUrl:l.string().optional()}),dr=l.object({id:l.string(),description:l.string(),status:l.literal("paused"),startedAt:l.string(),pausedAt:l.string(),pauseReason:l.string().optional(),type:Tt.optional(),sessionId:l.string().optional(),featureId:l.string().optional(),subtasks:l.array(gr).optional(),currentSubtaskIndex:l.number().optional(),subtaskProgress:fr.optional(),linearId:l.string().optional(),linearUuid:l.string().optional(),estimatedPoints:l.number().optional(),estimatedMinutes:l.number().optional(),modelMetadata:ut.optional(),tokensIn:l.number().optional(),tokensOut:l.number().optional()}),Zs=l.object({stackConfirmed:l.array(l.string()).optional(),patternsDiscovered:l.array(l.string()).optional(),agentAccuracy:l.array(l.object({agent:l.string(),rating:l.enum(["helpful","neutral","inaccurate"]),note:l.string().optional()})).optional(),issuesEncountered:l.array(l.string()).optional()}),tn=l.object({taskId:l.string(),title:l.string(),classification:Tt,startedAt:l.string(),completedAt:l.string(),subtaskCount:l.number(),subtaskSummaries:l.array(Jt),outcome:l.string(),branchName:l.string(),linearId:l.string().optional(),linearUuid:l.string().optional(),prUrl:l.string().optional(),feedback:Zs.optional(),tokensIn:l.number().optional(),tokensOut:l.number().optional()}),en=Vt.extend({workspaceId:l.string(),worktreePath:l.string().optional(),agentSessionId:l.string().optional(),jiraId:l.string().optional(),jiraUuid:l.string().optional(),dispatchedFrom:l.string().optional()}),hr=l.object({currentTask:Vt.nullable(),previousTask:dr.nullable().optional(),pausedTasks:l.array(dr).optional(),taskHistory:l.array(tn).optional(),activeTasks:l.array(en).optional(),lastUpdated:l.string()}),yr=l.object({id:l.string(),description:l.string(),body:l.string().optional(),priority:Js,type:Tt,featureId:l.string().optional(),originFeature:l.string().optional(),completed:l.boolean(),completedAt:l.string().optional(),createdAt:l.string(),section:Vs,agent:l.string().optional(),groupName:l.string().optional(),groupId:l.string().optional()}),Tr=l.object({tasks:l.array(yr),lastUpdated:l.string()}),rn=l.object({tasksToday:l.number(),tasksThisWeek:l.number(),streak:l.number(),velocity:l.string(),avgDuration:l.string()}),sn=l.object({type:Qs,description:l.string(),timestamp:l.string(),duration:l.string().optional()}),ua=l.object({projectId:l.string(),currentTask:Vt.nullable(),queue:l.array(yr),stats:rn,recentActivity:l.array(sn),lastSync:l.string()});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"}},Kt=class{static{c(this,"WorkflowStateMachine")}getCurrentState(t,e){let r=null;if(e&&t?.activeTasks?.length&&(r=t.activeTasks.find(o=>o.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 s=this.formatNextSteps(t).join(" | ");return{valid:!1,error:`Cannot transition to '${e}' from '${t}' state`,suggestion:`Valid next steps: ${s}`}}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}`}})}},Qt=new Kt;var nt={SHIPPED_RETENTION_DAYS:90,IDEA_DORMANT_DAYS:180,QUEUE_COMPLETED_DAYS:7,PAUSED_TASK_DAYS:30,MEMORY_MAX_ENTRIES:500},Zt=class{static{c(this,"ArchiveStorage")}archive(t,e){let r=$(),s=f();return T.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,s,e.reason),r}archiveMany(t,e){if(e.length===0)return 0;let r=f();return T.transaction(t,s=>{let o=s.prepare("INSERT INTO archives (id, entity_type, entity_id, entity_data, summary, archived_at, reason) VALUES (?, ?, ?, ?, ?, ?, ?)");for(let i of e)o.run($(),i.entityType,i.entityId,JSON.stringify(i.entityData),i.summary??null,r,i.reason)}),e.length}getArchived(t,e,r=50){return e?T.query(t,"SELECT * FROM archives WHERE entity_type = ? ORDER BY archived_at DESC LIMIT ?",e,r):T.query(t,"SELECT * FROM archives ORDER BY archived_at DESC LIMIT ?",r)}getStats(t){let e=T.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 s of e){let o=s.entity_type;o in r&&(r[o]=s.count),r.total+=s.count}return r}restore(t,e){let r=T.get(t,"SELECT * FROM archives WHERE id = ?",e);return r?(T.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(),s=this.getTotalCount(t);T.run(t,"DELETE FROM archives WHERE archived_at < ?",r);let o=this.getTotalCount(t);return s-o}getTotalCount(t){return T.get(t,"SELECT COUNT(*) as count FROM archives")?.count??0}},V=new Zt;U();var te=class{static{c(this,"SyncEventBus")}async publish(t){let e=b.getSyncPendingPath(t.projectId),r=await ct(e,[])??[],s=Array.isArray(r)?r:[];s.push(t),await M(e,s)}async getPending(t){let e=b.getSyncPendingPath(t),r=await ct(e,[])??[];return Array.isArray(r)?r:[]}async clearPending(t){let e=b.getSyncPendingPath(t);await M(e,[])}async updateLastSync(t){let e=b.getLastSyncPath(t),r={timestamp:f(),success:!0};await M(e,r)}async getLastSync(t){let e=b.getLastSyncPath(t);return await ct(e,null)}},Er=new te;At();var K=class{static{c(this,"StorageManager")}filename;cache;constructor(t,e){this.filename=t,this.cache=new lt({ttl:5e3,maxSize:50})}getStoreKey(){return this.filename.replace(".json","")}async read(t){let e=this.cache.get(t);if(e!==null)return e;try{let r=T.getDoc(t,this.getStoreKey());if(r!==null)return this.cache.set(t,r),r}catch{}return this.getDefault()}async write(t,e){T.setDoc(t,this.getStoreKey(),e),this.cache.set(t,e)}async update(t,e){let r=await this.read(t),s=e(r);return await this.write(t,s),s}async publishEvent(t,e,r){let s={type:e,path:[this.filename.replace(".json","")],data:r,timestamp:f(),projectId:t};await Er.publish(s)}async publishEntityEvent(t,e,r,s){let o=`${e}.${r}`,i={...s,timestamp:f()};await this.publishEvent(t,o,i)}async exists(t){try{return T.hasDoc(t,this.getStoreKey())}catch{return!1}}clearCache(t){t?this.cache.delete(t):this.cache.clear()}getCacheStats(){return this.cache.stats()}};var ee=class extends K{static{c(this,"StateStorage")}constructor(){super("state.json",hr)}getDefault(){return{currentTask:null,previousTask:null,pausedTasks:[],taskHistory:[],activeTasks:[],lastUpdated:""}}getEventType(t){return`state.${t}d`}validateTransition(t,e){let r=Qt.getCurrentState(t),s=Qt.canTransition(r,e);if(!s.valid)throw new Error(`${s.error}. ${s.suggestion||""}`.trim())}async getCurrentTask(t){return(await this.read(t)).currentTask}async startTask(t,e){let r=await this.read(t);this.validateTransition(r,"task");let s={...e,startedAt:f()};return await this.update(t,o=>({...o,currentTask:s,lastUpdated:f()})),await this.publishEvent(t,"task.started",{taskId:s.id,description:s.description,startedAt:s.startedAt,sessionId:s.sessionId}),s}async updateCurrentTask(t,e){let r=await this.read(t);if(!r.currentTask)return null;let s={...r.currentTask,...e};return await this.update(t,o=>({...o,currentTask:s,lastUpdated:f()})),s}async completeTask(t,e){let r=await this.read(t),s=r.currentTask;if(!s)return null;this.validateTransition(r,"done");let o=f(),i=this.createTaskHistoryEntry(s,o,e),a=this.getTaskHistoryFromState(r),u=[i,...a].slice(0,this.maxTaskHistory);return await this.update(t,p=>({...p,currentTask:null,previousTask:null,taskHistory:u,lastUpdated:o})),await this.publishEvent(t,"task.completed",{taskId:s.id,description:s.description,startedAt:s.startedAt,completedAt:o}),s}createTaskHistoryEntry(t,e,r){let s=(t.subtasks||[]).filter(a=>a.status==="completed"&&a.summary).map(a=>a.summary),o=s.length>0?s.map(a=>a.title).join(", "):"Task completed",i={taskId:t.id,title:t.parentDescription||t.description,classification:t.type||"improvement",startedAt:t.startedAt,completedAt:e,subtaskCount:t.subtasks?.length||0,subtaskSummaries:s,outcome:o,branchName:t.branch||"unknown",linearId:t.linearId,linearUuid:t.linearUuid,prUrl:t.prUrl};return r&&(i.feedback=r),t.tokensIn&&(i.tokensIn=t.tokensIn),t.tokensOut&&(i.tokensOut=t.tokensOut),i}maxPausedTasks=5;maxTaskHistory=20;stalenessThresholdDays=30;async pauseTask(t,e){let r=await this.read(t);if(!r.currentTask)return null;this.validateTransition(r,"pause");let s={...r.currentTask,status:"paused",pausedAt:f(),pauseReason:e},o=this.getPausedTasksFromState(r),i=[s,...o].slice(0,this.maxPausedTasks);return await this.update(t,a=>({...a,currentTask:null,previousTask:null,pausedTasks:i,lastUpdated:f()})),await this.publishEvent(t,"task.paused",{taskId:s.id,description:s.description,pausedAt:s.pausedAt,reason:e,pausedCount:i.length}),s}async resumeTask(t,e){let r=await this.read(t),s=this.getPausedTasksFromState(r);if(s.length===0)return null;this.validateTransition(r,"resume");let o=0;if(e&&(o=s.findIndex(h=>h.id===e),o===-1))return null;let i=s[o],a=s.filter((h,j)=>j!==o),{status:u,pausedAt:p,pauseReason:m,...d}=i,g={...d,startedAt:f(),sessionId:i.sessionId??$()};return await this.update(t,h=>({...h,currentTask:g,previousTask:null,pausedTasks:a,lastUpdated:f()})),await this.publishEvent(t,"task.resumed",{taskId:g.id,description:g.description,resumedAt:g.startedAt,remainingPaused:a.length}),g}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){let e=await this.read(t),r=this.getPausedTasksFromState(e),s=Date.now()-this.stalenessThresholdDays*24*60*60*1e3;return r.filter(o=>new Date(o.pausedAt).getTime()<s)}async archiveStalePausedTasks(t){let e=await this.read(t),r=this.getPausedTasksFromState(e),s=Date.now()-this.stalenessThresholdDays*24*60*60*1e3,o=r.filter(a=>new Date(a.pausedAt).getTime()<s),i=r.filter(a=>new Date(a.pausedAt).getTime()>=s);if(o.length===0)return[];V.archiveMany(t,o.map(a=>({entityType:"paused_task",entityId:a.id,entityData:a,summary:a.description,reason:"staleness"}))),await this.update(t,a=>({...a,pausedTasks:i,previousTask:null,lastUpdated:f()}));for(let a of o)await this.publishEvent(t,"task.archived",{taskId:a.id,description:a.description,pausedAt:a.pausedAt,reason:"staleness"});return o}async clearTask(t){await this.update(t,()=>({currentTask:null,previousTask:null,pausedTasks:[],activeTasks:[],lastUpdated:f()}))}async hasTask(t){let e=await this.read(t),r=this.getPausedTasksFromState(e);return e.currentTask!==null||r.length>0}async getPausedTask(t){let e=await this.read(t);return this.getPausedTasksFromState(e)[0]||null}async getAllPausedTasks(t){let e=await this.read(t);return this.getPausedTasksFromState(e)}async getTaskHistory(t){let e=await this.read(t);return this.getTaskHistoryFromState(e)}async getMostRecentTask(t){let e=await this.read(t);return this.getTaskHistoryFromState(e)[0]||null}async getTaskHistoryByType(t,e){let r=await this.read(t);return this.getTaskHistoryFromState(r).filter(o=>o.classification===e)}async getAggregatedFeedback(t){let r=(await this.getTaskHistory(t)).filter(g=>g.feedback),s=[],o=[],i=[],a=[];for(let g of r){let h=g.feedback;Array.isArray(h.stackConfirmed)&&s.push(...h.stackConfirmed),Array.isArray(h.patternsDiscovered)&&o.push(...h.patternsDiscovered),Array.isArray(h.agentAccuracy)&&i.push(...h.agentAccuracy),Array.isArray(h.issuesEncountered)&&a.push(...h.issuesEncountered)}let u=[...new Set(s)],p=[...new Set(o)],m=new Map;for(let g of a)m.set(g,(m.get(g)||0)+1);let d=[...m.entries()].filter(([g,h])=>h>=2).map(([g])=>g);return{stackConfirmed:u,patternsDiscovered:p,agentAccuracy:i,issuesEncountered:[...new Set(a)],knownGotchas:d}}async startTaskInWorkspace(t,e,r){let s={...e,workspaceId:r,startedAt:f()};return await this.update(t,o=>({...o,activeTasks:[...o.activeTasks||[],s],lastUpdated:f()})),await this.publishEvent(t,"task.started",{taskId:s.id,description:s.description,startedAt:s.startedAt,sessionId:s.sessionId,workspaceId:r}),s}async getCurrentTaskForWorkspace(t,e){return((await this.read(t)).activeTasks||[]).find(s=>s.workspaceId===e)??null}async completeTaskInWorkspace(t,e,r){let s=await this.read(t),i=(s.activeTasks||[]).find(d=>d.workspaceId===e);if(!i)return null;let a=f(),u=this.createTaskHistoryEntry(i,a,r),p=this.getTaskHistoryFromState(s),m=[u,...p].slice(0,this.maxTaskHistory);return await this.update(t,d=>({...d,activeTasks:(d.activeTasks||[]).filter(g=>g.workspaceId!==e),taskHistory:m,lastUpdated:a})),await this.publishEvent(t,"task.completed",{taskId:i.id,description:i.description,startedAt:i.startedAt,completedAt:a,workspaceId:e}),i}async getActiveTasks(t){return(await this.read(t)).activeTasks||[]}async getActiveTaskCount(t){return((await this.read(t)).activeTasks||[]).length}async updateWorkspaceTask(t,e,r){let o=(await this.read(t)).activeTasks||[],i=o.findIndex(u=>u.workspaceId===e);if(i===-1)return null;let a={...o[i],...r,workspaceId:e};return await this.update(t,u=>{let p=[...u.activeTasks||[]];return p[i]=a,{...u,activeTasks:p,lastUpdated:f()}}),a}async addTokens(t,e,r){let s=await this.read(t);if(!s.currentTask)return null;let o=(s.currentTask.tokensIn||0)+e,i=(s.currentTask.tokensOut||0)+r;return await this.update(t,a=>({...a,currentTask:{...a.currentTask,tokensIn:o,tokensOut:i},lastUpdated:f()})),{tokensIn:o,tokensOut:i}}async createSubtasks(t,e){let r=await this.read(t);if(!r.currentTask)return;let s=e.map((o,i)=>({...o,status:i===0?"in_progress":"pending",startedAt:i===0?f():void 0,dependsOn:o.dependsOn||[]}));await this.update(t,o=>({...o,currentTask:{...o.currentTask,subtasks:s,currentSubtaskIndex:0,subtaskProgress:{completed:0,total:s.length,percentage:0}},lastUpdated:f()})),await this.publishEvent(t,"subtasks.created",{taskId:r.currentTask.id,subtaskCount:s.length,subtasks:s.map(o=>({id:o.id,description:o.description,domain:o.domain}))})}async completeSubtask(t,e){let r=mr.safeParse(e);if(!r.success){let j=r.error.issues.map(it=>`${it.path.join(".")}: ${it.message}`);throw new Error(`Subtask completion requires handoff data:
501
+ `)}]}})),t.tool("prjct_related_context","Combined: import neighbors + co-change partners for seed files",{projectPath:A.string().describe("Project directory path"),seedFiles:A.array(A.string()).describe("Seed files to find related context for"),maxResults:A.number().optional().default(15).describe("Max results (default 15)")},S("prjct_related_context",async e=>{let r=await P(e.projectPath),s=rt(r),o=s?Je(e.seedFiles,s):[],i=Xt(r),a=i?Ut(e.seedFiles,i):[],u=new Map;for(let d of o)u.set(d.path,{importScore:d.score,cochangeScore:0});for(let d of a){let g=u.get(d.path);g?g.cochangeScore=d.score:u.set(d.path,{importScore:0,cochangeScore:d.score})}let p=Array.from(u.entries()).map(([d,g])=>({path:d,combined:g.importScore*.6+g.cochangeScore*.4,importScore:g.importScore,cochangeScore:g.cochangeScore})).sort((d,g)=>g.combined-d.combined).slice(0,e.maxResults);if(p.length===0)return{content:[{type:"text",text:"No related files found. Run `prjct sync` to build indexes."}]};let m=["## Related Context",`Seeds: ${e.seedFiles.join(", ")}`,""];for(let d of p){let g=[];d.importScore>0&&g.push(`import: ${d.importScore.toFixed(2)}`),d.cochangeScore>0&&g.push(`cochange: ${Math.round(d.cochangeScore*100)}%`),m.push(`- ${d.path} (${g.join(", ")})`)}return{content:[{type:"text",text:m.join(`
502
+ `)}]}}))}c(pr,"registerCodeIntelTools");import{z as H}from"zod";import qs from"node:crypto";import{homedir as zs}from"node:os";import{join as Ys}from"node:path";function $(){return qs.randomUUID()}c($,"generateUUID");var na=Ys(zs(),".prjct-cli","projects");At();import{z as l}from"zod";var Js=l.enum(["low","medium","high","critical"]),Et=l.enum(["feature","bug","improvement","chore"]),Vs=l.enum(["active","backlog","previously_active"]),Ks=l.enum(["pending","in_progress","completed","blocked","paused","failed","skipped"]),Qs=l.enum(["task_completed","feature_shipped","idea_captured","session_started"]),Jt=l.object({title:l.string(),description:l.string(),filesChanged:l.array(l.object({path:l.string(),action:l.enum(["created","modified","deleted"])})),whatWasDone:l.array(l.string()).min(1),outputForNextAgent:l.string().min(1),notes:l.string().optional()}),mr=l.object({output:l.string().min(1,"Subtask output is required"),summary:Jt}),gr=l.object({id:l.string(),description:l.string(),domain:l.string(),agent:l.string(),status:Ks,dependsOn:l.array(l.string()),startedAt:l.string().optional(),completedAt:l.string().optional(),output:l.string().optional(),summary:Jt.optional(),skipReason:l.string().optional(),blockReason:l.string().optional(),estimatedPoints:l.number().optional(),estimatedMinutes:l.number().optional()}),fr=l.object({completed:l.number(),total:l.number(),percentage:l.number()}),Vt=l.object({id:l.string(),description:l.string(),type:Et.optional(),startedAt:l.string(),sessionId:l.string(),featureId:l.string().optional(),subtasks:l.array(gr).optional(),currentSubtaskIndex:l.number().optional(),subtaskProgress:fr.optional(),linearId:l.string().optional(),linearUuid:l.string().optional(),estimatedPoints:l.number().optional(),estimatedMinutes:l.number().optional(),modelMetadata:lt.optional(),tokensIn:l.number().optional(),tokensOut:l.number().optional(),parentDescription:l.string().optional(),branch:l.string().optional(),prUrl:l.string().optional()}),dr=l.object({id:l.string(),description:l.string(),status:l.literal("paused"),startedAt:l.string(),pausedAt:l.string(),pauseReason:l.string().optional(),type:Et.optional(),sessionId:l.string().optional(),featureId:l.string().optional(),subtasks:l.array(gr).optional(),currentSubtaskIndex:l.number().optional(),subtaskProgress:fr.optional(),linearId:l.string().optional(),linearUuid:l.string().optional(),estimatedPoints:l.number().optional(),estimatedMinutes:l.number().optional(),modelMetadata:lt.optional(),tokensIn:l.number().optional(),tokensOut:l.number().optional()}),Zs=l.object({stackConfirmed:l.array(l.string()).optional(),patternsDiscovered:l.array(l.string()).optional(),agentAccuracy:l.array(l.object({agent:l.string(),rating:l.enum(["helpful","neutral","inaccurate"]),note:l.string().optional()})).optional(),issuesEncountered:l.array(l.string()).optional()}),tn=l.object({taskId:l.string(),title:l.string(),classification:Et,startedAt:l.string(),completedAt:l.string(),subtaskCount:l.number(),subtaskSummaries:l.array(Jt),outcome:l.string(),branchName:l.string(),linearId:l.string().optional(),linearUuid:l.string().optional(),prUrl:l.string().optional(),feedback:Zs.optional(),tokensIn:l.number().optional(),tokensOut:l.number().optional()}),en=Vt.extend({workspaceId:l.string(),worktreePath:l.string().optional(),agentSessionId:l.string().optional(),jiraId:l.string().optional(),jiraUuid:l.string().optional(),dispatchedFrom:l.string().optional()}),hr=l.object({currentTask:Vt.nullable(),previousTask:dr.nullable().optional(),pausedTasks:l.array(dr).optional(),taskHistory:l.array(tn).optional(),activeTasks:l.array(en).optional(),lastUpdated:l.string()}),yr=l.object({id:l.string(),description:l.string(),body:l.string().optional(),priority:Js,type:Et,featureId:l.string().optional(),originFeature:l.string().optional(),completed:l.boolean(),completedAt:l.string().optional(),createdAt:l.string(),section:Vs,agent:l.string().optional(),groupName:l.string().optional(),groupId:l.string().optional()}),Tr=l.object({tasks:l.array(yr),lastUpdated:l.string()}),rn=l.object({tasksToday:l.number(),tasksThisWeek:l.number(),streak:l.number(),velocity:l.string(),avgDuration:l.string()}),sn=l.object({type:Qs,description:l.string(),timestamp:l.string(),duration:l.string().optional()}),ua=l.object({projectId:l.string(),currentTask:Vt.nullable(),queue:l.array(yr),stats:rn,recentActivity:l.array(sn),lastSync:l.string()});var nt={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"}},Kt=class{static{c(this,"WorkflowStateMachine")}getCurrentState(t,e){let r=null;if(e&&t?.activeTasks?.length&&(r=t.activeTasks.find(o=>o.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(nt[t].transitions.includes(e))return{valid:!0};let s=this.formatNextSteps(t).join(" | ");return{valid:!1,error:`Cannot transition to '${e}' from '${t}' state`,suggestion:`Valid next steps: ${s}`}}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 nt[t]}getPrompt(t){return nt[t].prompt}getValidCommands(t){return nt[t].transitions}formatNextSteps(t){return nt[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}`}})}},Qt=new Kt;var ot={SHIPPED_RETENTION_DAYS:90,IDEA_DORMANT_DAYS:180,QUEUE_COMPLETED_DAYS:7,PAUSED_TASK_DAYS:30,MEMORY_MAX_ENTRIES:500},Zt=class{static{c(this,"ArchiveStorage")}archive(t,e){let r=$(),s=f();return T.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,s,e.reason),r}archiveMany(t,e){if(e.length===0)return 0;let r=f();return T.transaction(t,s=>{let o=s.prepare("INSERT INTO archives (id, entity_type, entity_id, entity_data, summary, archived_at, reason) VALUES (?, ?, ?, ?, ?, ?, ?)");for(let i of e)o.run($(),i.entityType,i.entityId,JSON.stringify(i.entityData),i.summary??null,r,i.reason)}),e.length}getArchived(t,e,r=50){return e?T.query(t,"SELECT * FROM archives WHERE entity_type = ? ORDER BY archived_at DESC LIMIT ?",e,r):T.query(t,"SELECT * FROM archives ORDER BY archived_at DESC LIMIT ?",r)}getStats(t){let e=T.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 s of e){let o=s.entity_type;o in r&&(r[o]=s.count),r.total+=s.count}return r}restore(t,e){let r=T.get(t,"SELECT * FROM archives WHERE id = ?",e);return r?(T.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(),s=this.getTotalCount(t);T.run(t,"DELETE FROM archives WHERE archived_at < ?",r);let o=this.getTotalCount(t);return s-o}getTotalCount(t){return T.get(t,"SELECT COUNT(*) as count FROM archives")?.count??0}},K=new Zt;U();var te=class{static{c(this,"SyncEventBus")}async publish(t){let e=b.getSyncPendingPath(t.projectId),r=await ut(e,[])??[],s=Array.isArray(r)?r:[];s.push(t),await M(e,s)}async getPending(t){let e=b.getSyncPendingPath(t),r=await ut(e,[])??[];return Array.isArray(r)?r:[]}async clearPending(t){let e=b.getSyncPendingPath(t);await M(e,[])}async updateLastSync(t){let e=b.getLastSyncPath(t),r={timestamp:f(),success:!0};await M(e,r)}async getLastSync(t){let e=b.getLastSyncPath(t);return await ut(e,null)}},Er=new te;Nt();var Q=class{static{c(this,"StorageManager")}filename;cache;constructor(t,e){this.filename=t,this.cache=new pt({ttl:5e3,maxSize:50})}getStoreKey(){return this.filename.replace(".json","")}async read(t){let e=this.cache.get(t);if(e!==null)return e;try{let r=T.getDoc(t,this.getStoreKey());if(r!==null)return this.cache.set(t,r),r}catch{}return this.getDefault()}async write(t,e){T.setDoc(t,this.getStoreKey(),e),this.cache.set(t,e)}async update(t,e){let r=await this.read(t),s=e(r);return await this.write(t,s),s}async publishEvent(t,e,r){let s={type:e,path:[this.filename.replace(".json","")],data:r,timestamp:f(),projectId:t};await Er.publish(s)}async publishEntityEvent(t,e,r,s){let o=`${e}.${r}`,i={...s,timestamp:f()};await this.publishEvent(t,o,i)}async exists(t){try{return T.hasDoc(t,this.getStoreKey())}catch{return!1}}clearCache(t){t?this.cache.delete(t):this.cache.clear()}getCacheStats(){return this.cache.stats()}};var ee=class extends Q{static{c(this,"StateStorage")}constructor(){super("state.json",hr)}getDefault(){return{currentTask:null,previousTask:null,pausedTasks:[],taskHistory:[],activeTasks:[],lastUpdated:""}}getEventType(t){return`state.${t}d`}validateTransition(t,e){let r=Qt.getCurrentState(t),s=Qt.canTransition(r,e);if(!s.valid)throw new Error(`${s.error}. ${s.suggestion||""}`.trim())}async getCurrentTask(t){return(await this.read(t)).currentTask}async startTask(t,e){let r=await this.read(t);this.validateTransition(r,"task");let s={...e,startedAt:f()};return await this.update(t,o=>({...o,currentTask:s,lastUpdated:f()})),await this.publishEvent(t,"task.started",{taskId:s.id,description:s.description,startedAt:s.startedAt,sessionId:s.sessionId}),s}async updateCurrentTask(t,e){let r=await this.read(t);if(!r.currentTask)return null;let s={...r.currentTask,...e};return await this.update(t,o=>({...o,currentTask:s,lastUpdated:f()})),s}async completeTask(t,e){let r=await this.read(t),s=r.currentTask;if(!s)return null;this.validateTransition(r,"done");let o=f(),i=this.createTaskHistoryEntry(s,o,e),a=this.getTaskHistoryFromState(r),u=[i,...a].slice(0,this.maxTaskHistory);return await this.update(t,p=>({...p,currentTask:null,previousTask:null,taskHistory:u,lastUpdated:o})),await this.publishEvent(t,"task.completed",{taskId:s.id,description:s.description,startedAt:s.startedAt,completedAt:o}),s}createTaskHistoryEntry(t,e,r){let s=(t.subtasks||[]).filter(a=>a.status==="completed"&&a.summary).map(a=>a.summary),o=s.length>0?s.map(a=>a.title).join(", "):"Task completed",i={taskId:t.id,title:t.parentDescription||t.description,classification:t.type||"improvement",startedAt:t.startedAt,completedAt:e,subtaskCount:t.subtasks?.length||0,subtaskSummaries:s,outcome:o,branchName:t.branch||"unknown",linearId:t.linearId,linearUuid:t.linearUuid,prUrl:t.prUrl};return r&&(i.feedback=r),t.tokensIn&&(i.tokensIn=t.tokensIn),t.tokensOut&&(i.tokensOut=t.tokensOut),i}maxPausedTasks=5;maxTaskHistory=20;stalenessThresholdDays=30;async pauseTask(t,e){let r=await this.read(t);if(!r.currentTask)return null;this.validateTransition(r,"pause");let s={...r.currentTask,status:"paused",pausedAt:f(),pauseReason:e},o=this.getPausedTasksFromState(r),i=[s,...o].slice(0,this.maxPausedTasks);return await this.update(t,a=>({...a,currentTask:null,previousTask:null,pausedTasks:i,lastUpdated:f()})),await this.publishEvent(t,"task.paused",{taskId:s.id,description:s.description,pausedAt:s.pausedAt,reason:e,pausedCount:i.length}),s}async resumeTask(t,e){let r=await this.read(t),s=this.getPausedTasksFromState(r);if(s.length===0)return null;this.validateTransition(r,"resume");let o=0;if(e&&(o=s.findIndex(y=>y.id===e),o===-1))return null;let i=s[o],a=s.filter((y,j)=>j!==o),{status:u,pausedAt:p,pauseReason:m,...d}=i,g={...d,startedAt:f(),sessionId:i.sessionId??$()};return await this.update(t,y=>({...y,currentTask:g,previousTask:null,pausedTasks:a,lastUpdated:f()})),await this.publishEvent(t,"task.resumed",{taskId:g.id,description:g.description,resumedAt:g.startedAt,remainingPaused:a.length}),g}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){let e=await this.read(t),r=this.getPausedTasksFromState(e),s=Date.now()-this.stalenessThresholdDays*24*60*60*1e3;return r.filter(o=>new Date(o.pausedAt).getTime()<s)}async archiveStalePausedTasks(t){let e=await this.read(t),r=this.getPausedTasksFromState(e),s=Date.now()-this.stalenessThresholdDays*24*60*60*1e3,o=r.filter(a=>new Date(a.pausedAt).getTime()<s),i=r.filter(a=>new Date(a.pausedAt).getTime()>=s);if(o.length===0)return[];K.archiveMany(t,o.map(a=>({entityType:"paused_task",entityId:a.id,entityData:a,summary:a.description,reason:"staleness"}))),await this.update(t,a=>({...a,pausedTasks:i,previousTask:null,lastUpdated:f()}));for(let a of o)await this.publishEvent(t,"task.archived",{taskId:a.id,description:a.description,pausedAt:a.pausedAt,reason:"staleness"});return o}async clearTask(t){await this.update(t,()=>({currentTask:null,previousTask:null,pausedTasks:[],activeTasks:[],lastUpdated:f()}))}async hasTask(t){let e=await this.read(t),r=this.getPausedTasksFromState(e);return e.currentTask!==null||r.length>0}async getPausedTask(t){let e=await this.read(t);return this.getPausedTasksFromState(e)[0]||null}async getAllPausedTasks(t){let e=await this.read(t);return this.getPausedTasksFromState(e)}async getTaskHistory(t){let e=await this.read(t);return this.getTaskHistoryFromState(e)}async getMostRecentTask(t){let e=await this.read(t);return this.getTaskHistoryFromState(e)[0]||null}async getTaskHistoryByType(t,e){let r=await this.read(t);return this.getTaskHistoryFromState(r).filter(o=>o.classification===e)}async getAggregatedFeedback(t){let r=(await this.getTaskHistory(t)).filter(g=>g.feedback),s=[],o=[],i=[],a=[];for(let g of r){let y=g.feedback;Array.isArray(y.stackConfirmed)&&s.push(...y.stackConfirmed),Array.isArray(y.patternsDiscovered)&&o.push(...y.patternsDiscovered),Array.isArray(y.agentAccuracy)&&i.push(...y.agentAccuracy),Array.isArray(y.issuesEncountered)&&a.push(...y.issuesEncountered)}let u=[...new Set(s)],p=[...new Set(o)],m=new Map;for(let g of a)m.set(g,(m.get(g)||0)+1);let d=[...m.entries()].filter(([g,y])=>y>=2).map(([g])=>g);return{stackConfirmed:u,patternsDiscovered:p,agentAccuracy:i,issuesEncountered:[...new Set(a)],knownGotchas:d}}async startTaskInWorkspace(t,e,r){let s={...e,workspaceId:r,startedAt:f()};return await this.update(t,o=>({...o,activeTasks:[...o.activeTasks||[],s],lastUpdated:f()})),await this.publishEvent(t,"task.started",{taskId:s.id,description:s.description,startedAt:s.startedAt,sessionId:s.sessionId,workspaceId:r}),s}async getCurrentTaskForWorkspace(t,e){return((await this.read(t)).activeTasks||[]).find(s=>s.workspaceId===e)??null}async completeTaskInWorkspace(t,e,r){let s=await this.read(t),i=(s.activeTasks||[]).find(d=>d.workspaceId===e);if(!i)return null;let a=f(),u=this.createTaskHistoryEntry(i,a,r),p=this.getTaskHistoryFromState(s),m=[u,...p].slice(0,this.maxTaskHistory);return await this.update(t,d=>({...d,activeTasks:(d.activeTasks||[]).filter(g=>g.workspaceId!==e),taskHistory:m,lastUpdated:a})),await this.publishEvent(t,"task.completed",{taskId:i.id,description:i.description,startedAt:i.startedAt,completedAt:a,workspaceId:e}),i}async getActiveTasks(t){return(await this.read(t)).activeTasks||[]}async getActiveTaskCount(t){return((await this.read(t)).activeTasks||[]).length}async updateWorkspaceTask(t,e,r){let o=(await this.read(t)).activeTasks||[],i=o.findIndex(u=>u.workspaceId===e);if(i===-1)return null;let a={...o[i],...r,workspaceId:e};return await this.update(t,u=>{let p=[...u.activeTasks||[]];return p[i]=a,{...u,activeTasks:p,lastUpdated:f()}}),a}async addTokens(t,e,r){let s=await this.read(t);if(!s.currentTask)return null;let o=(s.currentTask.tokensIn||0)+e,i=(s.currentTask.tokensOut||0)+r;return await this.update(t,a=>({...a,currentTask:{...a.currentTask,tokensIn:o,tokensOut:i},lastUpdated:f()})),{tokensIn:o,tokensOut:i}}async createSubtasks(t,e){let r=await this.read(t);if(!r.currentTask)return;let s=e.map((o,i)=>({...o,status:i===0?"in_progress":"pending",startedAt:i===0?f():void 0,dependsOn:o.dependsOn||[]}));await this.update(t,o=>({...o,currentTask:{...o.currentTask,subtasks:s,currentSubtaskIndex:0,subtaskProgress:{completed:0,total:s.length,percentage:0}},lastUpdated:f()})),await this.publishEvent(t,"subtasks.created",{taskId:r.currentTask.id,subtaskCount:s.length,subtasks:s.map(o=>({id:o.id,description:o.description,domain:o.domain}))})}async completeSubtask(t,e){let r=mr.safeParse(e);if(!r.success){let j=r.error.issues.map(at=>`${at.path.join(".")}: ${at.message}`);throw new Error(`Subtask completion requires handoff data:
503
503
  ${j.join(`
504
- `)}`)}let{output:s,summary:o}=r.data,i=await this.read(t);if(!i.currentTask?.subtasks)return null;let a=i.currentTask.currentSubtaskIndex||0,u=i.currentTask.subtasks[a];if(!u)return null;let p=[...i.currentTask.subtasks];p[a]={...u,status:"completed",completedAt:f(),output:s,summary:o};let m=p.filter(j=>j.status==="completed").length,d=p.length,g=Math.round(m/d*100),h=a+1;return h<p.length&&(p[h]={...p[h],status:"in_progress",startedAt:f()}),await this.update(t,j=>({...j,currentTask:{...j.currentTask,subtasks:p,currentSubtaskIndex:h<d?h:a,subtaskProgress:{completed:m,total:d,percentage:g}},lastUpdated:f()})),await this.publishEvent(t,"subtask.completed",{taskId:i.currentTask.id,subtaskId:u.id,description:u.description,output:s,handoff:o.outputForNextAgent,filesChanged:o.filesChanged.length,progress:{completed:m,total:d,percentage:g}}),h<d?p[h]:null}async getCurrentSubtask(t){let e=await this.read(t);if(!e.currentTask?.subtasks)return null;let r=e.currentTask.currentSubtaskIndex||0;return e.currentTask.subtasks[r]||null}async getNextSubtask(t){let e=await this.read(t);if(!e.currentTask?.subtasks)return null;let r=(e.currentTask.currentSubtaskIndex||0)+1;return e.currentTask.subtasks[r]||null}async getPreviousSubtask(t){let e=await this.read(t);if(!e.currentTask?.subtasks)return null;let r=(e.currentTask.currentSubtaskIndex||0)-1;return r<0?null:e.currentTask.subtasks[r]||null}async getPreviousHandoff(t){let e=await this.getPreviousSubtask(t);return e?.summary?.outputForNextAgent?{fromSubtask:e.description,outputForNextAgent:e.summary.outputForNextAgent,filesChanged:e.summary.filesChanged,whatWasDone:e.summary.whatWasDone}:null}async getSubtasks(t){return(await this.read(t)).currentTask?.subtasks||[]}async getSubtaskProgress(t){return(await this.read(t)).currentTask?.subtaskProgress||null}async hasSubtasks(t){return((await this.read(t)).currentTask?.subtasks?.length||0)>0}async areAllSubtasksComplete(t){let e=await this.read(t);return e.currentTask?.subtasks?e.currentTask.subtasks.every(r=>r.status==="completed"||r.status==="failed"||r.status==="skipped"):!0}async failSubtask(t,e){let r=await this.read(t);if(!r.currentTask?.subtasks)return null;let s=r.currentTask.currentSubtaskIndex||0,o=r.currentTask.subtasks[s];if(!o)return null;let i=[...r.currentTask.subtasks];i[s]={...o,status:"failed",completedAt:f(),output:`Failed: ${e}`};let a=s+1,u=i.length;a<u&&(i[a]={...i[a],status:"in_progress",startedAt:f()});let p=i.filter(d=>d.status==="completed"||d.status==="failed"||d.status==="skipped").length,m=Math.round(p/u*100);return await this.update(t,d=>({...d,currentTask:{...d.currentTask,subtasks:i,currentSubtaskIndex:a<u?a:s,subtaskProgress:{completed:p,total:u,percentage:m}},lastUpdated:f()})),await this.publishEvent(t,"subtask.failed",{taskId:r.currentTask.id,subtaskId:o.id,description:o.description,error:e}),a<u?i[a]:null}async skipSubtask(t,e){let r=await this.read(t);if(!r.currentTask?.subtasks)return null;let s=r.currentTask.currentSubtaskIndex||0,o=r.currentTask.subtasks[s];if(!o)return null;let i=[...r.currentTask.subtasks];i[s]={...o,status:"skipped",completedAt:f(),output:`Skipped: ${e}`,skipReason:e};let a=s+1,u=i.length;a<u&&(i[a]={...i[a],status:"in_progress",startedAt:f()});let p=i.filter(d=>d.status==="completed"||d.status==="failed"||d.status==="skipped").length,m=Math.round(p/u*100);return await this.update(t,d=>({...d,currentTask:{...d.currentTask,subtasks:i,currentSubtaskIndex:a<u?a:s,subtaskProgress:{completed:p,total:u,percentage:m}},lastUpdated:f()})),await this.publishEvent(t,"subtask.skipped",{taskId:r.currentTask.id,subtaskId:o.id,description:o.description,reason:e}),a<u?i[a]:null}async blockSubtask(t,e){let r=await this.read(t);if(!r.currentTask?.subtasks)return null;let s=r.currentTask.currentSubtaskIndex||0,o=r.currentTask.subtasks[s];if(!o)return null;let i=[...r.currentTask.subtasks];i[s]={...o,status:"blocked",output:`Blocked: ${e}`,blockReason:e};let a=s+1,u=i.length;return a<u&&(i[a]={...i[a],status:"in_progress",startedAt:f()}),await this.update(t,p=>({...p,currentTask:{...p.currentTask,subtasks:i,currentSubtaskIndex:a<u?a:s},lastUpdated:f()})),await this.publishEvent(t,"subtask.blocked",{taskId:r.currentTask.id,subtaskId:o.id,description:o.description,blocker:e}),a<u?i[a]:null}},Q=new ee;W();z();import nn from"node:fs/promises";import Et from"node:path";var on={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"]},an=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".py",".go",".rs",".java",".kt",".swift",".rb",".php",".c",".cpp",".h",".hpp",".cs",".vue",".svelte"]),cn=new Set(["node_modules",".git","dist","build",".next",".nuxt",".output","coverage",".cache","__pycache__",".pytest_cache","vendor","target",".turbo",".vercel"]);async function kr(n,t,e={}){let r=Date.now(),s=e.maxFiles??30,o=e.minScore??.1,i=e.includeTests??!1,a=un(n),u=await ln(t),p=await pn(t),m=[];for(let g of u){if(!i&&mn(g))continue;let h=dn(g,a,p,e.historicalBoosts);h.score>=o&&m.push(h)}m.sort((g,h)=>h.score-g.score);let d=m.slice(0,s);return{files:d,metrics:{filesScanned:u.length,filesReturned:d.length,scanDuration:Date.now()-r}}}c(kr,"findRelevantFiles");function un(n){let t=n.toLowerCase().split(/[^a-z0-9]+/).filter(Boolean),e=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"]);return t.filter(r=>!e.has(r)&&r.length>2)}c(un,"extractKeywords");async function ln(n){let t=[];async function e(r,s=""){try{let o=await nn.readdir(r,{withFileTypes:!0});for(let i of o){let a=Et.join(r,i.name),u=Et.join(s,i.name);if(i.isDirectory()){if(cn.has(i.name)||i.name.startsWith("."))continue;await e(a,u)}else if(i.isFile()){let p=Et.extname(i.name).toLowerCase();an.has(p)&&t.push(u)}}}catch(o){N(o)}}return c(e,"walk"),await e(n),t}c(ln,"getAllCodeFiles");async function pn(n){let t=new Map;try{let{stdout:e}=await k(`git log -30 --pretty=format:"%H %ct" --name-only | awk '
504
+ `)}`)}let{output:s,summary:o}=r.data,i=await this.read(t);if(!i.currentTask?.subtasks)return null;let a=i.currentTask.currentSubtaskIndex||0,u=i.currentTask.subtasks[a];if(!u)return null;let p=[...i.currentTask.subtasks];p[a]={...u,status:"completed",completedAt:f(),output:s,summary:o};let m=p.filter(j=>j.status==="completed").length,d=p.length,g=Math.round(m/d*100),y=a+1;return y<p.length&&(p[y]={...p[y],status:"in_progress",startedAt:f()}),await this.update(t,j=>({...j,currentTask:{...j.currentTask,subtasks:p,currentSubtaskIndex:y<d?y:a,subtaskProgress:{completed:m,total:d,percentage:g}},lastUpdated:f()})),await this.publishEvent(t,"subtask.completed",{taskId:i.currentTask.id,subtaskId:u.id,description:u.description,output:s,handoff:o.outputForNextAgent,filesChanged:o.filesChanged.length,progress:{completed:m,total:d,percentage:g}}),y<d?p[y]:null}async getCurrentSubtask(t){let e=await this.read(t);if(!e.currentTask?.subtasks)return null;let r=e.currentTask.currentSubtaskIndex||0;return e.currentTask.subtasks[r]||null}async getNextSubtask(t){let e=await this.read(t);if(!e.currentTask?.subtasks)return null;let r=(e.currentTask.currentSubtaskIndex||0)+1;return e.currentTask.subtasks[r]||null}async getPreviousSubtask(t){let e=await this.read(t);if(!e.currentTask?.subtasks)return null;let r=(e.currentTask.currentSubtaskIndex||0)-1;return r<0?null:e.currentTask.subtasks[r]||null}async getPreviousHandoff(t){let e=await this.getPreviousSubtask(t);return e?.summary?.outputForNextAgent?{fromSubtask:e.description,outputForNextAgent:e.summary.outputForNextAgent,filesChanged:e.summary.filesChanged,whatWasDone:e.summary.whatWasDone}:null}async getSubtasks(t){return(await this.read(t)).currentTask?.subtasks||[]}async getSubtaskProgress(t){return(await this.read(t)).currentTask?.subtaskProgress||null}async hasSubtasks(t){return((await this.read(t)).currentTask?.subtasks?.length||0)>0}async areAllSubtasksComplete(t){let e=await this.read(t);return e.currentTask?.subtasks?e.currentTask.subtasks.every(r=>r.status==="completed"||r.status==="failed"||r.status==="skipped"):!0}async failSubtask(t,e){let r=await this.read(t);if(!r.currentTask?.subtasks)return null;let s=r.currentTask.currentSubtaskIndex||0,o=r.currentTask.subtasks[s];if(!o)return null;let i=[...r.currentTask.subtasks];i[s]={...o,status:"failed",completedAt:f(),output:`Failed: ${e}`};let a=s+1,u=i.length;a<u&&(i[a]={...i[a],status:"in_progress",startedAt:f()});let p=i.filter(d=>d.status==="completed"||d.status==="failed"||d.status==="skipped").length,m=Math.round(p/u*100);return await this.update(t,d=>({...d,currentTask:{...d.currentTask,subtasks:i,currentSubtaskIndex:a<u?a:s,subtaskProgress:{completed:p,total:u,percentage:m}},lastUpdated:f()})),await this.publishEvent(t,"subtask.failed",{taskId:r.currentTask.id,subtaskId:o.id,description:o.description,error:e}),a<u?i[a]:null}async skipSubtask(t,e){let r=await this.read(t);if(!r.currentTask?.subtasks)return null;let s=r.currentTask.currentSubtaskIndex||0,o=r.currentTask.subtasks[s];if(!o)return null;let i=[...r.currentTask.subtasks];i[s]={...o,status:"skipped",completedAt:f(),output:`Skipped: ${e}`,skipReason:e};let a=s+1,u=i.length;a<u&&(i[a]={...i[a],status:"in_progress",startedAt:f()});let p=i.filter(d=>d.status==="completed"||d.status==="failed"||d.status==="skipped").length,m=Math.round(p/u*100);return await this.update(t,d=>({...d,currentTask:{...d.currentTask,subtasks:i,currentSubtaskIndex:a<u?a:s,subtaskProgress:{completed:p,total:u,percentage:m}},lastUpdated:f()})),await this.publishEvent(t,"subtask.skipped",{taskId:r.currentTask.id,subtaskId:o.id,description:o.description,reason:e}),a<u?i[a]:null}async blockSubtask(t,e){let r=await this.read(t);if(!r.currentTask?.subtasks)return null;let s=r.currentTask.currentSubtaskIndex||0,o=r.currentTask.subtasks[s];if(!o)return null;let i=[...r.currentTask.subtasks];i[s]={...o,status:"blocked",output:`Blocked: ${e}`,blockReason:e};let a=s+1,u=i.length;return a<u&&(i[a]={...i[a],status:"in_progress",startedAt:f()}),await this.update(t,p=>({...p,currentTask:{...p.currentTask,subtasks:i,currentSubtaskIndex:a<u?a:s},lastUpdated:f()})),await this.publishEvent(t,"subtask.blocked",{taskId:r.currentTask.id,subtaskId:o.id,description:o.description,blocker:e}),a<u?i[a]:null}},Z=new ee;W();z();import nn from"node:fs/promises";import kt from"node:path";var on={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"]},an=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".py",".go",".rs",".java",".kt",".swift",".rb",".php",".c",".cpp",".h",".hpp",".cs",".vue",".svelte"]),cn=new Set(["node_modules",".git","dist","build",".next",".nuxt",".output","coverage",".cache","__pycache__",".pytest_cache","vendor","target",".turbo",".vercel"]);async function kr(n,t,e={}){let r=Date.now(),s=e.maxFiles??30,o=e.minScore??.1,i=e.includeTests??!1,a=un(n),u=await ln(t),p=await pn(t),m=[];for(let g of u){if(!i&&mn(g))continue;let y=dn(g,a,p,e.historicalBoosts);y.score>=o&&m.push(y)}m.sort((g,y)=>y.score-g.score);let d=m.slice(0,s);return{files:d,metrics:{filesScanned:u.length,filesReturned:d.length,scanDuration:Date.now()-r}}}c(kr,"findRelevantFiles");function un(n){let t=n.toLowerCase().split(/[^a-z0-9]+/).filter(Boolean),e=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"]);return t.filter(r=>!e.has(r)&&r.length>2)}c(un,"extractKeywords");async function ln(n){let t=[];async function e(r,s=""){try{let o=await nn.readdir(r,{withFileTypes:!0});for(let i of o){let a=kt.join(r,i.name),u=kt.join(s,i.name);if(i.isDirectory()){if(cn.has(i.name)||i.name.startsWith("."))continue;await e(a,u)}else if(i.isFile()){let p=kt.extname(i.name).toLowerCase();an.has(p)&&t.push(u)}}}catch(o){N(o)}}return c(e,"walk"),await e(n),t}c(ln,"getAllCodeFiles");async function pn(n){let t=new Map;try{let{stdout:e}=await k(`git log -30 --pretty=format:"%H %ct" --name-only | awk '
505
505
  /^[a-f0-9]{40}/ { commit=$1; timestamp=$2; next }
506
506
  NF { files[$0]++; if (!lastmod[$0]) lastmod[$0]=timestamp }
507
507
  END { for (f in files) print files[f], lastmod[f], f }
508
508
  '`,{cwd:n,maxBuffer:10485760}),r=Math.floor(Date.now()/1e3),s=e.trim().split(`
509
- `).filter(Boolean);for(let o of s){let i=o.match(/^(\d+)\s+(\d+)\s+(.+)$/);if(i){let a=parseInt(i[1],10),u=parseInt(i[2],10),p=i[3],m=Math.floor((r-u)/86400);t.set(p,{commits:a,daysAgo:m})}}}catch{}return t}c(pn,"getGitRecency");function dn(n,t,e,r){let s=[],o=0,i=0,a=0,u=0,p=0,m=n.toLowerCase(),d=m.split("/").join(" ").split(/[^a-z0-9]+/);for(let R of t){m.includes(R)&&(o+=.3,s.push(`keyword:${R}`));for(let tt of d)if(tt.includes(R)||R.includes(tt)){o+=.15;break}}o=Math.min(1,o);for(let[R,tt]of Object.entries(on))for(let Gr of tt)if(m.includes(Gr)&&t.some(St=>tt.includes(St)||St.includes(R)||R.includes(St))){i+=.4,s.push(`domain:${R}`);break}i=Math.min(1,i);let g=e.get(n);g&&(g.daysAgo<=1?(a=1,s.push("recent:1d")):g.daysAgo<=3?(a=.8,s.push("recent:3d")):g.daysAgo<=7?(a=.6,s.push("recent:1w")):g.daysAgo<=30&&(a=.3,s.push("recent:1m")),g.commits>=5&&(a=Math.min(1,a+.2)));let h=Et.basename(n).toLowerCase();if((h.includes("index")||h.includes("main")||h.includes("app")||h.includes("entry"))&&(u=.5,s.push("import:0")),(m.includes("/core/")||m.includes("/shared/")||m.includes("/lib/"))&&(u=Math.max(u,.3),s.some(R=>R.startsWith("import:"))||s.push("import:1")),r){let R=r.get(n);R!==void 0&&(p=(R+1)/2,R>0?s.push("history:boosted"):R<0&&s.push("history:penalized"))}let it=r&&r.size>0?o*.54+i*.18+a*.13+u*.05+p*.1:o*.6+i*.2+a*.15+u*.05;return{path:n,score:Math.min(1,it),reasons:[...new Set(s)]}}c(dn,"scoreFile");function mn(n){let t=n.toLowerCase();return t.includes(".test.")||t.includes(".spec.")||t.includes("__tests__")||t.includes("__mocks__")||t.includes("/tests/")||t.includes("/test/")||t.endsWith("_test.go")||t.endsWith("_test.py")}c(mn,"isTestFile");W();import Tn from"node:fs/promises";import Z from"node:path";var fn={"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}},hn="claude-sonnet-4.5";function re(n){return!n||n.length===0?0:Math.ceil(n.length/4)}c(re,"countTokens");var br=["claude-sonnet-4.5","claude-opus-4.5","claude-opus-4-6","gpt-4o","gemini-1.5-pro"];function wr(n,t){let e=fn[t],r=n/1e3*e.input,s=n/1e3*e.output*.3;return{inputSaved:r,outputPotential:s,total:r+s}}c(wr,"calculateModelCost");function yn(n){return n<.001?"<$0.01":n<.01?`$${n.toFixed(3)}`:`$${n.toFixed(2)}`}c(yn,"formatCostSaved");function Sr(n,t){let e=re(n),r=re(t),s=Math.max(0,e-r),o=e>0?(e-r)/e:0,i=wr(s,hn),a=br.map(u=>({model:u,...wr(s,u)}));return{tokens:{original:e,filtered:r,saved:s},compression:Math.max(0,Math.min(1,o)),cost:{saved:i.total,formatted:yn(i.total),byModel:a}}}c(Sr,"measureCompression");function kt(n){let t=re(n);return{tokens:{original:t,filtered:t,saved:0},compression:0,cost:{saved:0,formatted:"$0.00",byModel:br.map(e=>({model:e,inputSaved:0,outputPotential:0,total:0}))}}}c(kt,"noCompression");var En={".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"},xr=[{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}],kn=[{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}],wn=[{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}],bn=[{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}],vr=[{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}],Sn={typescript:xr,javascript:xr,python:kn,go:wn,rust:bn,java:vr,csharp:vr,php:[],ruby:[],unknown:[]};async function _r(n,t=process.cwd()){let e=Z.isAbsolute(n)?n:Z.join(t,n),r=Z.resolve(t),s=Z.resolve(e);if(!s.startsWith(r+Z.sep)&&s!==r)return{file:n,language:"unknown",signatures:[],fallback:!0,fallbackReason:"Path traversal denied: file is outside project directory",metrics:kt("")};let o;try{o=await Tn.readFile(e,"utf-8")}catch(d){if(N(d))return{file:n,language:"unknown",signatures:[],fallback:!0,fallbackReason:"File not found",metrics:kt("")};throw d}let i=Z.extname(n).toLowerCase(),a=En[i]||"unknown",u=Sn[a];if(!u||u.length===0)return{file:n,language:a,signatures:[],fallback:!0,fallbackReason:`No extraction patterns for ${a}`,metrics:kt(o)};let p=xn(o,u),m=p.map(d=>`${d.exported?"export ":""}${d.type} ${d.name}: ${d.signature}`).join(`
509
+ `).filter(Boolean);for(let o of s){let i=o.match(/^(\d+)\s+(\d+)\s+(.+)$/);if(i){let a=parseInt(i[1],10),u=parseInt(i[2],10),p=i[3],m=Math.floor((r-u)/86400);t.set(p,{commits:a,daysAgo:m})}}}catch{}return t}c(pn,"getGitRecency");function dn(n,t,e,r){let s=[],o=0,i=0,a=0,u=0,p=0,m=n.toLowerCase(),d=m.split("/").join(" ").split(/[^a-z0-9]+/);for(let R of t){m.includes(R)&&(o+=.3,s.push(`keyword:${R}`));for(let et of d)if(et.includes(R)||R.includes(et)){o+=.15;break}}o=Math.min(1,o);for(let[R,et]of Object.entries(on))for(let Gr of et)if(m.includes(Gr)&&t.some(xt=>et.includes(xt)||xt.includes(R)||R.includes(xt))){i+=.4,s.push(`domain:${R}`);break}i=Math.min(1,i);let g=e.get(n);g&&(g.daysAgo<=1?(a=1,s.push("recent:1d")):g.daysAgo<=3?(a=.8,s.push("recent:3d")):g.daysAgo<=7?(a=.6,s.push("recent:1w")):g.daysAgo<=30&&(a=.3,s.push("recent:1m")),g.commits>=5&&(a=Math.min(1,a+.2)));let y=kt.basename(n).toLowerCase();if((y.includes("index")||y.includes("main")||y.includes("app")||y.includes("entry"))&&(u=.5,s.push("import:0")),(m.includes("/core/")||m.includes("/shared/")||m.includes("/lib/"))&&(u=Math.max(u,.3),s.some(R=>R.startsWith("import:"))||s.push("import:1")),r){let R=r.get(n);R!==void 0&&(p=(R+1)/2,R>0?s.push("history:boosted"):R<0&&s.push("history:penalized"))}let at=r&&r.size>0?o*.54+i*.18+a*.13+u*.05+p*.1:o*.6+i*.2+a*.15+u*.05;return{path:n,score:Math.min(1,at),reasons:[...new Set(s)]}}c(dn,"scoreFile");function mn(n){let t=n.toLowerCase();return t.includes(".test.")||t.includes(".spec.")||t.includes("__tests__")||t.includes("__mocks__")||t.includes("/tests/")||t.includes("/test/")||t.endsWith("_test.go")||t.endsWith("_test.py")}c(mn,"isTestFile");W();import Tn from"node:fs/promises";import tt from"node:path";var fn={"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}},hn="claude-sonnet-4.5";function re(n){return!n||n.length===0?0:Math.ceil(n.length/4)}c(re,"countTokens");var br=["claude-sonnet-4.5","claude-opus-4.5","claude-opus-4-6","gpt-4o","gemini-1.5-pro"];function wr(n,t){let e=fn[t],r=n/1e3*e.input,s=n/1e3*e.output*.3;return{inputSaved:r,outputPotential:s,total:r+s}}c(wr,"calculateModelCost");function yn(n){return n<.001?"<$0.01":n<.01?`$${n.toFixed(3)}`:`$${n.toFixed(2)}`}c(yn,"formatCostSaved");function Sr(n,t){let e=re(n),r=re(t),s=Math.max(0,e-r),o=e>0?(e-r)/e:0,i=wr(s,hn),a=br.map(u=>({model:u,...wr(s,u)}));return{tokens:{original:e,filtered:r,saved:s},compression:Math.max(0,Math.min(1,o)),cost:{saved:i.total,formatted:yn(i.total),byModel:a}}}c(Sr,"measureCompression");function wt(n){let t=re(n);return{tokens:{original:t,filtered:t,saved:0},compression:0,cost:{saved:0,formatted:"$0.00",byModel:br.map(e=>({model:e,inputSaved:0,outputPotential:0,total:0}))}}}c(wt,"noCompression");var En={".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"},xr=[{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}],kn=[{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}],wn=[{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}],bn=[{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}],vr=[{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}],Sn={typescript:xr,javascript:xr,python:kn,go:wn,rust:bn,java:vr,csharp:vr,php:[],ruby:[],unknown:[]};async function _r(n,t=process.cwd()){let e=tt.isAbsolute(n)?n:tt.join(t,n),r=tt.resolve(t),s=tt.resolve(e);if(!s.startsWith(r+tt.sep)&&s!==r)return{file:n,language:"unknown",signatures:[],fallback:!0,fallbackReason:"Path traversal denied: file is outside project directory",metrics:wt("")};let o;try{o=await Tn.readFile(e,"utf-8")}catch(d){if(N(d))return{file:n,language:"unknown",signatures:[],fallback:!0,fallbackReason:"File not found",metrics:wt("")};throw d}let i=tt.extname(n).toLowerCase(),a=En[i]||"unknown",u=Sn[a];if(!u||u.length===0)return{file:n,language:a,signatures:[],fallback:!0,fallbackReason:`No extraction patterns for ${a}`,metrics:wt(o)};let p=xn(o,u),m=p.map(d=>`${d.exported?"export ":""}${d.type} ${d.name}: ${d.signature}`).join(`
510
510
  `);return{file:n,language:a,signatures:p,fallback:!1,metrics:Sr(o,m)}}c(_r,"extractSignatures");function xn(n,t){let e=[],r=n.split(`
511
511
  `),s=new Set;for(let o of t){o.pattern.lastIndex=0;let i;for(;(i=o.pattern.exec(n))!==null;){let a=i[o.nameIndex];if(!a)continue;let u=`${o.type}:${a}`;if(s.has(u))continue;s.add(u);let p=i.index,m=n.substring(0,p).split(`
512
- `).length,d=i[0].trim(),g;if(m>1){let h=r[m-2]?.trim();(h?.startsWith("/**")||h?.startsWith("///")||h?.startsWith("#"))&&(g=h)}e.push({type:o.type,name:a,signature:vn(d),exported:o.exported||!1,line:m,docstring:g})}}return e.sort((o,i)=>o.line-i.line)}c(xn,"extractFromContent");function vn(n){return n.replace(/\{$/,"").replace(/\s+/g," ").trim()}c(vn,"cleanSignature");function Pr(n){let t=n;t.tool("prjct_relevant_files","BM25-ranked files relevant to a query",{projectPath:H.string().describe("Project directory path"),query:H.string().describe("Task or query to find relevant files for"),maxFiles:H.number().optional().default(10).describe("Max files to return")},S("prjct_relevant_files",async e=>{let r=await kr(e.query,e.projectPath,{maxFiles:e.maxFiles,minScore:.1});if(r.files.length===0)return{content:[{type:"text",text:"No relevant files found."}]};let s=r.files.map(i=>`- \`${i.path}\` (score: ${Math.round(i.score*100)}%) \u2014 ${i.reasons.join(", ")}`);return{content:[{type:"text",text:`## Relevant Files (${r.files.length}/${r.metrics.filesScanned} scanned)
512
+ `).length,d=i[0].trim(),g;if(m>1){let y=r[m-2]?.trim();(y?.startsWith("/**")||y?.startsWith("///")||y?.startsWith("#"))&&(g=y)}e.push({type:o.type,name:a,signature:vn(d),exported:o.exported||!1,line:m,docstring:g})}}return e.sort((o,i)=>o.line-i.line)}c(xn,"extractFromContent");function vn(n){return n.replace(/\{$/,"").replace(/\s+/g," ").trim()}c(vn,"cleanSignature");function Pr(n){let t=n;t.tool("prjct_relevant_files","BM25-ranked files relevant to a query",{projectPath:H.string().describe("Project directory path"),query:H.string().describe("Task or query to find relevant files for"),maxFiles:H.number().optional().default(10).describe("Max files to return")},S("prjct_relevant_files",async e=>{let r=await kr(e.query,e.projectPath,{maxFiles:e.maxFiles,minScore:.1});if(r.files.length===0)return{content:[{type:"text",text:"No relevant files found."}]};let s=r.files.map(i=>`- \`${i.path}\` (score: ${Math.round(i.score*100)}%) \u2014 ${i.reasons.join(", ")}`);return{content:[{type:"text",text:`## Relevant Files (${r.files.length}/${r.metrics.filesScanned} scanned)
513
513
 
514
514
  ${s.join(`
515
515
  `)}`}]}})),t.tool("prjct_signatures","Code signatures from a file (90% token reduction vs full content)",{projectPath:H.string().describe("Project directory path"),filePath:H.string().describe("Relative file path to extract signatures from")},S("prjct_signatures",async e=>{let r=await _r(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 s=r.signatures.map(a=>`${a.exported?"export ":""}${a.type} ${a.name}: ${a.signature}${a.docstring?` // ${a.docstring}`:""}`),o=r.metrics?.compression?` (${Math.round(r.metrics.compression*100)}% reduction)`:"";return{content:[{type:"text",text:`## ${r.file} (${r.language})
516
516
  \`\`\`
517
517
  ${s.join(`
518
518
  `)}
519
- \`\`\`${o}`}]}})),t.tool("prjct_history","Recent completed tasks with outcomes",{projectPath:H.string().describe("Project directory path"),limit:H.number().optional().default(10).describe("Max results")},S("prjct_history",async e=>{let r=await P(e.projectPath),s=await Q.getTaskHistory(r);if(s.length===0)return{content:[{type:"text",text:"No task history."}]};let i=s.slice(-e.limit).reverse().map(u=>{let p=[`- **${u.title}**`];return u.completedAt&&p.push(`completed: ${u.completedAt}`),u.classification&&p.push(`type: ${u.classification}`),p.join(" | ")});return{content:[{type:"text",text:`## Task History (${s.length} total)
519
+ \`\`\`${o}`}]}})),t.tool("prjct_history","Recent completed tasks with outcomes",{projectPath:H.string().describe("Project directory path"),limit:H.number().optional().default(10).describe("Max results")},S("prjct_history",async e=>{let r=await P(e.projectPath),s=await Z.getTaskHistory(r);if(s.length===0)return{content:[{type:"text",text:"No task history."}]};let i=s.slice(-e.limit).reverse().map(u=>{let p=[`- **${u.title}**`];return u.completedAt&&p.push(`completed: ${u.completedAt}`),u.classification&&p.push(`type: ${u.classification}`),p.join(" | ")});return{content:[{type:"text",text:`## Task History (${s.length} total)
520
520
 
521
521
  ${i.join(`
522
- `)}`}]}}))}c(Pr,"registerFileTools");import{z as v}from"zod";var se=class{static{c(this,"MemoryService")}async log(t,e,r,s){try{let o=await B.getProjectId(t);if(!o)return;E.appendEvent(o,`memory.${e}`,{...r,author:s})}catch(o){console.error(`Memory log error: ${o instanceof Error?o.message:String(o)}`)}}async getRecent(t,e=100){try{let r=await B.getProjectId(t);return r?E.query(r,"SELECT type, data, timestamp FROM events WHERE type LIKE 'memory.%' ORDER BY id DESC LIMIT ?",e).reverse().map(o=>{let i=JSON.parse(o.data),{author:a,...u}=i;return{timestamp:o.timestamp,action:o.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 s=await this.getRecent(t,1e3),o=e.toLowerCase();return s.filter(i=>{let a=i.action.toLowerCase().includes(o),u=JSON.stringify(i.data).toLowerCase().includes(o);return a||u}).slice(-r)}async getByAction(t,e,r=50){try{let s=await B.getProjectId(t);return s?E.query(s,"SELECT type, data, timestamp FROM events WHERE type = ? ORDER BY id DESC LIMIT ?",`memory.${e}`,r).reverse().map(i=>{let a=JSON.parse(i.data),{author:u,...p}=a;return{timestamp:i.timestamp,action:i.type.replace("memory.",""),data:p,author:u}}):[]}catch(s){return console.error(`Memory read error: ${s instanceof Error?s.message:String(s)}`),[]}}async clear(t){try{let e=await B.getProjectId(t);if(!e)return;E.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 E.query(t,"SELECT type, data, timestamp FROM events WHERE type LIKE 'memory.%' ORDER BY id DESC LIMIT ?",e).reverse().map(s=>{let o=JSON.parse(s.data);return{timestamp:s.timestamp,action:s.type.replace("memory.",""),...o}})}catch(r){return console.error(`Memory read error: ${r instanceof Error?r.message:String(r)}`),[]}}async capEntries(t){try{let r=E.get(t,"SELECT COUNT(*) as cnt FROM events WHERE type LIKE 'memory.%'")?.cnt??0;if(r<=nt.MEMORY_MAX_ENTRIES)return 0;let s=r-nt.MEMORY_MAX_ENTRIES,o=E.query(t,"SELECT id, type, data, timestamp FROM events WHERE type LIKE 'memory.%' ORDER BY id ASC LIMIT ?",s);V.archiveMany(t,o.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 i=o[o.length-1]?.id;return i!==void 0&&E.run(t,"DELETE FROM events WHERE type LIKE 'memory.%' AND id <= ?",i),s}catch(e){return console.error(`Memory cap error: ${e instanceof Error?e.message:String(e)}`),0}}},Rr=new se;var Ar="memory.",ne="remember.",oe=`${Ar}${ne}`,dc=`${Ar}task.tagged`;var Nr=["fact","decision","learning","gotcha","pattern","anti-pattern","shipped","inbox","todo","idea","insight","question","source","person"];var _n=25,Pn=4,Rn=100;function Cr(n,t){try{return JSON.parse(n)}catch{return t}}c(Cr,"safeJson");function An(n){let t=n.type.slice(oe.length),e=Cr(n.data,{});return{id:`mem_${n.id}`,type:t,content:e.content??"",tags:e.tags??{},rememberedAt:n.timestamp,source:e.source,provenance:e.provenance??"declared"}}c(An,"rowToEntry");function Nn(n){let t=n.data?Cr(n.data,{}):{},e=t.tags??{};return n.type&&(e.type=n.type),{id:`ship_${n.id}`,type:"shipped",content:n.name,tags:e,rememberedAt:n.shipped_at,source:t.taskId,provenance:"extracted"}}c(Nn,"shippedRowToEntry");function Cn(n,t){let e=t.toLowerCase();if(n.content.toLowerCase().includes(e))return!0;for(let r of Object.values(n.tags))if(r.toLowerCase().includes(e))return!0;return!1}c(Cn,"matchesTopic");function In(n,t){for(let[e,r]of Object.entries(t))if(n.tags[e]!==r)return!1;return!0}c(In,"matchesTags");var q={async remember(n,t){await Rr.log(n,`${ne}${t.type}`,{content:t.content,tags:t.tags??{},source:t.source,provenance:t.provenance??"declared"})},recall(n,t={}){let e=t.limit??_n,r=Math.max(e*Pn,Rn),s=E.query(n,"SELECT id, type, data, timestamp FROM events WHERE type LIKE ? ORDER BY id DESC LIMIT ?",`${oe}%`,r),o=E.query(n,"SELECT id, name, type, shipped_at, data FROM shipped_features ORDER BY shipped_at DESC LIMIT ?",r),i=[...s.map(An),...o.map(Nn)];if(t.types&&t.types.length>0){let a=new Set(t.types);i=i.filter(u=>a.has(u.type))}return t.tags&&(i=i.filter(a=>In(a,t.tags??{}))),t.topic&&(i=i.filter(a=>Cn(a,t.topic))),i.sort((a,u)=>u.rememberedAt.localeCompare(a.rememberedAt)),i.slice(0,e)},similar(n,t,e=10){let r=t.toLowerCase().split(/[^a-z0-9]+/).filter(i=>i.length>3);return r.length===0?[]:q.recall(n,{limit:200}).map(i=>{let a=`${i.content} ${Object.values(i.tags).join(" ")}`.toLowerCase(),u=r.reduce((p,m)=>a.includes(m)?p+1:p,0);return{entry:i,hits:u}}).filter(i=>i.hits>0).sort((i,a)=>a.hits-i.hits).slice(0,e).map(i=>i.entry)}};function ot(n){if(n.length===0)return"> No matching memory entries.";let t=new Map;for(let o of n){let i=t.get(o.type)??[];i.push(o),t.set(o.type,i)}let e=["decision","learning","anti-pattern","gotcha","pattern","fact","shipped"],r=[],s={declared:"DECL",extracted:"EXTR",inferred:"INFR",ambiguous:"AMBG"};for(let o of e){let i=t.get(o);if(!(!i||i.length===0)){r.push(`### ${o.toUpperCase()}`);for(let a of i){let u=Object.entries(a.tags).map(([d,g])=>`${d}=${g}`).join(" "),p=u?` _(${u})_`:"",m=s[a.provenance];r.push(`- \`${m}\` [${a.id}] ${a.content}${p}`)}r.push("")}}return r.join(`
523
- `).trim()}c(ot,"formatMemoryMd");var Dn=[{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/}];function Ir(n){let t=[];for(let{name:e,re:r}of Dn)r.test(n)&&t.push(e);return t}c(Ir,"scanForSecrets");var Dr=`Base types: ${Nr.join(", ")}. Any lowercase identifier is accepted (e.g. "recipe", "okr").`;function Lr(n){let t=n;t.tool("prjct_mem_save",`Save a memory entry. ${Dr} Secret-like content is refused unless force=true.`,{projectPath:v.string().describe("Project directory path"),type:v.string().describe("Memory type (fact/decision/learning/... or user-defined)"),content:v.string().describe("The memory content. Freeform text."),tags:v.record(v.string(),v.string()).optional().describe('Key:value tags (e.g. {domain: "auth"})'),source:v.string().optional().describe("Task id this memory came from, if any"),force:v.boolean().optional().describe("Bypass the secret-like-content refusal. Default false.")},S("prjct_mem_save",async e=>{await P(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. ${Dr}`}]};let s=Ir(e.content);return s.length>0&&!e.force?{content:[{type:"text",text:`Refused \u2014 content looks like a secret (${s.join(", ")}). Re-call with force=true if intentional.`}]}:(await q.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:v.string().describe("Project directory path"),topic:v.string().optional().describe("Keyword to match over content + tag values"),types:v.array(v.string()).optional().describe("Restrict to these types"),tags:v.record(v.string(),v.string()).optional().describe("Require exact match on these k:v pairs"),limit:v.number().optional().default(25).describe("Max entries (default 25)")},S("prjct_mem_list",async e=>{let r=await P(e.projectPath),s=q.recall(r,{topic:e.topic,types:e.types,tags:e.tags,limit:e.limit});return{content:[{type:"text",text:ot(s)}]}})),t.tool("prjct_mem_similar","Find memory entries similar to a free-text description. Keyword-based, best-effort.",{projectPath:v.string().describe("Project directory path"),description:v.string().describe("Free-text description to find similar memories for"),limit:v.number().optional().default(10).describe("Max results (default 10)")},S("prjct_mem_similar",async e=>{let r=await P(e.projectPath),s=q.similar(r,e.description,e.limit);return s.length===0?{content:[{type:"text",text:"No similar memories found."}]}:{content:[{type:"text",text:ot(s)}]}})),t.tool("prjct_mem_forget","Remove a memory entry by id. Ids are stable \u2014 pull them from `prjct_mem_list`.",{projectPath:v.string().describe("Project directory path"),id:v.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(Lr,"registerMemoryTools");import{z as ce}from"zod";var ie=class{static{c(this,"LLMAnalysisStorage")}save(t,e){let r=T.getDb(t),s=f();r.transaction(()=>{r.prepare("UPDATE llm_analysis SET status = 'superseded', superseded_at = ? WHERE status = 'active'").run(s),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=T.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?T.get(t,"SELECT commit_hash FROM llm_analysis WHERE status = 'active' LIMIT 1")?.commit_hash===e:!1}getHistory(t,e=10){return T.query(t,"SELECT id, commit_hash, status, analyzed_at, analysis FROM llm_analysis ORDER BY id DESC LIMIT ?",e).map(s=>{let o=JSON.parse(s.analysis);return{id:s.id,commitHash:s.commit_hash,status:s.status,analyzedAt:s.analyzed_at,patternCount:o.patterns.length}})}},Ln=new ie,Or=Ln;var jr={critical:0,high:1,medium:2,low:3},Mr={active:0,previously_active:1,backlog:2};function Fr(n){return[...n].sort((t,e)=>{let r=Mr[t.section]-Mr[e.section];return r!==0?r:jr[t.priority]-jr[e.priority]})}c(Fr,"sortBySectionAndPriority");var ae=class extends K{static{c(this,"QueueStorage")}constructor(){super("queue.json",Tr)}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 Fr(e)[0]||null}async addTask(t,e){let r={...e,id:$(),createdAt:f(),completed:!1};return await this.update(t,s=>({tasks:[...s.tasks,r],lastUpdated:f()})),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=f(),s=e.map(o=>({...o,id:$(),createdAt:r,completed:!1}));return await this.update(t,o=>({tasks:[...o.tasks,...s],lastUpdated:r})),await this.publishEvent(t,"queue.tasks_added",{count:s.length,tasks:s.map(o=>({id:o.id,description:o.description}))}),s}async removeTask(t,e){await this.update(t,r=>({tasks:r.tasks.filter(s=>s.id!==e),lastUpdated:f()})),await this.publishEvent(t,"queue.task_removed",{taskId:e})}async completeTask(t,e){let r=null;if(await this.update(t,s=>({tasks:s.tasks.map(i=>i.id===e?(r={...i,completed:!0,completedAt:f()},r):i),lastUpdated:f()})),r){let s=r;await this.publishEvent(t,"queue.task_completed",{taskId:e,description:s.description,completedAt:s.completedAt})}return r}async moveToSection(t,e,r){await this.update(t,s=>({tasks:s.tasks.map(o=>o.id===e?{...o,section:r}:o),lastUpdated:f()}))}async setPriority(t,e,r){await this.update(t,s=>({tasks:s.tasks.map(o=>o.id===e?{...o,priority:r}:o),lastUpdated:f()}))}async getTask(t,e){return(await this.read(t)).tasks.find(s=>s.id===e)||null}async updateTask(t,e,r){let s=null;return await this.update(t,o=>({tasks:o.tasks.map(i=>i.id===e?(s={...i,...r},s):i),lastUpdated:f()})),s&&await this.publishEvent(t,"queue.task_updated",{taskId:e}),s}async clearCompleted(t){let r=(await this.read(t)).tasks.filter(s=>s.completed).length;return await this.update(t,s=>({tasks:s.tasks.filter(o=>!o.completed),lastUpdated:f()})),r}async removeStaleCompleted(t){let e=await this.read(t),r=Ee(nt.QUEUE_COMPLETED_DAYS),s=e.tasks.filter(i=>i.completed&&i.completedAt&&new Date(i.completedAt)<r);if(s.length===0)return 0;V.archiveMany(t,s.map(i=>({entityType:"queue_task",entityId:i.id,entityData:i,summary:i.description,reason:"age"})));let o=new Set(s.map(i=>i.id));return await this.update(t,i=>({tasks:i.tasks.filter(a=>!o.has(a.id)),lastUpdated:f()})),await this.publishEvent(t,"queue.stale_removed",{count:s.length}),s.length}},Ur=new ae;function Xr(n){let t=n;t.tool("prjct_task_status","Current task, duration, subtasks, and queue",{projectPath:ce.string().describe("Project directory path")},S("prjct_task_status",async e=>{let r=await P(e.projectPath),s=await Q.getCurrentTask(r),o=await Ur.getActiveTasks(r),i=[];if(s?(i.push(`## Active Task
522
+ `)}`}]}}))}c(Pr,"registerFileTools");import{z as v}from"zod";var se=class{static{c(this,"MemoryService")}async log(t,e,r,s){try{let o=await B.getProjectId(t);if(!o)return;E.appendEvent(o,`memory.${e}`,{...r,author:s})}catch(o){console.error(`Memory log error: ${o instanceof Error?o.message:String(o)}`)}}async getRecent(t,e=100){try{let r=await B.getProjectId(t);return r?E.query(r,"SELECT type, data, timestamp FROM events WHERE type LIKE 'memory.%' ORDER BY id DESC LIMIT ?",e).reverse().map(o=>{let i=JSON.parse(o.data),{author:a,...u}=i;return{timestamp:o.timestamp,action:o.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 s=await this.getRecent(t,1e3),o=e.toLowerCase();return s.filter(i=>{let a=i.action.toLowerCase().includes(o),u=JSON.stringify(i.data).toLowerCase().includes(o);return a||u}).slice(-r)}async getByAction(t,e,r=50){try{let s=await B.getProjectId(t);return s?E.query(s,"SELECT type, data, timestamp FROM events WHERE type = ? ORDER BY id DESC LIMIT ?",`memory.${e}`,r).reverse().map(i=>{let a=JSON.parse(i.data),{author:u,...p}=a;return{timestamp:i.timestamp,action:i.type.replace("memory.",""),data:p,author:u}}):[]}catch(s){return console.error(`Memory read error: ${s instanceof Error?s.message:String(s)}`),[]}}async clear(t){try{let e=await B.getProjectId(t);if(!e)return;E.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 E.query(t,"SELECT type, data, timestamp FROM events WHERE type LIKE 'memory.%' ORDER BY id DESC LIMIT ?",e).reverse().map(s=>{let o=JSON.parse(s.data);return{timestamp:s.timestamp,action:s.type.replace("memory.",""),...o}})}catch(r){return console.error(`Memory read error: ${r instanceof Error?r.message:String(r)}`),[]}}async capEntries(t){try{let r=E.get(t,"SELECT COUNT(*) as cnt FROM events WHERE type LIKE 'memory.%'")?.cnt??0;if(r<=ot.MEMORY_MAX_ENTRIES)return 0;let s=r-ot.MEMORY_MAX_ENTRIES,o=E.query(t,"SELECT id, type, data, timestamp FROM events WHERE type LIKE 'memory.%' ORDER BY id ASC LIMIT ?",s);K.archiveMany(t,o.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 i=o[o.length-1]?.id;return i!==void 0&&E.run(t,"DELETE FROM events WHERE type LIKE 'memory.%' AND id <= ?",i),s}catch(e){return console.error(`Memory cap error: ${e instanceof Error?e.message:String(e)}`),0}}},Rr=new se;var Ar="memory.",ne="remember.",oe=`${Ar}${ne}`,dc=`${Ar}task.tagged`;var Nr=["fact","decision","learning","gotcha","pattern","anti-pattern","shipped","inbox","todo","idea","insight","question","source","person"];var _n=25,Pn=4,Rn=100;function Cr(n,t){try{return JSON.parse(n)}catch{return t}}c(Cr,"safeJson");function An(n){let t=n.type.slice(oe.length),e=Cr(n.data,{});return{id:`mem_${n.id}`,type:t,content:e.content??"",tags:e.tags??{},rememberedAt:n.timestamp,source:e.source,provenance:e.provenance??"declared"}}c(An,"rowToEntry");function Nn(n){let t=n.data?Cr(n.data,{}):{},e=t.tags??{};return n.type&&(e.type=n.type),{id:`ship_${n.id}`,type:"shipped",content:n.name,tags:e,rememberedAt:n.shipped_at,source:t.taskId,provenance:"extracted"}}c(Nn,"shippedRowToEntry");function Cn(n,t){let e=t.toLowerCase();if(n.content.toLowerCase().includes(e))return!0;for(let r of Object.values(n.tags))if(r.toLowerCase().includes(e))return!0;return!1}c(Cn,"matchesTopic");function In(n,t){for(let[e,r]of Object.entries(t))if(n.tags[e]!==r)return!1;return!0}c(In,"matchesTags");var q={async remember(n,t){await Rr.log(n,`${ne}${t.type}`,{content:t.content,tags:t.tags??{},source:t.source,provenance:t.provenance??"declared"})},recall(n,t={}){let e=t.limit??_n,r=Math.max(e*Pn,Rn),s=E.query(n,"SELECT id, type, data, timestamp FROM events WHERE type LIKE ? ORDER BY id DESC LIMIT ?",`${oe}%`,r),o=E.query(n,"SELECT id, name, type, shipped_at, data FROM shipped_features ORDER BY shipped_at DESC LIMIT ?",r),i=[...s.map(An),...o.map(Nn)];if(t.types&&t.types.length>0){let a=new Set(t.types);i=i.filter(u=>a.has(u.type))}return t.tags&&(i=i.filter(a=>In(a,t.tags??{}))),t.topic&&(i=i.filter(a=>Cn(a,t.topic))),i.sort((a,u)=>u.rememberedAt.localeCompare(a.rememberedAt)),i.slice(0,e)},similar(n,t,e=10){let r=t.toLowerCase().split(/[^a-z0-9]+/).filter(i=>i.length>3);return r.length===0?[]:q.recall(n,{limit:200}).map(i=>{let a=`${i.content} ${Object.values(i.tags).join(" ")}`.toLowerCase(),u=r.reduce((p,m)=>a.includes(m)?p+1:p,0);return{entry:i,hits:u}}).filter(i=>i.hits>0).sort((i,a)=>a.hits-i.hits).slice(0,e).map(i=>i.entry)}};function it(n){if(n.length===0)return"> No matching memory entries.";let t=new Map;for(let o of n){let i=t.get(o.type)??[];i.push(o),t.set(o.type,i)}let e=["decision","learning","anti-pattern","gotcha","pattern","fact","shipped"],r=[],s={declared:"DECL",extracted:"EXTR",inferred:"INFR",ambiguous:"AMBG"};for(let o of e){let i=t.get(o);if(!(!i||i.length===0)){r.push(`### ${o.toUpperCase()}`);for(let a of i){let u=Object.entries(a.tags).map(([d,g])=>`${d}=${g}`).join(" "),p=u?` _(${u})_`:"",m=s[a.provenance];r.push(`- \`${m}\` [${a.id}] ${a.content}${p}`)}r.push("")}}return r.join(`
523
+ `).trim()}c(it,"formatMemoryMd");var Dn=[{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/}];function Ir(n){let t=[];for(let{name:e,re:r}of Dn)r.test(n)&&t.push(e);return t}c(Ir,"scanForSecrets");var Dr=`Base types: ${Nr.join(", ")}. Any lowercase identifier is accepted (e.g. "recipe", "okr").`;function Lr(n){let t=n;t.tool("prjct_mem_save",`Save a memory entry. ${Dr} Secret-like content is refused unless force=true.`,{projectPath:v.string().describe("Project directory path"),type:v.string().describe("Memory type (fact/decision/learning/... or user-defined)"),content:v.string().describe("The memory content. Freeform text."),tags:v.record(v.string(),v.string()).optional().describe('Key:value tags (e.g. {domain: "auth"})'),source:v.string().optional().describe("Task id this memory came from, if any"),force:v.boolean().optional().describe("Bypass the secret-like-content refusal. Default false.")},S("prjct_mem_save",async e=>{await P(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. ${Dr}`}]};let s=Ir(e.content);return s.length>0&&!e.force?{content:[{type:"text",text:`Refused \u2014 content looks like a secret (${s.join(", ")}). Re-call with force=true if intentional.`}]}:(await q.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:v.string().describe("Project directory path"),topic:v.string().optional().describe("Keyword to match over content + tag values"),types:v.array(v.string()).optional().describe("Restrict to these types"),tags:v.record(v.string(),v.string()).optional().describe("Require exact match on these k:v pairs"),limit:v.number().optional().default(25).describe("Max entries (default 25)")},S("prjct_mem_list",async e=>{let r=await P(e.projectPath),s=q.recall(r,{topic:e.topic,types:e.types,tags:e.tags,limit:e.limit});return{content:[{type:"text",text:it(s)}]}})),t.tool("prjct_mem_similar","Find memory entries similar to a free-text description. Keyword-based, best-effort.",{projectPath:v.string().describe("Project directory path"),description:v.string().describe("Free-text description to find similar memories for"),limit:v.number().optional().default(10).describe("Max results (default 10)")},S("prjct_mem_similar",async e=>{let r=await P(e.projectPath),s=q.similar(r,e.description,e.limit);return s.length===0?{content:[{type:"text",text:"No similar memories found."}]}:{content:[{type:"text",text:it(s)}]}})),t.tool("prjct_mem_forget","Remove a memory entry by id. Ids are stable \u2014 pull them from `prjct_mem_list`.",{projectPath:v.string().describe("Project directory path"),id:v.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(Lr,"registerMemoryTools");import{z as ce}from"zod";var ie=class{static{c(this,"LLMAnalysisStorage")}save(t,e){let r=T.getDb(t),s=f();r.transaction(()=>{r.prepare("UPDATE llm_analysis SET status = 'superseded', superseded_at = ? WHERE status = 'active'").run(s),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=T.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?T.get(t,"SELECT commit_hash FROM llm_analysis WHERE status = 'active' LIMIT 1")?.commit_hash===e:!1}getHistory(t,e=10){return T.query(t,"SELECT id, commit_hash, status, analyzed_at, analysis FROM llm_analysis ORDER BY id DESC LIMIT ?",e).map(s=>{let o=JSON.parse(s.analysis);return{id:s.id,commitHash:s.commit_hash,status:s.status,analyzedAt:s.analyzed_at,patternCount:o.patterns.length}})}},Ln=new ie,Or=Ln;var jr={critical:0,high:1,medium:2,low:3},Mr={active:0,previously_active:1,backlog:2};function Fr(n){return[...n].sort((t,e)=>{let r=Mr[t.section]-Mr[e.section];return r!==0?r:jr[t.priority]-jr[e.priority]})}c(Fr,"sortBySectionAndPriority");var ae=class extends Q{static{c(this,"QueueStorage")}constructor(){super("queue.json",Tr)}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 Fr(e)[0]||null}async addTask(t,e){let r={...e,id:$(),createdAt:f(),completed:!1};return await this.update(t,s=>({tasks:[...s.tasks,r],lastUpdated:f()})),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=f(),s=e.map(o=>({...o,id:$(),createdAt:r,completed:!1}));return await this.update(t,o=>({tasks:[...o.tasks,...s],lastUpdated:r})),await this.publishEvent(t,"queue.tasks_added",{count:s.length,tasks:s.map(o=>({id:o.id,description:o.description}))}),s}async removeTask(t,e){await this.update(t,r=>({tasks:r.tasks.filter(s=>s.id!==e),lastUpdated:f()})),await this.publishEvent(t,"queue.task_removed",{taskId:e})}async completeTask(t,e){let r=null;if(await this.update(t,s=>({tasks:s.tasks.map(i=>i.id===e?(r={...i,completed:!0,completedAt:f()},r):i),lastUpdated:f()})),r){let s=r;await this.publishEvent(t,"queue.task_completed",{taskId:e,description:s.description,completedAt:s.completedAt})}return r}async moveToSection(t,e,r){await this.update(t,s=>({tasks:s.tasks.map(o=>o.id===e?{...o,section:r}:o),lastUpdated:f()}))}async setPriority(t,e,r){await this.update(t,s=>({tasks:s.tasks.map(o=>o.id===e?{...o,priority:r}:o),lastUpdated:f()}))}async getTask(t,e){return(await this.read(t)).tasks.find(s=>s.id===e)||null}async updateTask(t,e,r){let s=null;return await this.update(t,o=>({tasks:o.tasks.map(i=>i.id===e?(s={...i,...r},s):i),lastUpdated:f()})),s&&await this.publishEvent(t,"queue.task_updated",{taskId:e}),s}async clearCompleted(t){let r=(await this.read(t)).tasks.filter(s=>s.completed).length;return await this.update(t,s=>({tasks:s.tasks.filter(o=>!o.completed),lastUpdated:f()})),r}async removeStaleCompleted(t){let e=await this.read(t),r=Ee(ot.QUEUE_COMPLETED_DAYS),s=e.tasks.filter(i=>i.completed&&i.completedAt&&new Date(i.completedAt)<r);if(s.length===0)return 0;K.archiveMany(t,s.map(i=>({entityType:"queue_task",entityId:i.id,entityData:i,summary:i.description,reason:"age"})));let o=new Set(s.map(i=>i.id));return await this.update(t,i=>({tasks:i.tasks.filter(a=>!o.has(a.id)),lastUpdated:f()})),await this.publishEvent(t,"queue.stale_removed",{count:s.length}),s.length}},Ur=new ae;function Xr(n){let t=n;t.tool("prjct_task_status","Current task, duration, subtasks, and queue",{projectPath:ce.string().describe("Project directory path")},S("prjct_task_status",async e=>{let r=await P(e.projectPath),s=await Z.getCurrentTask(r),o=await Ur.getActiveTasks(r),i=[];if(s?(i.push(`## Active Task
524
524
  **${s.description}**`),s.branch&&i.push(`Branch: ${s.branch}`),i.push(`Started: ${s.startedAt}`)):i.push("No active task."),o.length>0){i.push(`
525
525
  ## Queue (${o.length} tasks)`);for(let a of o.slice(0,10))i.push(`- ${a.description} [${a.priority||"medium"}]`)}return{content:[{type:"text",text:i.join(`
526
526
  `)}]}})),t.tool("prjct_analysis","LLM analysis: stack, patterns, anti-patterns, conventions",{projectPath:ce.string().describe("Project directory path")},S("prjct_analysis",async e=>{let r=await P(e.projectPath),s=Or.getActive(r);if(!s)return{content:[{type:"text",text:"No analysis available. Run `prjct sync`."}]};let o=["## Project Analysis"];if(s.stack&&(o.push(`
@@ -528,14 +528,14 @@ ${i.join(`
528
528
  ### Patterns (${s.patterns.length})`);for(let i of s.patterns)o.push(`- **${i.name}**: ${i.description}`)}if(s.antiPatterns?.length){o.push(`
529
529
  ### Anti-Patterns (${s.antiPatterns.length})`);for(let i of s.antiPatterns)o.push(`- **${i.issue}**: ${i.suggestion}`)}if(s.conventions?.length){o.push(`
530
530
  ### Conventions (${s.conventions.length})`);for(let i of s.conventions)o.push(`- [${i.category}] ${i.rule}`)}return{content:[{type:"text",text:o.join(`
531
- `)}]}})),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:ce.string().describe("Project directory path")},S("prjct_patterns",async e=>{let r=await P(e.projectPath),s=q.recall(r,{types:["decision","pattern","anti-pattern","gotcha"],limit:50});return s.length===0?{content:[{type:"text",text:"No decisions or patterns captured yet."}]}:{content:[{type:"text",text:ot(s)}]}}))}c(Xr,"registerProjectTools");import{z as bt}from"zod";var ue=class{static{c(this,"CustomWorkflowStorage")}createWorkflow(t,e){let r=new Date().toISOString();E.run(t,`INSERT INTO custom_workflows (name, description, created_at, updated_at, is_builtin, enabled, metadata)
532
- VALUES (?, ?, ?, ?, 0, 1, ?)`,e.name,e.description??null,r,r,e.metadata?JSON.stringify(e.metadata):null);let s=E.get(t,"SELECT id FROM custom_workflows WHERE name = ?",e.name);if(!s)throw new Error(`Failed to create workflow: ${e.name}`);return s.id}getWorkflow(t,e){let r=E.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 E.query(t,r).map(o=>this.rowToWorkflow(o))}updateWorkflow(t,e,r){if(!this.getWorkflow(t,e))return!1;let o=new Date().toISOString(),i=[],a=[];return r.description!==void 0&&(i.push("description = ?"),a.push(r.description)),r.enabled!==void 0&&(i.push("enabled = ?"),a.push(r.enabled?1:0)),r.metadata!==void 0&&(i.push("metadata = ?"),a.push(JSON.stringify(r.metadata))),i.length===0?!1:(i.push("updated_at = ?"),a.push(o),a.push(e),E.run(t,`UPDATE custom_workflows SET ${i.join(", ")} WHERE name = ?`,...a),!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 E.run(t,"UPDATE custom_workflows SET enabled = 0 WHERE 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}}},wt=new ue;function le(n){let t=n.trust_source==="imported"?"imported":"local";return{id:n.id,type:n.type,command:n.command,position:n.position,action:n.action,description:n.description,enabled:n.enabled===1,timeoutMs:n.timeout_ms,createdAt:n.created_at,sortOrder:n.sort_order,whenExpr:n.when_expr??null,parallel:n.parallel===null?!0:n.parallel===1,trustSource:t}}c(le,"rowToRule");var pe=class{static{c(this,"WorkflowRuleStorage")}addRule(t,e){let r=T.get(t,"SELECT MAX(sort_order) as m FROM workflow_rules WHERE command = ?",e.command),s=e.sortOrder||(r?.m??-1)+1;return T.run(t,`INSERT INTO workflow_rules (type, command, position, action, description, enabled, timeout_ms, created_at, sort_order, when_expr, parallel, trust_source)
533
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,e.type,e.command,e.position,e.action,e.description??null,e.enabled?1:0,e.timeoutMs,e.createdAt,s,e.whenExpr??null,e.parallel===!1?0:1,e.trustSource??"local"),T.get(t,"SELECT last_insert_rowid() as id")?.id??0}removeRule(t,e){return T.get(t,"SELECT id FROM workflow_rules WHERE id = ?",e)?(T.run(t,"DELETE FROM workflow_rules WHERE id = ?",e),!0):!1}updateRule(t,e,r){if(!T.get(t,"SELECT id FROM workflow_rules WHERE id = ?",e))return!1;let o={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"}},i=[],a=[];for(let[u,p]of Object.entries(r)){let m=o[u];if(!m)continue;i.push(`${m.column} = ?`);let d=p;a.push(m.transform?m.transform(d):d)}return i.length===0||(a.push(e),T.run(t,`UPDATE workflow_rules SET ${i.join(", ")} WHERE id = ?`,...a)),!0}getRuleById(t,e){let r=T.get(t,"SELECT * FROM workflow_rules WHERE id = ?",e);return r?le(r):null}getRulesForCommand(t,e){let r=wt.getWorkflow(t,e);return!r||!r.enabled?[]:T.query(t,"SELECT * FROM workflow_rules WHERE command = ? AND enabled = 1 ORDER BY sort_order ASC",e).map(le)}getAllRules(t){return T.query(t,"SELECT * FROM workflow_rules ORDER BY command ASC, sort_order ASC").map(le)}resetRules(t){let e=T.get(t,"SELECT COUNT(*) as c FROM workflow_rules");return T.run(t,"DELETE FROM workflow_rules"),e?.c??0}},de=new pe;function $r(n){let t=n;t.tool("prjct_workflow_rules","Get workflow rules for a command (gates, hooks, steps, instructions)",{projectPath:bt.string().describe("Project directory path"),command:bt.string().describe("Command name (task, done, ship, sync, etc.)")},S("prjct_workflow_rules",async e=>{let r=await P(e.projectPath),s=de.getRulesForCommand(r,e.command);if(s.length===0)return{content:[{type:"text",text:`No workflow rules for \`${e.command}\`.`}]};let o={};for(let a of s){let u=`${a.type}:${a.position}`;o[u]||(o[u]=[]),o[u].push(a)}let i=[`## Workflow Rules for \`${e.command}\``];for(let[a,u]of Object.entries(o)){i.push(`
531
+ `)}]}})),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:ce.string().describe("Project directory path")},S("prjct_patterns",async e=>{let r=await P(e.projectPath),s=q.recall(r,{types:["decision","pattern","anti-pattern","gotcha"],limit:50});return s.length===0?{content:[{type:"text",text:"No decisions or patterns captured yet."}]}:{content:[{type:"text",text:it(s)}]}}))}c(Xr,"registerProjectTools");import{z as St}from"zod";var ue=class{static{c(this,"CustomWorkflowStorage")}createWorkflow(t,e){let r=new Date().toISOString();E.run(t,`INSERT INTO custom_workflows (name, description, created_at, updated_at, is_builtin, enabled, metadata)
532
+ VALUES (?, ?, ?, ?, 0, 1, ?)`,e.name,e.description??null,r,r,e.metadata?JSON.stringify(e.metadata):null);let s=E.get(t,"SELECT id FROM custom_workflows WHERE name = ?",e.name);if(!s)throw new Error(`Failed to create workflow: ${e.name}`);return s.id}getWorkflow(t,e){let r=E.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 E.query(t,r).map(o=>this.rowToWorkflow(o))}updateWorkflow(t,e,r){if(!this.getWorkflow(t,e))return!1;let o=new Date().toISOString(),i=[],a=[];return r.description!==void 0&&(i.push("description = ?"),a.push(r.description)),r.enabled!==void 0&&(i.push("enabled = ?"),a.push(r.enabled?1:0)),r.metadata!==void 0&&(i.push("metadata = ?"),a.push(JSON.stringify(r.metadata))),i.length===0?!1:(i.push("updated_at = ?"),a.push(o),a.push(e),E.run(t,`UPDATE custom_workflows SET ${i.join(", ")} WHERE name = ?`,...a),!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 E.run(t,"UPDATE custom_workflows SET enabled = 0 WHERE 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}}},bt=new ue;function le(n){let t=n.trust_source==="imported"?"imported":"local";return{id:n.id,type:n.type,command:n.command,position:n.position,action:n.action,description:n.description,enabled:n.enabled===1,timeoutMs:n.timeout_ms,createdAt:n.created_at,sortOrder:n.sort_order,whenExpr:n.when_expr??null,parallel:n.parallel===null?!0:n.parallel===1,trustSource:t}}c(le,"rowToRule");var pe=class{static{c(this,"WorkflowRuleStorage")}addRule(t,e){let r=T.get(t,"SELECT MAX(sort_order) as m FROM workflow_rules WHERE command = ?",e.command),s=e.sortOrder||(r?.m??-1)+1;return T.run(t,`INSERT INTO workflow_rules (type, command, position, action, description, enabled, timeout_ms, created_at, sort_order, when_expr, parallel, trust_source)
533
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,e.type,e.command,e.position,e.action,e.description??null,e.enabled?1:0,e.timeoutMs,e.createdAt,s,e.whenExpr??null,e.parallel===!1?0:1,e.trustSource??"local"),T.get(t,"SELECT last_insert_rowid() as id")?.id??0}removeRule(t,e){return T.get(t,"SELECT id FROM workflow_rules WHERE id = ?",e)?(T.run(t,"DELETE FROM workflow_rules WHERE id = ?",e),!0):!1}updateRule(t,e,r){if(!T.get(t,"SELECT id FROM workflow_rules WHERE id = ?",e))return!1;let o={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"}},i=[],a=[];for(let[u,p]of Object.entries(r)){let m=o[u];if(!m)continue;i.push(`${m.column} = ?`);let d=p;a.push(m.transform?m.transform(d):d)}return i.length===0||(a.push(e),T.run(t,`UPDATE workflow_rules SET ${i.join(", ")} WHERE id = ?`,...a)),!0}getRuleById(t,e){let r=T.get(t,"SELECT * FROM workflow_rules WHERE id = ?",e);return r?le(r):null}getRulesForCommand(t,e){let r=bt.getWorkflow(t,e);return!r||!r.enabled?[]:T.query(t,"SELECT * FROM workflow_rules WHERE command = ? AND enabled = 1 ORDER BY sort_order ASC",e).map(le)}getAllRules(t){return T.query(t,"SELECT * FROM workflow_rules ORDER BY command ASC, sort_order ASC").map(le)}resetRules(t){let e=T.get(t,"SELECT COUNT(*) as c FROM workflow_rules");return T.run(t,"DELETE FROM workflow_rules"),e?.c??0}},de=new pe;function $r(n){let t=n;t.tool("prjct_workflow_rules","Get workflow rules for a command (gates, hooks, steps, instructions)",{projectPath:St.string().describe("Project directory path"),command:St.string().describe("Command name (task, done, ship, sync, etc.)")},S("prjct_workflow_rules",async e=>{let r=await P(e.projectPath),s=de.getRulesForCommand(r,e.command);if(s.length===0)return{content:[{type:"text",text:`No workflow rules for \`${e.command}\`.`}]};let o={};for(let a of s){let u=`${a.type}:${a.position}`;o[u]||(o[u]=[]),o[u].push(a)}let i=[`## Workflow Rules for \`${e.command}\``];for(let[a,u]of Object.entries(o)){i.push(`
534
534
  ### ${a}`);for(let p of u){let m=p.enabled?"":" (disabled)";i.push(`- ${p.action}${p.description?` \u2014 ${p.description}`:""}${m}`)}}return{content:[{type:"text",text:i.join(`
535
- `)}]}})),t.tool("prjct_workflow_list","List all workflows for this project (built-in + custom)",{projectPath:bt.string().describe("Project directory path")},S("prjct_workflow_list",async e=>{let r=await P(e.projectPath),s=wt.getAllWorkflows(r);if(s.length===0)return{content:[{type:"text",text:"No workflows configured."}]};let o=s.map(i=>{let a=i.isBuiltin?"(built-in)":"(custom)",u=i.enabled?"":" [disabled]";return`- **${i.name}** ${a}${u}${i.description?`: ${i.description}`:""}`});return{content:[{type:"text",text:`## Workflows (${s.length})
535
+ `)}]}})),t.tool("prjct_workflow_list","List all workflows for this project (built-in + custom)",{projectPath:St.string().describe("Project directory path")},S("prjct_workflow_list",async e=>{let r=await P(e.projectPath),s=bt.getAllWorkflows(r);if(s.length===0)return{content:[{type:"text",text:"No workflows configured."}]};let o=s.map(i=>{let a=i.isBuiltin?"(built-in)":"(custom)",u=i.enabled?"":" [disabled]";return`- **${i.name}** ${a}${u}${i.description?`: ${i.description}`:""}`});return{content:[{type:"text",text:`## Workflows (${s.length})
536
536
 
537
537
  ${o.join(`
538
- `)}`}]}})),t.tool("prjct_workflow_status","Current workflow execution state + active rules",{projectPath:bt.string().describe("Project directory path")},S("prjct_workflow_status",async e=>{let r=await P(e.projectPath),s=await Q.getCurrentTask(r),o=de.getAllRules(r),i=["## Workflow Status"];s?(i.push(`
538
+ `)}`}]}})),t.tool("prjct_workflow_status","Current workflow execution state + active rules",{projectPath:St.string().describe("Project directory path")},S("prjct_workflow_status",async e=>{let r=await P(e.projectPath),s=await Z.getCurrentTask(r),o=de.getAllRules(r),i=["## Workflow Status"];s?(i.push(`
539
539
  Active task: **${s.description}**`),i.push(`Started: ${s.startedAt}`)):i.push(`
540
540
  No active task.`);let a=o.filter(u=>u.enabled);if(a.length>0){i.push(`
541
541
  ### Active Rules (${a.length})`);for(let u of a)i.push(`- [${u.type}] ${u.command}:${u.position} \u2192 ${u.action}`)}else i.push(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prjct-cli",
3
- "version": "2.1.2",
3
+ "version": "2.2.2",
4
4
  "description": "Context layer for AI agents. Project context for Claude Code, Gemini CLI, and more.",
5
5
  "main": "dist/bin/prjct.mjs",
6
6
  "bin": {