prjct-cli 1.56.10 → 2.0.0-alpha.12

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,32 +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 Ot=Object.defineProperty;var cs=Object.getOwnPropertyDescriptor;var us=Object.getOwnPropertyNames;var ls=Object.prototype.hasOwnProperty;var l=(i,t)=>Ot(i,"name",{value:t,configurable:!0}),fn=(i=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(i,{get:(t,e)=>(typeof require<"u"?require:t)[e]}):i)(function(i){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+i+'" is not supported')});var $=(i,t)=>()=>(i&&(t=i(i=0)),t);var Lt=(i,t)=>{for(var e in t)Ot(i,e,{get:t[e],enumerable:!0})},ps=(i,t,e,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of us(t))!ls.call(i,n)&&n!==e&&Ot(i,n,{get:()=>t[n],enumerable:!(r=cs(t,n))||r.enumerable});return i};var ae=i=>ps(Ot({},"__esModule",{value:!0}),i);var hn,yn,Tn,ce=$(()=>{"use strict";hn=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"]),yn=["",".ts",".tsx",".js",".jsx","/index.ts","/index.js"],Tn=/(?:import|from)\s+['"]([^'"]+)['"]/g});import{formatDistanceToNowStrict as Hi}from"date-fns";function wn(i){return{year:i.getFullYear().toString(),month:(i.getMonth()+1).toString().padStart(2,"0"),day:i.getDate().toString().padStart(2,"0")}}function f(){return new Date().toISOString()}function $t(i){let t=new Date;return t.setDate(t.getDate()-i),t}function bn(i){let t=i.match(/^([+-])(\d+)([mh])$/);if(!t)return 0;let e=t[1]==="-"?-1:1,r=Number.parseInt(t[2],10),n=t[3];return e*(n==="h"?r*60:r)}function gt(i){let t=0,e=i.match(/(\d+)h/);e&&(t+=Number.parseInt(e[1],10)*60);let r=i.match(/(\d+)m/);return r&&(t+=Number.parseInt(r[1],10)),i.match(/(\d+)s/)&&t===0&&(t=1),t}var W=$(()=>{"use strict";l(wn,"getYearMonthDay");l(f,"getTimestamp");l($t,"getDaysAgo");l(bn,"parseVarianceMinutes");l(gt,"parseDurationMinutes")});function ms(i){return i instanceof Error&&"code"in i}function H(i){return ms(i)&&i.code==="ENOENT"}function En(i){return i instanceof Error?i.message:typeof i=="string"?i:"Unknown error"}var ft=$(()=>{"use strict";l(ms,"isNodeError");l(H,"isNotFoundError");l(En,"getErrorMessage")});import xn from"node:fs/promises";async function _n(i,t){let e;try{e=await xn.readFile(i,"utf-8")}catch(s){if(H(s))return null;throw s}let r;try{r=JSON.parse(e)}catch{return await kn(i,e),Sn(i,"Malformed JSON"),null}let n=t.safeParse(r);return n.success?r:(await kn(i,e),Sn(i,gs(n.error)),null)}async function kn(i,t){let e=`${i}.backup`;try{await xn.writeFile(e,t,"utf-8")}catch{}}function Sn(i,t){console.error(`[prjct] Warning: Corrupted storage file: ${i}`),console.error(`[prjct] Reason: ${t}`),console.error("[prjct] A .backup file has been created. Returning defaults.")}function gs(i){return i.issues.slice(0,3).map(t=>`${t.path.join(".")}: ${t.message}`).join("; ")}var vn=$(()=>{"use strict";ft();l(_n,"safeRead");l(kn,"createBackup");l(Sn,"logCorruption");l(gs,"formatZodError")});import J from"node:fs/promises";import Ft from"node:path";async function Pn(i,t={}){let e=[],r=t.maxFiles??1/0,n=t.dotfileAllowlist?new Set(t.dotfileAllowlist):null;async function s(o){if(e.length>=r)return;let a=await J.readdir(o,{withFileTypes:!0}).catch(()=>[]);for(let c of a){if(e.length>=r)break;let u=String(c.name);if(hn.has(u)||t.skipDotfiles&&u.startsWith(".")&&(!n||!n.has(u)))continue;let p=Ft.join(o,u);c.isDirectory()?await s(p):c.isFile()&&e.push(Ft.relative(i,p))}}return l(s,"walk"),await s(i),e}async function jn(i,t,e){let r=[];for(let n=0;n<i.length;n+=t){let s=await Promise.all(i.slice(n,n+t).map(e));for(let o of s)o!==null&&r.push(o)}return r}async function Ut(i,t=null,e){if(e)return await _n(i,e)??t;try{let r=await J.readFile(i,"utf-8");return JSON.parse(r)}catch(r){if(H(r))return t;throw r}}async function rt(i,t,e=2){let r=Ft.dirname(i);await J.mkdir(r,{recursive:!0});let n=JSON.stringify(t,null,e);await J.writeFile(i,n,"utf-8")}async function ue(i,t=""){try{return await J.readFile(i,"utf-8")}catch(e){if(H(e))return t;throw e}}async function Rn(i,t){let e=Ft.dirname(i);await J.mkdir(e,{recursive:!0}),await J.appendFile(i,`${t}
9
- `,"utf-8")}async function N(i){try{return await J.access(i),!0}catch(t){if(H(t))return!1;throw t}}async function le(i){try{return(await J.stat(i)).isDirectory()}catch(t){if(H(t))return!1;throw t}}async function K(i){await J.mkdir(i,{recursive:!0})}var st=$(()=>{"use strict";ce();vn();ft();l(Pn,"walkDir");l(jn,"batchProcess");l(Ut,"readJson");l(rt,"writeJson");l(ue,"readFile");l(Rn,"appendLine");l(N,"fileExists");l(le,"dirExists");l(K,"ensureDir")});var An=$(()=>{"use strict"});import{z as Q}from"zod";function Cn(i,t){let e=i.split(".").map(Number),r=t.split(".").map(Number);for(let n=0;n<3;n++){let s=e[n]??0,o=r[n]??0;if(s<o)return-1;if(s>o)return 1}return 0}var oa,ia,aa,Wt,ca,de=$(()=>{"use strict";oa=Q.enum(["opus","sonnet","haiku"]),ia=Q.enum(["2.5-pro","2.5-flash","2.0-flash"]),aa=Q.string().min(1),Wt=Q.object({provider:Q.string(),model:Q.string(),cliVersion:Q.string().optional(),recordedAt:Q.string()}),ca=Q.object({preferredModel:Q.string().optional(),lastAnalysisModel:Wt.optional()});l(Cn,"compareSemver")});import{exec as fs,execFile as hs}from"node:child_process";import{promisify as Dn}from"node:util";var R,ma,ht=$(()=>{"use strict";R=Dn(fs),ma=Dn(hs)});function Nn(i,t){let e=typeof i=="string"?new Date(i).getTime():i;return Date.now()-e>t}var Xt,me=$(()=>{"use strict";l(Nn,"isExpired");Xt=class{static{l(this,"TTLCache")}cache=new Map;ttl;maxSize;constructor(t={}){this.ttl=t.ttl??5e3,this.maxSize=t.maxSize??50}isValid(t){let e=this.cache.get(t);return e?Date.now()-e.timestamp<this.ttl:!1}get(t){let e=this.cache.get(t);return e?this.isValid(t)?e.data:(this.cache.delete(t),null):null}set(t,e){this.cache.set(t,{data:e,timestamp:Date.now()}),this.evictOldEntries()}delete(t){this.cache.delete(t)}clear(){this.cache.clear()}has(t){return this.cache.has(t)}get size(){return this.cache.size}evictOldEntries(){if(this.cache.size<=this.maxSize)return;let e=Array.from(this.cache.entries()).sort((r,n)=>r[1].timestamp-n[1].timestamp).slice(0,this.cache.size-this.maxSize);for(let[r]of e)this.cache.delete(r)}stats(){return{size:this.cache.size,maxSize:this.maxSize,ttl:this.ttl}}prune(){let t=0;for(let e of this.cache.keys())this.isValid(e)||(this.cache.delete(e),t++);return t}}});import ys from"node:fs/promises";import Ts from"node:os";import In from"node:path";async function On(){try{let i=await ys.readFile(Mn,"utf-8"),t=JSON.parse(i);return!t.timestamp||!t.detection||!t.detection.claude||!t.detection.gemini||!t.detection.codex||Nn(t.timestamp,bs)?null:t.detection}catch{return null}}async function Ln(i){let t={timestamp:new Date().toISOString(),detection:i};await rt(Mn,t)}var ws,Mn,bs,$n=$(()=>{"use strict";me();st();ws=In.join(Ts.homedir(),".prjct-cli","cache"),Mn=In.join(ws,"providers.json"),bs=10*60*1e3;l(On,"readProviderCache");l(Ln,"writeProviderCache")});var Bt={};Lt(Bt,{AntigravityProvider:()=>he,ClaudeProvider:()=>Ht,CodexProvider:()=>ye,CursorProvider:()=>Un,GeminiProvider:()=>fe,Providers:()=>Y,WindsurfProvider:()=>Wn,detectAllProviders:()=>Te,detectAntigravity:()=>Rs,detectCodex:()=>qn,detectCursorProject:()=>Bn,detectProvider:()=>ge,detectWindsurfProject:()=>Gn,getActiveProvider:()=>xs,getCapabilities:()=>ks,getCommandsDir:()=>Ns,getGlobalContextPath:()=>As,getGlobalSettingsPath:()=>Cs,getProjectCommandsPath:()=>Is,getProviderBranding:()=>vs,getSkillsPath:()=>Ds,hasProviderConfig:()=>_s,needsCursorRouterRegeneration:()=>Ps,needsWindsurfRouterRegeneration:()=>js,selectProvider:()=>Ms,validateCliVersion:()=>Hn});import ut from"node:os";import O from"node:path";function ks(i,t){return{...Es[i],...t}}async function Xn(i){try{let{stdout:t}=await R(`which ${i}`,{timeout:2e3});return t.trim()}catch{return null}}async function Ss(i){try{let{stdout:t}=await R(`${i} --version`,{timeout:2e3}),e=t.match(/\d+\.\d+\.\d+/);return e?e[0]:t.trim()}catch{return null}}async function ge(i){let t=Y[i];if(!t.cliCommand)return{installed:!1};let e=await Xn(t.cliCommand);if(!e)return{installed:!1};let r=await Ss(t.cliCommand),n=Hn(i,r||void 0);return{installed:!0,version:r||void 0,path:e,versionWarning:n||void 0}}function Hn(i,t){let e=Y[i];return!e.minCliVersion||!t?null:Cn(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 Te(i=!1){if(!i){let o=await On();if(o)return o}let[t,e,r]=await Promise.all([ge("claude"),ge("gemini"),qn()]),n={installed:r.installed},s={claude:t,gemini:e,codex:n};return await Ln(s).catch(()=>{}),s}async function xs(i){if(i&&Y[i])return Y[i];let t=await Te();return t.claude.installed&&!t.gemini.installed?Ht:t.gemini.installed&&!t.claude.installed?fe:Ht}async function _s(i){let t=Y[i];return t.configDir?N(t.configDir):!1}function vs(i){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"}[i]||"\u26A1 prjct"}}async function Bn(i){let t=O.join(i,".cursor"),e=O.join(t,"rules"),r=O.join(e,"prjct.mdc"),[n,s]=await Promise.all([N(t),N(r)]);return{detected:n,routerInstalled:s,projectRoot:n?i:void 0}}async function Ps(i){let t=await Bn(i);return t.detected&&!t.routerInstalled}async function Gn(i){let t=O.join(i,".windsurf"),e=O.join(t,"rules"),r=O.join(e,"prjct.md"),[n,s]=await Promise.all([N(t),N(r)]);return{detected:n,routerInstalled:s,projectRoot:n?i:void 0}}async function js(i){let t=await Gn(i);return t.detected&&!t.routerInstalled}async function Rs(){let i=he.configDir;if(!i)return{installed:!1,skillInstalled:!1};let t=O.join(i,"skills","prjct","SKILL.md"),[e,r]=await Promise.all([N(i),N(t)]);return{installed:e,skillInstalled:r,configPath:e?i:void 0}}async function qn(){let i=ye.configDir;if(!i)return{installed:!1,skillInstalled:!1};let t=await Xn("codex"),e=O.join(i,"skills","prjct","SKILL.md"),r=await N(e),n=!!t;return{installed:n,skillInstalled:r,configPath:n?i:void 0}}function As(i){let t=Y[i];return t.configDir?O.join(t.configDir,t.contextFile):null}function Cs(i){let t=Y[i];return!t.configDir||!t.settingsFile?null:O.join(t.configDir,t.settingsFile)}function Ds(i){return Y[i].skillsDir}function Ns(i){return Y[i].commandsDir}function Is(i,t){let e=Y[i];return O.join(t,e.commandsDir)}async function Ms(){let i=await Te(),t=i.claude.installed,e=i.gemini.installed;return!t&&!e?{provider:"claude",userSelected:!1,detection:i}:t&&!e?{provider:"claude",userSelected:!1,detection:i}:e&&!t?{provider:"gemini",userSelected:!1,detection:i}:{provider:"claude",userSelected:!0,detection:i}}var Es,Ht,fe,he,Un,Wn,ye,Y,Gt=$(()=>{"use strict";An();de();ht();st();$n();Es={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}};l(ks,"getCapabilities");Ht={name:"claude",displayName:"Claude Code",cliCommand:"claude",configDir:O.join(ut.homedir(),".claude"),contextFile:"CLAUDE.md",skillsDir:O.join(ut.homedir(),".claude","skills"),commandsDir:".claude/commands",commandFormat:"md",settingsFile:"settings.json",projectSettingsFile:"settings.local.json",ignoreFile:".claudeignore",websiteUrl:"https://www.anthropic.com/claude",docsUrl:"https://docs.anthropic.com/claude-code",defaultModel:"sonnet",supportedModels:["opus","sonnet","haiku"],minCliVersion:"1.0.0",capabilityTier:"full"},fe={name:"gemini",displayName:"Gemini CLI",cliCommand:"gemini",configDir:O.join(ut.homedir(),".gemini"),contextFile:"GEMINI.md",skillsDir:O.join(ut.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"},he={name:"antigravity",displayName:"Google Antigravity",cliCommand:null,configDir:O.join(ut.homedir(),".gemini","antigravity"),contextFile:"ANTIGRAVITY.md",skillsDir:O.join(ut.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"},Un={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"},Wn={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"},ye={name:"codex",displayName:"OpenAI Codex",cliCommand:"codex",configDir:O.join(ut.homedir(),".codex"),contextFile:"AGENTS.md",skillsDir:O.join(ut.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"},Y={claude:Ht,gemini:fe,cursor:Un,antigravity:he,windsurf:Wn,codex:ye};l(Xn,"whichCommand");l(Ss,"getCliVersion");l(ge,"detectProvider");l(Hn,"validateCliVersion");l(Te,"detectAllProviders");l(xs,"getActiveProvider");l(_s,"hasProviderConfig");l(vs,"getProviderBranding");l(Bn,"detectCursorProject");l(Ps,"needsCursorRouterRegeneration");l(Gn,"detectWindsurfProject");l(js,"needsWindsurfRouterRegeneration");l(Rs,"detectAntigravity");l(qn,"detectCodex");l(As,"getGlobalContextPath");l(Cs,"getGlobalSettingsPath");l(Ds,"getSkillsPath");l(Ns,"getCommandsDir");l(Is,"getProjectCommandsPath");l(Ms,"selectProvider")});var er,Se=$(()=>{"use strict";er={sunday:0,monday:1,tuesday:2,wednesday:3,thursday:4,friday:5,saturday:6}});import je from"node:fs";import zt from"node:path";function ir(){if(Rt)return Rt;let i=__dirname;for(let t=0;t<5;t++){let e=zt.join(i,"package.json");if(je.existsSync(e))try{if(JSON.parse(je.readFileSync(e,"utf-8")).name==="prjct-cli")return Rt=i,i}catch{}i=zt.dirname(i)}return Rt=zt.join(__dirname,"..","..",".."),Rt}function Re(){if(qt)return qt;try{let i=zt.join(ir(),"package.json"),t=JSON.parse(je.readFileSync(i,"utf-8"));return qt=t.version,to=t,qt}catch(i){return console.error("Failed to read version from package.json:",En(i)),"0.0.0"}}var qt,to,Rt,Ae,Ec,Ce=$(()=>{"use strict";ft();qt=null,to=null,Rt=null;l(ir,"getPackageRoot");l(Re,"getVersion");Ae=Re(),Ec=ir()});var lr={};Lt(lr,{default:()=>oo,worktreeService:()=>ur});import De from"node:fs/promises";import tt from"node:path";var cr,Ne,ur,oo,pr=$(()=>{"use strict";ht();st();cr=".worktrees",Ne=class{static{l(this,"WorktreeService")}async create(t,e,r={}){let n=await this.getMainWorktree(t),s=tt.join(n,cr,e),o=r.branch||`feat/${e}`;await De.mkdir(tt.join(n,cr),{recursive:!0});let a=r.baseBranch?` ${r.baseBranch}`:"";await R(`git worktree add "${s}" -b "${o}"${a}`,{cwd:n});let{stdout:c}=await R("git rev-parse HEAD",{cwd:s});return{path:s,branch:o,commit:c.trim(),isMain:!1,slug:e}}async remove(t,e=!1){let r=await this.getMainWorktree(t),n;if(e)try{let{stdout:s}=await R("git rev-parse --abbrev-ref HEAD",{cwd:t});n=s.trim()}catch{}if(await R(`git worktree remove "${t}" --force`,{cwd:r}),e&&n&&n!=="main"&&n!=="master")try{await R(`git branch -D "${n}"`,{cwd:r})}catch{}}async list(t){let e=await this.getMainWorktree(t),{stdout:r}=await R("git worktree list --porcelain",{cwd:e});return this.parsePorcelainOutput(r,e)}async detect(t){try{let{stdout:e}=await R("git rev-parse --git-common-dir",{cwd:t}),{stdout:r}=await R("git rev-parse --git-dir",{cwd:t}),n=tt.resolve(t,e.trim()),s=tt.resolve(t,r.trim());if(n!==s){let{stdout:o}=await R("git rev-parse --abbrev-ref HEAD",{cwd:t}),{stdout:a}=await R("git rev-parse HEAD",{cwd:t}),{stdout:c}=await R("git rev-parse --show-toplevel",{cwd:t}),u=c.trim(),p=tt.basename(u);return{path:u,branch:o.trim(),commit:a.trim(),isMain:!1,slug:p}}return null}catch{return null}}async getMainWorktree(t){try{let{stdout:r}=await R("git worktree list --porcelain",{cwd:t}),n=r.split(`
10
- `)[0];if(n?.startsWith("worktree "))return n.replace("worktree ","").trim()}catch{}let{stdout:e}=await R("git rev-parse --show-toplevel",{cwd:t});return e.trim()}async setup(t,e){let r=tt.join(e,".env");await N(r)&&await De.copyFile(r,tt.join(t,".env"));let n=tt.join(e,".prjct"),s=tt.join(t,".prjct");await N(n)&&!await N(s)&&await De.symlink(n,s,"dir")}async teardown(t){}async clean(t){let e=await this.list(t),r=[],n=await this.getMainWorktree(t);await R("git worktree prune",{cwd:n});for(let s of e)s.isMain||await N(s.path)||r.push(s.slug);return r}parsePorcelainOutput(t,e){let r=[],n=t.trim().split(`
11
-
12
- `);for(let s of n){if(!s.trim())continue;let o=s.trim().split(`
13
- `),a="",c="",u="",p=!1;for(let d of o)d.startsWith("worktree ")?a=d.replace("worktree ","").trim():d.startsWith("HEAD ")?c=d.replace("HEAD ","").trim():d.startsWith("branch ")?u=d.replace("branch refs/heads/","").trim():d==="bare"?p=!0:d==="detached"&&(u="(detached)");if(a){let d=a===e||p;r.push({path:a,branch:u,commit:c,isMain:d,slug:d?"main":tt.basename(a)})}}return r}},ur=new Ne,oo=ur});var Br={};Lt(Br,{mdActionRequired:()=>hi,mdBadge:()=>si,mdCallout:()=>oi,mdCodeBlock:()=>ri,mdDone:()=>mi,mdError:()=>fi,mdFooter:()=>Wr,mdFrontmatter:()=>Xr,mdHeader:()=>Ur,mdJoin:()=>Hr,mdList:()=>ai,mdNextSteps:()=>pi,mdObsidianNote:()=>ct,mdOutput:()=>ni,mdRelevantFiles:()=>li,mdSection:()=>ii,mdStats:()=>di,mdSubtasks:()=>ui,mdTable:()=>_t,mdTaskHeader:()=>ci,mdWarn:()=>gi});function Ur(){return"---"}function Wr(){return`---
14
- prjct v${Re()}`}function ni(...i){return Hr(Ur(),...i.filter(Boolean),Wr())}function _t(i,t){let e=`| ${i.join(" | ")} |`,r=`|${i.map(()=>"---").join("|")}|`,n=t.map(s=>`| ${s.join(" | ")} |`);return[e,r,...n].join(`
15
- `)}function ri(i,t=""){return`\`\`\`${t}
16
- ${i}
17
- \`\`\``}function si(i,t){return`**${i}**: \`${t}\``}function oi(i,t){return`> **${{success:"OK",warn:"WARNING",error:"ERROR",info:"INFO"}[i]}:** ${t}`}function ii(i,t,e=3){return`### ${i}
18
- ${t}`}function ai(i,t=!1){return i.map((e,r)=>t?`${r+1}. ${e}`:`- ${e}`).join(`
19
- `)}function ci(i){let t=[];i.branch&&t.push(`Branch: \`${i.branch}\``),i.linearId&&t.push(`Linear: \`${i.linearId}\``),i.type&&t.push(`Type: ${i.type}`),i.estimatedPoints&&t.push(`~${i.estimatedPoints}pts`),i.estimatedMinutes&&t.push(`~${i.estimatedMinutes}min`),i.domains&&i.domains.length>0&&t.push(`Domains: ${i.domains.join(", ")}`),i.duration&&t.push(`Duration: ${i.duration}`),i.status&&t.push(`Status: ${i.status}`);let e=t.length>0?`
20
- > ${t.join(" | ")}`:"";return`## ${i.description}${e}`}function ui(i,t){let e=["#","Status","Description"],r=i.map((n,s)=>{let o=String(s+1),a;n.status==="completed"?a="done":s===t?a="current":a="pending";let c=s===t?" **<- current**":"";return[o,a,`${n.description}${c}`]});return`### Subtasks
21
- ${_t(e,r)}`}function li(i){return i.length===0?"":`### Relevant Files
22
- ${i.map(e=>{let r=e.lineRange?`:${e.lineRange}`:"",n=e.description?` \u2014 ${e.description}`:"";return`- \`${e.path}${r}\`${n}`}).join(`
23
- `)}`}function pi(i){let t=["Command","Action"],e=i.map(r=>[`\`${r.command}\``,r.label]);return`### Next
24
- ${_t(t,e)}`}function di(i){let t=Object.entries(i).filter(([,n])=>n!=null);if(t.length===0)return"";let e=["Metric","Value"],r=t.map(([n,s])=>[n,String(s)]);return _t(e,r)}function mi(i,t){return t?`## ${i}
25
- > ${t}`:`## ${i}`}function gi(i){return`> **WARNING:** ${i}`}function fi(i){return`> **ERROR:** ${i}`}function Xr(i){let t=["---"];for(let[e,r]of Object.entries(i))r!=null&&(Array.isArray(r)?t.push(`${e}: [${r.map(n=>String(n)).join(", ")}]`):typeof r=="object"||t.push(`${e}: ${String(r)}`));return t.push("---"),t.join(`
26
- `)}function ct(i,t,...e){return[Xr(i),`# ${t}`,...e.filter(Boolean)].join(`
27
-
28
- `)}function Hr(...i){return i.filter(Boolean).join(`
29
-
30
- `)}function hi(i,t,e,r){let n=t.replace(/_/g," "),s=[`> **${i}**: ${n}`];if(r)for(let[o,a]of Object.entries(r))s.push(`> ${o}: ${a}`);if(e.length>0){s.push("");for(let o of e)s.push(`- ${o.label}: \`${o.command}\``)}console.log(s.join(`
31
- `))}var tn=$(()=>{"use strict";Ce();l(Ur,"mdHeader");l(Wr,"mdFooter");l(ni,"mdOutput");l(_t,"mdTable");l(ri,"mdCodeBlock");l(si,"mdBadge");l(oi,"mdCallout");l(ii,"mdSection");l(ai,"mdList");l(ci,"mdTaskHeader");l(ui,"mdSubtasks");l(li,"mdRelevantFiles");l(pi,"mdNextSteps");l(di,"mdStats");l(mi,"mdDone");l(gi,"mdWarn");l(fi,"mdError");l(Xr,"mdFrontmatter");l(ct,"mdObsidianNote");l(Hr,"mdJoin");l(hi,"mdActionRequired")});import{z as P}from"zod";var yi,Ti,Vr,td,ed,nd,mt,nn=$(()=>{"use strict";yi=P.enum(["improving","stable","declining"]),Ti=P.object({sprintNumber:P.number(),startDate:P.string(),endDate:P.string(),pointsCompleted:P.number(),tasksCompleted:P.number(),avgVariance:P.number(),estimationAccuracy:P.number()}),Vr=P.object({category:P.string(),avgVariance:P.number(),taskCount:P.number()}),td=P.object({totalPoints:P.number(),sprints:P.number(),estimatedDate:P.string()}),ed=P.object({sprints:P.array(Ti),averageVelocity:P.number(),velocityTrend:yi,estimationAccuracy:P.number(),overEstimated:P.array(Vr),underEstimated:P.array(Vr),lastUpdated:P.string()}),nd=P.object({sprintLengthDays:P.number().min(1).max(90).default(7),startDay:P.enum(["monday","tuesday","wednesday","thursday","friday","saturday","sunday"]).default("monday"),windowSize:P.number().min(1).max(52).default(6),accuracyTolerance:P.number().min(0).max(100).default(20)}),mt={sprintLengthDays:7,startDay:"monday",windowSize:6,accuracyTolerance:20}});var Qr={};Lt(Qr,{calculateVelocity:()=>It,detectTrend:()=>Kr,formatVelocityContext:()=>sn,getSprintEnd:()=>Jr,getSprintStart:()=>se,parseDurationMinutes:()=>gt,projectCompletion:()=>bi});function se(i,t){let e=Mt(t),r=er[e.startDay],n=new Date(i);n.setHours(0,0,0,0);let o=(n.getDay()-r+7)%7;return n.setDate(n.getDate()-o),n}function Jr(i,t){let e=Mt(t),r=new Date(i);return r.setDate(r.getDate()+e.sprintLengthDays-1),r.setHours(23,59,59,999),r}function wi(i,t,e){let r=Mt(e),n=se(i,e),s=se(t,e),o=n.getTime()-s.getTime(),a=Math.round(o/(1e3*60*60*24));return Math.floor(a/r.sprintLengthDays)+1}function It(i,t=mt){let e=Mt(t);if(i.length===0)return{sprints:[],averageVelocity:0,velocityTrend:"stable",estimationAccuracy:0,overEstimated:[],underEstimated:[],lastUpdated:new Date().toISOString()};let r=Ei(i,t),n=ki(r,e.accuracyTolerance),s=n.slice(-e.windowSize),o=xi(s),a=Kr(s),c=Si(i,e.accuracyTolerance),{overEstimated:u,underEstimated:p}=_i(i);return{sprints:n,averageVelocity:o,velocityTrend:a,estimationAccuracy:c,overEstimated:u,underEstimated:p,lastUpdated:new Date().toISOString()}}function bi(i,t,e=mt){let r=Mt(e);if(t<=0)return{totalPoints:i,sprints:0,estimatedDate:""};let n=Math.ceil(i/t),s=n*r.sprintLengthDays,o=new Date;return o.setDate(o.getDate()+s),{totalPoints:i,sprints:n,estimatedDate:o.toISOString()}}function Ei(i,t){let e=new Map,r=i.map(s=>new Date(s.completedAt)),n=new Date(Math.min(...r.map(s=>s.getTime())));for(let s of i){let o=new Date(s.completedAt),a=wi(o,n,t);if(!e.has(a)){let c=se(o,t),u=Jr(c,t);e.set(a,{sprintNumber:a,startDate:c,endDate:u,outcomes:[]})}e.get(a).outcomes.push(s)}return e}function ki(i,t){let e=[];for(let[,r]of i){let n=r.outcomes.reduce((u,p)=>u+vi(p),0),s=r.outcomes.filter(u=>u.variance).map(u=>rn(u)),o=s.length>0?Math.round(s.reduce((u,p)=>u+p,0)/s.length):0,a=s.filter(u=>Math.abs(u)<=t).length,c=s.length>0?Math.round(a/s.length*100):0;e.push({sprintNumber:r.sprintNumber,startDate:r.startDate.toISOString(),endDate:r.endDate.toISOString(),pointsCompleted:n,tasksCompleted:r.outcomes.length,avgVariance:o,estimationAccuracy:c})}return e.sort((r,n)=>r.sprintNumber-n.sprintNumber)}function Kr(i){if(i.length<3)return"stable";let t=i.map(p=>p.pointsCompleted),e=t.length,r=0,n=0,s=0,o=0;for(let p=0;p<e;p++)r+=p,n+=t[p],s+=p*t[p],o+=p*p;let a=(e*s-r*n)/(e*o-r*r),c=n/e;if(c===0)return"stable";let u=a/c;return u>.1?"improving":u<-.1?"declining":"stable"}function Si(i,t){let e=i.filter(n=>n.variance);if(e.length===0)return 0;let r=e.filter(n=>{let s=rn(n);return Math.abs(s)<=t});return Math.round(r.length/e.length*100)}function xi(i){if(i.length===0)return 0;let t=i.reduce((e,r)=>e+r.pointsCompleted,0);return Math.round(t/i.length*10)/10}function _i(i){let t=new Map;for(let n of i){if(!n.variance)continue;let s=rn(n),o=n.tags&&n.tags.length>0?n.tags:["uncategorized"];for(let a of o){t.has(a)||t.set(a,{variances:[],count:0});let c=t.get(a);c.variances.push(s),c.count++}}let e=[],r=[];for(let[n,s]of t){if(s.count<2)continue;let o=Math.round(s.variances.reduce((a,c)=>a+c,0)/s.variances.length);o>10?r.push({category:n,avgVariance:o,taskCount:s.count}):o<-10&&e.push({category:n,avgVariance:Math.abs(o),taskCount:s.count})}return e.sort((n,s)=>s.avgVariance-n.avgVariance),r.sort((n,s)=>s.avgVariance-n.avgVariance),{overEstimated:e,underEstimated:r}}function rn(i){if(!i.variance)return 0;let t=gt(i.estimatedDuration),e=gt(i.actualDuration);return t<=0?0:Math.round((e-t)/t*100)}function sn(i){if(i.sprints.length===0)return"No velocity data available yet.";let t=[];t.push(`Project velocity: ${i.averageVelocity} pts/sprint (trend: ${i.velocityTrend})`),t.push(`Estimation accuracy: ${i.estimationAccuracy}%`);for(let e of i.underEstimated)t.push(`\u26A0 "${e.category}" tasks historically take ${e.avgVariance}% longer than estimated`);for(let e of i.overEstimated)t.push(`"${e.category}" tasks typically finish ${e.avgVariance}% faster than estimated`);return t.join(`
32
- `)}function vi(i){if(!i.estimatedDuration)return 0;let t=gt(i.estimatedDuration);if(t<=0)return 0;let e=Yr[0],r=Number.POSITIVE_INFINITY;for(let n of Yr){let s=Math.abs(n.typical-t);s<r&&(r=s,e=n)}return e.points}function Mt(i){return{sprintLengthDays:i.sprintLengthDays??7,startDay:i.startDay??"monday",windowSize:i.windowSize??6,accuracyTolerance:i.accuracyTolerance??20}}var Yr,on=$(()=>{"use strict";Se();nn();W();l(se,"getSprintStart");l(Jr,"getSprintEnd");l(wi,"getSprintNumber");l(It,"calculateVelocity");l(bi,"projectCompletion");l(Ei,"bucketBySprint");l(ki,"buildSprintVelocities");l(Kr,"detectTrend");l(Si,"calculateOverallAccuracy");l(xi,"calculateAverageVelocity");l(_i,"detectEstimationPatterns");l(rn,"parseVariancePercent");l(sn,"formatVelocityContext");Yr=[{points:1,typical:10},{points:2,typical:20},{points:3,typical:45},{points:5,typical:90},{points:8,typical:180},{points:13,typical:360},{points:21,typical:720}];l(vi,"derivePoints");l(Mt,"resolveConfig")});import{StdioServerTransport as $i}from"@modelcontextprotocol/sdk/server/stdio.js";import{McpServer as Oi}from"@modelcontextprotocol/sdk/server/mcp.js";import{z as B}from"zod";ce();import Yn from"node:fs/promises";import bt from"node:path";import Ee from"node:fs";import Vn from"node:path";W();st();import Os from"node:crypto";import Z from"node:fs/promises";import we from"node:os";import S from"node:path";import{globSync as Ls}from"glob";var be=class{static{l(this,"PathManager")}globalBaseDir;globalProjectsDir;globalConfigDir;constructor(){let t=process.env.PRJCT_CLI_HOME?.trim();this.globalBaseDir=t?S.resolve(t):S.join(we.homedir(),".prjct-cli"),this.globalProjectsDir=S.join(this.globalBaseDir,"projects"),this.globalConfigDir=S.join(this.globalBaseDir,"config")}setGlobalBaseDir(t){this.globalBaseDir=S.resolve(t),this.globalProjectsDir=S.join(this.globalBaseDir,"projects"),this.globalConfigDir=S.join(this.globalBaseDir,"config")}generateProjectId(t){return Os.randomUUID()}getGlobalBasePath(){return this.globalBaseDir}getGlobalProjectPath(t){return S.join(this.globalProjectsDir,t)}getLocalConfigPath(t){return S.join(t,".prjct","prjct.config.json")}getGlobalProjectConfigPath(t){return S.join(this.getGlobalProjectPath(t),"project.json")}getLegacyPrjctPath(t){return S.join(t,".prjct")}async hasLegacyStructure(t){let e=this.getLegacyPrjctPath(t);return await le(e)}async hasConfig(t){let e=this.getLocalConfigPath(t);return await N(e)}async ensureGlobalStructure(){await K(this.globalBaseDir),await K(this.globalProjectsDir),await K(this.globalConfigDir)}async ensureProjectStructure(t){await this.ensureGlobalStructure();let e=this.getGlobalProjectPath(t),r=["core","progress","planning","analysis","memory"];for(let n of r)await K(S.join(e,n));return await K(S.join(e,"planning","tasks")),await K(S.join(e,"sessions")),e}getSessionPath(t,e=new Date){let{year:r,month:n,day:s}=wn(e);return S.join(this.getGlobalProjectPath(t),"sessions",r,n,s)}getCurrentSessionPath(t){return this.getSessionPath(t,new Date)}async ensureSessionPath(t,e=new Date){let r=this.getSessionPath(t,e);return await K(r),r}async listSessions(t,e=null,r=null){let n=S.join(this.getGlobalProjectPath(t),"sessions"),s=[];try{let o=await Z.readdir(n,{withFileTypes:!0});for(let a of o){if(!a.isDirectory()||e&&a.name!==e.toString())continue;let c=S.join(n,a.name),u=await Z.readdir(c,{withFileTypes:!0});for(let p of u){if(!p.isDirectory()||r&&p.name!==r.toString().padStart(2,"0"))continue;let d=S.join(c,p.name),g=await Z.readdir(d,{withFileTypes:!0});for(let h of g)h.isDirectory()&&s.push({year:a.name,month:p.name,day:h.name,path:S.join(d,h.name),date:new Date(`${a.name}-${p.name}-${h.name}`)})}}return s.sort((a,c)=>c.date.getTime()-a.date.getTime()),s}catch{return[]}}async getSessionsInRange(t,e,r=new Date){return(await this.listSessions(t)).filter(s=>s.date>=e&&s.date<=r)}getFilePath(t,e,r){return S.join(this.getGlobalProjectPath(t),e,r)}async listProjects(){try{return await this.ensureGlobalStructure(),(await Z.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 le(e)}getDisplayPath(t){let e=we.homedir();return t.startsWith(e)?t.replace(e,"~"):t}getAuthConfigPath(){return S.join(this.globalConfigDir,"auth.json")}getSyncPendingPath(t){return S.join(this.getGlobalProjectPath(t),"sync","pending.json")}getLastSyncPath(t){return S.join(this.getGlobalProjectPath(t),"sync","last-sync.json")}getRunningStatusPath(){return S.join(this.globalBaseDir,".running")}getDocsPath(){return S.join(this.globalBaseDir,"docs")}async getAgentDir(){return(await(Gt(),ae(Bt)).getActiveProvider()).configDir}async getAgentSettingsPath(){let t=await(Gt(),ae(Bt)).getActiveProvider();return(Gt(),ae(Bt)).getGlobalSettingsPath(t.name)}getClaudeDir(){return S.join(we.homedir(),".claude")}getClaudeSettingsPath(){return S.join(this.getClaudeDir(),"settings.json")}getStoragePath(t,e){return S.join(this.getGlobalProjectPath(t),"storage",e)}getContextPath(t){return S.join(this.getGlobalProjectPath(t),"context")}async 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 n of r){let s=S.join(t,n.file);if(await N(s)){e.isMonorepo=!0,e.type=n.type;break}}if(!e.isMonorepo){let n=S.join(t,"package.json");if(await N(n))try{let s=await Z.readFile(n,"utf-8");JSON.parse(s).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=[],n=[];try{if(e==="pnpm"){let o=(await Z.readFile(S.join(t,"pnpm-workspace.yaml"),"utf-8")).match(/packages:\s*\n((?:\s*-\s*.+\n?)+)/);o&&(n=o[1].split(`
33
- `).map(a=>a.replace(/^\s*-\s*['"]?|['"]?\s*$/g,"")).filter(Boolean))}else if(e==="npm"||e==="lerna"){let s=S.join(t,"package.json"),o=await Z.readFile(s,"utf-8"),a=JSON.parse(o);if(Array.isArray(a.workspaces)?n=a.workspaces:a.workspaces?.packages&&(n=a.workspaces.packages),e==="lerna"){let c=S.join(t,"lerna.json");if(await N(c)){let u=await Z.readFile(c,"utf-8"),p=JSON.parse(u);p.packages&&(n=p.packages)}}}else if(e==="nx")n=["apps/*","libs/*","packages/*"];else if(e==="turborepo"){let s=S.join(t,"package.json"),o=await Z.readFile(s,"utf-8"),a=JSON.parse(o);Array.isArray(a.workspaces)&&(n=a.workspaces)}n.length===0&&(n=["packages/*","apps/*","libs/*"]);for(let s of n){if(s.startsWith("!"))continue;let o=Ls(s,{cwd:t,absolute:!1});for(let a of o){let c=S.join(t,a),u=S.join(c,"package.json");if(await N(u))try{let p=await Z.readFile(u,"utf-8"),d=JSON.parse(p),g=S.join(c,"PRJCT.md");r.push({name:d.name||S.basename(a),path:c,relativePath:a,hasPrjctMd:await N(g)})}catch{}}}}catch{}return r}async findContainingPackage(t,e){if(!e.isMonorepo)return null;let r=S.resolve(t);for(let n of e.packages){let s=S.resolve(n.path);if(r.startsWith(s))return n}return null}async findMonorepoRoot(t){let e=S.resolve(t),r=S.parse(e).root;for(;e!==r;){if((await this.detectMonorepo(e)).isMonorepo)return e;e=S.dirname(e)}return null}},$s=new be,A=$s;function Fs(){return typeof globalThis<"u"&&"Bun"in globalThis?"bun":"node"}l(Fs,"detectRuntime");function zn(){return Fs()==="bun"}l(zn,"isBun");function Us(i){if(zn()){let{Database:n}=fn("bun:sqlite");return new n(i,{create:!0})}let t=fn("better-sqlite3"),e=new t(i),r=e.exec.bind(e);return e.run=n=>r(n),e}l(Us,"openDatabase");var Ws=[{version:1,name:"initial-schema",up:l(i=>{i.run(`
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 j(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(j,"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 Me(n){let t={timestamp:new Date().toISOString(),detection:n};await j(Le,t)}var es,Le,rs,je=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(Me,"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 Me(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();je();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(`
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
+
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 jn}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 jt 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 Mt=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 Mt,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(`
34
14
  -- =======================================================================
35
15
  -- Document storage (backward-compatible with JSON file pattern)
36
16
  -- =======================================================================
@@ -244,7 +224,7 @@ ${_t(t,e)}`}function di(i){let t=Object.entries(i).filter(([,n])=>n!=null);if(t.
244
224
  started_at TEXT,
245
225
  ended_at TEXT
246
226
  );
247
- `)},"up")},{version:2,name:"archives-table",up:l(i=>{i.run(`
227
+ `)},"up")},{version:2,name:"archives-table",up:c(n=>{n.run(`
248
228
  -- =======================================================================
249
229
  -- Archives: Stale data moved out of active storage (PRJ-267)
250
230
  -- =======================================================================
@@ -261,7 +241,7 @@ ${_t(t,e)}`}function di(i){let t=Object.entries(i).filter(([,n])=>n!=null);if(t.
261
241
  CREATE INDEX idx_archives_entity_type ON archives(entity_type);
262
242
  CREATE INDEX idx_archives_archived_at ON archives(archived_at);
263
243
  CREATE INDEX idx_archives_entity_id ON archives(entity_id);
264
- `)},"up")},{version:3,name:"workflow-rules-table",up:l(i=>{i.run(`
244
+ `)},"up")},{version:3,name:"workflow-rules-table",up:c(n=>{n.run(`
265
245
  -- =======================================================================
266
246
  -- Workflow Rules: hooks, gates, and custom steps (Phase 2)
267
247
  -- =======================================================================
@@ -279,7 +259,7 @@ ${_t(t,e)}`}function di(i){let t=Object.entries(i).filter(([,n])=>n!=null);if(t.
279
259
  );
280
260
 
281
261
  CREATE INDEX idx_workflow_rules_command ON workflow_rules(command);
282
- `)},"up")},{version:4,name:"custom-workflows-table",up:l(i=>{i.run(`
262
+ `)},"up")},{version:4,name:"custom-workflows-table",up:c(n=>{n.run(`
283
263
  -- =======================================================================
284
264
  -- Custom Workflows: User-defined workflows with agentic auto-config
285
265
  -- =======================================================================
@@ -304,7 +284,7 @@ ${_t(t,e)}`}function di(i){let t=Object.entries(i).filter(([,n])=>n!=null);if(t.
304
284
  ('done', 'Complete current task/subtask', 1, 1, datetime('now'), datetime('now')),
305
285
  ('ship', 'Ship feature with version bump and PR', 1, 1, datetime('now'), datetime('now')),
306
286
  ('sync', 'Analyze project and regenerate context', 1, 1, datetime('now'), datetime('now'));
307
- `)},"up")},{version:5,name:"llm-analysis-table",up:l(i=>{i.run(`
287
+ `)},"up")},{version:5,name:"llm-analysis-table",up:c(n=>{n.run(`
308
288
  -- =======================================================================
309
289
  -- LLM Analysis: Structured findings from hybrid sync pipeline
310
290
  -- Pipeline: CLI (collect) \u2192 LLM (analyze) \u2192 CLI (store)
@@ -320,7 +300,7 @@ ${_t(t,e)}`}function di(i){let t=Object.entries(i).filter(([,n])=>n!=null);if(t.
320
300
 
321
301
  CREATE INDEX idx_llm_analysis_status ON llm_analysis(status);
322
302
  CREATE INDEX idx_llm_analysis_commit ON llm_analysis(commit_hash);
323
- `)},"up")},{version:6,name:"context-feedback-table",up:l(i=>{i.run(`
303
+ `)},"up")},{version:6,name:"context-feedback-table",up:c(n=>{n.run(`
324
304
  -- =======================================================================
325
305
  -- Context Feedback: RL loop for file suggestion improvement
326
306
  -- Records suggested vs actual files per task for scoring boosts
@@ -338,7 +318,7 @@ ${_t(t,e)}`}function di(i){let t=Object.entries(i).filter(([,n])=>n!=null);if(t.
338
318
  );
339
319
 
340
320
  CREATE INDEX idx_cf_task ON context_feedback(task_id);
341
- `)},"up")},{version:7,name:"sessions-table",up:l(i=>{i.run(`
321
+ `)},"up")},{version:7,name:"sessions-table",up:c(n=>{n.run(`
342
322
  -- =======================================================================
343
323
  -- Sessions: Task lifecycle tracking (replaces current.json + archive/)
344
324
  -- =======================================================================
@@ -358,13 +338,13 @@ ${_t(t,e)}`}function di(i){let t=Object.entries(i).filter(([,n])=>n!=null);if(t.
358
338
  CREATE INDEX idx_sessions_project ON sessions(project_id);
359
339
  CREATE INDEX idx_sessions_status ON sessions(status);
360
340
  CREATE INDEX idx_sessions_completed ON sessions(completed_at);
361
- `)},"up")},{version:8,name:"task-token-tracking",up:l(i=>{i.run(`
341
+ `)},"up")},{version:8,name:"task-token-tracking",up:c(n=>{n.run(`
362
342
  -- =======================================================================
363
343
  -- Token usage tracking per task (input + output)
364
344
  -- =======================================================================
365
345
  ALTER TABLE tasks ADD COLUMN tokens_in INTEGER DEFAULT 0;
366
346
  ALTER TABLE tasks ADD COLUMN tokens_out INTEGER DEFAULT 0;
367
- `)},"up")},{version:9,name:"context-health-tables",up:l(i=>{i.run(`
347
+ `)},"up")},{version:9,name:"context-health-tables",up:c(n=>{n.run(`
368
348
  -- =======================================================================
369
349
  -- Context Zone Events: Track zone transitions for health analytics
370
350
  -- =======================================================================
@@ -394,7 +374,7 @@ ${_t(t,e)}`}function di(i){let t=Object.entries(i).filter(([,n])=>n!=null);if(t.
394
374
  );
395
375
 
396
376
  CREATE INDEX idx_cc_project ON context_compactions(project_id);
397
- `)},"up")},{version:10,name:"fts5-memories",up:l(i=>{i.run(`
377
+ `)},"up")},{version:10,name:"fts5-memories",up:c(n=>{n.run(`
398
378
  -- =======================================================================
399
379
  -- Memories: Tagged, searchable memory store (replaces memories.json)
400
380
  -- =======================================================================
@@ -443,11 +423,11 @@ ${_t(t,e)}`}function di(i){let t=Object.entries(i).filter(([,n])=>n!=null);if(t.
443
423
  INSERT INTO memories_fts(rowid, title, content, tags)
444
424
  VALUES (NEW.rowid, NEW.title, NEW.content, NEW.tags);
445
425
  END;
446
- `);try{let t=i.prepare("SELECT data FROM kv_store WHERE key = 'memory:memories'").get();if(t){let e=JSON.parse(t.data);if(e.memories&&e.memories.length>0){let r=i.prepare(`
426
+ `);try{let t=n.prepare("SELECT data FROM kv_store WHERE key = 'memory:memories'").get();if(t){let e=JSON.parse(t.data);if(e.memories&&e.memories.length>0){let r=n.prepare(`
447
427
  INSERT OR IGNORE INTO memories
448
428
  (id, project_id, title, content, tags, content_hash, user_triggered, confidence, observation_count, created_at, updated_at)
449
429
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
450
- `);for(let n of e.memories)r.run(n.id,"_migrated",n.title,n.content,(n.tags||[]).join(","),null,n.userTriggered?1:0,n.confidence??null,n.observationCount??0,n.createdAt,n.updatedAt)}}}catch{}},"up")},{version:11,name:"agent-sessions",up:l(i=>{i.run(`
430
+ `);for(let s of e.memories)r.run(s.id,"_migrated",s.title,s.content,(s.tags||[]).join(","),null,s.userTriggered?1:0,s.confidence??null,s.observationCount??0,s.createdAt,s.updatedAt)}}}catch{}},"up")},{version:11,name:"agent-sessions",up:c(n=>{n.run(`
451
431
  -- =======================================================================
452
432
  -- Agent Sessions: Track AI agent work sessions across compactions
453
433
  -- =======================================================================
@@ -480,7 +460,7 @@ ${_t(t,e)}`}function di(i){let t=Object.entries(i).filter(([,n])=>n!=null);if(t.
480
460
 
481
461
  CREATE INDEX IF NOT EXISTS idx_user_prompts_project ON user_prompts(project_id);
482
462
  CREATE INDEX IF NOT EXISTS idx_user_prompts_session ON user_prompts(session_id);
483
- `);try{i.run("ALTER TABLE memories ADD COLUMN session_id TEXT")}catch{}},"up")},{version:12,name:"task-body-and-comments",up:l(i=>{try{i.run("ALTER TABLE queue_tasks ADD COLUMN body TEXT")}catch{}i.run(`
463
+ `);try{n.run("ALTER TABLE memories ADD COLUMN session_id TEXT")}catch{}},"up")},{version:12,name:"task-body-and-comments",up:c(n=>{try{n.run("ALTER TABLE queue_tasks ADD COLUMN body TEXT")}catch{}n.run(`
484
464
  CREATE TABLE IF NOT EXISTS queue_task_comments (
485
465
  id TEXT PRIMARY KEY,
486
466
  task_id TEXT NOT NULL,
@@ -491,332 +471,88 @@ ${_t(t,e)}`}function di(i){let t=Object.entries(i).filter(([,n])=>n!=null);if(t.
491
471
  );
492
472
 
493
473
  CREATE INDEX IF NOT EXISTS idx_qtc_task_id ON queue_task_comments(task_id);
494
- `)},"up")}],Xs=3,ke=class{static{l(this,"PrjctDatabase")}connections=new Map;accessOrder=[];getDbPath(t){return Vn.join(A.getGlobalProjectPath(t),"prjct.db")}getDb(t){let e=this.connections.get(t);if(e)return this.touchAccessOrder(t),e;this.connections.size>=Xs&&this.evictLru();let r=this.getDbPath(t),n=Vn.dirname(r);Ee.existsSync(n)||Ee.mkdirSync(n,{recursive:!0});let s=Us(r);return s.run("PRAGMA journal_mode = WAL"),s.run("PRAGMA synchronous = NORMAL"),s.run("PRAGMA cache_size = -2000"),s.run("PRAGMA temp_store = MEMORY"),s.run("PRAGMA mmap_size = 33554432"),this.runMigrations(s),this.connections.set(t,s),this.touchAccessOrder(t),s}close(t){if(t){let e=this.connections.get(t);e&&(e.close(),this.connections.delete(t),this.accessOrder=this.accessOrder.filter(r=>r!==t))}else this.connections.forEach(e=>{e.close()}),this.connections.clear(),this.accessOrder=[]}touchAccessOrder(t){this.accessOrder=this.accessOrder.filter(e=>e!==t),this.accessOrder.push(t)}evictLru(){if(this.accessOrder.length===0)return;let t=this.accessOrder.shift(),e=this.connections.get(t);e&&(e.close(),this.connections.delete(t))}checkpointAll(){for(let[t,e]of this.connections)try{e.run("PRAGMA wal_checkpoint(TRUNCATE)")}catch{}}exists(t){return Ee.existsSync(this.getDbPath(t))}getDoc(t,e){let n=this.getDb(t).prepare("SELECT data FROM kv_store WHERE key = ?").get(e);return n?JSON.parse(n.data):null}setDoc(t,e,r){let n=this.getDb(t),s=JSON.stringify(r),o=new Date().toISOString();n.prepare("INSERT OR REPLACE INTO kv_store (key, data, updated_at) VALUES (?, ?, ?)").run(e,s,o)}deleteDoc(t,e){this.getDb(t).prepare("DELETE FROM kv_store WHERE key = ?").run(e)}hasDoc(t,e){return this.getDb(t).prepare("SELECT 1 FROM kv_store WHERE key = ?").get(e)!==null}appendEvent(t,e,r,n){let s=this.getDb(t),o=new Date().toISOString();s.prepare("INSERT INTO events (type, task_id, data, timestamp) VALUES (?, ?, ?, ?)").run(e,n??null,JSON.stringify(r),o)}getEvents(t,e,r=100){let n=this.getDb(t);return e?n.prepare("SELECT * FROM events WHERE type = ? ORDER BY id DESC LIMIT ?").all(e,r):n.prepare("SELECT * FROM events ORDER BY id DESC LIMIT ?").all(r)}query(t,e,...r){return this.getDb(t).prepare(e).all(...r)}run(t,e,...r){this.getDb(t).prepare(e).run(...r)}get(t,e,...r){return this.getDb(t).prepare(e).get(...r)??null}transaction(t,e){let r=this.getDb(t);return r.transaction(e)(r)}runMigrations(t){t.run(`
474
+ `)},"up")},{version:13,name:"workflow-rules-v2",up:c(n=>{try{n.run("ALTER TABLE workflow_rules ADD COLUMN when_expr TEXT")}catch{}try{n.run("ALTER TABLE workflow_rules ADD COLUMN parallel INTEGER NOT NULL DEFAULT 1")}catch{}n.run(`
475
+ CREATE TABLE IF NOT EXISTS workflow_rule_cache (
476
+ rule_id INTEGER NOT NULL,
477
+ context_hash TEXT NOT NULL,
478
+ ran_at TEXT NOT NULL,
479
+ ttl_ms INTEGER NOT NULL DEFAULT 3600000,
480
+ PRIMARY KEY (rule_id, context_hash)
481
+ );
482
+
483
+ CREATE INDEX IF NOT EXISTS idx_wrc_rule ON workflow_rule_cache(rule_id);
484
+ `)},"up")},{version:14,name:"workflow-rules-trust-source",up:c(n=>{try{n.run("ALTER TABLE workflow_rules ADD COLUMN trust_source TEXT NOT NULL DEFAULT 'local'")}catch{}},"up")}],xs=3,Ft=class{static{c(this,"PrjctDatabase")}connections=new Map;accessOrder=[];getDbPath(t){return ze.join(b.getGlobalProjectPath(t),"prjct.db")}getDb(t){let e=this.connections.get(t);if(e)return this.touchAccessOrder(t),e;this.connections.size>=xs&&this.evictLru();let r=this.getDbPath(t),s=ze.dirname(r);jt.existsSync(s)||jt.mkdirSync(s,{recursive:!0});let o=bs(r);return o.run("PRAGMA journal_mode = WAL"),o.run("PRAGMA synchronous = NORMAL"),o.run("PRAGMA cache_size = -2000"),o.run("PRAGMA temp_store = MEMORY"),o.run("PRAGMA mmap_size = 33554432"),this.runMigrations(o),this.connections.set(t,o),this.touchAccessOrder(t),o}close(t){if(t){let e=this.connections.get(t);e&&(e.close(),this.connections.delete(t),this.accessOrder=this.accessOrder.filter(r=>r!==t))}else this.connections.forEach(e=>{e.close()}),this.connections.clear(),this.accessOrder=[]}touchAccessOrder(t){this.accessOrder=this.accessOrder.filter(e=>e!==t),this.accessOrder.push(t)}evictLru(){if(this.accessOrder.length===0)return;let t=this.accessOrder.shift(),e=this.connections.get(t);e&&(e.close(),this.connections.delete(t))}checkpointAll(){for(let[t,e]of this.connections)try{e.run("PRAGMA wal_checkpoint(TRUNCATE)")}catch{}}exists(t){return jt.existsSync(this.getDbPath(t))}getDoc(t,e){let s=this.getDb(t).prepare("SELECT data FROM kv_store WHERE key = ?").get(e);return s?JSON.parse(s.data):null}setDoc(t,e,r){let s=this.getDb(t),o=JSON.stringify(r),i=new Date().toISOString();s.prepare("INSERT OR REPLACE INTO kv_store (key, data, updated_at) VALUES (?, ?, ?)").run(e,o,i)}deleteDoc(t,e){this.getDb(t).prepare("DELETE FROM kv_store WHERE key = ?").run(e)}hasDoc(t,e){return this.getDb(t).prepare("SELECT 1 FROM kv_store WHERE key = ?").get(e)!==null}appendEvent(t,e,r,s){let o=this.getDb(t),i=new Date().toISOString();o.prepare("INSERT INTO events (type, task_id, data, timestamp) VALUES (?, ?, ?, ?)").run(e,s??null,JSON.stringify(r),i)}getEvents(t,e,r=100){let s=this.getDb(t);return e?s.prepare("SELECT * FROM events WHERE type = ? ORDER BY id DESC LIMIT ?").all(e,r):s.prepare("SELECT * FROM events ORDER BY id DESC LIMIT ?").all(r)}query(t,e,...r){return this.getDb(t).prepare(e).all(...r)}run(t,e,...r){this.getDb(t).prepare(e).run(...r)}get(t,e,...r){return this.getDb(t).prepare(e).get(...r)??null}transaction(t,e){let r=this.getDb(t);return r.transaction(e)(r)}runMigrations(t){t.run(`
495
485
  CREATE TABLE IF NOT EXISTS _migrations (
496
486
  version INTEGER PRIMARY KEY,
497
487
  name TEXT NOT NULL,
498
488
  applied_at TEXT NOT NULL
499
489
  )
500
- `);let e=new Set(t.prepare("SELECT version FROM _migrations").all().map(r=>r.version));for(let r of Ws)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}},_=new ke,T=_;st();function Hs(i){let t=[],e,r=new RegExp(Tn.source,"g");for(;(e=r.exec(i))!==null;){let n=e[1];(n.startsWith(".")||n.startsWith("@/"))&&t.push(n)}return t}l(Hs,"extractImportSources");async function Bs(i,t,e){let r;if(i.startsWith("@/"))r=bt.join(e,"src",i.slice(2));else{let n=bt.dirname(bt.join(e,t));r=bt.resolve(n,i)}for(let n of yn){let s=r+n;try{if((await Yn.stat(s)).isFile())return bt.relative(e,s)}catch{}}return null}l(Bs,"resolveImport");async function Gs(i){let t=await Pn(i),e={},r={},n=0,s=await jn(t,50,async o=>{try{let a=await Yn.readFile(bt.join(i,o),"utf-8"),c=Hs(a),u=[];for(let p of c){let d=await Bs(p,o,i);d&&d!==o&&u.push(d)}return u.length>0?{filePath:o,imports:u}:null}catch{return null}});for(let{filePath:o,imports:a}of s){e[o]=a,n+=a.length;for(let c of a)r[c]||(r[c]=[]),r[c].push(o)}return{forward:e,reverse:r,fileCount:t.length,edgeCount:n,builtAt:new Date().toISOString()}}l(Gs,"buildGraph");function Jn(i,t,e=2){let r=new Set(i),n=new Map,s=[];for(let o of i){let a=t.forward[o]||[],c=t.reverse[o]||[];for(let u of[...a,...c])r.has(u)||s.push({file:u,depth:1})}for(;s.length>0;){let{file:o,depth:a}=s.shift();if(a>e)continue;let c=1/(a+1),u=n.get(o);if(u){c>u.score&&n.set(o,{score:c,depth:a});continue}if(n.set(o,{score:c,depth:a}),a<e){let p=t.forward[o]||[],d=t.reverse[o]||[];for(let g of[...p,...d])!r.has(g)&&!n.has(g)&&s.push({file:g,depth:a+1})}}return Array.from(n.entries()).map(([o,{score:a,depth:c}])=>({path:o,score:a,depth:c})).sort((o,a)=>a.score-o.score)}l(Jn,"scoreFromSeeds");var Kn="import-graph";function qs(i,t){T.setDoc(i,Kn,t)}l(qs,"saveGraph");function jt(i){return T.getDoc(i,Kn)}l(jt,"loadGraph");async function Qn(i,t){let e=await Gs(i);return qs(t,e),e}l(Qn,"indexImports");function Zn(i,t){let e=[...i.added,...i.modified],r=new Set(e),n=new Set,s=jt(t);if(s)for(let c of e){let u=s.reverse[c];if(u)for(let p of u)r.has(p)||n.add(p)}let o=Array.from(n),a=[...e,...o];return{directlyChanged:e,affectedByImports:o,deleted:i.deleted,allAffected:a}}l(Zn,"propagateChanges");function tr(i){let t=new Set;for(let e of i){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}l(tr,"affectedDomains");Se();ht();async function Vs(i,t=100){try{let{stdout:e}=await R(`git log --name-only --pretty=format:'---COMMIT---' -${t}`,{cwd:i,maxBuffer:10485760}),r=[],n=null;for(let s of e.split(`
501
- `)){let o=s.trim();o==="---COMMIT---"?(n&&n.size>0&&n.size<=30&&r.push(n),n=new Set):o&&n&&Ys(o)&&n.add(o)}return n&&n.size>0&&n.size<=30&&r.push(n),r}catch{return[]}}l(Vs,"parseGitLog");function Ys(i){return/\.(ts|tsx|js|jsx|mjs|cjs|py|go|rs|java|cs|rb|php|vue|svelte)$/i.test(i)&&!i.includes("node_modules/")}l(Ys,"isSourceFile");async function Js(i,t=100){let e=await Vs(i,t),r=new Map,n=new Map;for(let o of e){let a=Array.from(o);for(let c of a)r.set(c,(r.get(c)||0)+1);for(let c=0;c<a.length;c++)for(let u=c+1;u<a.length;u++){let p=Ks(a[c],a[u]);n.set(p,(n.get(p)||0)+1)}}let s={};for(let[o,a]of n){let[c,u]=o.split("\0"),p=r.get(c)||0,d=r.get(u)||0;if(p<2||d<2)continue;let g=p+d-a,h=g>0?a/g:0;h<.1||(s[c]||(s[c]={}),s[u]||(s[u]={}),s[c][u]=h,s[u][c]=h)}return{matrix:s,commitsAnalyzed:e.length,filesAnalyzed:r.size,builtAt:new Date().toISOString()}}l(Js,"buildMatrix");function Ks(i,t){return i<t?`${i}\0${t}`:`${t}\0${i}`}l(Ks,"pairKey");function xe(i,t){let e=new Set(i),r=new Map;for(let n of i){let s=t.matrix[n];if(s)for(let[o,a]of Object.entries(s)){if(e.has(o))continue;let c=r.get(o)||0;a>c&&r.set(o,a)}}return Array.from(r.entries()).map(([n,s])=>({path:n,score:s})).sort((n,s)=>s.score-n.score)}l(xe,"scoreFromSeeds");var sr="cochange-index";function Qs(i,t){T.setDoc(i,sr,t)}l(Qs,"saveMatrix");function _e(i){return T.getDoc(i,sr)}l(_e,"loadMatrix");async function or(i,t,e=100){let r=await Js(i,e);return Qs(t,r),r}l(or,"indexCoChanges");import Ie from"node:fs/promises";import io from"node:path";import*as Yt from"jsonc-parser";import{z as D}from"zod";var Et={create(i,t){class e extends Error{static{l(this,"TypedError")}errorName;data;isOperational=!0;constructor(n){let s=t.parse(n);super(`${i}: ${JSON.stringify(s)}`),this.name=i,this.errorName=i,this.data=s,Error.captureStackTrace?.(this,this.constructor)}static throw(n){throw new e(n)}static is(n){return n instanceof e&&n.errorName===i}static create(n){return new e(n)}}return e}},lc=Et.create("FileError",D.object({path:D.string(),operation:D.enum(["read","write","delete","create","copy"]),reason:D.string().optional()})),pc=Et.create("ValidationError",D.object({field:D.string(),expected:D.string(),received:D.string().optional(),message:D.string().optional()})),dc=Et.create("PermissionError",D.object({action:D.string(),resource:D.string(),reason:D.string().optional()})),mc=Et.create("TaskError",D.object({taskId:D.string().optional(),operation:D.enum(["create","update","complete","pause","resume","delete"]),reason:D.string()})),gc=Et.create("SessionError",D.object({sessionId:D.string().optional(),reason:D.string()})),fc=Et.create("SyncError",D.object({projectId:D.string().optional(),operation:D.enum(["push","pull","auth","connect"]),reason:D.string()})),ve=class extends Error{static{l(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 Zs(i){return i instanceof ve}l(Zs,"isPrjctError");function Pe(i){return Zs(i)||i instanceof Error?i.message:typeof i=="string"?i:"Unknown error"}l(Pe,"getErrorMessage");ft();W();st();Ce();ht();async function Vt(i){try{let{stdout:t}=await R(i,{timeout:5e3});return{success:!0,output:t.trim()}}catch{return{success:!1,output:""}}}l(Vt,"execCommand");async function eo(){let i=await Vt("gh api user --jq .login");return i.success&&i.output||(i=await Vt("git config --global github.user"),i.success&&i.output)?i.output:null}l(eo,"detectGitHubUsername");async function no(){let i=await Vt("git config user.name");return i.success&&i.output?i.output:null}l(no,"detectGitName");async function ro(){let i=await Vt("git config user.email");return i.success&&i.output?i.output:null}l(ro,"detectGitEmail");async function ar(){let[i,t,e]=await Promise.all([eo(),no(),ro()]);return{github:i,email:e,name:t||i||"Unknown"}}l(ar,"detect");function dr(i){let t=[],e=Yt.parse(i,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}l(dr,"parseJsonc");var Me=class{static{l(this,"ConfigManager")}async readConfig(t){try{let e=A.getLocalConfigPath(t),r=await Ie.readFile(e,"utf-8");return dr(r)}catch(e){return H(e)||console.warn(`Warning: Could not read config at ${t}: ${Pe(e)}`),null}}async writeConfig(t,e){let r=A.getLocalConfigPath(t);await rt(r,e)}async readGlobalConfig(t){try{let e=A.getGlobalProjectConfigPath(t),r=await Ie.readFile(e,"utf-8");return dr(r)}catch(e){return H(e)||console.warn(`Warning: Could not read global config for ${t}: ${Pe(e)}`),null}}async writeGlobalConfig(t,e){let r=A.getGlobalProjectConfigPath(t);await rt(r,e)}async ensureGlobalConfig(t){let e=await this.readGlobalConfig(t);if(!e){let r=f();e={projectId:t,authors:[],version:Ae,lastSync:r},await this.writeGlobalConfig(t,e)}return e}async createConfig(t,e){let r=A.generateProjectId(t),n=A.getGlobalProjectPath(r),s=A.getDisplayPath(n),o=f(),a={projectId:r,dataPath:s,showMetrics:!0};await this.writeConfig(t,a);let c={projectId:r,authors:[{name:e.name||"Unknown",email:e.email||"",github:e.github||"",firstContribution:o,lastActivity:o}],version:Ae,created:o,lastSync:o};return await this.writeGlobalConfig(r,c),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 A.hasLegacyStructure(t))return!1;if(!await A.hasConfig(t))return!0;let n=await this.readConfig(t);if(!n||!n.projectId)return!0;let s=A.getGlobalProjectPath(n.projectId);try{return(await Ie.readdir(io.join(s,"core"))).length===0}catch(o){return H(o),!0}}async getProjectId(t){let e=await this.readConfig(t);if(e?.projectId)return e.projectId;try{let{worktreeService:r}=await Promise.resolve().then(()=>(pr(),lr));if(await r.detect(t)){let s=await r.getMainWorktree(t);if(s!==t){let o=await this.readConfig(s);if(o?.projectId)return o.projectId}}}catch{}return A.generateProjectId(t)}async findAuthor(t,e){let r=await this.readGlobalConfig(t);return!r||!r.authors?null:r.authors.find(n=>n.github===e)||null}async addAuthor(t,e){let r=await this.ensureGlobalConfig(t);if(r.authors.some(o=>o.github===e.github))return;let s=f();r.authors.push({name:e.name||"Unknown",email:e.email||"",github:e.github||"",firstContribution:s,lastActivity:s}),r.lastSync=s,await this.writeGlobalConfig(t,r)}async updateAuthorActivity(t,e){let r=await this.readGlobalConfig(t);if(!r||!r.authors)return;let n=r.authors.find(s=>s.github===e);n&&(n.lastActivity=f(),r.lastSync=n.lastActivity,await this.writeGlobalConfig(t,r))}async getCurrentAuthor(t){let e=await ar(),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=A.generateProjectId(t);return{projectId:r,dataPath:A.getDisplayPath(A.getGlobalProjectPath(r))}}},ao=new Me,At=ao;async function b(i){return At.getProjectId(i)}l(b,"resolveProjectId");function y(i,t){return async e=>{try{return await t(e)}catch(r){return co(r,i)}}}l(y,"safeMcpCall");function co(i,t){let e=i instanceof Error?i.message:String(i);return{content:[{type:"text",text:`[${t}] Error: ${e}`}],isError:!0}}l(co,"mcpError");function mr(i){let t=i;t.tool("prjct_impact_analysis","Given changed files, find affected files via import graph + affected domains",{projectPath:B.string().describe("Project directory path"),changedFiles:B.array(B.string()).describe("List of changed file paths (relative to project root)")},y("prjct_impact_analysis",async e=>{let r=await b(e.projectPath),n={added:[],modified:e.changedFiles,deleted:[],unchanged:[]},s=Zn(n,r),o=tr(s.allAffected),a=["## Impact Analysis"];a.push(`
502
- ### Directly Changed (${s.directlyChanged.length})`);for(let c of s.directlyChanged)a.push(`- ${c}`);if(s.affectedByImports.length>0){a.push(`
503
- ### Affected via Imports (${s.affectedByImports.length})`);for(let c of s.affectedByImports)a.push(`- ${c}`)}return a.push(`
504
- ### Affected Domains`),a.push(o.size>0?Array.from(o).join(", "):"none detected"),a.push(`
505
- Total affected: ${s.allAffected.length} files`),{content:[{type:"text",text:a.join(`
506
- `)}]}})),t.tool("prjct_import_graph","Import graph stats + file neighbors (imports/importers). Pass a file for its neighbors, omit for graph stats.",{projectPath:B.string().describe("Project directory path"),file:B.string().optional().describe("File path to get neighbors for (omit for graph stats)"),rebuild:B.boolean().optional().default(!1).describe("Force rebuild the import graph")},y("prjct_import_graph",async e=>{let r=await b(e.projectPath),n=e.rebuild?null:jt(r);if(n||(n=await Qn(e.projectPath,r)),e.file){let o=n.forward[e.file]||[],a=n.reverse[e.file]||[];return{content:[{type:"text",text:[`## Import Neighbors: ${e.file}`,`
507
- ### Imports (${o.length})`,...o.map(u=>`- ${u}`),`
508
- ### Imported By (${a.length})`,...a.map(u=>`- ${u}`)].join(`
509
- `)}]}}return{content:[{type:"text",text:["## Import Graph Stats",`Files: ${n.fileCount}`,`Edges: ${n.edgeCount}`,`Built: ${n.builtAt}`].join(`
510
- `)}]}})),t.tool("prjct_cochange","Files that historically change together (Jaccard similarity from git history)",{projectPath:B.string().describe("Project directory path"),seedFiles:B.array(B.string()).describe("Seed files to find co-change partners for"),rebuild:B.boolean().optional().default(!1).describe("Force rebuild the co-change matrix"),maxResults:B.number().optional().default(10).describe("Max results (default 10)")},y("prjct_cochange",async e=>{let r=await b(e.projectPath),n=e.rebuild?null:_e(r);n||(n=await or(e.projectPath,r));let s=xe(e.seedFiles,n).slice(0,e.maxResults);if(s.length===0)return{content:[{type:"text",text:"No co-change partners found."}]};let o=["## Co-Change Partners",`Seeds: ${e.seedFiles.join(", ")}`,`Commits analyzed: ${n.commitsAnalyzed}`,""];for(let a of s)o.push(`- ${a.path} (similarity: ${Math.round(a.score*100)}%)`);return{content:[{type:"text",text:o.join(`
511
- `)}]}})),t.tool("prjct_related_context","Combined: import neighbors + co-change partners for seed files",{projectPath:B.string().describe("Project directory path"),seedFiles:B.array(B.string()).describe("Seed files to find related context for"),maxResults:B.number().optional().default(15).describe("Max results (default 15)")},y("prjct_related_context",async e=>{let r=await b(e.projectPath),n=jt(r),s=n?Jn(e.seedFiles,n):[],o=_e(r),a=o?xe(e.seedFiles,o):[],c=new Map;for(let d of s)c.set(d.path,{importScore:d.score,cochangeScore:0});for(let d of a){let g=c.get(d.path);g?g.cochangeScore=d.score:c.set(d.path,{importScore:0,cochangeScore:d.score})}let u=Array.from(c.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(u.length===0)return{content:[{type:"text",text:"No related files found. Run `prjct sync` to build indexes."}]};let p=["## Related Context",`Seeds: ${e.seedFiles.join(", ")}`,""];for(let d of u){let g=[];d.importScore>0&&g.push(`import: ${d.importScore.toFixed(2)}`),d.cochangeScore>0&&g.push(`cochange: ${Math.round(d.cochangeScore*100)}%`),p.push(`- ${d.path} (${g.join(", ")})`)}return{content:[{type:"text",text:p.join(`
512
- `)}]}}))}l(mr,"registerCodeIntelTools");import{z as Ct}from"zod";var ot={CODE_STYLE:"code_style",NAMING_CONVENTION:"naming_convention",FILE_STRUCTURE:"file_structure",COMMIT_STYLE:"commit_style",BRANCH_NAMING:"branch_naming",TEST_BEHAVIOR:"test_behavior",SHIP_WORKFLOW:"ship_workflow",TECH_STACK:"tech_stack",ARCHITECTURE:"architecture",DEPENDENCIES:"dependencies",OUTPUT_VERBOSITY:"output_verbosity",CONFIRMATION_LEVEL:"confirmation_level",AGENT_PREFERENCE:"agent_preference"};function Jt(i,t=!1){return t||i>=6?"high":i>=3?"medium":"low"}l(Jt,"calculateConfidence");W();var Kt=class{static{l(this,"CachedStore")}_data=null;_loaded=!1;_projectId=null;getSubdirectory(){return null}getStoreKey(){let t=this.getFilename().replace(".json",""),e=this.getSubdirectory();return e?`memory:${e}:${t}`:`memory:${t}`}async load(t){if(this._loaded&&this._data&&this._projectId===t)return this._data;let e=this.getStoreKey(),r=T.getDoc(t,e);return r!==null?(this._data=r,this.afterLoad(this._data)):this._data=this.getDefault(),this._loaded=!0,this._projectId=t,this._data}afterLoad(t){}async save(t){if(!this._data)return;let e=this.getStoreKey();T.setDoc(t,e,this._data)}getData(){return this._data}setData(t){this._data=t}async update(t,e){let r=await this.load(t),n=e(r);return this._data=n,await this.save(t),n}isLoaded(t){return t?this._loaded&&this._projectId===t:this._loaded}reset(){this._data=null,this._loaded=!1,this._projectId=null}},Qt=class{static{l(this,"SessionStore")}_sessionMemory=new Map;setSession(t,e){this._sessionMemory.set(t,{value:e,timestamp:Date.now()})}getSession(t){return this._sessionMemory.get(t)?.value}clearSession(){this._sessionMemory.clear()}},Zt=class{static{l(this,"HistoryStore")}async appendHistory(t,e){let r={ts:f(),...e,type:e.type};T.appendEvent(t,`history.${e.type}`,r)}async getRecentHistory(t,e=20){return T.query(t,"SELECT data, timestamp FROM events WHERE type LIKE 'history.%' ORDER BY id DESC LIMIT ?",e).reverse().map(n=>JSON.parse(n.data))}};W();var kt=class i extends Kt{static{l(this,"PatternStore")}static MAX_CONTEXTS=20;static ARCHIVE_AGE_DAYS=90;getFilename(){return"patterns.json"}getDefault(){return{version:1,decisions:{},preferences:{},workflows:{},counters:{}}}afterLoad(t){for(let e of Object.values(t.decisions))Array.isArray(e.contexts)||(e.contexts=[]),e.contexts.length>i.MAX_CONTEXTS&&(e.contexts=e.contexts.slice(-i.MAX_CONTEXTS))}async loadPatterns(t){return this.load(t)}async savePatterns(t){return this.save(t)}async recordDecision(t,e,r,n="",s={}){let o=await this.load(t),a=f();if(!o.decisions[e])o.decisions[e]={value:r,count:1,firstSeen:a,lastSeen:a,confidence:s.userConfirmed?"high":"low",contexts:[n].filter(Boolean),userConfirmed:s.userConfirmed||!1};else{let c=o.decisions[e];c.value===r?(c.count++,c.lastSeen=a,n&&!c.contexts.includes(n)&&(c.contexts.push(n),c.contexts.length>i.MAX_CONTEXTS&&(c.contexts=c.contexts.slice(-i.MAX_CONTEXTS))),s.userConfirmed&&(c.userConfirmed=!0),c.confidence=Jt(c.count,c.userConfirmed)):(c.value=r,c.count=1,c.lastSeen=a,c.userConfirmed=s.userConfirmed||!1,c.confidence=s.userConfirmed?"high":"low")}await this.save(t)}async confirmDecision(t,e){let n=(await this.load(t)).decisions[e];return n?(n.userConfirmed=!0,n.confidence="high",n.lastSeen=f(),await this.save(t),!0):!1}async getDecision(t,e){let n=(await this.load(t)).decisions[e];return!n||n.confidence==="low"?null:{value:n.value,confidence:n.confidence}}async hasPattern(t,e){return await this.getDecision(t,e)!==null}async recordWorkflow(t,e,r){let n=await this.load(t),s=f();if(!n.workflows[e])n.workflows[e]={...r,count:1,firstSeen:s,lastSeen:s,confidence:"low",userConfirmed:!1};else{let o=n.workflows[e];o.count++,o.lastSeen=s,o.confidence=Jt(o.count,o.userConfirmed)}await this.save(t)}async confirmWorkflow(t,e){let n=(await this.load(t)).workflows[e];return n?(n.userConfirmed=!0,n.confidence="high",n.lastSeen=f(),await this.save(t),!0):!1}async getWorkflow(t,e){let n=(await this.load(t)).workflows[e];return!n||n.count<3?null:n}async setPreference(t,e,r,n={}){let s=await this.load(t),o=s.preferences[e],a=o?o.observationCount+1:1,c=n.userConfirmed||o?.userConfirmed||!1;s.preferences[e]={value:r,updatedAt:f(),confidence:Jt(a,c),observationCount:a,userConfirmed:c},await this.save(t)}async confirmPreference(t,e){let n=(await this.load(t)).preferences[e];return n?(n.userConfirmed=!0,n.confidence="high",n.updatedAt=f(),await this.save(t),!0):!1}async getPreference(t,e,r=null){return(await this.load(t)).preferences[e]?.value??r}async getPatternsSummary(t){let e=await this.load(t);return{decisions:Object.keys(e.decisions).length,learnedDecisions:Object.values(e.decisions).filter(r=>r.confidence!=="low").length,workflows:Object.keys(e.workflows).length,preferences:Object.keys(e.preferences).length}}async getPatternsSummaryDetailed(t){let e=await this.load(t),r={};for(let[o,a]of Object.entries(e.decisions))r[o]={value:a.value,confidence:a.confidence,count:a.count};let n={};for(let[o,a]of Object.entries(e.preferences))n[o]={value:a.value,confidence:a.confidence};let s={};for(let[o,a]of Object.entries(e.workflows))s[o]={confidence:a.confidence??"low",count:a.count};return{decisions:r,preferences:n,workflows:s}}async archiveStaleDecisions(t){let e=await this.load(t),r=Date.now(),n=i.ARCHIVE_AGE_DAYS*24*60*60*1e3,s=[];for(let[a,c]of Object.entries(e.decisions)){let u=new Date(c.lastSeen).getTime();r-u>n&&s.push(a)}if(s.length===0)return 0;let o=T.getDoc(t,"memory:patterns-archive")??{};for(let a of s)o[a]=e.decisions[a],delete e.decisions[a];return T.setDoc(t,"memory:patterns-archive",o),await this.save(t),s.length}};import uo from"node:crypto";import{homedir as lo}from"node:os";import{join as po}from"node:path";function F(){return uo.randomUUID()}l(F,"generateUUID");var yu=po(lo(),".prjct-cli","projects");W();import{createHash as mo}from"node:crypto";function go(i){return mo("sha256").update(i).digest("hex")}l(go,"sha256");function Oe(i){return go(i).slice(0,16)}l(Oe,"sha256Short");function it(i){return{id:i.id,title:i.title,content:i.content,tags:i.tags?i.tags.split(",").filter(Boolean):[],userTriggered:i.user_triggered===1,createdAt:i.created_at,updatedAt:i.updated_at,confidence:i.confidence,observationCount:i.observation_count||void 0}}l(it,"rowToMemory");var et=class{static{l(this,"SemanticMemories")}_coerceTags(t){let e=new Set(Object.values(ot));return t.filter(r=>e.has(r))}async createMemory(t,{title:e,content:r,tags:n=[],userTriggered:s=!1,topicKey:o}){let c=this._coerceTags(n).join(","),u=f(),p=Oe(r),d=T.get(t,"SELECT id FROM memories WHERE project_id = ? AND content_hash = ? AND deleted_at IS NULL",t,p);if(d)return d.id;if(o){let h=T.get(t,"SELECT * FROM memories WHERE project_id = ? AND topic_key = ? AND deleted_at IS NULL",t,o);if(h)return T.run(t,`UPDATE memories SET title = ?, content = ?, tags = ?, content_hash = ?,
513
- revision_count = revision_count + 1, updated_at = ? WHERE id = ?`,e,r,c,p,u,h.id),h.id}let g=F();return T.run(t,`INSERT INTO memories
514
- (id, project_id, title, content, tags, topic_key, content_hash, user_triggered, created_at, updated_at)
515
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,g,t,e,r,c,o??null,p,s?1:0,u,u),g}async updateMemory(t,e,r){let n=T.get(t,"SELECT * FROM memories WHERE id = ? AND project_id = ? AND deleted_at IS NULL",e,t);if(!n)return!1;let s=r.title??n.title,o=r.content??n.content,a=r.tags?this._coerceTags(r.tags).join(","):n.tags,c=r.content?Oe(o):n.content_hash;return T.run(t,`UPDATE memories SET title = ?, content = ?, tags = ?, content_hash = ?,
516
- revision_count = revision_count + 1, updated_at = ? WHERE id = ?`,s,o,a,c,f(),e),!0}async deleteMemory(t,e){return T.get(t,"SELECT id FROM memories WHERE id = ? AND project_id = ? AND deleted_at IS NULL",e,t)?(T.run(t,"UPDATE memories SET deleted_at = ? WHERE id = ?",f(),e),!0):!1}async findByTags(t,e,r=!1){let n=this._coerceTags(e);if(n.length===0)return[];let s=n.map(()=>"(tags = ? OR tags LIKE ? OR tags LIKE ? OR tags LIKE ?)"),o=r?" AND ":" OR ",a=s.join(o),c=[t];for(let p of n)c.push(p,`${p},%`,`%,${p},%`,`%,${p}`);return T.query(t,`SELECT * FROM memories WHERE project_id = ? AND deleted_at IS NULL
517
- AND (${a}) ORDER BY updated_at DESC`,...c).map(it)}async searchMemories(t,e,r=20,n=0){try{return T.query(t,`SELECT m.* FROM memories m
518
- JOIN memories_fts fts ON m.rowid = fts.rowid
519
- WHERE memories_fts MATCH ? AND m.project_id = ? AND m.deleted_at IS NULL
520
- ORDER BY bm25(memories_fts) LIMIT ? OFFSET ?`,e,t,r,n).map(it)}catch{let s=`%${e}%`;return T.query(t,`SELECT * FROM memories
521
- WHERE project_id = ? AND deleted_at IS NULL
522
- AND (title LIKE ? OR content LIKE ?)
523
- ORDER BY updated_at DESC LIMIT ? OFFSET ?`,t,s,s,r,n).map(it)}}async getRelevantMemories(t,e,r=5){let n=[];if(e.commandName&&n.push(e.commandName),e.params?.description&&n.push(String(e.params.description)),e.params?.task&&n.push(String(e.params.task)),e.params?.feature&&n.push(String(e.params.feature)),n.length===0)return T.query(t,"SELECT * FROM memories WHERE project_id = ? AND deleted_at IS NULL ORDER BY updated_at DESC LIMIT ?",t,r).map(it);let s=n.join(" ");try{return T.query(t,`SELECT m.* FROM memories m
524
- JOIN memories_fts fts ON m.rowid = fts.rowid
525
- WHERE memories_fts MATCH ? AND m.project_id = ? AND m.deleted_at IS NULL
526
- ORDER BY bm25(memories_fts) LIMIT ?`,s,t,r).map(it)}catch{return T.query(t,"SELECT * FROM memories WHERE project_id = ? AND deleted_at IS NULL ORDER BY updated_at DESC LIMIT ?",t,r).map(it)}}async getRelevantMemoriesWithMetrics(t,e){let n=T.get(t,"SELECT COUNT(*) as count FROM memories WHERE project_id = ? AND deleted_at IS NULL",t)?.count??0;if(n===0)return{memories:[],metrics:{totalMemories:0,memoriesConsidered:0,memoriesReturned:0,filteringRatio:0,avgRelevanceScore:0}};let s=e.maxResults??10,o={};e.commandName&&(o.commandName=e.commandName),e.taskDescription&&(o.params={description:e.taskDescription});let c=(await this.getRelevantMemories(t,o,s)).map((p,d)=>({...p,relevanceScore:Math.max(10,100-d*10),scoreBreakdown:{domainMatch:0,tagMatch:0,recency:0,confidence:0,keywords:Math.max(10,100-d*10),userTriggered:p.userTriggered?5:0}})),u=c.length>0?Math.round(c.reduce((p,d)=>p+d.relevanceScore,0)/c.length):0;return{memories:c,metrics:{totalMemories:n,memoriesConsidered:n,memoriesReturned:c.length,filteringRatio:n>0?c.length/n:0,avgRelevanceScore:u}}}async autoRemember(t,e,r,n=""){let o={commit_footer:[ot.COMMIT_STYLE],branch_naming:[ot.BRANCH_NAMING],test_before_ship:[ot.TEST_BEHAVIOR,ot.SHIP_WORKFLOW],preferred_agent:[ot.AGENT_PREFERENCE],code_style:[ot.CODE_STYLE],verbosity:[ot.OUTPUT_VERBOSITY]}[e]||[];await this.createMemory(t,{title:`Preference: ${e}`,content:`${e}: ${r}${n?`
527
- Context: ${n}`:""}`,tags:o,userTriggered:!0,topicKey:`preference:${e}`})}async findSimilar(t,e,r=5){let n=await this.getMemoryById(t,e);if(!n)return[];let s=n.title.split(/\s+/).filter(a=>a.length>2).slice(0,8);if(s.length===0)return[];let o=s.join(" OR ");try{return T.query(t,`SELECT m.* FROM memories m
528
- JOIN memories_fts fts ON m.rowid = fts.rowid
529
- WHERE memories_fts MATCH ? AND m.project_id = ? AND m.deleted_at IS NULL AND m.id != ?
530
- ORDER BY bm25(memories_fts) LIMIT ?`,o,t,e,r).map(it)}catch{return[]}}async consolidateMemories(t){let e={merged:0,groups:[]},r=T.query(t,`SELECT title, COUNT(*) as cnt FROM memories
531
- WHERE project_id = ? AND deleted_at IS NULL
532
- GROUP BY title HAVING cnt > 1`,t),n=f();for(let s of r){let o=T.query(t,`SELECT * FROM memories
533
- WHERE project_id = ? AND title = ? AND deleted_at IS NULL
534
- ORDER BY updated_at DESC`,t,s.title);if(o.length<2)continue;let[a,...c]=o,u=[a.content,...c.filter(g=>g.content!==a.content).map(g=>g.content)].filter((g,h,j)=>j.indexOf(g)===h).join(`
535
-
536
- ---
537
-
538
- `),p=new Set;for(let g of o)if(g.tags)for(let h of g.tags.split(",").filter(Boolean))p.add(h);(u!==a.content||p.size>0)&&T.run(t,"UPDATE memories SET content = ?, tags = ?, revision_count = revision_count + 1, updated_at = ? WHERE id = ?",u,Array.from(p).join(","),n,a.id);let d=[];for(let g of c)T.run(t,"UPDATE memories SET deleted_at = ? WHERE id = ?",n,g.id),d.push(g.id);e.merged+=c.length,e.groups.push({kept:a.id,merged:d})}return e}async getMemoryById(t,e){let r=T.get(t,"SELECT * FROM memories WHERE id = ? AND project_id = ? AND deleted_at IS NULL",e,t);return r?it(r):null}async getAllMemories(t){return T.query(t,"SELECT * FROM memories WHERE project_id = ? AND deleted_at IS NULL ORDER BY updated_at DESC",t).map(it)}async getMemoryStats(t){let e=T.query(t,"SELECT * FROM memories WHERE project_id = ? AND deleted_at IS NULL",t),r={};for(let n of e){let s=n.tags?n.tags.split(",").filter(Boolean):[];for(let o of s)r[o]=(r[o]||0)+1}return{totalMemories:e.length,userTriggered:e.filter(n=>n.user_triggered===1).length,tagCounts:r,oldestMemory:e[e.length-1]?.created_at,newestMemory:e[0]?.created_at}}async loadMemories(t){return{version:1,memories:await this.getAllMemories(t),index:{}}}async saveMemories(t){}reset(){}};var Le=class{static{l(this,"MemorySystem")}_semanticMemories;_patternStore;_historyStore;_sessionStore;constructor(){this._semanticMemories=new et,this._patternStore=new kt,this._historyStore=new Zt,this._sessionStore=new Qt}loadMemories(t){return this._semanticMemories.loadMemories(t)}saveMemories(t){return this._semanticMemories.saveMemories(t)}createMemory(t,e){return this._semanticMemories.createMemory(t,e)}updateMemory(t,e,r){return this._semanticMemories.updateMemory(t,e,r)}deleteMemory(t,e){return this._semanticMemories.deleteMemory(t,e)}findByTags(t,e,r){return this._semanticMemories.findByTags(t,e,r)}searchMemories(t,e){return this._semanticMemories.searchMemories(t,e)}getRelevantMemories(t,e,r){return this._semanticMemories.getRelevantMemories(t,e,r)}autoRemember(t,e,r,n){return this._semanticMemories.autoRemember(t,e,r,n)}getAllMemories(t){return this._semanticMemories.getAllMemories(t)}findSimilar(t,e,r){return this._semanticMemories.findSimilar(t,e,r)}consolidateMemories(t){return this._semanticMemories.consolidateMemories(t)}getMemoryStats(t){return this._semanticMemories.getMemoryStats(t)}getRelevantMemoriesWithMetrics(t,e){return this._semanticMemories.getRelevantMemoriesWithMetrics(t,e)}setSession(t,e){this._sessionStore.setSession(t,e)}getSession(t){return this._sessionStore.getSession(t)}clearSession(){this._sessionStore.clearSession()}loadPatterns(t){return this._patternStore.loadPatterns(t)}savePatterns(t){return this._patternStore.savePatterns(t)}recordDecision(t,e,r,n){return this._patternStore.recordDecision(t,e,r,n)}getDecision(t,e){return this._patternStore.getDecision(t,e)}hasPattern(t,e){return this._patternStore.hasPattern(t,e)}recordWorkflow(t,e,r){return this._patternStore.recordWorkflow(t,e,r)}getWorkflow(t,e){return this._patternStore.getWorkflow(t,e)}setPreference(t,e,r,n){return this._patternStore.setPreference(t,e,r,n)}getPreference(t,e,r){return this._patternStore.getPreference(t,e,r)}confirmPreference(t,e){return this._patternStore.confirmPreference(t,e)}confirmDecision(t,e){return this._patternStore.confirmDecision(t,e)}confirmWorkflow(t,e){return this._patternStore.confirmWorkflow(t,e)}getPatternsSummary(t){return this._patternStore.getPatternsSummary(t)}getPatternsSummaryDetailed(t){return this._patternStore.getPatternsSummaryDetailed(t)}archiveStaleDecisions(t){return this._patternStore.archiveStaleDecisions(t)}appendHistory(t,e){return this._historyStore.appendHistory(t,e)}getRecentHistory(t,e){return this._historyStore.getRecentHistory(t,e)}async getSmartDecision(t,e){let r=this.getSession(`decision:${e}`);if(r!==void 0)return r;let n=await this.getDecision(t,e);return n?n.value:null}async learnDecision(t,e,r,n=""){this.setSession(`decision:${e}`,r),await this.recordDecision(t,e,r,n),await this.appendHistory(t,{type:"decision",key:e,value:r,context:n})}resetState(){this._sessionStore.clearSession(),this._semanticMemories.reset(),this._patternStore.reset()}},fo=new Le,G=fo;var $e=class{static{l(this,"ContextZoneStorage")}recordTransition(t,e,r){_.run(t,`INSERT INTO context_zone_events (project_id, session_id, zone_from, zone_to, usage_percent, action, timestamp)
539
- VALUES (?, ?, ?, ?, ?, ?, ?)`,t,r??null,e.from,e.to,e.usagePercent,e.action??null,e.timestamp)}recordCompaction(t,e,r,n){_.run(t,`INSERT INTO context_compactions (project_id, format, original_turns, files_count, timestamp)
540
- VALUES (?, ?, ?, ?, ?)`,t,e,r,n,new Date().toISOString())}getTransitions(t,e=20){return _.query(t,"SELECT * FROM context_zone_events WHERE project_id = ? ORDER BY id DESC LIMIT ?",t,e).map(n=>({from:n.zone_from,to:n.zone_to,usagePercent:n.usage_percent,timestamp:n.timestamp,action:n.action}))}getSummary(t,e=7){let r=new Date(Date.now()-e*864e5).toISOString(),n=_.query(t,`SELECT zone_to, COUNT(*) as cnt FROM context_zone_events
541
- WHERE project_id = ? AND timestamp >= ?
542
- GROUP BY zone_to`,t,r),s={smart:0,warning:0,dumb:0},o=0;for(let u of n)s[u.zone_to]=u.cnt,o+=u.cnt;let c=_.query(t,`SELECT COUNT(*) as cnt FROM context_compactions
543
- WHERE project_id = ? AND timestamp >= ?`,t,r)[0]?.cnt??0;return o===0?{smartPercent:100,warningPercent:0,dumbPercent:0,compactions:c}:{smartPercent:Math.round(s.smart/o*100),warningPercent:Math.round(s.warning/o*100),dumbPercent:Math.round(s.dumb/o*100),compactions:c}}},Fe=new $e;W();var Ue=class{static{l(this,"LLMAnalysisStorage")}save(t,e){let r=_.getDb(t),n=f();r.transaction(()=>{r.prepare("UPDATE llm_analysis SET status = 'superseded', superseded_at = ? WHERE status = 'active'").run(n),r.prepare("INSERT INTO llm_analysis (commit_hash, status, analysis, analyzed_at) VALUES (?, ?, ?, ?)").run(e.commitHash??null,"active",JSON.stringify(e),e.analyzedAt)})()}getActive(t){let e=_.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?_.get(t,"SELECT commit_hash FROM llm_analysis WHERE status = 'active' LIMIT 1")?.commit_hash===e:!1}getHistory(t,e=10){return _.query(t,"SELECT id, commit_hash, status, analyzed_at, analysis FROM llm_analysis ORDER BY id DESC LIMIT ?",e).map(n=>{let s=JSON.parse(n.analysis);return{id:n.id,commitHash:n.commit_hash,status:n.status,analyzedAt:n.analyzed_at,patternCount:s.patterns.length}})}},ho=new Ue,lt=ho;ht();function gr(i){let t=i;t.tool("prjct_analysis_staleness","Is analysis current? How many commits behind? Shows analysis summary and history.",{projectPath:Ct.string().describe("Project directory path")},y("prjct_analysis_staleness",async e=>{let r=await b(e.projectPath),n=lt.getActiveSummary(r);if(!n)return{content:[{type:"text",text:"No analysis exists. Run `prjct sync` to analyze."}]};let s=null;try{let{stdout:p}=await R("git rev-parse HEAD",{cwd:e.projectPath});s=p.trim()}catch{}let o=s?lt.isCurrent(r,s):!1,a=0;if(s&&n.commitHash&&!o)try{let{stdout:p}=await R(`git rev-list ${n.commitHash}..HEAD --count`,{cwd:e.projectPath});a=parseInt(p.trim(),10)||0}catch{a=-1}let c=lt.getHistory(r,5),u=["## Analysis Staleness",`Status: ${o?"CURRENT":"STALE"}`];if(!o&&a>0?u.push(`Commits behind: ${a}`):!o&&a===-1&&u.push("Commits behind: unknown (commit hash not found in history)"),u.push(`
544
- ### Active Analysis`),u.push(`Architecture: ${n.architectureStyle}`),u.push(`Patterns: ${n.patternCount}`),u.push(`Anti-patterns: ${n.antiPatternCount}`),u.push(`Analyzed at: ${n.analyzedAt}`),n.commitHash&&u.push(`Commit: ${n.commitHash.slice(0,8)}`),c.length>1){u.push(`
545
- ### History (last ${c.length})`);for(let p of c)u.push(`- ${p.status} at ${p.analyzedAt} (${p.patternCount} patterns${p.commitHash?`, ${p.commitHash.slice(0,8)}`:""})`)}return{content:[{type:"text",text:u.join(`
546
- `)}]}})),t.tool("prjct_zone_health","Smart/warning/dumb zone distribution + compaction frequency",{projectPath:Ct.string().describe("Project directory path"),days:Ct.number().optional().default(7).describe("Time period in days (default 7)")},y("prjct_zone_health",async e=>{let r=await b(e.projectPath),n=Fe.getSummary(r,e.days),s=Fe.getTransitions(r,10),o=["## Context Zone Health",`Period: last ${e.days} days`,"","### Zone Distribution",`Smart: ${n.smartPercent}%`,`Warning: ${n.warningPercent}%`,`Dumb: ${n.dumbPercent}%`,`
547
- Compactions: ${n.compactions}`];if(s.length>0){o.push(`
548
- ### Recent Transitions (${s.length})`);for(let a of s){let c=a.action?` \u2192 ${a.action}`:"";o.push(`- ${a.from} \u2192 ${a.to} (${a.usagePercent}%${c}) at ${a.timestamp}`)}}return{content:[{type:"text",text:o.join(`
549
- `)}]}})),t.tool("prjct_audit_log","Recent history events (decisions, preferences, task actions)",{projectPath:Ct.string().describe("Project directory path"),limit:Ct.number().optional().default(20).describe("Max events to return (default 20)")},y("prjct_audit_log",async e=>{let r=await b(e.projectPath),n=await G.getRecentHistory(r,e.limit);if(!n||n.length===0)return{content:[{type:"text",text:"No history events found."}]};let s=[`## Audit Log (${n.length} events)`,""];for(let o of n){let a=o.type||"unknown",c=o.timestamp||"",u=Object.entries(o).filter(([p])=>p!=="type"&&p!=="timestamp").map(([p,d])=>`${p}=${typeof d=="string"?d:JSON.stringify(d)}`).join(", ");s.push(`- [${a}] ${u}${c?` (${c})`:""}`)}return{content:[{type:"text",text:s.join(`
550
- `)}]}}))}l(gr,"registerContextTools");import{z as yt}from"zod";de();import{z as m}from"zod";var yo=m.enum(["low","medium","high","critical"]),te=m.enum(["feature","bug","improvement","chore"]),To=m.enum(["active","backlog","previously_active"]),wo=m.enum(["pending","in_progress","completed","blocked","paused","failed","skipped"]),bo=m.enum(["task_completed","feature_shipped","idea_captured","session_started"]),We=m.object({title:m.string(),description:m.string(),filesChanged:m.array(m.object({path:m.string(),action:m.enum(["created","modified","deleted"])})),whatWasDone:m.array(m.string()).min(1),outputForNextAgent:m.string().min(1),notes:m.string().optional()}),hr=m.object({output:m.string().min(1,"Subtask output is required"),summary:We}),yr=m.object({id:m.string(),description:m.string(),domain:m.string(),agent:m.string(),status:wo,dependsOn:m.array(m.string()),startedAt:m.string().optional(),completedAt:m.string().optional(),output:m.string().optional(),summary:We.optional(),skipReason:m.string().optional(),blockReason:m.string().optional(),estimatedPoints:m.number().optional(),estimatedMinutes:m.number().optional()}),Tr=m.object({completed:m.number(),total:m.number(),percentage:m.number()}),Xe=m.object({id:m.string(),description:m.string(),type:te.optional(),startedAt:m.string(),sessionId:m.string(),featureId:m.string().optional(),subtasks:m.array(yr).optional(),currentSubtaskIndex:m.number().optional(),subtaskProgress:Tr.optional(),linearId:m.string().optional(),linearUuid:m.string().optional(),estimatedPoints:m.number().optional(),estimatedMinutes:m.number().optional(),modelMetadata:Wt.optional(),tokensIn:m.number().optional(),tokensOut:m.number().optional(),parentDescription:m.string().optional(),branch:m.string().optional(),prUrl:m.string().optional()}),fr=m.object({id:m.string(),description:m.string(),status:m.literal("paused"),startedAt:m.string(),pausedAt:m.string(),pauseReason:m.string().optional(),type:te.optional(),sessionId:m.string().optional(),featureId:m.string().optional(),subtasks:m.array(yr).optional(),currentSubtaskIndex:m.number().optional(),subtaskProgress:Tr.optional(),linearId:m.string().optional(),linearUuid:m.string().optional(),estimatedPoints:m.number().optional(),estimatedMinutes:m.number().optional(),modelMetadata:Wt.optional(),tokensIn:m.number().optional(),tokensOut:m.number().optional()}),Eo=m.object({stackConfirmed:m.array(m.string()).optional(),patternsDiscovered:m.array(m.string()).optional(),agentAccuracy:m.array(m.object({agent:m.string(),rating:m.enum(["helpful","neutral","inaccurate"]),note:m.string().optional()})).optional(),issuesEncountered:m.array(m.string()).optional()}),ko=m.object({taskId:m.string(),title:m.string(),classification:te,startedAt:m.string(),completedAt:m.string(),subtaskCount:m.number(),subtaskSummaries:m.array(We),outcome:m.string(),branchName:m.string(),linearId:m.string().optional(),linearUuid:m.string().optional(),prUrl:m.string().optional(),feedback:Eo.optional(),tokensIn:m.number().optional(),tokensOut:m.number().optional()}),So=Xe.extend({workspaceId:m.string(),worktreePath:m.string().optional(),agentSessionId:m.string().optional(),jiraId:m.string().optional(),jiraUuid:m.string().optional(),dispatchedFrom:m.string().optional()}),wr=m.object({currentTask:Xe.nullable(),previousTask:fr.nullable().optional(),pausedTasks:m.array(fr).optional(),taskHistory:m.array(ko).optional(),activeTasks:m.array(So).optional(),lastUpdated:m.string()}),br=m.object({id:m.string(),description:m.string(),body:m.string().optional(),priority:yo,type:te,featureId:m.string().optional(),originFeature:m.string().optional(),completed:m.boolean(),completedAt:m.string().optional(),createdAt:m.string(),section:To,agent:m.string().optional(),groupName:m.string().optional(),groupId:m.string().optional()}),Er=m.object({tasks:m.array(br),lastUpdated:m.string()}),xo=m.object({tasksToday:m.number(),tasksThisWeek:m.number(),streak:m.number(),velocity:m.string(),avgDuration:m.string()}),_o=m.object({type:bo,description:m.string(),timestamp:m.string(),duration:m.string().optional()}),Zu=m.object({projectId:m.string(),currentTask:Xe.nullable(),queue:m.array(br),stats:xo,recentActivity:m.array(_o),lastSync:m.string()});W();var Dt={idle:{transitions:["task","next"],prompt:"p. task <description> Start working",description:"No active task"},working:{transitions:["done","pause"],prompt:"p. done Complete task | p. pause Switch context",description:"Task in progress"},paused:{transitions:["resume","task","ship"],prompt:"p. resume Continue | p. task <new> Start different | p. ship Ship directly",description:"Task paused"},completed:{transitions:["ship","task","next","pause","reopen"],prompt:"p. ship Ship it | p. task <next> Start next | p. reopen Reopen for rework",description:"Task completed"},shipped:{transitions:["task","next"],prompt:"p. task <description> Start new task",description:"Feature shipped"}},He=class{static{l(this,"WorkflowStateMachine")}getCurrentState(t,e){let r=null;if(e&&t?.activeTasks?.length&&(r=t.activeTasks.find(s=>s.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){let r=Dt[t];if(r.transitions.includes(e))return{valid:!0};let n=r.transitions.map(s=>`p. ${s}`).join(", ");return{valid:!1,error:`Cannot run 'p. ${e}' in ${t} state`,suggestion:`Valid commands: ${n}`}}getNextState(t,e){switch(e){case"task":return"working";case"done":return"completed";case"pause":return"paused";case"resume":return"working";case"ship":return"shipped";case"reopen":return"working";case"next":return t;default:return t}}getStateInfo(t){return Dt[t]}getPrompt(t){return Dt[t].prompt}getValidCommands(t){return Dt[t].transitions}formatNextSteps(t){return Dt[t].transitions.map(r=>{switch(r){case"task":return"p. task <desc> Start new task";case"done":return"p. done Complete current task";case"pause":return"p. pause Pause and switch context";case"resume":return"p. resume Continue paused task";case"ship":return"p. ship Ship the feature";case"reopen":return"p. reopen Reopen for rework";case"next":return"p. next View task queue";default:return`p. ${r}`}})}},Be=new He;W();var ee={SHIPPED_RETENTION_DAYS:90,IDEA_DORMANT_DAYS:180,QUEUE_COMPLETED_DAYS:7,PAUSED_TASK_DAYS:30,MEMORY_MAX_ENTRIES:500},Ge=class{static{l(this,"ArchiveStorage")}archive(t,e){let r=F(),n=f();return _.run(t,"INSERT INTO archives (id, entity_type, entity_id, entity_data, summary, archived_at, reason) VALUES (?, ?, ?, ?, ?, ?, ?)",r,e.entityType,e.entityId,JSON.stringify(e.entityData),e.summary??null,n,e.reason),r}archiveMany(t,e){if(e.length===0)return 0;let r=f();return _.transaction(t,n=>{let s=n.prepare("INSERT INTO archives (id, entity_type, entity_id, entity_data, summary, archived_at, reason) VALUES (?, ?, ?, ?, ?, ?, ?)");for(let o of e)s.run(F(),o.entityType,o.entityId,JSON.stringify(o.entityData),o.summary??null,r,o.reason)}),e.length}getArchived(t,e,r=50){return e?_.query(t,"SELECT * FROM archives WHERE entity_type = ? ORDER BY archived_at DESC LIMIT ?",e,r):_.query(t,"SELECT * FROM archives ORDER BY archived_at DESC LIMIT ?",r)}getStats(t){let e=_.query(t,"SELECT entity_type, COUNT(*) as count FROM archives GROUP BY entity_type"),r={shipped:0,idea:0,queue_task:0,paused_task:0,memory_entry:0,total:0};for(let n of e){let s=n.entity_type;s in r&&(r[s]=n.count),r.total+=n.count}return r}restore(t,e){let r=_.get(t,"SELECT * FROM archives WHERE id = ?",e);return r?(_.run(t,"DELETE FROM archives WHERE id = ?",e),JSON.parse(r.entity_data)):null}pruneOldArchives(t,e){let r=new Date(Date.now()-e*24*60*60*1e3).toISOString(),n=this.getTotalCount(t);_.run(t,"DELETE FROM archives WHERE archived_at < ?",r);let s=this.getTotalCount(t);return n-s}getTotalCount(t){return _.get(t,"SELECT COUNT(*) as count FROM archives")?.count??0}},St=new Ge;W();st();var qe=class{static{l(this,"SyncEventBus")}async publish(t){let e=A.getSyncPendingPath(t.projectId),r=await Ut(e,[])??[];r.push(t),await rt(e,r)}async getPending(t){let e=A.getSyncPendingPath(t);return await Ut(e,[])??[]}async clearPending(t){let e=A.getSyncPendingPath(t);await rt(e,[])}async updateLastSync(t){let e=A.getLastSyncPath(t),r={timestamp:f(),success:!0};await rt(e,r)}async getLastSync(t){let e=A.getLastSyncPath(t);return await Ut(e,null)}},kr=new qe;me();W();var pt=class{static{l(this,"StorageManager")}filename;cache;constructor(t,e){this.filename=t,this.cache=new Xt({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=_.getDoc(t,this.getStoreKey());if(r!==null)return this.cache.set(t,r),r}catch{}return this.getDefault()}async write(t,e){_.setDoc(t,this.getStoreKey(),e),this.cache.set(t,e)}async update(t,e){let r=await this.read(t),n=e(r);return await this.write(t,n),n}async publishEvent(t,e,r){let n={type:e,path:[this.filename.replace(".json","")],data:r,timestamp:f(),projectId:t};await kr.publish(n)}async publishEntityEvent(t,e,r,n){let s=`${e}.${r}`,o={...n,timestamp:f()};await this.publishEvent(t,s,o)}async exists(t){try{return _.hasDoc(t,this.getStoreKey())}catch{return!1}}clearCache(t){t?this.cache.delete(t):this.cache.clear()}getCacheStats(){return this.cache.stats()}};var ze=class extends pt{static{l(this,"StateStorage")}constructor(){super("state.json",wr)}getDefault(){return{currentTask:null,previousTask:null,pausedTasks:[],taskHistory:[],activeTasks:[],lastUpdated:""}}getEventType(t){return`state.${t}d`}validateTransition(t,e){let r=Be.getCurrentState(t),n=Be.canTransition(r,e);if(!n.valid)throw new Error(`${n.error}. ${n.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 n={...e,startedAt:f()};return await this.update(t,s=>({...s,currentTask:n,lastUpdated:f()})),await this.publishEvent(t,"task.started",{taskId:n.id,description:n.description,startedAt:n.startedAt,sessionId:n.sessionId}),n}async updateCurrentTask(t,e){let r=await this.read(t);if(!r.currentTask)return null;let n={...r.currentTask,...e};return await this.update(t,s=>({...s,currentTask:n,lastUpdated:f()})),n}async completeTask(t,e){let r=await this.read(t),n=r.currentTask;if(!n)return null;this.validateTransition(r,"done");let s=f(),o=this.createTaskHistoryEntry(n,s,e),a=this.getTaskHistoryFromState(r),c=[o,...a].slice(0,this.maxTaskHistory);return await this.update(t,u=>({...u,currentTask:null,previousTask:null,taskHistory:c,lastUpdated:s})),await this.publishEvent(t,"task.completed",{taskId:n.id,description:n.description,startedAt:n.startedAt,completedAt:s}),n}createTaskHistoryEntry(t,e,r){let n=(t.subtasks||[]).filter(a=>a.status==="completed"&&a.summary).map(a=>a.summary),s=n.length>0?n.map(a=>a.title).join(", "):"Task completed",o={taskId:t.id,title:t.parentDescription||t.description,classification:t.type||"improvement",startedAt:t.startedAt,completedAt:e,subtaskCount:t.subtasks?.length||0,subtaskSummaries:n,outcome:s,branchName:t.branch||"unknown",linearId:t.linearId,linearUuid:t.linearUuid,prUrl:t.prUrl};return r&&(o.feedback=r),t.tokensIn&&(o.tokensIn=t.tokensIn),t.tokensOut&&(o.tokensOut=t.tokensOut),o}maxPausedTasks=5;maxTaskHistory=20;stalenessThresholdDays=30;async pauseTask(t,e){let r=await this.read(t);if(!r.currentTask)return null;this.validateTransition(r,"pause");let n={...r.currentTask,status:"paused",pausedAt:f(),pauseReason:e},s=this.getPausedTasksFromState(r),o=[n,...s].slice(0,this.maxPausedTasks);return await this.update(t,a=>({...a,currentTask:null,previousTask:null,pausedTasks:o,lastUpdated:f()})),await this.publishEvent(t,"task.paused",{taskId:n.id,description:n.description,pausedAt:n.pausedAt,reason:e,pausedCount:o.length}),n}async resumeTask(t,e){let r=await this.read(t),n=this.getPausedTasksFromState(r);if(n.length===0)return null;this.validateTransition(r,"resume");let s=0;if(e&&(s=n.findIndex(h=>h.id===e),s===-1))return null;let o=n[s],a=n.filter((h,j)=>j!==s),{status:c,pausedAt:u,pauseReason:p,...d}=o,g={...d,startedAt:f(),sessionId:o.sessionId??F()};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 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),n=Date.now()-this.stalenessThresholdDays*24*60*60*1e3;return r.filter(s=>new Date(s.pausedAt).getTime()<n)}async archiveStalePausedTasks(t){let e=await this.read(t),r=this.getPausedTasksFromState(e),n=Date.now()-this.stalenessThresholdDays*24*60*60*1e3,s=r.filter(a=>new Date(a.pausedAt).getTime()<n),o=r.filter(a=>new Date(a.pausedAt).getTime()>=n);if(s.length===0)return[];St.archiveMany(t,s.map(a=>({entityType:"paused_task",entityId:a.id,entityData:a,summary:a.description,reason:"staleness"}))),await this.update(t,a=>({...a,pausedTasks:o,previousTask:null,lastUpdated:f()}));for(let a of s)await this.publishEvent(t,"task.archived",{taskId:a.id,description:a.description,pausedAt:a.pausedAt,reason:"staleness"});return s}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(s=>s.classification===e)}async getAggregatedFeedback(t){let r=(await this.getTaskHistory(t)).filter(g=>g.feedback),n=[],s=[],o=[],a=[];for(let g of r){let h=g.feedback;Array.isArray(h.stackConfirmed)&&n.push(...h.stackConfirmed),Array.isArray(h.patternsDiscovered)&&s.push(...h.patternsDiscovered),Array.isArray(h.agentAccuracy)&&o.push(...h.agentAccuracy),Array.isArray(h.issuesEncountered)&&a.push(...h.issuesEncountered)}let c=[...new Set(n)],u=[...new Set(s)],p=new Map;for(let g of a)p.set(g,(p.get(g)||0)+1);let d=[...p.entries()].filter(([g,h])=>h>=2).map(([g])=>g);return{stackConfirmed:c,patternsDiscovered:u,agentAccuracy:o,issuesEncountered:[...new Set(a)],knownGotchas:d}}async startTaskInWorkspace(t,e,r){let n={...e,workspaceId:r,startedAt:f()};return await this.update(t,s=>({...s,activeTasks:[...s.activeTasks||[],n],lastUpdated:f()})),await this.publishEvent(t,"task.started",{taskId:n.id,description:n.description,startedAt:n.startedAt,sessionId:n.sessionId,workspaceId:r}),n}async getCurrentTaskForWorkspace(t,e){return((await this.read(t)).activeTasks||[]).find(n=>n.workspaceId===e)??null}async completeTaskInWorkspace(t,e,r){let n=await this.read(t),o=(n.activeTasks||[]).find(d=>d.workspaceId===e);if(!o)return null;let a=f(),c=this.createTaskHistoryEntry(o,a,r),u=this.getTaskHistoryFromState(n),p=[c,...u].slice(0,this.maxTaskHistory);return await this.update(t,d=>({...d,activeTasks:(d.activeTasks||[]).filter(g=>g.workspaceId!==e),taskHistory:p,lastUpdated:a})),await this.publishEvent(t,"task.completed",{taskId:o.id,description:o.description,startedAt:o.startedAt,completedAt:a,workspaceId:e}),o}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 s=(await this.read(t)).activeTasks||[],o=s.findIndex(c=>c.workspaceId===e);if(o===-1)return null;let a={...s[o],...r,workspaceId:e};return await this.update(t,c=>{let u=[...c.activeTasks||[]];return u[o]=a,{...c,activeTasks:u,lastUpdated:f()}}),a}async addTokens(t,e,r){let n=await this.read(t);if(!n.currentTask)return null;let s=(n.currentTask.tokensIn||0)+e,o=(n.currentTask.tokensOut||0)+r;return await this.update(t,a=>({...a,currentTask:{...a.currentTask,tokensIn:s,tokensOut:o},lastUpdated:f()})),{tokensIn:s,tokensOut:o}}async createSubtasks(t,e){let r=await this.read(t);if(!r.currentTask)return;let n=e.map((s,o)=>({...s,status:o===0?"in_progress":"pending",startedAt:o===0?f():void 0,dependsOn:s.dependsOn||[]}));await this.update(t,s=>({...s,currentTask:{...s.currentTask,subtasks:n,currentSubtaskIndex:0,subtaskProgress:{completed:0,total:n.length,percentage:0}},lastUpdated:f()})),await this.publishEvent(t,"subtasks.created",{taskId:r.currentTask.id,subtaskCount:n.length,subtasks:n.map(s=>({id:s.id,description:s.description,domain:s.domain}))})}async completeSubtask(t,e){let r=hr.safeParse(e);if(!r.success){let j=r.error.issues.map(w=>`${w.path.join(".")}: ${w.message}`);throw new Error(`Subtask completion requires handoff data:
551
- ${j.join(`
552
- `)}`)}let{output:n,summary:s}=r.data,o=await this.read(t);if(!o.currentTask?.subtasks)return null;let a=o.currentTask.currentSubtaskIndex||0,c=o.currentTask.subtasks[a];if(!c)return null;let u=[...o.currentTask.subtasks];u[a]={...c,status:"completed",completedAt:f(),output:n,summary:s};let p=u.filter(j=>j.status==="completed").length,d=u.length,g=Math.round(p/d*100),h=a+1;return h<u.length&&(u[h]={...u[h],status:"in_progress",startedAt:f()}),await this.update(t,j=>({...j,currentTask:{...j.currentTask,subtasks:u,currentSubtaskIndex:h<d?h:a,subtaskProgress:{completed:p,total:d,percentage:g}},lastUpdated:f()})),await this.publishEvent(t,"subtask.completed",{taskId:o.currentTask.id,subtaskId:c.id,description:c.description,output:n,handoff:s.outputForNextAgent,filesChanged:s.filesChanged.length,progress:{completed:p,total:d,percentage:g}}),h<d?u[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 n=r.currentTask.currentSubtaskIndex||0,s=r.currentTask.subtasks[n];if(!s)return null;let o=[...r.currentTask.subtasks];o[n]={...s,status:"failed",completedAt:f(),output:`Failed: ${e}`};let a=n+1,c=o.length;a<c&&(o[a]={...o[a],status:"in_progress",startedAt:f()});let u=o.filter(d=>d.status==="completed"||d.status==="failed"||d.status==="skipped").length,p=Math.round(u/c*100);return await this.update(t,d=>({...d,currentTask:{...d.currentTask,subtasks:o,currentSubtaskIndex:a<c?a:n,subtaskProgress:{completed:u,total:c,percentage:p}},lastUpdated:f()})),await this.publishEvent(t,"subtask.failed",{taskId:r.currentTask.id,subtaskId:s.id,description:s.description,error:e}),a<c?o[a]:null}async skipSubtask(t,e){let r=await this.read(t);if(!r.currentTask?.subtasks)return null;let n=r.currentTask.currentSubtaskIndex||0,s=r.currentTask.subtasks[n];if(!s)return null;let o=[...r.currentTask.subtasks];o[n]={...s,status:"skipped",completedAt:f(),output:`Skipped: ${e}`,skipReason:e};let a=n+1,c=o.length;a<c&&(o[a]={...o[a],status:"in_progress",startedAt:f()});let u=o.filter(d=>d.status==="completed"||d.status==="failed"||d.status==="skipped").length,p=Math.round(u/c*100);return await this.update(t,d=>({...d,currentTask:{...d.currentTask,subtasks:o,currentSubtaskIndex:a<c?a:n,subtaskProgress:{completed:u,total:c,percentage:p}},lastUpdated:f()})),await this.publishEvent(t,"subtask.skipped",{taskId:r.currentTask.id,subtaskId:s.id,description:s.description,reason:e}),a<c?o[a]:null}async blockSubtask(t,e){let r=await this.read(t);if(!r.currentTask?.subtasks)return null;let n=r.currentTask.currentSubtaskIndex||0,s=r.currentTask.subtasks[n];if(!s)return null;let o=[...r.currentTask.subtasks];o[n]={...s,status:"blocked",output:`Blocked: ${e}`,blockReason:e};let a=n+1,c=o.length;return a<c&&(o[a]={...o[a],status:"in_progress",startedAt:f()}),await this.update(t,u=>({...u,currentTask:{...u.currentTask,subtasks:o,currentSubtaskIndex:a<c?a:n},lastUpdated:f()})),await this.publishEvent(t,"subtask.blocked",{taskId:r.currentTask.id,subtaskId:s.id,description:s.description,blocker:e}),a<c?o[a]:null}},X=new ze;ft();ht();import vo from"node:fs/promises";import ne from"node:path";var Po={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"]},jo=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".py",".go",".rs",".java",".kt",".swift",".rb",".php",".c",".cpp",".h",".hpp",".cs",".vue",".svelte"]),Ro=new Set(["node_modules",".git","dist","build",".next",".nuxt",".output","coverage",".cache","__pycache__",".pytest_cache","vendor","target",".turbo",".vercel"]);async function Sr(i,t,e={}){let r=Date.now(),n=e.maxFiles??30,s=e.minScore??.1,o=e.includeTests??!1,a=Ao(i),c=await Co(t),u=await Do(t),p=[];for(let g of c){if(!o&&Io(g))continue;let h=No(g,a,u,e.historicalBoosts);h.score>=s&&p.push(h)}p.sort((g,h)=>h.score-g.score);let d=p.slice(0,n);return{files:d,metrics:{filesScanned:c.length,filesReturned:d.length,scanDuration:Date.now()-r}}}l(Sr,"findRelevantFiles");function Ao(i){let t=i.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)}l(Ao,"extractKeywords");async function Co(i){let t=[];async function e(r,n=""){try{let s=await vo.readdir(r,{withFileTypes:!0});for(let o of s){let a=ne.join(r,o.name),c=ne.join(n,o.name);if(o.isDirectory()){if(Ro.has(o.name)||o.name.startsWith("."))continue;await e(a,c)}else if(o.isFile()){let u=ne.extname(o.name).toLowerCase();jo.has(u)&&t.push(c)}}}catch(s){H(s)}}return l(e,"walk"),await e(i),t}l(Co,"getAllCodeFiles");async function Do(i){let t=new Map;try{let{stdout:e}=await R(`git log -30 --pretty=format:"%H %ct" --name-only | awk '
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,Ms=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 js(){if(gt)return gt;try{let n=ft.join(nr(),"package.json"),t=JSON.parse(Gt.readFileSync(n,"utf-8"));return gt=t.version,Ms=t,gt}catch(n){return console.error("Failed to read version from package.json:",ke(n)),"0.0.0"}}c(js,"getVersion");var Bt=js(),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 j(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 j(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
+ ### Directly Changed (${o.directlyChanged.length})`);for(let u of o.directlyChanged)a.push(`- ${u}`);if(o.affectedByImports.length>0){a.push(`
493
+ ### Affected via Imports (${o.affectedByImports.length})`);for(let u of o.affectedByImports)a.push(`- ${u}`)}return a.push(`
494
+ ### Affected Domains`),a.push(i.size>0?Array.from(i).join(", "):"none detected"),a.push(`
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}`,`
497
+ ### Imports (${i.length})`,...i.map(p=>`- ${p}`),`
498
+ ### Imported By (${a.length})`,...a.map(p=>`- ${p}`)].join(`
499
+ `)}]}}return{content:[{type:"text",text:["## Import Graph Stats",`Files: ${s.fileCount}`,`Edges: ${s.edgeCount}`,`Built: ${s.builtAt}`].join(`
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","next"],prompt:"p. task <description> Start working",description:"No active task"},working:{transitions:["done","pause"],prompt:"p. done Complete task | p. pause Switch context",description:"Task in progress"},paused:{transitions:["resume","task","ship"],prompt:"p. resume Continue | p. task <new> Start different | p. ship Ship directly",description:"Task paused"},completed:{transitions:["ship","task","next","pause","reopen"],prompt:"p. ship Ship it | p. task <next> Start next | p. reopen Reopen for rework",description:"Task completed"},shipped:{transitions:["task","next"],prompt:"p. 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){let r=st[t];if(r.transitions.includes(e))return{valid:!0};let s=r.transitions.map(o=>`p. ${o}`).join(", ");return{valid:!1,error:`Cannot run 'p. ${e}' in ${t} state`,suggestion:`Valid commands: ${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";case"next":return t;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"p. task <desc> Start new task";case"done":return"p. done Complete current task";case"pause":return"p. pause Pause and switch context";case"resume":return"p. resume Continue paused task";case"ship":return"p. ship Ship the feature";case"reopen":return"p. reopen Reopen for rework";case"next":return"p. next View task queue";default:return`p. ${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 j(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 j(e,[])}async updateLastSync(t){let e=b.getLastSyncPath(t),r={timestamp:f(),success:!0};await j(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,M)=>M!==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 M=r.error.issues.map(it=>`${it.path.join(".")}: ${it.message}`);throw new Error(`Subtask completion requires handoff data:
503
+ ${M.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(M=>M.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,M=>({...M,currentTask:{...M.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 '
553
505
  /^[a-f0-9]{40}/ { commit=$1; timestamp=$2; next }
554
506
  NF { files[$0]++; if (!lastmod[$0]) lastmod[$0]=timestamp }
555
507
  END { for (f in files) print files[f], lastmod[f], f }
556
- '`,{cwd:i,maxBuffer:10485760}),r=Math.floor(Date.now()/1e3),n=e.trim().split(`
557
- `).filter(Boolean);for(let s of n){let o=s.match(/^(\d+)\s+(\d+)\s+(.+)$/);if(o){let a=parseInt(o[1],10),c=parseInt(o[2],10),u=o[3],p=Math.floor((r-c)/86400);t.set(u,{commits:a,daysAgo:p})}}}catch{}return t}l(Do,"getGitRecency");function No(i,t,e,r){let n=[],s=0,o=0,a=0,c=0,u=0,p=i.toLowerCase(),d=p.split("/").join(" ").split(/[^a-z0-9]+/);for(let k of t){p.includes(k)&&(s+=.3,n.push(`keyword:${k}`));for(let I of d)if(I.includes(k)||k.includes(I)){s+=.15;break}}s=Math.min(1,s);for(let[k,I]of Object.entries(Po))for(let z of I)if(p.includes(z)&&t.some(wt=>I.includes(wt)||wt.includes(k)||k.includes(wt))){o+=.4,n.push(`domain:${k}`);break}o=Math.min(1,o);let g=e.get(i);g&&(g.daysAgo<=1?(a=1,n.push("recent:1d")):g.daysAgo<=3?(a=.8,n.push("recent:3d")):g.daysAgo<=7?(a=.6,n.push("recent:1w")):g.daysAgo<=30&&(a=.3,n.push("recent:1m")),g.commits>=5&&(a=Math.min(1,a+.2)));let h=ne.basename(i).toLowerCase();if((h.includes("index")||h.includes("main")||h.includes("app")||h.includes("entry"))&&(c=.5,n.push("import:0")),(p.includes("/core/")||p.includes("/shared/")||p.includes("/lib/"))&&(c=Math.max(c,.3),n.some(k=>k.startsWith("import:"))||n.push("import:1")),r){let k=r.get(i);k!==void 0&&(u=(k+1)/2,k>0?n.push("history:boosted"):k<0&&n.push("history:penalized"))}let w=r&&r.size>0?s*.54+o*.18+a*.13+c*.05+u*.1:s*.6+o*.2+a*.15+c*.05;return{path:i,score:Math.min(1,w),reasons:[...new Set(n)]}}l(No,"scoreFile");function Io(i){let t=i.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")}l(Io,"isTestFile");ft();import Fo from"node:fs/promises";import xt from"node:path";var Oo={"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}},Lo="claude-sonnet-4.5";function Ve(i){return!i||i.length===0?0:Math.ceil(i.length/4)}l(Ve,"countTokens");var _r=["claude-sonnet-4.5","claude-opus-4.5","claude-opus-4-6","gpt-4o","gemini-1.5-pro"];function xr(i,t){let e=Oo[t],r=i/1e3*e.input,n=i/1e3*e.output*.3;return{inputSaved:r,outputPotential:n,total:r+n}}l(xr,"calculateModelCost");function $o(i){return i<.001?"<$0.01":i<.01?`$${i.toFixed(3)}`:`$${i.toFixed(2)}`}l($o,"formatCostSaved");function vr(i,t){let e=Ve(i),r=Ve(t),n=Math.max(0,e-r),s=e>0?(e-r)/e:0,o=xr(n,Lo),a=_r.map(c=>({model:c,...xr(n,c)}));return{tokens:{original:e,filtered:r,saved:n},compression:Math.max(0,Math.min(1,s)),cost:{saved:o.total,formatted:$o(o.total),byModel:a}}}l(vr,"measureCompression");function re(i){let t=Ve(i);return{tokens:{original:t,filtered:t,saved:0},compression:0,cost:{saved:0,formatted:"$0.00",byModel:_r.map(e=>({model:e,inputSaved:0,outputPotential:0,total:0}))}}}l(re,"noCompression");var Uo={".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"},Pr=[{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}],Wo=[{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}],Xo=[{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}],Ho=[{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}],jr=[{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}],Bo={typescript:Pr,javascript:Pr,python:Wo,go:Xo,rust:Ho,java:jr,csharp:jr,php:[],ruby:[],unknown:[]};async function Rr(i,t=process.cwd()){let e=xt.isAbsolute(i)?i:xt.join(t,i),r=xt.resolve(t),n=xt.resolve(e);if(!n.startsWith(r+xt.sep)&&n!==r)return{file:i,language:"unknown",signatures:[],fallback:!0,fallbackReason:"Path traversal denied: file is outside project directory",metrics:re("")};let s;try{s=await Fo.readFile(e,"utf-8")}catch(d){if(H(d))return{file:i,language:"unknown",signatures:[],fallback:!0,fallbackReason:"File not found",metrics:re("")};throw d}let o=xt.extname(i).toLowerCase(),a=Uo[o]||"unknown",c=Bo[a];if(!c||c.length===0)return{file:i,language:a,signatures:[],fallback:!0,fallbackReason:`No extraction patterns for ${a}`,metrics:re(s)};let u=Go(s,c),p=u.map(d=>`${d.exported?"export ":""}${d.type} ${d.name}: ${d.signature}`).join(`
558
- `);return{file:i,language:a,signatures:u,fallback:!1,metrics:vr(s,p)}}l(Rr,"extractSignatures");function Go(i,t){let e=[],r=i.split(`
559
- `),n=new Set;for(let s of t){s.pattern.lastIndex=0;let o;for(;(o=s.pattern.exec(i))!==null;){let a=o[s.nameIndex];if(!a)continue;let c=`${s.type}:${a}`;if(n.has(c))continue;n.add(c);let u=o.index,p=i.substring(0,u).split(`
560
- `).length,d=o[0].trim(),g;if(p>1){let h=r[p-2]?.trim();(h?.startsWith("/**")||h?.startsWith("///")||h?.startsWith("#"))&&(g=h)}e.push({type:s.type,name:a,signature:qo(d),exported:s.exported||!1,line:p,docstring:g})}}return e.sort((s,o)=>s.line-o.line)}l(Go,"extractFromContent");function qo(i){return i.replace(/\{$/,"").replace(/\s+/g," ").trim()}l(qo,"cleanSignature");function Ar(i){let t=i;t.tool("prjct_relevant_files","BM25-ranked files relevant to a query",{projectPath:yt.string().describe("Project directory path"),query:yt.string().describe("Task or query to find relevant files for"),maxFiles:yt.number().optional().default(10).describe("Max files to return")},y("prjct_relevant_files",async e=>{let r=await Sr(e.query,e.projectPath,{maxFiles:e.maxFiles,minScore:.1});if(r.files.length===0)return{content:[{type:"text",text:"No relevant files found."}]};let n=r.files.map(o=>`- \`${o.path}\` (score: ${Math.round(o.score*100)}%) \u2014 ${o.reasons.join(", ")}`);return{content:[{type:"text",text:`## Relevant Files (${r.files.length}/${r.metrics.filesScanned} scanned)
561
-
562
- ${n.join(`
563
- `)}`}]}})),t.tool("prjct_signatures","Code signatures from a file (90% token reduction vs full content)",{projectPath:yt.string().describe("Project directory path"),filePath:yt.string().describe("Relative file path to extract signatures from")},y("prjct_signatures",async e=>{let r=await Rr(e.filePath,e.projectPath);if(r.signatures.length===0)return{content:[{type:"text",text:r.fallback?`No signatures extracted: ${r.fallbackReason}`:"No signatures found."}]};let n=r.signatures.map(a=>`${a.exported?"export ":""}${a.type} ${a.name}: ${a.signature}${a.docstring?` // ${a.docstring}`:""}`),s=r.metrics?.compression?` (${Math.round(r.metrics.compression*100)}% reduction)`:"";return{content:[{type:"text",text:`## ${r.file} (${r.language})
564
- \`\`\`
565
- ${n.join(`
566
- `)}
567
- \`\`\`${s}`}]}})),t.tool("prjct_history","Recent completed tasks with outcomes",{projectPath:yt.string().describe("Project directory path"),limit:yt.number().optional().default(10).describe("Max results")},y("prjct_history",async e=>{let r=await b(e.projectPath),n=await X.getTaskHistory(r);if(n.length===0)return{content:[{type:"text",text:"No task history."}]};let o=n.slice(-e.limit).reverse().map(c=>{let u=[`- **${c.title}**`];return c.completedAt&&u.push(`completed: ${c.completedAt}`),c.classification&&u.push(`type: ${c.classification}`),u.join(" | ")});return{content:[{type:"text",text:`## Task History (${n.length} total)
568
-
569
- ${o.join(`
570
- `)}`}]}}))}l(Ar,"registerFileTools");import{z as x}from"zod";var at=new et,zo=new kt,Cr=3e3,Dr=`
571
- ... [truncated]`;function Ye(i){return i.replace(/<private>[\s\S]*?<\/private>/gi,"").trim()}l(Ye,"stripPrivateTags");function Je(i){return i.length<=Cr?i:i.slice(0,Cr-Dr.length)+Dr}l(Je,"truncateContent");var Ke=[{prefix:"architecture",keywords:["design","structure","system","module","layer","pattern","dependency","api"],description:"System design decisions"},{prefix:"pattern",keywords:["pattern","convention","style","approach","technique","idiom"],description:"Code patterns discovered"},{prefix:"bug",keywords:["bug","fix","error","issue","crash","broken","regression","debug"],description:"Bugs found and fixed"},{prefix:"decision",keywords:["decided","chose","selected","prefer","switched","migrated","replaced"],description:"Technical decisions made"},{prefix:"config",keywords:["config","setting","env","variable","flag","option","parameter"],description:"Configuration preferences"},{prefix:"workflow",keywords:["workflow","process","pipeline","deploy","ci","cd","release","ship"],description:"Process preferences"},{prefix:"convention",keywords:["naming","format","lint","style","indent","import","export","case"],description:"Naming, formatting, style"},{prefix:"preference",keywords:["prefer","like","always","never","use","avoid","want"],description:"User preferences"}];function Nr(i){let t=i;t.tool("prjct_mem_save","Save a memory with title, content, tags, and optional topic_key for upsert. Strips <private> tags and truncates at 3K chars.",{projectPath:x.string().describe("Project directory path"),title:x.string().describe("Memory title"),content:x.string().describe("Memory content"),tags:x.array(x.string()).optional().describe("Tags for categorization"),topicKey:x.string().optional().describe("Topic key for upsert (e.g. decision/auth-strategy, bug/cors-issue)"),sessionId:x.string().optional().describe("Current session ID to link this memory to")},y("prjct_mem_save",async e=>{let r=await b(e.projectPath),n=Je(Ye(e.content)),s=await at.createMemory(r,{title:e.title,content:n,tags:e.tags,topicKey:e.topicKey,userTriggered:!0});return e.sessionId&&T.run(r,"UPDATE memories SET session_id = ? WHERE id = ?",e.sessionId,s),{content:[{type:"text",text:`Memory saved: ${s}`}]}})),t.tool("prjct_mem_search","FTS5 search \u2014 returns compact results (title + snippet + ID). Use prjct_mem_get for full content.",{projectPath:x.string().describe("Project directory path"),query:x.string().describe("Search query"),limit:x.number().optional().default(20).describe("Max results (default 20)"),offset:x.number().optional().default(0).describe("Offset for pagination (default 0)")},y("prjct_mem_search",async e=>{let r=await b(e.projectPath),n=await at.searchMemories(r,e.query,e.limit,e.offset),s=e.query.toLowerCase(),o=[];try{let c=await zo.getPatternsSummaryDetailed(r);for(let[u,p]of Object.entries(c.decisions))(u.toLowerCase().includes(s)||p.value.toLowerCase().includes(s))&&o.push(`- **[decision] ${u}**: ${p.value} (confidence: ${p.confidence}, seen: ${p.count}x)`);for(let[u,p]of Object.entries(c.preferences)){let d=typeof p.value=="string"?p.value:JSON.stringify(p.value);(u.toLowerCase().includes(s)||d.toLowerCase().includes(s))&&o.push(`- **[preference] ${u}**: ${d} (confidence: ${p.confidence})`)}}catch{}if(n.length===0&&o.length===0)return{content:[{type:"text",text:"No memories found."}]};let a=[];if(n.length>0){let c=n.map(u=>{let p=u.content.slice(0,120).replace(/\n/g," "),d=u.tags.length>0?` [${u.tags.join(", ")}]`:"";return`- **${u.title}** (id: ${u.id})${d}
572
- ${p}${u.content.length>120?"...":""}`});a.push(`Found ${n.length} memories:
573
-
574
- ${c.join(`
575
- `)}`)}return o.length>0&&a.push(`
576
- ### Matching Patterns (${o.length})
577
- ${o.join(`
578
- `)}`),{content:[{type:"text",text:a.join(`
579
- `)}]}})),t.tool("prjct_mem_get","Get full untruncated memory content by ID (progressive disclosure step 2)",{projectPath:x.string().describe("Project directory path"),memoryId:x.string().describe("Memory ID")},y("prjct_mem_get",async e=>{let r=await b(e.projectPath),n=await at.getMemoryById(r,e.memoryId);return n?{content:[{type:"text",text:`# ${n.title}
580
-
581
- ${n.content}
582
-
583
- Tags: ${n.tags.join(", ")||"none"}
584
- Created: ${n.createdAt}
585
- Updated: ${n.updatedAt}`}]}:{content:[{type:"text",text:`Memory ${e.memoryId} not found.`}]}})),t.tool("prjct_mem_delete","Soft-delete a memory by ID",{projectPath:x.string().describe("Project directory path"),memoryId:x.string().describe("Memory ID to delete")},y("prjct_mem_delete",async e=>{let r=await b(e.projectPath);return{content:[{type:"text",text:await at.deleteMemory(r,e.memoryId)?"Memory deleted.":"Memory not found."}]}})),t.tool("prjct_mem_context","Get memories relevant to a task description",{projectPath:x.string().describe("Project directory path"),task:x.string().describe("Task description for relevance matching"),limit:x.number().optional().default(5).describe("Max results")},y("prjct_mem_context",async e=>{let r=await b(e.projectPath),n=await at.getRelevantMemories(r,{params:{description:e.task}},e.limit);return n.length===0?{content:[{type:"text",text:"No relevant memories."}]}:{content:[{type:"text",text:n.map(o=>`- **${o.title}**: ${o.content.slice(0,200)}`).join(`
586
- `)}]}})),t.tool("prjct_mem_timeline","Chronological memories around a specific memory (progressive disclosure step 2). Shows \xB15 items in the same session.",{projectPath:x.string().describe("Project directory path"),memoryId:x.string().describe("Memory ID to center timeline on")},y("prjct_mem_timeline",async e=>{let r=await b(e.projectPath),n=T.get(r,"SELECT * FROM memories WHERE id = ? AND project_id = ? AND deleted_at IS NULL",e.memoryId,r);if(!n)return{content:[{type:"text",text:`Memory ${e.memoryId} not found.`}]};let s;if(n.session_id)s=T.query(r,`SELECT * FROM memories
587
- WHERE project_id = ? AND session_id = ? AND deleted_at IS NULL
588
- ORDER BY created_at ASC`,r,n.session_id);else{let c=T.query(r,`SELECT * FROM memories
589
- WHERE project_id = ? AND deleted_at IS NULL AND created_at < ?
590
- ORDER BY created_at DESC LIMIT 5`,r,n.created_at).reverse(),u=T.query(r,`SELECT * FROM memories
591
- WHERE project_id = ? AND deleted_at IS NULL AND created_at > ?
592
- ORDER BY created_at ASC LIMIT 5`,r,n.created_at);s=[...c,n,...u]}if(s.length===0)return{content:[{type:"text",text:"No timeline context."}]};let o=s.map(c=>{let u=c.id===e.memoryId?"\u2192":" ",p=c.content.slice(0,100).replace(/\n/g," ");return`${u} [${c.created_at}] **${c.title}** (${c.id})
593
- ${p}${c.content.length>100?"...":""}`}),a=n.session_id?`
594
- Session: ${n.session_id}`:"";return{content:[{type:"text",text:`## Timeline around "${n.title}"${a}
595
-
596
- ${o.join(`
597
- `)}`}]}})),t.tool("prjct_mem_suggest_topic","Suggest a stable topic_key based on title and content. Uses family heuristics: architecture/*, pattern/*, bug/*, decision/*, config/*, workflow/*, convention/*, preference/*",{projectPath:x.string().describe("Project directory path"),title:x.string().describe("Memory title"),content:x.string().describe("Memory content")},y("prjct_mem_suggest_topic",async e=>{let r=`${e.title} ${e.content}`.toLowerCase(),n=Ke[0],s=0;for(let d of Ke){let g=d.keywords.filter(h=>r.includes(h)).length;g>s&&(s=g,n=d)}let o=e.title.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"").slice(0,40),a=`${n.prefix}/${o}`,c=await b(e.projectPath),u=T.get(c,"SELECT id, title FROM memories WHERE project_id = ? AND topic_key = ? AND deleted_at IS NULL",c,a),p=[`Suggested topic_key: \`${a}\``,`Family: ${n.prefix} \u2014 ${n.description}`,`Confidence: ${s===0?"low (no keyword matches, defaulted)":s>=3?"high":"medium"}`];u&&p.push(`
598
- Note: This topic_key already exists \u2192 will UPDATE "${u.title}" (id: ${u.id})`),p.push(`
599
- Available families:`);for(let d of Ke)p.push(`- \`${d.prefix}/*\` \u2014 ${d.description}`);return{content:[{type:"text",text:p.join(`
600
- `)}]}})),t.tool("prjct_mem_capture_passive",'Extract structured learnings from text and save each as a memory. Looks for "Key Learnings:", "Discoveries:", "Lessons:", or "## Learnings" sections.',{projectPath:x.string().describe("Project directory path"),text:x.string().describe("Text to extract learnings from (e.g. agent output)"),sessionId:x.string().optional().describe("Current session ID")},y("prjct_mem_capture_passive",async e=>{let r=await b(e.projectPath),n=[/(?:^|\n)#{1,3}\s*(?:Key\s+)?Learnings?\s*:?\s*\n([\s\S]*?)(?=\n#{1,3}\s|\n---|\n\*\*[A-Z]|$)/i,/(?:^|\n)#{1,3}\s*Discoveries?\s*:?\s*\n([\s\S]*?)(?=\n#{1,3}\s|\n---|\n\*\*[A-Z]|$)/i,/(?:^|\n)#{1,3}\s*Lessons?\s*:?\s*\n([\s\S]*?)(?=\n#{1,3}\s|\n---|\n\*\*[A-Z]|$)/i,/(?:^|\n)\*\*(?:Key\s+)?Learnings?\*\*\s*:?\s*\n([\s\S]*?)(?=\n\*\*[A-Z]|\n#{1,3}\s|\n---|$)/i],s=[];for(let c of n){let u=e.text.match(c);if(u?.[1]){let p=u[1].split(/\n[-*•]\s+|\n\d+[.)]\s+/).map(d=>d.trim()).filter(d=>d.length>10);s.push(...p)}}if(s.length===0)return{content:[{type:"text",text:"No structured learnings found in text."}]};let o=[...new Set(s)],a=[];for(let c of o.slice(0,10)){let u=c.slice(0,80).replace(/\n/g," "),p=Je(Ye(c)),d=await at.createMemory(r,{title:u,content:p,tags:[],topicKey:`learning/${u.toLowerCase().replace(/[^a-z0-9]+/g,"-").slice(0,40)}`,userTriggered:!1});e.sessionId&&T.run(r,"UPDATE memories SET session_id = ? WHERE id = ?",e.sessionId,d),a.push(d)}return{content:[{type:"text",text:`Extracted and saved ${a.length} learnings:
601
- ${a.map((c,u)=>`- ${o[u].slice(0,60)}... (${c})`).join(`
602
- `)}`}]}})),t.tool("prjct_mem_update","Update an existing memory by ID. Partial updates supported (title, content, tags).",{projectPath:x.string().describe("Project directory path"),memoryId:x.string().describe("Memory ID to update"),title:x.string().optional().describe("New title"),content:x.string().optional().describe("New content"),tags:x.array(x.string()).optional().describe("New tags")},y("prjct_mem_update",async e=>{let r=await b(e.projectPath),n={};return e.title&&(n.title=e.title),e.content&&(n.content=Je(Ye(e.content))),e.tags&&(n.tags=e.tags),{content:[{type:"text",text:await at.updateMemory(r,e.memoryId,n)?`Memory ${e.memoryId} updated.`:"Memory not found."}]}})),t.tool("prjct_mem_stats","Memory statistics: total count, user-triggered count, tag distribution, age range",{projectPath:x.string().describe("Project directory path")},y("prjct_mem_stats",async e=>{let r=await b(e.projectPath),n=await at.getMemoryStats(r),s=["## Memory Stats",`Total: ${n.totalMemories}`,`User-triggered: ${n.userTriggered}`,`Auto-captured: ${n.totalMemories-n.userTriggered}`];n.oldestMemory&&s.push(`Oldest: ${n.oldestMemory}`),n.newestMemory&&s.push(`Newest: ${n.newestMemory}`);let o=Object.entries(n.tagCounts);if(o.length>0){s.push(`
603
- ### Tags`);for(let[a,c]of o.sort(([,u],[,p])=>p-u))s.push(`- ${a}: ${c}`)}return{content:[{type:"text",text:s.join(`
604
- `)}]}})),t.tool("prjct_mem_tags","Find memories by tags (matchAll: require all tags, default: match any)",{projectPath:x.string().describe("Project directory path"),tags:x.array(x.string()).describe("Tags to search for"),matchAll:x.boolean().optional().default(!1).describe("Require all tags to match (default: any)")},y("prjct_mem_tags",async e=>{let r=await b(e.projectPath),n=await at.findByTags(r,e.tags,e.matchAll);if(n.length===0)return{content:[{type:"text",text:"No memories found with those tags."}]};let s=n.map(o=>{let a=o.content.slice(0,120).replace(/\n/g," "),c=o.tags.length>0?` [${o.tags.join(", ")}]`:"";return`- **${o.title}** (id: ${o.id})${c}
605
- ${a}${o.content.length>120?"...":""}`});return{content:[{type:"text",text:`Found ${n.length} memories:
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(`
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
+ `),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)
606
513
 
607
514
  ${s.join(`
608
- `)}`}]}})),t.tool("prjct_mem_topic",'Browse memories by topic_key prefix (e.g. "bug/*", "decision/*")',{projectPath:x.string().describe("Project directory path"),prefix:x.string().describe('Topic key prefix to match (e.g. "bug/", "decision/")'),limit:x.number().optional().default(20).describe("Max results (default 20)")},y("prjct_mem_topic",async e=>{let r=await b(e.projectPath),n=e.prefix.endsWith("*")?`${e.prefix.slice(0,-1)}%`:e.prefix.endsWith("%")?e.prefix:`${e.prefix}%`,s=T.query(r,`SELECT * FROM memories
609
- WHERE project_id = ? AND topic_key LIKE ? AND deleted_at IS NULL
610
- ORDER BY updated_at DESC LIMIT ?`,r,n,e.limit);if(s.length===0)return{content:[{type:"text",text:`No memories found with topic prefix "${e.prefix}".`}]};let o=s.map(a=>{let c=a.content.slice(0,120).replace(/\n/g," ");return`- **${a.title}** (topic: ${a.topic_key}, id: ${a.id})
611
- ${c}${a.content.length>120?"...":""}`});return{content:[{type:"text",text:`## Memories: ${e.prefix} (${s.length})
612
-
613
- ${o.join(`
614
- `)}`}]}})),t.tool("prjct_mem_consolidate","Find and merge duplicate/similar memories (same title). Returns count merged.",{projectPath:x.string().describe("Project directory path")},y("prjct_mem_consolidate",async e=>{let r=await b(e.projectPath),n=await G.consolidateMemories(r);if(n.merged===0)return{content:[{type:"text",text:"No duplicate memories found."}]};let s=["## Consolidation Complete",`Merged: ${n.merged} duplicate memories
615
- `];for(let o of n.groups)s.push(`- Kept ${o.kept}, merged ${o.merged.length} duplicates`);return{content:[{type:"text",text:s.join(`
616
- `)}]}})),t.tool("prjct_feedback_aggregate","Aggregated task feedback: confirmed stack, gotchas, agent accuracy",{projectPath:x.string().describe("Project directory path")},y("prjct_feedback_aggregate",async e=>{let r=await b(e.projectPath),n=await X.getAggregatedFeedback(r),s=["## Aggregated Task Feedback"];if(n.stackConfirmed.length>0&&(s.push(`
617
- ### Confirmed Stack`),s.push(n.stackConfirmed.join(", "))),n.patternsDiscovered.length>0){s.push(`
618
- ### Patterns Discovered`);for(let a of n.patternsDiscovered)s.push(`- ${a}`)}if(n.knownGotchas.length>0){s.push(`
619
- ### Known Gotchas`);for(let a of n.knownGotchas)s.push(`- ${a}`)}if(n.agentAccuracy.length>0){s.push(`
620
- ### Agent Accuracy`);for(let a of n.agentAccuracy)s.push(`- ${a.agent}: ${a.rating}${a.note?` \u2014 ${a.note}`:""}`)}if(n.issuesEncountered.length>0){s.push(`
621
- ### Issues Encountered`);for(let a of n.issuesEncountered)s.push(`- ${a}`)}return n.stackConfirmed.length===0&&n.patternsDiscovered.length===0&&n.knownGotchas.length===0&&s.push(`
622
- No task feedback recorded yet.`),{content:[{type:"text",text:s.join(`
623
- `)}]}}))}l(Nr,"registerMemoryTools");import Gr from"node:path";import{z as C}from"zod";import M from"node:fs/promises";import E from"node:path";var Ir={critical:0,high:1,medium:2,low:3},Mr={active:0,previously_active:1,backlog:2};function Or(i){return[...i].sort((t,e)=>{let r=Mr[t.section]-Mr[e.section];return r!==0?r:Ir[t.priority]-Ir[e.priority]})}l(Or,"sortBySectionAndPriority");W();var Qe=class extends pt{static{l(this,"QueueStorage")}constructor(){super("queue.json",Er)}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 Or(e)[0]||null}async addTask(t,e){let r={...e,id:F(),createdAt:f(),completed:!1};return await this.update(t,n=>({tasks:[...n.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(),n=e.map(s=>({...s,id:F(),createdAt:r,completed:!1}));return await this.update(t,s=>({tasks:[...s.tasks,...n],lastUpdated:r})),await this.publishEvent(t,"queue.tasks_added",{count:n.length,tasks:n.map(s=>({id:s.id,description:s.description}))}),n}async removeTask(t,e){await this.update(t,r=>({tasks:r.tasks.filter(n=>n.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,n=>({tasks:n.tasks.map(o=>o.id===e?(r={...o,completed:!0,completedAt:f()},r):o),lastUpdated:f()})),r){let n=r;await this.publishEvent(t,"queue.task_completed",{taskId:e,description:n.description,completedAt:n.completedAt})}return r}async moveToSection(t,e,r){await this.update(t,n=>({tasks:n.tasks.map(s=>s.id===e?{...s,section:r}:s),lastUpdated:f()}))}async setPriority(t,e,r){await this.update(t,n=>({tasks:n.tasks.map(s=>s.id===e?{...s,priority:r}:s),lastUpdated:f()}))}async getTask(t,e){return(await this.read(t)).tasks.find(n=>n.id===e)||null}async updateTask(t,e,r){let n=null;return await this.update(t,s=>({tasks:s.tasks.map(o=>o.id===e?(n={...o,...r},n):o),lastUpdated:f()})),n&&await this.publishEvent(t,"queue.task_updated",{taskId:e}),n}async clearCompleted(t){let r=(await this.read(t)).tasks.filter(n=>n.completed).length;return await this.update(t,n=>({tasks:n.tasks.filter(s=>!s.completed),lastUpdated:f()})),r}async removeStaleCompleted(t){let e=await this.read(t),r=$t(ee.QUEUE_COMPLETED_DAYS),n=e.tasks.filter(o=>o.completed&&o.completedAt&&new Date(o.completedAt)<r);if(n.length===0)return 0;St.archiveMany(t,n.map(o=>({entityType:"queue_task",entityId:o.id,entityData:o,summary:o.description,reason:"age"})));let s=new Set(n.map(o=>o.id));return await this.update(t,o=>({tasks:o.tasks.filter(a=>!s.has(a.id)),lastUpdated:f()})),await this.publishEvent(t,"queue.stale_removed",{count:n.length}),n.length}},Nt=new Qe;import{z as v}from"zod";var Vo=v.enum(["feature","fix","improvement","refactor"]),Lr=v.enum(["pass","warning","fail","skipped"]),Yo=v.enum(["added","changed","fixed","removed"]),Jo=v.object({hours:v.number(),minutes:v.number(),totalMinutes:v.number()}),Ko=v.object({filesChanged:v.number().nullable().optional(),linesAdded:v.number().nullable().optional(),linesRemoved:v.number().nullable().optional(),commits:v.number().nullable().optional()}),Qo=v.object({description:v.string(),type:Yo.optional()}),Zo=v.object({lintStatus:Lr.nullable().optional(),lintDetails:v.string().optional(),testStatus:Lr.nullable().optional(),testDetails:v.string().optional()}),ti=v.object({hash:v.string().optional(),message:v.string().optional(),branch:v.string().optional()}),ei=v.object({id:v.string(),name:v.string(),version:v.string().nullable().optional(),type:Vo,agent:v.string().optional(),description:v.string().optional(),changes:v.array(Qo).optional(),codeSnippets:v.array(v.string()).optional(),commit:ti.optional(),codeMetrics:Ko.optional(),qualityMetrics:Zo.optional(),quantitativeImpact:v.string().optional(),duration:Jo.optional(),tasksCompleted:v.number().nullable().optional(),shippedAt:v.string(),featureId:v.string().optional()}),$r=v.object({shipped:v.array(ei),lastUpdated:v.string()});W();var Ze=class extends pt{static{l(this,"ShippedStorage")}constructor(){super("shipped.json",$r)}getDefault(){return{shipped:[],lastUpdated:""}}getEventType(t){return`shipped.${t}d`}async getAll(t){return(await this.read(t)).shipped}async getRecent(t,e=5){return(await this.read(t)).shipped.sort((n,s)=>new Date(s.shippedAt).getTime()-new Date(n.shippedAt).getTime()).slice(0,e)}async addShipped(t,e){let r={...e,id:F(),shippedAt:f()};return await this.update(t,n=>({shipped:[r,...n.shipped],lastUpdated:f()})),await this.publishEvent(t,"feature.shipped",{shipId:r.id,name:r.name,version:r.version,shippedAt:r.shippedAt}),r}async getByVersion(t,e){return(await this.read(t)).shipped.find(n=>n.version===e)}async getCount(t){return(await this.read(t)).shipped.length}async getByDateRange(t,e,r){return(await this.read(t)).shipped.filter(s=>{let o=new Date(s.shippedAt);return o>=e&&o<=r})}async getStats(t,e="month"){let r=new Date,n;switch(e){case"week":n=new Date(r.getTime()-7*24*60*60*1e3);break;case"month":n=new Date(r.getFullYear(),r.getMonth(),1);break;case"year":n=new Date(r.getFullYear(),0,1);break}return{count:(await this.getByDateRange(t,n,r)).length,period:e}}async archiveOldShipped(t){let e=await this.read(t),r=$t(ee.SHIPPED_RETENTION_DAYS),n=e.shipped.filter(o=>new Date(o.shippedAt)<r);if(n.length===0)return 0;St.archiveMany(t,n.map(o=>({entityType:"shipped",entityId:o.id,entityData:o,summary:`${o.name} v${o.version}`,reason:"age"})));let s=new Set(e.shipped.filter(o=>new Date(o.shippedAt)>=r).map(o=>o.id));return await this.update(t,o=>({shipped:o.shipped.filter(a=>s.has(a.id)),lastUpdated:f()})),await this.publishEvent(t,"shipped.archived",{count:n.length,oldestShippedAt:n[n.length-1]?.shippedAt}),n.length}},Fr=new Ze;tn();var en=class i{static{l(this,"ObsidianExporter")}getProjectPath(t,e){let r=t.projectFolder||e;return E.join(t.vaultPath,"projects",r)}async exportAll(t,e,r){let n=this.getProjectPath(r,e),s=[],o={success:!0,projectFolder:n,exported:{board:0,queue:0,shipped:0,roadmap:0,daily:!1},errors:s};await this.ensureStructure(n);try{o.exported.board=await this.exportBoard(t,n)}catch(a){s.push(`board: ${a instanceof Error?a.message:String(a)}`)}try{o.exported.queue=await this.exportQueue(t,n)}catch(a){s.push(`queue: ${a instanceof Error?a.message:String(a)}`)}try{o.exported.shipped=await this.exportShipped(t,n)}catch(a){s.push(`shipped: ${a instanceof Error?a.message:String(a)}`)}try{o.exported.roadmap=await this.exportRoadmap(t,n)}catch(a){s.push(`roadmap: ${a instanceof Error?a.message:String(a)}`)}try{o.exported.daily=await this.exportDaily(t,n)}catch(a){s.push(`daily: ${a instanceof Error?a.message:String(a)}`)}try{await this.exportIndex(e,n)}catch(a){s.push(`index: ${a instanceof Error?a.message:String(a)}`)}return o.success=s.length===0,o}async ensureStructure(t){let e=["board","queue","shipped","roadmap","architecture","design","research","meetings","notes","daily","retros"];for(let r of e)await M.mkdir(E.join(t,r),{recursive:!0})}async writeLink(t,e,r){let n=[`projectId: ${e}`,`projectPath: ${r}`,`linkedAt: ${new Date().toISOString()}`].join(`
624
- `);await M.writeFile(E.join(t,".prjct-link.yml"),n,"utf-8")}async exportBoard(t,e){let r=await X.read(t),n=E.join(e,"board"),s=0;if(r.currentTask){let c=r.currentTask,u=c.subtasks||[],p=c.currentSubtaskIndex??0,d={prjct_id:c.id,prjct_type:"task",status:"in_progress",type:c.type||"feature",description:c.description,branch:c.branch,linear_id:c.linearId,estimated_points:c.estimatedPoints,started_at:c.startedAt,updated_at:new Date().toISOString()},g=u.map((k,I)=>{let z=k.status==="completed"?"x":" ",V=I===p&&k.status!=="completed"?" <- current":"";return`- [${z}] ${k.description}${V}`}),h=u.filter(k=>k.status==="completed").length,j=u.length>0?`${h}/${u.length} (${Math.round(h/u.length*100)}%)`:"",w=ct(d,c.description,g.length>0?`## Subtasks
625
- ${g.join(`
626
- `)}`:null,j?`## Progress
627
- ${j}`:null);await M.writeFile(E.join(n,`${c.id}.md`),w,"utf-8"),s++}let o=r.pausedTasks||[];for(let c of o){let u=c.id||`paused_${Date.now()}`,p={prjct_id:u,prjct_type:"task",status:"paused",type:c.type||"feature",description:c.description,branch:c.branch,linear_id:c.linearId,updated_at:new Date().toISOString()},d=ct(p,c.description,"Status: paused");await M.writeFile(E.join(n,`${u}.md`),d,"utf-8"),s++}let a=r.activeTasks||[];for(let c of a){let u={prjct_id:c.id,prjct_type:"task",status:"in_progress",type:c.type||"feature",description:c.description,branch:c.branch,linear_id:c.linearId,started_at:c.startedAt,worktree:c.worktreePath,updated_at:new Date().toISOString()},p=ct(u,c.description);await M.writeFile(E.join(n,`${c.id}.md`),p,"utf-8"),s++}return await this.generateKanbanBoard(r,n),s}async generateKanbanBoard(t,e){let r=["---","kanban-plugin: board","---",""],n=[],s=[],o=[];t.currentTask&&n.push(`- [[${t.currentTask.id}]]`);for(let c of t.activeTasks||[])n.push(`- [[${c.id}]]`);for(let c of t.pausedTasks||[])c.id&&s.push(`- [[${c.id}]]`);let a=t.taskHistory||[];for(let c of a.slice(0,5))o.push(`- [[${c.taskId}]]`);r.push("## In Progress"),r.push(...n.length>0?n:[""]),r.push(""),r.push("## Paused"),r.push(...s.length>0?s:[""]),r.push(""),r.push("## Done"),r.push(...o.length>0?o:[""]),await M.writeFile(E.join(e,"_kanban.md"),r.join(`
628
- `),"utf-8")}async exportQueue(t,e){let r=await Nt.read(t),n=E.join(e,"queue"),s=0;for(let o of r.tasks){if(o.completed)continue;let a={prjct_id:o.id,prjct_type:"queue",priority:o.priority,type:o.type,section:o.section,created_at:o.createdAt,updated_at:new Date().toISOString()};o.agent&&(a.agent=o.agent),o.groupName&&(a.group=o.groupName),o.featureId&&(a.feature_id=o.featureId);let c=ct(a,o.description);await M.writeFile(E.join(n,`${o.id}.md`),c,"utf-8"),s++}return s}async exportShipped(t,e){let r=await Fr.read(t),n=E.join(e,"shipped"),s=0;for(let o of r.shipped){let a={prjct_id:o.id,prjct_type:"shipped",name:o.name,version:o.version,type:o.type,shipped_at:o.shippedAt};o.duration&&(a.duration=o.duration),o.codeMetrics?.filesChanged&&(a.files_changed=o.codeMetrics.filesChanged),o.codeMetrics?.linesAdded&&(a.lines_added=o.codeMetrics.linesAdded),o.codeMetrics?.linesRemoved&&(a.lines_removed=o.codeMetrics.linesRemoved);let c=[];if(o.changes&&o.changes.length>0){let p=o.changes.map(d=>`- ${d.type?`**${d.type}**: `:""}${d.description}`);c.push(`## Changes
629
- ${p.join(`
630
- `)}`)}if(o.codeMetrics){let p=o.codeMetrics,d=[];p.filesChanged&&d.push(`- **Files**: ${p.filesChanged} changed`),(p.linesAdded||p.linesRemoved)&&d.push(`- **Lines**: +${p.linesAdded||0} / -${p.linesRemoved||0}`),o.duration&&d.push(`- **Duration**: ${o.duration}`),d.length>0&&c.push(`## Metrics
631
- ${d.join(`
632
- `)}`)}let u=ct(a,o.name,o.description||null,...c);await M.writeFile(E.join(n,`${o.id}.md`),u,"utf-8"),s++}return s}async exportRoadmap(t,e){let r=_.getDoc(t,"roadmap");if(!r)return 0;let n=E.join(e,"roadmap"),s=0,o=r.features||[];for(let a of o){let c={prjct_id:a.id,prjct_type:"feature",status:a.status,impact:a.impact,progress:a.progress,updated_at:new Date().toISOString()};a.phase&&(c.phase=a.phase),a.quarter&&(c.quarter=a.quarter),a.dependencies&&a.dependencies.length>0&&(c.dependencies=a.dependencies);let u=(a.tasks||[]).map(d=>`- [${d.completed?"x":" "}] ${d.description}`),p=ct(c,a.name,a.description||null,u.length>0?`## Tasks
633
- ${u.join(`
634
- `)}`:null);await M.writeFile(E.join(n,`${a.id}.md`),p,"utf-8"),s++}return await this.generateCanvas(o,n),s}async generateCanvas(t,e){let r={shipped:"4",completed:"4",active:"5",planned:"0"},n=t.map((a,c)=>({id:a.id,type:"text",text:`**${a.name}**
635
- Status: ${a.status}${a.quarter?`
636
- Quarter: ${a.quarter}`:""}`,x:c%4*300,y:Math.floor(c/4)*200,width:260,height:120,color:r[a.status]||"0"})),s=[];for(let a of t)for(let c of a.dependencies||[])t.some(u=>u.id===c)&&s.push({id:`edge_${a.id}_${c}`,fromNode:c,toNode:a.id,label:"depends on"});let o=JSON.stringify({nodes:n,edges:s},null,2);await M.writeFile(E.join(e,"roadmap.canvas"),o,"utf-8")}async exportDaily(t,e){let r=await X.read(t),n=await Nt.read(t),s=new Date().toISOString().split("T")[0],o=E.join(e,"daily"),a={prjct_type:"daily",date:s,has_active_task:!!r.currentTask,queue_depth:n.tasks.filter(d=>!d.completed).length},c=[];if(r.currentTask){let d=r.currentTask,g=d.subtasks||[],h=g.filter(j=>j.status==="completed").length;c.push(`## Active Task
637
- **${d.description}**
638
- `+(d.branch?`Branch: \`${d.branch}\`
639
- `:"")+(g.length>0?`Progress: ${h}/${g.length}`:""))}else c.push(`## Active Task
640
- No active task.`);let u=n.tasks.filter(d=>!d.completed).slice(0,5);if(u.length>0){let d=u.map(g=>[g.priority,g.type,g.description]);c.push(`## Queue (Top ${u.length})
641
- ${_t(["Priority","Type","Description"],d)}`)}let p=ct(a,`Daily: ${s}`,...c);return await M.writeFile(E.join(o,`${s}.md`),p,"utf-8"),!0}async exportIndex(t,e){let r=`# ${t}
642
-
643
- ## Board
644
- \`\`\`dataview
645
- TABLE status, type, priority
646
- FROM "${E.basename(E.dirname(e))}/${E.basename(e)}/board"
647
- WHERE prjct_type = "task"
648
- SORT priority DESC
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})
649
516
  \`\`\`
650
-
651
- ## Queue (Top 10)
652
- \`\`\`dataview
653
- TABLE priority, type
654
- FROM "${E.basename(E.dirname(e))}/${E.basename(e)}/queue"
655
- SORT priority DESC
656
- LIMIT 10
657
- \`\`\`
658
-
659
- ## Recent Shipped
660
- \`\`\`dataview
661
- TABLE version, type, duration_hours
662
- FROM "${E.basename(E.dirname(e))}/${E.basename(e)}/shipped"
663
- SORT shipped_at DESC
664
- LIMIT 5
665
- \`\`\`
666
-
667
- ## Knowledge Base
668
- \`\`\`dataview
669
- TABLE file.mtime as "Updated"
670
- FROM "${E.basename(E.dirname(e))}/${E.basename(e)}/architecture" OR "${E.basename(E.dirname(e))}/${E.basename(e)}/research"
671
- SORT file.mtime DESC
672
- LIMIT 10
673
- \`\`\`
674
- `;await M.writeFile(E.join(e,"_index.md"),r,"utf-8")}static ALLOWED_EXTENSIONS=new Set([".md",".markdown",".txt",".canvas"]);static BLOCKED_DIRS=new Set([".obsidian",".git",".trash","node_modules"]);validatePath(t,e){let r=E.resolve(t,e);if(!r.startsWith(E.resolve(t)))throw new Error(`Path traversal blocked: ${e}`);let s=E.relative(t,r).split(E.sep);for(let o of s)if(i.BLOCKED_DIRS.has(o))throw new Error(`Blocked directory: ${o}`);return r}validateFileExtension(t){let e=E.extname(t).toLowerCase();if(e&&!i.ALLOWED_EXTENSIONS.has(e))throw new Error(`Blocked file extension: ${e}. Allowed: ${[...i.ALLOWED_EXTENSIONS].join(", ")}`)}async readNote(t,e,r){let n=this.getProjectPath(t,e),s=this.validatePath(n,r);this.validateFileExtension(s);let o=await M.readFile(s,"utf-8"),a=null,c=o,u=o.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);return u&&(a=this.parseYamlFrontmatter(u[1]),c=u[2]),{content:c,frontmatter:a}}async writeNote(t,e,r,n,s){let o=this.getProjectPath(t,e),a=this.validatePath(o,r);this.validateFileExtension(a),await M.mkdir(E.dirname(a),{recursive:!0});let c=n;if(s&&Object.keys(s).length>0){let{mdFrontmatter:u}=await Promise.resolve().then(()=>(tn(),Br));c=`${u(s)}
675
-
676
- ${n}`}await M.writeFile(a,c,"utf-8")}async searchNotes(t,e,r,n={}){let s=this.getProjectPath(t,e),o=n.folder?this.validatePath(s,n.folder):s,a=n.limit||20,c=[],u=r.toLowerCase(),p=u.split(/\s+/).filter(g=>g.length>1),d=await this.walkDir(o);for(let g of d)if(i.ALLOWED_EXTENSIONS.has(E.extname(g).toLowerCase()))try{let h=await M.readFile(g,"utf-8"),j=h.toLowerCase(),w=E.relative(s,g),k=0;for(let I of p){let z=0,V=0;for(;(z=j.indexOf(I,z))!==-1;)V++,z+=I.length;V>0&&(k+=Math.log(1+V)),w.toLowerCase().includes(I)&&(k+=2)}if(k>0){let I=h.match(/^#\s+(.+)$/m),z=I?I[1]:E.basename(g,E.extname(g)),V=j.indexOf(u.split(/\s+/)[0]),wt=Math.max(0,V-50),gn=Math.min(h.length,V+150),as=(wt>0?"...":"")+h.slice(wt,gn).replace(/\n/g," ").trim()+(gn<h.length?"...":"");c.push({path:w,title:z,excerpt:as,score:k})}}catch{}return c.sort((g,h)=>h.score-g.score),c.slice(0,a)}async listNotes(t,e,r){let n=this.getProjectPath(t,e),s=r?this.validatePath(n,r):n,o=await M.readdir(s,{withFileTypes:!0}),a=[];for(let c of o){if(i.BLOCKED_DIRS.has(c.name)||c.name.startsWith("."))continue;let u=r?`${r}/${c.name}`:c.name;if(c.isDirectory())a.push({path:u,name:c.name,isDir:!0});else if(i.ALLOWED_EXTENSIONS.has(E.extname(c.name).toLowerCase())){let p=await M.stat(E.join(s,c.name));a.push({path:u,name:c.name,isDir:!1,size:p.size})}}return a}async getVaultStats(t,e){let r=this.getProjectPath(t,e),n={},s=0,o=0,a=await this.walkDir(r);for(let c of a){if(!i.ALLOWED_EXTENSIONS.has(E.extname(c).toLowerCase()))continue;let u=E.relative(r,c),p=E.dirname(u).split(E.sep)[0]||".";n[p]=(n[p]||0)+1,s++;try{let d=await M.stat(c);o+=d.size}catch{}}return{totalNotes:s,folders:n,totalSize:o}}parseYamlFrontmatter(t){let e={};for(let r of t.split(`
677
- `)){let n=r.match(/^(\w[\w-]*)\s*:\s*(.*)$/);if(n){let[,s,o]=n;o.startsWith("[")&&o.endsWith("]")?e[s]=o.slice(1,-1).split(",").map(a=>a.trim()).filter(Boolean):o==="true"?e[s]=!0:o==="false"?e[s]=!1:!Number.isNaN(Number(o))&&o.trim()!==""?e[s]=Number(o):e[s]=o}}return e}async walkDir(t){let e=[];try{let r=await M.readdir(t,{withFileTypes:!0});for(let n of r){if(i.BLOCKED_DIRS.has(n.name)||n.name.startsWith("."))continue;let s=E.join(t,n.name);n.isDirectory()?e.push(...await this.walkDir(s)):e.push(s)}}catch{}return e}},dt=new en;async function Tt(i){let t=await b(i),r=(await At.readGlobalConfig(t))?.integrations?.obsidian;if(!r)throw new Error("Obsidian not configured. Run: prjct obsidian setup --vault-path /path/to/vault");let n=r.projectFolder||Gr.basename(i);return{projectId:t,config:r,projectName:n}}l(Tt,"resolveObsidian");function qr(i){let t=i;t.tool("prjct_obsidian_read","Read a note from the project Obsidian vault. Returns content and frontmatter.",{projectPath:C.string().describe("Project directory path"),notePath:C.string().describe('Relative path within the project vault folder (e.g., "architecture/auth.md")')},y("prjct_obsidian_read",async e=>{let{config:r,projectName:n}=await Tt(e.projectPath),s=await dt.readNote(r,n,e.notePath),o=[];return s.frontmatter&&o.push(`**Frontmatter:**
678
- ${Object.entries(s.frontmatter).map(([a,c])=>`- ${a}: ${JSON.stringify(c)}`).join(`
679
- `)}`),o.push(s.content),{content:[{type:"text",text:o.join(`
680
-
681
- `)}]}})),t.tool("prjct_obsidian_write","Create or update a note in the project Obsidian vault with optional frontmatter.",{projectPath:C.string().describe("Project directory path"),notePath:C.string().describe('Relative path within the project vault folder (e.g., "architecture/new-decision.md")'),content:C.string().describe("Markdown content of the note (without frontmatter)"),frontmatter:C.record(C.unknown()).optional().describe("YAML frontmatter as key-value object")},y("prjct_obsidian_write",async e=>{let{config:r,projectName:n}=await Tt(e.projectPath);return await dt.writeNote(r,n,e.notePath,e.content,e.frontmatter),{content:[{type:"text",text:`Note written: ${e.notePath}`}]}})),t.tool("prjct_obsidian_search","Search notes in the project Obsidian vault by text query. Returns ranked results with excerpts.",{projectPath:C.string().describe("Project directory path"),query:C.string().describe("Search query (multi-word supported)"),folder:C.string().optional().describe('Restrict to a folder (e.g., "architecture", "research")'),limit:C.number().optional().default(10).describe("Max results (default 10)")},y("prjct_obsidian_search",async e=>{let{config:r,projectName:n}=await Tt(e.projectPath),s=await dt.searchNotes(r,n,e.query,{limit:e.limit,folder:e.folder});if(s.length===0)return{content:[{type:"text",text:`No notes found for: "${e.query}"`}]};let o=s.map(a=>`### ${a.title}
682
- \`${a.path}\` (score: ${a.score.toFixed(1)})
683
- > ${a.excerpt}`);return{content:[{type:"text",text:`## Search: "${e.query}" (${s.length} results)
517
+ ${s.join(`
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)
520
+
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 Mr={critical:0,high:1,medium:2,low:3},jr={active:0,previously_active:1,backlog:2};function Fr(n){return[...n].sort((t,e)=>{let r=jr[t.section]-jr[e.section];return r!==0?r:Mr[t.priority]-Mr[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
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
+ ## 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
+ `)}]}})),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(`
527
+ ### Stack`),s.stack.languages?.length&&o.push(`Languages: ${s.stack.languages.join(", ")}`),s.stack.frameworks?.length&&o.push(`Frameworks: ${s.stack.frameworks.join(", ")}`),s.stack.packageManager&&o.push(`Package Manager: ${s.stack.packageManager}`)),s.patterns?.length){o.push(`
528
+ ### Patterns (${s.patterns.length})`);for(let i of s.patterns)o.push(`- **${i.name}**: ${i.description}`)}if(s.antiPatterns?.length){o.push(`
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
+ ### 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(`
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})
684
536
 
685
537
  ${o.join(`
686
-
687
- `)}`}]}})),t.tool("prjct_obsidian_list","List notes and folders in the project Obsidian vault.",{projectPath:C.string().describe("Project directory path"),folder:C.string().optional().describe('Subfolder to list (e.g., "architecture"). Omit for root.')},y("prjct_obsidian_list",async e=>{let{config:r,projectName:n}=await Tt(e.projectPath),s=await dt.listNotes(r,n,e.folder);if(s.length===0)return{content:[{type:"text",text:`Empty: ${e.folder||"vault root"}`}]};let o=s.filter(u=>u.isDir),a=s.filter(u=>!u.isDir),c=[];return o.length>0&&c.push(`**Folders (${o.length}):**
688
- ${o.map(u=>`- ${u.name}/`).join(`
689
- `)}`),a.length>0&&c.push(`**Notes (${a.length}):**
690
- ${a.map(u=>`- ${u.name}${u.size?` (${(u.size/1024).toFixed(1)}KB)`:""}`).join(`
691
- `)}`),{content:[{type:"text",text:`## ${e.folder||"Vault Root"}
692
-
693
- ${c.join(`
694
-
695
- `)}`}]}})),t.tool("prjct_obsidian_export","Export all prjct data (board, queue, shipped, roadmap, daily) to Obsidian vault.",{projectPath:C.string().describe("Project directory path")},y("prjct_obsidian_export",async e=>{let{projectId:r,config:n,projectName:s}=await Tt(e.projectPath),o=await dt.exportAll(r,s,n),a=["## Obsidian Export",`Board: ${o.exported.board} tasks`,`Queue: ${o.exported.queue} items`,`Shipped: ${o.exported.shipped} items`,`Roadmap: ${o.exported.roadmap} features`,`Daily: ${o.exported.daily?"generated":"skipped"}`];return o.errors.length>0&&a.push(`
696
- Errors:
697
- ${o.errors.map(c=>`- ${c}`).join(`
698
- `)}`),{content:[{type:"text",text:a.join(`
699
- `)}]}})),t.tool("prjct_obsidian_stats","Get statistics about the project Obsidian vault (note count, folders, size).",{projectPath:C.string().describe("Project directory path")},y("prjct_obsidian_stats",async e=>{let{config:r,projectName:n}=await Tt(e.projectPath),s=await dt.getVaultStats(r,n),o=Object.entries(s.folders).sort(([,a],[,c])=>c-a).map(([a,c])=>`- ${a}: ${c} notes`);return{content:[{type:"text",text:["## Vault Stats",`Total notes: ${s.totalNotes}`,`Total size: ${(s.totalSize/1024).toFixed(1)} KB`,`
700
- **By folder:**`,...o].join(`
701
- `)}]}})),t.tool("prjct_obsidian_status","Check Obsidian integration status for this project.",{projectPath:C.string().describe("Project directory path")},y("prjct_obsidian_status",async e=>{let r=await b(e.projectPath),s=(await At.readGlobalConfig(r))?.integrations?.obsidian;return s?{content:[{type:"text",text:["## Obsidian Status",`Vault: ${s.vaultPath}`,`Project folder: ${s.projectFolder||Gr.basename(e.projectPath)}`,`Auto-export: ${s.autoExport?"enabled":"disabled"}`].join(`
702
- `)}]}:{content:[{type:"text",text:"Obsidian not configured. Run: prjct obsidian setup --vault-path /path/to/vault"}]}})),t.tool("prjct_obsidian_import","Import structured data (e.g., Linear issues, tasks) into the Obsidian vault as individual notes.",{projectPath:C.string().describe("Project directory path"),folder:C.string().describe('Target folder (e.g., "linear", "board", "research")'),notes:C.array(C.object({filename:C.string().describe('Note filename (e.g., "ENG-123.md")'),title:C.string().describe("Note title (H1)"),content:C.string().describe("Markdown body"),frontmatter:C.record(C.unknown()).optional().describe("YAML frontmatter fields")})).describe("Array of notes to import")},y("prjct_obsidian_import",async e=>{let{config:r,projectName:n}=await Tt(e.projectPath),s=0,o=[];for(let c of e.notes)try{let u=`${e.folder}/${c.filename}`,p=`# ${c.title}
703
-
704
- ${c.content}`;await dt.writeNote(r,n,u,p,c.frontmatter),s++}catch(u){o.push(`${c.filename}: ${u instanceof Error?u.message:String(u)}`)}let a=["## Import Complete",`Imported: ${s}/${e.notes.length} notes`];return o.length>0&&a.push(`
705
- Errors:
706
- ${o.map(c=>`- ${c}`).join(`
707
- `)}`),{content:[{type:"text",text:a.join(`
708
- `)}]}}))}l(qr,"registerObsidianTools");import{z as q}from"zod";function zr(i){let t=i;t.tool("prjct_decision_record","Record a technical decision with confidence tracking. Repeated observations increase confidence.",{projectPath:q.string().describe("Project directory path"),key:q.string().describe("Decision key (e.g. commit_style, branch_naming, test_framework)"),value:q.string().describe('Decision value (e.g. "conventional commits", "feature/*")'),context:q.string().optional().default("").describe("Context for this decision")},y("prjct_decision_record",async e=>{let r=await b(e.projectPath);return await G.learnDecision(r,e.key,e.value,e.context),{content:[{type:"text",text:`Decision recorded: ${e.key} = "${e.value}"`}]}})),t.tool("prjct_decision_get","Retrieve a learned decision (checks session cache \u2192 pattern store). Returns null for low-confidence decisions.",{projectPath:q.string().describe("Project directory path"),key:q.string().describe("Decision key to look up")},y("prjct_decision_get",async e=>{let r=await b(e.projectPath),n=await G.getSmartDecision(r,e.key);return n===null?{content:[{type:"text",text:`No decision found for "${e.key}".`}]}:{content:[{type:"text",text:`${e.key} = "${n}"`}]}})),t.tool("prjct_preference_set","Set a user preference with confidence tracking",{projectPath:q.string().describe("Project directory path"),key:q.string().describe("Preference key (e.g. verbosity, test_runner, editor)"),value:q.string().describe("Preference value")},y("prjct_preference_set",async e=>{let r=await b(e.projectPath);return await G.setPreference(r,e.key,e.value,{userConfirmed:!0}),{content:[{type:"text",text:`Preference set: ${e.key} = "${e.value}"`}]}})),t.tool("prjct_preference_get","Get a user preference value",{projectPath:q.string().describe("Project directory path"),key:q.string().describe("Preference key to look up")},y("prjct_preference_get",async e=>{let r=await b(e.projectPath),n=await G.getPreference(r,e.key);return n===null?{content:[{type:"text",text:`No preference found for "${e.key}".`}]}:{content:[{type:"text",text:`${e.key} = "${n}"`}]}})),t.tool("prjct_confirm","Confirm a decision/preference/workflow \u2192 boosts confidence to high",{projectPath:q.string().describe("Project directory path"),type:q.enum(["decision","preference","workflow"]).describe("Type to confirm"),key:q.string().describe("Key of the decision/preference/workflow to confirm")},y("prjct_confirm",async e=>{let r=await b(e.projectPath),n;switch(e.type){case"decision":n=await G.confirmDecision(r,e.key);break;case"preference":n=await G.confirmPreference(r,e.key);break;case"workflow":n=await G.confirmWorkflow(r,e.key);break}return n?{content:[{type:"text",text:`Confirmed ${e.type} "${e.key}" \u2192 confidence set to high.`}]}:{content:[{type:"text",text:`${e.type} "${e.key}" not found.`}]}})),t.tool("prjct_archive_stale","Archive stale decisions (>90 days) + paused tasks (>30 days)",{projectPath:q.string().describe("Project directory path")},y("prjct_archive_stale",async e=>{let r=await b(e.projectPath),n=await G.archiveStaleDecisions(r),s=await X.archiveStalePausedTasks(r),o=["## Archive Results"];if(o.push(`Stale decisions archived: ${n}`),o.push(`Stale paused tasks archived: ${s.length}`),s.length>0){o.push(`
709
- ### Archived Tasks`);for(let a of s)o.push(`- ${a.description} (paused at ${a.pausedAt})`)}return{content:[{type:"text",text:o.join(`
710
- `)}]}}))}l(zr,"registerPatternTools");import{z as U}from"zod";on();nn();import an from"node:path";W();st();var Pi="outcomes",ji="outcomes.jsonl",cn=class{static{l(this,"OutcomeRecorder")}_cache=new Map;getOutcomesDir(t){let e=A.getGlobalProjectPath(t);return an.join(e,Pi)}getOutcomesPath(t){return an.join(this.getOutcomesDir(t),ji)}async record(t,e){let r={...e,id:F()},n=this.getOutcomesPath(t);return await K(an.dirname(n)),await Rn(n,JSON.stringify(r)),this._cache.delete(t),r}async getAll(t){let e=this.getOutcomesPath(t);if(!await N(e))return[];try{let{statSync:r}=await import("node:fs"),s=r(e).mtimeMs,o=this._cache.get(t);if(o&&o.mtime===s)return o.outcomes;let a=await ue(e);if(!a.trim())return[];let c=a.trim().split(`
711
- `).filter(u=>u.trim()).map(u=>JSON.parse(u));return this._cache.set(t,{outcomes:c,mtime:s}),c}catch{let r=await ue(e);return r.trim()?r.trim().split(`
712
- `).filter(n=>n.trim()).map(n=>JSON.parse(n)):[]}}async filter(t,e){return(await this.getAll(t)).filter(n=>{if(e.sessionId&&n.sessionId!==e.sessionId||e.command&&n.command!==e.command||e.agent&&n.agentUsed!==e.agent||e.fromDate&&n.startedAt<e.fromDate||e.toDate&&n.completedAt>e.toDate||e.minQuality&&n.qualityScore<e.minQuality)return!1;if(e.tags&&e.tags.length>0){let s=n.tags||[];if(!e.tags.some(o=>s.includes(o)))return!1}return!0})}async getRecent(t,e=10){return(await this.getAll(t)).slice(-e)}async getByCommand(t,e){return this.filter(t,{command:e})}async getByAgent(t,e){return this.filter(t,{agent:e})}async getEstimateAccuracy(t){let e=await this.getAll(t);if(e.length===0)return 0;let r=e.filter(n=>{if(!n.variance)return!1;let s=bn(n.variance),o=gt(n.estimatedDuration);return o===0?!1:Math.abs(s)/o<=.2});return Math.round(r.length/e.length*100)}},Ri=new cn,nt=Ri;function Zr(i){let t=i;t.tool("prjct_task_status","Current task, duration, subtasks, and queue",{projectPath:U.string().describe("Project directory path")},y("prjct_task_status",async e=>{let r=await b(e.projectPath),n=await X.getCurrentTask(r),s=await Nt.getActiveTasks(r),o=[];if(n?(o.push(`## Active Task
713
- **${n.description}**`),n.branch&&o.push(`Branch: ${n.branch}`),o.push(`Started: ${n.startedAt}`)):o.push("No active task."),s.length>0){o.push(`
714
- ## Queue (${s.length} tasks)`);for(let a of s.slice(0,10))o.push(`- ${a.description} [${a.priority||"medium"}]`)}return{content:[{type:"text",text:o.join(`
715
- `)}]}})),t.tool("prjct_velocity","Sprint velocity, estimation accuracy, and trend",{projectPath:U.string().describe("Project directory path")},y("prjct_velocity",async e=>{let r=await b(e.projectPath),n=await nt.getAll(r);if(n.length===0)return{content:[{type:"text",text:"No outcome data yet."}]};let s=It(n,mt);return s.sprints.length===0?{content:[{type:"text",text:"Not enough data for velocity."}]}:{content:[{type:"text",text:sn(s)}]}})),t.tool("prjct_analysis","LLM analysis: stack, patterns, anti-patterns, conventions",{projectPath:U.string().describe("Project directory path")},y("prjct_analysis",async e=>{let r=await b(e.projectPath),n=lt.getActive(r);if(!n)return{content:[{type:"text",text:"No analysis available. Run `prjct sync`."}]};let s=["## Project Analysis"];if(n.stack&&(s.push(`
716
- ### Stack`),n.stack.languages?.length&&s.push(`Languages: ${n.stack.languages.join(", ")}`),n.stack.frameworks?.length&&s.push(`Frameworks: ${n.stack.frameworks.join(", ")}`),n.stack.packageManager&&s.push(`Package Manager: ${n.stack.packageManager}`)),n.patterns?.length){s.push(`
717
- ### Patterns (${n.patterns.length})`);for(let o of n.patterns)s.push(`- **${o.name}**: ${o.description}`)}if(n.antiPatterns?.length){s.push(`
718
- ### Anti-Patterns (${n.antiPatterns.length})`);for(let o of n.antiPatterns)s.push(`- **${o.issue}**: ${o.suggestion}`)}if(n.conventions?.length){s.push(`
719
- ### Conventions (${n.conventions.length})`);for(let o of n.conventions)s.push(`- [${o.category}] ${o.rule}`)}return{content:[{type:"text",text:s.join(`
720
- `)}]}})),t.tool("prjct_patterns","Learned decisions, preferences, and workflows with confidence tracking",{projectPath:U.string().describe("Project directory path")},y("prjct_patterns",async e=>{let r=await b(e.projectPath),n=await G.getPatternsSummaryDetailed(r);if(!n)return{content:[{type:"text",text:"No patterns learned yet."}]};let s=["## Learned Patterns"];if(Object.keys(n.decisions).length>0){s.push(`
721
- ### Decisions`);for(let[o,a]of Object.entries(n.decisions))s.push(`- **${o}**: ${a.value} (${a.confidence}, ${a.count}x)`)}if(Object.keys(n.preferences).length>0){s.push(`
722
- ### Preferences`);for(let[o,a]of Object.entries(n.preferences))s.push(`- **${o}**: ${a.value} (${a.confidence})`)}if(Object.keys(n.workflows).length>0){s.push(`
723
- ### Workflows`);for(let[o,a]of Object.entries(n.workflows))s.push(`- **${o}**: ${a.confidence}, ${a.count}x`)}return{content:[{type:"text",text:s.join(`
724
- `)}]}})),t.tool("prjct_outcomes_search","Search completed task outcomes \u2014 what worked, what failed, duration, blockers",{projectPath:U.string().describe("Project directory path"),query:U.string().describe("Search query (matches task description, blockers, patterns)"),limit:U.number().optional().default(10).describe("Max results"),offset:U.number().optional().default(0).describe("Offset for pagination (default 0)")},y("prjct_outcomes_search",async e=>{let r=await b(e.projectPath),n=await nt.getAll(r);if(n.length===0)return{content:[{type:"text",text:"No outcomes recorded yet."}]};let o=e.query.toLowerCase().split(/\s+/),a=n.map(u=>{let p=`${u.task} ${u.command} ${(u.blockers||[]).join(" ")} ${u.patternDetected||""} ${(u.tags||[]).join(" ")}`.toLowerCase(),d=o.filter(g=>p.includes(g)).length;return{outcome:u,score:d}}).filter(u=>u.score>0).sort((u,p)=>p.score-u.score).slice(e.offset,e.offset+e.limit);if(a.length===0)return{content:[{type:"text",text:`No outcomes matching "${e.query}".`}]};let c=a.map(({outcome:u})=>{let p=u.completedAsPlanned?"success":"issues",d=[`- **${u.task}** [${p}, ${u.actualDuration}]`];return u.variance&&d.push(` Variance: ${u.variance}`),u.blockers?.length&&d.push(` Blockers: ${u.blockers.join(", ")}`),u.patternDetected&&d.push(` Pattern: ${u.patternDetected}`),d.join(`
725
- `)});return{content:[{type:"text",text:`## Outcomes matching "${e.query}" (${a.length}/${n.length})
726
-
727
- ${c.join(`
728
- `)}`}]}})),t.tool("prjct_outcomes_similar","Find similar past tasks and their outcomes: avg duration, success rate, common blockers",{projectPath:U.string().describe("Project directory path"),task:U.string().describe("Task description to find similar outcomes for")},y("prjct_outcomes_similar",async e=>{let r=await b(e.projectPath),n=await nt.getAll(r);if(n.length===0)return{content:[{type:"text",text:"No outcomes recorded yet."}]};let s=new Set(e.task.toLowerCase().split(/\s+/).filter(w=>w.length>2)),o=n.map(w=>{let k=new Set(w.task.toLowerCase().split(/\s+/).filter(V=>V.length>2)),I=[...s].filter(V=>k.has(V)).length,z=s.size>0?I/s.size:0;return{outcome:w,similarity:z}}).filter(w=>w.similarity>=.2).sort((w,k)=>k.similarity-w.similarity).slice(0,10);if(o.length===0)return{content:[{type:"text",text:"No similar past tasks found."}]};let a=o.filter(w=>w.outcome.completedAsPlanned).length,c=Math.round(a/o.length*100),u=o.map(w=>{let k=w.outcome.actualDuration.match(/(\d+)/);return k?Number.parseInt(k[1],10):0}).filter(w=>w>0),p=u.length>0?Math.round(u.reduce((w,k)=>w+k,0)/u.length):0,d=o.flatMap(w=>w.outcome.blockers||[]),g={};for(let w of d)g[w]=(g[w]||0)+1;let h=Object.entries(g).sort(([,w],[,k])=>k-w).slice(0,3),j=[`## Similar Tasks (${o.length} matches)`,`
729
- **Success rate**: ${c}% (${a}/${o.length})`];p>0&&j.push(`**Avg duration**: ${p}m`),h.length>0&&j.push(`**Common blockers**: ${h.map(([w,k])=>`${w} (${k}x)`).join(", ")}`),j.push(`
730
- ### Past tasks`);for(let{outcome:w,similarity:k}of o){let I=w.completedAsPlanned?"ok":"issues";j.push(`- [${I}] **${w.task}** \u2014 ${w.actualDuration} (${Math.round(k*100)}% similar)`)}return{content:[{type:"text",text:j.join(`
731
- `)}]}})),t.tool("prjct_outcomes_recent","Last N outcomes with optional command/agent filter",{projectPath:U.string().describe("Project directory path"),count:U.number().optional().default(10).describe("Number of recent outcomes (default 10)"),command:U.string().optional().describe('Filter by command (e.g. "done", "ship")'),agent:U.string().optional().describe("Filter by agent used")},y("prjct_outcomes_recent",async e=>{let r=await b(e.projectPath),n;if(e.command?(n=await nt.getByCommand(r,e.command),n=n.slice(-e.count)):e.agent?(n=await nt.getByAgent(r,e.agent),n=n.slice(-e.count)):n=await nt.getRecent(r,e.count),n.length===0)return{content:[{type:"text",text:"No outcomes found."}]};let s=[`## Recent Outcomes (${n.length})`],o=e.command?` [command: ${e.command}]`:e.agent?` [agent: ${e.agent}]`:"";o&&(s[0]+=o),s.push("");for(let a of n){let u=[`- [${a.completedAsPlanned?"ok":"issues"}] **${a.task}** \u2014 ${a.actualDuration}`];a.command&&u.push(` Command: ${a.command}`),a.variance&&u.push(` Variance: ${a.variance}`),a.blockers?.length&&u.push(` Blockers: ${a.blockers.join(", ")}`),s.push(u.join(`
732
- `))}return{content:[{type:"text",text:s.join(`
733
- `)}]}})),t.tool("prjct_estimate_accuracy","Overall estimation accuracy % + per-category over/under patterns",{projectPath:U.string().describe("Project directory path")},y("prjct_estimate_accuracy",async e=>{let r=await b(e.projectPath),n=await nt.getAll(r);if(n.length===0)return{content:[{type:"text",text:"No outcome data yet."}]};let s=await nt.getEstimateAccuracy(r),o=It(n,mt),a=["## Estimation Accuracy",`Overall: ${s}%`,`Total outcomes: ${n.length}`];if(o.overEstimated.length>0){a.push(`
734
- ### Over-Estimated (finish faster than expected)`);for(let c of o.overEstimated)a.push(`- **${c.category}**: ${c.avgVariance}% faster (${c.taskCount} tasks)`)}if(o.underEstimated.length>0){a.push(`
735
- ### Under-Estimated (take longer than expected)`);for(let c of o.underEstimated)a.push(`- **${c.category}**: ${c.avgVariance}% longer (${c.taskCount} tasks)`)}return o.overEstimated.length===0&&o.underEstimated.length===0&&a.push(`
736
- No significant estimation patterns detected.`),{content:[{type:"text",text:a.join(`
737
- `)}]}})),t.tool("prjct_velocity_detail","Sprint-by-sprint breakdown + completion projection",{projectPath:U.string().describe("Project directory path"),remainingPoints:U.number().optional().describe("Remaining story points for completion projection")},y("prjct_velocity_detail",async e=>{let r=await b(e.projectPath),n=await nt.getAll(r);if(n.length===0)return{content:[{type:"text",text:"No outcome data yet."}]};let s=It(n,mt);if(s.sprints.length===0)return{content:[{type:"text",text:"Not enough data for velocity."}]};let o=["## Velocity Detail",`Average: ${s.averageVelocity} pts/sprint`,`Trend: ${s.velocityTrend}`,`Estimation accuracy: ${s.estimationAccuracy}%`,`
738
- ### Sprints (${s.sprints.length})`];for(let a of s.sprints)o.push(`- Sprint ${a.sprintNumber}: ${a.pointsCompleted} pts, ${a.tasksCompleted} tasks, accuracy ${a.estimationAccuracy}%${a.avgVariance?`, variance ${a.avgVariance>0?"+":""}${a.avgVariance}%`:""}`);if(e.remainingPoints&&s.averageVelocity>0){let{projectCompletion:a}=await Promise.resolve().then(()=>(on(),Qr)),c=a(e.remainingPoints,s.averageVelocity,mt);o.push(`
739
- ### Completion Projection`),o.push(`Remaining: ${c.totalPoints} points`),o.push(`Sprints needed: ${c.sprints}`),c.estimatedDate&&o.push(`Estimated completion: ${c.estimatedDate.slice(0,10)}`)}return{content:[{type:"text",text:o.join(`
740
- `)}]}}))}l(Zr,"registerProjectTools");import{execSync as un}from"node:child_process";import ns from"node:fs";import vt from"node:path";import{z as Pt}from"zod";var Ai=new et;function Ci(i){try{return un("git diff --cached --name-only --diff-filter=ACMR",{cwd:i,encoding:"utf-8",timeout:1e4}).trim().split(`
741
- `).filter(e=>e.length>0)}catch{return[]}}l(Ci,"getStagedFiles");function Di(i){try{return un("git diff --name-only --diff-filter=ACMR",{cwd:i,encoding:"utf-8",timeout:1e4}).trim().split(`
742
- `).filter(e=>e.length>0)}catch{return[]}}l(Di,"getChangedFiles");function Ni(i,t){try{return un(t?"git diff --cached":"git diff",{cwd:i,encoding:"utf-8",timeout:15e3,maxBuffer:1024*1024}).trim()}catch{return""}}l(Ni,"getDiff");function ts(i,t=3e3){try{let e=ns.readFileSync(i,"utf-8");return e.length>t?`${e.slice(0,t)}
743
- ... [truncated at ${t} chars]`:e}catch{return null}}l(ts,"readFileSafe");function Ii(i,t,e){let r=i;return t&&t.length>0&&(r=r.filter(n=>t.some(s=>es(n,s)))),e&&e.length>0&&(r=r.filter(n=>!e.some(s=>es(n,s)))),r}l(Ii,"filterFiles");function es(i,t){return t.startsWith("*.")?i.endsWith(t.slice(1)):t.startsWith("**/*.")?i.endsWith(t.slice(3)):i.includes(t)}l(es,"matchGlob");function rs(i){i.tool("prjct_review_context","Build AI code review context: git diff (primary) + rules (AGENTS.md) + project patterns/anti-patterns + related memories. The agent reviews in-context.",{projectPath:Pt.string().describe("Project directory path"),include:Pt.array(Pt.string()).optional().describe('File patterns to include (e.g. ["*.ts", "*.tsx"])'),exclude:Pt.array(Pt.string()).optional().describe('File patterns to exclude (e.g. ["*.test.ts"])'),rulesFile:Pt.string().optional().default("AGENTS.md").describe("Rules file path (default: AGENTS.md)")},y("prjct_review_context",async e=>{let r=await b(e.projectPath),n=[],s=Ci(e.projectPath),o=s.length>0,a=o?"staged":"changed";if(s.length===0&&(s=Di(e.projectPath)),s.length===0)return{content:[{type:"text",text:"No staged or changed files to review."}]};if(s=Ii(s,e.include,e.exclude),s.length===0)return{content:[{type:"text",text:"No files match include/exclude filters."}]};n.push(`## Code Review Context (${s.length} ${a} files)
744
- `);let c=vt.join(e.projectPath,e.rulesFile),u=ts(c);u&&(n.push(`### Rules (${e.rulesFile})
745
- `),n.push("```markdown"),n.push(u),n.push("```\n"));let p=lt.getActive(r);if(p){if(p.patterns?.length){n.push(`### Project Patterns (follow these)
746
- `);for(let w of p.patterns)n.push(`- **${w.name}**: ${w.description}`);n.push("")}if(p.antiPatterns?.length){n.push(`### Anti-Patterns (flag these)
747
- `);for(let w of p.antiPatterns)n.push(`- **${w.issue}**: ${w.suggestion}`);n.push("")}if(p.conventions?.length){n.push(`### Conventions
748
- `);for(let w of p.conventions)n.push(`- [${w.category}] ${w.rule}`);n.push("")}}let d=s.map(w=>vt.basename(w,vt.extname(w))).join(" "),g=await Ai.searchMemories(r,`bug ${d}`,5);if(g.length>0){n.push(`### Related Bug Memories
749
- `);for(let w of g)n.push(`- **${w.title}**: ${w.content.slice(0,200)}`);n.push("")}let h=Ni(e.projectPath,o);h&&(n.push(`### Git Diff
750
- `),n.push("```diff"),n.push(h.length>2e4?`${h.slice(0,2e4)}
751
- ... [diff truncated]`:h),n.push("```\n"));let j=s.filter(w=>{try{return ns.statSync(vt.join(e.projectPath,w)).size<3e3}catch{return!1}});if(j.length>0){n.push(`### Small Files (full content)
752
- `);for(let w of j.slice(0,10)){let k=vt.join(e.projectPath,w),I=ts(k);if(I){n.push(`#### \`${w}\`
753
- `);let z=vt.extname(w).slice(1)||"text";n.push(`\`\`\`${z}`),n.push(I),n.push("```\n")}}}return n.push(`### Review Instructions
754
- `),n.push("Review the diff above against the rules, patterns, and conventions."),n.push("For each file, check:"),n.push("1. Compliance with rules (AGENTS.md)"),n.push("2. Known anti-patterns (flag any matches)"),n.push("3. Convention violations"),n.push("4. Past bug patterns from memory"),n.push(`5. General code quality
755
- `),n.push("End your review with: **STATUS: PASSED** or **STATUS: FAILED**"),n.push("If FAILED, list specific violations with file:line references."),{content:[{type:"text",text:n.join(`
756
- `)}]}}))}l(rs,"registerReviewTools");import{z as L}from"zod";W();var Mi=new et;function ss(i){let t=i;t.tool("prjct_session_start","Start an agent session. Auto-links to active prjct task if one exists.",{projectPath:L.string().describe("Project directory path"),goal:L.string().optional().describe("Session goal or objective")},y("prjct_session_start",async e=>{let r=await b(e.projectPath),n=f(),s=F(),o=await X.getCurrentTask(r),a=o?.id??null;T.run(r,`INSERT INTO agent_sessions (id, project_id, directory, task_id, goal, started_at, created_at)
757
- VALUES (?, ?, ?, ?, ?, ?, ?)`,s,r,e.projectPath,a,e.goal??null,n,n);let c=[`Session started: ${s}`];return o&&(c.push(`Linked to task: ${o.description}`),c.push(`Task started: ${o.startedAt}`)),e.goal&&c.push(`Goal: ${e.goal}`),{content:[{type:"text",text:c.join(`
758
- `)}]}})),t.tool("prjct_session_end","End the current agent session with optional summary",{projectPath:L.string().describe("Project directory path"),sessionId:L.string().describe("Session ID to end"),summary:L.string().optional().describe("Brief session summary")},y("prjct_session_end",async e=>{let r=await b(e.projectPath),n=f();return T.get(r,"SELECT * FROM agent_sessions WHERE id = ? AND project_id = ?",e.sessionId,r)?(T.run(r,"UPDATE agent_sessions SET ended_at = ?, summary = ? WHERE id = ?",n,e.summary??null,e.sessionId),{content:[{type:"text",text:"Session ended."}]}):{content:[{type:"text",text:`Session ${e.sessionId} not found.`}]}})),t.tool("prjct_session_summary","Save structured end-of-session summary (Goal/Accomplished/Discoveries/Next Steps/Files)",{projectPath:L.string().describe("Project directory path"),sessionId:L.string().describe("Session ID"),goal:L.string().describe("What was the goal"),accomplished:L.string().describe("What was accomplished"),discoveries:L.string().optional().describe("Key discoveries or learnings"),nextSteps:L.string().optional().describe("What should happen next"),filesTouched:L.array(L.string()).optional().describe("Files modified during session")},y("prjct_session_summary",async e=>{let r=await b(e.projectPath),n=f(),s=[`## Goal
759
- ${e.goal}`,`## Accomplished
760
- ${e.accomplished}`];e.discoveries&&s.push(`## Discoveries
761
- ${e.discoveries}`),e.nextSteps&&s.push(`## Next Steps
762
- ${e.nextSteps}`);let o=s.join(`
763
-
764
- `),a=e.filesTouched?JSON.stringify(e.filesTouched):null;return T.run(r,"UPDATE agent_sessions SET ended_at = ?, summary = ?, goal = ?, files_touched = ? WHERE id = ? AND project_id = ?",n,o,e.goal,a,e.sessionId,r),{content:[{type:"text",text:`Session summary saved (${o.length} chars).`}]}})),t.tool("prjct_prompt_save","Capture user prompt text for future context",{projectPath:L.string().describe("Project directory path"),content:L.string().describe("User prompt text"),sessionId:L.string().optional().describe("Current session ID")},y("prjct_prompt_save",async e=>{let r=await b(e.projectPath),n=F();return T.run(r,"INSERT INTO user_prompts (id, project_id, session_id, content, created_at) VALUES (?, ?, ?, ?, ?)",n,r,e.sessionId??null,e.content,f()),{content:[{type:"text",text:`Prompt saved: ${n}`}]}})),t.tool("prjct_session_context","Recover context after compaction: last session + relevant/recent memories + active task state",{projectPath:L.string().describe("Project directory path"),memoryLimit:L.number().optional().default(5).describe("Max memories to include (default 5)"),promptLimit:L.number().optional().default(3).describe("Max prompts to include (default 3)")},y("prjct_session_context",async e=>{let r=await b(e.projectPath),n=[],s=await X.getCurrentTask(r);s?(n.push("## Active Task"),n.push(`**${s.description}**`),s.branch&&n.push(`Branch: ${s.branch}`),n.push(`Started: ${s.startedAt}`)):n.push("## No Active Task");let o=T.get(r,`SELECT * FROM agent_sessions WHERE project_id = ?
765
- ORDER BY started_at DESC LIMIT 1`,r);if(o&&(n.push(`
766
- ## Last Session`),o.goal&&n.push(`Goal: ${o.goal}`),o.summary&&n.push(o.summary),o.ended_at?n.push(`Ended: ${o.ended_at}`):n.push("Status: **still open** (may have been interrupted)"),o.files_touched))try{let c=JSON.parse(o.files_touched);c.length>0&&n.push(`Files: ${c.join(", ")}`)}catch{}if(s){let c=await Mi.getRelevantMemories(r,{params:{description:s.description}},e.memoryLimit);if(c.length>0){n.push(`
767
- ## Relevant Memories`);for(let u of c)n.push(`- **${u.title}**: ${u.content.slice(0,150)}${u.content.length>150?"...":""}`)}}else{let c=T.query(r,`SELECT id, title, content, tags, updated_at FROM memories
768
- WHERE project_id = ? AND deleted_at IS NULL
769
- ORDER BY updated_at DESC LIMIT ?`,r,e.memoryLimit);if(c.length>0){n.push(`
770
- ## Recent Memories`);for(let u of c)n.push(`- **${u.title}**: ${u.content.slice(0,150)}${u.content.length>150?"...":""}`)}}let a=T.query(r,`SELECT * FROM user_prompts WHERE project_id = ?
771
- ORDER BY created_at DESC LIMIT ?`,r,e.promptLimit);if(a.length>0){n.push(`
772
- ## Recent User Prompts`);for(let c of a)n.push(`- ${c.content.slice(0,200)}${c.content.length>200?"...":""}`)}return n.length===0?{content:[{type:"text",text:"No session context available."}]}:{content:[{type:"text",text:n.join(`
773
- `)}]}}))}l(ss,"registerSessionTools");import{z as ie}from"zod";var ln=class{static{l(this,"CustomWorkflowStorage")}createWorkflow(t,e){let r=new Date().toISOString();T.run(t,`INSERT INTO custom_workflows (name, description, created_at, updated_at, is_builtin, enabled, metadata)
774
- VALUES (?, ?, ?, ?, 0, 1, ?)`,e.name,e.description??null,r,r,e.metadata?JSON.stringify(e.metadata):null);let n=T.get(t,"SELECT id FROM custom_workflows WHERE name = ?",e.name);if(!n)throw new Error(`Failed to create workflow: ${e.name}`);return n.id}getWorkflow(t,e){let r=T.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 T.query(t,r).map(s=>this.rowToWorkflow(s))}updateWorkflow(t,e,r){if(!this.getWorkflow(t,e))return!1;let s=new Date().toISOString(),o=[],a=[];return r.description!==void 0&&(o.push("description = ?"),a.push(r.description)),r.enabled!==void 0&&(o.push("enabled = ?"),a.push(r.enabled?1:0)),r.metadata!==void 0&&(o.push("metadata = ?"),a.push(JSON.stringify(r.metadata))),o.length===0?!1:(o.push("updated_at = ?"),a.push(s),a.push(e),T.run(t,`UPDATE custom_workflows SET ${o.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 T.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}}},oe=new ln;function pn(i){return{id:i.id,type:i.type,command:i.command,position:i.position,action:i.action,description:i.description,enabled:i.enabled===1,timeoutMs:i.timeout_ms,createdAt:i.created_at,sortOrder:i.sort_order}}l(pn,"rowToRule");var dn=class{static{l(this,"WorkflowRuleStorage")}addRule(t,e){let r=_.get(t,"SELECT MAX(sort_order) as m FROM workflow_rules WHERE command = ?",e.command),n=e.sortOrder||(r?.m??-1)+1;return _.run(t,`INSERT INTO workflow_rules (type, command, position, action, description, enabled, timeout_ms, created_at, sort_order)
775
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,e.type,e.command,e.position,e.action,e.description??null,e.enabled?1:0,e.timeoutMs,e.createdAt,n),_.get(t,"SELECT last_insert_rowid() as id")?.id??0}removeRule(t,e){return _.get(t,"SELECT id FROM workflow_rules WHERE id = ?",e)?(_.run(t,"DELETE FROM workflow_rules WHERE id = ?",e),!0):!1}updateRule(t,e,r){if(!_.get(t,"SELECT id FROM workflow_rules WHERE id = ?",e))return!1;let s={type:{column:"type"},command:{column:"command"},position:{column:"position"},action:{column:"action"},description:{column:"description"},enabled:{column:"enabled",transform:l(c=>c?1:0,"transform")},timeoutMs:{column:"timeout_ms"},createdAt:{column:"created_at"},sortOrder:{column:"sort_order"}},o=[],a=[];for(let[c,u]of Object.entries(r)){let p=s[c];if(!p)continue;o.push(`${p.column} = ?`);let d=u;a.push(p.transform?p.transform(d):d)}return o.length===0||(a.push(e),_.run(t,`UPDATE workflow_rules SET ${o.join(", ")} WHERE id = ?`,...a)),!0}getRuleById(t,e){let r=_.get(t,"SELECT * FROM workflow_rules WHERE id = ?",e);return r?pn(r):null}getRulesForCommand(t,e){let r=oe.getWorkflow(t,e);return!r||!r.enabled?[]:_.query(t,"SELECT * FROM workflow_rules WHERE command = ? AND enabled = 1 ORDER BY sort_order ASC",e).map(pn)}getAllRules(t){return _.query(t,"SELECT * FROM workflow_rules ORDER BY command ASC, sort_order ASC").map(pn)}resetRules(t){let e=_.get(t,"SELECT COUNT(*) as c FROM workflow_rules");return _.run(t,"DELETE FROM workflow_rules"),e?.c??0}},mn=new dn;function os(i){let t=i;t.tool("prjct_workflow_rules","Get workflow rules for a command (gates, hooks, steps, instructions)",{projectPath:ie.string().describe("Project directory path"),command:ie.string().describe("Command name (task, done, ship, sync, etc.)")},y("prjct_workflow_rules",async e=>{let r=await b(e.projectPath),n=mn.getRulesForCommand(r,e.command);if(n.length===0)return{content:[{type:"text",text:`No workflow rules for \`${e.command}\`.`}]};let s={};for(let a of n){let c=`${a.type}:${a.position}`;s[c]||(s[c]=[]),s[c].push(a)}let o=[`## Workflow Rules for \`${e.command}\``];for(let[a,c]of Object.entries(s)){o.push(`
776
- ### ${a}`);for(let u of c){let p=u.enabled?"":" (disabled)";o.push(`- ${u.action}${u.description?` \u2014 ${u.description}`:""}${p}`)}}return{content:[{type:"text",text:o.join(`
777
- `)}]}})),t.tool("prjct_workflow_list","List all workflows for this project (built-in + custom)",{projectPath:ie.string().describe("Project directory path")},y("prjct_workflow_list",async e=>{let r=await b(e.projectPath),n=oe.getAllWorkflows(r);if(n.length===0)return{content:[{type:"text",text:"No workflows configured."}]};let s=n.map(o=>{let a=o.isBuiltin?"(built-in)":"(custom)",c=o.enabled?"":" [disabled]";return`- **${o.name}** ${a}${c}${o.description?`: ${o.description}`:""}`});return{content:[{type:"text",text:`## Workflows (${n.length})
778
-
779
- ${s.join(`
780
- `)}`}]}})),t.tool("prjct_workflow_status","Current workflow execution state + active rules",{projectPath:ie.string().describe("Project directory path")},y("prjct_workflow_status",async e=>{let r=await b(e.projectPath),n=await X.getCurrentTask(r),s=mn.getAllRules(r),o=["## Workflow Status"];n?(o.push(`
781
- Active task: **${n.description}**`),o.push(`Started: ${n.startedAt}`)):o.push(`
782
- No active task.`);let a=s.filter(c=>c.enabled);if(a.length>0){o.push(`
783
- ### Active Rules (${a.length})`);for(let c of a)o.push(`- [${c.type}] ${c.command}:${c.position} \u2192 ${c.action}`)}else o.push(`
784
- No active workflow rules.`);return{content:[{type:"text",text:o.join(`
785
- `)}]}}))}l(os,"registerWorkflowTools");var Li=`## prjct Memory Protocol
786
-
787
- ### On session start:
788
- 1. Call prjct_session_start to register this session
789
- 2. Call prjct_session_context to recover context from last session
790
- 3. Call prjct_mem_search for any relevant memories to current task
791
-
792
- ### During work \u2014 SAVE when you:
793
- - Make a technical decision \u2192 prjct_decision_record (key/value with confidence tracking)
794
- - Discover a project pattern \u2192 prjct_mem_save with topic_key pattern/*
795
- - Fix a non-obvious bug \u2192 topic_key bug/*
796
- - Learn a user preference \u2192 prjct_preference_set (key/value)
797
- - Find an architectural constraint \u2192 topic_key architecture/*
798
- - Use prjct_mem_suggest_topic if unsure about the right topic_key
799
-
800
- ### During work \u2014 SEARCH when you:
801
- - Start a new subtask (search for related memories)
802
- - Hit an error (search for similar bugs)
803
- - Need to make a decision (prjct_decision_get to check prior decisions)
804
-
805
- ### Decisions & Preferences:
806
- - prjct_decision_record / prjct_decision_get \u2014 technical decisions with confidence tracking
807
- - prjct_preference_set / prjct_preference_get \u2014 user preferences
808
-
809
- ### Code Intelligence:
810
- - prjct_impact_analysis \u2014 before reviewing changes, check what else is affected
811
- - prjct_related_context \u2014 find related files (imports + co-change) for context
812
-
813
- ### Maintenance:
814
- - prjct_archive_stale \u2014 periodically clean up old decisions
815
- - prjct_confirm \u2014 when user confirms a decision/preference, boost confidence
816
- - prjct_analysis_staleness \u2014 check if project analysis needs refresh
817
- - prjct_mem_consolidate \u2014 merge duplicate memories (run periodically)
818
-
819
- ### On session end:
820
- 1. Call prjct_session_summary with Goal/Accomplished/Discoveries/Next Steps/Files
821
- 2. Save any important learnings not yet captured via prjct_mem_save
822
- 3. Call prjct_mem_capture_passive on your final output to auto-extract learnings`;function is(){let i=new Oi({name:"prjct",version:"1.0.0"},{instructions:Li});return Nr(i),ss(i),Zr(i),Ar(i),os(i),rs(i),zr(i),mr(i),gr(i),qr(i),i}l(is,"createServer");async function Fi(){let i=is(),t=new $i;await i.connect(t)}l(Fi,"main");Fi().catch(i=>{console.error("prjct MCP server failed:",i),process.exit(1)});
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(`
539
+ Active task: **${s.description}**`),i.push(`Started: ${s.startedAt}`)):i.push(`
540
+ No active task.`);let a=o.filter(u=>u.enabled);if(a.length>0){i.push(`
541
+ ### Active Rules (${a.length})`);for(let u of a)i.push(`- [${u.type}] ${u.command}:${u.position} \u2192 ${u.action}`)}else i.push(`
542
+ No active workflow rules.`);return{content:[{type:"text",text:i.join(`
543
+ `)}]}}))}c($r,"registerWorkflowTools");var Mn=`# prjct \u2014 persona-aware context broker
544
+
545
+ Use when you want prior project memory, state, or a registered workflow. You decide whether any of it is relevant to the current turn.
546
+
547
+ ## What's here
548
+ - **Memory** (facts, decisions, learnings, gotchas, patterns, anti-patterns, insights, questions, sources, people, okrs, shipped work, inbox). Save via memory tools; recall via search/list. Tags are freeform.
549
+ - **Session + task state** via the session and project tools.
550
+ - **Workflows** registered in this project (can be run, listed, edited).
551
+ - **Code intelligence** helpers (impact, related context) for navigating repos.
552
+ - **Patterns** detected by analysis.
553
+
554
+ ## Gotchas
555
+ - Memory is best-effort \u2014 never assume recall returned everything; it's a query, not a lookup.
556
+ - Topic keys are free-form strings; don't invent new vocabularies when existing ones fit.
557
+ - Not every project defines every memory type \u2014 if one is empty, that's fine.
558
+ - Saving a secret-looking string is refused by default. Re-save with a scrubbed version.`;function Wr(){let n=new On({name:"prjct",version:"1.0.0"},{instructions:Mn});return Lr(n),Xr(n),Pr(n),$r(n),pr(n),n}c(Wr,"createServer");async function Fn(){let n=Wr(),t=new jn;await n.connect(t)}c(Fn,"main");Fn().catch(n=>{console.error("prjct MCP server failed:",n),process.exit(1)});