prjct-cli 1.56.2 → 1.56.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,13 +5,13 @@ import { dirname as __pathDirname } from 'path';
5
5
  var require = __createRequire(import.meta.url);
6
6
  var __filename = __fileURLToPath(import.meta.url);
7
7
  var __dirname = __pathDirname(__filename);
8
- var 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 Bi}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 B(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(B,"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(B(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 K 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 K.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 K.readFile(i,"utf-8");return JSON.parse(r)}catch(r){if(B(r))return t;throw r}}async function rt(i,t,e=2){let r=Ft.dirname(i);await K.mkdir(r,{recursive:!0});let n=JSON.stringify(t,null,e);await K.writeFile(i,n,"utf-8")}async function ue(i,t=""){try{return await K.readFile(i,"utf-8")}catch(e){if(B(e))return t;throw e}}async function Rn(i,t){let e=Ft.dirname(i);await K.mkdir(e,{recursive:!0}),await K.appendFile(i,`${t}
9
- `,"utf-8")}async function N(i){try{return await K.access(i),!0}catch(t){if(B(t))return!1;throw t}}async function le(i){try{return(await K.stat(i)).isDirectory()}catch(t){if(B(t))return!1;throw t}}async function J(i){await K.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(J,"ensureDir")});var Dn=$(()=>{"use strict"});import{z as Q}from"zod";function An(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(An,"compareSemver")});import{exec as fs,execFile as hs}from"node:child_process";import{promisify as Cn}from"node:util";var R,ma,ht=$(()=>{"use strict";R=Cn(fs),ma=Cn(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=600*1e3;l(On,"readProviderCache");l(Ln,"writeProviderCache")});var Ht={};Lt(Ht,{AntigravityProvider:()=>he,ClaudeProvider:()=>Bt,CodexProvider:()=>ye,CursorProvider:()=>Un,GeminiProvider:()=>fe,Providers:()=>Y,WindsurfProvider:()=>Wn,detectAllProviders:()=>Te,detectAntigravity:()=>Rs,detectCodex:()=>qn,detectCursorProject:()=>Hn,detectProvider:()=>ge,detectWindsurfProject:()=>Gn,getActiveProvider:()=>xs,getCapabilities:()=>ks,getCommandsDir:()=>Ns,getGlobalContextPath:()=>Ds,getGlobalSettingsPath:()=>As,getProjectCommandsPath:()=>Is,getProviderBranding:()=>vs,getSkillsPath:()=>Cs,hasProviderConfig:()=>_s,needsCursorRouterRegeneration:()=>Ps,needsWindsurfRouterRegeneration:()=>js,selectProvider:()=>Ms,validateCliVersion:()=>Bn});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=Bn(i,r||void 0);return{installed:!0,version:r||void 0,path:e,versionWarning:n||void 0}}function Bn(i,t){let e=Y[i];return!e.minCliVersion||!t?null:An(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?Bt:t.gemini.installed&&!t.claude.installed?fe:Bt}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 Hn(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 Hn(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 Ds(i){let t=Y[i];return t.configDir?O.join(t.configDir,t.contextFile):null}function As(i){let t=Y[i];return!t.configDir||!t.settingsFile?null:O.join(t.configDir,t.settingsFile)}function Cs(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,Bt,fe,he,Un,Wn,ye,Y,Gt=$(()=>{"use strict";Dn();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");Bt={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:Bt,gemini:fe,cursor:Un,antigravity:he,windsurf:Wn,codex:ye};l(Xn,"whichCommand");l(Ss,"getCliVersion");l(ge,"detectProvider");l(Bn,"validateCliVersion");l(Te,"detectAllProviders");l(xs,"getActiveProvider");l(_s,"hasProviderConfig");l(vs,"getProviderBranding");l(Hn,"detectCursorProject");l(Ps,"needsCursorRouterRegeneration");l(Gn,"detectWindsurfProject");l(js,"needsWindsurfRouterRegeneration");l(Rs,"detectAntigravity");l(qn,"detectCodex");l(Ds,"getGlobalContextPath");l(As,"getGlobalSettingsPath");l(Cs,"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,De,Ec,Ae=$(()=>{"use strict";ft();qt=null,to=null,Rt=null;l(ir,"getPackageRoot");l(Re,"getVersion");De=Re(),Ec=ir()});var lr={};Lt(lr,{default:()=>oo,worktreeService:()=>ur});import Ce 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 Ce.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 Ce.copyFile(r,tt.join(t,".env"));let n=tt.join(e,".prjct"),s=tt.join(t,".prjct");await N(n)&&!await N(s)&&await Ce.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(`
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
11
 
12
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 Hr={};Lt(Hr,{mdActionRequired:()=>hi,mdBadge:()=>si,mdCallout:()=>oi,mdCodeBlock:()=>ri,mdDone:()=>mi,mdError:()=>fi,mdFooter:()=>Wr,mdFrontmatter:()=>Xr,mdHeader:()=>Ur,mdJoin:()=>Br,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 Br(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(`
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
15
  `)}function ri(i,t=""){return`\`\`\`${t}
16
16
  ${i}
17
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}
@@ -25,12 +25,12 @@ ${_t(t,e)}`}function di(i){let t=Object.entries(i).filter(([,n])=>n!=null);if(t.
25
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
26
  `)}function ct(i,t,...e){return[Xr(i),`# ${t}`,...e.filter(Boolean)].join(`
27
27
 
28
- `)}function Br(...i){return i.filter(Boolean).join(`
28
+ `)}function Hr(...i){return i.filter(Boolean).join(`
29
29
 
30
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";Ae();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(Br,"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:()=>Jr,formatVelocityContext:()=>sn,getSprintEnd:()=>Kr,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 Kr(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=Jr(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=Kr(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 Jr(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(Kr,"getSprintEnd");l(wi,"getSprintNumber");l(It,"calculateVelocity");l(bi,"projectCompletion");l(Ei,"bucketBySprint");l(ki,"buildSprintVelocities");l(Jr,"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 H}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 J(this.globalBaseDir),await J(this.globalProjectsDir),await J(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 J(S.join(e,n));return await J(S.join(e,"planning","tasks")),await J(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 J(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(Ht)).getActiveProvider()).configDir}async getAgentSettingsPath(){let t=await(Gt(),ae(Ht)).getActiveProvider();return(Gt(),ae(Ht)).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,D=$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(`
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(`
34
34
  -- =======================================================================
35
35
  -- Document storage (backward-compatible with JSON file pattern)
36
36
  -- =======================================================================
@@ -491,25 +491,25 @@ ${_t(t,e)}`}function di(i){let t=Object.entries(i).filter(([,n])=>n!=null);if(t.
491
491
  );
492
492
 
493
493
  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(D.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(`
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(`
495
495
  CREATE TABLE IF NOT EXISTS _migrations (
496
496
  version INTEGER PRIMARY KEY,
497
497
  name TEXT NOT NULL,
498
498
  applied_at TEXT NOT NULL
499
499
  )
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 Bs(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(Bs,"extractImportSources");async function Hs(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(Hs,"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=Bs(a),u=[];for(let p of c){let d=await Hs(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 Kn(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(Kn,"scoreFromSeeds");var Jn="import-graph";function qs(i,t){T.setDoc(i,Jn,t)}l(qs,"saveGraph");function jt(i){return T.getDoc(i,Jn)}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 Ks(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=Js(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(Ks,"buildMatrix");function Js(i,t){return i<t?`${i}\0${t}`:`${t}\0${i}`}l(Js,"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 Ks(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 C}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",C.object({path:C.string(),operation:C.enum(["read","write","delete","create","copy"]),reason:C.string().optional()})),pc=Et.create("ValidationError",C.object({field:C.string(),expected:C.string(),received:C.string().optional(),message:C.string().optional()})),dc=Et.create("PermissionError",C.object({action:C.string(),resource:C.string(),reason:C.string().optional()})),mc=Et.create("TaskError",C.object({taskId:C.string().optional(),operation:C.enum(["create","update","complete","pause","resume","delete"]),reason:C.string()})),gc=Et.create("SessionError",C.object({sessionId:C.string().optional(),reason:C.string()})),fc=Et.create("SyncError",C.object({projectId:C.string().optional(),operation:C.enum(["push","pull","auth","connect"]),reason:C.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();Ae();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=D.getLocalConfigPath(t),r=await Ie.readFile(e,"utf-8");return dr(r)}catch(e){return B(e)||console.warn(`Warning: Could not read config at ${t}: ${Pe(e)}`),null}}async writeConfig(t,e){let r=D.getLocalConfigPath(t);await rt(r,e)}async readGlobalConfig(t){try{let e=D.getGlobalProjectConfigPath(t),r=await Ie.readFile(e,"utf-8");return dr(r)}catch(e){return B(e)||console.warn(`Warning: Could not read global config for ${t}: ${Pe(e)}`),null}}async writeGlobalConfig(t,e){let r=D.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:De,lastSync:r},await this.writeGlobalConfig(t,e)}return e}async createConfig(t,e){let r=D.generateProjectId(t),n=D.getGlobalProjectPath(r),s=D.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:De,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 D.hasLegacyStructure(t))return!1;if(!await D.hasConfig(t))return!0;let n=await this.readConfig(t);if(!n||!n.projectId)return!0;let s=D.getGlobalProjectPath(n.projectId);try{return(await Ie.readdir(io.join(s,"core"))).length===0}catch(o){return B(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 D.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=D.generateProjectId(t);return{projectId:r,dataPath:D.getDisplayPath(D.getGlobalProjectPath(r))}}},ao=new Me,Dt=ao;async function b(i){return Dt.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:H.string().describe("Project directory path"),changedFiles:H.array(H.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(`
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
502
  ### Directly Changed (${s.directlyChanged.length})`);for(let c of s.directlyChanged)a.push(`- ${c}`);if(s.affectedByImports.length>0){a.push(`
503
503
  ### Affected via Imports (${s.affectedByImports.length})`);for(let c of s.affectedByImports)a.push(`- ${c}`)}return a.push(`
504
504
  ### Affected Domains`),a.push(o.size>0?Array.from(o).join(", "):"none detected"),a.push(`
505
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:H.string().describe("Project directory path"),file:H.string().optional().describe("File path to get neighbors for (omit for graph stats)"),rebuild:H.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}`,`
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
507
  ### Imports (${o.length})`,...o.map(u=>`- ${u}`),`
508
508
  ### Imported By (${a.length})`,...a.map(u=>`- ${u}`)].join(`
509
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:H.string().describe("Project directory path"),seedFiles:H.array(H.string()).describe("Seed files to find co-change partners for"),rebuild:H.boolean().optional().default(!1).describe("Force rebuild the co-change matrix"),maxResults:H.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:H.string().describe("Project directory path"),seedFiles:H.array(H.string()).describe("Seed files to find related context for"),maxResults:H.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?Kn(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 At}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 Kt(i,t=!1){return t||i>=6?"high":i>=3?"medium":"low"}l(Kt,"calculateConfidence");W();var Jt=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 Jt{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=Kt(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=Kt(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:Kt(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 = ?,
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
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
514
  (id, project_id, title, content, tags, topic_key, content_hash, user_triggered, created_at, updated_at)
515
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 = ?,
@@ -540,24 +540,24 @@ Context: ${n}`:""}`,tags:o,userTriggered:!0,topicKey:`preference:${e}`})}async f
540
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
541
  WHERE project_id = ? AND timestamp >= ?
542
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:At.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(`
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
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
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:At.string().describe("Project directory path"),days:At.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}%`,`
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
547
  Compactions: ${n.compactions}`];if(s.length>0){o.push(`
548
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:At.string().describe("Project directory path"),limit:At.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 Ct={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"}},Be=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=Ct[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 Ct[t]}getPrompt(t){return Ct[t].prompt}getValidCommands(t){return Ct[t].transitions}formatNextSteps(t){return Ct[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}`}})}},He=new Be;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=D.getSyncPendingPath(t.projectId),r=await Ut(e,[])??[];r.push(t),await rt(e,r)}async getPending(t){let e=D.getSyncPendingPath(t);return await Ut(e,[])??[]}async clearPending(t){let e=D.getSyncPendingPath(t);await rt(e,[])}async updateLastSync(t){let e=D.getLastSyncPath(t),r={timestamp:f(),success:!0};await rt(e,r)}async getLastSync(t){let e=D.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=He.getCurrentState(t),n=He.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:
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
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=Do(i),c=await Ao(t),u=await Co(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 Do(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(Do,"extractKeywords");async function Ao(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){B(s)}}return l(e,"walk"),await e(i),t}l(Ao,"getAllCodeFiles");async function Co(i){let t=new Map;try{let{stdout:e}=await R(`git log -30 --pretty=format:"%H %ct" --name-only | awk '
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 '
553
553
  /^[a-f0-9]{40}/ { commit=$1; timestamp=$2; next }
554
554
  NF { files[$0]++; if (!lastmod[$0]) lastmod[$0]=timestamp }
555
555
  END { for (f in files) print files[f], lastmod[f], f }
556
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(Co,"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}],Bo=[{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}],Ho={typescript:Pr,javascript:Pr,python:Wo,go:Xo,rust:Bo,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(B(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=Ho[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(`
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
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
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 Dr(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)
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
561
 
562
562
  ${n.join(`
563
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})
@@ -567,8 +567,8 @@ ${n.join(`
567
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
568
 
569
569
  ${o.join(`
570
- `)}`}]}}))}l(Dr,"registerFileTools");import{z as x}from"zod";var at=new et,zo=new kt,Ar=3e3,Cr=`
571
- ... [truncated]`;function Ye(i){return i.replace(/<private>[\s\S]*?<\/private>/gi,"").trim()}l(Ye,"stripPrivateTags");function Ke(i){return i.length<=Ar?i:i.slice(0,Ar-Cr.length)+Cr}l(Ke,"truncateContent");var Je=[{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=Ke(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}
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
572
  ${p}${u.content.length>120?"...":""}`});a.push(`Found ${n.length} memories:
573
573
 
574
574
  ${c.join(`
@@ -594,12 +594,12 @@ Updated: ${n.updatedAt}`}]}:{content:[{type:"text",text:`Memory ${e.memoryId} no
594
594
  Session: ${n.session_id}`:"";return{content:[{type:"text",text:`## Timeline around "${n.title}"${a}
595
595
 
596
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=Je[0],s=0;for(let d of Je){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(`
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
598
  Note: This topic_key already exists \u2192 will UPDATE "${u.title}" (id: ${u.id})`),p.push(`
599
- Available families:`);for(let d of Je)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=Ke(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:
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
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=Ke(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(`
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
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
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
605
  ${a}${o.content.length>120?"...":""}`});return{content:[{type:"text",text:`Found ${n.length} memories:
@@ -620,7 +620,7 @@ ${o.join(`
620
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
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
622
  No task feedback recorded yet.`),{content:[{type:"text",text:s.join(`
623
- `)}]}}))}l(Nr,"registerMemoryTools");import Gr from"node:path";import{z as A}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"]),Ko=v.object({hours:v.number(),minutes:v.number(),totalMinutes:v.number()}),Jo=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:Jo.optional(),qualityMetrics:Zo.optional(),quantitativeImpact:v.string().optional(),duration:Ko.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()-10080*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(`
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
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
625
  ${g.join(`
626
626
  `)}`:null,j?`## Progress
@@ -671,20 +671,20 @@ FROM "${E.basename(E.dirname(e))}/${E.basename(e)}/architecture" OR "${E.basenam
671
671
  SORT file.mtime DESC
672
672
  LIMIT 10
673
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(),Hr));c=`${u(s)}
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
675
 
676
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 Dt.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:A.string().describe("Project directory path"),notePath:A.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:**
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
678
  ${Object.entries(s.frontmatter).map(([a,c])=>`- ${a}: ${JSON.stringify(c)}`).join(`
679
679
  `)}`),o.push(s.content),{content:[{type:"text",text:o.join(`
680
680
 
681
- `)}]}})),t.tool("prjct_obsidian_write","Create or update a note in the project Obsidian vault with optional frontmatter.",{projectPath:A.string().describe("Project directory path"),notePath:A.string().describe('Relative path within the project vault folder (e.g., "architecture/new-decision.md")'),content:A.string().describe("Markdown content of the note (without frontmatter)"),frontmatter:A.record(A.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:A.string().describe("Project directory path"),query:A.string().describe("Search query (multi-word supported)"),folder:A.string().optional().describe('Restrict to a folder (e.g., "architecture", "research")'),limit:A.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}
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
682
  \`${a.path}\` (score: ${a.score.toFixed(1)})
683
683
  > ${a.excerpt}`);return{content:[{type:"text",text:`## Search: "${e.query}" (${s.length} results)
684
684
 
685
685
  ${o.join(`
686
686
 
687
- `)}`}]}})),t.tool("prjct_obsidian_list","List notes and folders in the project Obsidian vault.",{projectPath:A.string().describe("Project directory path"),folder:A.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}):**
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
688
  ${o.map(u=>`- ${u.name}/`).join(`
689
689
  `)}`),a.length>0&&c.push(`**Notes (${a.length}):**
690
690
  ${a.map(u=>`- ${u.name}${u.size?` (${(u.size/1024).toFixed(1)}KB)`:""}`).join(`
@@ -692,14 +692,14 @@ ${a.map(u=>`- ${u.name}${u.size?` (${(u.size/1024).toFixed(1)}KB)`:""}`).join(`
692
692
 
693
693
  ${c.join(`
694
694
 
695
- `)}`}]}})),t.tool("prjct_obsidian_export","Export all prjct data (board, queue, shipped, roadmap, daily) to Obsidian vault.",{projectPath:A.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(`
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
696
  Errors:
697
697
  ${o.errors.map(c=>`- ${c}`).join(`
698
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:A.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`,`
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
700
  **By folder:**`,...o].join(`
701
- `)}]}})),t.tool("prjct_obsidian_status","Check Obsidian integration status for this project.",{projectPath:A.string().describe("Project directory path")},y("prjct_obsidian_status",async e=>{let r=await b(e.projectPath),s=(await Dt.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:A.string().describe("Project directory path"),folder:A.string().describe('Target folder (e.g., "linear", "board", "research")'),notes:A.array(A.object({filename:A.string().describe('Note filename (e.g., "ENG-123.md")'),title:A.string().describe("Note title (H1)"),content:A.string().describe("Markdown body"),frontmatter:A.record(A.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}
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
703
 
704
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
705
  Errors:
@@ -707,7 +707,7 @@ ${o.map(c=>`- ${c}`).join(`
707
707
  `)}`),{content:[{type:"text",text:a.join(`
708
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
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=D.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 J(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(`
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
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
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
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(`
@@ -737,15 +737,15 @@ No significant estimation patterns detected.`),{content:[{type:"text",text:a.joi
737
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
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
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 Di=new et;function Ai(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(Ai,"getStagedFiles");function Ci(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(Ci,"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=Ai(e.projectPath),o=s.length>0,a=o?"staged":"changed";if(s.length===0&&(s=Ci(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)
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
744
  `);let c=vt.join(e.projectPath,e.rulesFile),u=ts(c);u&&(n.push(`### Rules (${e.rulesFile})
745
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
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
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 Di.searchMemories(r,`bug ${d}`,5);if(g.length>0){n.push(`### Related Bug Memories
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
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
750
  `),n.push("```diff"),n.push(h.length>2e4?`${h.slice(0,2e4)}
751
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)
@@ -819,4 +819,4 @@ No active workflow rules.`);return{content:[{type:"text",text:o.join(`
819
819
  ### On session end:
820
820
  1. Call prjct_session_summary with Goal/Accomplished/Discoveries/Next Steps/Files
821
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),Dr(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)});
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)});