prjct-cli 1.52.3 → 1.54.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,10 +5,14 @@ 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 St=Object.defineProperty;var jr=Object.getOwnPropertyDescriptor;var Dr=Object.getOwnPropertyNames;var Ar=Object.prototype.hasOwnProperty;var u=(o,e)=>St(o,"name",{value:e,configurable:!0}),Ge=(o=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(o,{get:(e,t)=>(typeof require<"u"?require:e)[t]}):o)(function(o){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+o+'" is not supported')});var F=(o,e)=>()=>(o&&(e=o(o=0)),e);var Ve=(o,e)=>{for(var t in e)St(o,t,{get:e[t],enumerable:!0})},Nr=(o,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of Dr(e))!Ar.call(o,n)&&n!==t&&St(o,n,{get:()=>e[n],enumerable:!(r=jr(e,n))||r.enumerable});return o};var zt=o=>Nr(St({},"__esModule",{value:!0}),o);var ze,qe,Ye,qt=F(()=>{"use strict";ze=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"]),qe=["",".ts",".tsx",".js",".jsx","/index.ts","/index.js"],Ye=/(?:import|from)\s+['"]([^'"]+)['"]/g});import{formatDistanceToNowStrict as Xo}from"date-fns";function Ke(o){return{year:o.getFullYear().toString(),month:(o.getMonth()+1).toString().padStart(2,"0"),day:o.getDate().toString().padStart(2,"0")}}function f(){return new Date().toISOString()}function Je(o){let e=new Date;return e.setDate(e.getDate()-o),e}function Qe(o){let e=o.match(/^([+-])(\d+)([mh])$/);if(!e)return 0;let t=e[1]==="-"?-1:1,r=Number.parseInt(e[2],10),n=e[3];return t*(n==="h"?r*60:r)}function st(o){let e=0,t=o.match(/(\d+)h/);t&&(e+=Number.parseInt(t[1],10)*60);let r=o.match(/(\d+)m/);return r&&(e+=Number.parseInt(r[1],10)),o.match(/(\d+)s/)&&e===0&&(e=1),e}var N=F(()=>{"use strict";u(Ke,"getYearMonthDay");u(f,"getTimestamp");u(Je,"getDaysAgo");u(Qe,"parseVarianceMinutes");u(st,"parseDurationMinutes")});function Ir(o){return o instanceof Error&&"code"in o}function M(o){return Ir(o)&&o.code==="ENOENT"}function Ze(o){return o instanceof Error?o.message:typeof o=="string"?o:"Unknown error"}var ot=F(()=>{"use strict";u(Ir,"isNodeError");u(M,"isNotFoundError");u(Ze,"getErrorMessage")});import nn from"node:fs/promises";async function rn(o,e){let t;try{t=await nn.readFile(o,"utf-8")}catch(s){if(M(s))return null;throw s}let r;try{r=JSON.parse(t)}catch{return await tn(o,t),en(o,"Malformed JSON"),null}let n=e.safeParse(r);return n.success?r:(await tn(o,t),en(o,Or(n.error)),null)}async function tn(o,e){let t=`${o}.backup`;try{await nn.writeFile(t,e,"utf-8")}catch{}}function en(o,e){console.error(`[prjct] Warning: Corrupted storage file: ${o}`),console.error(`[prjct] Reason: ${e}`),console.error("[prjct] A .backup file has been created. Returning defaults.")}function Or(o){return o.issues.slice(0,3).map(e=>`${e.path.join(".")}: ${e.message}`).join("; ")}var sn=F(()=>{"use strict";ot();u(rn,"safeRead");u(tn,"createBackup");u(en,"logCorruption");u(Or,"formatZodError")});import B from"node:fs/promises";import _t from"node:path";async function on(o,e={}){let t=[],r=e.maxFiles??1/0,n=e.dotfileAllowlist?new Set(e.dotfileAllowlist):null;async function s(i){if(t.length>=r)return;let a=await B.readdir(i,{withFileTypes:!0}).catch(()=>[]);for(let c of a){if(t.length>=r)break;let l=String(c.name);if(ze.has(l)||e.skipDotfiles&&l.startsWith(".")&&(!n||!n.has(l)))continue;let p=_t.join(i,l);c.isDirectory()?await s(p):c.isFile()&&t.push(_t.relative(o,p))}}return u(s,"walk"),await s(o),t}async function an(o,e,t){let r=[];for(let n=0;n<o.length;n+=e){let s=await Promise.all(o.slice(n,n+e).map(t));for(let i of s)i!==null&&r.push(i)}return r}async function xt(o,e=null,t){if(t)return await rn(o,t)??e;try{let r=await B.readFile(o,"utf-8");return JSON.parse(r)}catch(r){if(M(r))return e;throw r}}async function K(o,e,t=2){let r=_t.dirname(o);await B.mkdir(r,{recursive:!0});let n=JSON.stringify(e,null,t);await B.writeFile(o,n,"utf-8")}async function Yt(o,e=""){try{return await B.readFile(o,"utf-8")}catch(t){if(M(t))return e;throw t}}async function cn(o,e){let t=_t.dirname(o);await B.mkdir(t,{recursive:!0}),await B.appendFile(o,`${e}
9
- `,"utf-8")}async function D(o){try{return await B.access(o),!0}catch(e){if(M(e))return!1;throw e}}async function Kt(o){try{return(await B.stat(o)).isDirectory()}catch(e){if(M(e))return!1;throw e}}async function G(o){await B.mkdir(o,{recursive:!0})}var tt=F(()=>{"use strict";qt();sn();ot();u(on,"walkDir");u(an,"batchProcess");u(xt,"readJson");u(K,"writeJson");u(Yt,"readFile");u(cn,"appendLine");u(D,"fileExists");u(Kt,"dirExists");u(G,"ensureDir")});var un=F(()=>{"use strict"});import{z as V}from"zod";function ln(o,e){let t=o.split(".").map(Number),r=e.split(".").map(Number);for(let n=0;n<3;n++){let s=t[n]??0,i=r[n]??0;if(s<i)return-1;if(s>i)return 1}return 0}var ri,si,oi,vt,ii,Qt=F(()=>{"use strict";ri=V.enum(["opus","sonnet","haiku"]),si=V.enum(["2.5-pro","2.5-flash","2.0-flash"]),oi=V.string().min(1),vt=V.object({provider:V.string(),model:V.string(),cliVersion:V.string().optional(),recordedAt:V.string()}),ii=V.object({preferredModel:V.string().optional(),lastAnalysisModel:vt.optional()});u(ln,"compareSemver")});import{exec as Lr,execFile as $r}from"node:child_process";import{promisify as pn}from"node:util";var W,pi,at=F(()=>{"use strict";W=pn(Lr),pi=pn($r)});function dn(o,e){let t=typeof o=="string"?new Date(o).getTime():o;return Date.now()-t>e}var Pt,Zt=F(()=>{"use strict";u(dn,"isExpired");Pt=class{static{u(this,"TTLCache")}cache=new Map;ttl;maxSize;constructor(e={}){this.ttl=e.ttl??5e3,this.maxSize=e.maxSize??50}isValid(e){let t=this.cache.get(e);return t?Date.now()-t.timestamp<this.ttl:!1}get(e){let t=this.cache.get(e);return t?this.isValid(e)?t.data:(this.cache.delete(e),null):null}set(e,t){this.cache.set(e,{data:t,timestamp:Date.now()}),this.evictOldEntries()}delete(e){this.cache.delete(e)}clear(){this.cache.clear()}has(e){return this.cache.has(e)}get size(){return this.cache.size}evictOldEntries(){if(this.cache.size<=this.maxSize)return;let t=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 t)this.cache.delete(r)}stats(){return{size:this.cache.size,maxSize:this.maxSize,ttl:this.ttl}}prune(){let e=0;for(let t of this.cache.keys())this.isValid(t)||(this.cache.delete(t),e++);return e}}});import Fr from"node:fs/promises";import Ur from"node:os";import mn from"node:path";async function fn(){try{let o=await Fr.readFile(gn,"utf-8"),e=JSON.parse(o);return!e.timestamp||!e.detection||!e.detection.claude||!e.detection.gemini||!e.detection.codex||dn(e.timestamp,Wr)?null:e.detection}catch{return null}}async function hn(o){let e={timestamp:new Date().toISOString(),detection:o};await K(gn,e)}var Xr,gn,Wr,yn=F(()=>{"use strict";Zt();tt();Xr=mn.join(Ur.homedir(),".prjct-cli","cache"),gn=mn.join(Xr,"providers.json"),Wr=600*1e3;u(fn,"readProviderCache");u(hn,"writeProviderCache")});var Ct={};Ve(Ct,{AntigravityProvider:()=>ne,ClaudeProvider:()=>Rt,CodexProvider:()=>re,CursorProvider:()=>En,GeminiProvider:()=>ee,Providers:()=>H,WindsurfProvider:()=>wn,detectAllProviders:()=>se,detectAntigravity:()=>Jr,detectCodex:()=>xn,detectCursorProject:()=>Sn,detectProvider:()=>te,detectWindsurfProject:()=>_n,getActiveProvider:()=>Vr,getCapabilities:()=>Br,getCommandsDir:()=>es,getGlobalContextPath:()=>Qr,getGlobalSettingsPath:()=>Zr,getProjectCommandsPath:()=>ns,getProviderBranding:()=>qr,getSkillsPath:()=>ts,hasProviderConfig:()=>zr,needsCursorRouterRegeneration:()=>Yr,needsWindsurfRouterRegeneration:()=>Kr,selectProvider:()=>rs,validateCliVersion:()=>kn});import et from"node:os";import C from"node:path";function Br(o,e){return{...Hr[o],...e}}async function bn(o){try{let{stdout:e}=await W(`which ${o}`,{timeout:2e3});return e.trim()}catch{return null}}async function Gr(o){try{let{stdout:e}=await W(`${o} --version`,{timeout:2e3}),t=e.match(/\d+\.\d+\.\d+/);return t?t[0]:e.trim()}catch{return null}}async function te(o){let e=H[o];if(!e.cliCommand)return{installed:!1};let t=await bn(e.cliCommand);if(!t)return{installed:!1};let r=await Gr(e.cliCommand),n=kn(o,r||void 0);return{installed:!0,version:r||void 0,path:t,versionWarning:n||void 0}}function kn(o,e){let t=H[o];return!t.minCliVersion||!e?null:ln(e,t.minCliVersion)<0?`\u26A0\uFE0F ${t.displayName} v${e} is below minimum v${t.minCliVersion}. Some features may not work correctly.`:null}async function se(o=!1){if(!o){let i=await fn();if(i)return i}let[e,t,r]=await Promise.all([te("claude"),te("gemini"),xn()]),n={installed:r.installed},s={claude:e,gemini:t,codex:n};return await hn(s).catch(()=>{}),s}async function Vr(o){if(o&&H[o])return H[o];let e=await se();return e.claude.installed&&!e.gemini.installed?Rt:e.gemini.installed&&!e.claude.installed?ee:Rt}async function zr(o){let e=H[o];return e.configDir?D(e.configDir):!1}function qr(o){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"}[o]||"\u26A1 prjct"}}async function Sn(o){let e=C.join(o,".cursor"),t=C.join(e,"rules"),r=C.join(t,"prjct.mdc"),[n,s]=await Promise.all([D(e),D(r)]);return{detected:n,routerInstalled:s,projectRoot:n?o:void 0}}async function Yr(o){let e=await Sn(o);return e.detected&&!e.routerInstalled}async function _n(o){let e=C.join(o,".windsurf"),t=C.join(e,"rules"),r=C.join(t,"prjct.md"),[n,s]=await Promise.all([D(e),D(r)]);return{detected:n,routerInstalled:s,projectRoot:n?o:void 0}}async function Kr(o){let e=await _n(o);return e.detected&&!e.routerInstalled}async function Jr(){let o=ne.configDir;if(!o)return{installed:!1,skillInstalled:!1};let e=C.join(o,"skills","prjct","SKILL.md"),[t,r]=await Promise.all([D(o),D(e)]);return{installed:t,skillInstalled:r,configPath:t?o:void 0}}async function xn(){let o=re.configDir;if(!o)return{installed:!1,skillInstalled:!1};let e=await bn("codex"),t=C.join(o,"skills","prjct","SKILL.md"),r=await D(t),n=!!e;return{installed:n,skillInstalled:r,configPath:n?o:void 0}}function Qr(o){let e=H[o];return e.configDir?C.join(e.configDir,e.contextFile):null}function Zr(o){let e=H[o];return!e.configDir||!e.settingsFile?null:C.join(e.configDir,e.settingsFile)}function ts(o){return H[o].skillsDir}function es(o){return H[o].commandsDir}function ns(o,e){let t=H[o];return C.join(e,t.commandsDir)}async function rs(){let o=await se(),e=o.claude.installed,t=o.gemini.installed;return!e&&!t?{provider:"claude",userSelected:!1,detection:o}:e&&!t?{provider:"claude",userSelected:!1,detection:o}:t&&!e?{provider:"gemini",userSelected:!1,detection:o}:{provider:"claude",userSelected:!0,detection:o}}var Hr,Rt,ee,ne,En,wn,re,H,jt=F(()=>{"use strict";un();Qt();at();tt();yn();Hr={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}};u(Br,"getCapabilities");Rt={name:"claude",displayName:"Claude Code",cliCommand:"claude",configDir:C.join(et.homedir(),".claude"),contextFile:"CLAUDE.md",skillsDir:C.join(et.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"},ee={name:"gemini",displayName:"Gemini CLI",cliCommand:"gemini",configDir:C.join(et.homedir(),".gemini"),contextFile:"GEMINI.md",skillsDir:C.join(et.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"},ne={name:"antigravity",displayName:"Google Antigravity",cliCommand:null,configDir:C.join(et.homedir(),".gemini","antigravity"),contextFile:"ANTIGRAVITY.md",skillsDir:C.join(et.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"},En={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"},re={name:"codex",displayName:"OpenAI Codex",cliCommand:"codex",configDir:C.join(et.homedir(),".codex"),contextFile:"AGENTS.md",skillsDir:C.join(et.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"},H={claude:Rt,gemini:ee,cursor:En,antigravity:ne,windsurf:wn,codex:re};u(bn,"whichCommand");u(Gr,"getCliVersion");u(te,"detectProvider");u(kn,"validateCliVersion");u(se,"detectAllProviders");u(Vr,"getActiveProvider");u(zr,"hasProviderConfig");u(qr,"getProviderBranding");u(Sn,"detectCursorProject");u(Yr,"needsCursorRouterRegeneration");u(_n,"detectWindsurfProject");u(Kr,"needsWindsurfRouterRegeneration");u(Jr,"detectAntigravity");u(xn,"detectCodex");u(Qr,"getGlobalContextPath");u(Zr,"getGlobalSettingsPath");u(ts,"getSkillsPath");u(es,"getCommandsDir");u(ns,"getProjectCommandsPath");u(rs,"selectProvider")});var Mn,ue=F(()=>{"use strict";Mn={sunday:0,monday:1,tuesday:2,wednesday:3,thursday:4,friday:5,saturday:6}});import{z as x}from"zod";var fo,ho,mr,cl,ul,ll,rt,Ne=F(()=>{"use strict";fo=x.enum(["improving","stable","declining"]),ho=x.object({sprintNumber:x.number(),startDate:x.string(),endDate:x.string(),pointsCompleted:x.number(),tasksCompleted:x.number(),avgVariance:x.number(),estimationAccuracy:x.number()}),mr=x.object({category:x.string(),avgVariance:x.number(),taskCount:x.number()}),cl=x.object({totalPoints:x.number(),sprints:x.number(),estimatedDate:x.string()}),ul=x.object({sprints:x.array(ho),averageVelocity:x.number(),velocityTrend:fo,estimationAccuracy:x.number(),overEstimated:x.array(mr),underEstimated:x.array(mr),lastUpdated:x.string()}),ll=x.object({sprintLengthDays:x.number().min(1).max(90).default(7),startDay:x.enum(["monday","tuesday","wednesday","thursday","friday","saturday","sunday"]).default("monday"),windowSize:x.number().min(1).max(52).default(6),accuracyTolerance:x.number().min(0).max(100).default(20)}),rt={sprintLengthDays:7,startDay:"monday",windowSize:6,accuracyTolerance:20}});var yr={};Ve(yr,{calculateVelocity:()=>wt,detectTrend:()=>hr,formatVelocityContext:()=>Ie,getSprintEnd:()=>fr,getSprintStart:()=>Ht,parseDurationMinutes:()=>st,projectCompletion:()=>To});function Ht(o,e){let t=bt(e),r=Mn[t.startDay],n=new Date(o);n.setHours(0,0,0,0);let i=(n.getDay()-r+7)%7;return n.setDate(n.getDate()-i),n}function fr(o,e){let t=bt(e),r=new Date(o);return r.setDate(r.getDate()+t.sprintLengthDays-1),r.setHours(23,59,59,999),r}function yo(o,e,t){let r=bt(t),n=Ht(o,t),s=Ht(e,t),i=n.getTime()-s.getTime(),a=Math.round(i/(1e3*60*60*24));return Math.floor(a/r.sprintLengthDays)+1}function wt(o,e=rt){let t=bt(e);if(o.length===0)return{sprints:[],averageVelocity:0,velocityTrend:"stable",estimationAccuracy:0,overEstimated:[],underEstimated:[],lastUpdated:new Date().toISOString()};let r=Eo(o,e),n=wo(r,t.accuracyTolerance),s=n.slice(-t.windowSize),i=ko(s),a=hr(s),c=bo(o,t.accuracyTolerance),{overEstimated:l,underEstimated:p}=So(o);return{sprints:n,averageVelocity:i,velocityTrend:a,estimationAccuracy:c,overEstimated:l,underEstimated:p,lastUpdated:new Date().toISOString()}}function To(o,e,t=rt){let r=bt(t);if(e<=0)return{totalPoints:o,sprints:0,estimatedDate:""};let n=Math.ceil(o/e),s=n*r.sprintLengthDays,i=new Date;return i.setDate(i.getDate()+s),{totalPoints:o,sprints:n,estimatedDate:i.toISOString()}}function Eo(o,e){let t=new Map,r=o.map(s=>new Date(s.completedAt)),n=new Date(Math.min(...r.map(s=>s.getTime())));for(let s of o){let i=new Date(s.completedAt),a=yo(i,n,e);if(!t.has(a)){let c=Ht(i,e),l=fr(c,e);t.set(a,{sprintNumber:a,startDate:c,endDate:l,outcomes:[]})}t.get(a).outcomes.push(s)}return t}function wo(o,e){let t=[];for(let[,r]of o){let n=r.outcomes.reduce((l,p)=>l+_o(p),0),s=r.outcomes.filter(l=>l.variance).map(l=>Me(l)),i=s.length>0?Math.round(s.reduce((l,p)=>l+p,0)/s.length):0,a=s.filter(l=>Math.abs(l)<=e).length,c=s.length>0?Math.round(a/s.length*100):0;t.push({sprintNumber:r.sprintNumber,startDate:r.startDate.toISOString(),endDate:r.endDate.toISOString(),pointsCompleted:n,tasksCompleted:r.outcomes.length,avgVariance:i,estimationAccuracy:c})}return t.sort((r,n)=>r.sprintNumber-n.sprintNumber)}function hr(o){if(o.length<3)return"stable";let e=o.map(p=>p.pointsCompleted),t=e.length,r=0,n=0,s=0,i=0;for(let p=0;p<t;p++)r+=p,n+=e[p],s+=p*e[p],i+=p*p;let a=(t*s-r*n)/(t*i-r*r),c=n/t;if(c===0)return"stable";let l=a/c;return l>.1?"improving":l<-.1?"declining":"stable"}function bo(o,e){let t=o.filter(n=>n.variance);if(t.length===0)return 0;let r=t.filter(n=>{let s=Me(n);return Math.abs(s)<=e});return Math.round(r.length/t.length*100)}function ko(o){if(o.length===0)return 0;let e=o.reduce((t,r)=>t+r.pointsCompleted,0);return Math.round(e/o.length*10)/10}function So(o){let e=new Map;for(let n of o){if(!n.variance)continue;let s=Me(n),i=n.tags&&n.tags.length>0?n.tags:["uncategorized"];for(let a of i){e.has(a)||e.set(a,{variances:[],count:0});let c=e.get(a);c.variances.push(s),c.count++}}let t=[],r=[];for(let[n,s]of e){if(s.count<2)continue;let i=Math.round(s.variances.reduce((a,c)=>a+c,0)/s.variances.length);i>10?r.push({category:n,avgVariance:i,taskCount:s.count}):i<-10&&t.push({category:n,avgVariance:Math.abs(i),taskCount:s.count})}return t.sort((n,s)=>s.avgVariance-n.avgVariance),r.sort((n,s)=>s.avgVariance-n.avgVariance),{overEstimated:t,underEstimated:r}}function Me(o){if(!o.variance)return 0;let e=st(o.estimatedDuration),t=st(o.actualDuration);return e<=0?0:Math.round((t-e)/e*100)}function Ie(o){if(o.sprints.length===0)return"No velocity data available yet.";let e=[];e.push(`Project velocity: ${o.averageVelocity} pts/sprint (trend: ${o.velocityTrend})`),e.push(`Estimation accuracy: ${o.estimationAccuracy}%`);for(let t of o.underEstimated)e.push(`\u26A0 "${t.category}" tasks historically take ${t.avgVariance}% longer than estimated`);for(let t of o.overEstimated)e.push(`"${t.category}" tasks typically finish ${t.avgVariance}% faster than estimated`);return e.join(`
10
- `)}function _o(o){if(!o.estimatedDuration)return 0;let e=st(o.estimatedDuration);if(e<=0)return 0;let t=gr[0],r=Number.POSITIVE_INFINITY;for(let n of gr){let s=Math.abs(n.typical-e);s<r&&(r=s,t=n)}return t.points}function bt(o){return{sprintLengthDays:o.sprintLengthDays??7,startDay:o.startDay??"monday",windowSize:o.windowSize??6,accuracyTolerance:o.accuracyTolerance??20}}var gr,Oe=F(()=>{"use strict";ue();Ne();N();u(Ht,"getSprintStart");u(fr,"getSprintEnd");u(yo,"getSprintNumber");u(wt,"calculateVelocity");u(To,"projectCompletion");u(Eo,"bucketBySprint");u(wo,"buildSprintVelocities");u(hr,"detectTrend");u(bo,"calculateOverallAccuracy");u(ko,"calculateAverageVelocity");u(So,"detectEstimationPatterns");u(Me,"parseVariancePercent");u(Ie,"formatVelocityContext");gr=[{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}];u(_o,"derivePoints");u(bt,"resolveConfig")});import{StdioServerTransport as Oo}from"@modelcontextprotocol/sdk/server/stdio.js";import{McpServer as Mo}from"@modelcontextprotocol/sdk/server/mcp.js";import{z as I}from"zod";qt();import Rn from"node:fs/promises";import ct from"node:path";import ae from"node:fs";import Pn from"node:path";N();tt();import ss from"node:crypto";import z from"node:fs/promises";import oe from"node:os";import b from"node:path";import{globSync as os}from"glob";var ie=class{static{u(this,"PathManager")}globalBaseDir;globalProjectsDir;globalConfigDir;constructor(){let e=process.env.PRJCT_CLI_HOME?.trim();this.globalBaseDir=e?b.resolve(e):b.join(oe.homedir(),".prjct-cli"),this.globalProjectsDir=b.join(this.globalBaseDir,"projects"),this.globalConfigDir=b.join(this.globalBaseDir,"config")}setGlobalBaseDir(e){this.globalBaseDir=b.resolve(e),this.globalProjectsDir=b.join(this.globalBaseDir,"projects"),this.globalConfigDir=b.join(this.globalBaseDir,"config")}generateProjectId(e){return ss.randomUUID()}getGlobalBasePath(){return this.globalBaseDir}getGlobalProjectPath(e){return b.join(this.globalProjectsDir,e)}getLocalConfigPath(e){return b.join(e,".prjct","prjct.config.json")}getGlobalProjectConfigPath(e){return b.join(this.getGlobalProjectPath(e),"project.json")}getLegacyPrjctPath(e){return b.join(e,".prjct")}async hasLegacyStructure(e){let t=this.getLegacyPrjctPath(e);return await Kt(t)}async hasConfig(e){let t=this.getLocalConfigPath(e);return await D(t)}async ensureGlobalStructure(){await G(this.globalBaseDir),await G(this.globalProjectsDir),await G(this.globalConfigDir)}async ensureProjectStructure(e){await this.ensureGlobalStructure();let t=this.getGlobalProjectPath(e),r=["core","progress","planning","analysis","memory"];for(let n of r)await G(b.join(t,n));return await G(b.join(t,"planning","tasks")),await G(b.join(t,"sessions")),t}getSessionPath(e,t=new Date){let{year:r,month:n,day:s}=Ke(t);return b.join(this.getGlobalProjectPath(e),"sessions",r,n,s)}getCurrentSessionPath(e){return this.getSessionPath(e,new Date)}async ensureSessionPath(e,t=new Date){let r=this.getSessionPath(e,t);return await G(r),r}async listSessions(e,t=null,r=null){let n=b.join(this.getGlobalProjectPath(e),"sessions"),s=[];try{let i=await z.readdir(n,{withFileTypes:!0});for(let a of i){if(!a.isDirectory()||t&&a.name!==t.toString())continue;let c=b.join(n,a.name),l=await z.readdir(c,{withFileTypes:!0});for(let p of l){if(!p.isDirectory()||r&&p.name!==r.toString().padStart(2,"0"))continue;let m=b.join(c,p.name),g=await z.readdir(m,{withFileTypes:!0});for(let h of g)h.isDirectory()&&s.push({year:a.name,month:p.name,day:h.name,path:b.join(m,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(e,t,r=new Date){return(await this.listSessions(e)).filter(s=>s.date>=t&&s.date<=r)}getFilePath(e,t,r){return b.join(this.getGlobalProjectPath(e),t,r)}async listProjects(){try{return await this.ensureGlobalStructure(),(await z.readdir(this.globalProjectsDir,{withFileTypes:!0})).filter(t=>t.isDirectory()).map(t=>t.name)}catch{return[]}}async projectExists(e){let t=this.getGlobalProjectPath(e);return await Kt(t)}getDisplayPath(e){let t=oe.homedir();return e.startsWith(t)?e.replace(t,"~"):e}getAuthConfigPath(){return b.join(this.globalConfigDir,"auth.json")}getSyncPendingPath(e){return b.join(this.getGlobalProjectPath(e),"sync","pending.json")}getLastSyncPath(e){return b.join(this.getGlobalProjectPath(e),"sync","last-sync.json")}getRunningStatusPath(){return b.join(this.globalBaseDir,".running")}getDocsPath(){return b.join(this.globalBaseDir,"docs")}async getAgentDir(){return(await(jt(),zt(Ct)).getActiveProvider()).configDir}async getAgentSettingsPath(){let e=await(jt(),zt(Ct)).getActiveProvider();return(jt(),zt(Ct)).getGlobalSettingsPath(e.name)}getClaudeDir(){return b.join(oe.homedir(),".claude")}getClaudeSettingsPath(){return b.join(this.getClaudeDir(),"settings.json")}getStoragePath(e,t){return b.join(this.getGlobalProjectPath(e),"storage",t)}getContextPath(e){return b.join(this.getGlobalProjectPath(e),"context")}async detectMonorepo(e){let t={isMonorepo:!1,type:null,rootPath:e,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=b.join(e,n.file);if(await D(s)){t.isMonorepo=!0,t.type=n.type;break}}if(!t.isMonorepo){let n=b.join(e,"package.json");if(await D(n))try{let s=await z.readFile(n,"utf-8");JSON.parse(s).workspaces&&(t.isMonorepo=!0,t.type="npm")}catch{}}return t.isMonorepo&&(t.packages=await this.discoverMonorepoPackages(e,t.type)),t}async discoverMonorepoPackages(e,t){let r=[],n=[];try{if(t==="pnpm"){let i=(await z.readFile(b.join(e,"pnpm-workspace.yaml"),"utf-8")).match(/packages:\s*\n((?:\s*-\s*.+\n?)+)/);i&&(n=i[1].split(`
11
- `).map(a=>a.replace(/^\s*-\s*['"]?|['"]?\s*$/g,"")).filter(Boolean))}else if(t==="npm"||t==="lerna"){let s=b.join(e,"package.json"),i=await z.readFile(s,"utf-8"),a=JSON.parse(i);if(Array.isArray(a.workspaces)?n=a.workspaces:a.workspaces?.packages&&(n=a.workspaces.packages),t==="lerna"){let c=b.join(e,"lerna.json");if(await D(c)){let l=await z.readFile(c,"utf-8"),p=JSON.parse(l);p.packages&&(n=p.packages)}}}else if(t==="nx")n=["apps/*","libs/*","packages/*"];else if(t==="turborepo"){let s=b.join(e,"package.json"),i=await z.readFile(s,"utf-8"),a=JSON.parse(i);Array.isArray(a.workspaces)&&(n=a.workspaces)}n.length===0&&(n=["packages/*","apps/*","libs/*"]);for(let s of n){if(s.startsWith("!"))continue;let i=os(s,{cwd:e,absolute:!1});for(let a of i){let c=b.join(e,a),l=b.join(c,"package.json");if(await D(l))try{let p=await z.readFile(l,"utf-8"),m=JSON.parse(p),g=b.join(c,"PRJCT.md");r.push({name:m.name||b.basename(a),path:c,relativePath:a,hasPrjctMd:await D(g)})}catch{}}}}catch{}return r}async findContainingPackage(e,t){if(!t.isMonorepo)return null;let r=b.resolve(e);for(let n of t.packages){let s=b.resolve(n.path);if(r.startsWith(s))return n}return null}async findMonorepoRoot(e){let t=b.resolve(e),r=b.parse(t).root;for(;t!==r;){if((await this.detectMonorepo(t)).isMonorepo)return t;t=b.dirname(t)}return null}},is=new ie,v=is;function as(){return typeof globalThis<"u"&&"Bun"in globalThis?"bun":"node"}u(as,"detectRuntime");function vn(){return as()==="bun"}u(vn,"isBun");function cs(o){if(vn()){let{Database:n}=Ge("bun:sqlite");return new n(o,{create:!0})}let e=Ge("better-sqlite3"),t=new e(o),r=t.exec.bind(t);return t.run=n=>r(n),t}u(cs,"openDatabase");var us=[{version:1,name:"initial-schema",up:u(o=>{o.run(`
8
+ var _t=Object.defineProperty;var Ln=Object.getOwnPropertyDescriptor;var $n=Object.getOwnPropertyNames;var Fn=Object.prototype.hasOwnProperty;var u=(o,t)=>_t(o,"name",{value:t,configurable:!0}),Ke=(o=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(o,{get:(t,e)=>(typeof require<"u"?require:t)[e]}):o)(function(o){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+o+'" is not supported')});var M=(o,t)=>()=>(o&&(t=o(o=0)),t);var qt=(o,t)=>{for(var e in t)_t(o,e,{get:t[e],enumerable:!0})},Un=(o,t,e,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of $n(t))!Fn.call(o,r)&&r!==e&&_t(o,r,{get:()=>t[r],enumerable:!(n=Ln(t,r))||n.enumerable});return o};var Yt=o=>Un(_t({},"__esModule",{value:!0}),o);var Je,Qe,Ze,Kt=M(()=>{"use strict";Je=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"]),Qe=["",".ts",".tsx",".js",".jsx","/index.ts","/index.js"],Ze=/(?:import|from)\s+['"]([^'"]+)['"]/g});import{formatDistanceToNowStrict as Ko}from"date-fns";function tr(o){return{year:o.getFullYear().toString(),month:(o.getMonth()+1).toString().padStart(2,"0"),day:o.getDate().toString().padStart(2,"0")}}function f(){return new Date().toISOString()}function er(o){let t=new Date;return t.setDate(t.getDate()-o),t}function rr(o){let t=o.match(/^([+-])(\d+)([mh])$/);if(!t)return 0;let e=t[1]==="-"?-1:1,n=Number.parseInt(t[2],10),r=t[3];return e*(r==="h"?n*60:n)}function ot(o){let t=0,e=o.match(/(\d+)h/);e&&(t+=Number.parseInt(e[1],10)*60);let n=o.match(/(\d+)m/);return n&&(t+=Number.parseInt(n[1],10)),o.match(/(\d+)s/)&&t===0&&(t=1),t}var I=M(()=>{"use strict";u(tr,"getYearMonthDay");u(f,"getTimestamp");u(er,"getDaysAgo");u(rr,"parseVarianceMinutes");u(ot,"parseDurationMinutes")});function Xn(o){return o instanceof Error&&"code"in o}function O(o){return Xn(o)&&o.code==="ENOENT"}function nr(o){return o instanceof Error?o.message:typeof o=="string"?o:"Unknown error"}var it=M(()=>{"use strict";u(Xn,"isNodeError");u(O,"isNotFoundError");u(nr,"getErrorMessage")});import ir from"node:fs/promises";async function ar(o,t){let e;try{e=await ir.readFile(o,"utf-8")}catch(s){if(O(s))return null;throw s}let n;try{n=JSON.parse(e)}catch{return await sr(o,e),or(o,"Malformed JSON"),null}let r=t.safeParse(n);return r.success?n:(await sr(o,e),or(o,Hn(r.error)),null)}async function sr(o,t){let e=`${o}.backup`;try{await ir.writeFile(e,t,"utf-8")}catch{}}function or(o,t){console.error(`[prjct] Warning: Corrupted storage file: ${o}`),console.error(`[prjct] Reason: ${t}`),console.error("[prjct] A .backup file has been created. Returning defaults.")}function Hn(o){return o.issues.slice(0,3).map(t=>`${t.path.join(".")}: ${t.message}`).join("; ")}var cr=M(()=>{"use strict";it();u(ar,"safeRead");u(sr,"createBackup");u(or,"logCorruption");u(Hn,"formatZodError")});import B from"node:fs/promises";import xt from"node:path";async function ur(o,t={}){let e=[],n=t.maxFiles??1/0,r=t.dotfileAllowlist?new Set(t.dotfileAllowlist):null;async function s(i){if(e.length>=n)return;let a=await B.readdir(i,{withFileTypes:!0}).catch(()=>[]);for(let c of a){if(e.length>=n)break;let l=String(c.name);if(Je.has(l)||t.skipDotfiles&&l.startsWith(".")&&(!r||!r.has(l)))continue;let p=xt.join(i,l);c.isDirectory()?await s(p):c.isFile()&&e.push(xt.relative(o,p))}}return u(s,"walk"),await s(o),e}async function lr(o,t,e){let n=[];for(let r=0;r<o.length;r+=t){let s=await Promise.all(o.slice(r,r+t).map(e));for(let i of s)i!==null&&n.push(i)}return n}async function vt(o,t=null,e){if(e)return await ar(o,e)??t;try{let n=await B.readFile(o,"utf-8");return JSON.parse(n)}catch(n){if(O(n))return t;throw n}}async function J(o,t,e=2){let n=xt.dirname(o);await B.mkdir(n,{recursive:!0});let r=JSON.stringify(t,null,e);await B.writeFile(o,r,"utf-8")}async function Jt(o,t=""){try{return await B.readFile(o,"utf-8")}catch(e){if(O(e))return t;throw e}}async function pr(o,t){let e=xt.dirname(o);await B.mkdir(e,{recursive:!0}),await B.appendFile(o,`${t}
9
+ `,"utf-8")}async function C(o){try{return await B.access(o),!0}catch(t){if(O(t))return!1;throw t}}async function Qt(o){try{return(await B.stat(o)).isDirectory()}catch(t){if(O(t))return!1;throw t}}async function G(o){await B.mkdir(o,{recursive:!0})}var Q=M(()=>{"use strict";Kt();cr();it();u(ur,"walkDir");u(lr,"batchProcess");u(vt,"readJson");u(J,"writeJson");u(Jt,"readFile");u(pr,"appendLine");u(C,"fileExists");u(Qt,"dirExists");u(G,"ensureDir")});var dr=M(()=>{"use strict"});import{z as V}from"zod";function mr(o,t){let e=o.split(".").map(Number),n=t.split(".").map(Number);for(let r=0;r<3;r++){let s=e[r]??0,i=n[r]??0;if(s<i)return-1;if(s>i)return 1}return 0}var di,mi,gi,Pt,fi,te=M(()=>{"use strict";di=V.enum(["opus","sonnet","haiku"]),mi=V.enum(["2.5-pro","2.5-flash","2.0-flash"]),gi=V.string().min(1),Pt=V.object({provider:V.string(),model:V.string(),cliVersion:V.string().optional(),recordedAt:V.string()}),fi=V.object({preferredModel:V.string().optional(),lastAnalysisModel:Pt.optional()});u(mr,"compareSemver")});import{exec as Bn,execFile as Gn}from"node:child_process";import{promisify as gr}from"node:util";var v,ki,at=M(()=>{"use strict";v=gr(Bn),ki=gr(Gn)});function fr(o,t){let e=typeof o=="string"?new Date(o).getTime():o;return Date.now()-e>t}var Rt,ee=M(()=>{"use strict";u(fr,"isExpired");Rt=class{static{u(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((n,r)=>n[1].timestamp-r[1].timestamp).slice(0,this.cache.size-this.maxSize);for(let[n]of e)this.cache.delete(n)}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 Vn from"node:fs/promises";import zn from"node:os";import hr from"node:path";async function Tr(){try{let o=await Vn.readFile(yr,"utf-8"),t=JSON.parse(o);return!t.timestamp||!t.detection||!t.detection.claude||!t.detection.gemini||!t.detection.codex||fr(t.timestamp,Yn)?null:t.detection}catch{return null}}async function Er(o){let t={timestamp:new Date().toISOString(),detection:o};await J(yr,t)}var qn,yr,Yn,kr=M(()=>{"use strict";ee();Q();qn=hr.join(zn.homedir(),".prjct-cli","cache"),yr=hr.join(qn,"providers.json"),Yn=600*1e3;u(Tr,"readProviderCache");u(Er,"writeProviderCache")});var At={};qt(At,{AntigravityProvider:()=>se,ClaudeProvider:()=>Ct,CodexProvider:()=>oe,CursorProvider:()=>br,GeminiProvider:()=>ne,Providers:()=>H,WindsurfProvider:()=>Sr,detectAllProviders:()=>ie,detectAntigravity:()=>ss,detectCodex:()=>Rr,detectCursorProject:()=>vr,detectProvider:()=>re,detectWindsurfProject:()=>Pr,getActiveProvider:()=>Zn,getCapabilities:()=>Jn,getCommandsDir:()=>cs,getGlobalContextPath:()=>os,getGlobalSettingsPath:()=>is,getProjectCommandsPath:()=>us,getProviderBranding:()=>es,getSkillsPath:()=>as,hasProviderConfig:()=>ts,needsCursorRouterRegeneration:()=>rs,needsWindsurfRouterRegeneration:()=>ns,selectProvider:()=>ls,validateCliVersion:()=>xr});import rt from"node:os";import D from"node:path";function Jn(o,t){return{...Kn[o],...t}}async function _r(o){try{let{stdout:t}=await v(`which ${o}`,{timeout:2e3});return t.trim()}catch{return null}}async function Qn(o){try{let{stdout:t}=await v(`${o} --version`,{timeout:2e3}),e=t.match(/\d+\.\d+\.\d+/);return e?e[0]:t.trim()}catch{return null}}async function re(o){let t=H[o];if(!t.cliCommand)return{installed:!1};let e=await _r(t.cliCommand);if(!e)return{installed:!1};let n=await Qn(t.cliCommand),r=xr(o,n||void 0);return{installed:!0,version:n||void 0,path:e,versionWarning:r||void 0}}function xr(o,t){let e=H[o];return!e.minCliVersion||!t?null:mr(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 ie(o=!1){if(!o){let i=await Tr();if(i)return i}let[t,e,n]=await Promise.all([re("claude"),re("gemini"),Rr()]),r={installed:n.installed},s={claude:t,gemini:e,codex:r};return await Er(s).catch(()=>{}),s}async function Zn(o){if(o&&H[o])return H[o];let t=await ie();return t.claude.installed&&!t.gemini.installed?Ct:t.gemini.installed&&!t.claude.installed?ne:Ct}async function ts(o){let t=H[o];return t.configDir?C(t.configDir):!1}function es(o){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"}[o]||"\u26A1 prjct"}}async function vr(o){let t=D.join(o,".cursor"),e=D.join(t,"rules"),n=D.join(e,"prjct.mdc"),[r,s]=await Promise.all([C(t),C(n)]);return{detected:r,routerInstalled:s,projectRoot:r?o:void 0}}async function rs(o){let t=await vr(o);return t.detected&&!t.routerInstalled}async function Pr(o){let t=D.join(o,".windsurf"),e=D.join(t,"rules"),n=D.join(e,"prjct.md"),[r,s]=await Promise.all([C(t),C(n)]);return{detected:r,routerInstalled:s,projectRoot:r?o:void 0}}async function ns(o){let t=await Pr(o);return t.detected&&!t.routerInstalled}async function ss(){let o=se.configDir;if(!o)return{installed:!1,skillInstalled:!1};let t=D.join(o,"skills","prjct","SKILL.md"),[e,n]=await Promise.all([C(o),C(t)]);return{installed:e,skillInstalled:n,configPath:e?o:void 0}}async function Rr(){let o=oe.configDir;if(!o)return{installed:!1,skillInstalled:!1};let t=await _r("codex"),e=D.join(o,"skills","prjct","SKILL.md"),n=await C(e),r=!!t;return{installed:r,skillInstalled:n,configPath:r?o:void 0}}function os(o){let t=H[o];return t.configDir?D.join(t.configDir,t.contextFile):null}function is(o){let t=H[o];return!t.configDir||!t.settingsFile?null:D.join(t.configDir,t.settingsFile)}function as(o){return H[o].skillsDir}function cs(o){return H[o].commandsDir}function us(o,t){let e=H[o];return D.join(t,e.commandsDir)}async function ls(){let o=await ie(),t=o.claude.installed,e=o.gemini.installed;return!t&&!e?{provider:"claude",userSelected:!1,detection:o}:t&&!e?{provider:"claude",userSelected:!1,detection:o}:e&&!t?{provider:"gemini",userSelected:!1,detection:o}:{provider:"claude",userSelected:!0,detection:o}}var Kn,Ct,ne,se,br,Sr,oe,H,Dt=M(()=>{"use strict";dr();te();at();Q();kr();Kn={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}};u(Jn,"getCapabilities");Ct={name:"claude",displayName:"Claude Code",cliCommand:"claude",configDir:D.join(rt.homedir(),".claude"),contextFile:"CLAUDE.md",skillsDir:D.join(rt.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"},ne={name:"gemini",displayName:"Gemini CLI",cliCommand:"gemini",configDir:D.join(rt.homedir(),".gemini"),contextFile:"GEMINI.md",skillsDir:D.join(rt.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"},se={name:"antigravity",displayName:"Google Antigravity",cliCommand:null,configDir:D.join(rt.homedir(),".gemini","antigravity"),contextFile:"ANTIGRAVITY.md",skillsDir:D.join(rt.homedir(),".gemini","antigravity","global_skills"),commandsDir:".agent/skills",commandFormat:"md",settingsFile:"mcp_config.json",projectSettingsFile:null,ignoreFile:".agentignore",websiteUrl:"https://gemini.google.com/app/antigravity",docsUrl:"https://gemini.google.com/app/antigravity",defaultModel:null,supportedModels:[],minCliVersion:null,capabilityTier:"basic"},br={name:"cursor",displayName:"Cursor IDE",cliCommand:null,configDir:null,contextFile:"prjct.mdc",skillsDir:null,commandsDir:".cursor/commands",rulesDir:".cursor/rules",commandFormat:"md",settingsFile:null,projectSettingsFile:null,ignoreFile:".cursorignore",isProjectLevel:!0,websiteUrl:"https://cursor.com",docsUrl:"https://cursor.com/docs",defaultModel:null,supportedModels:[],minCliVersion:null,capabilityTier:"basic"},Sr={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"},oe={name:"codex",displayName:"OpenAI Codex",cliCommand:"codex",configDir:D.join(rt.homedir(),".codex"),contextFile:"AGENTS.md",skillsDir:D.join(rt.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"},H={claude:Ct,gemini:ne,cursor:br,antigravity:se,windsurf:Sr,codex:oe};u(_r,"whichCommand");u(Qn,"getCliVersion");u(re,"detectProvider");u(xr,"validateCliVersion");u(ie,"detectAllProviders");u(Zn,"getActiveProvider");u(ts,"hasProviderConfig");u(es,"getProviderBranding");u(vr,"detectCursorProject");u(rs,"needsCursorRouterRegeneration");u(Pr,"detectWindsurfProject");u(ns,"needsWindsurfRouterRegeneration");u(ss,"detectAntigravity");u(Rr,"detectCodex");u(os,"getGlobalContextPath");u(is,"getGlobalSettingsPath");u(as,"getSkillsPath");u(cs,"getCommandsDir");u(us,"getProjectCommandsPath");u(ls,"selectProvider")});var Lr,pe=M(()=>{"use strict";Lr={sunday:0,monday:1,tuesday:2,wednesday:3,thursday:4,friday:5,saturday:6}});var Vr={};qt(Vr,{default:()=>Is,worktreeService:()=>Gr});import Te from"node:fs/promises";import q from"node:path";var Br,Ee,Gr,Is,zr=M(()=>{"use strict";at();Q();Br=".worktrees",Ee=class{static{u(this,"WorktreeService")}async create(t,e,n={}){let r=await this.getMainWorktree(t),s=q.join(r,Br,e),i=n.branch||`feat/${e}`;await Te.mkdir(q.join(r,Br),{recursive:!0});let a=n.baseBranch?` ${n.baseBranch}`:"";await v(`git worktree add "${s}" -b "${i}"${a}`,{cwd:r});let{stdout:c}=await v("git rev-parse HEAD",{cwd:s});return{path:s,branch:i,commit:c.trim(),isMain:!1,slug:e}}async remove(t,e=!1){let n=await this.getMainWorktree(t),r;if(e)try{let{stdout:s}=await v("git rev-parse --abbrev-ref HEAD",{cwd:t});r=s.trim()}catch{}if(await v(`git worktree remove "${t}" --force`,{cwd:n}),e&&r&&r!=="main"&&r!=="master")try{await v(`git branch -D "${r}"`,{cwd:n})}catch{}}async list(t){let e=await this.getMainWorktree(t),{stdout:n}=await v("git worktree list --porcelain",{cwd:e});return this.parsePorcelainOutput(n,e)}async detect(t){try{let{stdout:e}=await v("git rev-parse --git-common-dir",{cwd:t}),{stdout:n}=await v("git rev-parse --git-dir",{cwd:t}),r=q.resolve(t,e.trim()),s=q.resolve(t,n.trim());if(r!==s){let{stdout:i}=await v("git rev-parse --abbrev-ref HEAD",{cwd:t}),{stdout:a}=await v("git rev-parse HEAD",{cwd:t}),{stdout:c}=await v("git rev-parse --show-toplevel",{cwd:t}),l=c.trim(),p=q.basename(l);return{path:l,branch:i.trim(),commit:a.trim(),isMain:!1,slug:p}}return null}catch{return null}}async getMainWorktree(t){try{let{stdout:n}=await v("git worktree list --porcelain",{cwd:t}),r=n.split(`
10
+ `)[0];if(r?.startsWith("worktree "))return r.replace("worktree ","").trim()}catch{}let{stdout:e}=await v("git rev-parse --show-toplevel",{cwd:t});return e.trim()}async setup(t,e){let n=q.join(e,".env");await C(n)&&await Te.copyFile(n,q.join(t,".env"));let r=q.join(e,".prjct"),s=q.join(t,".prjct");await C(r)&&!await C(s)&&await Te.symlink(r,s,"dir")}async teardown(t){}async clean(t){let e=await this.list(t),n=[],r=await this.getMainWorktree(t);await v("git worktree prune",{cwd:r});for(let s of e)s.isMain||await C(s.path)||n.push(s.slug);return n}parsePorcelainOutput(t,e){let n=[],r=t.trim().split(`
11
+
12
+ `);for(let s of r){if(!s.trim())continue;let i=s.trim().split(`
13
+ `),a="",c="",l="",p=!1;for(let m of i)m.startsWith("worktree ")?a=m.replace("worktree ","").trim():m.startsWith("HEAD ")?c=m.replace("HEAD ","").trim():m.startsWith("branch ")?l=m.replace("branch refs/heads/","").trim():m==="bare"?p=!0:m==="detached"&&(l="(detached)");if(a){let m=a===e||p;n.push({path:a,branch:l,commit:c,isMain:m,slug:m?"main":q.basename(a)})}}return n}},Gr=new Ee,Is=Gr});import{z as x}from"zod";var _o,xo,kn,bl,Sl,_l,st,$e=M(()=>{"use strict";_o=x.enum(["improving","stable","declining"]),xo=x.object({sprintNumber:x.number(),startDate:x.string(),endDate:x.string(),pointsCompleted:x.number(),tasksCompleted:x.number(),avgVariance:x.number(),estimationAccuracy:x.number()}),kn=x.object({category:x.string(),avgVariance:x.number(),taskCount:x.number()}),bl=x.object({totalPoints:x.number(),sprints:x.number(),estimatedDate:x.string()}),Sl=x.object({sprints:x.array(xo),averageVelocity:x.number(),velocityTrend:_o,estimationAccuracy:x.number(),overEstimated:x.array(kn),underEstimated:x.array(kn),lastUpdated:x.string()}),_l=x.object({sprintLengthDays:x.number().min(1).max(90).default(7),startDay:x.enum(["monday","tuesday","wednesday","thursday","friday","saturday","sunday"]).default("monday"),windowSize:x.number().min(1).max(52).default(6),accuracyTolerance:x.number().min(0).max(100).default(20)}),st={sprintLengthDays:7,startDay:"monday",windowSize:6,accuracyTolerance:20}});var _n={};qt(_n,{calculateVelocity:()=>wt,detectTrend:()=>Sn,formatVelocityContext:()=>Ue,getSprintEnd:()=>bn,getSprintStart:()=>Bt,parseDurationMinutes:()=>ot,projectCompletion:()=>Po});function Bt(o,t){let e=bt(t),n=Lr[e.startDay],r=new Date(o);r.setHours(0,0,0,0);let i=(r.getDay()-n+7)%7;return r.setDate(r.getDate()-i),r}function bn(o,t){let e=bt(t),n=new Date(o);return n.setDate(n.getDate()+e.sprintLengthDays-1),n.setHours(23,59,59,999),n}function vo(o,t,e){let n=bt(e),r=Bt(o,e),s=Bt(t,e),i=r.getTime()-s.getTime(),a=Math.round(i/(1e3*60*60*24));return Math.floor(a/n.sprintLengthDays)+1}function wt(o,t=st){let e=bt(t);if(o.length===0)return{sprints:[],averageVelocity:0,velocityTrend:"stable",estimationAccuracy:0,overEstimated:[],underEstimated:[],lastUpdated:new Date().toISOString()};let n=Ro(o,t),r=Co(n,e.accuracyTolerance),s=r.slice(-e.windowSize),i=Do(s),a=Sn(s),c=Ao(o,e.accuracyTolerance),{overEstimated:l,underEstimated:p}=jo(o);return{sprints:r,averageVelocity:i,velocityTrend:a,estimationAccuracy:c,overEstimated:l,underEstimated:p,lastUpdated:new Date().toISOString()}}function Po(o,t,e=st){let n=bt(e);if(t<=0)return{totalPoints:o,sprints:0,estimatedDate:""};let r=Math.ceil(o/t),s=r*n.sprintLengthDays,i=new Date;return i.setDate(i.getDate()+s),{totalPoints:o,sprints:r,estimatedDate:i.toISOString()}}function Ro(o,t){let e=new Map,n=o.map(s=>new Date(s.completedAt)),r=new Date(Math.min(...n.map(s=>s.getTime())));for(let s of o){let i=new Date(s.completedAt),a=vo(i,r,t);if(!e.has(a)){let c=Bt(i,t),l=bn(c,t);e.set(a,{sprintNumber:a,startDate:c,endDate:l,outcomes:[]})}e.get(a).outcomes.push(s)}return e}function Co(o,t){let e=[];for(let[,n]of o){let r=n.outcomes.reduce((l,p)=>l+No(p),0),s=n.outcomes.filter(l=>l.variance).map(l=>Fe(l)),i=s.length>0?Math.round(s.reduce((l,p)=>l+p,0)/s.length):0,a=s.filter(l=>Math.abs(l)<=t).length,c=s.length>0?Math.round(a/s.length*100):0;e.push({sprintNumber:n.sprintNumber,startDate:n.startDate.toISOString(),endDate:n.endDate.toISOString(),pointsCompleted:r,tasksCompleted:n.outcomes.length,avgVariance:i,estimationAccuracy:c})}return e.sort((n,r)=>n.sprintNumber-r.sprintNumber)}function Sn(o){if(o.length<3)return"stable";let t=o.map(p=>p.pointsCompleted),e=t.length,n=0,r=0,s=0,i=0;for(let p=0;p<e;p++)n+=p,r+=t[p],s+=p*t[p],i+=p*p;let a=(e*s-n*r)/(e*i-n*n),c=r/e;if(c===0)return"stable";let l=a/c;return l>.1?"improving":l<-.1?"declining":"stable"}function Ao(o,t){let e=o.filter(r=>r.variance);if(e.length===0)return 0;let n=e.filter(r=>{let s=Fe(r);return Math.abs(s)<=t});return Math.round(n.length/e.length*100)}function Do(o){if(o.length===0)return 0;let t=o.reduce((e,n)=>e+n.pointsCompleted,0);return Math.round(t/o.length*10)/10}function jo(o){let t=new Map;for(let r of o){if(!r.variance)continue;let s=Fe(r),i=r.tags&&r.tags.length>0?r.tags:["uncategorized"];for(let a of i){t.has(a)||t.set(a,{variances:[],count:0});let c=t.get(a);c.variances.push(s),c.count++}}let e=[],n=[];for(let[r,s]of t){if(s.count<2)continue;let i=Math.round(s.variances.reduce((a,c)=>a+c,0)/s.variances.length);i>10?n.push({category:r,avgVariance:i,taskCount:s.count}):i<-10&&e.push({category:r,avgVariance:Math.abs(i),taskCount:s.count})}return e.sort((r,s)=>s.avgVariance-r.avgVariance),n.sort((r,s)=>s.avgVariance-r.avgVariance),{overEstimated:e,underEstimated:n}}function Fe(o){if(!o.variance)return 0;let t=ot(o.estimatedDuration),e=ot(o.actualDuration);return t<=0?0:Math.round((e-t)/t*100)}function Ue(o){if(o.sprints.length===0)return"No velocity data available yet.";let t=[];t.push(`Project velocity: ${o.averageVelocity} pts/sprint (trend: ${o.velocityTrend})`),t.push(`Estimation accuracy: ${o.estimationAccuracy}%`);for(let e of o.underEstimated)t.push(`\u26A0 "${e.category}" tasks historically take ${e.avgVariance}% longer than estimated`);for(let e of o.overEstimated)t.push(`"${e.category}" tasks typically finish ${e.avgVariance}% faster than estimated`);return t.join(`
14
+ `)}function No(o){if(!o.estimatedDuration)return 0;let t=ot(o.estimatedDuration);if(t<=0)return 0;let e=wn[0],n=Number.POSITIVE_INFINITY;for(let r of wn){let s=Math.abs(r.typical-t);s<n&&(n=s,e=r)}return e.points}function bt(o){return{sprintLengthDays:o.sprintLengthDays??7,startDay:o.startDay??"monday",windowSize:o.windowSize??6,accuracyTolerance:o.accuracyTolerance??20}}var wn,We=M(()=>{"use strict";pe();$e();I();u(Bt,"getSprintStart");u(bn,"getSprintEnd");u(vo,"getSprintNumber");u(wt,"calculateVelocity");u(Po,"projectCompletion");u(Ro,"bucketBySprint");u(Co,"buildSprintVelocities");u(Sn,"detectTrend");u(Ao,"calculateOverallAccuracy");u(Do,"calculateAverageVelocity");u(jo,"detectEstimationPatterns");u(Fe,"parseVariancePercent");u(Ue,"formatVelocityContext");wn=[{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}];u(No,"derivePoints");u(bt,"resolveConfig")});import{StdioServerTransport as Go}from"@modelcontextprotocol/sdk/server/stdio.js";import{McpServer as Ho}from"@modelcontextprotocol/sdk/server/mcp.js";import{z as L}from"zod";Kt();import Dr from"node:fs/promises";import ut from"node:path";import ue from"node:fs";import Ar from"node:path";I();Q();import ps from"node:crypto";import z from"node:fs/promises";import ae from"node:os";import w from"node:path";import{globSync as ds}from"glob";var ce=class{static{u(this,"PathManager")}globalBaseDir;globalProjectsDir;globalConfigDir;constructor(){let t=process.env.PRJCT_CLI_HOME?.trim();this.globalBaseDir=t?w.resolve(t):w.join(ae.homedir(),".prjct-cli"),this.globalProjectsDir=w.join(this.globalBaseDir,"projects"),this.globalConfigDir=w.join(this.globalBaseDir,"config")}setGlobalBaseDir(t){this.globalBaseDir=w.resolve(t),this.globalProjectsDir=w.join(this.globalBaseDir,"projects"),this.globalConfigDir=w.join(this.globalBaseDir,"config")}generateProjectId(t){return ps.randomUUID()}getGlobalBasePath(){return this.globalBaseDir}getGlobalProjectPath(t){return w.join(this.globalProjectsDir,t)}getLocalConfigPath(t){return w.join(t,".prjct","prjct.config.json")}getGlobalProjectConfigPath(t){return w.join(this.getGlobalProjectPath(t),"project.json")}getLegacyPrjctPath(t){return w.join(t,".prjct")}async hasLegacyStructure(t){let e=this.getLegacyPrjctPath(t);return await Qt(e)}async hasConfig(t){let e=this.getLocalConfigPath(t);return await C(e)}async ensureGlobalStructure(){await G(this.globalBaseDir),await G(this.globalProjectsDir),await G(this.globalConfigDir)}async ensureProjectStructure(t){await this.ensureGlobalStructure();let e=this.getGlobalProjectPath(t),n=["core","progress","planning","analysis","memory"];for(let r of n)await G(w.join(e,r));return await G(w.join(e,"planning","tasks")),await G(w.join(e,"sessions")),e}getSessionPath(t,e=new Date){let{year:n,month:r,day:s}=tr(e);return w.join(this.getGlobalProjectPath(t),"sessions",n,r,s)}getCurrentSessionPath(t){return this.getSessionPath(t,new Date)}async ensureSessionPath(t,e=new Date){let n=this.getSessionPath(t,e);return await G(n),n}async listSessions(t,e=null,n=null){let r=w.join(this.getGlobalProjectPath(t),"sessions"),s=[];try{let i=await z.readdir(r,{withFileTypes:!0});for(let a of i){if(!a.isDirectory()||e&&a.name!==e.toString())continue;let c=w.join(r,a.name),l=await z.readdir(c,{withFileTypes:!0});for(let p of l){if(!p.isDirectory()||n&&p.name!==n.toString().padStart(2,"0"))continue;let m=w.join(c,p.name),g=await z.readdir(m,{withFileTypes:!0});for(let h of g)h.isDirectory()&&s.push({year:a.name,month:p.name,day:h.name,path:w.join(m,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,n=new Date){return(await this.listSessions(t)).filter(s=>s.date>=e&&s.date<=n)}getFilePath(t,e,n){return w.join(this.getGlobalProjectPath(t),e,n)}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 Qt(e)}getDisplayPath(t){let e=ae.homedir();return t.startsWith(e)?t.replace(e,"~"):t}getAuthConfigPath(){return w.join(this.globalConfigDir,"auth.json")}getSyncPendingPath(t){return w.join(this.getGlobalProjectPath(t),"sync","pending.json")}getLastSyncPath(t){return w.join(this.getGlobalProjectPath(t),"sync","last-sync.json")}getRunningStatusPath(){return w.join(this.globalBaseDir,".running")}getDocsPath(){return w.join(this.globalBaseDir,"docs")}async getAgentDir(){return(await(Dt(),Yt(At)).getActiveProvider()).configDir}async getAgentSettingsPath(){let t=await(Dt(),Yt(At)).getActiveProvider();return(Dt(),Yt(At)).getGlobalSettingsPath(t.name)}getClaudeDir(){return w.join(ae.homedir(),".claude")}getClaudeSettingsPath(){return w.join(this.getClaudeDir(),"settings.json")}getStoragePath(t,e){return w.join(this.getGlobalProjectPath(t),"storage",e)}getContextPath(t){return w.join(this.getGlobalProjectPath(t),"context")}async detectMonorepo(t){let e={isMonorepo:!1,type:null,rootPath:t,packages:[]},n=[{file:"pnpm-workspace.yaml",type:"pnpm"},{file:"lerna.json",type:"lerna"},{file:"nx.json",type:"nx"},{file:"rush.json",type:"rush"},{file:"turbo.json",type:"turborepo"}];for(let r of n){let s=w.join(t,r.file);if(await C(s)){e.isMonorepo=!0,e.type=r.type;break}}if(!e.isMonorepo){let r=w.join(t,"package.json");if(await C(r))try{let s=await z.readFile(r,"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 n=[],r=[];try{if(e==="pnpm"){let i=(await z.readFile(w.join(t,"pnpm-workspace.yaml"),"utf-8")).match(/packages:\s*\n((?:\s*-\s*.+\n?)+)/);i&&(r=i[1].split(`
15
+ `).map(a=>a.replace(/^\s*-\s*['"]?|['"]?\s*$/g,"")).filter(Boolean))}else if(e==="npm"||e==="lerna"){let s=w.join(t,"package.json"),i=await z.readFile(s,"utf-8"),a=JSON.parse(i);if(Array.isArray(a.workspaces)?r=a.workspaces:a.workspaces?.packages&&(r=a.workspaces.packages),e==="lerna"){let c=w.join(t,"lerna.json");if(await C(c)){let l=await z.readFile(c,"utf-8"),p=JSON.parse(l);p.packages&&(r=p.packages)}}}else if(e==="nx")r=["apps/*","libs/*","packages/*"];else if(e==="turborepo"){let s=w.join(t,"package.json"),i=await z.readFile(s,"utf-8"),a=JSON.parse(i);Array.isArray(a.workspaces)&&(r=a.workspaces)}r.length===0&&(r=["packages/*","apps/*","libs/*"]);for(let s of r){if(s.startsWith("!"))continue;let i=ds(s,{cwd:t,absolute:!1});for(let a of i){let c=w.join(t,a),l=w.join(c,"package.json");if(await C(l))try{let p=await z.readFile(l,"utf-8"),m=JSON.parse(p),g=w.join(c,"PRJCT.md");n.push({name:m.name||w.basename(a),path:c,relativePath:a,hasPrjctMd:await C(g)})}catch{}}}}catch{}return n}async findContainingPackage(t,e){if(!e.isMonorepo)return null;let n=w.resolve(t);for(let r of e.packages){let s=w.resolve(r.path);if(n.startsWith(s))return r}return null}async findMonorepoRoot(t){let e=w.resolve(t),n=w.parse(e).root;for(;e!==n;){if((await this.detectMonorepo(e)).isMonorepo)return e;e=w.dirname(e)}return null}},ms=new ce,P=ms;function gs(){return typeof globalThis<"u"&&"Bun"in globalThis?"bun":"node"}u(gs,"detectRuntime");function Cr(){return gs()==="bun"}u(Cr,"isBun");function fs(o){if(Cr()){let{Database:r}=Ke("bun:sqlite");return new r(o,{create:!0})}let t=Ke("better-sqlite3"),e=new t(o),n=e.exec.bind(e);return e.run=r=>n(r),e}u(fs,"openDatabase");var hs=[{version:1,name:"initial-schema",up:u(o=>{o.run(`
12
16
  -- =======================================================================
13
17
  -- Document storage (backward-compatible with JSON file pattern)
14
18
  -- =======================================================================
@@ -421,11 +425,11 @@ var St=Object.defineProperty;var jr=Object.getOwnPropertyDescriptor;var Dr=Objec
421
425
  INSERT INTO memories_fts(rowid, title, content, tags)
422
426
  VALUES (NEW.rowid, NEW.title, NEW.content, NEW.tags);
423
427
  END;
424
- `);try{let e=o.prepare("SELECT data FROM kv_store WHERE key = 'memory:memories'").get();if(e){let t=JSON.parse(e.data);if(t.memories&&t.memories.length>0){let r=o.prepare(`
428
+ `);try{let t=o.prepare("SELECT data FROM kv_store WHERE key = 'memory:memories'").get();if(t){let e=JSON.parse(t.data);if(e.memories&&e.memories.length>0){let n=o.prepare(`
425
429
  INSERT OR IGNORE INTO memories
426
430
  (id, project_id, title, content, tags, content_hash, user_triggered, confidence, observation_count, created_at, updated_at)
427
431
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
428
- `);for(let n of t.memories)r.run(n.id,"_migrated",n.title,n.content,(n.tags||[]).join(","),null,n.userTriggered?1:0,n.confidence??null,n.observationCount??0,n.createdAt,n.updatedAt)}}}catch{}},"up")},{version:11,name:"agent-sessions",up:u(o=>{o.run(`
432
+ `);for(let r of e.memories)n.run(r.id,"_migrated",r.title,r.content,(r.tags||[]).join(","),null,r.userTriggered?1:0,r.confidence??null,r.observationCount??0,r.createdAt,r.updatedAt)}}}catch{}},"up")},{version:11,name:"agent-sessions",up:u(o=>{o.run(`
429
433
  -- =======================================================================
430
434
  -- Agent Sessions: Track AI agent work sessions across compactions
431
435
  -- =======================================================================
@@ -458,213 +462,213 @@ var St=Object.defineProperty;var jr=Object.getOwnPropertyDescriptor;var Dr=Objec
458
462
 
459
463
  CREATE INDEX IF NOT EXISTS idx_user_prompts_project ON user_prompts(project_id);
460
464
  CREATE INDEX IF NOT EXISTS idx_user_prompts_session ON user_prompts(session_id);
461
- `);try{o.run("ALTER TABLE memories ADD COLUMN session_id TEXT")}catch{}},"up")}],ls=3,ce=class{static{u(this,"PrjctDatabase")}connections=new Map;accessOrder=[];getDbPath(e){return Pn.join(v.getGlobalProjectPath(e),"prjct.db")}getDb(e){let t=this.connections.get(e);if(t)return this.touchAccessOrder(e),t;this.connections.size>=ls&&this.evictLru();let r=this.getDbPath(e),n=Pn.dirname(r);ae.existsSync(n)||ae.mkdirSync(n,{recursive:!0});let s=cs(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(e,s),this.touchAccessOrder(e),s}close(e){if(e){let t=this.connections.get(e);t&&(t.close(),this.connections.delete(e),this.accessOrder=this.accessOrder.filter(r=>r!==e))}else this.connections.forEach(t=>{t.close()}),this.connections.clear(),this.accessOrder=[]}touchAccessOrder(e){this.accessOrder=this.accessOrder.filter(t=>t!==e),this.accessOrder.push(e)}evictLru(){if(this.accessOrder.length===0)return;let e=this.accessOrder.shift(),t=this.connections.get(e);t&&(t.close(),this.connections.delete(e))}checkpointAll(){for(let[e,t]of this.connections)try{t.run("PRAGMA wal_checkpoint(TRUNCATE)")}catch{}}exists(e){return ae.existsSync(this.getDbPath(e))}getDoc(e,t){let n=this.getDb(e).prepare("SELECT data FROM kv_store WHERE key = ?").get(t);return n?JSON.parse(n.data):null}setDoc(e,t,r){let n=this.getDb(e),s=JSON.stringify(r),i=new Date().toISOString();n.prepare("INSERT OR REPLACE INTO kv_store (key, data, updated_at) VALUES (?, ?, ?)").run(t,s,i)}deleteDoc(e,t){this.getDb(e).prepare("DELETE FROM kv_store WHERE key = ?").run(t)}hasDoc(e,t){return this.getDb(e).prepare("SELECT 1 FROM kv_store WHERE key = ?").get(t)!==null}appendEvent(e,t,r,n){let s=this.getDb(e),i=new Date().toISOString();s.prepare("INSERT INTO events (type, task_id, data, timestamp) VALUES (?, ?, ?, ?)").run(t,n??null,JSON.stringify(r),i)}getEvents(e,t,r=100){let n=this.getDb(e);return t?n.prepare("SELECT * FROM events WHERE type = ? ORDER BY id DESC LIMIT ?").all(t,r):n.prepare("SELECT * FROM events ORDER BY id DESC LIMIT ?").all(r)}query(e,t,...r){return this.getDb(e).prepare(t).all(...r)}run(e,t,...r){this.getDb(e).prepare(t).run(...r)}get(e,t,...r){return this.getDb(e).prepare(t).get(...r)??null}transaction(e,t){let r=this.getDb(e);return r.transaction(t)(r)}runMigrations(e){e.run(`
465
+ `);try{o.run("ALTER TABLE memories ADD COLUMN session_id TEXT")}catch{}},"up")}],ys=3,le=class{static{u(this,"PrjctDatabase")}connections=new Map;accessOrder=[];getDbPath(t){return Ar.join(P.getGlobalProjectPath(t),"prjct.db")}getDb(t){let e=this.connections.get(t);if(e)return this.touchAccessOrder(t),e;this.connections.size>=ys&&this.evictLru();let n=this.getDbPath(t),r=Ar.dirname(n);ue.existsSync(r)||ue.mkdirSync(r,{recursive:!0});let s=fs(n);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(n=>n!==t))}else this.connections.forEach(e=>{e.close()}),this.connections.clear(),this.accessOrder=[]}touchAccessOrder(t){this.accessOrder=this.accessOrder.filter(e=>e!==t),this.accessOrder.push(t)}evictLru(){if(this.accessOrder.length===0)return;let t=this.accessOrder.shift(),e=this.connections.get(t);e&&(e.close(),this.connections.delete(t))}checkpointAll(){for(let[t,e]of this.connections)try{e.run("PRAGMA wal_checkpoint(TRUNCATE)")}catch{}}exists(t){return ue.existsSync(this.getDbPath(t))}getDoc(t,e){let r=this.getDb(t).prepare("SELECT data FROM kv_store WHERE key = ?").get(e);return r?JSON.parse(r.data):null}setDoc(t,e,n){let r=this.getDb(t),s=JSON.stringify(n),i=new Date().toISOString();r.prepare("INSERT OR REPLACE INTO kv_store (key, data, updated_at) VALUES (?, ?, ?)").run(e,s,i)}deleteDoc(t,e){this.getDb(t).prepare("DELETE FROM kv_store WHERE key = ?").run(e)}hasDoc(t,e){return this.getDb(t).prepare("SELECT 1 FROM kv_store WHERE key = ?").get(e)!==null}appendEvent(t,e,n,r){let s=this.getDb(t),i=new Date().toISOString();s.prepare("INSERT INTO events (type, task_id, data, timestamp) VALUES (?, ?, ?, ?)").run(e,r??null,JSON.stringify(n),i)}getEvents(t,e,n=100){let r=this.getDb(t);return e?r.prepare("SELECT * FROM events WHERE type = ? ORDER BY id DESC LIMIT ?").all(e,n):r.prepare("SELECT * FROM events ORDER BY id DESC LIMIT ?").all(n)}query(t,e,...n){return this.getDb(t).prepare(e).all(...n)}run(t,e,...n){this.getDb(t).prepare(e).run(...n)}get(t,e,...n){return this.getDb(t).prepare(e).get(...n)??null}transaction(t,e){let n=this.getDb(t);return n.transaction(e)(n)}runMigrations(t){t.run(`
462
466
  CREATE TABLE IF NOT EXISTS _migrations (
463
467
  version INTEGER PRIMARY KEY,
464
468
  name TEXT NOT NULL,
465
469
  applied_at TEXT NOT NULL
466
470
  )
467
- `);let t=new Set(e.prepare("SELECT version FROM _migrations").all().map(r=>r.version));for(let r of us)t.has(r.version)||e.transaction(()=>{r.up(e),e.prepare("INSERT INTO _migrations (version, name, applied_at) VALUES (?, ?, ?)").run(r.version,r.name,new Date().toISOString())})()}getMigrations(e){return this.getDb(e).prepare("SELECT * FROM _migrations ORDER BY version").all()}getSchemaVersion(e){return this.getDb(e).prepare("SELECT MAX(version) as version FROM _migrations").get()?.version??0}},S=new ce,y=S;tt();function ps(o){let e=[],t,r=new RegExp(Ye.source,"g");for(;(t=r.exec(o))!==null;){let n=t[1];(n.startsWith(".")||n.startsWith("@/"))&&e.push(n)}return e}u(ps,"extractImportSources");async function ds(o,e,t){let r;if(o.startsWith("@/"))r=ct.join(t,"src",o.slice(2));else{let n=ct.dirname(ct.join(t,e));r=ct.resolve(n,o)}for(let n of qe){let s=r+n;try{if((await Rn.stat(s)).isFile())return ct.relative(t,s)}catch{}}return null}u(ds,"resolveImport");async function ms(o){let e=await on(o),t={},r={},n=0,s=await an(e,50,async i=>{try{let a=await Rn.readFile(ct.join(o,i),"utf-8"),c=ps(a),l=[];for(let p of c){let m=await ds(p,i,o);m&&m!==i&&l.push(m)}return l.length>0?{filePath:i,imports:l}:null}catch{return null}});for(let{filePath:i,imports:a}of s){t[i]=a,n+=a.length;for(let c of a)r[c]||(r[c]=[]),r[c].push(i)}return{forward:t,reverse:r,fileCount:e.length,edgeCount:n,builtAt:new Date().toISOString()}}u(ms,"buildGraph");function Cn(o,e,t=2){let r=new Set(o),n=new Map,s=[];for(let i of o){let a=e.forward[i]||[],c=e.reverse[i]||[];for(let l of[...a,...c])r.has(l)||s.push({file:l,depth:1})}for(;s.length>0;){let{file:i,depth:a}=s.shift();if(a>t)continue;let c=1/(a+1),l=n.get(i);if(l){c>l.score&&n.set(i,{score:c,depth:a});continue}if(n.set(i,{score:c,depth:a}),a<t){let p=e.forward[i]||[],m=e.reverse[i]||[];for(let g of[...p,...m])!r.has(g)&&!n.has(g)&&s.push({file:g,depth:a+1})}}return Array.from(n.entries()).map(([i,{score:a,depth:c}])=>({path:i,score:a,depth:c})).sort((i,a)=>a.score-i.score)}u(Cn,"scoreFromSeeds");var jn="import-graph";function gs(o,e){y.setDoc(o,jn,e)}u(gs,"saveGraph");function ht(o){return y.getDoc(o,jn)}u(ht,"loadGraph");async function Dn(o,e){let t=await ms(o);return gs(e,t),t}u(Dn,"indexImports");function An(o,e){let t=[...o.added,...o.modified],r=new Set(t),n=new Set,s=ht(e);if(s)for(let c of t){let l=s.reverse[c];if(l)for(let p of l)r.has(p)||n.add(p)}let i=Array.from(n),a=[...t,...i];return{directlyChanged:t,affectedByImports:i,deleted:o.deleted,allAffected:a}}u(An,"propagateChanges");function Nn(o){let e=new Set;for(let t of o){let r=t.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/"))&&(e.add("frontend"),e.add("uxui")),(r.includes(".test.")||r.includes(".spec.")||r.includes("__tests__")||r.includes("/test/"))&&e.add("testing"),(r.includes("dockerfile")||r.includes("docker-compose")||r.includes(".dockerignore")||r.includes(".github/")||r.includes("ci/")||r.includes("cd/"))&&e.add("devops"),(r.endsWith(".sql")||r.includes("prisma")||r.includes("drizzle")||r.includes("migration")||r.includes("/db/"))&&e.add("database"),(r.endsWith(".ts")||r.endsWith(".js"))&&!r.includes(".test.")&&!r.includes(".spec.")&&!r.endsWith(".d.ts")&&e.add("backend")}return e}u(Nn,"affectedDomains");ue();at();async function hs(o,e=100){try{let{stdout:t}=await W(`git log --name-only --pretty=format:'---COMMIT---' -${e}`,{cwd:o,maxBuffer:10485760}),r=[],n=null;for(let s of t.split(`
468
- `)){let i=s.trim();i==="---COMMIT---"?(n&&n.size>0&&n.size<=30&&r.push(n),n=new Set):i&&n&&ys(i)&&n.add(i)}return n&&n.size>0&&n.size<=30&&r.push(n),r}catch{return[]}}u(hs,"parseGitLog");function ys(o){return/\.(ts|tsx|js|jsx|mjs|cjs|py|go|rs|java|cs|rb|php|vue|svelte)$/i.test(o)&&!o.includes("node_modules/")}u(ys,"isSourceFile");async function Ts(o,e=100){let t=await hs(o,e),r=new Map,n=new Map;for(let i of t){let a=Array.from(i);for(let c of a)r.set(c,(r.get(c)||0)+1);for(let c=0;c<a.length;c++)for(let l=c+1;l<a.length;l++){let p=Es(a[c],a[l]);n.set(p,(n.get(p)||0)+1)}}let s={};for(let[i,a]of n){let[c,l]=i.split("\0"),p=r.get(c)||0,m=r.get(l)||0;if(p<2||m<2)continue;let g=p+m-a,h=g>0?a/g:0;h<.1||(s[c]||(s[c]={}),s[l]||(s[l]={}),s[c][l]=h,s[l][c]=h)}return{matrix:s,commitsAnalyzed:t.length,filesAnalyzed:r.size,builtAt:new Date().toISOString()}}u(Ts,"buildMatrix");function Es(o,e){return o<e?`${o}\0${e}`:`${e}\0${o}`}u(Es,"pairKey");function le(o,e){let t=new Set(o),r=new Map;for(let n of o){let s=e.matrix[n];if(s)for(let[i,a]of Object.entries(s)){if(t.has(i))continue;let c=r.get(i)||0;a>c&&r.set(i,a)}}return Array.from(r.entries()).map(([n,s])=>({path:n,score:s})).sort((n,s)=>s.score-n.score)}u(le,"scoreFromSeeds");var Ln="cochange-index";function ws(o,e){y.setDoc(o,Ln,e)}u(ws,"saveMatrix");function pe(o){return y.getDoc(o,Ln)}u(pe,"loadMatrix");async function $n(o,e,t=100){let r=await Ts(o,t);return ws(e,r),r}u($n,"indexCoChanges");import he from"node:fs/promises";import Rs from"node:path";import*as Mt from"jsonc-parser";import{z as P}from"zod";var ut={create(o,e){class t extends Error{static{u(this,"TypedError")}errorName;data;isOperational=!0;constructor(n){let s=e.parse(n);super(`${o}: ${JSON.stringify(s)}`),this.name=o,this.errorName=o,this.data=s,Error.captureStackTrace?.(this,this.constructor)}static throw(n){throw new t(n)}static is(n){return n instanceof t&&n.errorName===o}static create(n){return new t(n)}}return t}},ca=ut.create("FileError",P.object({path:P.string(),operation:P.enum(["read","write","delete","create","copy"]),reason:P.string().optional()})),ua=ut.create("ValidationError",P.object({field:P.string(),expected:P.string(),received:P.string().optional(),message:P.string().optional()})),la=ut.create("PermissionError",P.object({action:P.string(),resource:P.string(),reason:P.string().optional()})),pa=ut.create("TaskError",P.object({taskId:P.string().optional(),operation:P.enum(["create","update","complete","pause","resume","delete"]),reason:P.string()})),da=ut.create("SessionError",P.object({sessionId:P.string().optional(),reason:P.string()})),ma=ut.create("SyncError",P.object({projectId:P.string().optional(),operation:P.enum(["push","pull","auth","connect"]),reason:P.string()})),de=class extends Error{static{u(this,"PrjctError")}code;isOperational;constructor(e,t="PRJCT_ERROR"){super(e),this.name="PrjctError",this.code=t,this.isOperational=!0,Error.captureStackTrace?.(this,this.constructor)}};function bs(o){return o instanceof de}u(bs,"isPrjctError");function me(o){return bs(o)||o instanceof Error?o.message:typeof o=="string"?o:"Unknown error"}u(me,"getErrorMessage");ot();N();tt();ot();import ge from"node:fs";import At from"node:path";var Dt=null,ks=null,yt=null;function Fn(){if(yt)return yt;let o=__dirname;for(let e=0;e<5;e++){let t=At.join(o,"package.json");if(ge.existsSync(t))try{if(JSON.parse(ge.readFileSync(t,"utf-8")).name==="prjct-cli")return yt=o,o}catch{}o=At.dirname(o)}return yt=At.join(__dirname,"..","..",".."),yt}u(Fn,"getPackageRoot");function Ss(){if(Dt)return Dt;try{let o=At.join(Fn(),"package.json"),e=JSON.parse(ge.readFileSync(o,"utf-8"));return Dt=e.version,ks=e,Dt}catch(o){return console.error("Failed to read version from package.json:",Ze(o)),"0.0.0"}}u(Ss,"getVersion");var fe=Ss(),Ea=Fn();at();async function Nt(o){try{let{stdout:e}=await W(o,{timeout:5e3});return{success:!0,output:e.trim()}}catch{return{success:!1,output:""}}}u(Nt,"execCommand");async function _s(){let o=await Nt("gh api user --jq .login");return o.success&&o.output||(o=await Nt("git config --global github.user"),o.success&&o.output)?o.output:null}u(_s,"detectGitHubUsername");async function xs(){let o=await Nt("git config user.name");return o.success&&o.output?o.output:null}u(xs,"detectGitName");async function vs(){let o=await Nt("git config user.email");return o.success&&o.output?o.output:null}u(vs,"detectGitEmail");async function Un(){let[o,e,t]=await Promise.all([_s(),xs(),vs()]);return{github:o,email:t,name:e||o||"Unknown"}}u(Un,"detect");function Xn(o){let e=[],t=Mt.parse(o,e,{allowTrailingComma:!0,disallowComments:!1});if(e.length>0){let r=e[0];throw new SyntaxError(`JSON parse error at offset ${r.offset}: ${Mt.printParseErrorCode(r.error)}`)}return t}u(Xn,"parseJsonc");var ye=class{static{u(this,"ConfigManager")}async readConfig(e){try{let t=v.getLocalConfigPath(e),r=await he.readFile(t,"utf-8");return Xn(r)}catch(t){return M(t)||console.warn(`Warning: Could not read config at ${e}: ${me(t)}`),null}}async writeConfig(e,t){let r=v.getLocalConfigPath(e);await K(r,t)}async readGlobalConfig(e){try{let t=v.getGlobalProjectConfigPath(e),r=await he.readFile(t,"utf-8");return Xn(r)}catch(t){return M(t)||console.warn(`Warning: Could not read global config for ${e}: ${me(t)}`),null}}async writeGlobalConfig(e,t){let r=v.getGlobalProjectConfigPath(e);await K(r,t)}async ensureGlobalConfig(e){let t=await this.readGlobalConfig(e);if(!t){let r=f();t={projectId:e,authors:[],version:fe,lastSync:r},await this.writeGlobalConfig(e,t)}return t}async createConfig(e,t){let r=v.generateProjectId(e),n=v.getGlobalProjectPath(r),s=v.getDisplayPath(n),i=f(),a={projectId:r,dataPath:s,showMetrics:!0};await this.writeConfig(e,a);let c={projectId:r,authors:[{name:t.name||"Unknown",email:t.email||"",github:t.github||"",firstContribution:i,lastActivity:i}],version:fe,created:i,lastSync:i};return await this.writeGlobalConfig(r,c),a}async updateLastSync(e){let t=await this.getProjectId(e),r=await this.readGlobalConfig(t);r&&(r.lastSync=f(),await this.writeGlobalConfig(t,r))}validateConfig(e){return!(!e||!e.projectId||!e.dataPath)}async needsMigration(e){if(!await v.hasLegacyStructure(e))return!1;if(!await v.hasConfig(e))return!0;let n=await this.readConfig(e);if(!n||!n.projectId)return!0;let s=v.getGlobalProjectPath(n.projectId);try{return(await he.readdir(Rs.join(s,"core"))).length===0}catch(i){return M(i),!0}}async getProjectId(e){let t=await this.readConfig(e);return t?.projectId?t.projectId:v.generateProjectId(e)}async findAuthor(e,t){let r=await this.readGlobalConfig(e);return!r||!r.authors?null:r.authors.find(n=>n.github===t)||null}async addAuthor(e,t){let r=await this.ensureGlobalConfig(e);if(r.authors.some(i=>i.github===t.github))return;let s=f();r.authors.push({name:t.name||"Unknown",email:t.email||"",github:t.github||"",firstContribution:s,lastActivity:s}),r.lastSync=s,await this.writeGlobalConfig(e,r)}async updateAuthorActivity(e,t){let r=await this.readGlobalConfig(e);if(!r||!r.authors)return;let n=r.authors.find(s=>s.github===t);n&&(n.lastActivity=f(),r.lastSync=n.lastActivity,await this.writeGlobalConfig(e,r))}async getCurrentAuthor(e){let t=await Un(),r=await this.getProjectId(e);return await this.addAuthor(r,{name:t.name??void 0,email:t.email??void 0,github:t.github??void 0}),t.github||t.name||"Unknown"}async isConfigured(e){let t=await this.readConfig(e);return this.validateConfig(t)}async getShowMetrics(e){return(await this.readConfig(e))?.showMetrics??!0}async setShowMetrics(e,t){let r=await this.readConfig(e);r&&(r.showMetrics=t,await this.writeConfig(e,r))}async getConfigWithDefaults(e){let t=await this.readConfig(e);if(t)return t;let r=v.generateProjectId(e);return{projectId:r,dataPath:v.getDisplayPath(v.getGlobalProjectPath(r))}}},Cs=new ye,Wn=Cs;async function w(o){return Wn.getProjectId(o)}u(w,"resolveProjectId");function T(o,e){return async t=>{try{return await e(t)}catch(r){return js(r,o)}}}u(T,"safeMcpCall");function js(o,e){let t=o instanceof Error?o.message:String(o);return{content:[{type:"text",text:`[${e}] Error: ${t}`}],isError:!0}}u(js,"mcpError");function Hn(o){let e=o;e.tool("prjct_impact_analysis","Given changed files, find affected files via import graph + affected domains",{projectPath:I.string().describe("Project directory path"),changedFiles:I.array(I.string()).describe("List of changed file paths (relative to project root)")},T("prjct_impact_analysis",async t=>{let r=await w(t.projectPath),n={added:[],modified:t.changedFiles,deleted:[],unchanged:[]},s=An(n,r),i=Nn(s.allAffected),a=["## Impact Analysis"];a.push(`
471
+ `);let e=new Set(t.prepare("SELECT version FROM _migrations").all().map(n=>n.version));for(let n of hs)e.has(n.version)||t.transaction(()=>{n.up(t),t.prepare("INSERT INTO _migrations (version, name, applied_at) VALUES (?, ?, ?)").run(n.version,n.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}},S=new le,y=S;Q();function Ts(o){let t=[],e,n=new RegExp(Ze.source,"g");for(;(e=n.exec(o))!==null;){let r=e[1];(r.startsWith(".")||r.startsWith("@/"))&&t.push(r)}return t}u(Ts,"extractImportSources");async function Es(o,t,e){let n;if(o.startsWith("@/"))n=ut.join(e,"src",o.slice(2));else{let r=ut.dirname(ut.join(e,t));n=ut.resolve(r,o)}for(let r of Qe){let s=n+r;try{if((await Dr.stat(s)).isFile())return ut.relative(e,s)}catch{}}return null}u(Es,"resolveImport");async function ks(o){let t=await ur(o),e={},n={},r=0,s=await lr(t,50,async i=>{try{let a=await Dr.readFile(ut.join(o,i),"utf-8"),c=Ts(a),l=[];for(let p of c){let m=await Es(p,i,o);m&&m!==i&&l.push(m)}return l.length>0?{filePath:i,imports:l}:null}catch{return null}});for(let{filePath:i,imports:a}of s){e[i]=a,r+=a.length;for(let c of a)n[c]||(n[c]=[]),n[c].push(i)}return{forward:e,reverse:n,fileCount:t.length,edgeCount:r,builtAt:new Date().toISOString()}}u(ks,"buildGraph");function jr(o,t,e=2){let n=new Set(o),r=new Map,s=[];for(let i of o){let a=t.forward[i]||[],c=t.reverse[i]||[];for(let l of[...a,...c])n.has(l)||s.push({file:l,depth:1})}for(;s.length>0;){let{file:i,depth:a}=s.shift();if(a>e)continue;let c=1/(a+1),l=r.get(i);if(l){c>l.score&&r.set(i,{score:c,depth:a});continue}if(r.set(i,{score:c,depth:a}),a<e){let p=t.forward[i]||[],m=t.reverse[i]||[];for(let g of[...p,...m])!n.has(g)&&!r.has(g)&&s.push({file:g,depth:a+1})}}return Array.from(r.entries()).map(([i,{score:a,depth:c}])=>({path:i,score:a,depth:c})).sort((i,a)=>a.score-i.score)}u(jr,"scoreFromSeeds");var Nr="import-graph";function ws(o,t){y.setDoc(o,Nr,t)}u(ws,"saveGraph");function yt(o){return y.getDoc(o,Nr)}u(yt,"loadGraph");async function Mr(o,t){let e=await ks(o);return ws(t,e),e}u(Mr,"indexImports");function Ir(o,t){let e=[...o.added,...o.modified],n=new Set(e),r=new Set,s=yt(t);if(s)for(let c of e){let l=s.reverse[c];if(l)for(let p of l)n.has(p)||r.add(p)}let i=Array.from(r),a=[...e,...i];return{directlyChanged:e,affectedByImports:i,deleted:o.deleted,allAffected:a}}u(Ir,"propagateChanges");function Or(o){let t=new Set;for(let e of o){let n=e.toLowerCase();(n.endsWith(".tsx")||n.endsWith(".jsx")||n.endsWith(".css")||n.endsWith(".scss")||n.endsWith(".vue")||n.endsWith(".svelte")||n.includes("/components/")||n.includes("/pages/")||n.includes("/app/"))&&(t.add("frontend"),t.add("uxui")),(n.includes(".test.")||n.includes(".spec.")||n.includes("__tests__")||n.includes("/test/"))&&t.add("testing"),(n.includes("dockerfile")||n.includes("docker-compose")||n.includes(".dockerignore")||n.includes(".github/")||n.includes("ci/")||n.includes("cd/"))&&t.add("devops"),(n.endsWith(".sql")||n.includes("prisma")||n.includes("drizzle")||n.includes("migration")||n.includes("/db/"))&&t.add("database"),(n.endsWith(".ts")||n.endsWith(".js"))&&!n.includes(".test.")&&!n.includes(".spec.")&&!n.endsWith(".d.ts")&&t.add("backend")}return t}u(Or,"affectedDomains");pe();at();async function Ss(o,t=100){try{let{stdout:e}=await v(`git log --name-only --pretty=format:'---COMMIT---' -${t}`,{cwd:o,maxBuffer:10485760}),n=[],r=null;for(let s of e.split(`
472
+ `)){let i=s.trim();i==="---COMMIT---"?(r&&r.size>0&&r.size<=30&&n.push(r),r=new Set):i&&r&&_s(i)&&r.add(i)}return r&&r.size>0&&r.size<=30&&n.push(r),n}catch{return[]}}u(Ss,"parseGitLog");function _s(o){return/\.(ts|tsx|js|jsx|mjs|cjs|py|go|rs|java|cs|rb|php|vue|svelte)$/i.test(o)&&!o.includes("node_modules/")}u(_s,"isSourceFile");async function xs(o,t=100){let e=await Ss(o,t),n=new Map,r=new Map;for(let i of e){let a=Array.from(i);for(let c of a)n.set(c,(n.get(c)||0)+1);for(let c=0;c<a.length;c++)for(let l=c+1;l<a.length;l++){let p=vs(a[c],a[l]);r.set(p,(r.get(p)||0)+1)}}let s={};for(let[i,a]of r){let[c,l]=i.split("\0"),p=n.get(c)||0,m=n.get(l)||0;if(p<2||m<2)continue;let g=p+m-a,h=g>0?a/g:0;h<.1||(s[c]||(s[c]={}),s[l]||(s[l]={}),s[c][l]=h,s[l][c]=h)}return{matrix:s,commitsAnalyzed:e.length,filesAnalyzed:n.size,builtAt:new Date().toISOString()}}u(xs,"buildMatrix");function vs(o,t){return o<t?`${o}\0${t}`:`${t}\0${o}`}u(vs,"pairKey");function de(o,t){let e=new Set(o),n=new Map;for(let r of o){let s=t.matrix[r];if(s)for(let[i,a]of Object.entries(s)){if(e.has(i))continue;let c=n.get(i)||0;a>c&&n.set(i,a)}}return Array.from(n.entries()).map(([r,s])=>({path:r,score:s})).sort((r,s)=>s.score-r.score)}u(de,"scoreFromSeeds");var Ur="cochange-index";function Ps(o,t){y.setDoc(o,Ur,t)}u(Ps,"saveMatrix");function me(o){return y.getDoc(o,Ur)}u(me,"loadMatrix");async function Wr(o,t,e=100){let n=await xs(o,e);return Ps(t,n),n}u(Wr,"indexCoChanges");import ke from"node:fs/promises";import Os from"node:path";import*as It from"jsonc-parser";import{z as R}from"zod";var lt={create(o,t){class e extends Error{static{u(this,"TypedError")}errorName;data;isOperational=!0;constructor(r){let s=t.parse(r);super(`${o}: ${JSON.stringify(s)}`),this.name=o,this.errorName=o,this.data=s,Error.captureStackTrace?.(this,this.constructor)}static throw(r){throw new e(r)}static is(r){return r instanceof e&&r.errorName===o}static create(r){return new e(r)}}return e}},ya=lt.create("FileError",R.object({path:R.string(),operation:R.enum(["read","write","delete","create","copy"]),reason:R.string().optional()})),Ta=lt.create("ValidationError",R.object({field:R.string(),expected:R.string(),received:R.string().optional(),message:R.string().optional()})),Ea=lt.create("PermissionError",R.object({action:R.string(),resource:R.string(),reason:R.string().optional()})),ka=lt.create("TaskError",R.object({taskId:R.string().optional(),operation:R.enum(["create","update","complete","pause","resume","delete"]),reason:R.string()})),wa=lt.create("SessionError",R.object({sessionId:R.string().optional(),reason:R.string()})),ba=lt.create("SyncError",R.object({projectId:R.string().optional(),operation:R.enum(["push","pull","auth","connect"]),reason:R.string()})),ge=class extends Error{static{u(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 Rs(o){return o instanceof ge}u(Rs,"isPrjctError");function fe(o){return Rs(o)||o instanceof Error?o.message:typeof o=="string"?o:"Unknown error"}u(fe,"getErrorMessage");it();I();Q();it();import he from"node:fs";import Nt from"node:path";var jt=null,Cs=null,Tt=null;function Xr(){if(Tt)return Tt;let o=__dirname;for(let t=0;t<5;t++){let e=Nt.join(o,"package.json");if(he.existsSync(e))try{if(JSON.parse(he.readFileSync(e,"utf-8")).name==="prjct-cli")return Tt=o,o}catch{}o=Nt.dirname(o)}return Tt=Nt.join(__dirname,"..","..",".."),Tt}u(Xr,"getPackageRoot");function As(){if(jt)return jt;try{let o=Nt.join(Xr(),"package.json"),t=JSON.parse(he.readFileSync(o,"utf-8"));return jt=t.version,Cs=t,jt}catch(o){return console.error("Failed to read version from package.json:",nr(o)),"0.0.0"}}u(As,"getVersion");var ye=As(),Ra=Xr();at();async function Mt(o){try{let{stdout:t}=await v(o,{timeout:5e3});return{success:!0,output:t.trim()}}catch{return{success:!1,output:""}}}u(Mt,"execCommand");async function Ds(){let o=await Mt("gh api user --jq .login");return o.success&&o.output||(o=await Mt("git config --global github.user"),o.success&&o.output)?o.output:null}u(Ds,"detectGitHubUsername");async function js(){let o=await Mt("git config user.name");return o.success&&o.output?o.output:null}u(js,"detectGitName");async function Ns(){let o=await Mt("git config user.email");return o.success&&o.output?o.output:null}u(Ns,"detectGitEmail");async function Hr(){let[o,t,e]=await Promise.all([Ds(),js(),Ns()]);return{github:o,email:e,name:t||o||"Unknown"}}u(Hr,"detect");function qr(o){let t=[],e=It.parse(o,t,{allowTrailingComma:!0,disallowComments:!1});if(t.length>0){let n=t[0];throw new SyntaxError(`JSON parse error at offset ${n.offset}: ${It.printParseErrorCode(n.error)}`)}return e}u(qr,"parseJsonc");var we=class{static{u(this,"ConfigManager")}async readConfig(t){try{let e=P.getLocalConfigPath(t),n=await ke.readFile(e,"utf-8");return qr(n)}catch(e){return O(e)||console.warn(`Warning: Could not read config at ${t}: ${fe(e)}`),null}}async writeConfig(t,e){let n=P.getLocalConfigPath(t);await J(n,e)}async readGlobalConfig(t){try{let e=P.getGlobalProjectConfigPath(t),n=await ke.readFile(e,"utf-8");return qr(n)}catch(e){return O(e)||console.warn(`Warning: Could not read global config for ${t}: ${fe(e)}`),null}}async writeGlobalConfig(t,e){let n=P.getGlobalProjectConfigPath(t);await J(n,e)}async ensureGlobalConfig(t){let e=await this.readGlobalConfig(t);if(!e){let n=f();e={projectId:t,authors:[],version:ye,lastSync:n},await this.writeGlobalConfig(t,e)}return e}async createConfig(t,e){let n=P.generateProjectId(t),r=P.getGlobalProjectPath(n),s=P.getDisplayPath(r),i=f(),a={projectId:n,dataPath:s,showMetrics:!0};await this.writeConfig(t,a);let c={projectId:n,authors:[{name:e.name||"Unknown",email:e.email||"",github:e.github||"",firstContribution:i,lastActivity:i}],version:ye,created:i,lastSync:i};return await this.writeGlobalConfig(n,c),a}async updateLastSync(t){let e=await this.getProjectId(t),n=await this.readGlobalConfig(e);n&&(n.lastSync=f(),await this.writeGlobalConfig(e,n))}validateConfig(t){return!(!t||!t.projectId||!t.dataPath)}async needsMigration(t){if(!await P.hasLegacyStructure(t))return!1;if(!await P.hasConfig(t))return!0;let r=await this.readConfig(t);if(!r||!r.projectId)return!0;let s=P.getGlobalProjectPath(r.projectId);try{return(await ke.readdir(Os.join(s,"core"))).length===0}catch(i){return O(i),!0}}async getProjectId(t){let e=await this.readConfig(t);if(e?.projectId)return e.projectId;try{let{worktreeService:n}=await Promise.resolve().then(()=>(zr(),Vr));if(await n.detect(t)){let s=await n.getMainWorktree(t);if(s!==t){let i=await this.readConfig(s);if(i?.projectId)return i.projectId}}}catch{}return P.generateProjectId(t)}async findAuthor(t,e){let n=await this.readGlobalConfig(t);return!n||!n.authors?null:n.authors.find(r=>r.github===e)||null}async addAuthor(t,e){let n=await this.ensureGlobalConfig(t);if(n.authors.some(i=>i.github===e.github))return;let s=f();n.authors.push({name:e.name||"Unknown",email:e.email||"",github:e.github||"",firstContribution:s,lastActivity:s}),n.lastSync=s,await this.writeGlobalConfig(t,n)}async updateAuthorActivity(t,e){let n=await this.readGlobalConfig(t);if(!n||!n.authors)return;let r=n.authors.find(s=>s.github===e);r&&(r.lastActivity=f(),n.lastSync=r.lastActivity,await this.writeGlobalConfig(t,n))}async getCurrentAuthor(t){let e=await Hr(),n=await this.getProjectId(t);return await this.addAuthor(n,{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 n=await this.readConfig(t);n&&(n.showMetrics=e,await this.writeConfig(t,n))}async getConfigWithDefaults(t){let e=await this.readConfig(t);if(e)return e;let n=P.generateProjectId(t);return{projectId:n,dataPath:P.getDisplayPath(P.getGlobalProjectPath(n))}}},Ls=new we,Yr=Ls;async function k(o){return Yr.getProjectId(o)}u(k,"resolveProjectId");function T(o,t){return async e=>{try{return await t(e)}catch(n){return $s(n,o)}}}u(T,"safeMcpCall");function $s(o,t){let e=o instanceof Error?o.message:String(o);return{content:[{type:"text",text:`[${t}] Error: ${e}`}],isError:!0}}u($s,"mcpError");function Kr(o){let t=o;t.tool("prjct_impact_analysis","Given changed files, find affected files via import graph + affected domains",{projectPath:L.string().describe("Project directory path"),changedFiles:L.array(L.string()).describe("List of changed file paths (relative to project root)")},T("prjct_impact_analysis",async e=>{let n=await k(e.projectPath),r={added:[],modified:e.changedFiles,deleted:[],unchanged:[]},s=Ir(r,n),i=Or(s.allAffected),a=["## Impact Analysis"];a.push(`
469
473
  ### Directly Changed (${s.directlyChanged.length})`);for(let c of s.directlyChanged)a.push(`- ${c}`);if(s.affectedByImports.length>0){a.push(`
470
474
  ### Affected via Imports (${s.affectedByImports.length})`);for(let c of s.affectedByImports)a.push(`- ${c}`)}return a.push(`
471
475
  ### Affected Domains`),a.push(i.size>0?Array.from(i).join(", "):"none detected"),a.push(`
472
476
  Total affected: ${s.allAffected.length} files`),{content:[{type:"text",text:a.join(`
473
- `)}]}})),e.tool("prjct_import_graph","Import graph stats + file neighbors (imports/importers). Pass a file for its neighbors, omit for graph stats.",{projectPath:I.string().describe("Project directory path"),file:I.string().optional().describe("File path to get neighbors for (omit for graph stats)"),rebuild:I.boolean().optional().default(!1).describe("Force rebuild the import graph")},T("prjct_import_graph",async t=>{let r=await w(t.projectPath),n=t.rebuild?null:ht(r);if(n||(n=await Dn(t.projectPath,r)),t.file){let i=n.forward[t.file]||[],a=n.reverse[t.file]||[];return{content:[{type:"text",text:[`## Import Neighbors: ${t.file}`,`
477
+ `)}]}})),t.tool("prjct_import_graph","Import graph stats + file neighbors (imports/importers). Pass a file for its neighbors, omit for graph stats.",{projectPath:L.string().describe("Project directory path"),file:L.string().optional().describe("File path to get neighbors for (omit for graph stats)"),rebuild:L.boolean().optional().default(!1).describe("Force rebuild the import graph")},T("prjct_import_graph",async e=>{let n=await k(e.projectPath),r=e.rebuild?null:yt(n);if(r||(r=await Mr(e.projectPath,n)),e.file){let i=r.forward[e.file]||[],a=r.reverse[e.file]||[];return{content:[{type:"text",text:[`## Import Neighbors: ${e.file}`,`
474
478
  ### Imports (${i.length})`,...i.map(l=>`- ${l}`),`
475
479
  ### Imported By (${a.length})`,...a.map(l=>`- ${l}`)].join(`
476
- `)}]}}return{content:[{type:"text",text:["## Import Graph Stats",`Files: ${n.fileCount}`,`Edges: ${n.edgeCount}`,`Built: ${n.builtAt}`].join(`
477
- `)}]}})),e.tool("prjct_cochange","Files that historically change together (Jaccard similarity from git history)",{projectPath:I.string().describe("Project directory path"),seedFiles:I.array(I.string()).describe("Seed files to find co-change partners for"),rebuild:I.boolean().optional().default(!1).describe("Force rebuild the co-change matrix"),maxResults:I.number().optional().default(10).describe("Max results (default 10)")},T("prjct_cochange",async t=>{let r=await w(t.projectPath),n=t.rebuild?null:pe(r);n||(n=await $n(t.projectPath,r));let s=le(t.seedFiles,n).slice(0,t.maxResults);if(s.length===0)return{content:[{type:"text",text:"No co-change partners found."}]};let i=["## Co-Change Partners",`Seeds: ${t.seedFiles.join(", ")}`,`Commits analyzed: ${n.commitsAnalyzed}`,""];for(let a of s)i.push(`- ${a.path} (similarity: ${Math.round(a.score*100)}%)`);return{content:[{type:"text",text:i.join(`
478
- `)}]}})),e.tool("prjct_related_context","Combined: import neighbors + co-change partners for seed files",{projectPath:I.string().describe("Project directory path"),seedFiles:I.array(I.string()).describe("Seed files to find related context for"),maxResults:I.number().optional().default(15).describe("Max results (default 15)")},T("prjct_related_context",async t=>{let r=await w(t.projectPath),n=ht(r),s=n?Cn(t.seedFiles,n):[],i=pe(r),a=i?le(t.seedFiles,i):[],c=new Map;for(let m of s)c.set(m.path,{importScore:m.score,cochangeScore:0});for(let m of a){let g=c.get(m.path);g?g.cochangeScore=m.score:c.set(m.path,{importScore:0,cochangeScore:m.score})}let l=Array.from(c.entries()).map(([m,g])=>({path:m,combined:g.importScore*.6+g.cochangeScore*.4,importScore:g.importScore,cochangeScore:g.cochangeScore})).sort((m,g)=>g.combined-m.combined).slice(0,t.maxResults);if(l.length===0)return{content:[{type:"text",text:"No related files found. Run `prjct sync` to build indexes."}]};let p=["## Related Context",`Seeds: ${t.seedFiles.join(", ")}`,""];for(let m of l){let g=[];m.importScore>0&&g.push(`import: ${m.importScore.toFixed(2)}`),m.cochangeScore>0&&g.push(`cochange: ${Math.round(m.cochangeScore*100)}%`),p.push(`- ${m.path} (${g.join(", ")})`)}return{content:[{type:"text",text:p.join(`
479
- `)}]}}))}u(Hn,"registerCodeIntelTools");import{z as Tt}from"zod";var J={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 It(o,e=!1){return e||o>=6?"high":o>=3?"medium":"low"}u(It,"calculateConfidence");N();var Ot=class{static{u(this,"CachedStore")}_data=null;_loaded=!1;_projectId=null;getSubdirectory(){return null}getStoreKey(){let e=this.getFilename().replace(".json",""),t=this.getSubdirectory();return t?`memory:${t}:${e}`:`memory:${e}`}async load(e){if(this._loaded&&this._data&&this._projectId===e)return this._data;let t=this.getStoreKey(),r=y.getDoc(e,t);return r!==null?(this._data=r,this.afterLoad(this._data)):this._data=this.getDefault(),this._loaded=!0,this._projectId=e,this._data}afterLoad(e){}async save(e){if(!this._data)return;let t=this.getStoreKey();y.setDoc(e,t,this._data)}getData(){return this._data}setData(e){this._data=e}async update(e,t){let r=await this.load(e),n=t(r);return this._data=n,await this.save(e),n}isLoaded(e){return e?this._loaded&&this._projectId===e:this._loaded}reset(){this._data=null,this._loaded=!1,this._projectId=null}},Lt=class{static{u(this,"SessionStore")}_sessionMemory=new Map;setSession(e,t){this._sessionMemory.set(e,{value:t,timestamp:Date.now()})}getSession(e){return this._sessionMemory.get(e)?.value}clearSession(){this._sessionMemory.clear()}},$t=class{static{u(this,"HistoryStore")}async appendHistory(e,t){let r={ts:f(),...t,type:t.type};y.appendEvent(e,`history.${t.type}`,r)}async getRecentHistory(e,t=20){return y.query(e,"SELECT data, timestamp FROM events WHERE type LIKE 'history.%' ORDER BY id DESC LIMIT ?",t).reverse().map(n=>JSON.parse(n.data))}};N();var lt=class o extends Ot{static{u(this,"PatternStore")}static MAX_CONTEXTS=20;static ARCHIVE_AGE_DAYS=90;getFilename(){return"patterns.json"}getDefault(){return{version:1,decisions:{},preferences:{},workflows:{},counters:{}}}afterLoad(e){for(let t of Object.values(e.decisions))Array.isArray(t.contexts)||(t.contexts=[]),t.contexts.length>o.MAX_CONTEXTS&&(t.contexts=t.contexts.slice(-o.MAX_CONTEXTS))}async loadPatterns(e){return this.load(e)}async savePatterns(e){return this.save(e)}async recordDecision(e,t,r,n="",s={}){let i=await this.load(e),a=f();if(!i.decisions[t])i.decisions[t]={value:r,count:1,firstSeen:a,lastSeen:a,confidence:s.userConfirmed?"high":"low",contexts:[n].filter(Boolean),userConfirmed:s.userConfirmed||!1};else{let c=i.decisions[t];c.value===r?(c.count++,c.lastSeen=a,n&&!c.contexts.includes(n)&&(c.contexts.push(n),c.contexts.length>o.MAX_CONTEXTS&&(c.contexts=c.contexts.slice(-o.MAX_CONTEXTS))),s.userConfirmed&&(c.userConfirmed=!0),c.confidence=It(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(e)}async confirmDecision(e,t){let n=(await this.load(e)).decisions[t];return n?(n.userConfirmed=!0,n.confidence="high",n.lastSeen=f(),await this.save(e),!0):!1}async getDecision(e,t){let n=(await this.load(e)).decisions[t];return!n||n.confidence==="low"?null:{value:n.value,confidence:n.confidence}}async hasPattern(e,t){return await this.getDecision(e,t)!==null}async recordWorkflow(e,t,r){let n=await this.load(e),s=f();if(!n.workflows[t])n.workflows[t]={...r,count:1,firstSeen:s,lastSeen:s,confidence:"low",userConfirmed:!1};else{let i=n.workflows[t];i.count++,i.lastSeen=s,i.confidence=It(i.count,i.userConfirmed)}await this.save(e)}async confirmWorkflow(e,t){let n=(await this.load(e)).workflows[t];return n?(n.userConfirmed=!0,n.confidence="high",n.lastSeen=f(),await this.save(e),!0):!1}async getWorkflow(e,t){let n=(await this.load(e)).workflows[t];return!n||n.count<3?null:n}async setPreference(e,t,r,n={}){let s=await this.load(e),i=s.preferences[t],a=i?i.observationCount+1:1,c=n.userConfirmed||i?.userConfirmed||!1;s.preferences[t]={value:r,updatedAt:f(),confidence:It(a,c),observationCount:a,userConfirmed:c},await this.save(e)}async confirmPreference(e,t){let n=(await this.load(e)).preferences[t];return n?(n.userConfirmed=!0,n.confidence="high",n.updatedAt=f(),await this.save(e),!0):!1}async getPreference(e,t,r=null){return(await this.load(e)).preferences[t]?.value??r}async getPatternsSummary(e){let t=await this.load(e);return{decisions:Object.keys(t.decisions).length,learnedDecisions:Object.values(t.decisions).filter(r=>r.confidence!=="low").length,workflows:Object.keys(t.workflows).length,preferences:Object.keys(t.preferences).length}}async getPatternsSummaryDetailed(e){let t=await this.load(e),r={};for(let[i,a]of Object.entries(t.decisions))r[i]={value:a.value,confidence:a.confidence,count:a.count};let n={};for(let[i,a]of Object.entries(t.preferences))n[i]={value:a.value,confidence:a.confidence};let s={};for(let[i,a]of Object.entries(t.workflows))s[i]={confidence:a.confidence??"low",count:a.count};return{decisions:r,preferences:n,workflows:s}}async archiveStaleDecisions(e){let t=await this.load(e),r=Date.now(),n=o.ARCHIVE_AGE_DAYS*24*60*60*1e3,s=[];for(let[a,c]of Object.entries(t.decisions)){let l=new Date(c.lastSeen).getTime();r-l>n&&s.push(a)}if(s.length===0)return 0;let i=y.getDoc(e,"memory:patterns-archive")??{};for(let a of s)i[a]=t.decisions[a],delete t.decisions[a];return y.setDoc(e,"memory:patterns-archive",i),await this.save(e),s.length}};import Ds from"node:crypto";import{homedir as As}from"node:os";import{join as Ns}from"node:path";function O(){return Ds.randomUUID()}u(O,"generateUUID");var lc=Ns(As(),".prjct-cli","projects");N();import{createHash as Ms}from"node:crypto";function Is(o){return Ms("sha256").update(o).digest("hex")}u(Is,"sha256");function Te(o){return Is(o).slice(0,16)}u(Te,"sha256Short");function Q(o){return{id:o.id,title:o.title,content:o.content,tags:o.tags?o.tags.split(",").filter(Boolean):[],userTriggered:o.user_triggered===1,createdAt:o.created_at,updatedAt:o.updated_at,confidence:o.confidence,observationCount:o.observation_count||void 0}}u(Q,"rowToMemory");var q=class{static{u(this,"SemanticMemories")}_coerceTags(e){let t=new Set(Object.values(J));return e.filter(r=>t.has(r))}async createMemory(e,{title:t,content:r,tags:n=[],userTriggered:s=!1,topicKey:i}){let c=this._coerceTags(n).join(","),l=f(),p=Te(r),m=y.get(e,"SELECT id FROM memories WHERE project_id = ? AND content_hash = ? AND deleted_at IS NULL",e,p);if(m)return m.id;if(i){let h=y.get(e,"SELECT * FROM memories WHERE project_id = ? AND topic_key = ? AND deleted_at IS NULL",e,i);if(h)return y.run(e,`UPDATE memories SET title = ?, content = ?, tags = ?, content_hash = ?,
480
- revision_count = revision_count + 1, updated_at = ? WHERE id = ?`,t,r,c,p,l,h.id),h.id}let g=O();return y.run(e,`INSERT INTO memories
480
+ `)}]}}return{content:[{type:"text",text:["## Import Graph Stats",`Files: ${r.fileCount}`,`Edges: ${r.edgeCount}`,`Built: ${r.builtAt}`].join(`
481
+ `)}]}})),t.tool("prjct_cochange","Files that historically change together (Jaccard similarity from git history)",{projectPath:L.string().describe("Project directory path"),seedFiles:L.array(L.string()).describe("Seed files to find co-change partners for"),rebuild:L.boolean().optional().default(!1).describe("Force rebuild the co-change matrix"),maxResults:L.number().optional().default(10).describe("Max results (default 10)")},T("prjct_cochange",async e=>{let n=await k(e.projectPath),r=e.rebuild?null:me(n);r||(r=await Wr(e.projectPath,n));let s=de(e.seedFiles,r).slice(0,e.maxResults);if(s.length===0)return{content:[{type:"text",text:"No co-change partners found."}]};let i=["## Co-Change Partners",`Seeds: ${e.seedFiles.join(", ")}`,`Commits analyzed: ${r.commitsAnalyzed}`,""];for(let a of s)i.push(`- ${a.path} (similarity: ${Math.round(a.score*100)}%)`);return{content:[{type:"text",text:i.join(`
482
+ `)}]}})),t.tool("prjct_related_context","Combined: import neighbors + co-change partners for seed files",{projectPath:L.string().describe("Project directory path"),seedFiles:L.array(L.string()).describe("Seed files to find related context for"),maxResults:L.number().optional().default(15).describe("Max results (default 15)")},T("prjct_related_context",async e=>{let n=await k(e.projectPath),r=yt(n),s=r?jr(e.seedFiles,r):[],i=me(n),a=i?de(e.seedFiles,i):[],c=new Map;for(let m of s)c.set(m.path,{importScore:m.score,cochangeScore:0});for(let m of a){let g=c.get(m.path);g?g.cochangeScore=m.score:c.set(m.path,{importScore:0,cochangeScore:m.score})}let l=Array.from(c.entries()).map(([m,g])=>({path:m,combined:g.importScore*.6+g.cochangeScore*.4,importScore:g.importScore,cochangeScore:g.cochangeScore})).sort((m,g)=>g.combined-m.combined).slice(0,e.maxResults);if(l.length===0)return{content:[{type:"text",text:"No related files found. Run `prjct sync` to build indexes."}]};let p=["## Related Context",`Seeds: ${e.seedFiles.join(", ")}`,""];for(let m of l){let g=[];m.importScore>0&&g.push(`import: ${m.importScore.toFixed(2)}`),m.cochangeScore>0&&g.push(`cochange: ${Math.round(m.cochangeScore*100)}%`),p.push(`- ${m.path} (${g.join(", ")})`)}return{content:[{type:"text",text:p.join(`
483
+ `)}]}}))}u(Kr,"registerCodeIntelTools");import{z as Et}from"zod";var Z={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 Ot(o,t=!1){return t||o>=6?"high":o>=3?"medium":"low"}u(Ot,"calculateConfidence");I();var Lt=class{static{u(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(),n=y.getDoc(t,e);return n!==null?(this._data=n,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();y.setDoc(t,e,this._data)}getData(){return this._data}setData(t){this._data=t}async update(t,e){let n=await this.load(t),r=e(n);return this._data=r,await this.save(t),r}isLoaded(t){return t?this._loaded&&this._projectId===t:this._loaded}reset(){this._data=null,this._loaded=!1,this._projectId=null}},$t=class{static{u(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()}},Ft=class{static{u(this,"HistoryStore")}async appendHistory(t,e){let n={ts:f(),...e,type:e.type};y.appendEvent(t,`history.${e.type}`,n)}async getRecentHistory(t,e=20){return y.query(t,"SELECT data, timestamp FROM events WHERE type LIKE 'history.%' ORDER BY id DESC LIMIT ?",e).reverse().map(r=>JSON.parse(r.data))}};I();var pt=class o extends Lt{static{u(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>o.MAX_CONTEXTS&&(e.contexts=e.contexts.slice(-o.MAX_CONTEXTS))}async loadPatterns(t){return this.load(t)}async savePatterns(t){return this.save(t)}async recordDecision(t,e,n,r="",s={}){let i=await this.load(t),a=f();if(!i.decisions[e])i.decisions[e]={value:n,count:1,firstSeen:a,lastSeen:a,confidence:s.userConfirmed?"high":"low",contexts:[r].filter(Boolean),userConfirmed:s.userConfirmed||!1};else{let c=i.decisions[e];c.value===n?(c.count++,c.lastSeen=a,r&&!c.contexts.includes(r)&&(c.contexts.push(r),c.contexts.length>o.MAX_CONTEXTS&&(c.contexts=c.contexts.slice(-o.MAX_CONTEXTS))),s.userConfirmed&&(c.userConfirmed=!0),c.confidence=Ot(c.count,c.userConfirmed)):(c.value=n,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 r=(await this.load(t)).decisions[e];return r?(r.userConfirmed=!0,r.confidence="high",r.lastSeen=f(),await this.save(t),!0):!1}async getDecision(t,e){let r=(await this.load(t)).decisions[e];return!r||r.confidence==="low"?null:{value:r.value,confidence:r.confidence}}async hasPattern(t,e){return await this.getDecision(t,e)!==null}async recordWorkflow(t,e,n){let r=await this.load(t),s=f();if(!r.workflows[e])r.workflows[e]={...n,count:1,firstSeen:s,lastSeen:s,confidence:"low",userConfirmed:!1};else{let i=r.workflows[e];i.count++,i.lastSeen=s,i.confidence=Ot(i.count,i.userConfirmed)}await this.save(t)}async confirmWorkflow(t,e){let r=(await this.load(t)).workflows[e];return r?(r.userConfirmed=!0,r.confidence="high",r.lastSeen=f(),await this.save(t),!0):!1}async getWorkflow(t,e){let r=(await this.load(t)).workflows[e];return!r||r.count<3?null:r}async setPreference(t,e,n,r={}){let s=await this.load(t),i=s.preferences[e],a=i?i.observationCount+1:1,c=r.userConfirmed||i?.userConfirmed||!1;s.preferences[e]={value:n,updatedAt:f(),confidence:Ot(a,c),observationCount:a,userConfirmed:c},await this.save(t)}async confirmPreference(t,e){let r=(await this.load(t)).preferences[e];return r?(r.userConfirmed=!0,r.confidence="high",r.updatedAt=f(),await this.save(t),!0):!1}async getPreference(t,e,n=null){return(await this.load(t)).preferences[e]?.value??n}async getPatternsSummary(t){let e=await this.load(t);return{decisions:Object.keys(e.decisions).length,learnedDecisions:Object.values(e.decisions).filter(n=>n.confidence!=="low").length,workflows:Object.keys(e.workflows).length,preferences:Object.keys(e.preferences).length}}async getPatternsSummaryDetailed(t){let e=await this.load(t),n={};for(let[i,a]of Object.entries(e.decisions))n[i]={value:a.value,confidence:a.confidence,count:a.count};let r={};for(let[i,a]of Object.entries(e.preferences))r[i]={value:a.value,confidence:a.confidence};let s={};for(let[i,a]of Object.entries(e.workflows))s[i]={confidence:a.confidence??"low",count:a.count};return{decisions:n,preferences:r,workflows:s}}async archiveStaleDecisions(t){let e=await this.load(t),n=Date.now(),r=o.ARCHIVE_AGE_DAYS*24*60*60*1e3,s=[];for(let[a,c]of Object.entries(e.decisions)){let l=new Date(c.lastSeen).getTime();n-l>r&&s.push(a)}if(s.length===0)return 0;let i=y.getDoc(t,"memory:patterns-archive")??{};for(let a of s)i[a]=e.decisions[a],delete e.decisions[a];return y.setDoc(t,"memory:patterns-archive",i),await this.save(t),s.length}};import Fs from"node:crypto";import{homedir as Us}from"node:os";import{join as Ws}from"node:path";function $(){return Fs.randomUUID()}u($,"generateUUID");var _c=Ws(Us(),".prjct-cli","projects");I();import{createHash as Xs}from"node:crypto";function Hs(o){return Xs("sha256").update(o).digest("hex")}u(Hs,"sha256");function be(o){return Hs(o).slice(0,16)}u(be,"sha256Short");function tt(o){return{id:o.id,title:o.title,content:o.content,tags:o.tags?o.tags.split(",").filter(Boolean):[],userTriggered:o.user_triggered===1,createdAt:o.created_at,updatedAt:o.updated_at,confidence:o.confidence,observationCount:o.observation_count||void 0}}u(tt,"rowToMemory");var Y=class{static{u(this,"SemanticMemories")}_coerceTags(t){let e=new Set(Object.values(Z));return t.filter(n=>e.has(n))}async createMemory(t,{title:e,content:n,tags:r=[],userTriggered:s=!1,topicKey:i}){let c=this._coerceTags(r).join(","),l=f(),p=be(n),m=y.get(t,"SELECT id FROM memories WHERE project_id = ? AND content_hash = ? AND deleted_at IS NULL",t,p);if(m)return m.id;if(i){let h=y.get(t,"SELECT * FROM memories WHERE project_id = ? AND topic_key = ? AND deleted_at IS NULL",t,i);if(h)return y.run(t,`UPDATE memories SET title = ?, content = ?, tags = ?, content_hash = ?,
484
+ revision_count = revision_count + 1, updated_at = ? WHERE id = ?`,e,n,c,p,l,h.id),h.id}let g=$();return y.run(t,`INSERT INTO memories
481
485
  (id, project_id, title, content, tags, topic_key, content_hash, user_triggered, created_at, updated_at)
482
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,g,e,t,r,c,i??null,p,s?1:0,l,l),g}async updateMemory(e,t,r){let n=y.get(e,"SELECT * FROM memories WHERE id = ? AND project_id = ? AND deleted_at IS NULL",t,e);if(!n)return!1;let s=r.title??n.title,i=r.content??n.content,a=r.tags?this._coerceTags(r.tags).join(","):n.tags,c=r.content?Te(i):n.content_hash;return y.run(e,`UPDATE memories SET title = ?, content = ?, tags = ?, content_hash = ?,
483
- revision_count = revision_count + 1, updated_at = ? WHERE id = ?`,s,i,a,c,f(),t),!0}async deleteMemory(e,t){return y.get(e,"SELECT id FROM memories WHERE id = ? AND project_id = ? AND deleted_at IS NULL",t,e)?(y.run(e,"UPDATE memories SET deleted_at = ? WHERE id = ?",f(),t),!0):!1}async findByTags(e,t,r=!1){let n=this._coerceTags(t);if(n.length===0)return[];let s=n.map(()=>"(tags = ? OR tags LIKE ? OR tags LIKE ? OR tags LIKE ?)"),i=r?" AND ":" OR ",a=s.join(i),c=[e];for(let p of n)c.push(p,`${p},%`,`%,${p},%`,`%,${p}`);return y.query(e,`SELECT * FROM memories WHERE project_id = ? AND deleted_at IS NULL
484
- AND (${a}) ORDER BY updated_at DESC`,...c).map(Q)}async searchMemories(e,t,r=20,n=0){try{return y.query(e,`SELECT m.* FROM memories m
486
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,g,t,e,n,c,i??null,p,s?1:0,l,l),g}async updateMemory(t,e,n){let r=y.get(t,"SELECT * FROM memories WHERE id = ? AND project_id = ? AND deleted_at IS NULL",e,t);if(!r)return!1;let s=n.title??r.title,i=n.content??r.content,a=n.tags?this._coerceTags(n.tags).join(","):r.tags,c=n.content?be(i):r.content_hash;return y.run(t,`UPDATE memories SET title = ?, content = ?, tags = ?, content_hash = ?,
487
+ revision_count = revision_count + 1, updated_at = ? WHERE id = ?`,s,i,a,c,f(),e),!0}async deleteMemory(t,e){return y.get(t,"SELECT id FROM memories WHERE id = ? AND project_id = ? AND deleted_at IS NULL",e,t)?(y.run(t,"UPDATE memories SET deleted_at = ? WHERE id = ?",f(),e),!0):!1}async findByTags(t,e,n=!1){let r=this._coerceTags(e);if(r.length===0)return[];let s=r.map(()=>"(tags = ? OR tags LIKE ? OR tags LIKE ? OR tags LIKE ?)"),i=n?" AND ":" OR ",a=s.join(i),c=[t];for(let p of r)c.push(p,`${p},%`,`%,${p},%`,`%,${p}`);return y.query(t,`SELECT * FROM memories WHERE project_id = ? AND deleted_at IS NULL
488
+ AND (${a}) ORDER BY updated_at DESC`,...c).map(tt)}async searchMemories(t,e,n=20,r=0){try{return y.query(t,`SELECT m.* FROM memories m
485
489
  JOIN memories_fts fts ON m.rowid = fts.rowid
486
490
  WHERE memories_fts MATCH ? AND m.project_id = ? AND m.deleted_at IS NULL
487
- ORDER BY bm25(memories_fts) LIMIT ? OFFSET ?`,t,e,r,n).map(Q)}catch{let s=`%${t}%`;return y.query(e,`SELECT * FROM memories
491
+ ORDER BY bm25(memories_fts) LIMIT ? OFFSET ?`,e,t,n,r).map(tt)}catch{let s=`%${e}%`;return y.query(t,`SELECT * FROM memories
488
492
  WHERE project_id = ? AND deleted_at IS NULL
489
493
  AND (title LIKE ? OR content LIKE ?)
490
- ORDER BY updated_at DESC LIMIT ? OFFSET ?`,e,s,s,r,n).map(Q)}}async getRelevantMemories(e,t,r=5){let n=[];if(t.commandName&&n.push(t.commandName),t.params?.description&&n.push(String(t.params.description)),t.params?.task&&n.push(String(t.params.task)),t.params?.feature&&n.push(String(t.params.feature)),n.length===0)return y.query(e,"SELECT * FROM memories WHERE project_id = ? AND deleted_at IS NULL ORDER BY updated_at DESC LIMIT ?",e,r).map(Q);let s=n.join(" ");try{return y.query(e,`SELECT m.* FROM memories m
494
+ ORDER BY updated_at DESC LIMIT ? OFFSET ?`,t,s,s,n,r).map(tt)}}async getRelevantMemories(t,e,n=5){let r=[];if(e.commandName&&r.push(e.commandName),e.params?.description&&r.push(String(e.params.description)),e.params?.task&&r.push(String(e.params.task)),e.params?.feature&&r.push(String(e.params.feature)),r.length===0)return y.query(t,"SELECT * FROM memories WHERE project_id = ? AND deleted_at IS NULL ORDER BY updated_at DESC LIMIT ?",t,n).map(tt);let s=r.join(" ");try{return y.query(t,`SELECT m.* FROM memories m
491
495
  JOIN memories_fts fts ON m.rowid = fts.rowid
492
496
  WHERE memories_fts MATCH ? AND m.project_id = ? AND m.deleted_at IS NULL
493
- ORDER BY bm25(memories_fts) LIMIT ?`,s,e,r).map(Q)}catch{return y.query(e,"SELECT * FROM memories WHERE project_id = ? AND deleted_at IS NULL ORDER BY updated_at DESC LIMIT ?",e,r).map(Q)}}async getRelevantMemoriesWithMetrics(e,t){let n=y.get(e,"SELECT COUNT(*) as count FROM memories WHERE project_id = ? AND deleted_at IS NULL",e)?.count??0;if(n===0)return{memories:[],metrics:{totalMemories:0,memoriesConsidered:0,memoriesReturned:0,filteringRatio:0,avgRelevanceScore:0}};let s=t.maxResults??10,i={};t.commandName&&(i.commandName=t.commandName),t.taskDescription&&(i.params={description:t.taskDescription});let c=(await this.getRelevantMemories(e,i,s)).map((p,m)=>({...p,relevanceScore:Math.max(10,100-m*10),scoreBreakdown:{domainMatch:0,tagMatch:0,recency:0,confidence:0,keywords:Math.max(10,100-m*10),userTriggered:p.userTriggered?5:0}})),l=c.length>0?Math.round(c.reduce((p,m)=>p+m.relevanceScore,0)/c.length):0;return{memories:c,metrics:{totalMemories:n,memoriesConsidered:n,memoriesReturned:c.length,filteringRatio:n>0?c.length/n:0,avgRelevanceScore:l}}}async autoRemember(e,t,r,n=""){let i={commit_footer:[J.COMMIT_STYLE],branch_naming:[J.BRANCH_NAMING],test_before_ship:[J.TEST_BEHAVIOR,J.SHIP_WORKFLOW],preferred_agent:[J.AGENT_PREFERENCE],code_style:[J.CODE_STYLE],verbosity:[J.OUTPUT_VERBOSITY]}[t]||[];await this.createMemory(e,{title:`Preference: ${t}`,content:`${t}: ${r}${n?`
494
- Context: ${n}`:""}`,tags:i,userTriggered:!0,topicKey:`preference:${t}`})}async findSimilar(e,t,r=5){let n=await this.getMemoryById(e,t);if(!n)return[];let s=n.title.split(/\s+/).filter(a=>a.length>2).slice(0,8);if(s.length===0)return[];let i=s.join(" OR ");try{return y.query(e,`SELECT m.* FROM memories m
497
+ ORDER BY bm25(memories_fts) LIMIT ?`,s,t,n).map(tt)}catch{return y.query(t,"SELECT * FROM memories WHERE project_id = ? AND deleted_at IS NULL ORDER BY updated_at DESC LIMIT ?",t,n).map(tt)}}async getRelevantMemoriesWithMetrics(t,e){let r=y.get(t,"SELECT COUNT(*) as count FROM memories WHERE project_id = ? AND deleted_at IS NULL",t)?.count??0;if(r===0)return{memories:[],metrics:{totalMemories:0,memoriesConsidered:0,memoriesReturned:0,filteringRatio:0,avgRelevanceScore:0}};let s=e.maxResults??10,i={};e.commandName&&(i.commandName=e.commandName),e.taskDescription&&(i.params={description:e.taskDescription});let c=(await this.getRelevantMemories(t,i,s)).map((p,m)=>({...p,relevanceScore:Math.max(10,100-m*10),scoreBreakdown:{domainMatch:0,tagMatch:0,recency:0,confidence:0,keywords:Math.max(10,100-m*10),userTriggered:p.userTriggered?5:0}})),l=c.length>0?Math.round(c.reduce((p,m)=>p+m.relevanceScore,0)/c.length):0;return{memories:c,metrics:{totalMemories:r,memoriesConsidered:r,memoriesReturned:c.length,filteringRatio:r>0?c.length/r:0,avgRelevanceScore:l}}}async autoRemember(t,e,n,r=""){let i={commit_footer:[Z.COMMIT_STYLE],branch_naming:[Z.BRANCH_NAMING],test_before_ship:[Z.TEST_BEHAVIOR,Z.SHIP_WORKFLOW],preferred_agent:[Z.AGENT_PREFERENCE],code_style:[Z.CODE_STYLE],verbosity:[Z.OUTPUT_VERBOSITY]}[e]||[];await this.createMemory(t,{title:`Preference: ${e}`,content:`${e}: ${n}${r?`
498
+ Context: ${r}`:""}`,tags:i,userTriggered:!0,topicKey:`preference:${e}`})}async findSimilar(t,e,n=5){let r=await this.getMemoryById(t,e);if(!r)return[];let s=r.title.split(/\s+/).filter(a=>a.length>2).slice(0,8);if(s.length===0)return[];let i=s.join(" OR ");try{return y.query(t,`SELECT m.* FROM memories m
495
499
  JOIN memories_fts fts ON m.rowid = fts.rowid
496
500
  WHERE memories_fts MATCH ? AND m.project_id = ? AND m.deleted_at IS NULL AND m.id != ?
497
- ORDER BY bm25(memories_fts) LIMIT ?`,i,e,t,r).map(Q)}catch{return[]}}async consolidateMemories(e){let t={merged:0,groups:[]},r=y.query(e,`SELECT title, COUNT(*) as cnt FROM memories
501
+ ORDER BY bm25(memories_fts) LIMIT ?`,i,t,e,n).map(tt)}catch{return[]}}async consolidateMemories(t){let e={merged:0,groups:[]},n=y.query(t,`SELECT title, COUNT(*) as cnt FROM memories
498
502
  WHERE project_id = ? AND deleted_at IS NULL
499
- GROUP BY title HAVING cnt > 1`,e),n=f();for(let s of r){let i=y.query(e,`SELECT * FROM memories
503
+ GROUP BY title HAVING cnt > 1`,t),r=f();for(let s of n){let i=y.query(t,`SELECT * FROM memories
500
504
  WHERE project_id = ? AND title = ? AND deleted_at IS NULL
501
- ORDER BY updated_at DESC`,e,s.title);if(i.length<2)continue;let[a,...c]=i,l=[a.content,...c.filter(g=>g.content!==a.content).map(g=>g.content)].filter((g,h,R)=>R.indexOf(g)===h).join(`
505
+ ORDER BY updated_at DESC`,t,s.title);if(i.length<2)continue;let[a,...c]=i,l=[a.content,...c.filter(g=>g.content!==a.content).map(g=>g.content)].filter((g,h,A)=>A.indexOf(g)===h).join(`
502
506
 
503
507
  ---
504
508
 
505
- `),p=new Set;for(let g of i)if(g.tags)for(let h of g.tags.split(",").filter(Boolean))p.add(h);(l!==a.content||p.size>0)&&y.run(e,"UPDATE memories SET content = ?, tags = ?, revision_count = revision_count + 1, updated_at = ? WHERE id = ?",l,Array.from(p).join(","),n,a.id);let m=[];for(let g of c)y.run(e,"UPDATE memories SET deleted_at = ? WHERE id = ?",n,g.id),m.push(g.id);t.merged+=c.length,t.groups.push({kept:a.id,merged:m})}return t}async getMemoryById(e,t){let r=y.get(e,"SELECT * FROM memories WHERE id = ? AND project_id = ? AND deleted_at IS NULL",t,e);return r?Q(r):null}async getAllMemories(e){return y.query(e,"SELECT * FROM memories WHERE project_id = ? AND deleted_at IS NULL ORDER BY updated_at DESC",e).map(Q)}async getMemoryStats(e){let t=y.query(e,"SELECT * FROM memories WHERE project_id = ? AND deleted_at IS NULL",e),r={};for(let n of t){let s=n.tags?n.tags.split(",").filter(Boolean):[];for(let i of s)r[i]=(r[i]||0)+1}return{totalMemories:t.length,userTriggered:t.filter(n=>n.user_triggered===1).length,tagCounts:r,oldestMemory:t[t.length-1]?.created_at,newestMemory:t[0]?.created_at}}async loadMemories(e){return{version:1,memories:await this.getAllMemories(e),index:{}}}async saveMemories(e){}reset(){}};var Ee=class{static{u(this,"MemorySystem")}_semanticMemories;_patternStore;_historyStore;_sessionStore;constructor(){this._semanticMemories=new q,this._patternStore=new lt,this._historyStore=new $t,this._sessionStore=new Lt}loadMemories(e){return this._semanticMemories.loadMemories(e)}saveMemories(e){return this._semanticMemories.saveMemories(e)}createMemory(e,t){return this._semanticMemories.createMemory(e,t)}updateMemory(e,t,r){return this._semanticMemories.updateMemory(e,t,r)}deleteMemory(e,t){return this._semanticMemories.deleteMemory(e,t)}findByTags(e,t,r){return this._semanticMemories.findByTags(e,t,r)}searchMemories(e,t){return this._semanticMemories.searchMemories(e,t)}getRelevantMemories(e,t,r){return this._semanticMemories.getRelevantMemories(e,t,r)}autoRemember(e,t,r,n){return this._semanticMemories.autoRemember(e,t,r,n)}getAllMemories(e){return this._semanticMemories.getAllMemories(e)}findSimilar(e,t,r){return this._semanticMemories.findSimilar(e,t,r)}consolidateMemories(e){return this._semanticMemories.consolidateMemories(e)}getMemoryStats(e){return this._semanticMemories.getMemoryStats(e)}getRelevantMemoriesWithMetrics(e,t){return this._semanticMemories.getRelevantMemoriesWithMetrics(e,t)}setSession(e,t){this._sessionStore.setSession(e,t)}getSession(e){return this._sessionStore.getSession(e)}clearSession(){this._sessionStore.clearSession()}loadPatterns(e){return this._patternStore.loadPatterns(e)}savePatterns(e){return this._patternStore.savePatterns(e)}recordDecision(e,t,r,n){return this._patternStore.recordDecision(e,t,r,n)}getDecision(e,t){return this._patternStore.getDecision(e,t)}hasPattern(e,t){return this._patternStore.hasPattern(e,t)}recordWorkflow(e,t,r){return this._patternStore.recordWorkflow(e,t,r)}getWorkflow(e,t){return this._patternStore.getWorkflow(e,t)}setPreference(e,t,r,n){return this._patternStore.setPreference(e,t,r,n)}getPreference(e,t,r){return this._patternStore.getPreference(e,t,r)}confirmPreference(e,t){return this._patternStore.confirmPreference(e,t)}confirmDecision(e,t){return this._patternStore.confirmDecision(e,t)}confirmWorkflow(e,t){return this._patternStore.confirmWorkflow(e,t)}getPatternsSummary(e){return this._patternStore.getPatternsSummary(e)}getPatternsSummaryDetailed(e){return this._patternStore.getPatternsSummaryDetailed(e)}archiveStaleDecisions(e){return this._patternStore.archiveStaleDecisions(e)}appendHistory(e,t){return this._historyStore.appendHistory(e,t)}getRecentHistory(e,t){return this._historyStore.getRecentHistory(e,t)}async getSmartDecision(e,t){let r=this.getSession(`decision:${t}`);if(r!==void 0)return r;let n=await this.getDecision(e,t);return n?n.value:null}async learnDecision(e,t,r,n=""){this.setSession(`decision:${t}`,r),await this.recordDecision(e,t,r,n),await this.appendHistory(e,{type:"decision",key:t,value:r,context:n})}resetState(){this._sessionStore.clearSession(),this._semanticMemories.reset(),this._patternStore.reset()}},Os=new Ee,L=Os;var we=class{static{u(this,"ContextZoneStorage")}recordTransition(e,t,r){S.run(e,`INSERT INTO context_zone_events (project_id, session_id, zone_from, zone_to, usage_percent, action, timestamp)
506
- VALUES (?, ?, ?, ?, ?, ?, ?)`,e,r??null,t.from,t.to,t.usagePercent,t.action??null,t.timestamp)}recordCompaction(e,t,r,n){S.run(e,`INSERT INTO context_compactions (project_id, format, original_turns, files_count, timestamp)
507
- VALUES (?, ?, ?, ?, ?)`,e,t,r,n,new Date().toISOString())}getTransitions(e,t=20){return S.query(e,"SELECT * FROM context_zone_events WHERE project_id = ? ORDER BY id DESC LIMIT ?",e,t).map(n=>({from:n.zone_from,to:n.zone_to,usagePercent:n.usage_percent,timestamp:n.timestamp,action:n.action}))}getSummary(e,t=7){let r=new Date(Date.now()-t*864e5).toISOString(),n=S.query(e,`SELECT zone_to, COUNT(*) as cnt FROM context_zone_events
509
+ `),p=new Set;for(let g of i)if(g.tags)for(let h of g.tags.split(",").filter(Boolean))p.add(h);(l!==a.content||p.size>0)&&y.run(t,"UPDATE memories SET content = ?, tags = ?, revision_count = revision_count + 1, updated_at = ? WHERE id = ?",l,Array.from(p).join(","),r,a.id);let m=[];for(let g of c)y.run(t,"UPDATE memories SET deleted_at = ? WHERE id = ?",r,g.id),m.push(g.id);e.merged+=c.length,e.groups.push({kept:a.id,merged:m})}return e}async getMemoryById(t,e){let n=y.get(t,"SELECT * FROM memories WHERE id = ? AND project_id = ? AND deleted_at IS NULL",e,t);return n?tt(n):null}async getAllMemories(t){return y.query(t,"SELECT * FROM memories WHERE project_id = ? AND deleted_at IS NULL ORDER BY updated_at DESC",t).map(tt)}async getMemoryStats(t){let e=y.query(t,"SELECT * FROM memories WHERE project_id = ? AND deleted_at IS NULL",t),n={};for(let r of e){let s=r.tags?r.tags.split(",").filter(Boolean):[];for(let i of s)n[i]=(n[i]||0)+1}return{totalMemories:e.length,userTriggered:e.filter(r=>r.user_triggered===1).length,tagCounts:n,oldestMemory:e[e.length-1]?.created_at,newestMemory:e[0]?.created_at}}async loadMemories(t){return{version:1,memories:await this.getAllMemories(t),index:{}}}async saveMemories(t){}reset(){}};var Se=class{static{u(this,"MemorySystem")}_semanticMemories;_patternStore;_historyStore;_sessionStore;constructor(){this._semanticMemories=new Y,this._patternStore=new pt,this._historyStore=new Ft,this._sessionStore=new $t}loadMemories(t){return this._semanticMemories.loadMemories(t)}saveMemories(t){return this._semanticMemories.saveMemories(t)}createMemory(t,e){return this._semanticMemories.createMemory(t,e)}updateMemory(t,e,n){return this._semanticMemories.updateMemory(t,e,n)}deleteMemory(t,e){return this._semanticMemories.deleteMemory(t,e)}findByTags(t,e,n){return this._semanticMemories.findByTags(t,e,n)}searchMemories(t,e){return this._semanticMemories.searchMemories(t,e)}getRelevantMemories(t,e,n){return this._semanticMemories.getRelevantMemories(t,e,n)}autoRemember(t,e,n,r){return this._semanticMemories.autoRemember(t,e,n,r)}getAllMemories(t){return this._semanticMemories.getAllMemories(t)}findSimilar(t,e,n){return this._semanticMemories.findSimilar(t,e,n)}consolidateMemories(t){return this._semanticMemories.consolidateMemories(t)}getMemoryStats(t){return this._semanticMemories.getMemoryStats(t)}getRelevantMemoriesWithMetrics(t,e){return this._semanticMemories.getRelevantMemoriesWithMetrics(t,e)}setSession(t,e){this._sessionStore.setSession(t,e)}getSession(t){return this._sessionStore.getSession(t)}clearSession(){this._sessionStore.clearSession()}loadPatterns(t){return this._patternStore.loadPatterns(t)}savePatterns(t){return this._patternStore.savePatterns(t)}recordDecision(t,e,n,r){return this._patternStore.recordDecision(t,e,n,r)}getDecision(t,e){return this._patternStore.getDecision(t,e)}hasPattern(t,e){return this._patternStore.hasPattern(t,e)}recordWorkflow(t,e,n){return this._patternStore.recordWorkflow(t,e,n)}getWorkflow(t,e){return this._patternStore.getWorkflow(t,e)}setPreference(t,e,n,r){return this._patternStore.setPreference(t,e,n,r)}getPreference(t,e,n){return this._patternStore.getPreference(t,e,n)}confirmPreference(t,e){return this._patternStore.confirmPreference(t,e)}confirmDecision(t,e){return this._patternStore.confirmDecision(t,e)}confirmWorkflow(t,e){return this._patternStore.confirmWorkflow(t,e)}getPatternsSummary(t){return this._patternStore.getPatternsSummary(t)}getPatternsSummaryDetailed(t){return this._patternStore.getPatternsSummaryDetailed(t)}archiveStaleDecisions(t){return this._patternStore.archiveStaleDecisions(t)}appendHistory(t,e){return this._historyStore.appendHistory(t,e)}getRecentHistory(t,e){return this._historyStore.getRecentHistory(t,e)}async getSmartDecision(t,e){let n=this.getSession(`decision:${e}`);if(n!==void 0)return n;let r=await this.getDecision(t,e);return r?r.value:null}async learnDecision(t,e,n,r=""){this.setSession(`decision:${e}`,n),await this.recordDecision(t,e,n,r),await this.appendHistory(t,{type:"decision",key:e,value:n,context:r})}resetState(){this._sessionStore.clearSession(),this._semanticMemories.reset(),this._patternStore.reset()}},Bs=new Se,F=Bs;var _e=class{static{u(this,"ContextZoneStorage")}recordTransition(t,e,n){S.run(t,`INSERT INTO context_zone_events (project_id, session_id, zone_from, zone_to, usage_percent, action, timestamp)
510
+ VALUES (?, ?, ?, ?, ?, ?, ?)`,t,n??null,e.from,e.to,e.usagePercent,e.action??null,e.timestamp)}recordCompaction(t,e,n,r){S.run(t,`INSERT INTO context_compactions (project_id, format, original_turns, files_count, timestamp)
511
+ VALUES (?, ?, ?, ?, ?)`,t,e,n,r,new Date().toISOString())}getTransitions(t,e=20){return S.query(t,"SELECT * FROM context_zone_events WHERE project_id = ? ORDER BY id DESC LIMIT ?",t,e).map(r=>({from:r.zone_from,to:r.zone_to,usagePercent:r.usage_percent,timestamp:r.timestamp,action:r.action}))}getSummary(t,e=7){let n=new Date(Date.now()-e*864e5).toISOString(),r=S.query(t,`SELECT zone_to, COUNT(*) as cnt FROM context_zone_events
508
512
  WHERE project_id = ? AND timestamp >= ?
509
- GROUP BY zone_to`,e,r),s={smart:0,warning:0,dumb:0},i=0;for(let l of n)s[l.zone_to]=l.cnt,i+=l.cnt;let c=S.query(e,`SELECT COUNT(*) as cnt FROM context_compactions
510
- WHERE project_id = ? AND timestamp >= ?`,e,r)[0]?.cnt??0;return i===0?{smartPercent:100,warningPercent:0,dumbPercent:0,compactions:c}:{smartPercent:Math.round(s.smart/i*100),warningPercent:Math.round(s.warning/i*100),dumbPercent:Math.round(s.dumb/i*100),compactions:c}}},be=new we;N();var ke=class{static{u(this,"LLMAnalysisStorage")}save(e,t){let r=S.getDb(e),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(t.commitHash??null,"active",JSON.stringify(t),t.analyzedAt)})()}getActive(e){let t=S.get(e,"SELECT analysis FROM llm_analysis WHERE status = 'active' LIMIT 1");return t?JSON.parse(t.analysis):null}getActiveSummary(e){let t=this.getActive(e);return t?{commitHash:t.commitHash,architectureStyle:t.architecture.style,patternCount:t.patterns.length,antiPatternCount:t.antiPatterns.length,analyzedAt:t.analyzedAt}:null}isCurrent(e,t){return t?S.get(e,"SELECT commit_hash FROM llm_analysis WHERE status = 'active' LIMIT 1")?.commit_hash===t:!1}getHistory(e,t=10){return S.query(e,"SELECT id, commit_hash, status, analyzed_at, analysis FROM llm_analysis ORDER BY id DESC LIMIT ?",t).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}})}},Ls=new ke,nt=Ls;at();function Bn(o){let e=o;e.tool("prjct_analysis_staleness","Is analysis current? How many commits behind? Shows analysis summary and history.",{projectPath:Tt.string().describe("Project directory path")},T("prjct_analysis_staleness",async t=>{let r=await w(t.projectPath),n=nt.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 W("git rev-parse HEAD",{cwd:t.projectPath});s=p.trim()}catch{}let i=s?nt.isCurrent(r,s):!1,a=0;if(s&&n.commitHash&&!i)try{let{stdout:p}=await W(`git rev-list ${n.commitHash}..HEAD --count`,{cwd:t.projectPath});a=parseInt(p.trim(),10)||0}catch{a=-1}let c=nt.getHistory(r,5),l=["## Analysis Staleness",`Status: ${i?"CURRENT":"STALE"}`];if(!i&&a>0?l.push(`Commits behind: ${a}`):!i&&a===-1&&l.push("Commits behind: unknown (commit hash not found in history)"),l.push(`
511
- ### Active Analysis`),l.push(`Architecture: ${n.architectureStyle}`),l.push(`Patterns: ${n.patternCount}`),l.push(`Anti-patterns: ${n.antiPatternCount}`),l.push(`Analyzed at: ${n.analyzedAt}`),n.commitHash&&l.push(`Commit: ${n.commitHash.slice(0,8)}`),c.length>1){l.push(`
513
+ GROUP BY zone_to`,t,n),s={smart:0,warning:0,dumb:0},i=0;for(let l of r)s[l.zone_to]=l.cnt,i+=l.cnt;let c=S.query(t,`SELECT COUNT(*) as cnt FROM context_compactions
514
+ WHERE project_id = ? AND timestamp >= ?`,t,n)[0]?.cnt??0;return i===0?{smartPercent:100,warningPercent:0,dumbPercent:0,compactions:c}:{smartPercent:Math.round(s.smart/i*100),warningPercent:Math.round(s.warning/i*100),dumbPercent:Math.round(s.dumb/i*100),compactions:c}}},xe=new _e;I();var ve=class{static{u(this,"LLMAnalysisStorage")}save(t,e){let n=S.getDb(t),r=f();n.transaction(()=>{n.prepare("UPDATE llm_analysis SET status = 'superseded', superseded_at = ? WHERE status = 'active'").run(r),n.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=S.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?S.get(t,"SELECT commit_hash FROM llm_analysis WHERE status = 'active' LIMIT 1")?.commit_hash===e:!1}getHistory(t,e=10){return S.query(t,"SELECT id, commit_hash, status, analyzed_at, analysis FROM llm_analysis ORDER BY id DESC LIMIT ?",e).map(r=>{let s=JSON.parse(r.analysis);return{id:r.id,commitHash:r.commit_hash,status:r.status,analyzedAt:r.analyzed_at,patternCount:s.patterns.length}})}},Gs=new ve,nt=Gs;at();function Jr(o){let t=o;t.tool("prjct_analysis_staleness","Is analysis current? How many commits behind? Shows analysis summary and history.",{projectPath:Et.string().describe("Project directory path")},T("prjct_analysis_staleness",async e=>{let n=await k(e.projectPath),r=nt.getActiveSummary(n);if(!r)return{content:[{type:"text",text:"No analysis exists. Run `prjct sync` to analyze."}]};let s=null;try{let{stdout:p}=await v("git rev-parse HEAD",{cwd:e.projectPath});s=p.trim()}catch{}let i=s?nt.isCurrent(n,s):!1,a=0;if(s&&r.commitHash&&!i)try{let{stdout:p}=await v(`git rev-list ${r.commitHash}..HEAD --count`,{cwd:e.projectPath});a=parseInt(p.trim(),10)||0}catch{a=-1}let c=nt.getHistory(n,5),l=["## Analysis Staleness",`Status: ${i?"CURRENT":"STALE"}`];if(!i&&a>0?l.push(`Commits behind: ${a}`):!i&&a===-1&&l.push("Commits behind: unknown (commit hash not found in history)"),l.push(`
515
+ ### Active Analysis`),l.push(`Architecture: ${r.architectureStyle}`),l.push(`Patterns: ${r.patternCount}`),l.push(`Anti-patterns: ${r.antiPatternCount}`),l.push(`Analyzed at: ${r.analyzedAt}`),r.commitHash&&l.push(`Commit: ${r.commitHash.slice(0,8)}`),c.length>1){l.push(`
512
516
  ### History (last ${c.length})`);for(let p of c)l.push(`- ${p.status} at ${p.analyzedAt} (${p.patternCount} patterns${p.commitHash?`, ${p.commitHash.slice(0,8)}`:""})`)}return{content:[{type:"text",text:l.join(`
513
- `)}]}})),e.tool("prjct_zone_health","Smart/warning/dumb zone distribution + compaction frequency",{projectPath:Tt.string().describe("Project directory path"),days:Tt.number().optional().default(7).describe("Time period in days (default 7)")},T("prjct_zone_health",async t=>{let r=await w(t.projectPath),n=be.getSummary(r,t.days),s=be.getTransitions(r,10),i=["## Context Zone Health",`Period: last ${t.days} days`,"","### Zone Distribution",`Smart: ${n.smartPercent}%`,`Warning: ${n.warningPercent}%`,`Dumb: ${n.dumbPercent}%`,`
514
- Compactions: ${n.compactions}`];if(s.length>0){i.push(`
517
+ `)}]}})),t.tool("prjct_zone_health","Smart/warning/dumb zone distribution + compaction frequency",{projectPath:Et.string().describe("Project directory path"),days:Et.number().optional().default(7).describe("Time period in days (default 7)")},T("prjct_zone_health",async e=>{let n=await k(e.projectPath),r=xe.getSummary(n,e.days),s=xe.getTransitions(n,10),i=["## Context Zone Health",`Period: last ${e.days} days`,"","### Zone Distribution",`Smart: ${r.smartPercent}%`,`Warning: ${r.warningPercent}%`,`Dumb: ${r.dumbPercent}%`,`
518
+ Compactions: ${r.compactions}`];if(s.length>0){i.push(`
515
519
  ### Recent Transitions (${s.length})`);for(let a of s){let c=a.action?` \u2192 ${a.action}`:"";i.push(`- ${a.from} \u2192 ${a.to} (${a.usagePercent}%${c}) at ${a.timestamp}`)}}return{content:[{type:"text",text:i.join(`
516
- `)}]}})),e.tool("prjct_audit_log","Recent history events (decisions, preferences, task actions)",{projectPath:Tt.string().describe("Project directory path"),limit:Tt.number().optional().default(20).describe("Max events to return (default 20)")},T("prjct_audit_log",async t=>{let r=await w(t.projectPath),n=await L.getRecentHistory(r,t.limit);if(!n||n.length===0)return{content:[{type:"text",text:"No history events found."}]};let s=[`## Audit Log (${n.length} events)`,""];for(let i of n){let a=i.type||"unknown",c=i.timestamp||"",l=Object.entries(i).filter(([p])=>p!=="type"&&p!=="timestamp").map(([p,m])=>`${p}=${typeof m=="string"?m:JSON.stringify(m)}`).join(", ");s.push(`- [${a}] ${l}${c?` (${c})`:""}`)}return{content:[{type:"text",text:s.join(`
517
- `)}]}}))}u(Bn,"registerContextTools");import{z as it}from"zod";Qt();import{z as d}from"zod";var $s=d.enum(["low","medium","high","critical"]),Ft=d.enum(["feature","bug","improvement","chore"]),Fs=d.enum(["active","backlog","previously_active"]),Us=d.enum(["pending","in_progress","completed","blocked","paused","failed","skipped"]),Xs=d.enum(["task_completed","feature_shipped","idea_captured","session_started"]),Se=d.object({title:d.string(),description:d.string(),filesChanged:d.array(d.object({path:d.string(),action:d.enum(["created","modified","deleted"])})),whatWasDone:d.array(d.string()).min(1),outputForNextAgent:d.string().min(1),notes:d.string().optional()}),Vn=d.object({output:d.string().min(1,"Subtask output is required"),summary:Se}),zn=d.object({id:d.string(),description:d.string(),domain:d.string(),agent:d.string(),status:Us,dependsOn:d.array(d.string()),startedAt:d.string().optional(),completedAt:d.string().optional(),output:d.string().optional(),summary:Se.optional(),skipReason:d.string().optional(),blockReason:d.string().optional(),estimatedPoints:d.number().optional(),estimatedMinutes:d.number().optional()}),qn=d.object({completed:d.number(),total:d.number(),percentage:d.number()}),Yn=d.object({id:d.string(),description:d.string(),type:Ft.optional(),startedAt:d.string(),sessionId:d.string(),featureId:d.string().optional(),subtasks:d.array(zn).optional(),currentSubtaskIndex:d.number().optional(),subtaskProgress:qn.optional(),linearId:d.string().optional(),linearUuid:d.string().optional(),estimatedPoints:d.number().optional(),estimatedMinutes:d.number().optional(),modelMetadata:vt.optional(),tokensIn:d.number().optional(),tokensOut:d.number().optional(),parentDescription:d.string().optional(),branch:d.string().optional(),prUrl:d.string().optional()}),Gn=d.object({id:d.string(),description:d.string(),status:d.literal("paused"),startedAt:d.string(),pausedAt:d.string(),pauseReason:d.string().optional(),type:Ft.optional(),sessionId:d.string().optional(),featureId:d.string().optional(),subtasks:d.array(zn).optional(),currentSubtaskIndex:d.number().optional(),subtaskProgress:qn.optional(),linearId:d.string().optional(),linearUuid:d.string().optional(),estimatedPoints:d.number().optional(),estimatedMinutes:d.number().optional(),modelMetadata:vt.optional(),tokensIn:d.number().optional(),tokensOut:d.number().optional()}),Ws=d.object({stackConfirmed:d.array(d.string()).optional(),patternsDiscovered:d.array(d.string()).optional(),agentAccuracy:d.array(d.object({agent:d.string(),rating:d.enum(["helpful","neutral","inaccurate"]),note:d.string().optional()})).optional(),issuesEncountered:d.array(d.string()).optional()}),Hs=d.object({taskId:d.string(),title:d.string(),classification:Ft,startedAt:d.string(),completedAt:d.string(),subtaskCount:d.number(),subtaskSummaries:d.array(Se),outcome:d.string(),branchName:d.string(),linearId:d.string().optional(),linearUuid:d.string().optional(),prUrl:d.string().optional(),feedback:Ws.optional(),tokensIn:d.number().optional(),tokensOut:d.number().optional()}),Kn=d.object({currentTask:Yn.nullable(),previousTask:Gn.nullable().optional(),pausedTasks:d.array(Gn).optional(),taskHistory:d.array(Hs).optional(),lastUpdated:d.string()}),Jn=d.object({id:d.string(),description:d.string(),priority:$s,type:Ft,featureId:d.string().optional(),originFeature:d.string().optional(),completed:d.boolean(),completedAt:d.string().optional(),createdAt:d.string(),section:Fs,agent:d.string().optional(),groupName:d.string().optional(),groupId:d.string().optional()}),Qn=d.object({tasks:d.array(Jn),lastUpdated:d.string()}),Bs=d.object({tasksToday:d.number(),tasksThisWeek:d.number(),streak:d.number(),velocity:d.string(),avgDuration:d.string()}),Gs=d.object({type:Xs,description:d.string(),timestamp:d.string(),duration:d.string().optional()}),Vc=d.object({projectId:d.string(),currentTask:Yn.nullable(),queue:d.array(Jn),stats:Bs,recentActivity:d.array(Gs),lastSync:d.string()});N();var Et={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"}},_e=class{static{u(this,"WorkflowStateMachine")}getCurrentState(e){let t=e?.currentTask;if(!t)return(e?.pausedTasks?.length||0)>0||e?.previousTask?.status==="paused"?"paused":"idle";switch((typeof t.status=="string"?t.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 t?"working":"idle"}}canTransition(e,t){let r=Et[e];if(r.transitions.includes(t))return{valid:!0};let n=r.transitions.map(s=>`p. ${s}`).join(", ");return{valid:!1,error:`Cannot run 'p. ${t}' in ${e} state`,suggestion:`Valid commands: ${n}`}}getNextState(e,t){switch(t){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 e;default:return e}}getStateInfo(e){return Et[e]}getPrompt(e){return Et[e].prompt}getValidCommands(e){return Et[e].transitions}formatNextSteps(e){return Et[e].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}`}})}},xe=new _e;N();var Zn={SHIPPED_RETENTION_DAYS:90,IDEA_DORMANT_DAYS:180,QUEUE_COMPLETED_DAYS:7,PAUSED_TASK_DAYS:30,MEMORY_MAX_ENTRIES:500},ve=class{static{u(this,"ArchiveStorage")}archive(e,t){let r=O(),n=f();return S.run(e,"INSERT INTO archives (id, entity_type, entity_id, entity_data, summary, archived_at, reason) VALUES (?, ?, ?, ?, ?, ?, ?)",r,t.entityType,t.entityId,JSON.stringify(t.entityData),t.summary??null,n,t.reason),r}archiveMany(e,t){if(t.length===0)return 0;let r=f();return S.transaction(e,n=>{let s=n.prepare("INSERT INTO archives (id, entity_type, entity_id, entity_data, summary, archived_at, reason) VALUES (?, ?, ?, ?, ?, ?, ?)");for(let i of t)s.run(O(),i.entityType,i.entityId,JSON.stringify(i.entityData),i.summary??null,r,i.reason)}),t.length}getArchived(e,t,r=50){return t?S.query(e,"SELECT * FROM archives WHERE entity_type = ? ORDER BY archived_at DESC LIMIT ?",t,r):S.query(e,"SELECT * FROM archives ORDER BY archived_at DESC LIMIT ?",r)}getStats(e){let t=S.query(e,"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 t){let s=n.entity_type;s in r&&(r[s]=n.count),r.total+=n.count}return r}restore(e,t){let r=S.get(e,"SELECT * FROM archives WHERE id = ?",t);return r?(S.run(e,"DELETE FROM archives WHERE id = ?",t),JSON.parse(r.entity_data)):null}pruneOldArchives(e,t){let r=new Date(Date.now()-t*24*60*60*1e3).toISOString(),n=this.getTotalCount(e);S.run(e,"DELETE FROM archives WHERE archived_at < ?",r);let s=this.getTotalCount(e);return n-s}getTotalCount(e){return S.get(e,"SELECT COUNT(*) as count FROM archives")?.count??0}},Ut=new ve;N();tt();var Pe=class{static{u(this,"SyncEventBus")}async publish(e){let t=v.getSyncPendingPath(e.projectId),r=await xt(t,[])??[];r.push(e),await K(t,r)}async getPending(e){let t=v.getSyncPendingPath(e);return await xt(t,[])??[]}async clearPending(e){let t=v.getSyncPendingPath(e);await K(t,[])}async updateLastSync(e){let t=v.getLastSyncPath(e),r={timestamp:f(),success:!0};await K(t,r)}async getLastSync(e){let t=v.getLastSyncPath(e);return await xt(t,null)}},tr=new Pe;Zt();N();var pt=class{static{u(this,"StorageManager")}filename;cache;constructor(e,t){this.filename=e,this.cache=new Pt({ttl:5e3,maxSize:50})}getStoreKey(){return this.filename.replace(".json","")}async read(e){let t=this.cache.get(e);if(t!==null)return t;try{let r=S.getDoc(e,this.getStoreKey());if(r!==null)return this.cache.set(e,r),r}catch{}return this.getDefault()}async write(e,t){S.setDoc(e,this.getStoreKey(),t),this.cache.set(e,t)}async update(e,t){let r=await this.read(e),n=t(r);return await this.write(e,n),n}async publishEvent(e,t,r){let n={type:t,path:[this.filename.replace(".json","")],data:r,timestamp:f(),projectId:e};await tr.publish(n)}async publishEntityEvent(e,t,r,n){let s=`${t}.${r}`,i={...n,timestamp:f()};await this.publishEvent(e,s,i)}async exists(e){try{return S.hasDoc(e,this.getStoreKey())}catch{return!1}}clearCache(e){e?this.cache.delete(e):this.cache.clear()}getCacheStats(){return this.cache.stats()}};var Re=class extends pt{static{u(this,"StateStorage")}constructor(){super("state.json",Kn)}getDefault(){return{currentTask:null,previousTask:null,pausedTasks:[],taskHistory:[],lastUpdated:""}}getEventType(e){return`state.${e}d`}validateTransition(e,t){let r=xe.getCurrentState(e),n=xe.canTransition(r,t);if(!n.valid)throw new Error(`${n.error}. ${n.suggestion||""}`.trim())}async getCurrentTask(e){return(await this.read(e)).currentTask}async startTask(e,t){let r=await this.read(e);this.validateTransition(r,"task");let n={...t,startedAt:f()};return await this.update(e,s=>({...s,currentTask:n,lastUpdated:f()})),await this.publishEvent(e,"task.started",{taskId:n.id,description:n.description,startedAt:n.startedAt,sessionId:n.sessionId}),n}async updateCurrentTask(e,t){let r=await this.read(e);if(!r.currentTask)return null;let n={...r.currentTask,...t};return await this.update(e,s=>({...s,currentTask:n,lastUpdated:f()})),n}async completeTask(e,t){let r=await this.read(e),n=r.currentTask;if(!n)return null;this.validateTransition(r,"done");let s=f(),i=this.createTaskHistoryEntry(n,s,t),a=this.getTaskHistoryFromState(r),c=[i,...a].slice(0,this.maxTaskHistory);return await this.update(e,l=>({...l,currentTask:null,previousTask:null,taskHistory:c,lastUpdated:s})),await this.publishEvent(e,"task.completed",{taskId:n.id,description:n.description,startedAt:n.startedAt,completedAt:s}),n}createTaskHistoryEntry(e,t,r){let n=(e.subtasks||[]).filter(a=>a.status==="completed"&&a.summary).map(a=>a.summary),s=n.length>0?n.map(a=>a.title).join(", "):"Task completed",i={taskId:e.id,title:e.parentDescription||e.description,classification:e.type||"improvement",startedAt:e.startedAt,completedAt:t,subtaskCount:e.subtasks?.length||0,subtaskSummaries:n,outcome:s,branchName:e.branch||"unknown",linearId:e.linearId,linearUuid:e.linearUuid,prUrl:e.prUrl};return r&&(i.feedback=r),e.tokensIn&&(i.tokensIn=e.tokensIn),e.tokensOut&&(i.tokensOut=e.tokensOut),i}maxPausedTasks=5;maxTaskHistory=20;stalenessThresholdDays=30;async pauseTask(e,t){let r=await this.read(e);if(!r.currentTask)return null;this.validateTransition(r,"pause");let n={...r.currentTask,status:"paused",pausedAt:f(),pauseReason:t},s=this.getPausedTasksFromState(r),i=[n,...s].slice(0,this.maxPausedTasks);return await this.update(e,a=>({...a,currentTask:null,previousTask:null,pausedTasks:i,lastUpdated:f()})),await this.publishEvent(e,"task.paused",{taskId:n.id,description:n.description,pausedAt:n.pausedAt,reason:t,pausedCount:i.length}),n}async resumeTask(e,t){let r=await this.read(e),n=this.getPausedTasksFromState(r);if(n.length===0)return null;this.validateTransition(r,"resume");let s=0;if(t&&(s=n.findIndex(h=>h.id===t),s===-1))return null;let i=n[s],a=n.filter((h,R)=>R!==s),{status:c,pausedAt:l,pauseReason:p,...m}=i,g={...m,startedAt:f(),sessionId:i.sessionId??O()};return await this.update(e,h=>({...h,currentTask:g,previousTask:null,pausedTasks:a,lastUpdated:f()})),await this.publishEvent(e,"task.resumed",{taskId:g.id,description:g.description,resumedAt:g.startedAt,remainingPaused:a.length}),g}getPausedTasksFromState(e){return e.pausedTasks&&e.pausedTasks.length>0?e.pausedTasks:e.previousTask?[e.previousTask]:[]}getTaskHistoryFromState(e){return e.taskHistory||[]}async getStalePausedTasks(e){let t=await this.read(e),r=this.getPausedTasksFromState(t),n=Date.now()-this.stalenessThresholdDays*24*60*60*1e3;return r.filter(s=>new Date(s.pausedAt).getTime()<n)}async archiveStalePausedTasks(e){let t=await this.read(e),r=this.getPausedTasksFromState(t),n=Date.now()-this.stalenessThresholdDays*24*60*60*1e3,s=r.filter(a=>new Date(a.pausedAt).getTime()<n),i=r.filter(a=>new Date(a.pausedAt).getTime()>=n);if(s.length===0)return[];Ut.archiveMany(e,s.map(a=>({entityType:"paused_task",entityId:a.id,entityData:a,summary:a.description,reason:"staleness"}))),await this.update(e,a=>({...a,pausedTasks:i,previousTask:null,lastUpdated:f()}));for(let a of s)await this.publishEvent(e,"task.archived",{taskId:a.id,description:a.description,pausedAt:a.pausedAt,reason:"staleness"});return s}async clearTask(e){await this.update(e,()=>({currentTask:null,previousTask:null,pausedTasks:[],lastUpdated:f()}))}async hasTask(e){let t=await this.read(e),r=this.getPausedTasksFromState(t);return t.currentTask!==null||r.length>0}async getPausedTask(e){let t=await this.read(e);return this.getPausedTasksFromState(t)[0]||null}async getAllPausedTasks(e){let t=await this.read(e);return this.getPausedTasksFromState(t)}async getTaskHistory(e){let t=await this.read(e);return this.getTaskHistoryFromState(t)}async getMostRecentTask(e){let t=await this.read(e);return this.getTaskHistoryFromState(t)[0]||null}async getTaskHistoryByType(e,t){let r=await this.read(e);return this.getTaskHistoryFromState(r).filter(s=>s.classification===t)}async getAggregatedFeedback(e){let r=(await this.getTaskHistory(e)).filter(g=>g.feedback),n=[],s=[],i=[],a=[];for(let g of r){let h=g.feedback;h.stackConfirmed&&n.push(...h.stackConfirmed),h.patternsDiscovered&&s.push(...h.patternsDiscovered),h.agentAccuracy&&i.push(...h.agentAccuracy),h.issuesEncountered&&a.push(...h.issuesEncountered)}let c=[...new Set(n)],l=[...new Set(s)],p=new Map;for(let g of a)p.set(g,(p.get(g)||0)+1);let m=[...p.entries()].filter(([g,h])=>h>=2).map(([g])=>g);return{stackConfirmed:c,patternsDiscovered:l,agentAccuracy:i,issuesEncountered:[...new Set(a)],knownGotchas:m}}async addTokens(e,t,r){let n=await this.read(e);if(!n.currentTask)return null;let s=(n.currentTask.tokensIn||0)+t,i=(n.currentTask.tokensOut||0)+r;return await this.update(e,a=>({...a,currentTask:{...a.currentTask,tokensIn:s,tokensOut:i},lastUpdated:f()})),{tokensIn:s,tokensOut:i}}async createSubtasks(e,t){let r=await this.read(e);if(!r.currentTask)return;let n=t.map((s,i)=>({...s,status:i===0?"in_progress":"pending",startedAt:i===0?f():void 0,dependsOn:s.dependsOn||[]}));await this.update(e,s=>({...s,currentTask:{...s.currentTask,subtasks:n,currentSubtaskIndex:0,subtaskProgress:{completed:0,total:n.length,percentage:0}},lastUpdated:f()})),await this.publishEvent(e,"subtasks.created",{taskId:r.currentTask.id,subtaskCount:n.length,subtasks:n.map(s=>({id:s.id,description:s.description,domain:s.domain}))})}async completeSubtask(e,t){let r=Vn.safeParse(t);if(!r.success){let R=r.error.issues.map(E=>`${E.path.join(".")}: ${E.message}`);throw new Error(`Subtask completion requires handoff data:
518
- ${R.join(`
519
- `)}`)}let{output:n,summary:s}=r.data,i=await this.read(e);if(!i.currentTask?.subtasks)return null;let a=i.currentTask.currentSubtaskIndex||0,c=i.currentTask.subtasks[a];if(!c)return null;let l=[...i.currentTask.subtasks];l[a]={...c,status:"completed",completedAt:f(),output:n,summary:s};let p=l.filter(R=>R.status==="completed").length,m=l.length,g=Math.round(p/m*100),h=a+1;return h<l.length&&(l[h]={...l[h],status:"in_progress",startedAt:f()}),await this.update(e,R=>({...R,currentTask:{...R.currentTask,subtasks:l,currentSubtaskIndex:h<m?h:a,subtaskProgress:{completed:p,total:m,percentage:g}},lastUpdated:f()})),await this.publishEvent(e,"subtask.completed",{taskId:i.currentTask.id,subtaskId:c.id,description:c.description,output:n,handoff:s.outputForNextAgent,filesChanged:s.filesChanged.length,progress:{completed:p,total:m,percentage:g}}),h<m?l[h]:null}async getCurrentSubtask(e){let t=await this.read(e);if(!t.currentTask?.subtasks)return null;let r=t.currentTask.currentSubtaskIndex||0;return t.currentTask.subtasks[r]||null}async getNextSubtask(e){let t=await this.read(e);if(!t.currentTask?.subtasks)return null;let r=(t.currentTask.currentSubtaskIndex||0)+1;return t.currentTask.subtasks[r]||null}async getPreviousSubtask(e){let t=await this.read(e);if(!t.currentTask?.subtasks)return null;let r=(t.currentTask.currentSubtaskIndex||0)-1;return r<0?null:t.currentTask.subtasks[r]||null}async getPreviousHandoff(e){let t=await this.getPreviousSubtask(e);return t?.summary?.outputForNextAgent?{fromSubtask:t.description,outputForNextAgent:t.summary.outputForNextAgent,filesChanged:t.summary.filesChanged,whatWasDone:t.summary.whatWasDone}:null}async getSubtasks(e){return(await this.read(e)).currentTask?.subtasks||[]}async getSubtaskProgress(e){return(await this.read(e)).currentTask?.subtaskProgress||null}async hasSubtasks(e){return((await this.read(e)).currentTask?.subtasks?.length||0)>0}async areAllSubtasksComplete(e){let t=await this.read(e);return t.currentTask?.subtasks?t.currentTask.subtasks.every(r=>r.status==="completed"||r.status==="failed"||r.status==="skipped"):!0}async failSubtask(e,t){let r=await this.read(e);if(!r.currentTask?.subtasks)return null;let n=r.currentTask.currentSubtaskIndex||0,s=r.currentTask.subtasks[n];if(!s)return null;let i=[...r.currentTask.subtasks];i[n]={...s,status:"failed",completedAt:f(),output:`Failed: ${t}`};let a=n+1,c=i.length;a<c&&(i[a]={...i[a],status:"in_progress",startedAt:f()});let l=i.filter(m=>m.status==="completed"||m.status==="failed"||m.status==="skipped").length,p=Math.round(l/c*100);return await this.update(e,m=>({...m,currentTask:{...m.currentTask,subtasks:i,currentSubtaskIndex:a<c?a:n,subtaskProgress:{completed:l,total:c,percentage:p}},lastUpdated:f()})),await this.publishEvent(e,"subtask.failed",{taskId:r.currentTask.id,subtaskId:s.id,description:s.description,error:t}),a<c?i[a]:null}async skipSubtask(e,t){let r=await this.read(e);if(!r.currentTask?.subtasks)return null;let n=r.currentTask.currentSubtaskIndex||0,s=r.currentTask.subtasks[n];if(!s)return null;let i=[...r.currentTask.subtasks];i[n]={...s,status:"skipped",completedAt:f(),output:`Skipped: ${t}`,skipReason:t};let a=n+1,c=i.length;a<c&&(i[a]={...i[a],status:"in_progress",startedAt:f()});let l=i.filter(m=>m.status==="completed"||m.status==="failed"||m.status==="skipped").length,p=Math.round(l/c*100);return await this.update(e,m=>({...m,currentTask:{...m.currentTask,subtasks:i,currentSubtaskIndex:a<c?a:n,subtaskProgress:{completed:l,total:c,percentage:p}},lastUpdated:f()})),await this.publishEvent(e,"subtask.skipped",{taskId:r.currentTask.id,subtaskId:s.id,description:s.description,reason:t}),a<c?i[a]:null}async blockSubtask(e,t){let r=await this.read(e);if(!r.currentTask?.subtasks)return null;let n=r.currentTask.currentSubtaskIndex||0,s=r.currentTask.subtasks[n];if(!s)return null;let i=[...r.currentTask.subtasks];i[n]={...s,status:"blocked",output:`Blocked: ${t}`,blockReason:t};let a=n+1,c=i.length;return a<c&&(i[a]={...i[a],status:"in_progress",startedAt:f()}),await this.update(e,l=>({...l,currentTask:{...l.currentTask,subtasks:i,currentSubtaskIndex:a<c?a:n},lastUpdated:f()})),await this.publishEvent(e,"subtask.blocked",{taskId:r.currentTask.id,subtaskId:s.id,description:s.description,blocker:t}),a<c?i[a]:null}},U=new Re;ot();at();import Vs from"node:fs/promises";import Xt from"node:path";var zs={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"]},qs=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".py",".go",".rs",".java",".kt",".swift",".rb",".php",".c",".cpp",".h",".hpp",".cs",".vue",".svelte"]),Ys=new Set(["node_modules",".git","dist","build",".next",".nuxt",".output","coverage",".cache","__pycache__",".pytest_cache","vendor","target",".turbo",".vercel"]);async function er(o,e,t={}){let r=Date.now(),n=t.maxFiles??30,s=t.minScore??.1,i=t.includeTests??!1,a=Ks(o),c=await Js(e),l=await Qs(e),p=[];for(let g of c){if(!i&&to(g))continue;let h=Zs(g,a,l,t.historicalBoosts);h.score>=s&&p.push(h)}p.sort((g,h)=>h.score-g.score);let m=p.slice(0,n);return{files:m,metrics:{filesScanned:c.length,filesReturned:m.length,scanDuration:Date.now()-r}}}u(er,"findRelevantFiles");function Ks(o){let e=o.toLowerCase().split(/[^a-z0-9]+/).filter(Boolean),t=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 e.filter(r=>!t.has(r)&&r.length>2)}u(Ks,"extractKeywords");async function Js(o){let e=[];async function t(r,n=""){try{let s=await Vs.readdir(r,{withFileTypes:!0});for(let i of s){let a=Xt.join(r,i.name),c=Xt.join(n,i.name);if(i.isDirectory()){if(Ys.has(i.name)||i.name.startsWith("."))continue;await t(a,c)}else if(i.isFile()){let l=Xt.extname(i.name).toLowerCase();qs.has(l)&&e.push(c)}}}catch(s){M(s)}}return u(t,"walk"),await t(o),e}u(Js,"getAllCodeFiles");async function Qs(o){let e=new Map;try{let{stdout:t}=await W(`git log -30 --pretty=format:"%H %ct" --name-only | awk '
520
+ `)}]}})),t.tool("prjct_audit_log","Recent history events (decisions, preferences, task actions)",{projectPath:Et.string().describe("Project directory path"),limit:Et.number().optional().default(20).describe("Max events to return (default 20)")},T("prjct_audit_log",async e=>{let n=await k(e.projectPath),r=await F.getRecentHistory(n,e.limit);if(!r||r.length===0)return{content:[{type:"text",text:"No history events found."}]};let s=[`## Audit Log (${r.length} events)`,""];for(let i of r){let a=i.type||"unknown",c=i.timestamp||"",l=Object.entries(i).filter(([p])=>p!=="type"&&p!=="timestamp").map(([p,m])=>`${p}=${typeof m=="string"?m:JSON.stringify(m)}`).join(", ");s.push(`- [${a}] ${l}${c?` (${c})`:""}`)}return{content:[{type:"text",text:s.join(`
521
+ `)}]}}))}u(Jr,"registerContextTools");import{z as ct}from"zod";te();import{z as d}from"zod";var Vs=d.enum(["low","medium","high","critical"]),Ut=d.enum(["feature","bug","improvement","chore"]),zs=d.enum(["active","backlog","previously_active"]),qs=d.enum(["pending","in_progress","completed","blocked","paused","failed","skipped"]),Ys=d.enum(["task_completed","feature_shipped","idea_captured","session_started"]),Pe=d.object({title:d.string(),description:d.string(),filesChanged:d.array(d.object({path:d.string(),action:d.enum(["created","modified","deleted"])})),whatWasDone:d.array(d.string()).min(1),outputForNextAgent:d.string().min(1),notes:d.string().optional()}),Zr=d.object({output:d.string().min(1,"Subtask output is required"),summary:Pe}),tn=d.object({id:d.string(),description:d.string(),domain:d.string(),agent:d.string(),status:qs,dependsOn:d.array(d.string()),startedAt:d.string().optional(),completedAt:d.string().optional(),output:d.string().optional(),summary:Pe.optional(),skipReason:d.string().optional(),blockReason:d.string().optional(),estimatedPoints:d.number().optional(),estimatedMinutes:d.number().optional()}),en=d.object({completed:d.number(),total:d.number(),percentage:d.number()}),Re=d.object({id:d.string(),description:d.string(),type:Ut.optional(),startedAt:d.string(),sessionId:d.string(),featureId:d.string().optional(),subtasks:d.array(tn).optional(),currentSubtaskIndex:d.number().optional(),subtaskProgress:en.optional(),linearId:d.string().optional(),linearUuid:d.string().optional(),estimatedPoints:d.number().optional(),estimatedMinutes:d.number().optional(),modelMetadata:Pt.optional(),tokensIn:d.number().optional(),tokensOut:d.number().optional(),parentDescription:d.string().optional(),branch:d.string().optional(),prUrl:d.string().optional()}),Qr=d.object({id:d.string(),description:d.string(),status:d.literal("paused"),startedAt:d.string(),pausedAt:d.string(),pauseReason:d.string().optional(),type:Ut.optional(),sessionId:d.string().optional(),featureId:d.string().optional(),subtasks:d.array(tn).optional(),currentSubtaskIndex:d.number().optional(),subtaskProgress:en.optional(),linearId:d.string().optional(),linearUuid:d.string().optional(),estimatedPoints:d.number().optional(),estimatedMinutes:d.number().optional(),modelMetadata:Pt.optional(),tokensIn:d.number().optional(),tokensOut:d.number().optional()}),Ks=d.object({stackConfirmed:d.array(d.string()).optional(),patternsDiscovered:d.array(d.string()).optional(),agentAccuracy:d.array(d.object({agent:d.string(),rating:d.enum(["helpful","neutral","inaccurate"]),note:d.string().optional()})).optional(),issuesEncountered:d.array(d.string()).optional()}),Js=d.object({taskId:d.string(),title:d.string(),classification:Ut,startedAt:d.string(),completedAt:d.string(),subtaskCount:d.number(),subtaskSummaries:d.array(Pe),outcome:d.string(),branchName:d.string(),linearId:d.string().optional(),linearUuid:d.string().optional(),prUrl:d.string().optional(),feedback:Ks.optional(),tokensIn:d.number().optional(),tokensOut:d.number().optional()}),Qs=Re.extend({workspaceId:d.string(),worktreePath:d.string().optional(),agentSessionId:d.string().optional(),jiraId:d.string().optional(),jiraUuid:d.string().optional(),dispatchedFrom:d.string().optional()}),rn=d.object({currentTask:Re.nullable(),previousTask:Qr.nullable().optional(),pausedTasks:d.array(Qr).optional(),taskHistory:d.array(Js).optional(),activeTasks:d.array(Qs).optional(),lastUpdated:d.string()}),nn=d.object({id:d.string(),description:d.string(),priority:Vs,type:Ut,featureId:d.string().optional(),originFeature:d.string().optional(),completed:d.boolean(),completedAt:d.string().optional(),createdAt:d.string(),section:zs,agent:d.string().optional(),groupName:d.string().optional(),groupId:d.string().optional()}),sn=d.object({tasks:d.array(nn),lastUpdated:d.string()}),Zs=d.object({tasksToday:d.number(),tasksThisWeek:d.number(),streak:d.number(),velocity:d.string(),avgDuration:d.string()}),to=d.object({type:Ys,description:d.string(),timestamp:d.string(),duration:d.string().optional()}),iu=d.object({projectId:d.string(),currentTask:Re.nullable(),queue:d.array(nn),stats:Zs,recentActivity:d.array(to),lastSync:d.string()});I();var kt={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"}},Ce=class{static{u(this,"WorkflowStateMachine")}getCurrentState(t,e){let n=null;if(e&&t?.activeTasks?.length&&(n=t.activeTasks.find(s=>s.workspaceId===e)),n||(n=t?.currentTask),!n)return(t?.pausedTasks?.length||0)>0||t?.previousTask?.status==="paused"?"paused":"idle";switch((typeof n.status=="string"?n.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 n?"working":"idle"}}canTransition(t,e){let n=kt[t];if(n.transitions.includes(e))return{valid:!0};let r=n.transitions.map(s=>`p. ${s}`).join(", ");return{valid:!1,error:`Cannot run 'p. ${e}' in ${t} state`,suggestion:`Valid commands: ${r}`}}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 kt[t]}getPrompt(t){return kt[t].prompt}getValidCommands(t){return kt[t].transitions}formatNextSteps(t){return kt[t].transitions.map(n=>{switch(n){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. ${n}`}})}},Ae=new Ce;I();var on={SHIPPED_RETENTION_DAYS:90,IDEA_DORMANT_DAYS:180,QUEUE_COMPLETED_DAYS:7,PAUSED_TASK_DAYS:30,MEMORY_MAX_ENTRIES:500},De=class{static{u(this,"ArchiveStorage")}archive(t,e){let n=$(),r=f();return S.run(t,"INSERT INTO archives (id, entity_type, entity_id, entity_data, summary, archived_at, reason) VALUES (?, ?, ?, ?, ?, ?, ?)",n,e.entityType,e.entityId,JSON.stringify(e.entityData),e.summary??null,r,e.reason),n}archiveMany(t,e){if(e.length===0)return 0;let n=f();return S.transaction(t,r=>{let s=r.prepare("INSERT INTO archives (id, entity_type, entity_id, entity_data, summary, archived_at, reason) VALUES (?, ?, ?, ?, ?, ?, ?)");for(let i of e)s.run($(),i.entityType,i.entityId,JSON.stringify(i.entityData),i.summary??null,n,i.reason)}),e.length}getArchived(t,e,n=50){return e?S.query(t,"SELECT * FROM archives WHERE entity_type = ? ORDER BY archived_at DESC LIMIT ?",e,n):S.query(t,"SELECT * FROM archives ORDER BY archived_at DESC LIMIT ?",n)}getStats(t){let e=S.query(t,"SELECT entity_type, COUNT(*) as count FROM archives GROUP BY entity_type"),n={shipped:0,idea:0,queue_task:0,paused_task:0,memory_entry:0,total:0};for(let r of e){let s=r.entity_type;s in n&&(n[s]=r.count),n.total+=r.count}return n}restore(t,e){let n=S.get(t,"SELECT * FROM archives WHERE id = ?",e);return n?(S.run(t,"DELETE FROM archives WHERE id = ?",e),JSON.parse(n.entity_data)):null}pruneOldArchives(t,e){let n=new Date(Date.now()-e*24*60*60*1e3).toISOString(),r=this.getTotalCount(t);S.run(t,"DELETE FROM archives WHERE archived_at < ?",n);let s=this.getTotalCount(t);return r-s}getTotalCount(t){return S.get(t,"SELECT COUNT(*) as count FROM archives")?.count??0}},Wt=new De;I();Q();var je=class{static{u(this,"SyncEventBus")}async publish(t){let e=P.getSyncPendingPath(t.projectId),n=await vt(e,[])??[];n.push(t),await J(e,n)}async getPending(t){let e=P.getSyncPendingPath(t);return await vt(e,[])??[]}async clearPending(t){let e=P.getSyncPendingPath(t);await J(e,[])}async updateLastSync(t){let e=P.getLastSyncPath(t),n={timestamp:f(),success:!0};await J(e,n)}async getLastSync(t){let e=P.getLastSyncPath(t);return await vt(e,null)}},an=new je;ee();I();var dt=class{static{u(this,"StorageManager")}filename;cache;constructor(t,e){this.filename=t,this.cache=new Rt({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 n=S.getDoc(t,this.getStoreKey());if(n!==null)return this.cache.set(t,n),n}catch{}return this.getDefault()}async write(t,e){S.setDoc(t,this.getStoreKey(),e),this.cache.set(t,e)}async update(t,e){let n=await this.read(t),r=e(n);return await this.write(t,r),r}async publishEvent(t,e,n){let r={type:e,path:[this.filename.replace(".json","")],data:n,timestamp:f(),projectId:t};await an.publish(r)}async publishEntityEvent(t,e,n,r){let s=`${e}.${n}`,i={...r,timestamp:f()};await this.publishEvent(t,s,i)}async exists(t){try{return S.hasDoc(t,this.getStoreKey())}catch{return!1}}clearCache(t){t?this.cache.delete(t):this.cache.clear()}getCacheStats(){return this.cache.stats()}};var Ne=class extends dt{static{u(this,"StateStorage")}constructor(){super("state.json",rn)}getDefault(){return{currentTask:null,previousTask:null,pausedTasks:[],taskHistory:[],activeTasks:[],lastUpdated:""}}getEventType(t){return`state.${t}d`}validateTransition(t,e){let n=Ae.getCurrentState(t),r=Ae.canTransition(n,e);if(!r.valid)throw new Error(`${r.error}. ${r.suggestion||""}`.trim())}async getCurrentTask(t){return(await this.read(t)).currentTask}async startTask(t,e){let n=await this.read(t);this.validateTransition(n,"task");let r={...e,startedAt:f()};return await this.update(t,s=>({...s,currentTask:r,lastUpdated:f()})),await this.publishEvent(t,"task.started",{taskId:r.id,description:r.description,startedAt:r.startedAt,sessionId:r.sessionId}),r}async updateCurrentTask(t,e){let n=await this.read(t);if(!n.currentTask)return null;let r={...n.currentTask,...e};return await this.update(t,s=>({...s,currentTask:r,lastUpdated:f()})),r}async completeTask(t,e){let n=await this.read(t),r=n.currentTask;if(!r)return null;this.validateTransition(n,"done");let s=f(),i=this.createTaskHistoryEntry(r,s,e),a=this.getTaskHistoryFromState(n),c=[i,...a].slice(0,this.maxTaskHistory);return await this.update(t,l=>({...l,currentTask:null,previousTask:null,taskHistory:c,lastUpdated:s})),await this.publishEvent(t,"task.completed",{taskId:r.id,description:r.description,startedAt:r.startedAt,completedAt:s}),r}createTaskHistoryEntry(t,e,n){let r=(t.subtasks||[]).filter(a=>a.status==="completed"&&a.summary).map(a=>a.summary),s=r.length>0?r.map(a=>a.title).join(", "):"Task completed",i={taskId:t.id,title:t.parentDescription||t.description,classification:t.type||"improvement",startedAt:t.startedAt,completedAt:e,subtaskCount:t.subtasks?.length||0,subtaskSummaries:r,outcome:s,branchName:t.branch||"unknown",linearId:t.linearId,linearUuid:t.linearUuid,prUrl:t.prUrl};return n&&(i.feedback=n),t.tokensIn&&(i.tokensIn=t.tokensIn),t.tokensOut&&(i.tokensOut=t.tokensOut),i}maxPausedTasks=5;maxTaskHistory=20;stalenessThresholdDays=30;async pauseTask(t,e){let n=await this.read(t);if(!n.currentTask)return null;this.validateTransition(n,"pause");let r={...n.currentTask,status:"paused",pausedAt:f(),pauseReason:e},s=this.getPausedTasksFromState(n),i=[r,...s].slice(0,this.maxPausedTasks);return await this.update(t,a=>({...a,currentTask:null,previousTask:null,pausedTasks:i,lastUpdated:f()})),await this.publishEvent(t,"task.paused",{taskId:r.id,description:r.description,pausedAt:r.pausedAt,reason:e,pausedCount:i.length}),r}async resumeTask(t,e){let n=await this.read(t),r=this.getPausedTasksFromState(n);if(r.length===0)return null;this.validateTransition(n,"resume");let s=0;if(e&&(s=r.findIndex(h=>h.id===e),s===-1))return null;let i=r[s],a=r.filter((h,A)=>A!==s),{status:c,pausedAt:l,pauseReason:p,...m}=i,g={...m,startedAt:f(),sessionId:i.sessionId??$()};return await this.update(t,h=>({...h,currentTask:g,previousTask:null,pausedTasks:a,lastUpdated:f()})),await this.publishEvent(t,"task.resumed",{taskId:g.id,description:g.description,resumedAt:g.startedAt,remainingPaused:a.length}),g}getPausedTasksFromState(t){return 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),n=this.getPausedTasksFromState(e),r=Date.now()-this.stalenessThresholdDays*24*60*60*1e3;return n.filter(s=>new Date(s.pausedAt).getTime()<r)}async archiveStalePausedTasks(t){let e=await this.read(t),n=this.getPausedTasksFromState(e),r=Date.now()-this.stalenessThresholdDays*24*60*60*1e3,s=n.filter(a=>new Date(a.pausedAt).getTime()<r),i=n.filter(a=>new Date(a.pausedAt).getTime()>=r);if(s.length===0)return[];Wt.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:i,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),n=this.getPausedTasksFromState(e);return e.currentTask!==null||n.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 n=await this.read(t);return this.getTaskHistoryFromState(n).filter(s=>s.classification===e)}async getAggregatedFeedback(t){let n=(await this.getTaskHistory(t)).filter(g=>g.feedback),r=[],s=[],i=[],a=[];for(let g of n){let h=g.feedback;Array.isArray(h.stackConfirmed)&&r.push(...h.stackConfirmed),Array.isArray(h.patternsDiscovered)&&s.push(...h.patternsDiscovered),Array.isArray(h.agentAccuracy)&&i.push(...h.agentAccuracy),Array.isArray(h.issuesEncountered)&&a.push(...h.issuesEncountered)}let c=[...new Set(r)],l=[...new Set(s)],p=new Map;for(let g of a)p.set(g,(p.get(g)||0)+1);let m=[...p.entries()].filter(([g,h])=>h>=2).map(([g])=>g);return{stackConfirmed:c,patternsDiscovered:l,agentAccuracy:i,issuesEncountered:[...new Set(a)],knownGotchas:m}}async startTaskInWorkspace(t,e,n){let r={...e,workspaceId:n,startedAt:f()};return await this.update(t,s=>({...s,activeTasks:[...s.activeTasks||[],r],lastUpdated:f()})),await this.publishEvent(t,"task.started",{taskId:r.id,description:r.description,startedAt:r.startedAt,sessionId:r.sessionId,workspaceId:n}),r}async getCurrentTaskForWorkspace(t,e){return((await this.read(t)).activeTasks||[]).find(r=>r.workspaceId===e)??null}async completeTaskInWorkspace(t,e,n){let r=await this.read(t),i=(r.activeTasks||[]).find(m=>m.workspaceId===e);if(!i)return null;let a=f(),c=this.createTaskHistoryEntry(i,a,n),l=this.getTaskHistoryFromState(r),p=[c,...l].slice(0,this.maxTaskHistory);return await this.update(t,m=>({...m,activeTasks:(m.activeTasks||[]).filter(g=>g.workspaceId!==e),taskHistory:p,lastUpdated:a})),await this.publishEvent(t,"task.completed",{taskId:i.id,description:i.description,startedAt:i.startedAt,completedAt:a,workspaceId:e}),i}async getActiveTasks(t){return(await this.read(t)).activeTasks||[]}async getActiveTaskCount(t){return((await this.read(t)).activeTasks||[]).length}async updateWorkspaceTask(t,e,n){let s=(await this.read(t)).activeTasks||[],i=s.findIndex(c=>c.workspaceId===e);if(i===-1)return null;let a={...s[i],...n,workspaceId:e};return await this.update(t,c=>{let l=[...c.activeTasks||[]];return l[i]=a,{...c,activeTasks:l,lastUpdated:f()}}),a}async addTokens(t,e,n){let r=await this.read(t);if(!r.currentTask)return null;let s=(r.currentTask.tokensIn||0)+e,i=(r.currentTask.tokensOut||0)+n;return await this.update(t,a=>({...a,currentTask:{...a.currentTask,tokensIn:s,tokensOut:i},lastUpdated:f()})),{tokensIn:s,tokensOut:i}}async createSubtasks(t,e){let n=await this.read(t);if(!n.currentTask)return;let r=e.map((s,i)=>({...s,status:i===0?"in_progress":"pending",startedAt:i===0?f():void 0,dependsOn:s.dependsOn||[]}));await this.update(t,s=>({...s,currentTask:{...s.currentTask,subtasks:r,currentSubtaskIndex:0,subtaskProgress:{completed:0,total:r.length,percentage:0}},lastUpdated:f()})),await this.publishEvent(t,"subtasks.created",{taskId:n.currentTask.id,subtaskCount:r.length,subtasks:r.map(s=>({id:s.id,description:s.description,domain:s.domain}))})}async completeSubtask(t,e){let n=Zr.safeParse(e);if(!n.success){let A=n.error.issues.map(E=>`${E.path.join(".")}: ${E.message}`);throw new Error(`Subtask completion requires handoff data:
522
+ ${A.join(`
523
+ `)}`)}let{output:r,summary:s}=n.data,i=await this.read(t);if(!i.currentTask?.subtasks)return null;let a=i.currentTask.currentSubtaskIndex||0,c=i.currentTask.subtasks[a];if(!c)return null;let l=[...i.currentTask.subtasks];l[a]={...c,status:"completed",completedAt:f(),output:r,summary:s};let p=l.filter(A=>A.status==="completed").length,m=l.length,g=Math.round(p/m*100),h=a+1;return h<l.length&&(l[h]={...l[h],status:"in_progress",startedAt:f()}),await this.update(t,A=>({...A,currentTask:{...A.currentTask,subtasks:l,currentSubtaskIndex:h<m?h:a,subtaskProgress:{completed:p,total:m,percentage:g}},lastUpdated:f()})),await this.publishEvent(t,"subtask.completed",{taskId:i.currentTask.id,subtaskId:c.id,description:c.description,output:r,handoff:s.outputForNextAgent,filesChanged:s.filesChanged.length,progress:{completed:p,total:m,percentage:g}}),h<m?l[h]:null}async getCurrentSubtask(t){let e=await this.read(t);if(!e.currentTask?.subtasks)return null;let n=e.currentTask.currentSubtaskIndex||0;return e.currentTask.subtasks[n]||null}async getNextSubtask(t){let e=await this.read(t);if(!e.currentTask?.subtasks)return null;let n=(e.currentTask.currentSubtaskIndex||0)+1;return e.currentTask.subtasks[n]||null}async getPreviousSubtask(t){let e=await this.read(t);if(!e.currentTask?.subtasks)return null;let n=(e.currentTask.currentSubtaskIndex||0)-1;return n<0?null:e.currentTask.subtasks[n]||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(n=>n.status==="completed"||n.status==="failed"||n.status==="skipped"):!0}async failSubtask(t,e){let n=await this.read(t);if(!n.currentTask?.subtasks)return null;let r=n.currentTask.currentSubtaskIndex||0,s=n.currentTask.subtasks[r];if(!s)return null;let i=[...n.currentTask.subtasks];i[r]={...s,status:"failed",completedAt:f(),output:`Failed: ${e}`};let a=r+1,c=i.length;a<c&&(i[a]={...i[a],status:"in_progress",startedAt:f()});let l=i.filter(m=>m.status==="completed"||m.status==="failed"||m.status==="skipped").length,p=Math.round(l/c*100);return await this.update(t,m=>({...m,currentTask:{...m.currentTask,subtasks:i,currentSubtaskIndex:a<c?a:r,subtaskProgress:{completed:l,total:c,percentage:p}},lastUpdated:f()})),await this.publishEvent(t,"subtask.failed",{taskId:n.currentTask.id,subtaskId:s.id,description:s.description,error:e}),a<c?i[a]:null}async skipSubtask(t,e){let n=await this.read(t);if(!n.currentTask?.subtasks)return null;let r=n.currentTask.currentSubtaskIndex||0,s=n.currentTask.subtasks[r];if(!s)return null;let i=[...n.currentTask.subtasks];i[r]={...s,status:"skipped",completedAt:f(),output:`Skipped: ${e}`,skipReason:e};let a=r+1,c=i.length;a<c&&(i[a]={...i[a],status:"in_progress",startedAt:f()});let l=i.filter(m=>m.status==="completed"||m.status==="failed"||m.status==="skipped").length,p=Math.round(l/c*100);return await this.update(t,m=>({...m,currentTask:{...m.currentTask,subtasks:i,currentSubtaskIndex:a<c?a:r,subtaskProgress:{completed:l,total:c,percentage:p}},lastUpdated:f()})),await this.publishEvent(t,"subtask.skipped",{taskId:n.currentTask.id,subtaskId:s.id,description:s.description,reason:e}),a<c?i[a]:null}async blockSubtask(t,e){let n=await this.read(t);if(!n.currentTask?.subtasks)return null;let r=n.currentTask.currentSubtaskIndex||0,s=n.currentTask.subtasks[r];if(!s)return null;let i=[...n.currentTask.subtasks];i[r]={...s,status:"blocked",output:`Blocked: ${e}`,blockReason:e};let a=r+1,c=i.length;return a<c&&(i[a]={...i[a],status:"in_progress",startedAt:f()}),await this.update(t,l=>({...l,currentTask:{...l.currentTask,subtasks:i,currentSubtaskIndex:a<c?a:r},lastUpdated:f()})),await this.publishEvent(t,"subtask.blocked",{taskId:n.currentTask.id,subtaskId:s.id,description:s.description,blocker:e}),a<c?i[a]:null}},W=new Ne;it();at();import eo from"node:fs/promises";import Xt from"node:path";var ro={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"]},no=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".py",".go",".rs",".java",".kt",".swift",".rb",".php",".c",".cpp",".h",".hpp",".cs",".vue",".svelte"]),so=new Set(["node_modules",".git","dist","build",".next",".nuxt",".output","coverage",".cache","__pycache__",".pytest_cache","vendor","target",".turbo",".vercel"]);async function cn(o,t,e={}){let n=Date.now(),r=e.maxFiles??30,s=e.minScore??.1,i=e.includeTests??!1,a=oo(o),c=await io(t),l=await ao(t),p=[];for(let g of c){if(!i&&uo(g))continue;let h=co(g,a,l,e.historicalBoosts);h.score>=s&&p.push(h)}p.sort((g,h)=>h.score-g.score);let m=p.slice(0,r);return{files:m,metrics:{filesScanned:c.length,filesReturned:m.length,scanDuration:Date.now()-n}}}u(cn,"findRelevantFiles");function oo(o){let t=o.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(n=>!e.has(n)&&n.length>2)}u(oo,"extractKeywords");async function io(o){let t=[];async function e(n,r=""){try{let s=await eo.readdir(n,{withFileTypes:!0});for(let i of s){let a=Xt.join(n,i.name),c=Xt.join(r,i.name);if(i.isDirectory()){if(so.has(i.name)||i.name.startsWith("."))continue;await e(a,c)}else if(i.isFile()){let l=Xt.extname(i.name).toLowerCase();no.has(l)&&t.push(c)}}}catch(s){O(s)}}return u(e,"walk"),await e(o),t}u(io,"getAllCodeFiles");async function ao(o){let t=new Map;try{let{stdout:e}=await v(`git log -30 --pretty=format:"%H %ct" --name-only | awk '
520
524
  /^[a-f0-9]{40}/ { commit=$1; timestamp=$2; next }
521
525
  NF { files[$0]++; if (!lastmod[$0]) lastmod[$0]=timestamp }
522
526
  END { for (f in files) print files[f], lastmod[f], f }
523
- '`,{cwd:o,maxBuffer:10485760}),r=Math.floor(Date.now()/1e3),n=t.trim().split(`
524
- `).filter(Boolean);for(let s of n){let i=s.match(/^(\d+)\s+(\d+)\s+(.+)$/);if(i){let a=parseInt(i[1],10),c=parseInt(i[2],10),l=i[3],p=Math.floor((r-c)/86400);e.set(l,{commits:a,daysAgo:p})}}}catch{}return e}u(Qs,"getGitRecency");function Zs(o,e,t,r){let n=[],s=0,i=0,a=0,c=0,l=0,p=o.toLowerCase(),m=p.split("/").join(" ").split(/[^a-z0-9]+/);for(let _ of e){p.includes(_)&&(s+=.3,n.push(`keyword:${_}`));for(let X of m)if(X.includes(_)||_.includes(X)){s+=.15;break}}s=Math.min(1,s);for(let[_,X]of Object.entries(zs))for(let ft of X)if(p.includes(ft)&&e.some(Vt=>X.includes(Vt)||Vt.includes(_)||_.includes(Vt))){i+=.4,n.push(`domain:${_}`);break}i=Math.min(1,i);let g=t.get(o);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=Xt.basename(o).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(_=>_.startsWith("import:"))||n.push("import:1")),r){let _=r.get(o);_!==void 0&&(l=(_+1)/2,_>0?n.push("history:boosted"):_<0&&n.push("history:penalized"))}let E=r&&r.size>0?s*.54+i*.18+a*.13+c*.05+l*.1:s*.6+i*.2+a*.15+c*.05;return{path:o,score:Math.min(1,E),reasons:[...new Set(n)]}}u(Zs,"scoreFile");function to(o){let e=o.toLowerCase();return e.includes(".test.")||e.includes(".spec.")||e.includes("__tests__")||e.includes("__mocks__")||e.includes("/tests/")||e.includes("/test/")||e.endsWith("_test.go")||e.endsWith("_test.py")}u(to,"isTestFile");ot();import oo from"node:fs/promises";import dt from"node:path";var no={"claude-opus-4.5":{input:.005,output:.025},"claude-sonnet-4.5":{input:.003,output:.015},"claude-haiku-4.5":{input:.001,output:.005},"claude-opus-4":{input:.015,output:.075},"claude-opus-4-6":{input:.015,output:.075},"gpt-4o":{input:.0025,output:.01},"gpt-4-turbo":{input:.01,output:.03},"gpt-4o-mini":{input:15e-5,output:6e-4},"gemini-1.5-pro":{input:.00125,output:.005},"gemini-1.5-flash":{input:75e-6,output:3e-4}},ro="claude-sonnet-4.5";function Ce(o){return!o||o.length===0?0:Math.ceil(o.length/4)}u(Ce,"countTokens");var rr=["claude-sonnet-4.5","claude-opus-4.5","claude-opus-4-6","gpt-4o","gemini-1.5-pro"];function nr(o,e){let t=no[e],r=o/1e3*t.input,n=o/1e3*t.output*.3;return{inputSaved:r,outputPotential:n,total:r+n}}u(nr,"calculateModelCost");function so(o){return o<.001?"<$0.01":o<.01?`$${o.toFixed(3)}`:`$${o.toFixed(2)}`}u(so,"formatCostSaved");function sr(o,e){let t=Ce(o),r=Ce(e),n=Math.max(0,t-r),s=t>0?(t-r)/t:0,i=nr(n,ro),a=rr.map(c=>({model:c,...nr(n,c)}));return{tokens:{original:t,filtered:r,saved:n},compression:Math.max(0,Math.min(1,s)),cost:{saved:i.total,formatted:so(i.total),byModel:a}}}u(sr,"measureCompression");function Wt(o){let e=Ce(o);return{tokens:{original:e,filtered:e,saved:0},compression:0,cost:{saved:0,formatted:"$0.00",byModel:rr.map(t=>({model:t,inputSaved:0,outputPotential:0,total:0}))}}}u(Wt,"noCompression");var io={".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"},or=[{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}],ao=[{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}],co=[{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}],uo=[{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}],ir=[{type:"class",pattern:/^(?:public\s+)?(?:abstract\s+)?(?:final\s+)?class\s+(\w+)(?:<[^>]+>)?(?:\s+extends\s+\w+)?(?:\s+implements\s+[^{]+)?\s*\{/gm,nameIndex:1,exported:!0},{type:"interface",pattern:/^(?:public\s+)?interface\s+(\w+)(?:<[^>]+>)?(?:\s+extends\s+[^{]+)?\s*\{/gm,nameIndex:1,exported:!0},{type:"method",pattern:/^\s+(?:public|private|protected)?\s*(?:static\s+)?(?:final\s+)?(?:synchronized\s+)?(?:<[^>]+>\s+)?(\w+(?:<[^>]+>)?)\s+(\w+)\s*\([^)]*\)\s*(?:throws\s+[^{]+)?\s*\{/gm,nameIndex:2}],lo={typescript:or,javascript:or,python:ao,go:co,rust:uo,java:ir,csharp:ir,php:[],ruby:[],unknown:[]};async function ar(o,e=process.cwd()){let t=dt.isAbsolute(o)?o:dt.join(e,o),r=dt.resolve(e),n=dt.resolve(t);if(!n.startsWith(r+dt.sep)&&n!==r)return{file:o,language:"unknown",signatures:[],fallback:!0,fallbackReason:"Path traversal denied: file is outside project directory",metrics:Wt("")};let s;try{s=await oo.readFile(t,"utf-8")}catch(m){if(M(m))return{file:o,language:"unknown",signatures:[],fallback:!0,fallbackReason:"File not found",metrics:Wt("")};throw m}let i=dt.extname(o).toLowerCase(),a=io[i]||"unknown",c=lo[a];if(!c||c.length===0)return{file:o,language:a,signatures:[],fallback:!0,fallbackReason:`No extraction patterns for ${a}`,metrics:Wt(s)};let l=po(s,c),p=l.map(m=>`${m.exported?"export ":""}${m.type} ${m.name}: ${m.signature}`).join(`
525
- `);return{file:o,language:a,signatures:l,fallback:!1,metrics:sr(s,p)}}u(ar,"extractSignatures");function po(o,e){let t=[],r=o.split(`
526
- `),n=new Set;for(let s of e){s.pattern.lastIndex=0;let i;for(;(i=s.pattern.exec(o))!==null;){let a=i[s.nameIndex];if(!a)continue;let c=`${s.type}:${a}`;if(n.has(c))continue;n.add(c);let l=i.index,p=o.substring(0,l).split(`
527
- `).length,m=i[0].trim(),g;if(p>1){let h=r[p-2]?.trim();(h?.startsWith("/**")||h?.startsWith("///")||h?.startsWith("#"))&&(g=h)}t.push({type:s.type,name:a,signature:mo(m),exported:s.exported||!1,line:p,docstring:g})}}return t.sort((s,i)=>s.line-i.line)}u(po,"extractFromContent");function mo(o){return o.replace(/\{$/,"").replace(/\s+/g," ").trim()}u(mo,"cleanSignature");function cr(o){let e=o;e.tool("prjct_relevant_files","BM25-ranked files relevant to a query",{projectPath:it.string().describe("Project directory path"),query:it.string().describe("Task or query to find relevant files for"),maxFiles:it.number().optional().default(10).describe("Max files to return")},T("prjct_relevant_files",async t=>{let r=await er(t.query,t.projectPath,{maxFiles:t.maxFiles,minScore:.1});if(r.files.length===0)return{content:[{type:"text",text:"No relevant files found."}]};let n=r.files.map(i=>`- \`${i.path}\` (score: ${Math.round(i.score*100)}%) \u2014 ${i.reasons.join(", ")}`);return{content:[{type:"text",text:`## Relevant Files (${r.files.length}/${r.metrics.filesScanned} scanned)
528
-
529
- ${n.join(`
530
- `)}`}]}})),e.tool("prjct_signatures","Code signatures from a file (90% token reduction vs full content)",{projectPath:it.string().describe("Project directory path"),filePath:it.string().describe("Relative file path to extract signatures from")},T("prjct_signatures",async t=>{let r=await ar(t.filePath,t.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})
527
+ '`,{cwd:o,maxBuffer:10485760}),n=Math.floor(Date.now()/1e3),r=e.trim().split(`
528
+ `).filter(Boolean);for(let s of r){let i=s.match(/^(\d+)\s+(\d+)\s+(.+)$/);if(i){let a=parseInt(i[1],10),c=parseInt(i[2],10),l=i[3],p=Math.floor((n-c)/86400);t.set(l,{commits:a,daysAgo:p})}}}catch{}return t}u(ao,"getGitRecency");function co(o,t,e,n){let r=[],s=0,i=0,a=0,c=0,l=0,p=o.toLowerCase(),m=p.split("/").join(" ").split(/[^a-z0-9]+/);for(let _ of t){p.includes(_)&&(s+=.3,r.push(`keyword:${_}`));for(let X of m)if(X.includes(_)||_.includes(X)){s+=.15;break}}s=Math.min(1,s);for(let[_,X]of Object.entries(ro))for(let ht of X)if(p.includes(ht)&&t.some(zt=>X.includes(zt)||zt.includes(_)||_.includes(zt))){i+=.4,r.push(`domain:${_}`);break}i=Math.min(1,i);let g=e.get(o);g&&(g.daysAgo<=1?(a=1,r.push("recent:1d")):g.daysAgo<=3?(a=.8,r.push("recent:3d")):g.daysAgo<=7?(a=.6,r.push("recent:1w")):g.daysAgo<=30&&(a=.3,r.push("recent:1m")),g.commits>=5&&(a=Math.min(1,a+.2)));let h=Xt.basename(o).toLowerCase();if((h.includes("index")||h.includes("main")||h.includes("app")||h.includes("entry"))&&(c=.5,r.push("import:0")),(p.includes("/core/")||p.includes("/shared/")||p.includes("/lib/"))&&(c=Math.max(c,.3),r.some(_=>_.startsWith("import:"))||r.push("import:1")),n){let _=n.get(o);_!==void 0&&(l=(_+1)/2,_>0?r.push("history:boosted"):_<0&&r.push("history:penalized"))}let E=n&&n.size>0?s*.54+i*.18+a*.13+c*.05+l*.1:s*.6+i*.2+a*.15+c*.05;return{path:o,score:Math.min(1,E),reasons:[...new Set(r)]}}u(co,"scoreFile");function uo(o){let t=o.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")}u(uo,"isTestFile");it();import fo from"node:fs/promises";import mt from"node:path";var po={"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}},mo="claude-sonnet-4.5";function Me(o){return!o||o.length===0?0:Math.ceil(o.length/4)}u(Me,"countTokens");var ln=["claude-sonnet-4.5","claude-opus-4.5","claude-opus-4-6","gpt-4o","gemini-1.5-pro"];function un(o,t){let e=po[t],n=o/1e3*e.input,r=o/1e3*e.output*.3;return{inputSaved:n,outputPotential:r,total:n+r}}u(un,"calculateModelCost");function go(o){return o<.001?"<$0.01":o<.01?`$${o.toFixed(3)}`:`$${o.toFixed(2)}`}u(go,"formatCostSaved");function pn(o,t){let e=Me(o),n=Me(t),r=Math.max(0,e-n),s=e>0?(e-n)/e:0,i=un(r,mo),a=ln.map(c=>({model:c,...un(r,c)}));return{tokens:{original:e,filtered:n,saved:r},compression:Math.max(0,Math.min(1,s)),cost:{saved:i.total,formatted:go(i.total),byModel:a}}}u(pn,"measureCompression");function Ht(o){let t=Me(o);return{tokens:{original:t,filtered:t,saved:0},compression:0,cost:{saved:0,formatted:"$0.00",byModel:ln.map(e=>({model:e,inputSaved:0,outputPotential:0,total:0}))}}}u(Ht,"noCompression");var ho={".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"},dn=[{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}],yo=[{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}],To=[{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}],Eo=[{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}],mn=[{type:"class",pattern:/^(?:public\s+)?(?:abstract\s+)?(?:final\s+)?class\s+(\w+)(?:<[^>]+>)?(?:\s+extends\s+\w+)?(?:\s+implements\s+[^{]+)?\s*\{/gm,nameIndex:1,exported:!0},{type:"interface",pattern:/^(?:public\s+)?interface\s+(\w+)(?:<[^>]+>)?(?:\s+extends\s+[^{]+)?\s*\{/gm,nameIndex:1,exported:!0},{type:"method",pattern:/^\s+(?:public|private|protected)?\s*(?:static\s+)?(?:final\s+)?(?:synchronized\s+)?(?:<[^>]+>\s+)?(\w+(?:<[^>]+>)?)\s+(\w+)\s*\([^)]*\)\s*(?:throws\s+[^{]+)?\s*\{/gm,nameIndex:2}],ko={typescript:dn,javascript:dn,python:yo,go:To,rust:Eo,java:mn,csharp:mn,php:[],ruby:[],unknown:[]};async function gn(o,t=process.cwd()){let e=mt.isAbsolute(o)?o:mt.join(t,o),n=mt.resolve(t),r=mt.resolve(e);if(!r.startsWith(n+mt.sep)&&r!==n)return{file:o,language:"unknown",signatures:[],fallback:!0,fallbackReason:"Path traversal denied: file is outside project directory",metrics:Ht("")};let s;try{s=await fo.readFile(e,"utf-8")}catch(m){if(O(m))return{file:o,language:"unknown",signatures:[],fallback:!0,fallbackReason:"File not found",metrics:Ht("")};throw m}let i=mt.extname(o).toLowerCase(),a=ho[i]||"unknown",c=ko[a];if(!c||c.length===0)return{file:o,language:a,signatures:[],fallback:!0,fallbackReason:`No extraction patterns for ${a}`,metrics:Ht(s)};let l=wo(s,c),p=l.map(m=>`${m.exported?"export ":""}${m.type} ${m.name}: ${m.signature}`).join(`
529
+ `);return{file:o,language:a,signatures:l,fallback:!1,metrics:pn(s,p)}}u(gn,"extractSignatures");function wo(o,t){let e=[],n=o.split(`
530
+ `),r=new Set;for(let s of t){s.pattern.lastIndex=0;let i;for(;(i=s.pattern.exec(o))!==null;){let a=i[s.nameIndex];if(!a)continue;let c=`${s.type}:${a}`;if(r.has(c))continue;r.add(c);let l=i.index,p=o.substring(0,l).split(`
531
+ `).length,m=i[0].trim(),g;if(p>1){let h=n[p-2]?.trim();(h?.startsWith("/**")||h?.startsWith("///")||h?.startsWith("#"))&&(g=h)}e.push({type:s.type,name:a,signature:bo(m),exported:s.exported||!1,line:p,docstring:g})}}return e.sort((s,i)=>s.line-i.line)}u(wo,"extractFromContent");function bo(o){return o.replace(/\{$/,"").replace(/\s+/g," ").trim()}u(bo,"cleanSignature");function fn(o){let t=o;t.tool("prjct_relevant_files","BM25-ranked files relevant to a query",{projectPath:ct.string().describe("Project directory path"),query:ct.string().describe("Task or query to find relevant files for"),maxFiles:ct.number().optional().default(10).describe("Max files to return")},T("prjct_relevant_files",async e=>{let n=await cn(e.query,e.projectPath,{maxFiles:e.maxFiles,minScore:.1});if(n.files.length===0)return{content:[{type:"text",text:"No relevant files found."}]};let r=n.files.map(i=>`- \`${i.path}\` (score: ${Math.round(i.score*100)}%) \u2014 ${i.reasons.join(", ")}`);return{content:[{type:"text",text:`## Relevant Files (${n.files.length}/${n.metrics.filesScanned} scanned)
532
+
533
+ ${r.join(`
534
+ `)}`}]}})),t.tool("prjct_signatures","Code signatures from a file (90% token reduction vs full content)",{projectPath:ct.string().describe("Project directory path"),filePath:ct.string().describe("Relative file path to extract signatures from")},T("prjct_signatures",async e=>{let n=await gn(e.filePath,e.projectPath);if(n.signatures.length===0)return{content:[{type:"text",text:n.fallback?`No signatures extracted: ${n.fallbackReason}`:"No signatures found."}]};let r=n.signatures.map(a=>`${a.exported?"export ":""}${a.type} ${a.name}: ${a.signature}${a.docstring?` // ${a.docstring}`:""}`),s=n.metrics?.compression?` (${Math.round(n.metrics.compression*100)}% reduction)`:"";return{content:[{type:"text",text:`## ${n.file} (${n.language})
531
535
  \`\`\`
532
- ${n.join(`
536
+ ${r.join(`
533
537
  `)}
534
- \`\`\`${s}`}]}})),e.tool("prjct_history","Recent completed tasks with outcomes",{projectPath:it.string().describe("Project directory path"),limit:it.number().optional().default(10).describe("Max results")},T("prjct_history",async t=>{let r=await w(t.projectPath),n=await U.getTaskHistory(r);if(n.length===0)return{content:[{type:"text",text:"No task history."}]};let i=n.slice(-t.limit).reverse().map(c=>{let l=[`- **${c.title}**`];return c.completedAt&&l.push(`completed: ${c.completedAt}`),c.classification&&l.push(`type: ${c.classification}`),l.join(" | ")});return{content:[{type:"text",text:`## Task History (${n.length} total)
538
+ \`\`\`${s}`}]}})),t.tool("prjct_history","Recent completed tasks with outcomes",{projectPath:ct.string().describe("Project directory path"),limit:ct.number().optional().default(10).describe("Max results")},T("prjct_history",async e=>{let n=await k(e.projectPath),r=await W.getTaskHistory(n);if(r.length===0)return{content:[{type:"text",text:"No task history."}]};let i=r.slice(-e.limit).reverse().map(c=>{let l=[`- **${c.title}**`];return c.completedAt&&l.push(`completed: ${c.completedAt}`),c.classification&&l.push(`type: ${c.classification}`),l.join(" | ")});return{content:[{type:"text",text:`## Task History (${r.length} total)
535
539
 
536
540
  ${i.join(`
537
- `)}`}]}}))}u(cr,"registerFileTools");import{z as k}from"zod";var Z=new q,go=new lt,ur=3e3,lr=`
538
- ... [truncated]`;function je(o){return o.replace(/<private>[\s\S]*?<\/private>/gi,"").trim()}u(je,"stripPrivateTags");function De(o){return o.length<=ur?o:o.slice(0,ur-lr.length)+lr}u(De,"truncateContent");var Ae=[{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 pr(o){let e=o;e.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:k.string().describe("Project directory path"),title:k.string().describe("Memory title"),content:k.string().describe("Memory content"),tags:k.array(k.string()).optional().describe("Tags for categorization"),topicKey:k.string().optional().describe("Topic key for upsert (e.g. decision/auth-strategy, bug/cors-issue)"),sessionId:k.string().optional().describe("Current session ID to link this memory to")},T("prjct_mem_save",async t=>{let r=await w(t.projectPath),n=De(je(t.content)),s=await Z.createMemory(r,{title:t.title,content:n,tags:t.tags,topicKey:t.topicKey,userTriggered:!0});return t.sessionId&&y.run(r,"UPDATE memories SET session_id = ? WHERE id = ?",t.sessionId,s),{content:[{type:"text",text:`Memory saved: ${s}`}]}})),e.tool("prjct_mem_search","FTS5 search \u2014 returns compact results (title + snippet + ID). Use prjct_mem_get for full content.",{projectPath:k.string().describe("Project directory path"),query:k.string().describe("Search query"),limit:k.number().optional().default(20).describe("Max results (default 20)"),offset:k.number().optional().default(0).describe("Offset for pagination (default 0)")},T("prjct_mem_search",async t=>{let r=await w(t.projectPath),n=await Z.searchMemories(r,t.query,t.limit,t.offset),s=t.query.toLowerCase(),i=[];try{let c=await go.getPatternsSummaryDetailed(r);for(let[l,p]of Object.entries(c.decisions))(l.toLowerCase().includes(s)||p.value.toLowerCase().includes(s))&&i.push(`- **[decision] ${l}**: ${p.value} (confidence: ${p.confidence}, seen: ${p.count}x)`);for(let[l,p]of Object.entries(c.preferences)){let m=typeof p.value=="string"?p.value:JSON.stringify(p.value);(l.toLowerCase().includes(s)||m.toLowerCase().includes(s))&&i.push(`- **[preference] ${l}**: ${m} (confidence: ${p.confidence})`)}}catch{}if(n.length===0&&i.length===0)return{content:[{type:"text",text:"No memories found."}]};let a=[];if(n.length>0){let c=n.map(l=>{let p=l.content.slice(0,120).replace(/\n/g," "),m=l.tags.length>0?` [${l.tags.join(", ")}]`:"";return`- **${l.title}** (id: ${l.id})${m}
539
- ${p}${l.content.length>120?"...":""}`});a.push(`Found ${n.length} memories:
541
+ `)}`}]}}))}u(fn,"registerFileTools");import{z as b}from"zod";var et=new Y,So=new pt,hn=3e3,yn=`
542
+ ... [truncated]`;function Ie(o){return o.replace(/<private>[\s\S]*?<\/private>/gi,"").trim()}u(Ie,"stripPrivateTags");function Oe(o){return o.length<=hn?o:o.slice(0,hn-yn.length)+yn}u(Oe,"truncateContent");var Le=[{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 Tn(o){let t=o;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:b.string().describe("Project directory path"),title:b.string().describe("Memory title"),content:b.string().describe("Memory content"),tags:b.array(b.string()).optional().describe("Tags for categorization"),topicKey:b.string().optional().describe("Topic key for upsert (e.g. decision/auth-strategy, bug/cors-issue)"),sessionId:b.string().optional().describe("Current session ID to link this memory to")},T("prjct_mem_save",async e=>{let n=await k(e.projectPath),r=Oe(Ie(e.content)),s=await et.createMemory(n,{title:e.title,content:r,tags:e.tags,topicKey:e.topicKey,userTriggered:!0});return e.sessionId&&y.run(n,"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:b.string().describe("Project directory path"),query:b.string().describe("Search query"),limit:b.number().optional().default(20).describe("Max results (default 20)"),offset:b.number().optional().default(0).describe("Offset for pagination (default 0)")},T("prjct_mem_search",async e=>{let n=await k(e.projectPath),r=await et.searchMemories(n,e.query,e.limit,e.offset),s=e.query.toLowerCase(),i=[];try{let c=await So.getPatternsSummaryDetailed(n);for(let[l,p]of Object.entries(c.decisions))(l.toLowerCase().includes(s)||p.value.toLowerCase().includes(s))&&i.push(`- **[decision] ${l}**: ${p.value} (confidence: ${p.confidence}, seen: ${p.count}x)`);for(let[l,p]of Object.entries(c.preferences)){let m=typeof p.value=="string"?p.value:JSON.stringify(p.value);(l.toLowerCase().includes(s)||m.toLowerCase().includes(s))&&i.push(`- **[preference] ${l}**: ${m} (confidence: ${p.confidence})`)}}catch{}if(r.length===0&&i.length===0)return{content:[{type:"text",text:"No memories found."}]};let a=[];if(r.length>0){let c=r.map(l=>{let p=l.content.slice(0,120).replace(/\n/g," "),m=l.tags.length>0?` [${l.tags.join(", ")}]`:"";return`- **${l.title}** (id: ${l.id})${m}
543
+ ${p}${l.content.length>120?"...":""}`});a.push(`Found ${r.length} memories:
540
544
 
541
545
  ${c.join(`
542
546
  `)}`)}return i.length>0&&a.push(`
543
547
  ### Matching Patterns (${i.length})
544
548
  ${i.join(`
545
549
  `)}`),{content:[{type:"text",text:a.join(`
546
- `)}]}})),e.tool("prjct_mem_get","Get full untruncated memory content by ID (progressive disclosure step 2)",{projectPath:k.string().describe("Project directory path"),memoryId:k.string().describe("Memory ID")},T("prjct_mem_get",async t=>{let r=await w(t.projectPath),n=await Z.getMemoryById(r,t.memoryId);return n?{content:[{type:"text",text:`# ${n.title}
550
+ `)}]}})),t.tool("prjct_mem_get","Get full untruncated memory content by ID (progressive disclosure step 2)",{projectPath:b.string().describe("Project directory path"),memoryId:b.string().describe("Memory ID")},T("prjct_mem_get",async e=>{let n=await k(e.projectPath),r=await et.getMemoryById(n,e.memoryId);return r?{content:[{type:"text",text:`# ${r.title}
547
551
 
548
- ${n.content}
552
+ ${r.content}
549
553
 
550
- Tags: ${n.tags.join(", ")||"none"}
551
- Created: ${n.createdAt}
552
- Updated: ${n.updatedAt}`}]}:{content:[{type:"text",text:`Memory ${t.memoryId} not found.`}]}})),e.tool("prjct_mem_delete","Soft-delete a memory by ID",{projectPath:k.string().describe("Project directory path"),memoryId:k.string().describe("Memory ID to delete")},T("prjct_mem_delete",async t=>{let r=await w(t.projectPath);return{content:[{type:"text",text:await Z.deleteMemory(r,t.memoryId)?"Memory deleted.":"Memory not found."}]}})),e.tool("prjct_mem_context","Get memories relevant to a task description",{projectPath:k.string().describe("Project directory path"),task:k.string().describe("Task description for relevance matching"),limit:k.number().optional().default(5).describe("Max results")},T("prjct_mem_context",async t=>{let r=await w(t.projectPath),n=await Z.getRelevantMemories(r,{params:{description:t.task}},t.limit);return n.length===0?{content:[{type:"text",text:"No relevant memories."}]}:{content:[{type:"text",text:n.map(i=>`- **${i.title}**: ${i.content.slice(0,200)}`).join(`
553
- `)}]}})),e.tool("prjct_mem_timeline","Chronological memories around a specific memory (progressive disclosure step 2). Shows \xB15 items in the same session.",{projectPath:k.string().describe("Project directory path"),memoryId:k.string().describe("Memory ID to center timeline on")},T("prjct_mem_timeline",async t=>{let r=await w(t.projectPath),n=y.get(r,"SELECT * FROM memories WHERE id = ? AND project_id = ? AND deleted_at IS NULL",t.memoryId,r);if(!n)return{content:[{type:"text",text:`Memory ${t.memoryId} not found.`}]};let s;if(n.session_id)s=y.query(r,`SELECT * FROM memories
554
+ Tags: ${r.tags.join(", ")||"none"}
555
+ Created: ${r.createdAt}
556
+ Updated: ${r.updatedAt}`}]}:{content:[{type:"text",text:`Memory ${e.memoryId} not found.`}]}})),t.tool("prjct_mem_delete","Soft-delete a memory by ID",{projectPath:b.string().describe("Project directory path"),memoryId:b.string().describe("Memory ID to delete")},T("prjct_mem_delete",async e=>{let n=await k(e.projectPath);return{content:[{type:"text",text:await et.deleteMemory(n,e.memoryId)?"Memory deleted.":"Memory not found."}]}})),t.tool("prjct_mem_context","Get memories relevant to a task description",{projectPath:b.string().describe("Project directory path"),task:b.string().describe("Task description for relevance matching"),limit:b.number().optional().default(5).describe("Max results")},T("prjct_mem_context",async e=>{let n=await k(e.projectPath),r=await et.getRelevantMemories(n,{params:{description:e.task}},e.limit);return r.length===0?{content:[{type:"text",text:"No relevant memories."}]}:{content:[{type:"text",text:r.map(i=>`- **${i.title}**: ${i.content.slice(0,200)}`).join(`
557
+ `)}]}})),t.tool("prjct_mem_timeline","Chronological memories around a specific memory (progressive disclosure step 2). Shows \xB15 items in the same session.",{projectPath:b.string().describe("Project directory path"),memoryId:b.string().describe("Memory ID to center timeline on")},T("prjct_mem_timeline",async e=>{let n=await k(e.projectPath),r=y.get(n,"SELECT * FROM memories WHERE id = ? AND project_id = ? AND deleted_at IS NULL",e.memoryId,n);if(!r)return{content:[{type:"text",text:`Memory ${e.memoryId} not found.`}]};let s;if(r.session_id)s=y.query(n,`SELECT * FROM memories
554
558
  WHERE project_id = ? AND session_id = ? AND deleted_at IS NULL
555
- ORDER BY created_at ASC`,r,n.session_id);else{let c=y.query(r,`SELECT * FROM memories
559
+ ORDER BY created_at ASC`,n,r.session_id);else{let c=y.query(n,`SELECT * FROM memories
556
560
  WHERE project_id = ? AND deleted_at IS NULL AND created_at < ?
557
- ORDER BY created_at DESC LIMIT 5`,r,n.created_at).reverse(),l=y.query(r,`SELECT * FROM memories
561
+ ORDER BY created_at DESC LIMIT 5`,n,r.created_at).reverse(),l=y.query(n,`SELECT * FROM memories
558
562
  WHERE project_id = ? AND deleted_at IS NULL AND created_at > ?
559
- ORDER BY created_at ASC LIMIT 5`,r,n.created_at);s=[...c,n,...l]}if(s.length===0)return{content:[{type:"text",text:"No timeline context."}]};let i=s.map(c=>{let l=c.id===t.memoryId?"\u2192":" ",p=c.content.slice(0,100).replace(/\n/g," ");return`${l} [${c.created_at}] **${c.title}** (${c.id})
560
- ${p}${c.content.length>100?"...":""}`}),a=n.session_id?`
561
- Session: ${n.session_id}`:"";return{content:[{type:"text",text:`## Timeline around "${n.title}"${a}
563
+ ORDER BY created_at ASC LIMIT 5`,n,r.created_at);s=[...c,r,...l]}if(s.length===0)return{content:[{type:"text",text:"No timeline context."}]};let i=s.map(c=>{let l=c.id===e.memoryId?"\u2192":" ",p=c.content.slice(0,100).replace(/\n/g," ");return`${l} [${c.created_at}] **${c.title}** (${c.id})
564
+ ${p}${c.content.length>100?"...":""}`}),a=r.session_id?`
565
+ Session: ${r.session_id}`:"";return{content:[{type:"text",text:`## Timeline around "${r.title}"${a}
562
566
 
563
567
  ${i.join(`
564
- `)}`}]}})),e.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:k.string().describe("Project directory path"),title:k.string().describe("Memory title"),content:k.string().describe("Memory content")},T("prjct_mem_suggest_topic",async t=>{let r=`${t.title} ${t.content}`.toLowerCase(),n=Ae[0],s=0;for(let m of Ae){let g=m.keywords.filter(h=>r.includes(h)).length;g>s&&(s=g,n=m)}let i=t.title.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"").slice(0,40),a=`${n.prefix}/${i}`,c=await w(t.projectPath),l=y.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"}`];l&&p.push(`
568
+ `)}`}]}})),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:b.string().describe("Project directory path"),title:b.string().describe("Memory title"),content:b.string().describe("Memory content")},T("prjct_mem_suggest_topic",async e=>{let n=`${e.title} ${e.content}`.toLowerCase(),r=Le[0],s=0;for(let m of Le){let g=m.keywords.filter(h=>n.includes(h)).length;g>s&&(s=g,r=m)}let i=e.title.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"").slice(0,40),a=`${r.prefix}/${i}`,c=await k(e.projectPath),l=y.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: ${r.prefix} \u2014 ${r.description}`,`Confidence: ${s===0?"low (no keyword matches, defaulted)":s>=3?"high":"medium"}`];l&&p.push(`
565
569
  Note: This topic_key already exists \u2192 will UPDATE "${l.title}" (id: ${l.id})`),p.push(`
566
- Available families:`);for(let m of Ae)p.push(`- \`${m.prefix}/*\` \u2014 ${m.description}`);return{content:[{type:"text",text:p.join(`
567
- `)}]}})),e.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:k.string().describe("Project directory path"),text:k.string().describe("Text to extract learnings from (e.g. agent output)"),sessionId:k.string().optional().describe("Current session ID")},T("prjct_mem_capture_passive",async t=>{let r=await w(t.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 l=t.text.match(c);if(l?.[1]){let p=l[1].split(/\n[-*•]\s+|\n\d+[.)]\s+/).map(m=>m.trim()).filter(m=>m.length>10);s.push(...p)}}if(s.length===0)return{content:[{type:"text",text:"No structured learnings found in text."}]};let i=[...new Set(s)],a=[];for(let c of i.slice(0,10)){let l=c.slice(0,80).replace(/\n/g," "),p=De(je(c)),m=await Z.createMemory(r,{title:l,content:p,tags:[],topicKey:`learning/${l.toLowerCase().replace(/[^a-z0-9]+/g,"-").slice(0,40)}`,userTriggered:!1});t.sessionId&&y.run(r,"UPDATE memories SET session_id = ? WHERE id = ?",t.sessionId,m),a.push(m)}return{content:[{type:"text",text:`Extracted and saved ${a.length} learnings:
570
+ Available families:`);for(let m of Le)p.push(`- \`${m.prefix}/*\` \u2014 ${m.description}`);return{content:[{type:"text",text:p.join(`
571
+ `)}]}})),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:b.string().describe("Project directory path"),text:b.string().describe("Text to extract learnings from (e.g. agent output)"),sessionId:b.string().optional().describe("Current session ID")},T("prjct_mem_capture_passive",async e=>{let n=await k(e.projectPath),r=[/(?:^|\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 r){let l=e.text.match(c);if(l?.[1]){let p=l[1].split(/\n[-*•]\s+|\n\d+[.)]\s+/).map(m=>m.trim()).filter(m=>m.length>10);s.push(...p)}}if(s.length===0)return{content:[{type:"text",text:"No structured learnings found in text."}]};let i=[...new Set(s)],a=[];for(let c of i.slice(0,10)){let l=c.slice(0,80).replace(/\n/g," "),p=Oe(Ie(c)),m=await et.createMemory(n,{title:l,content:p,tags:[],topicKey:`learning/${l.toLowerCase().replace(/[^a-z0-9]+/g,"-").slice(0,40)}`,userTriggered:!1});e.sessionId&&y.run(n,"UPDATE memories SET session_id = ? WHERE id = ?",e.sessionId,m),a.push(m)}return{content:[{type:"text",text:`Extracted and saved ${a.length} learnings:
568
572
  ${a.map((c,l)=>`- ${i[l].slice(0,60)}... (${c})`).join(`
569
- `)}`}]}})),e.tool("prjct_mem_update","Update an existing memory by ID. Partial updates supported (title, content, tags).",{projectPath:k.string().describe("Project directory path"),memoryId:k.string().describe("Memory ID to update"),title:k.string().optional().describe("New title"),content:k.string().optional().describe("New content"),tags:k.array(k.string()).optional().describe("New tags")},T("prjct_mem_update",async t=>{let r=await w(t.projectPath),n={};return t.title&&(n.title=t.title),t.content&&(n.content=De(je(t.content))),t.tags&&(n.tags=t.tags),{content:[{type:"text",text:await Z.updateMemory(r,t.memoryId,n)?`Memory ${t.memoryId} updated.`:"Memory not found."}]}})),e.tool("prjct_mem_stats","Memory statistics: total count, user-triggered count, tag distribution, age range",{projectPath:k.string().describe("Project directory path")},T("prjct_mem_stats",async t=>{let r=await w(t.projectPath),n=await Z.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 i=Object.entries(n.tagCounts);if(i.length>0){s.push(`
573
+ `)}`}]}})),t.tool("prjct_mem_update","Update an existing memory by ID. Partial updates supported (title, content, tags).",{projectPath:b.string().describe("Project directory path"),memoryId:b.string().describe("Memory ID to update"),title:b.string().optional().describe("New title"),content:b.string().optional().describe("New content"),tags:b.array(b.string()).optional().describe("New tags")},T("prjct_mem_update",async e=>{let n=await k(e.projectPath),r={};return e.title&&(r.title=e.title),e.content&&(r.content=Oe(Ie(e.content))),e.tags&&(r.tags=e.tags),{content:[{type:"text",text:await et.updateMemory(n,e.memoryId,r)?`Memory ${e.memoryId} updated.`:"Memory not found."}]}})),t.tool("prjct_mem_stats","Memory statistics: total count, user-triggered count, tag distribution, age range",{projectPath:b.string().describe("Project directory path")},T("prjct_mem_stats",async e=>{let n=await k(e.projectPath),r=await et.getMemoryStats(n),s=["## Memory Stats",`Total: ${r.totalMemories}`,`User-triggered: ${r.userTriggered}`,`Auto-captured: ${r.totalMemories-r.userTriggered}`];r.oldestMemory&&s.push(`Oldest: ${r.oldestMemory}`),r.newestMemory&&s.push(`Newest: ${r.newestMemory}`);let i=Object.entries(r.tagCounts);if(i.length>0){s.push(`
570
574
  ### Tags`);for(let[a,c]of i.sort(([,l],[,p])=>p-l))s.push(`- ${a}: ${c}`)}return{content:[{type:"text",text:s.join(`
571
- `)}]}})),e.tool("prjct_mem_tags","Find memories by tags (matchAll: require all tags, default: match any)",{projectPath:k.string().describe("Project directory path"),tags:k.array(k.string()).describe("Tags to search for"),matchAll:k.boolean().optional().default(!1).describe("Require all tags to match (default: any)")},T("prjct_mem_tags",async t=>{let r=await w(t.projectPath),n=await Z.findByTags(r,t.tags,t.matchAll);if(n.length===0)return{content:[{type:"text",text:"No memories found with those tags."}]};let s=n.map(i=>{let a=i.content.slice(0,120).replace(/\n/g," "),c=i.tags.length>0?` [${i.tags.join(", ")}]`:"";return`- **${i.title}** (id: ${i.id})${c}
572
- ${a}${i.content.length>120?"...":""}`});return{content:[{type:"text",text:`Found ${n.length} memories:
575
+ `)}]}})),t.tool("prjct_mem_tags","Find memories by tags (matchAll: require all tags, default: match any)",{projectPath:b.string().describe("Project directory path"),tags:b.array(b.string()).describe("Tags to search for"),matchAll:b.boolean().optional().default(!1).describe("Require all tags to match (default: any)")},T("prjct_mem_tags",async e=>{let n=await k(e.projectPath),r=await et.findByTags(n,e.tags,e.matchAll);if(r.length===0)return{content:[{type:"text",text:"No memories found with those tags."}]};let s=r.map(i=>{let a=i.content.slice(0,120).replace(/\n/g," "),c=i.tags.length>0?` [${i.tags.join(", ")}]`:"";return`- **${i.title}** (id: ${i.id})${c}
576
+ ${a}${i.content.length>120?"...":""}`});return{content:[{type:"text",text:`Found ${r.length} memories:
573
577
 
574
578
  ${s.join(`
575
- `)}`}]}})),e.tool("prjct_mem_topic",'Browse memories by topic_key prefix (e.g. "bug/*", "decision/*")',{projectPath:k.string().describe("Project directory path"),prefix:k.string().describe('Topic key prefix to match (e.g. "bug/", "decision/")'),limit:k.number().optional().default(20).describe("Max results (default 20)")},T("prjct_mem_topic",async t=>{let r=await w(t.projectPath),n=t.prefix.endsWith("*")?`${t.prefix.slice(0,-1)}%`:t.prefix.endsWith("%")?t.prefix:`${t.prefix}%`,s=y.query(r,`SELECT * FROM memories
579
+ `)}`}]}})),t.tool("prjct_mem_topic",'Browse memories by topic_key prefix (e.g. "bug/*", "decision/*")',{projectPath:b.string().describe("Project directory path"),prefix:b.string().describe('Topic key prefix to match (e.g. "bug/", "decision/")'),limit:b.number().optional().default(20).describe("Max results (default 20)")},T("prjct_mem_topic",async e=>{let n=await k(e.projectPath),r=e.prefix.endsWith("*")?`${e.prefix.slice(0,-1)}%`:e.prefix.endsWith("%")?e.prefix:`${e.prefix}%`,s=y.query(n,`SELECT * FROM memories
576
580
  WHERE project_id = ? AND topic_key LIKE ? AND deleted_at IS NULL
577
- ORDER BY updated_at DESC LIMIT ?`,r,n,t.limit);if(s.length===0)return{content:[{type:"text",text:`No memories found with topic prefix "${t.prefix}".`}]};let i=s.map(a=>{let c=a.content.slice(0,120).replace(/\n/g," ");return`- **${a.title}** (topic: ${a.topic_key}, id: ${a.id})
578
- ${c}${a.content.length>120?"...":""}`});return{content:[{type:"text",text:`## Memories: ${t.prefix} (${s.length})
581
+ ORDER BY updated_at DESC LIMIT ?`,n,r,e.limit);if(s.length===0)return{content:[{type:"text",text:`No memories found with topic prefix "${e.prefix}".`}]};let i=s.map(a=>{let c=a.content.slice(0,120).replace(/\n/g," ");return`- **${a.title}** (topic: ${a.topic_key}, id: ${a.id})
582
+ ${c}${a.content.length>120?"...":""}`});return{content:[{type:"text",text:`## Memories: ${e.prefix} (${s.length})
579
583
 
580
584
  ${i.join(`
581
- `)}`}]}})),e.tool("prjct_mem_consolidate","Find and merge duplicate/similar memories (same title). Returns count merged.",{projectPath:k.string().describe("Project directory path")},T("prjct_mem_consolidate",async t=>{let r=await w(t.projectPath),n=await L.consolidateMemories(r);if(n.merged===0)return{content:[{type:"text",text:"No duplicate memories found."}]};let s=["## Consolidation Complete",`Merged: ${n.merged} duplicate memories
582
- `];for(let i of n.groups)s.push(`- Kept ${i.kept}, merged ${i.merged.length} duplicates`);return{content:[{type:"text",text:s.join(`
583
- `)}]}})),e.tool("prjct_feedback_aggregate","Aggregated task feedback: confirmed stack, gotchas, agent accuracy",{projectPath:k.string().describe("Project directory path")},T("prjct_feedback_aggregate",async t=>{let r=await w(t.projectPath),n=await U.getAggregatedFeedback(r),s=["## Aggregated Task Feedback"];if(n.stackConfirmed.length>0&&(s.push(`
584
- ### Confirmed Stack`),s.push(n.stackConfirmed.join(", "))),n.patternsDiscovered.length>0){s.push(`
585
- ### Patterns Discovered`);for(let a of n.patternsDiscovered)s.push(`- ${a}`)}if(n.knownGotchas.length>0){s.push(`
586
- ### Known Gotchas`);for(let a of n.knownGotchas)s.push(`- ${a}`)}if(n.agentAccuracy.length>0){s.push(`
587
- ### 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(`
588
- ### 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(`
585
+ `)}`}]}})),t.tool("prjct_mem_consolidate","Find and merge duplicate/similar memories (same title). Returns count merged.",{projectPath:b.string().describe("Project directory path")},T("prjct_mem_consolidate",async e=>{let n=await k(e.projectPath),r=await F.consolidateMemories(n);if(r.merged===0)return{content:[{type:"text",text:"No duplicate memories found."}]};let s=["## Consolidation Complete",`Merged: ${r.merged} duplicate memories
586
+ `];for(let i of r.groups)s.push(`- Kept ${i.kept}, merged ${i.merged.length} duplicates`);return{content:[{type:"text",text:s.join(`
587
+ `)}]}})),t.tool("prjct_feedback_aggregate","Aggregated task feedback: confirmed stack, gotchas, agent accuracy",{projectPath:b.string().describe("Project directory path")},T("prjct_feedback_aggregate",async e=>{let n=await k(e.projectPath),r=await W.getAggregatedFeedback(n),s=["## Aggregated Task Feedback"];if(r.stackConfirmed.length>0&&(s.push(`
588
+ ### Confirmed Stack`),s.push(r.stackConfirmed.join(", "))),r.patternsDiscovered.length>0){s.push(`
589
+ ### Patterns Discovered`);for(let a of r.patternsDiscovered)s.push(`- ${a}`)}if(r.knownGotchas.length>0){s.push(`
590
+ ### Known Gotchas`);for(let a of r.knownGotchas)s.push(`- ${a}`)}if(r.agentAccuracy.length>0){s.push(`
591
+ ### Agent Accuracy`);for(let a of r.agentAccuracy)s.push(`- ${a.agent}: ${a.rating}${a.note?` \u2014 ${a.note}`:""}`)}if(r.issuesEncountered.length>0){s.push(`
592
+ ### Issues Encountered`);for(let a of r.issuesEncountered)s.push(`- ${a}`)}return r.stackConfirmed.length===0&&r.patternsDiscovered.length===0&&r.knownGotchas.length===0&&s.push(`
589
593
  No task feedback recorded yet.`),{content:[{type:"text",text:s.join(`
590
- `)}]}}))}u(pr,"registerMemoryTools");import{z as $}from"zod";function dr(o){let e=o;e.tool("prjct_decision_record","Record a technical decision with confidence tracking. Repeated observations increase confidence.",{projectPath:$.string().describe("Project directory path"),key:$.string().describe("Decision key (e.g. commit_style, branch_naming, test_framework)"),value:$.string().describe('Decision value (e.g. "conventional commits", "feature/*")'),context:$.string().optional().default("").describe("Context for this decision")},T("prjct_decision_record",async t=>{let r=await w(t.projectPath);return await L.learnDecision(r,t.key,t.value,t.context),{content:[{type:"text",text:`Decision recorded: ${t.key} = "${t.value}"`}]}})),e.tool("prjct_decision_get","Retrieve a learned decision (checks session cache \u2192 pattern store). Returns null for low-confidence decisions.",{projectPath:$.string().describe("Project directory path"),key:$.string().describe("Decision key to look up")},T("prjct_decision_get",async t=>{let r=await w(t.projectPath),n=await L.getSmartDecision(r,t.key);return n===null?{content:[{type:"text",text:`No decision found for "${t.key}".`}]}:{content:[{type:"text",text:`${t.key} = "${n}"`}]}})),e.tool("prjct_preference_set","Set a user preference with confidence tracking",{projectPath:$.string().describe("Project directory path"),key:$.string().describe("Preference key (e.g. verbosity, test_runner, editor)"),value:$.string().describe("Preference value")},T("prjct_preference_set",async t=>{let r=await w(t.projectPath);return await L.setPreference(r,t.key,t.value,{userConfirmed:!0}),{content:[{type:"text",text:`Preference set: ${t.key} = "${t.value}"`}]}})),e.tool("prjct_preference_get","Get a user preference value",{projectPath:$.string().describe("Project directory path"),key:$.string().describe("Preference key to look up")},T("prjct_preference_get",async t=>{let r=await w(t.projectPath),n=await L.getPreference(r,t.key);return n===null?{content:[{type:"text",text:`No preference found for "${t.key}".`}]}:{content:[{type:"text",text:`${t.key} = "${n}"`}]}})),e.tool("prjct_confirm","Confirm a decision/preference/workflow \u2192 boosts confidence to high",{projectPath:$.string().describe("Project directory path"),type:$.enum(["decision","preference","workflow"]).describe("Type to confirm"),key:$.string().describe("Key of the decision/preference/workflow to confirm")},T("prjct_confirm",async t=>{let r=await w(t.projectPath),n;switch(t.type){case"decision":n=await L.confirmDecision(r,t.key);break;case"preference":n=await L.confirmPreference(r,t.key);break;case"workflow":n=await L.confirmWorkflow(r,t.key);break}return n?{content:[{type:"text",text:`Confirmed ${t.type} "${t.key}" \u2192 confidence set to high.`}]}:{content:[{type:"text",text:`${t.type} "${t.key}" not found.`}]}})),e.tool("prjct_archive_stale","Archive stale decisions (>90 days) + paused tasks (>30 days)",{projectPath:$.string().describe("Project directory path")},T("prjct_archive_stale",async t=>{let r=await w(t.projectPath),n=await L.archiveStaleDecisions(r),s=await U.archiveStalePausedTasks(r),i=["## Archive Results"];if(i.push(`Stale decisions archived: ${n}`),i.push(`Stale paused tasks archived: ${s.length}`),s.length>0){i.push(`
594
+ `)}]}}))}u(Tn,"registerMemoryTools");import{z as U}from"zod";function En(o){let t=o;t.tool("prjct_decision_record","Record a technical decision with confidence tracking. Repeated observations increase confidence.",{projectPath:U.string().describe("Project directory path"),key:U.string().describe("Decision key (e.g. commit_style, branch_naming, test_framework)"),value:U.string().describe('Decision value (e.g. "conventional commits", "feature/*")'),context:U.string().optional().default("").describe("Context for this decision")},T("prjct_decision_record",async e=>{let n=await k(e.projectPath);return await F.learnDecision(n,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:U.string().describe("Project directory path"),key:U.string().describe("Decision key to look up")},T("prjct_decision_get",async e=>{let n=await k(e.projectPath),r=await F.getSmartDecision(n,e.key);return r===null?{content:[{type:"text",text:`No decision found for "${e.key}".`}]}:{content:[{type:"text",text:`${e.key} = "${r}"`}]}})),t.tool("prjct_preference_set","Set a user preference with confidence tracking",{projectPath:U.string().describe("Project directory path"),key:U.string().describe("Preference key (e.g. verbosity, test_runner, editor)"),value:U.string().describe("Preference value")},T("prjct_preference_set",async e=>{let n=await k(e.projectPath);return await F.setPreference(n,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:U.string().describe("Project directory path"),key:U.string().describe("Preference key to look up")},T("prjct_preference_get",async e=>{let n=await k(e.projectPath),r=await F.getPreference(n,e.key);return r===null?{content:[{type:"text",text:`No preference found for "${e.key}".`}]}:{content:[{type:"text",text:`${e.key} = "${r}"`}]}})),t.tool("prjct_confirm","Confirm a decision/preference/workflow \u2192 boosts confidence to high",{projectPath:U.string().describe("Project directory path"),type:U.enum(["decision","preference","workflow"]).describe("Type to confirm"),key:U.string().describe("Key of the decision/preference/workflow to confirm")},T("prjct_confirm",async e=>{let n=await k(e.projectPath),r;switch(e.type){case"decision":r=await F.confirmDecision(n,e.key);break;case"preference":r=await F.confirmPreference(n,e.key);break;case"workflow":r=await F.confirmWorkflow(n,e.key);break}return r?{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:U.string().describe("Project directory path")},T("prjct_archive_stale",async e=>{let n=await k(e.projectPath),r=await F.archiveStaleDecisions(n),s=await W.archiveStalePausedTasks(n),i=["## Archive Results"];if(i.push(`Stale decisions archived: ${r}`),i.push(`Stale paused tasks archived: ${s.length}`),s.length>0){i.push(`
591
595
  ### Archived Tasks`);for(let a of s)i.push(`- ${a.description} (paused at ${a.pausedAt})`)}return{content:[{type:"text",text:i.join(`
592
- `)}]}}))}u(dr,"registerPatternTools");import{z as A}from"zod";Oe();Ne();var Tr={critical:0,high:1,medium:2,low:3},Er={active:0,previously_active:1,backlog:2};function wr(o){return[...o].sort((e,t)=>{let r=Er[e.section]-Er[t.section];return r!==0?r:Tr[e.priority]-Tr[t.priority]})}u(wr,"sortBySectionAndPriority");N();var Le=class extends pt{static{u(this,"QueueStorage")}constructor(){super("queue.json",Qn)}getDefault(){return{tasks:[],lastUpdated:""}}getEventType(e){return`queue.${e}d`}async getTasks(e){return(await this.read(e)).tasks}async getActiveTasks(e){return(await this.read(e)).tasks.filter(r=>r.section==="active"&&!r.completed)}async getBacklog(e){return(await this.read(e)).tasks.filter(r=>r.section==="backlog"&&!r.completed)}async getNextTask(e){let t=await this.getActiveTasks(e);return wr(t)[0]||null}async addTask(e,t){let r={...t,id:O(),createdAt:f(),completed:!1};return await this.update(e,n=>({tasks:[...n.tasks,r],lastUpdated:f()})),await this.publishEvent(e,"queue.task_added",{taskId:r.id,description:r.description,priority:r.priority,section:r.section}),r}async addTasks(e,t){let r=f(),n=t.map(s=>({...s,id:O(),createdAt:r,completed:!1}));return await this.update(e,s=>({tasks:[...s.tasks,...n],lastUpdated:r})),await this.publishEvent(e,"queue.tasks_added",{count:n.length,tasks:n.map(s=>({id:s.id,description:s.description}))}),n}async removeTask(e,t){await this.update(e,r=>({tasks:r.tasks.filter(n=>n.id!==t),lastUpdated:f()})),await this.publishEvent(e,"queue.task_removed",{taskId:t})}async completeTask(e,t){let r=null;if(await this.update(e,n=>({tasks:n.tasks.map(i=>i.id===t?(r={...i,completed:!0,completedAt:f()},r):i),lastUpdated:f()})),r){let n=r;await this.publishEvent(e,"queue.task_completed",{taskId:t,description:n.description,completedAt:n.completedAt})}return r}async moveToSection(e,t,r){await this.update(e,n=>({tasks:n.tasks.map(s=>s.id===t?{...s,section:r}:s),lastUpdated:f()}))}async setPriority(e,t,r){await this.update(e,n=>({tasks:n.tasks.map(s=>s.id===t?{...s,priority:r}:s),lastUpdated:f()}))}async clearCompleted(e){let r=(await this.read(e)).tasks.filter(n=>n.completed).length;return await this.update(e,n=>({tasks:n.tasks.filter(s=>!s.completed),lastUpdated:f()})),r}async removeStaleCompleted(e){let t=await this.read(e),r=Je(Zn.QUEUE_COMPLETED_DAYS),n=t.tasks.filter(i=>i.completed&&i.completedAt&&new Date(i.completedAt)<r);if(n.length===0)return 0;Ut.archiveMany(e,n.map(i=>({entityType:"queue_task",entityId:i.id,entityData:i,summary:i.description,reason:"age"})));let s=new Set(n.map(i=>i.id));return await this.update(e,i=>({tasks:i.tasks.filter(a=>!s.has(a.id)),lastUpdated:f()})),await this.publishEvent(e,"queue.stale_removed",{count:n.length}),n.length}},br=new Le;import $e from"node:path";N();tt();var xo="outcomes",vo="outcomes.jsonl",Fe=class{static{u(this,"OutcomeRecorder")}_cache=new Map;getOutcomesDir(e){let t=v.getGlobalProjectPath(e);return $e.join(t,xo)}getOutcomesPath(e){return $e.join(this.getOutcomesDir(e),vo)}async record(e,t){let r={...t,id:O()},n=this.getOutcomesPath(e);return await G($e.dirname(n)),await cn(n,JSON.stringify(r)),this._cache.delete(e),r}async getAll(e){let t=this.getOutcomesPath(e);if(!await D(t))return[];try{let{statSync:r}=await import("node:fs"),s=r(t).mtimeMs,i=this._cache.get(e);if(i&&i.mtime===s)return i.outcomes;let a=await Yt(t);if(!a.trim())return[];let c=a.trim().split(`
593
- `).filter(l=>l.trim()).map(l=>JSON.parse(l));return this._cache.set(e,{outcomes:c,mtime:s}),c}catch{let r=await Yt(t);return r.trim()?r.trim().split(`
594
- `).filter(n=>n.trim()).map(n=>JSON.parse(n)):[]}}async filter(e,t){return(await this.getAll(e)).filter(n=>{if(t.sessionId&&n.sessionId!==t.sessionId||t.command&&n.command!==t.command||t.agent&&n.agentUsed!==t.agent||t.fromDate&&n.startedAt<t.fromDate||t.toDate&&n.completedAt>t.toDate||t.minQuality&&n.qualityScore<t.minQuality)return!1;if(t.tags&&t.tags.length>0){let s=n.tags||[];if(!t.tags.some(i=>s.includes(i)))return!1}return!0})}async getRecent(e,t=10){return(await this.getAll(e)).slice(-t)}async getByCommand(e,t){return this.filter(e,{command:t})}async getByAgent(e,t){return this.filter(e,{agent:t})}async getEstimateAccuracy(e){let t=await this.getAll(e);if(t.length===0)return 0;let r=t.filter(n=>{if(!n.variance)return!1;let s=Qe(n.variance),i=st(n.estimatedDuration);return i===0?!1:Math.abs(s)/i<=.2});return Math.round(r.length/t.length*100)}},Po=new Fe,Y=Po;function kr(o){let e=o;e.tool("prjct_task_status","Current task, duration, subtasks, and queue",{projectPath:A.string().describe("Project directory path")},T("prjct_task_status",async t=>{let r=await w(t.projectPath),n=await U.getCurrentTask(r),s=await br.getActiveTasks(r),i=[];if(n?(i.push(`## Active Task
595
- **${n.description}**`),n.branch&&i.push(`Branch: ${n.branch}`),i.push(`Started: ${n.startedAt}`)):i.push("No active task."),s.length>0){i.push(`
596
+ `)}]}}))}u(En,"registerPatternTools");import{z as N}from"zod";We();$e();var xn={critical:0,high:1,medium:2,low:3},vn={active:0,previously_active:1,backlog:2};function Pn(o){return[...o].sort((t,e)=>{let n=vn[t.section]-vn[e.section];return n!==0?n:xn[t.priority]-xn[e.priority]})}u(Pn,"sortBySectionAndPriority");I();var Xe=class extends dt{static{u(this,"QueueStorage")}constructor(){super("queue.json",sn)}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(n=>n.section==="active"&&!n.completed)}async getBacklog(t){return(await this.read(t)).tasks.filter(n=>n.section==="backlog"&&!n.completed)}async getNextTask(t){let e=await this.getActiveTasks(t);return Pn(e)[0]||null}async addTask(t,e){let n={...e,id:$(),createdAt:f(),completed:!1};return await this.update(t,r=>({tasks:[...r.tasks,n],lastUpdated:f()})),await this.publishEvent(t,"queue.task_added",{taskId:n.id,description:n.description,priority:n.priority,section:n.section}),n}async addTasks(t,e){let n=f(),r=e.map(s=>({...s,id:$(),createdAt:n,completed:!1}));return await this.update(t,s=>({tasks:[...s.tasks,...r],lastUpdated:n})),await this.publishEvent(t,"queue.tasks_added",{count:r.length,tasks:r.map(s=>({id:s.id,description:s.description}))}),r}async removeTask(t,e){await this.update(t,n=>({tasks:n.tasks.filter(r=>r.id!==e),lastUpdated:f()})),await this.publishEvent(t,"queue.task_removed",{taskId:e})}async completeTask(t,e){let n=null;if(await this.update(t,r=>({tasks:r.tasks.map(i=>i.id===e?(n={...i,completed:!0,completedAt:f()},n):i),lastUpdated:f()})),n){let r=n;await this.publishEvent(t,"queue.task_completed",{taskId:e,description:r.description,completedAt:r.completedAt})}return n}async moveToSection(t,e,n){await this.update(t,r=>({tasks:r.tasks.map(s=>s.id===e?{...s,section:n}:s),lastUpdated:f()}))}async setPriority(t,e,n){await this.update(t,r=>({tasks:r.tasks.map(s=>s.id===e?{...s,priority:n}:s),lastUpdated:f()}))}async clearCompleted(t){let n=(await this.read(t)).tasks.filter(r=>r.completed).length;return await this.update(t,r=>({tasks:r.tasks.filter(s=>!s.completed),lastUpdated:f()})),n}async removeStaleCompleted(t){let e=await this.read(t),n=er(on.QUEUE_COMPLETED_DAYS),r=e.tasks.filter(i=>i.completed&&i.completedAt&&new Date(i.completedAt)<n);if(r.length===0)return 0;Wt.archiveMany(t,r.map(i=>({entityType:"queue_task",entityId:i.id,entityData:i,summary:i.description,reason:"age"})));let s=new Set(r.map(i=>i.id));return await this.update(t,i=>({tasks:i.tasks.filter(a=>!s.has(a.id)),lastUpdated:f()})),await this.publishEvent(t,"queue.stale_removed",{count:r.length}),r.length}},Rn=new Xe;import He from"node:path";I();Q();var Mo="outcomes",Io="outcomes.jsonl",Be=class{static{u(this,"OutcomeRecorder")}_cache=new Map;getOutcomesDir(t){let e=P.getGlobalProjectPath(t);return He.join(e,Mo)}getOutcomesPath(t){return He.join(this.getOutcomesDir(t),Io)}async record(t,e){let n={...e,id:$()},r=this.getOutcomesPath(t);return await G(He.dirname(r)),await pr(r,JSON.stringify(n)),this._cache.delete(t),n}async getAll(t){let e=this.getOutcomesPath(t);if(!await C(e))return[];try{let{statSync:n}=await import("node:fs"),s=n(e).mtimeMs,i=this._cache.get(t);if(i&&i.mtime===s)return i.outcomes;let a=await Jt(e);if(!a.trim())return[];let c=a.trim().split(`
597
+ `).filter(l=>l.trim()).map(l=>JSON.parse(l));return this._cache.set(t,{outcomes:c,mtime:s}),c}catch{let n=await Jt(e);return n.trim()?n.trim().split(`
598
+ `).filter(r=>r.trim()).map(r=>JSON.parse(r)):[]}}async filter(t,e){return(await this.getAll(t)).filter(r=>{if(e.sessionId&&r.sessionId!==e.sessionId||e.command&&r.command!==e.command||e.agent&&r.agentUsed!==e.agent||e.fromDate&&r.startedAt<e.fromDate||e.toDate&&r.completedAt>e.toDate||e.minQuality&&r.qualityScore<e.minQuality)return!1;if(e.tags&&e.tags.length>0){let s=r.tags||[];if(!e.tags.some(i=>s.includes(i)))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 n=e.filter(r=>{if(!r.variance)return!1;let s=rr(r.variance),i=ot(r.estimatedDuration);return i===0?!1:Math.abs(s)/i<=.2});return Math.round(n.length/e.length*100)}},Oo=new Be,K=Oo;function Cn(o){let t=o;t.tool("prjct_task_status","Current task, duration, subtasks, and queue",{projectPath:N.string().describe("Project directory path")},T("prjct_task_status",async e=>{let n=await k(e.projectPath),r=await W.getCurrentTask(n),s=await Rn.getActiveTasks(n),i=[];if(r?(i.push(`## Active Task
599
+ **${r.description}**`),r.branch&&i.push(`Branch: ${r.branch}`),i.push(`Started: ${r.startedAt}`)):i.push("No active task."),s.length>0){i.push(`
596
600
  ## Queue (${s.length} tasks)`);for(let a of s.slice(0,10))i.push(`- ${a.description} [${a.priority||"medium"}]`)}return{content:[{type:"text",text:i.join(`
597
- `)}]}})),e.tool("prjct_velocity","Sprint velocity, estimation accuracy, and trend",{projectPath:A.string().describe("Project directory path")},T("prjct_velocity",async t=>{let r=await w(t.projectPath),n=await Y.getAll(r);if(n.length===0)return{content:[{type:"text",text:"No outcome data yet."}]};let s=wt(n,rt);return s.sprints.length===0?{content:[{type:"text",text:"Not enough data for velocity."}]}:{content:[{type:"text",text:Ie(s)}]}})),e.tool("prjct_analysis","LLM analysis: stack, patterns, anti-patterns, conventions",{projectPath:A.string().describe("Project directory path")},T("prjct_analysis",async t=>{let r=await w(t.projectPath),n=nt.getActive(r);if(!n)return{content:[{type:"text",text:"No analysis available. Run `prjct sync`."}]};let s=["## Project Analysis"];if(n.stack&&(s.push(`
598
- ### Stack`),n.stack.languages?.length&&s.push(`Languages: ${n.stack.languages.join(", ")}`),n.stack.frameworks?.length&&s.push(`Frameworks: ${n.stack.frameworks.join(", ")}`),n.stack.packageManager&&s.push(`Package Manager: ${n.stack.packageManager}`)),n.patterns?.length){s.push(`
599
- ### Patterns (${n.patterns.length})`);for(let i of n.patterns)s.push(`- **${i.name}**: ${i.description}`)}if(n.antiPatterns?.length){s.push(`
600
- ### Anti-Patterns (${n.antiPatterns.length})`);for(let i of n.antiPatterns)s.push(`- **${i.issue}**: ${i.suggestion}`)}if(n.conventions?.length){s.push(`
601
- ### Conventions (${n.conventions.length})`);for(let i of n.conventions)s.push(`- [${i.category}] ${i.rule}`)}return{content:[{type:"text",text:s.join(`
602
- `)}]}})),e.tool("prjct_patterns","Learned decisions, preferences, and workflows with confidence tracking",{projectPath:A.string().describe("Project directory path")},T("prjct_patterns",async t=>{let r=await w(t.projectPath),n=await L.getPatternsSummaryDetailed(r);if(!n)return{content:[{type:"text",text:"No patterns learned yet."}]};let s=["## Learned Patterns"];if(Object.keys(n.decisions).length>0){s.push(`
603
- ### Decisions`);for(let[i,a]of Object.entries(n.decisions))s.push(`- **${i}**: ${a.value} (${a.confidence}, ${a.count}x)`)}if(Object.keys(n.preferences).length>0){s.push(`
604
- ### Preferences`);for(let[i,a]of Object.entries(n.preferences))s.push(`- **${i}**: ${a.value} (${a.confidence})`)}if(Object.keys(n.workflows).length>0){s.push(`
605
- ### Workflows`);for(let[i,a]of Object.entries(n.workflows))s.push(`- **${i}**: ${a.confidence}, ${a.count}x`)}return{content:[{type:"text",text:s.join(`
606
- `)}]}})),e.tool("prjct_outcomes_search","Search completed task outcomes \u2014 what worked, what failed, duration, blockers",{projectPath:A.string().describe("Project directory path"),query:A.string().describe("Search query (matches task description, blockers, patterns)"),limit:A.number().optional().default(10).describe("Max results"),offset:A.number().optional().default(0).describe("Offset for pagination (default 0)")},T("prjct_outcomes_search",async t=>{let r=await w(t.projectPath),n=await Y.getAll(r);if(n.length===0)return{content:[{type:"text",text:"No outcomes recorded yet."}]};let i=t.query.toLowerCase().split(/\s+/),a=n.map(l=>{let p=`${l.task} ${l.command} ${(l.blockers||[]).join(" ")} ${l.patternDetected||""} ${(l.tags||[]).join(" ")}`.toLowerCase(),m=i.filter(g=>p.includes(g)).length;return{outcome:l,score:m}}).filter(l=>l.score>0).sort((l,p)=>p.score-l.score).slice(t.offset,t.offset+t.limit);if(a.length===0)return{content:[{type:"text",text:`No outcomes matching "${t.query}".`}]};let c=a.map(({outcome:l})=>{let p=l.completedAsPlanned?"success":"issues",m=[`- **${l.task}** [${p}, ${l.actualDuration}]`];return l.variance&&m.push(` Variance: ${l.variance}`),l.blockers?.length&&m.push(` Blockers: ${l.blockers.join(", ")}`),l.patternDetected&&m.push(` Pattern: ${l.patternDetected}`),m.join(`
607
- `)});return{content:[{type:"text",text:`## Outcomes matching "${t.query}" (${a.length}/${n.length})
601
+ `)}]}})),t.tool("prjct_velocity","Sprint velocity, estimation accuracy, and trend",{projectPath:N.string().describe("Project directory path")},T("prjct_velocity",async e=>{let n=await k(e.projectPath),r=await K.getAll(n);if(r.length===0)return{content:[{type:"text",text:"No outcome data yet."}]};let s=wt(r,st);return s.sprints.length===0?{content:[{type:"text",text:"Not enough data for velocity."}]}:{content:[{type:"text",text:Ue(s)}]}})),t.tool("prjct_analysis","LLM analysis: stack, patterns, anti-patterns, conventions",{projectPath:N.string().describe("Project directory path")},T("prjct_analysis",async e=>{let n=await k(e.projectPath),r=nt.getActive(n);if(!r)return{content:[{type:"text",text:"No analysis available. Run `prjct sync`."}]};let s=["## Project Analysis"];if(r.stack&&(s.push(`
602
+ ### Stack`),r.stack.languages?.length&&s.push(`Languages: ${r.stack.languages.join(", ")}`),r.stack.frameworks?.length&&s.push(`Frameworks: ${r.stack.frameworks.join(", ")}`),r.stack.packageManager&&s.push(`Package Manager: ${r.stack.packageManager}`)),r.patterns?.length){s.push(`
603
+ ### Patterns (${r.patterns.length})`);for(let i of r.patterns)s.push(`- **${i.name}**: ${i.description}`)}if(r.antiPatterns?.length){s.push(`
604
+ ### Anti-Patterns (${r.antiPatterns.length})`);for(let i of r.antiPatterns)s.push(`- **${i.issue}**: ${i.suggestion}`)}if(r.conventions?.length){s.push(`
605
+ ### Conventions (${r.conventions.length})`);for(let i of r.conventions)s.push(`- [${i.category}] ${i.rule}`)}return{content:[{type:"text",text:s.join(`
606
+ `)}]}})),t.tool("prjct_patterns","Learned decisions, preferences, and workflows with confidence tracking",{projectPath:N.string().describe("Project directory path")},T("prjct_patterns",async e=>{let n=await k(e.projectPath),r=await F.getPatternsSummaryDetailed(n);if(!r)return{content:[{type:"text",text:"No patterns learned yet."}]};let s=["## Learned Patterns"];if(Object.keys(r.decisions).length>0){s.push(`
607
+ ### Decisions`);for(let[i,a]of Object.entries(r.decisions))s.push(`- **${i}**: ${a.value} (${a.confidence}, ${a.count}x)`)}if(Object.keys(r.preferences).length>0){s.push(`
608
+ ### Preferences`);for(let[i,a]of Object.entries(r.preferences))s.push(`- **${i}**: ${a.value} (${a.confidence})`)}if(Object.keys(r.workflows).length>0){s.push(`
609
+ ### Workflows`);for(let[i,a]of Object.entries(r.workflows))s.push(`- **${i}**: ${a.confidence}, ${a.count}x`)}return{content:[{type:"text",text:s.join(`
610
+ `)}]}})),t.tool("prjct_outcomes_search","Search completed task outcomes \u2014 what worked, what failed, duration, blockers",{projectPath:N.string().describe("Project directory path"),query:N.string().describe("Search query (matches task description, blockers, patterns)"),limit:N.number().optional().default(10).describe("Max results"),offset:N.number().optional().default(0).describe("Offset for pagination (default 0)")},T("prjct_outcomes_search",async e=>{let n=await k(e.projectPath),r=await K.getAll(n);if(r.length===0)return{content:[{type:"text",text:"No outcomes recorded yet."}]};let i=e.query.toLowerCase().split(/\s+/),a=r.map(l=>{let p=`${l.task} ${l.command} ${(l.blockers||[]).join(" ")} ${l.patternDetected||""} ${(l.tags||[]).join(" ")}`.toLowerCase(),m=i.filter(g=>p.includes(g)).length;return{outcome:l,score:m}}).filter(l=>l.score>0).sort((l,p)=>p.score-l.score).slice(e.offset,e.offset+e.limit);if(a.length===0)return{content:[{type:"text",text:`No outcomes matching "${e.query}".`}]};let c=a.map(({outcome:l})=>{let p=l.completedAsPlanned?"success":"issues",m=[`- **${l.task}** [${p}, ${l.actualDuration}]`];return l.variance&&m.push(` Variance: ${l.variance}`),l.blockers?.length&&m.push(` Blockers: ${l.blockers.join(", ")}`),l.patternDetected&&m.push(` Pattern: ${l.patternDetected}`),m.join(`
611
+ `)});return{content:[{type:"text",text:`## Outcomes matching "${e.query}" (${a.length}/${r.length})
608
612
 
609
613
  ${c.join(`
610
- `)}`}]}})),e.tool("prjct_outcomes_similar","Find similar past tasks and their outcomes: avg duration, success rate, common blockers",{projectPath:A.string().describe("Project directory path"),task:A.string().describe("Task description to find similar outcomes for")},T("prjct_outcomes_similar",async t=>{let r=await w(t.projectPath),n=await Y.getAll(r);if(n.length===0)return{content:[{type:"text",text:"No outcomes recorded yet."}]};let s=new Set(t.task.toLowerCase().split(/\s+/).filter(E=>E.length>2)),i=n.map(E=>{let _=new Set(E.task.toLowerCase().split(/\s+/).filter(kt=>kt.length>2)),X=[...s].filter(kt=>_.has(kt)).length,ft=s.size>0?X/s.size:0;return{outcome:E,similarity:ft}}).filter(E=>E.similarity>=.2).sort((E,_)=>_.similarity-E.similarity).slice(0,10);if(i.length===0)return{content:[{type:"text",text:"No similar past tasks found."}]};let a=i.filter(E=>E.outcome.completedAsPlanned).length,c=Math.round(a/i.length*100),l=i.map(E=>{let _=E.outcome.actualDuration.match(/(\d+)/);return _?Number.parseInt(_[1],10):0}).filter(E=>E>0),p=l.length>0?Math.round(l.reduce((E,_)=>E+_,0)/l.length):0,m=i.flatMap(E=>E.outcome.blockers||[]),g={};for(let E of m)g[E]=(g[E]||0)+1;let h=Object.entries(g).sort(([,E],[,_])=>_-E).slice(0,3),R=[`## Similar Tasks (${i.length} matches)`,`
611
- **Success rate**: ${c}% (${a}/${i.length})`];p>0&&R.push(`**Avg duration**: ${p}m`),h.length>0&&R.push(`**Common blockers**: ${h.map(([E,_])=>`${E} (${_}x)`).join(", ")}`),R.push(`
612
- ### Past tasks`);for(let{outcome:E,similarity:_}of i){let X=E.completedAsPlanned?"ok":"issues";R.push(`- [${X}] **${E.task}** \u2014 ${E.actualDuration} (${Math.round(_*100)}% similar)`)}return{content:[{type:"text",text:R.join(`
613
- `)}]}})),e.tool("prjct_outcomes_recent","Last N outcomes with optional command/agent filter",{projectPath:A.string().describe("Project directory path"),count:A.number().optional().default(10).describe("Number of recent outcomes (default 10)"),command:A.string().optional().describe('Filter by command (e.g. "done", "ship")'),agent:A.string().optional().describe("Filter by agent used")},T("prjct_outcomes_recent",async t=>{let r=await w(t.projectPath),n;if(t.command?(n=await Y.getByCommand(r,t.command),n=n.slice(-t.count)):t.agent?(n=await Y.getByAgent(r,t.agent),n=n.slice(-t.count)):n=await Y.getRecent(r,t.count),n.length===0)return{content:[{type:"text",text:"No outcomes found."}]};let s=[`## Recent Outcomes (${n.length})`],i=t.command?` [command: ${t.command}]`:t.agent?` [agent: ${t.agent}]`:"";i&&(s[0]+=i),s.push("");for(let a of n){let l=[`- [${a.completedAsPlanned?"ok":"issues"}] **${a.task}** \u2014 ${a.actualDuration}`];a.command&&l.push(` Command: ${a.command}`),a.variance&&l.push(` Variance: ${a.variance}`),a.blockers?.length&&l.push(` Blockers: ${a.blockers.join(", ")}`),s.push(l.join(`
614
+ `)}`}]}})),t.tool("prjct_outcomes_similar","Find similar past tasks and their outcomes: avg duration, success rate, common blockers",{projectPath:N.string().describe("Project directory path"),task:N.string().describe("Task description to find similar outcomes for")},T("prjct_outcomes_similar",async e=>{let n=await k(e.projectPath),r=await K.getAll(n);if(r.length===0)return{content:[{type:"text",text:"No outcomes recorded yet."}]};let s=new Set(e.task.toLowerCase().split(/\s+/).filter(E=>E.length>2)),i=r.map(E=>{let _=new Set(E.task.toLowerCase().split(/\s+/).filter(St=>St.length>2)),X=[...s].filter(St=>_.has(St)).length,ht=s.size>0?X/s.size:0;return{outcome:E,similarity:ht}}).filter(E=>E.similarity>=.2).sort((E,_)=>_.similarity-E.similarity).slice(0,10);if(i.length===0)return{content:[{type:"text",text:"No similar past tasks found."}]};let a=i.filter(E=>E.outcome.completedAsPlanned).length,c=Math.round(a/i.length*100),l=i.map(E=>{let _=E.outcome.actualDuration.match(/(\d+)/);return _?Number.parseInt(_[1],10):0}).filter(E=>E>0),p=l.length>0?Math.round(l.reduce((E,_)=>E+_,0)/l.length):0,m=i.flatMap(E=>E.outcome.blockers||[]),g={};for(let E of m)g[E]=(g[E]||0)+1;let h=Object.entries(g).sort(([,E],[,_])=>_-E).slice(0,3),A=[`## Similar Tasks (${i.length} matches)`,`
615
+ **Success rate**: ${c}% (${a}/${i.length})`];p>0&&A.push(`**Avg duration**: ${p}m`),h.length>0&&A.push(`**Common blockers**: ${h.map(([E,_])=>`${E} (${_}x)`).join(", ")}`),A.push(`
616
+ ### Past tasks`);for(let{outcome:E,similarity:_}of i){let X=E.completedAsPlanned?"ok":"issues";A.push(`- [${X}] **${E.task}** \u2014 ${E.actualDuration} (${Math.round(_*100)}% similar)`)}return{content:[{type:"text",text:A.join(`
617
+ `)}]}})),t.tool("prjct_outcomes_recent","Last N outcomes with optional command/agent filter",{projectPath:N.string().describe("Project directory path"),count:N.number().optional().default(10).describe("Number of recent outcomes (default 10)"),command:N.string().optional().describe('Filter by command (e.g. "done", "ship")'),agent:N.string().optional().describe("Filter by agent used")},T("prjct_outcomes_recent",async e=>{let n=await k(e.projectPath),r;if(e.command?(r=await K.getByCommand(n,e.command),r=r.slice(-e.count)):e.agent?(r=await K.getByAgent(n,e.agent),r=r.slice(-e.count)):r=await K.getRecent(n,e.count),r.length===0)return{content:[{type:"text",text:"No outcomes found."}]};let s=[`## Recent Outcomes (${r.length})`],i=e.command?` [command: ${e.command}]`:e.agent?` [agent: ${e.agent}]`:"";i&&(s[0]+=i),s.push("");for(let a of r){let l=[`- [${a.completedAsPlanned?"ok":"issues"}] **${a.task}** \u2014 ${a.actualDuration}`];a.command&&l.push(` Command: ${a.command}`),a.variance&&l.push(` Variance: ${a.variance}`),a.blockers?.length&&l.push(` Blockers: ${a.blockers.join(", ")}`),s.push(l.join(`
614
618
  `))}return{content:[{type:"text",text:s.join(`
615
- `)}]}})),e.tool("prjct_estimate_accuracy","Overall estimation accuracy % + per-category over/under patterns",{projectPath:A.string().describe("Project directory path")},T("prjct_estimate_accuracy",async t=>{let r=await w(t.projectPath),n=await Y.getAll(r);if(n.length===0)return{content:[{type:"text",text:"No outcome data yet."}]};let s=await Y.getEstimateAccuracy(r),i=wt(n,rt),a=["## Estimation Accuracy",`Overall: ${s}%`,`Total outcomes: ${n.length}`];if(i.overEstimated.length>0){a.push(`
619
+ `)}]}})),t.tool("prjct_estimate_accuracy","Overall estimation accuracy % + per-category over/under patterns",{projectPath:N.string().describe("Project directory path")},T("prjct_estimate_accuracy",async e=>{let n=await k(e.projectPath),r=await K.getAll(n);if(r.length===0)return{content:[{type:"text",text:"No outcome data yet."}]};let s=await K.getEstimateAccuracy(n),i=wt(r,st),a=["## Estimation Accuracy",`Overall: ${s}%`,`Total outcomes: ${r.length}`];if(i.overEstimated.length>0){a.push(`
616
620
  ### Over-Estimated (finish faster than expected)`);for(let c of i.overEstimated)a.push(`- **${c.category}**: ${c.avgVariance}% faster (${c.taskCount} tasks)`)}if(i.underEstimated.length>0){a.push(`
617
621
  ### Under-Estimated (take longer than expected)`);for(let c of i.underEstimated)a.push(`- **${c.category}**: ${c.avgVariance}% longer (${c.taskCount} tasks)`)}return i.overEstimated.length===0&&i.underEstimated.length===0&&a.push(`
618
622
  No significant estimation patterns detected.`),{content:[{type:"text",text:a.join(`
619
- `)}]}})),e.tool("prjct_velocity_detail","Sprint-by-sprint breakdown + completion projection",{projectPath:A.string().describe("Project directory path"),remainingPoints:A.number().optional().describe("Remaining story points for completion projection")},T("prjct_velocity_detail",async t=>{let r=await w(t.projectPath),n=await Y.getAll(r);if(n.length===0)return{content:[{type:"text",text:"No outcome data yet."}]};let s=wt(n,rt);if(s.sprints.length===0)return{content:[{type:"text",text:"Not enough data for velocity."}]};let i=["## Velocity Detail",`Average: ${s.averageVelocity} pts/sprint`,`Trend: ${s.velocityTrend}`,`Estimation accuracy: ${s.estimationAccuracy}%`,`
620
- ### Sprints (${s.sprints.length})`];for(let a of s.sprints)i.push(`- Sprint ${a.sprintNumber}: ${a.pointsCompleted} pts, ${a.tasksCompleted} tasks, accuracy ${a.estimationAccuracy}%${a.avgVariance?`, variance ${a.avgVariance>0?"+":""}${a.avgVariance}%`:""}`);if(t.remainingPoints&&s.averageVelocity>0){let{projectCompletion:a}=await Promise.resolve().then(()=>(Oe(),yr)),c=a(t.remainingPoints,s.averageVelocity,rt);i.push(`
623
+ `)}]}})),t.tool("prjct_velocity_detail","Sprint-by-sprint breakdown + completion projection",{projectPath:N.string().describe("Project directory path"),remainingPoints:N.number().optional().describe("Remaining story points for completion projection")},T("prjct_velocity_detail",async e=>{let n=await k(e.projectPath),r=await K.getAll(n);if(r.length===0)return{content:[{type:"text",text:"No outcome data yet."}]};let s=wt(r,st);if(s.sprints.length===0)return{content:[{type:"text",text:"Not enough data for velocity."}]};let i=["## Velocity Detail",`Average: ${s.averageVelocity} pts/sprint`,`Trend: ${s.velocityTrend}`,`Estimation accuracy: ${s.estimationAccuracy}%`,`
624
+ ### Sprints (${s.sprints.length})`];for(let a of s.sprints)i.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(()=>(We(),_n)),c=a(e.remainingPoints,s.averageVelocity,st);i.push(`
621
625
  ### Completion Projection`),i.push(`Remaining: ${c.totalPoints} points`),i.push(`Sprints needed: ${c.sprints}`),c.estimatedDate&&i.push(`Estimated completion: ${c.estimatedDate.slice(0,10)}`)}return{content:[{type:"text",text:i.join(`
622
- `)}]}}))}u(kr,"registerProjectTools");import{execSync as Ue}from"node:child_process";import xr from"node:fs";import mt from"node:path";import{z as gt}from"zod";var Ro=new q;function Co(o){try{return Ue("git diff --cached --name-only --diff-filter=ACMR",{cwd:o,encoding:"utf-8",timeout:1e4}).trim().split(`
623
- `).filter(t=>t.length>0)}catch{return[]}}u(Co,"getStagedFiles");function jo(o){try{return Ue("git diff --name-only --diff-filter=ACMR",{cwd:o,encoding:"utf-8",timeout:1e4}).trim().split(`
624
- `).filter(t=>t.length>0)}catch{return[]}}u(jo,"getChangedFiles");function Do(o,e){try{return Ue(e?"git diff --cached":"git diff",{cwd:o,encoding:"utf-8",timeout:15e3,maxBuffer:1024*1024}).trim()}catch{return""}}u(Do,"getDiff");function Sr(o,e=3e3){try{let t=xr.readFileSync(o,"utf-8");return t.length>e?`${t.slice(0,e)}
625
- ... [truncated at ${e} chars]`:t}catch{return null}}u(Sr,"readFileSafe");function Ao(o,e,t){let r=o;return e&&e.length>0&&(r=r.filter(n=>e.some(s=>_r(n,s)))),t&&t.length>0&&(r=r.filter(n=>!t.some(s=>_r(n,s)))),r}u(Ao,"filterFiles");function _r(o,e){return e.startsWith("*.")?o.endsWith(e.slice(1)):e.startsWith("**/*.")?o.endsWith(e.slice(3)):o.includes(e)}u(_r,"matchGlob");function vr(o){o.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:gt.string().describe("Project directory path"),include:gt.array(gt.string()).optional().describe('File patterns to include (e.g. ["*.ts", "*.tsx"])'),exclude:gt.array(gt.string()).optional().describe('File patterns to exclude (e.g. ["*.test.ts"])'),rulesFile:gt.string().optional().default("AGENTS.md").describe("Rules file path (default: AGENTS.md)")},T("prjct_review_context",async t=>{let r=await w(t.projectPath),n=[],s=Co(t.projectPath),i=s.length>0,a=i?"staged":"changed";if(s.length===0&&(s=jo(t.projectPath)),s.length===0)return{content:[{type:"text",text:"No staged or changed files to review."}]};if(s=Ao(s,t.include,t.exclude),s.length===0)return{content:[{type:"text",text:"No files match include/exclude filters."}]};n.push(`## Code Review Context (${s.length} ${a} files)
626
- `);let c=mt.join(t.projectPath,t.rulesFile),l=Sr(c);l&&(n.push(`### Rules (${t.rulesFile})
627
- `),n.push("```markdown"),n.push(l),n.push("```\n"));let p=nt.getActive(r);if(p){if(p.patterns?.length){n.push(`### Project Patterns (follow these)
628
- `);for(let E of p.patterns)n.push(`- **${E.name}**: ${E.description}`);n.push("")}if(p.antiPatterns?.length){n.push(`### Anti-Patterns (flag these)
629
- `);for(let E of p.antiPatterns)n.push(`- **${E.issue}**: ${E.suggestion}`);n.push("")}if(p.conventions?.length){n.push(`### Conventions
630
- `);for(let E of p.conventions)n.push(`- [${E.category}] ${E.rule}`);n.push("")}}let m=s.map(E=>mt.basename(E,mt.extname(E))).join(" "),g=await Ro.searchMemories(r,`bug ${m}`,5);if(g.length>0){n.push(`### Related Bug Memories
631
- `);for(let E of g)n.push(`- **${E.title}**: ${E.content.slice(0,200)}`);n.push("")}let h=Do(t.projectPath,i);h&&(n.push(`### Git Diff
632
- `),n.push("```diff"),n.push(h.length>2e4?`${h.slice(0,2e4)}
633
- ... [diff truncated]`:h),n.push("```\n"));let R=s.filter(E=>{try{return xr.statSync(mt.join(t.projectPath,E)).size<3e3}catch{return!1}});if(R.length>0){n.push(`### Small Files (full content)
634
- `);for(let E of R.slice(0,10)){let _=mt.join(t.projectPath,E),X=Sr(_);if(X){n.push(`#### \`${E}\`
635
- `);let ft=mt.extname(E).slice(1)||"text";n.push(`\`\`\`${ft}`),n.push(X),n.push("```\n")}}}return n.push(`### Review Instructions
636
- `),n.push("Review the diff above against the rules, patterns, and conventions."),n.push("For each file, check:"),n.push("1. Compliance with rules (AGENTS.md)"),n.push("2. Known anti-patterns (flag any matches)"),n.push("3. Convention violations"),n.push("4. Past bug patterns from memory"),n.push(`5. General code quality
637
- `),n.push("End your review with: **STATUS: PASSED** or **STATUS: FAILED**"),n.push("If FAILED, list specific violations with file:line references."),{content:[{type:"text",text:n.join(`
638
- `)}]}}))}u(vr,"registerReviewTools");import{z as j}from"zod";N();var No=new q;function Pr(o){let e=o;e.tool("prjct_session_start","Start an agent session. Auto-links to active prjct task if one exists.",{projectPath:j.string().describe("Project directory path"),goal:j.string().optional().describe("Session goal or objective")},T("prjct_session_start",async t=>{let r=await w(t.projectPath),n=f(),s=O(),i=await U.getCurrentTask(r),a=i?.id??null;y.run(r,`INSERT INTO agent_sessions (id, project_id, directory, task_id, goal, started_at, created_at)
639
- VALUES (?, ?, ?, ?, ?, ?, ?)`,s,r,t.projectPath,a,t.goal??null,n,n);let c=[`Session started: ${s}`];return i&&(c.push(`Linked to task: ${i.description}`),c.push(`Task started: ${i.startedAt}`)),t.goal&&c.push(`Goal: ${t.goal}`),{content:[{type:"text",text:c.join(`
640
- `)}]}})),e.tool("prjct_session_end","End the current agent session with optional summary",{projectPath:j.string().describe("Project directory path"),sessionId:j.string().describe("Session ID to end"),summary:j.string().optional().describe("Brief session summary")},T("prjct_session_end",async t=>{let r=await w(t.projectPath),n=f();return y.get(r,"SELECT * FROM agent_sessions WHERE id = ? AND project_id = ?",t.sessionId,r)?(y.run(r,"UPDATE agent_sessions SET ended_at = ?, summary = ? WHERE id = ?",n,t.summary??null,t.sessionId),{content:[{type:"text",text:"Session ended."}]}):{content:[{type:"text",text:`Session ${t.sessionId} not found.`}]}})),e.tool("prjct_session_summary","Save structured end-of-session summary (Goal/Accomplished/Discoveries/Next Steps/Files)",{projectPath:j.string().describe("Project directory path"),sessionId:j.string().describe("Session ID"),goal:j.string().describe("What was the goal"),accomplished:j.string().describe("What was accomplished"),discoveries:j.string().optional().describe("Key discoveries or learnings"),nextSteps:j.string().optional().describe("What should happen next"),filesTouched:j.array(j.string()).optional().describe("Files modified during session")},T("prjct_session_summary",async t=>{let r=await w(t.projectPath),n=f(),s=[`## Goal
641
- ${t.goal}`,`## Accomplished
642
- ${t.accomplished}`];t.discoveries&&s.push(`## Discoveries
643
- ${t.discoveries}`),t.nextSteps&&s.push(`## Next Steps
644
- ${t.nextSteps}`);let i=s.join(`
645
-
646
- `),a=t.filesTouched?JSON.stringify(t.filesTouched):null;return y.run(r,"UPDATE agent_sessions SET ended_at = ?, summary = ?, goal = ?, files_touched = ? WHERE id = ? AND project_id = ?",n,i,t.goal,a,t.sessionId,r),{content:[{type:"text",text:`Session summary saved (${i.length} chars).`}]}})),e.tool("prjct_prompt_save","Capture user prompt text for future context",{projectPath:j.string().describe("Project directory path"),content:j.string().describe("User prompt text"),sessionId:j.string().optional().describe("Current session ID")},T("prjct_prompt_save",async t=>{let r=await w(t.projectPath),n=O();return y.run(r,"INSERT INTO user_prompts (id, project_id, session_id, content, created_at) VALUES (?, ?, ?, ?, ?)",n,r,t.sessionId??null,t.content,f()),{content:[{type:"text",text:`Prompt saved: ${n}`}]}})),e.tool("prjct_session_context","Recover context after compaction: last session + relevant/recent memories + active task state",{projectPath:j.string().describe("Project directory path"),memoryLimit:j.number().optional().default(5).describe("Max memories to include (default 5)"),promptLimit:j.number().optional().default(3).describe("Max prompts to include (default 3)")},T("prjct_session_context",async t=>{let r=await w(t.projectPath),n=[],s=await U.getCurrentTask(r);s?(n.push("## Active Task"),n.push(`**${s.description}**`),s.branch&&n.push(`Branch: ${s.branch}`),n.push(`Started: ${s.startedAt}`)):n.push("## No Active Task");let i=y.get(r,`SELECT * FROM agent_sessions WHERE project_id = ?
647
- ORDER BY started_at DESC LIMIT 1`,r);if(i&&(n.push(`
648
- ## Last Session`),i.goal&&n.push(`Goal: ${i.goal}`),i.summary&&n.push(i.summary),i.ended_at?n.push(`Ended: ${i.ended_at}`):n.push("Status: **still open** (may have been interrupted)"),i.files_touched))try{let c=JSON.parse(i.files_touched);c.length>0&&n.push(`Files: ${c.join(", ")}`)}catch{}if(s){let c=await No.getRelevantMemories(r,{params:{description:s.description}},t.memoryLimit);if(c.length>0){n.push(`
649
- ## Relevant Memories`);for(let l of c)n.push(`- **${l.title}**: ${l.content.slice(0,150)}${l.content.length>150?"...":""}`)}}else{let c=y.query(r,`SELECT id, title, content, tags, updated_at FROM memories
626
+ `)}]}}))}u(Cn,"registerProjectTools");import{execSync as Ge}from"node:child_process";import jn from"node:fs";import gt from"node:path";import{z as ft}from"zod";var Lo=new Y;function $o(o){try{return Ge("git diff --cached --name-only --diff-filter=ACMR",{cwd:o,encoding:"utf-8",timeout:1e4}).trim().split(`
627
+ `).filter(e=>e.length>0)}catch{return[]}}u($o,"getStagedFiles");function Fo(o){try{return Ge("git diff --name-only --diff-filter=ACMR",{cwd:o,encoding:"utf-8",timeout:1e4}).trim().split(`
628
+ `).filter(e=>e.length>0)}catch{return[]}}u(Fo,"getChangedFiles");function Uo(o,t){try{return Ge(t?"git diff --cached":"git diff",{cwd:o,encoding:"utf-8",timeout:15e3,maxBuffer:1024*1024}).trim()}catch{return""}}u(Uo,"getDiff");function An(o,t=3e3){try{let e=jn.readFileSync(o,"utf-8");return e.length>t?`${e.slice(0,t)}
629
+ ... [truncated at ${t} chars]`:e}catch{return null}}u(An,"readFileSafe");function Wo(o,t,e){let n=o;return t&&t.length>0&&(n=n.filter(r=>t.some(s=>Dn(r,s)))),e&&e.length>0&&(n=n.filter(r=>!e.some(s=>Dn(r,s)))),n}u(Wo,"filterFiles");function Dn(o,t){return t.startsWith("*.")?o.endsWith(t.slice(1)):t.startsWith("**/*.")?o.endsWith(t.slice(3)):o.includes(t)}u(Dn,"matchGlob");function Nn(o){o.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:ft.string().describe("Project directory path"),include:ft.array(ft.string()).optional().describe('File patterns to include (e.g. ["*.ts", "*.tsx"])'),exclude:ft.array(ft.string()).optional().describe('File patterns to exclude (e.g. ["*.test.ts"])'),rulesFile:ft.string().optional().default("AGENTS.md").describe("Rules file path (default: AGENTS.md)")},T("prjct_review_context",async e=>{let n=await k(e.projectPath),r=[],s=$o(e.projectPath),i=s.length>0,a=i?"staged":"changed";if(s.length===0&&(s=Fo(e.projectPath)),s.length===0)return{content:[{type:"text",text:"No staged or changed files to review."}]};if(s=Wo(s,e.include,e.exclude),s.length===0)return{content:[{type:"text",text:"No files match include/exclude filters."}]};r.push(`## Code Review Context (${s.length} ${a} files)
630
+ `);let c=gt.join(e.projectPath,e.rulesFile),l=An(c);l&&(r.push(`### Rules (${e.rulesFile})
631
+ `),r.push("```markdown"),r.push(l),r.push("```\n"));let p=nt.getActive(n);if(p){if(p.patterns?.length){r.push(`### Project Patterns (follow these)
632
+ `);for(let E of p.patterns)r.push(`- **${E.name}**: ${E.description}`);r.push("")}if(p.antiPatterns?.length){r.push(`### Anti-Patterns (flag these)
633
+ `);for(let E of p.antiPatterns)r.push(`- **${E.issue}**: ${E.suggestion}`);r.push("")}if(p.conventions?.length){r.push(`### Conventions
634
+ `);for(let E of p.conventions)r.push(`- [${E.category}] ${E.rule}`);r.push("")}}let m=s.map(E=>gt.basename(E,gt.extname(E))).join(" "),g=await Lo.searchMemories(n,`bug ${m}`,5);if(g.length>0){r.push(`### Related Bug Memories
635
+ `);for(let E of g)r.push(`- **${E.title}**: ${E.content.slice(0,200)}`);r.push("")}let h=Uo(e.projectPath,i);h&&(r.push(`### Git Diff
636
+ `),r.push("```diff"),r.push(h.length>2e4?`${h.slice(0,2e4)}
637
+ ... [diff truncated]`:h),r.push("```\n"));let A=s.filter(E=>{try{return jn.statSync(gt.join(e.projectPath,E)).size<3e3}catch{return!1}});if(A.length>0){r.push(`### Small Files (full content)
638
+ `);for(let E of A.slice(0,10)){let _=gt.join(e.projectPath,E),X=An(_);if(X){r.push(`#### \`${E}\`
639
+ `);let ht=gt.extname(E).slice(1)||"text";r.push(`\`\`\`${ht}`),r.push(X),r.push("```\n")}}}return r.push(`### Review Instructions
640
+ `),r.push("Review the diff above against the rules, patterns, and conventions."),r.push("For each file, check:"),r.push("1. Compliance with rules (AGENTS.md)"),r.push("2. Known anti-patterns (flag any matches)"),r.push("3. Convention violations"),r.push("4. Past bug patterns from memory"),r.push(`5. General code quality
641
+ `),r.push("End your review with: **STATUS: PASSED** or **STATUS: FAILED**"),r.push("If FAILED, list specific violations with file:line references."),{content:[{type:"text",text:r.join(`
642
+ `)}]}}))}u(Nn,"registerReviewTools");import{z as j}from"zod";I();var Xo=new Y;function Mn(o){let t=o;t.tool("prjct_session_start","Start an agent session. Auto-links to active prjct task if one exists.",{projectPath:j.string().describe("Project directory path"),goal:j.string().optional().describe("Session goal or objective")},T("prjct_session_start",async e=>{let n=await k(e.projectPath),r=f(),s=$(),i=await W.getCurrentTask(n),a=i?.id??null;y.run(n,`INSERT INTO agent_sessions (id, project_id, directory, task_id, goal, started_at, created_at)
643
+ VALUES (?, ?, ?, ?, ?, ?, ?)`,s,n,e.projectPath,a,e.goal??null,r,r);let c=[`Session started: ${s}`];return i&&(c.push(`Linked to task: ${i.description}`),c.push(`Task started: ${i.startedAt}`)),e.goal&&c.push(`Goal: ${e.goal}`),{content:[{type:"text",text:c.join(`
644
+ `)}]}})),t.tool("prjct_session_end","End the current agent session with optional summary",{projectPath:j.string().describe("Project directory path"),sessionId:j.string().describe("Session ID to end"),summary:j.string().optional().describe("Brief session summary")},T("prjct_session_end",async e=>{let n=await k(e.projectPath),r=f();return y.get(n,"SELECT * FROM agent_sessions WHERE id = ? AND project_id = ?",e.sessionId,n)?(y.run(n,"UPDATE agent_sessions SET ended_at = ?, summary = ? WHERE id = ?",r,e.summary??null,e.sessionId),{content:[{type:"text",text:"Session ended."}]}):{content:[{type:"text",text:`Session ${e.sessionId} not found.`}]}})),t.tool("prjct_session_summary","Save structured end-of-session summary (Goal/Accomplished/Discoveries/Next Steps/Files)",{projectPath:j.string().describe("Project directory path"),sessionId:j.string().describe("Session ID"),goal:j.string().describe("What was the goal"),accomplished:j.string().describe("What was accomplished"),discoveries:j.string().optional().describe("Key discoveries or learnings"),nextSteps:j.string().optional().describe("What should happen next"),filesTouched:j.array(j.string()).optional().describe("Files modified during session")},T("prjct_session_summary",async e=>{let n=await k(e.projectPath),r=f(),s=[`## Goal
645
+ ${e.goal}`,`## Accomplished
646
+ ${e.accomplished}`];e.discoveries&&s.push(`## Discoveries
647
+ ${e.discoveries}`),e.nextSteps&&s.push(`## Next Steps
648
+ ${e.nextSteps}`);let i=s.join(`
649
+
650
+ `),a=e.filesTouched?JSON.stringify(e.filesTouched):null;return y.run(n,"UPDATE agent_sessions SET ended_at = ?, summary = ?, goal = ?, files_touched = ? WHERE id = ? AND project_id = ?",r,i,e.goal,a,e.sessionId,n),{content:[{type:"text",text:`Session summary saved (${i.length} chars).`}]}})),t.tool("prjct_prompt_save","Capture user prompt text for future context",{projectPath:j.string().describe("Project directory path"),content:j.string().describe("User prompt text"),sessionId:j.string().optional().describe("Current session ID")},T("prjct_prompt_save",async e=>{let n=await k(e.projectPath),r=$();return y.run(n,"INSERT INTO user_prompts (id, project_id, session_id, content, created_at) VALUES (?, ?, ?, ?, ?)",r,n,e.sessionId??null,e.content,f()),{content:[{type:"text",text:`Prompt saved: ${r}`}]}})),t.tool("prjct_session_context","Recover context after compaction: last session + relevant/recent memories + active task state",{projectPath:j.string().describe("Project directory path"),memoryLimit:j.number().optional().default(5).describe("Max memories to include (default 5)"),promptLimit:j.number().optional().default(3).describe("Max prompts to include (default 3)")},T("prjct_session_context",async e=>{let n=await k(e.projectPath),r=[],s=await W.getCurrentTask(n);s?(r.push("## Active Task"),r.push(`**${s.description}**`),s.branch&&r.push(`Branch: ${s.branch}`),r.push(`Started: ${s.startedAt}`)):r.push("## No Active Task");let i=y.get(n,`SELECT * FROM agent_sessions WHERE project_id = ?
651
+ ORDER BY started_at DESC LIMIT 1`,n);if(i&&(r.push(`
652
+ ## Last Session`),i.goal&&r.push(`Goal: ${i.goal}`),i.summary&&r.push(i.summary),i.ended_at?r.push(`Ended: ${i.ended_at}`):r.push("Status: **still open** (may have been interrupted)"),i.files_touched))try{let c=JSON.parse(i.files_touched);c.length>0&&r.push(`Files: ${c.join(", ")}`)}catch{}if(s){let c=await Xo.getRelevantMemories(n,{params:{description:s.description}},e.memoryLimit);if(c.length>0){r.push(`
653
+ ## Relevant Memories`);for(let l of c)r.push(`- **${l.title}**: ${l.content.slice(0,150)}${l.content.length>150?"...":""}`)}}else{let c=y.query(n,`SELECT id, title, content, tags, updated_at FROM memories
650
654
  WHERE project_id = ? AND deleted_at IS NULL
651
- ORDER BY updated_at DESC LIMIT ?`,r,t.memoryLimit);if(c.length>0){n.push(`
652
- ## Recent Memories`);for(let l of c)n.push(`- **${l.title}**: ${l.content.slice(0,150)}${l.content.length>150?"...":""}`)}}let a=y.query(r,`SELECT * FROM user_prompts WHERE project_id = ?
653
- ORDER BY created_at DESC LIMIT ?`,r,t.promptLimit);if(a.length>0){n.push(`
654
- ## Recent User Prompts`);for(let c of a)n.push(`- ${c.content.slice(0,200)}${c.content.length>200?"...":""}`)}return n.length===0?{content:[{type:"text",text:"No session context available."}]}:{content:[{type:"text",text:n.join(`
655
- `)}]}}))}u(Pr,"registerSessionTools");import{z as Gt}from"zod";var Xe=class{static{u(this,"CustomWorkflowStorage")}createWorkflow(e,t){let r=new Date().toISOString();y.run(e,`INSERT INTO custom_workflows (name, description, created_at, updated_at, is_builtin, enabled, metadata)
656
- VALUES (?, ?, ?, ?, 0, 1, ?)`,t.name,t.description??null,r,r,t.metadata?JSON.stringify(t.metadata):null);let n=y.get(e,"SELECT id FROM custom_workflows WHERE name = ?",t.name);if(!n)throw new Error(`Failed to create workflow: ${t.name}`);return n.id}getWorkflow(e,t){let r=y.get(e,"SELECT * FROM custom_workflows WHERE name = ?",t);return r?this.rowToWorkflow(r):null}getAllWorkflows(e,t=!1){let r=t?"SELECT * FROM custom_workflows ORDER BY is_builtin DESC, name ASC":"SELECT * FROM custom_workflows WHERE enabled = 1 ORDER BY is_builtin DESC, name ASC";return y.query(e,r).map(s=>this.rowToWorkflow(s))}updateWorkflow(e,t,r){if(!this.getWorkflow(e,t))return!1;let s=new Date().toISOString(),i=[],a=[];return r.description!==void 0&&(i.push("description = ?"),a.push(r.description)),r.enabled!==void 0&&(i.push("enabled = ?"),a.push(r.enabled?1:0)),r.metadata!==void 0&&(i.push("metadata = ?"),a.push(JSON.stringify(r.metadata))),i.length===0?!1:(i.push("updated_at = ?"),a.push(s),a.push(t),y.run(e,`UPDATE custom_workflows SET ${i.join(", ")} WHERE name = ?`,...a),!0)}deleteWorkflow(e,t){let r=this.getWorkflow(e,t);if(!r)return!1;if(r.isBuiltin)throw new Error(`Cannot delete built-in workflow: ${t}`);return y.run(e,"UPDATE custom_workflows SET enabled = 0 WHERE name = ?",t),!0}isBuiltin(e,t){return this.getWorkflow(e,t)?.isBuiltin??!1}isReservedName(e){let t=["task","done","ship","sync"],r=["add","rm","gate","list","create","delete","run","help","reset","init"];return t.includes(e)||r.includes(e)}isValidName(e){return/^[a-z0-9-]+$/.test(e)}rowToWorkflow(e){return{id:e.id,name:e.name,description:e.description,createdAt:e.created_at,updatedAt:e.updated_at,isBuiltin:e.is_builtin===1,enabled:e.enabled===1,metadata:e.metadata?JSON.parse(e.metadata):null}}},Bt=new Xe;function We(o){return{id:o.id,type:o.type,command:o.command,position:o.position,action:o.action,description:o.description,enabled:o.enabled===1,timeoutMs:o.timeout_ms,createdAt:o.created_at,sortOrder:o.sort_order}}u(We,"rowToRule");var He=class{static{u(this,"WorkflowRuleStorage")}addRule(e,t){let r=S.get(e,"SELECT MAX(sort_order) as m FROM workflow_rules WHERE command = ?",t.command),n=t.sortOrder||(r?.m??-1)+1;return S.run(e,`INSERT INTO workflow_rules (type, command, position, action, description, enabled, timeout_ms, created_at, sort_order)
657
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,t.type,t.command,t.position,t.action,t.description??null,t.enabled?1:0,t.timeoutMs,t.createdAt,n),S.get(e,"SELECT last_insert_rowid() as id")?.id??0}removeRule(e,t){return S.get(e,"SELECT id FROM workflow_rules WHERE id = ?",t)?(S.run(e,"DELETE FROM workflow_rules WHERE id = ?",t),!0):!1}updateRule(e,t,r){if(!S.get(e,"SELECT id FROM workflow_rules WHERE id = ?",t))return!1;let s={type:{column:"type"},command:{column:"command"},position:{column:"position"},action:{column:"action"},description:{column:"description"},enabled:{column:"enabled",transform:u(c=>c?1:0,"transform")},timeoutMs:{column:"timeout_ms"},createdAt:{column:"created_at"},sortOrder:{column:"sort_order"}},i=[],a=[];for(let[c,l]of Object.entries(r)){let p=s[c];if(!p)continue;i.push(`${p.column} = ?`);let m=l;a.push(p.transform?p.transform(m):m)}return i.length===0||(a.push(t),S.run(e,`UPDATE workflow_rules SET ${i.join(", ")} WHERE id = ?`,...a)),!0}getRuleById(e,t){let r=S.get(e,"SELECT * FROM workflow_rules WHERE id = ?",t);return r?We(r):null}getRulesForCommand(e,t){let r=Bt.getWorkflow(e,t);return!r||!r.enabled?[]:S.query(e,"SELECT * FROM workflow_rules WHERE command = ? AND enabled = 1 ORDER BY sort_order ASC",t).map(We)}getAllRules(e){return S.query(e,"SELECT * FROM workflow_rules ORDER BY command ASC, sort_order ASC").map(We)}resetRules(e){let t=S.get(e,"SELECT COUNT(*) as c FROM workflow_rules");return S.run(e,"DELETE FROM workflow_rules"),t?.c??0}},Be=new He;function Rr(o){let e=o;e.tool("prjct_workflow_rules","Get workflow rules for a command (gates, hooks, steps, instructions)",{projectPath:Gt.string().describe("Project directory path"),command:Gt.string().describe("Command name (task, done, ship, sync, etc.)")},T("prjct_workflow_rules",async t=>{let r=await w(t.projectPath),n=Be.getRulesForCommand(r,t.command);if(n.length===0)return{content:[{type:"text",text:`No workflow rules for \`${t.command}\`.`}]};let s={};for(let a of n){let c=`${a.type}:${a.position}`;s[c]||(s[c]=[]),s[c].push(a)}let i=[`## Workflow Rules for \`${t.command}\``];for(let[a,c]of Object.entries(s)){i.push(`
655
+ ORDER BY updated_at DESC LIMIT ?`,n,e.memoryLimit);if(c.length>0){r.push(`
656
+ ## Recent Memories`);for(let l of c)r.push(`- **${l.title}**: ${l.content.slice(0,150)}${l.content.length>150?"...":""}`)}}let a=y.query(n,`SELECT * FROM user_prompts WHERE project_id = ?
657
+ ORDER BY created_at DESC LIMIT ?`,n,e.promptLimit);if(a.length>0){r.push(`
658
+ ## Recent User Prompts`);for(let c of a)r.push(`- ${c.content.slice(0,200)}${c.content.length>200?"...":""}`)}return r.length===0?{content:[{type:"text",text:"No session context available."}]}:{content:[{type:"text",text:r.join(`
659
+ `)}]}}))}u(Mn,"registerSessionTools");import{z as Vt}from"zod";var Ve=class{static{u(this,"CustomWorkflowStorage")}createWorkflow(t,e){let n=new Date().toISOString();y.run(t,`INSERT INTO custom_workflows (name, description, created_at, updated_at, is_builtin, enabled, metadata)
660
+ VALUES (?, ?, ?, ?, 0, 1, ?)`,e.name,e.description??null,n,n,e.metadata?JSON.stringify(e.metadata):null);let r=y.get(t,"SELECT id FROM custom_workflows WHERE name = ?",e.name);if(!r)throw new Error(`Failed to create workflow: ${e.name}`);return r.id}getWorkflow(t,e){let n=y.get(t,"SELECT * FROM custom_workflows WHERE name = ?",e);return n?this.rowToWorkflow(n):null}getAllWorkflows(t,e=!1){let n=e?"SELECT * FROM custom_workflows ORDER BY is_builtin DESC, name ASC":"SELECT * FROM custom_workflows WHERE enabled = 1 ORDER BY is_builtin DESC, name ASC";return y.query(t,n).map(s=>this.rowToWorkflow(s))}updateWorkflow(t,e,n){if(!this.getWorkflow(t,e))return!1;let s=new Date().toISOString(),i=[],a=[];return n.description!==void 0&&(i.push("description = ?"),a.push(n.description)),n.enabled!==void 0&&(i.push("enabled = ?"),a.push(n.enabled?1:0)),n.metadata!==void 0&&(i.push("metadata = ?"),a.push(JSON.stringify(n.metadata))),i.length===0?!1:(i.push("updated_at = ?"),a.push(s),a.push(e),y.run(t,`UPDATE custom_workflows SET ${i.join(", ")} WHERE name = ?`,...a),!0)}deleteWorkflow(t,e){let n=this.getWorkflow(t,e);if(!n)return!1;if(n.isBuiltin)throw new Error(`Cannot delete built-in workflow: ${e}`);return y.run(t,"UPDATE custom_workflows SET enabled = 0 WHERE name = ?",e),!0}isBuiltin(t,e){return this.getWorkflow(t,e)?.isBuiltin??!1}isReservedName(t){let e=["task","done","ship","sync"],n=["add","rm","gate","list","create","delete","run","help","reset","init"];return e.includes(t)||n.includes(t)}isValidName(t){return/^[a-z0-9-]+$/.test(t)}rowToWorkflow(t){return{id:t.id,name:t.name,description:t.description,createdAt:t.created_at,updatedAt:t.updated_at,isBuiltin:t.is_builtin===1,enabled:t.enabled===1,metadata:t.metadata?JSON.parse(t.metadata):null}}},Gt=new Ve;function ze(o){return{id:o.id,type:o.type,command:o.command,position:o.position,action:o.action,description:o.description,enabled:o.enabled===1,timeoutMs:o.timeout_ms,createdAt:o.created_at,sortOrder:o.sort_order}}u(ze,"rowToRule");var qe=class{static{u(this,"WorkflowRuleStorage")}addRule(t,e){let n=S.get(t,"SELECT MAX(sort_order) as m FROM workflow_rules WHERE command = ?",e.command),r=e.sortOrder||(n?.m??-1)+1;return S.run(t,`INSERT INTO workflow_rules (type, command, position, action, description, enabled, timeout_ms, created_at, sort_order)
661
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,e.type,e.command,e.position,e.action,e.description??null,e.enabled?1:0,e.timeoutMs,e.createdAt,r),S.get(t,"SELECT last_insert_rowid() as id")?.id??0}removeRule(t,e){return S.get(t,"SELECT id FROM workflow_rules WHERE id = ?",e)?(S.run(t,"DELETE FROM workflow_rules WHERE id = ?",e),!0):!1}updateRule(t,e,n){if(!S.get(t,"SELECT id FROM workflow_rules WHERE id = ?",e))return!1;let s={type:{column:"type"},command:{column:"command"},position:{column:"position"},action:{column:"action"},description:{column:"description"},enabled:{column:"enabled",transform:u(c=>c?1:0,"transform")},timeoutMs:{column:"timeout_ms"},createdAt:{column:"created_at"},sortOrder:{column:"sort_order"}},i=[],a=[];for(let[c,l]of Object.entries(n)){let p=s[c];if(!p)continue;i.push(`${p.column} = ?`);let m=l;a.push(p.transform?p.transform(m):m)}return i.length===0||(a.push(e),S.run(t,`UPDATE workflow_rules SET ${i.join(", ")} WHERE id = ?`,...a)),!0}getRuleById(t,e){let n=S.get(t,"SELECT * FROM workflow_rules WHERE id = ?",e);return n?ze(n):null}getRulesForCommand(t,e){let n=Gt.getWorkflow(t,e);return!n||!n.enabled?[]:S.query(t,"SELECT * FROM workflow_rules WHERE command = ? AND enabled = 1 ORDER BY sort_order ASC",e).map(ze)}getAllRules(t){return S.query(t,"SELECT * FROM workflow_rules ORDER BY command ASC, sort_order ASC").map(ze)}resetRules(t){let e=S.get(t,"SELECT COUNT(*) as c FROM workflow_rules");return S.run(t,"DELETE FROM workflow_rules"),e?.c??0}},Ye=new qe;function In(o){let t=o;t.tool("prjct_workflow_rules","Get workflow rules for a command (gates, hooks, steps, instructions)",{projectPath:Vt.string().describe("Project directory path"),command:Vt.string().describe("Command name (task, done, ship, sync, etc.)")},T("prjct_workflow_rules",async e=>{let n=await k(e.projectPath),r=Ye.getRulesForCommand(n,e.command);if(r.length===0)return{content:[{type:"text",text:`No workflow rules for \`${e.command}\`.`}]};let s={};for(let a of r){let c=`${a.type}:${a.position}`;s[c]||(s[c]=[]),s[c].push(a)}let i=[`## Workflow Rules for \`${e.command}\``];for(let[a,c]of Object.entries(s)){i.push(`
658
662
  ### ${a}`);for(let l of c){let p=l.enabled?"":" (disabled)";i.push(`- ${l.action}${l.description?` \u2014 ${l.description}`:""}${p}`)}}return{content:[{type:"text",text:i.join(`
659
- `)}]}})),e.tool("prjct_workflow_list","List all workflows for this project (built-in + custom)",{projectPath:Gt.string().describe("Project directory path")},T("prjct_workflow_list",async t=>{let r=await w(t.projectPath),n=Bt.getAllWorkflows(r);if(n.length===0)return{content:[{type:"text",text:"No workflows configured."}]};let s=n.map(i=>{let a=i.isBuiltin?"(built-in)":"(custom)",c=i.enabled?"":" [disabled]";return`- **${i.name}** ${a}${c}${i.description?`: ${i.description}`:""}`});return{content:[{type:"text",text:`## Workflows (${n.length})
663
+ `)}]}})),t.tool("prjct_workflow_list","List all workflows for this project (built-in + custom)",{projectPath:Vt.string().describe("Project directory path")},T("prjct_workflow_list",async e=>{let n=await k(e.projectPath),r=Gt.getAllWorkflows(n);if(r.length===0)return{content:[{type:"text",text:"No workflows configured."}]};let s=r.map(i=>{let a=i.isBuiltin?"(built-in)":"(custom)",c=i.enabled?"":" [disabled]";return`- **${i.name}** ${a}${c}${i.description?`: ${i.description}`:""}`});return{content:[{type:"text",text:`## Workflows (${r.length})
660
664
 
661
665
  ${s.join(`
662
- `)}`}]}})),e.tool("prjct_workflow_status","Current workflow execution state + active rules",{projectPath:Gt.string().describe("Project directory path")},T("prjct_workflow_status",async t=>{let r=await w(t.projectPath),n=await U.getCurrentTask(r),s=Be.getAllRules(r),i=["## Workflow Status"];n?(i.push(`
663
- Active task: **${n.description}**`),i.push(`Started: ${n.startedAt}`)):i.push(`
666
+ `)}`}]}})),t.tool("prjct_workflow_status","Current workflow execution state + active rules",{projectPath:Vt.string().describe("Project directory path")},T("prjct_workflow_status",async e=>{let n=await k(e.projectPath),r=await W.getCurrentTask(n),s=Ye.getAllRules(n),i=["## Workflow Status"];r?(i.push(`
667
+ Active task: **${r.description}**`),i.push(`Started: ${r.startedAt}`)):i.push(`
664
668
  No active task.`);let a=s.filter(c=>c.enabled);if(a.length>0){i.push(`
665
669
  ### Active Rules (${a.length})`);for(let c of a)i.push(`- [${c.type}] ${c.command}:${c.position} \u2192 ${c.action}`)}else i.push(`
666
670
  No active workflow rules.`);return{content:[{type:"text",text:i.join(`
667
- `)}]}}))}u(Rr,"registerWorkflowTools");var Io=`## prjct Memory Protocol
671
+ `)}]}}))}u(In,"registerWorkflowTools");var Bo=`## prjct Memory Protocol
668
672
 
669
673
  ### On session start:
670
674
  1. Call prjct_session_start to register this session
@@ -701,4 +705,4 @@ No active workflow rules.`);return{content:[{type:"text",text:i.join(`
701
705
  ### On session end:
702
706
  1. Call prjct_session_summary with Goal/Accomplished/Discoveries/Next Steps/Files
703
707
  2. Save any important learnings not yet captured via prjct_mem_save
704
- 3. Call prjct_mem_capture_passive on your final output to auto-extract learnings`;function Cr(){let o=new Mo({name:"prjct",version:"1.0.0"},{instructions:Io});return pr(o),Pr(o),kr(o),cr(o),Rr(o),vr(o),dr(o),Hn(o),Bn(o),o}u(Cr,"createServer");async function Lo(){let o=Cr(),e=new Oo;await o.connect(e)}u(Lo,"main");Lo().catch(o=>{console.error("prjct MCP server failed:",o),process.exit(1)});
708
+ 3. Call prjct_mem_capture_passive on your final output to auto-extract learnings`;function On(){let o=new Ho({name:"prjct",version:"1.0.0"},{instructions:Bo});return Tn(o),Mn(o),Cn(o),fn(o),In(o),Nn(o),En(o),Kr(o),Jr(o),o}u(On,"createServer");async function Vo(){let o=On(),t=new Go;await o.connect(t)}u(Vo,"main");Vo().catch(o=>{console.error("prjct MCP server failed:",o),process.exit(1)});