prjct-cli 2.2.4 → 2.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,12 +5,13 @@ import { dirname as __pathDirname } from 'path';
5
5
  var require = __createRequire(import.meta.url);
6
6
  var __filename = __fileURLToPath(import.meta.url);
7
7
  var __dirname = __pathDirname(__filename);
8
- var ct=Object.defineProperty;var Br=Object.getOwnPropertyDescriptor;var Hr=Object.getOwnPropertyNames;var qr=Object.prototype.hasOwnProperty;var c=(n,t)=>ct(n,"name",{value:t,configurable:!0}),me=(n=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(n,{get:(t,e)=>(typeof require<"u"?require:t)[e]}):n)(function(n){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+n+'" is not supported')});var C=(n,t)=>()=>(n&&(t=n(n=0)),t);var ge=(n,t)=>{for(var e in t)ct(n,e,{get:t[e],enumerable:!0})},zr=(n,t,e,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of Hr(t))!qr.call(n,s)&&s!==e&&ct(n,s,{get:()=>t[s],enumerable:!(r=Br(t,s))||r.enumerable});return n};var vt=n=>zr(ct({},"__esModule",{value:!0}),n);var fe,he,ye,_t=C(()=>{"use strict";fe=new Set(["node_modules",".git","dist","build","out",".next",".nuxt","coverage",".cache",".turbo",".vercel",".parcel-cache","__pycache__",".pytest_cache","target","vendor",".venv","venv","eggs","*.egg-info",".prjct",".worktrees"]),he=["",".ts",".tsx",".js",".jsx","/index.ts","/index.js"],ye=/(?:import|from)\s+['"]([^'"]+)['"]/g});function Jr(n){return n instanceof Error&&"code"in n}function N(n){return Jr(n)&&n.code==="ENOENT"}function ke(n){return n instanceof Error?n.message:typeof n=="string"?n:"Unknown error"}var W=C(()=>{"use strict";c(Jr,"isNodeError");c(N,"isNotFoundError");c(ke,"getErrorMessage")});import Se from"node:fs/promises";async function xe(n,t){let e;try{e=await Se.readFile(n,"utf-8")}catch(o){if(N(o))return null;throw o}let r;try{r=JSON.parse(e)}catch{return await we(n,e),be(n,"Malformed JSON"),null}let s=t.safeParse(r);return s.success?r:(await we(n,e),be(n,Vr(s.error)),null)}async function we(n,t){let e=`${n}.backup`;try{await Se.writeFile(e,t,"utf-8")}catch{}}function be(n,t){console.error(`[prjct] Warning: Corrupted storage file: ${n}`),console.error(`[prjct] Reason: ${t}`),console.error("[prjct] A .backup file has been created. Returning defaults.")}function Vr(n){return n.issues.slice(0,3).map(t=>`${t.path.join(".")}: ${t.message}`).join("; ")}var ve=C(()=>{"use strict";W();c(xe,"safeRead");c(we,"createBackup");c(be,"logCorruption");c(Vr,"formatZodError")});import G from"node:fs/promises";import Pt from"node:path";async function _e(n,t={}){let e=[],r=t.maxFiles??1/0,s=t.dotfileAllowlist?new Set(t.dotfileAllowlist):null;async function o(i){if(e.length>=r)return;let a=await G.readdir(i,{withFileTypes:!0}).catch(()=>[]);for(let u of a){if(e.length>=r)break;let p=String(u.name);if(fe.has(p)||t.skipDotfiles&&p.startsWith(".")&&(!s||!s.has(p)))continue;let m=Pt.join(i,p);u.isDirectory()?await o(m):u.isFile()&&e.push(Pt.relative(n,m))}}return c(o,"walk"),await o(n),e}async function Pe(n,t,e){let r=[];for(let s=0;s<n.length;s+=t){let o=await Promise.all(n.slice(s,s+t).map(e));for(let i of o)i!==null&&r.push(i)}return r}async function ut(n,t=null,e){if(e)return await xe(n,e)??t;try{let r=await G.readFile(n,"utf-8");return JSON.parse(r)}catch(r){if(N(r))return t;throw r}}async function M(n,t,e=2){let r=Pt.dirname(n);await G.mkdir(r,{recursive:!0});let s=JSON.stringify(t,null,e);await G.writeFile(n,s,"utf-8")}async function x(n){try{return await G.access(n),!0}catch(t){if(N(t))return!1;throw t}}async function Rt(n){try{return(await G.stat(n)).isDirectory()}catch(t){if(N(t))return!1;throw t}}async function F(n){await G.mkdir(n,{recursive:!0})}var U=C(()=>{"use strict";_t();ve();W();c(_e,"walkDir");c(Pe,"batchProcess");c(ut,"readJson");c(M,"writeJson");c(x,"fileExists");c(Rt,"dirExists");c(F,"ensureDir")});var Ae=C(()=>{"use strict"});import{z as D}from"zod";function Ne(n,t){let e=n.split(".").map(Number),r=t.split(".").map(Number);for(let s=0;s<3;s++){let o=e[s]??0,i=r[s]??0;if(o<i)return-1;if(o>i)return 1}return 0}var oo,io,ao,lt,co,At=C(()=>{"use strict";oo=D.enum(["opus","sonnet","haiku"]),io=D.enum(["2.5-pro","2.5-flash","2.0-flash"]),ao=D.string().min(1),lt=D.object({provider:D.string(),model:D.string(),cliVersion:D.string().optional(),recordedAt:D.string()}),co=D.object({preferredModel:D.string().optional(),lastAnalysisModel:lt.optional()});c(Ne,"compareSemver")});import{exec as Kr,execFile as Qr}from"node:child_process";import{promisify as Ce}from"node:util";var k,go,z=C(()=>{"use strict";k=Ce(Kr),go=Ce(Qr)});function Ie(n,t){let e=typeof n=="string"?new Date(n).getTime():n;return Date.now()-e>t}var pt,Nt=C(()=>{"use strict";c(Ie,"isExpired");pt=class{static{c(this,"TTLCache")}cache=new Map;ttl;maxSize;constructor(t={}){this.ttl=t.ttl??5e3,this.maxSize=t.maxSize??50}isValid(t){let e=this.cache.get(t);return e?Date.now()-e.timestamp<this.ttl:!1}get(t){let e=this.cache.get(t);return e?this.isValid(t)?e.data:(this.cache.delete(t),null):null}set(t,e){this.cache.set(t,{data:e,timestamp:Date.now()}),this.evictOldEntries()}delete(t){this.cache.delete(t)}clear(){this.cache.clear()}has(t){return this.cache.has(t)}get size(){return this.cache.size}evictOldEntries(){if(this.cache.size<=this.maxSize)return;let e=Array.from(this.cache.entries()).sort((r,s)=>r[1].timestamp-s[1].timestamp).slice(0,this.cache.size-this.maxSize);for(let[r]of e)this.cache.delete(r)}stats(){return{size:this.cache.size,maxSize:this.maxSize,ttl:this.ttl}}prune(){let t=0;for(let e of this.cache.keys())this.isValid(e)||(this.cache.delete(e),t++);return t}}});import Zr from"node:fs/promises";import ts from"node:os";import De from"node:path";async function Oe(){try{let n=await Zr.readFile(Le,"utf-8"),t=JSON.parse(n);return!t.timestamp||!t.detection||!t.detection.claude||!t.detection.gemini||!t.detection.codex||Ie(t.timestamp,rs)?null:t.detection}catch{return null}}async function je(n){let t={timestamp:new Date().toISOString(),detection:n};await M(Le,t)}var es,Le,rs,Me=C(()=>{"use strict";Nt();U();es=De.join(ts.homedir(),".prjct-cli","cache"),Le=De.join(es,"providers.json"),rs=10*60*1e3;c(Oe,"readProviderCache");c(je,"writeProviderCache")});var mt={};ge(mt,{AntigravityProvider:()=>Dt,ClaudeProvider:()=>dt,CodexProvider:()=>Lt,CursorProvider:()=>Ue,GeminiProvider:()=>It,Providers:()=>I,WindsurfProvider:()=>Xe,detectAllProviders:()=>Ot,detectAntigravity:()=>ps,detectCodex:()=>He,detectCursorProject:()=>Ge,detectProvider:()=>Ct,detectWindsurfProject:()=>Be,getActiveProvider:()=>is,getCapabilities:()=>ns,getCommandsDir:()=>fs,getGlobalContextPath:()=>ds,getGlobalSettingsPath:()=>ms,getProjectCommandsPath:()=>hs,getProviderBranding:()=>cs,getSkillsPath:()=>gs,hasProviderConfig:()=>as,needsCursorRouterRegeneration:()=>us,needsWindsurfRouterRegeneration:()=>ls,selectProvider:()=>ys,validateCliVersion:()=>We});import X from"node:os";import _ from"node:path";function ns(n,t){return{...ss[n],...t}}async function $e(n){try{let{stdout:t}=await k(`which ${n}`,{timeout:2e3});return t.trim()}catch{return null}}async function os(n){try{let{stdout:t}=await k(`${n} --version`,{timeout:2e3}),e=t.match(/\d+\.\d+\.\d+/);return e?e[0]:t.trim()}catch{return null}}async function Ct(n){let t=I[n];if(!t.cliCommand)return{installed:!1};let e=await $e(t.cliCommand);if(!e)return{installed:!1};let r=await os(t.cliCommand),s=We(n,r||void 0);return{installed:!0,version:r||void 0,path:e,versionWarning:s||void 0}}function We(n,t){let e=I[n];return!e.minCliVersion||!t?null:Ne(t,e.minCliVersion)<0?`\u26A0\uFE0F ${e.displayName} v${t} is below minimum v${e.minCliVersion}. Some features may not work correctly.`:null}async function Ot(n=!1){if(!n){let i=await Oe();if(i)return i}let[t,e,r]=await Promise.all([Ct("claude"),Ct("gemini"),He()]),s={installed:r.installed},o={claude:t,gemini:e,codex:s};return await je(o).catch(()=>{}),o}async function is(n){if(n&&I[n])return I[n];let t=await Ot();return t.claude.installed&&!t.gemini.installed?dt:t.gemini.installed&&!t.claude.installed?It:dt}async function as(n){let t=I[n];return t.configDir?x(t.configDir):!1}function cs(n){return{commitFooter:"Generated with [p/](https://www.prjct.app/)",signature:{claude:"\u26A1 prjct + Claude",gemini:"\u26A1 prjct + Gemini",cursor:"\u26A1 prjct + Cursor",antigravity:"\u26A1 prjct + Antigravity",windsurf:"\u26A1 prjct + Windsurf",codex:"\u26A1 prjct + Codex"}[n]||"\u26A1 prjct"}}async function Ge(n){let t=_.join(n,".cursor"),e=_.join(t,"rules"),r=_.join(e,"prjct.mdc"),[s,o]=await Promise.all([x(t),x(r)]);return{detected:s,routerInstalled:o,projectRoot:s?n:void 0}}async function us(n){let t=await Ge(n);return t.detected&&!t.routerInstalled}async function Be(n){let t=_.join(n,".windsurf"),e=_.join(t,"rules"),r=_.join(e,"prjct.md"),[s,o]=await Promise.all([x(t),x(r)]);return{detected:s,routerInstalled:o,projectRoot:s?n:void 0}}async function ls(n){let t=await Be(n);return t.detected&&!t.routerInstalled}async function ps(){let n=Dt.configDir;if(!n)return{installed:!1,skillInstalled:!1};let t=_.join(n,"skills","prjct","SKILL.md"),[e,r]=await Promise.all([x(n),x(t)]);return{installed:e,skillInstalled:r,configPath:e?n:void 0}}async function He(){let n=Lt.configDir;if(!n)return{installed:!1,skillInstalled:!1};let t=await $e("codex"),e=_.join(n,"skills","prjct","SKILL.md"),r=await x(e),s=!!t;return{installed:s,skillInstalled:r,configPath:s?n:void 0}}function ds(n){let t=I[n];return t.configDir?_.join(t.configDir,t.contextFile):null}function ms(n){let t=I[n];return!t.configDir||!t.settingsFile?null:_.join(t.configDir,t.settingsFile)}function gs(n){return I[n].skillsDir}function fs(n){return I[n].commandsDir}function hs(n,t){let e=I[n];return _.join(t,e.commandsDir)}async function ys(){let n=await Ot(),t=n.claude.installed,e=n.gemini.installed;return!t&&!e?{provider:"claude",userSelected:!1,detection:n}:t&&!e?{provider:"claude",userSelected:!1,detection:n}:e&&!t?{provider:"gemini",userSelected:!1,detection:n}:{provider:"claude",userSelected:!0,detection:n}}var ss,dt,It,Dt,Ue,Xe,Lt,I,gt=C(()=>{"use strict";Ae();At();z();U();Me();ss={full:{shell:!0,fileRead:!0,fileWrite:!0,fileSearch:!0,structuredQuestions:!0,subagents:!0,webFetch:!0,todoTracking:!0},standard:{shell:!0,fileRead:!0,fileWrite:!0,fileSearch:!0,structuredQuestions:!0,subagents:!1,webFetch:!1,todoTracking:!1},basic:{shell:!0,fileRead:!0,fileWrite:!0,fileSearch:!0,structuredQuestions:!1,subagents:!1,webFetch:!1,todoTracking:!1}};c(ns,"getCapabilities");dt={name:"claude",displayName:"Claude Code",cliCommand:"claude",configDir:_.join(X.homedir(),".claude"),contextFile:"CLAUDE.md",skillsDir:_.join(X.homedir(),".claude","skills"),commandsDir:".claude/commands",commandFormat:"md",settingsFile:"settings.json",projectSettingsFile:"settings.local.json",ignoreFile:".claudeignore",websiteUrl:"https://www.anthropic.com/claude",docsUrl:"https://docs.anthropic.com/claude-code",defaultModel:"sonnet",supportedModels:["opus","sonnet","haiku"],minCliVersion:"1.0.0",capabilityTier:"full"},It={name:"gemini",displayName:"Gemini CLI",cliCommand:"gemini",configDir:_.join(X.homedir(),".gemini"),contextFile:"GEMINI.md",skillsDir:_.join(X.homedir(),".gemini","skills"),commandsDir:".gemini/commands",commandFormat:"toml",settingsFile:"settings.json",projectSettingsFile:"settings.json",ignoreFile:".geminiignore",websiteUrl:"https://geminicli.com",docsUrl:"https://geminicli.com/docs",defaultModel:"2.5-flash",supportedModels:["2.5-pro","2.5-flash","2.0-flash"],minCliVersion:"1.0.0",capabilityTier:"standard"},Dt={name:"antigravity",displayName:"Google Antigravity",cliCommand:null,configDir:_.join(X.homedir(),".gemini","antigravity"),contextFile:"ANTIGRAVITY.md",skillsDir:_.join(X.homedir(),".gemini","antigravity","global_skills"),commandsDir:".agent/skills",commandFormat:"md",settingsFile:"mcp_config.json",projectSettingsFile:null,ignoreFile:".agentignore",websiteUrl:"https://gemini.google.com/app/antigravity",docsUrl:"https://gemini.google.com/app/antigravity",defaultModel:null,supportedModels:[],minCliVersion:null,capabilityTier:"basic"},Ue={name:"cursor",displayName:"Cursor IDE",cliCommand:null,configDir:null,contextFile:"prjct.mdc",skillsDir:null,commandsDir:".cursor/commands",rulesDir:".cursor/rules",commandFormat:"md",settingsFile:null,projectSettingsFile:null,ignoreFile:".cursorignore",isProjectLevel:!0,websiteUrl:"https://cursor.com",docsUrl:"https://cursor.com/docs",defaultModel:null,supportedModels:[],minCliVersion:null,capabilityTier:"basic"},Xe={name:"windsurf",displayName:"Windsurf IDE",cliCommand:null,configDir:null,contextFile:"prjct.md",skillsDir:null,commandsDir:".windsurf/workflows",rulesDir:".windsurf/rules",commandFormat:"md",settingsFile:null,projectSettingsFile:null,ignoreFile:".windsurfignore",isProjectLevel:!0,websiteUrl:"https://windsurf.com",docsUrl:"https://docs.windsurf.com",defaultModel:null,supportedModels:[],minCliVersion:null,capabilityTier:"basic"},Lt={name:"codex",displayName:"OpenAI Codex",cliCommand:"codex",configDir:_.join(X.homedir(),".codex"),contextFile:"AGENTS.md",skillsDir:_.join(X.homedir(),".codex","skills"),commandsDir:".agents/skills",commandFormat:"md",settingsFile:null,projectSettingsFile:null,ignoreFile:".codexignore",websiteUrl:"https://openai.com/codex",docsUrl:"https://github.com/openai/codex",defaultModel:null,supportedModels:[],minCliVersion:null,capabilityTier:"basic"},I={claude:dt,gemini:It,cursor:Ue,antigravity:Dt,windsurf:Xe,codex:Lt};c($e,"whichCommand");c(os,"getCliVersion");c(Ct,"detectProvider");c(We,"validateCliVersion");c(Ot,"detectAllProviders");c(is,"getActiveProvider");c(as,"hasProviderConfig");c(cs,"getProviderBranding");c(Ge,"detectCursorProject");c(us,"needsCursorRouterRegeneration");c(Be,"detectWindsurfProject");c(ls,"needsWindsurfRouterRegeneration");c(ps,"detectAntigravity");c(He,"detectCodex");c(ds,"getGlobalContextPath");c(ms,"getGlobalSettingsPath");c(gs,"getSkillsPath");c(fs,"getCommandsDir");c(hs,"getProjectCommandsPath");c(ys,"selectProvider")});var cr={};ge(cr,{default:()=>Ws,worktreeService:()=>ar});import Ht from"node:fs/promises";import O from"node:path";var ir,qt,ar,Ws,ur=C(()=>{"use strict";z();U();ir=".worktrees",qt=class{static{c(this,"WorktreeService")}async create(t,e,r={}){let s=await this.getMainWorktree(t),o=O.join(s,ir,e),i=r.branch||`feat/${e}`;await Ht.mkdir(O.join(s,ir),{recursive:!0});let a=r.baseBranch?` ${r.baseBranch}`:"";await k(`git worktree add "${o}" -b "${i}"${a}`,{cwd:s});let{stdout:u}=await k("git rev-parse HEAD",{cwd:o});return{path:o,branch:i,commit:u.trim(),isMain:!1,slug:e}}async remove(t,e=!1){let r=await this.getMainWorktree(t),s;if(e)try{let{stdout:o}=await k("git rev-parse --abbrev-ref HEAD",{cwd:t});s=o.trim()}catch{}if(await k(`git worktree remove "${t}" --force`,{cwd:r}),e&&s&&s!=="main"&&s!=="master")try{await k(`git branch -D "${s}"`,{cwd:r})}catch{}}async list(t){let e=await this.getMainWorktree(t),{stdout:r}=await k("git worktree list --porcelain",{cwd:e});return this.parsePorcelainOutput(r,e)}async detect(t){try{let{stdout:e}=await k("git rev-parse --git-common-dir",{cwd:t}),{stdout:r}=await k("git rev-parse --git-dir",{cwd:t}),s=O.resolve(t,e.trim()),o=O.resolve(t,r.trim());if(s!==o){let{stdout:i}=await k("git rev-parse --abbrev-ref HEAD",{cwd:t}),{stdout:a}=await k("git rev-parse HEAD",{cwd:t}),{stdout:u}=await k("git rev-parse --show-toplevel",{cwd:t}),p=u.trim(),m=O.basename(p);return{path:p,branch:i.trim(),commit:a.trim(),isMain:!1,slug:m}}return null}catch{return null}}async getMainWorktree(t){try{let{stdout:r}=await k("git worktree list --porcelain",{cwd:t}),s=r.split(`
9
- `)[0];if(s?.startsWith("worktree "))return s.replace("worktree ","").trim()}catch{}let{stdout:e}=await k("git rev-parse --show-toplevel",{cwd:t});return e.trim()}async setup(t,e){let r=O.join(e,".env");await x(r)&&await Ht.copyFile(r,O.join(t,".env"));let s=O.join(e,".prjct"),o=O.join(t,".prjct");await x(s)&&!await x(o)&&await Ht.symlink(s,o,"dir")}async teardown(t){}async clean(t){let e=await this.list(t),r=[],s=await this.getMainWorktree(t);await k("git worktree prune",{cwd:s});for(let o of e)o.isMain||await x(o.path)||r.push(o.slug);return r}parsePorcelainOutput(t,e){let r=[],s=t.trim().split(`
8
+ var it=Object.defineProperty;var Xr=Object.getOwnPropertyDescriptor;var $r=Object.getOwnPropertyNames;var Wr=Object.prototype.hasOwnProperty;var c=(n,t)=>it(n,"name",{value:t,configurable:!0}),ue=(n=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(n,{get:(t,e)=>(typeof require<"u"?require:t)[e]}):n)(function(n){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+n+'" is not supported')});var A=(n,t)=>()=>(n&&(t=n(n=0)),t);var le=(n,t)=>{for(var e in t)it(n,e,{get:t[e],enumerable:!0})},Gr=(n,t,e,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of $r(t))!Wr.call(n,s)&&s!==e&&it(n,s,{get:()=>t[s],enumerable:!(r=Xr(t,s))||r.enumerable});return n};var bt=n=>Gr(it({},"__esModule",{value:!0}),n);var de,pe,me,St=A(()=>{"use strict";de=new Set(["node_modules",".git","dist","build","out",".next",".nuxt","coverage",".cache",".turbo",".vercel",".parcel-cache","__pycache__",".pytest_cache","target","vendor",".venv","venv","eggs","*.egg-info",".prjct",".worktrees"]),pe=["",".ts",".tsx",".js",".jsx","/index.ts","/index.js"],me=/(?:import|from)\s+['"]([^'"]+)['"]/g});function Hr(n){return n instanceof Error&&"code"in n}function P(n){return Hr(n)&&n.code==="ENOENT"}function he(n){return n instanceof Error?n.message:typeof n=="string"?n:"Unknown error"}var U=A(()=>{"use strict";c(Hr,"isNodeError");c(P,"isNotFoundError");c(he,"getErrorMessage")});import Ee from"node:fs/promises";async function ke(n,t){let e;try{e=await Ee.readFile(n,"utf-8")}catch(i){if(P(i))return null;throw i}let r;try{r=JSON.parse(e)}catch{return await Te(n,e),ye(n,"Malformed JSON"),null}let s=t.safeParse(r);return s.success?r:(await Te(n,e),ye(n,qr(s.error)),null)}async function Te(n,t){let e=`${n}.backup`;try{await Ee.writeFile(e,t,"utf-8")}catch{}}function ye(n,t){console.error(`[prjct] Warning: Corrupted storage file: ${n}`),console.error(`[prjct] Reason: ${t}`),console.error("[prjct] A .backup file has been created. Returning defaults.")}function qr(n){return n.issues.slice(0,3).map(t=>`${t.path.join(".")}: ${t.message}`).join("; ")}var we=A(()=>{"use strict";U();c(ke,"safeRead");c(Te,"createBackup");c(ye,"logCorruption");c(qr,"formatZodError")});import X from"node:fs/promises";import vt from"node:path";async function be(n,t={}){let e=[],r=t.maxFiles??1/0,s=t.dotfileAllowlist?new Set(t.dotfileAllowlist):null;async function i(o){if(e.length>=r)return;let a=await X.readdir(o,{withFileTypes:!0}).catch(()=>[]);for(let u of a){if(e.length>=r)break;let d=String(u.name);if(de.has(d)||t.skipDotfiles&&d.startsWith(".")&&(!s||!s.has(d)))continue;let m=vt.join(o,d);u.isDirectory()?await i(m):u.isFile()&&e.push(vt.relative(n,m))}}return c(i,"walk"),await i(n),e}async function Se(n,t,e){let r=[];for(let s=0;s<n.length;s+=t){let i=await Promise.all(n.slice(s,s+t).map(e));for(let o of i)o!==null&&r.push(o)}return r}async function ot(n,t=null,e){if(e)return await ke(n,e)??t;try{let r=await X.readFile(n,"utf-8");return JSON.parse(r)}catch(r){if(P(r))return t;throw r}}async function L(n,t,e=2){let r=vt.dirname(n);await X.mkdir(r,{recursive:!0});let s=`${JSON.stringify(t,null,e)}
9
+ `;await X.writeFile(n,s,"utf-8")}async function _(n){try{return await X.access(n),!0}catch(t){if(P(t))return!1;throw t}}async function _t(n){try{return(await X.stat(n)).isDirectory()}catch(t){if(P(t))return!1;throw t}}async function O(n){await X.mkdir(n,{recursive:!0})}var M=A(()=>{"use strict";St();we();U();c(be,"walkDir");c(Se,"batchProcess");c(ot,"readJson");c(L,"writeJson");c(_,"fileExists");c(_t,"dirExists");c(O,"ensureDir")});var _e=A(()=>{"use strict"});import{z as Q}from"zod";function xe(n,t){let e=n.split(".").map(Number),r=t.split(".").map(Number);for(let s=0;s<3;s++){let i=e[s]??0,o=r[s]??0;if(i<o)return-1;if(i>o)return 1}return 0}var xt,Rt=A(()=>{"use strict";xt=Q.object({provider:Q.string(),model:Q.string(),cliVersion:Q.string().optional(),recordedAt:Q.string()});c(xe,"compareSemver")});import{exec as Yr,execFile as zr}from"node:child_process";import{promisify as Re}from"node:util";var k,Bn,B=A(()=>{"use strict";k=Re(Yr),Bn=Re(zr)});function Pe(n,t){let e=typeof n=="string"?new Date(n).getTime():n;return Date.now()-e>t}var at,Pt=A(()=>{"use strict";c(Pe,"isExpired");at=class{static{c(this,"TTLCache")}cache=new Map;ttl;maxSize;constructor(t={}){this.ttl=t.ttl??5e3,this.maxSize=t.maxSize??50}isValid(t){let e=this.cache.get(t);return e?Date.now()-e.timestamp<this.ttl:!1}get(t){let e=this.cache.get(t);return e?this.isValid(t)?e.data:(this.cache.delete(t),null):null}set(t,e){this.cache.set(t,{data:e,timestamp:Date.now()}),this.evictOldEntries()}delete(t){this.cache.delete(t)}clear(){this.cache.clear()}has(t){return this.cache.has(t)}get size(){return this.cache.size}evictOldEntries(){if(this.cache.size<=this.maxSize)return;let e=Array.from(this.cache.entries()).sort((r,s)=>r[1].timestamp-s[1].timestamp).slice(0,this.cache.size-this.maxSize);for(let[r]of e)this.cache.delete(r)}stats(){return{size:this.cache.size,maxSize:this.maxSize,ttl:this.ttl}}prune(){let t=0;for(let e of this.cache.keys())this.isValid(e)||(this.cache.delete(e),t++);return t}}});import Jr from"node:fs/promises";import Kr from"node:os";import Ae from"node:path";async function Ce(){try{let n=await Jr.readFile(Ne,"utf-8"),t=JSON.parse(n);return!t.timestamp||!t.detection||!t.detection.claude||!t.detection.gemini||!t.detection.codex||Pe(t.timestamp,Qr)?null:t.detection}catch{return null}}async function Ie(n){let t={timestamp:new Date().toISOString(),detection:n};await L(Ne,t)}var Vr,Ne,Qr,De=A(()=>{"use strict";Pt();M();Vr=Ae.join(Kr.homedir(),".prjct-cli","cache"),Ne=Ae.join(Vr,"providers.json"),Qr=10*60*1e3;c(Ce,"readProviderCache");c(Ie,"writeProviderCache")});var ct={};le(ct,{ClaudeProvider:()=>Oe,CursorProvider:()=>Fe,GeminiProvider:()=>Me,Providers:()=>Nt,detectAllProviders:()=>We,detectAntigravity:()=>rs,detectCodex:()=>Ge,detectProvider:()=>At,getProviderBranding:()=>es,selectProvider:()=>ss,validateCliVersion:()=>$e});import j from"node:os";import N from"node:path";async function Xe(n){try{let{stdout:t}=await k(`which ${n}`,{timeout:2e3});return t.trim()}catch{return null}}async function ts(n){try{let{stdout:t}=await k(`${n} --version`,{timeout:2e3}),e=t.match(/\d+\.\d+\.\d+/);return e?e[0]:t.trim()}catch{return null}}async function At(n){let t=Nt[n];if(!t.cliCommand)return{installed:!1};let e=await Xe(t.cliCommand);if(!e)return{installed:!1};let r=await ts(t.cliCommand),s=$e(n,r||void 0);return{installed:!0,version:r||void 0,path:e,versionWarning:s||void 0}}function $e(n,t){let e=Nt[n];return!e.minCliVersion||!t?null:xe(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 We(n=!1){if(!n){let o=await Ce();if(o)return o}let[t,e,r]=await Promise.all([At("claude"),At("gemini"),Ge()]),s={installed:r.installed},i={claude:t,gemini:e,codex:s};return await Ie(i).catch(()=>{}),i}function es(n){return{commitFooter:"Generated with [p/](https://www.prjct.app/)",signature:{claude:"\u26A1 prjct + Claude",gemini:"\u26A1 prjct + Gemini",cursor:"\u26A1 prjct + Cursor",antigravity:"\u26A1 prjct + Antigravity",windsurf:"\u26A1 prjct + Windsurf",codex:"\u26A1 prjct + Codex"}[n]||"\u26A1 prjct"}}async function rs(){let n=je.configDir;if(!n)return{installed:!1,skillInstalled:!1};let t=N.join(n,"skills","prjct","SKILL.md"),[e,r]=await Promise.all([_(n),_(t)]);return{installed:e,skillInstalled:r,configPath:e?n:void 0}}async function Ge(){let n=Ue.configDir;if(!n)return{installed:!1,skillInstalled:!1};let t=await Xe("codex"),e=N.join(n,"skills","prjct","SKILL.md"),r=await _(e),s=!!t;return{installed:s,skillInstalled:r,configPath:s?n:void 0}}async function ss(){let n=await We(),t=n.claude.installed,e=n.gemini.installed;return!t&&!e?{provider:"claude",userSelected:!1,detection:n}:t&&!e?{provider:"claude",userSelected:!1,detection:n}:e&&!t?{provider:"gemini",userSelected:!1,detection:n}:{provider:"claude",userSelected:!0,detection:n}}var Oe,Me,je,Fe,Zr,Ue,Nt,ut=A(()=>{"use strict";_e();Rt();B();M();De();Oe={name:"claude",displayName:"Claude Code",cliCommand:"claude",configDir:N.join(j.homedir(),".claude"),contextFile:"CLAUDE.md",skillsDir:N.join(j.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"},Me={name:"gemini",displayName:"Gemini CLI",cliCommand:"gemini",configDir:N.join(j.homedir(),".gemini"),contextFile:"GEMINI.md",skillsDir:N.join(j.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"},je={name:"antigravity",displayName:"Google Antigravity",cliCommand:null,configDir:N.join(j.homedir(),".gemini","antigravity"),contextFile:"ANTIGRAVITY.md",skillsDir:N.join(j.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"},Fe={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"},Zr={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"},Ue={name:"codex",displayName:"OpenAI Codex",cliCommand:"codex",configDir:N.join(j.homedir(),".codex"),contextFile:"AGENTS.md",skillsDir:N.join(j.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"},Nt={claude:Oe,gemini:Me,cursor:Fe,antigravity:je,windsurf:Zr,codex:Ue};c(Xe,"whichCommand");c(ts,"getCliVersion");c(At,"detectProvider");c($e,"validateCliVersion");c(We,"detectAllProviders");c(es,"getProviderBranding");c(rs,"detectAntigravity");c(Ge,"detectCodex");c(ss,"selectProvider")});var nr={};le(nr,{default:()=>Rs,worktreeService:()=>sr});import Wt from"node:fs/promises";import I from"node:path";var rr,Gt,sr,Rs,ir=A(()=>{"use strict";B();M();rr=".worktrees",Gt=class{static{c(this,"WorktreeService")}async create(t,e,r={}){let s=await this.getMainWorktree(t),i=I.join(s,rr,e),o=r.branch||`feat/${e}`;await Wt.mkdir(I.join(s,rr),{recursive:!0});let a=r.baseBranch?` ${r.baseBranch}`:"";await k(`git worktree add "${i}" -b "${o}"${a}`,{cwd:s});let{stdout:u}=await k("git rev-parse HEAD",{cwd:i});return{path:i,branch:o,commit:u.trim(),isMain:!1,slug:e}}async remove(t,e=!1){let r=await this.getMainWorktree(t),s;if(e)try{let{stdout:i}=await k("git rev-parse --abbrev-ref HEAD",{cwd:t});s=i.trim()}catch{}if(await k(`git worktree remove "${t}" --force`,{cwd:r}),e&&s&&s!=="main"&&s!=="master")try{await k(`git branch -D "${s}"`,{cwd:r})}catch{}}async list(t){let e=await this.getMainWorktree(t),{stdout:r}=await k("git worktree list --porcelain",{cwd:e});return this.parsePorcelainOutput(r,e)}async detect(t){try{let{stdout:e}=await k("git rev-parse --git-common-dir",{cwd:t}),{stdout:r}=await k("git rev-parse --git-dir",{cwd:t}),s=I.resolve(t,e.trim()),i=I.resolve(t,r.trim());if(s!==i){let{stdout:o}=await k("git rev-parse --abbrev-ref HEAD",{cwd:t}),{stdout:a}=await k("git rev-parse HEAD",{cwd:t}),{stdout:u}=await k("git rev-parse --show-toplevel",{cwd:t}),d=u.trim(),m=I.basename(d);return{path:d,branch:o.trim(),commit:a.trim(),isMain:!1,slug:m}}return null}catch{return null}}async getMainWorktree(t){try{let{stdout:r}=await k("git worktree list --porcelain",{cwd:t}),s=r.split(`
10
+ `)[0];if(s?.startsWith("worktree "))return s.replace("worktree ","").trim()}catch{}let{stdout:e}=await k("git rev-parse --show-toplevel",{cwd:t});return e.trim()}async setup(t,e){let r=I.join(e,".env");await _(r)&&await Wt.copyFile(r,I.join(t,".env"));let s=I.join(e,".prjct"),i=I.join(t,".prjct");await _(s)&&!await _(i)&&await Wt.symlink(s,i,"dir")}async teardown(t){}async clean(t){let e=await this.list(t),r=[],s=await this.getMainWorktree(t);await k("git worktree prune",{cwd:s});for(let i of e)i.isMain||await _(i.path)||r.push(i.slug);return r}parsePorcelainOutput(t,e){let r=[],s=t.trim().split(`
10
11
 
11
- `);for(let o of s){if(!o.trim())continue;let i=o.trim().split(`
12
- `),a="",u="",p="",m=!1;for(let d of i)d.startsWith("worktree ")?a=d.replace("worktree ","").trim():d.startsWith("HEAD ")?u=d.replace("HEAD ","").trim():d.startsWith("branch ")?p=d.replace("branch refs/heads/","").trim():d==="bare"?m=!0:d==="detached"&&(p="(detached)");if(a){let d=a===e||m;r.push({path:a,branch:p,commit:u,isMain:d,slug:d?"main":O.basename(a)})}}return r}},ar=new qt,Ws=ar});import{StdioServerTransport as Mn}from"@modelcontextprotocol/sdk/server/stdio.js";import{McpServer as On}from"@modelcontextprotocol/sdk/server/mcp.js";import{z as A}from"zod";_t();import Ye from"node:fs/promises";import J from"node:path";import Mt from"node:fs";import ze from"node:path";import Ts from"node:crypto";import L from"node:fs/promises";import Y from"node:os";import h from"node:path";import{globSync as Es}from"glob";import{formatDistanceToNowStrict as Gn}from"date-fns";function Te(n){return{year:n.getFullYear().toString(),month:(n.getMonth()+1).toString().padStart(2,"0"),day:n.getDate().toString().padStart(2,"0")}}c(Te,"getYearMonthDay");function f(){return new Date().toISOString()}c(f,"getTimestamp");function Ee(n){let t=new Date;return t.setDate(t.getDate()-n),t}c(Ee,"getDaysAgo");U();var jt=class{static{c(this,"PathManager")}globalBaseDir;globalProjectsDir;globalConfigDir;constructor(){let t=process.env.PRJCT_CLI_HOME?.trim();this.globalBaseDir=t?h.resolve(t):h.join(Y.homedir(),".prjct-cli"),this.globalProjectsDir=h.join(this.globalBaseDir,"projects"),this.globalConfigDir=h.join(this.globalBaseDir,"config")}setGlobalBaseDir(t){this.globalBaseDir=h.resolve(t),this.globalProjectsDir=h.join(this.globalBaseDir,"projects"),this.globalConfigDir=h.join(this.globalBaseDir,"config")}generateProjectId(t){return Ts.randomUUID()}getGlobalBasePath(){return this.globalBaseDir}getGlobalProjectPath(t){return h.join(this.globalProjectsDir,t)}getLocalConfigPath(t){return h.join(t,".prjct","prjct.config.json")}getGlobalProjectConfigPath(t){return h.join(this.getGlobalProjectPath(t),"project.json")}getLegacyPrjctPath(t){return h.join(t,".prjct")}async hasLegacyStructure(t){let e=this.getLegacyPrjctPath(t);return await Rt(e)}async hasConfig(t){let e=this.getLocalConfigPath(t);return await x(e)}async ensureGlobalStructure(){await F(this.globalBaseDir),await F(this.globalProjectsDir),await F(this.globalConfigDir)}async ensureProjectStructure(t){await this.ensureGlobalStructure();let e=this.getGlobalProjectPath(t),r=["core","progress","planning","analysis","memory"];for(let s of r)await F(h.join(e,s));return await F(h.join(e,"planning","tasks")),await F(h.join(e,"sessions")),e}getSessionPath(t,e=new Date){let{year:r,month:s,day:o}=Te(e);return h.join(this.getGlobalProjectPath(t),"sessions",r,s,o)}getCurrentSessionPath(t){return this.getSessionPath(t,new Date)}async ensureSessionPath(t,e=new Date){let r=this.getSessionPath(t,e);return await F(r),r}async listSessions(t,e=null,r=null){let s=h.join(this.getGlobalProjectPath(t),"sessions"),o=[];try{let i=await L.readdir(s,{withFileTypes:!0});for(let a of i){if(!a.isDirectory()||e&&a.name!==e.toString())continue;let u=h.join(s,a.name),p=await L.readdir(u,{withFileTypes:!0});for(let m of p){if(!m.isDirectory()||r&&m.name!==r.toString().padStart(2,"0"))continue;let d=h.join(u,m.name),g=await L.readdir(d,{withFileTypes:!0});for(let y of g)y.isDirectory()&&o.push({year:a.name,month:m.name,day:y.name,path:h.join(d,y.name),date:new Date(`${a.name}-${m.name}-${y.name}`)})}}return o.sort((a,u)=>u.date.getTime()-a.date.getTime()),o}catch{return[]}}async getSessionsInRange(t,e,r=new Date){return(await this.listSessions(t)).filter(o=>o.date>=e&&o.date<=r)}getFilePath(t,e,r){return h.join(this.getGlobalProjectPath(t),e,r)}async listProjects(){try{return await this.ensureGlobalStructure(),(await L.readdir(this.globalProjectsDir,{withFileTypes:!0})).filter(e=>e.isDirectory()).map(e=>e.name)}catch{return[]}}async projectExists(t){let e=this.getGlobalProjectPath(t);return await Rt(e)}getDisplayPath(t){let e=Y.homedir();return t.startsWith(e)?t.replace(e,"~"):t}getAuthConfigPath(){return h.join(this.globalConfigDir,"auth.json")}getSyncPendingPath(t){return h.join(this.getGlobalProjectPath(t),"sync","pending.json")}getLastSyncPath(t){return h.join(this.getGlobalProjectPath(t),"sync","last-sync.json")}getRunningStatusPath(){return h.join(this.globalBaseDir,".running")}getDocsPath(){return h.join(this.globalBaseDir,"docs")}async getAgentDir(){return(await(gt(),vt(mt)).getActiveProvider()).configDir}async getAgentSettingsPath(){let t=await(gt(),vt(mt)).getActiveProvider();return(gt(),vt(mt)).getGlobalSettingsPath(t.name)}getClaudeDir(){return h.join(Y.homedir(),".claude")}getClaudeSettingsPath(){return h.join(this.getClaudeDir(),"settings.json")}getStoragePath(t,e){return h.join(this.getGlobalProjectPath(t),"storage",e)}getContextPath(t){return h.join(this.getGlobalProjectPath(t),"context")}getWikiPath(t,e){if(e&&e.trim().length>0)return this.resolveVaultOverride(t,e);let s=h.basename(h.resolve(t)).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"project";return h.join(Y.homedir(),"Documents","prjct",s)}getWikiPathWithProjectHash(t,e){let s=h.basename(h.resolve(t)).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"project",o=e.replace(/-/g,"").slice(0,8);return h.join(Y.homedir(),"Documents","prjct",`${s}-${o}`)}getLegacyWikiPath(t){return h.join(t,".prjct","wiki")}resolveVaultOverride(t,e){let r=e.trim();return(r.startsWith("~/")||r==="~")&&(r=h.join(Y.homedir(),r.slice(1))),h.isAbsolute(r)||(r=h.resolve(t,r)),r}async detectMonorepo(t){let e={isMonorepo:!1,type:null,rootPath:t,packages:[]},r=[{file:"pnpm-workspace.yaml",type:"pnpm"},{file:"lerna.json",type:"lerna"},{file:"nx.json",type:"nx"},{file:"rush.json",type:"rush"},{file:"turbo.json",type:"turborepo"}];for(let s of r){let o=h.join(t,s.file);if(await x(o)){e.isMonorepo=!0,e.type=s.type;break}}if(!e.isMonorepo){let s=h.join(t,"package.json");if(await x(s))try{let o=await L.readFile(s,"utf-8");JSON.parse(o).workspaces&&(e.isMonorepo=!0,e.type="npm")}catch{}}return e.isMonorepo&&(e.packages=await this.discoverMonorepoPackages(t,e.type)),e}async discoverMonorepoPackages(t,e){let r=[],s=[];try{if(e==="pnpm"){let i=(await L.readFile(h.join(t,"pnpm-workspace.yaml"),"utf-8")).match(/packages:\s*\n((?:\s*-\s*.+\n?)+)/);i&&(s=i[1].split(`
13
- `).map(a=>a.replace(/^\s*-\s*['"]?|['"]?\s*$/g,"")).filter(Boolean))}else if(e==="npm"||e==="lerna"){let o=h.join(t,"package.json"),i=await L.readFile(o,"utf-8"),a=JSON.parse(i);if(Array.isArray(a.workspaces)?s=a.workspaces:a.workspaces?.packages&&(s=a.workspaces.packages),e==="lerna"){let u=h.join(t,"lerna.json");if(await x(u)){let p=await L.readFile(u,"utf-8"),m=JSON.parse(p);m.packages&&(s=m.packages)}}}else if(e==="nx")s=["apps/*","libs/*","packages/*"];else if(e==="turborepo"){let o=h.join(t,"package.json"),i=await L.readFile(o,"utf-8"),a=JSON.parse(i);Array.isArray(a.workspaces)&&(s=a.workspaces)}s.length===0&&(s=["packages/*","apps/*","libs/*"]);for(let o of s){if(o.startsWith("!"))continue;let i=Es(o,{cwd:t,absolute:!1});for(let a of i){let u=h.join(t,a),p=h.join(u,"package.json");if(await x(p))try{let m=await L.readFile(p,"utf-8"),d=JSON.parse(m),g=h.join(u,"PRJCT.md");r.push({name:d.name||h.basename(a),path:u,relativePath:a,hasPrjctMd:await x(g)})}catch{}}}}catch{}return r}async findContainingPackage(t,e){if(!e.isMonorepo)return null;let r=h.resolve(t);for(let s of e.packages){let o=h.resolve(s.path);if(r.startsWith(o))return s}return null}async findMonorepoRoot(t){let e=h.resolve(t),r=h.parse(e).root;for(;e!==r;){if((await this.detectMonorepo(e)).isMonorepo)return e;e=h.dirname(e)}return null}},ks=new jt,b=ks;function ws(){return typeof globalThis<"u"&&"Bun"in globalThis?"bun":"node"}c(ws,"detectRuntime");function qe(){return ws()==="bun"}c(qe,"isBun");function bs(n){if(qe()){let{Database:s}=me("bun:sqlite");return new s(n,{create:!0})}let t=me("better-sqlite3"),e=new t(n),r=e.exec.bind(e);return e.run=s=>r(s),e}c(bs,"openDatabase");var Ss=[{version:1,name:"initial-schema",up:c(n=>{n.run(`
12
+ `);for(let i of s){if(!i.trim())continue;let o=i.trim().split(`
13
+ `),a="",u="",d="",m=!1;for(let p of o)p.startsWith("worktree ")?a=p.replace("worktree ","").trim():p.startsWith("HEAD ")?u=p.replace("HEAD ","").trim():p.startsWith("branch ")?d=p.replace("branch refs/heads/","").trim():p==="bare"?m=!0:p==="detached"&&(d="(detached)");if(a){let p=a===e||m;r.push({path:a,branch:d,commit:u,isMain:p,slug:p?"main":I.basename(a)})}}return r}},sr=new Gt,Rs=sr});import{StdioServerTransport as yn}from"@modelcontextprotocol/sdk/server/stdio.js";import{McpServer as hn}from"@modelcontextprotocol/sdk/server/mcp.js";import{z as R}from"zod";St();import qe from"node:fs/promises";import q from"node:path";import It from"node:fs";import He from"node:path";import ns from"node:crypto";import C from"node:fs/promises";import H from"node:os";import h from"node:path";import{globSync as is}from"glob";import{formatDistanceToNowStrict as vn}from"date-fns";function ge(n){return{year:n.getFullYear().toString(),month:(n.getMonth()+1).toString().padStart(2,"0"),day:n.getDate().toString().padStart(2,"0")}}c(ge,"getYearMonthDay");function f(){return new Date().toISOString()}c(f,"getTimestamp");function fe(n){let t=new Date;return t.setDate(t.getDate()-n),t}c(fe,"getDaysAgo");M();var Ct=class{static{c(this,"PathManager")}globalBaseDir;globalProjectsDir;globalConfigDir;constructor(){let t=process.env.PRJCT_CLI_HOME?.trim();this.globalBaseDir=t?h.resolve(t):h.join(H.homedir(),".prjct-cli"),this.globalProjectsDir=h.join(this.globalBaseDir,"projects"),this.globalConfigDir=h.join(this.globalBaseDir,"config")}setGlobalBaseDir(t){this.globalBaseDir=h.resolve(t),this.globalProjectsDir=h.join(this.globalBaseDir,"projects"),this.globalConfigDir=h.join(this.globalBaseDir,"config")}generateProjectId(t){return ns.randomUUID()}getGlobalBasePath(){return this.globalBaseDir}getGlobalProjectPath(t){return h.join(this.globalProjectsDir,t)}getLocalConfigPath(t){return h.join(t,".prjct","prjct.config.json")}getGlobalProjectConfigPath(t){return h.join(this.getGlobalProjectPath(t),"project.json")}getLegacyPrjctPath(t){return h.join(t,".prjct")}async hasLegacyStructure(t){let e=this.getLegacyPrjctPath(t);return await _t(e)}async hasConfig(t){let e=this.getLocalConfigPath(t);return await _(e)}async ensureGlobalStructure(){await O(this.globalBaseDir),await O(this.globalProjectsDir),await O(this.globalConfigDir)}async ensureProjectStructure(t){await this.ensureGlobalStructure();let e=this.getGlobalProjectPath(t),r=["core","progress","planning","analysis","memory"];for(let s of r)await O(h.join(e,s));return await O(h.join(e,"planning","tasks")),await O(h.join(e,"sessions")),e}getSessionPath(t,e=new Date){let{year:r,month:s,day:i}=ge(e);return h.join(this.getGlobalProjectPath(t),"sessions",r,s,i)}getCurrentSessionPath(t){return this.getSessionPath(t,new Date)}async ensureSessionPath(t,e=new Date){let r=this.getSessionPath(t,e);return await O(r),r}async listSessions(t,e=null,r=null){let s=h.join(this.getGlobalProjectPath(t),"sessions"),i=[];try{let o=await C.readdir(s,{withFileTypes:!0});for(let a of o){if(!a.isDirectory()||e&&a.name!==e.toString())continue;let u=h.join(s,a.name),d=await C.readdir(u,{withFileTypes:!0});for(let m of d){if(!m.isDirectory()||r&&m.name!==r.toString().padStart(2,"0"))continue;let p=h.join(u,m.name),g=await C.readdir(p,{withFileTypes:!0});for(let T of g)T.isDirectory()&&i.push({year:a.name,month:m.name,day:T.name,path:h.join(p,T.name),date:new Date(`${a.name}-${m.name}-${T.name}`)})}}return i.sort((a,u)=>u.date.getTime()-a.date.getTime()),i}catch{return[]}}async getSessionsInRange(t,e,r=new Date){return(await this.listSessions(t)).filter(i=>i.date>=e&&i.date<=r)}getFilePath(t,e,r){return h.join(this.getGlobalProjectPath(t),e,r)}async listProjects(){try{return await this.ensureGlobalStructure(),(await C.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 _t(e)}getDisplayPath(t){let e=H.homedir();return t.startsWith(e)?t.replace(e,"~"):t}getAuthConfigPath(){return h.join(this.globalConfigDir,"auth.json")}getSyncPendingPath(t){return h.join(this.getGlobalProjectPath(t),"sync","pending.json")}getLastSyncPath(t){return h.join(this.getGlobalProjectPath(t),"sync","last-sync.json")}getRunningStatusPath(){return h.join(this.globalBaseDir,".running")}getDocsPath(){return h.join(this.globalBaseDir,"docs")}async getAgentDir(){return(await(ut(),bt(ct)).getActiveProvider()).configDir}async getAgentSettingsPath(){let t=await(ut(),bt(ct)).getActiveProvider();return(ut(),bt(ct)).getGlobalSettingsPath(t.name)}getClaudeDir(){return h.join(H.homedir(),".claude")}getClaudeSettingsPath(){return h.join(this.getClaudeDir(),"settings.json")}getStoragePath(t,e){return h.join(this.getGlobalProjectPath(t),"storage",e)}getContextPath(t){return h.join(this.getGlobalProjectPath(t),"context")}getWikiPath(t,e){if(e&&e.trim().length>0)return this.resolveVaultOverride(t,e);let s=h.basename(h.resolve(t)).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"project";return h.join(H.homedir(),"Documents","prjct",s)}getWikiPathWithProjectHash(t,e){let s=h.basename(h.resolve(t)).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"project",i=e.replace(/-/g,"").slice(0,8);return h.join(H.homedir(),"Documents","prjct",`${s}-${i}`)}getLegacyWikiPath(t){return h.join(t,".prjct","wiki")}resolveVaultOverride(t,e){let r=e.trim();return(r.startsWith("~/")||r==="~")&&(r=h.join(H.homedir(),r.slice(1))),h.isAbsolute(r)||(r=h.resolve(t,r)),r}async detectMonorepo(t){let e={isMonorepo:!1,type:null,rootPath:t,packages:[]},r=[{file:"pnpm-workspace.yaml",type:"pnpm"},{file:"lerna.json",type:"lerna"},{file:"nx.json",type:"nx"},{file:"rush.json",type:"rush"},{file:"turbo.json",type:"turborepo"}];for(let s of r){let i=h.join(t,s.file);if(await _(i)){e.isMonorepo=!0,e.type=s.type;break}}if(!e.isMonorepo){let s=h.join(t,"package.json");if(await _(s))try{let i=await C.readFile(s,"utf-8");JSON.parse(i).workspaces&&(e.isMonorepo=!0,e.type="npm")}catch{}}return e.isMonorepo&&(e.packages=await this.discoverMonorepoPackages(t,e.type)),e}async discoverMonorepoPackages(t,e){let r=[],s=[];try{if(e==="pnpm"){let o=(await C.readFile(h.join(t,"pnpm-workspace.yaml"),"utf-8")).match(/packages:\s*\n((?:\s*-\s*.+\n?)+)/);o&&(s=o[1].split(`
14
+ `).map(a=>a.replace(/^\s*-\s*['"]?|['"]?\s*$/g,"")).filter(Boolean))}else if(e==="npm"||e==="lerna"){let i=h.join(t,"package.json"),o=await C.readFile(i,"utf-8"),a=JSON.parse(o);if(Array.isArray(a.workspaces)?s=a.workspaces:a.workspaces?.packages&&(s=a.workspaces.packages),e==="lerna"){let u=h.join(t,"lerna.json");if(await _(u)){let d=await C.readFile(u,"utf-8"),m=JSON.parse(d);m.packages&&(s=m.packages)}}}else if(e==="nx")s=["apps/*","libs/*","packages/*"];else if(e==="turborepo"){let i=h.join(t,"package.json"),o=await C.readFile(i,"utf-8"),a=JSON.parse(o);Array.isArray(a.workspaces)&&(s=a.workspaces)}s.length===0&&(s=["packages/*","apps/*","libs/*"]);for(let i of s){if(i.startsWith("!"))continue;let o=is(i,{cwd:t,absolute:!1});for(let a of o){let u=h.join(t,a),d=h.join(u,"package.json");if(await _(d))try{let m=await C.readFile(d,"utf-8"),p=JSON.parse(m),g=h.join(u,"PRJCT.md");r.push({name:p.name||h.basename(a),path:u,relativePath:a,hasPrjctMd:await _(g)})}catch{}}}}catch{}return r}async findContainingPackage(t,e){if(!e.isMonorepo)return null;let r=h.resolve(t);for(let s of e.packages){let i=h.resolve(s.path);if(r.startsWith(i))return s}return null}async findMonorepoRoot(t){let e=h.resolve(t),r=h.parse(e).root;for(;e!==r;){if((await this.detectMonorepo(e)).isMonorepo)return e;e=h.dirname(e)}return null}},os=new Ct,w=os;function as(){return typeof globalThis<"u"&&"Bun"in globalThis?"bun":"node"}c(as,"detectRuntime");function Be(){return as()==="bun"}c(Be,"isBun");function cs(n){if(Be()){let{Database:s}=ue("bun:sqlite");return new s(n,{create:!0})}let t=ue("better-sqlite3"),e=new t(n),r=e.exec.bind(e);return e.run=s=>r(s),e}c(cs,"openDatabase");var us=[{version:1,name:"initial-schema",up:c(n=>{n.run(`
14
15
  -- =======================================================================
15
16
  -- Document storage (backward-compatible with JSON file pattern)
16
17
  -- =======================================================================
@@ -481,66 +482,66 @@ var ct=Object.defineProperty;var Br=Object.getOwnPropertyDescriptor;var Hr=Objec
481
482
  );
482
483
 
483
484
  CREATE INDEX IF NOT EXISTS idx_wrc_rule ON workflow_rule_cache(rule_id);
484
- `)},"up")},{version:14,name:"workflow-rules-trust-source",up:c(n=>{try{n.run("ALTER TABLE workflow_rules ADD COLUMN trust_source TEXT NOT NULL DEFAULT 'local'")}catch{}},"up")},{version:15,name:"disable-orphan-workflow-rules",up:c(n=>{let e=["pause","resume","reopen","next","dash","bug","idea","linear","jira","tokens","velocity","plan"].map(r=>`'${r}'`).join(",");n.run(`UPDATE workflow_rules SET enabled = 0 WHERE command IN (${e}) AND enabled = 1`)},"up")}],xs=3,Ft=class{static{c(this,"PrjctDatabase")}connections=new Map;accessOrder=[];getDbPath(t){return ze.join(b.getGlobalProjectPath(t),"prjct.db")}getDb(t){let e=this.connections.get(t);if(e)return this.touchAccessOrder(t),e;this.connections.size>=xs&&this.evictLru();let r=this.getDbPath(t),s=ze.dirname(r);Mt.existsSync(s)||Mt.mkdirSync(s,{recursive:!0});let o=bs(r);return o.run("PRAGMA journal_mode = WAL"),o.run("PRAGMA synchronous = NORMAL"),o.run("PRAGMA cache_size = -2000"),o.run("PRAGMA temp_store = MEMORY"),o.run("PRAGMA mmap_size = 33554432"),this.runMigrations(o),this.connections.set(t,o),this.touchAccessOrder(t),o}close(t){if(t){let e=this.connections.get(t);e&&(e.close(),this.connections.delete(t),this.accessOrder=this.accessOrder.filter(r=>r!==t))}else this.connections.forEach(e=>{e.close()}),this.connections.clear(),this.accessOrder=[]}touchAccessOrder(t){this.accessOrder=this.accessOrder.filter(e=>e!==t),this.accessOrder.push(t)}evictLru(){if(this.accessOrder.length===0)return;let t=this.accessOrder.shift(),e=this.connections.get(t);e&&(e.close(),this.connections.delete(t))}checkpointAll(){for(let[t,e]of this.connections)try{e.run("PRAGMA wal_checkpoint(TRUNCATE)")}catch{}}exists(t){return Mt.existsSync(this.getDbPath(t))}getDoc(t,e){let s=this.getDb(t).prepare("SELECT data FROM kv_store WHERE key = ?").get(e);return s?JSON.parse(s.data):null}setDoc(t,e,r){let s=this.getDb(t),o=JSON.stringify(r),i=new Date().toISOString();s.prepare("INSERT OR REPLACE INTO kv_store (key, data, updated_at) VALUES (?, ?, ?)").run(e,o,i)}deleteDoc(t,e){this.getDb(t).prepare("DELETE FROM kv_store WHERE key = ?").run(e)}hasDoc(t,e){return this.getDb(t).prepare("SELECT 1 FROM kv_store WHERE key = ?").get(e)!==null}appendEvent(t,e,r,s){let o=this.getDb(t),i=new Date().toISOString();o.prepare("INSERT INTO events (type, task_id, data, timestamp) VALUES (?, ?, ?, ?)").run(e,s??null,JSON.stringify(r),i)}getEvents(t,e,r=100){let s=this.getDb(t);return e?s.prepare("SELECT * FROM events WHERE type = ? ORDER BY id DESC LIMIT ?").all(e,r):s.prepare("SELECT * FROM events ORDER BY id DESC LIMIT ?").all(r)}query(t,e,...r){return this.getDb(t).prepare(e).all(...r)}run(t,e,...r){this.getDb(t).prepare(e).run(...r)}get(t,e,...r){return this.getDb(t).prepare(e).get(...r)??null}transaction(t,e){let r=this.getDb(t);return r.transaction(e)(r)}runMigrations(t){t.run(`
485
+ `)},"up")},{version:14,name:"workflow-rules-trust-source",up:c(n=>{try{n.run("ALTER TABLE workflow_rules ADD COLUMN trust_source TEXT NOT NULL DEFAULT 'local'")}catch{}},"up")},{version:15,name:"disable-orphan-workflow-rules",up:c(n=>{let e=["pause","resume","reopen","next","dash","bug","idea","linear","jira","tokens","velocity","plan"].map(r=>`'${r}'`).join(",");n.run(`UPDATE workflow_rules SET enabled = 0 WHERE command IN (${e}) AND enabled = 1`)},"up")}],ls=3,Dt=class{static{c(this,"PrjctDatabase")}connections=new Map;accessOrder=[];getDbPath(t){return He.join(w.getGlobalProjectPath(t),"prjct.db")}getDb(t){let e=this.connections.get(t);if(e)return this.touchAccessOrder(t),e;this.connections.size>=ls&&this.evictLru();let r=this.getDbPath(t),s=He.dirname(r);It.existsSync(s)||It.mkdirSync(s,{recursive:!0});let i=cs(r);return i.run("PRAGMA journal_mode = WAL"),i.run("PRAGMA synchronous = NORMAL"),i.run("PRAGMA cache_size = -2000"),i.run("PRAGMA temp_store = MEMORY"),i.run("PRAGMA mmap_size = 33554432"),this.runMigrations(i),this.connections.set(t,i),this.touchAccessOrder(t),i}close(t){if(t){let e=this.connections.get(t);e&&(e.close(),this.connections.delete(t),this.accessOrder=this.accessOrder.filter(r=>r!==t))}else this.connections.forEach(e=>{e.close()}),this.connections.clear(),this.accessOrder=[]}touchAccessOrder(t){this.accessOrder=this.accessOrder.filter(e=>e!==t),this.accessOrder.push(t)}evictLru(){if(this.accessOrder.length===0)return;let t=this.accessOrder.shift(),e=this.connections.get(t);e&&(e.close(),this.connections.delete(t))}checkpointAll(){for(let[t,e]of this.connections)try{e.run("PRAGMA wal_checkpoint(TRUNCATE)")}catch{}}exists(t){return It.existsSync(this.getDbPath(t))}getDoc(t,e){let s=this.getDb(t).prepare("SELECT data FROM kv_store WHERE key = ?").get(e);return s?JSON.parse(s.data):null}setDoc(t,e,r){let s=this.getDb(t),i=JSON.stringify(r),o=new Date().toISOString();s.prepare("INSERT OR REPLACE INTO kv_store (key, data, updated_at) VALUES (?, ?, ?)").run(e,i,o)}deleteDoc(t,e){this.getDb(t).prepare("DELETE FROM kv_store WHERE key = ?").run(e)}hasDoc(t,e){return this.getDb(t).prepare("SELECT 1 FROM kv_store WHERE key = ?").get(e)!==null}appendEvent(t,e,r,s){let i=this.getDb(t),o=new Date().toISOString();i.prepare("INSERT INTO events (type, task_id, data, timestamp) VALUES (?, ?, ?, ?)").run(e,s??null,JSON.stringify(r),o)}getEvents(t,e,r=100){let s=this.getDb(t);return e?s.prepare("SELECT * FROM events WHERE type = ? ORDER BY id DESC LIMIT ?").all(e,r):s.prepare("SELECT * FROM events ORDER BY id DESC LIMIT ?").all(r)}query(t,e,...r){return this.getDb(t).prepare(e).all(...r)}run(t,e,...r){this.getDb(t).prepare(e).run(...r)}get(t,e,...r){return this.getDb(t).prepare(e).get(...r)??null}transaction(t,e){let r=this.getDb(t);return r.transaction(e)(r)}runMigrations(t){t.run(`
485
486
  CREATE TABLE IF NOT EXISTS _migrations (
486
487
  version INTEGER PRIMARY KEY,
487
488
  name TEXT NOT NULL,
488
489
  applied_at TEXT NOT NULL
489
490
  )
490
- `);let e=new Set(t.prepare("SELECT version FROM _migrations").all().map(r=>r.version));for(let r of Ss)e.has(r.version)||t.transaction(()=>{r.up(t),t.prepare("INSERT INTO _migrations (version, name, applied_at) VALUES (?, ?, ?)").run(r.version,r.name,new Date().toISOString())})()}getMigrations(t){return this.getDb(t).prepare("SELECT * FROM _migrations ORDER BY version").all()}getSchemaVersion(t){return this.getDb(t).prepare("SELECT MAX(version) as version FROM _migrations").get()?.version??0}},T=new Ft,E=T;U();function vs(n){let t=[],e,r=new RegExp(ye.source,"g");for(;(e=r.exec(n))!==null;){let s=e[1];(s.startsWith(".")||s.startsWith("@/"))&&t.push(s)}return t}c(vs,"extractImportSources");async function _s(n,t,e){let r;if(n.startsWith("@/"))r=J.join(e,"src",n.slice(2));else{let s=J.dirname(J.join(e,t));r=J.resolve(s,n)}for(let s of he){let o=r+s;try{if((await Ye.stat(o)).isFile())return J.relative(e,o)}catch{}}return null}c(_s,"resolveImport");async function Ps(n){let t=await _e(n),e={},r={},s=0,o=await Pe(t,50,async i=>{try{let a=await Ye.readFile(J.join(n,i),"utf-8"),u=vs(a),p=[];for(let m of u){let d=await _s(m,i,n);d&&d!==i&&p.push(d)}return p.length>0?{filePath:i,imports:p}:null}catch{return null}});for(let{filePath:i,imports:a}of o){e[i]=a,s+=a.length;for(let u of a)r[u]||(r[u]=[]),r[u].push(i)}return{forward:e,reverse:r,fileCount:t.length,edgeCount:s,builtAt:new Date().toISOString()}}c(Ps,"buildGraph");function Je(n,t,e=2){let r=new Set(n),s=new Map,o=[];for(let i of n){let a=t.forward[i]||[],u=t.reverse[i]||[];for(let p of[...a,...u])r.has(p)||o.push({file:p,depth:1})}for(;o.length>0;){let{file:i,depth:a}=o.shift();if(a>e)continue;let u=1/(a+1),p=s.get(i);if(p){u>p.score&&s.set(i,{score:u,depth:a});continue}if(s.set(i,{score:u,depth:a}),a<e){let m=t.forward[i]||[],d=t.reverse[i]||[];for(let g of[...m,...d])!r.has(g)&&!s.has(g)&&o.push({file:g,depth:a+1})}}return Array.from(s.entries()).map(([i,{score:a,depth:u}])=>({path:i,score:a,depth:u})).sort((i,a)=>a.score-i.score)}c(Je,"scoreFromSeeds");var Ve="import-graph";function Rs(n,t){E.setDoc(n,Ve,t)}c(Rs,"saveGraph");function rt(n){return E.getDoc(n,Ve)}c(rt,"loadGraph");async function Ke(n,t){let e=await Ps(n);return Rs(t,e),e}c(Ke,"indexImports");function Qe(n,t){let e=[...n.added,...n.modified],r=new Set(e),s=new Set,o=rt(t);if(o)for(let u of e){let p=o.reverse[u];if(p)for(let m of p)r.has(m)||s.add(m)}let i=Array.from(s),a=[...e,...i];return{directlyChanged:e,affectedByImports:i,deleted:n.deleted,allAffected:a}}c(Qe,"propagateChanges");function Ze(n){let t=new Set;for(let e of n){let r=e.toLowerCase();(r.endsWith(".tsx")||r.endsWith(".jsx")||r.endsWith(".css")||r.endsWith(".scss")||r.endsWith(".vue")||r.endsWith(".svelte")||r.includes("/components/")||r.includes("/pages/")||r.includes("/app/"))&&(t.add("frontend"),t.add("uxui")),(r.includes(".test.")||r.includes(".spec.")||r.includes("__tests__")||r.includes("/test/"))&&t.add("testing"),(r.includes("dockerfile")||r.includes("docker-compose")||r.includes(".dockerignore")||r.includes(".github/")||r.includes("ci/")||r.includes("cd/"))&&t.add("devops"),(r.endsWith(".sql")||r.includes("prisma")||r.includes("drizzle")||r.includes("migration")||r.includes("/db/"))&&t.add("database"),(r.endsWith(".ts")||r.endsWith(".js"))&&!r.includes(".test.")&&!r.includes(".spec.")&&!r.endsWith(".d.ts")&&t.add("backend")}return t}c(Ze,"affectedDomains");z();async function Ns(n,t=100){try{let{stdout:e}=await k(`git log --name-only --pretty=format:'---COMMIT---' -${t}`,{cwd:n,maxBuffer:10485760}),r=[],s=null;for(let o of e.split(`
491
- `)){let i=o.trim();i==="---COMMIT---"?(s&&s.size>0&&s.size<=30&&r.push(s),s=new Set):i&&s&&Cs(i)&&s.add(i)}return s&&s.size>0&&s.size<=30&&r.push(s),r}catch{return[]}}c(Ns,"parseGitLog");function Cs(n){return/\.(ts|tsx|js|jsx|mjs|cjs|py|go|rs|java|cs|rb|php|vue|svelte)$/i.test(n)&&!n.includes("node_modules/")}c(Cs,"isSourceFile");async function Is(n,t=100){let e=await Ns(n,t),r=new Map,s=new Map;for(let i of e){let a=Array.from(i);for(let u of a)r.set(u,(r.get(u)||0)+1);for(let u=0;u<a.length;u++)for(let p=u+1;p<a.length;p++){let m=Ds(a[u],a[p]);s.set(m,(s.get(m)||0)+1)}}let o={};for(let[i,a]of s){let[u,p]=i.split("\0"),m=r.get(u)||0,d=r.get(p)||0;if(m<2||d<2)continue;let g=m+d-a,y=g>0?a/g:0;y<.1||(o[u]||(o[u]={}),o[p]||(o[p]={}),o[u][p]=y,o[p][u]=y)}return{matrix:o,commitsAnalyzed:e.length,filesAnalyzed:r.size,builtAt:new Date().toISOString()}}c(Is,"buildMatrix");function Ds(n,t){return n<t?`${n}\0${t}`:`${t}\0${n}`}c(Ds,"pairKey");function Ut(n,t){let e=new Set(n),r=new Map;for(let s of n){let o=t.matrix[s];if(o)for(let[i,a]of Object.entries(o)){if(e.has(i))continue;let u=r.get(i)||0;a>u&&r.set(i,a)}}return Array.from(r.entries()).map(([s,o])=>({path:s,score:o})).sort((s,o)=>o.score-s.score)}c(Ut,"scoreFromSeeds");var rr="cochange-index";function Ls(n,t){E.setDoc(n,rr,t)}c(Ls,"saveMatrix");function Xt(n){return E.getDoc(n,rr)}c(Xt,"loadMatrix");async function sr(n,t,e=100){let r=await Is(n,e);return Ls(t,r),r}c(sr,"indexCoChanges");import zt from"node:fs/promises";import Gs from"node:path";import*as Tt from"jsonc-parser";import{z as w}from"zod";var V={create(n,t){class e extends Error{static{c(this,"TypedError")}errorName;data;isOperational=!0;constructor(s){let o=t.parse(s);super(`${n}: ${JSON.stringify(o)}`),this.name=n,this.errorName=n,this.data=o,Error.captureStackTrace?.(this,this.constructor)}static throw(s){throw new e(s)}static is(s){return s instanceof e&&s.errorName===n}static create(s){return new e(s)}}return e}},pi=V.create("FileError",w.object({path:w.string(),operation:w.enum(["read","write","delete","create","copy"]),reason:w.string().optional()})),di=V.create("ValidationError",w.object({field:w.string(),expected:w.string(),received:w.string().optional(),message:w.string().optional()})),mi=V.create("PermissionError",w.object({action:w.string(),resource:w.string(),reason:w.string().optional()})),gi=V.create("TaskError",w.object({taskId:w.string().optional(),operation:w.enum(["create","update","complete","pause","resume","delete"]),reason:w.string()})),fi=V.create("SessionError",w.object({sessionId:w.string().optional(),reason:w.string()})),hi=V.create("SyncError",w.object({projectId:w.string().optional(),operation:w.enum(["push","pull","auth","connect"]),reason:w.string()})),$t=class extends Error{static{c(this,"PrjctError")}code;isOperational;constructor(t,e="PRJCT_ERROR"){super(t),this.name="PrjctError",this.code=e,this.isOperational=!0,Error.captureStackTrace?.(this,this.constructor)}};function Os(n){return n instanceof $t}c(Os,"isPrjctError");function Wt(n){return Os(n)||n instanceof Error?n.message:typeof n=="string"?n:"Unknown error"}c(Wt,"getErrorMessage");W();U();W();import Gt from"node:fs";import ht from"node:path";var ft=null,js=null,st=null;function nr(){if(st)return st;let n=__dirname;for(let t=0;t<5;t++){let e=ht.join(n,"package.json");if(Gt.existsSync(e))try{if(JSON.parse(Gt.readFileSync(e,"utf-8")).name==="prjct-cli")return st=n,n}catch{}n=ht.dirname(n)}return st=ht.join(__dirname,"..","..",".."),st}c(nr,"getPackageRoot");function Ms(){if(ft)return ft;try{let n=ht.join(nr(),"package.json"),t=JSON.parse(Gt.readFileSync(n,"utf-8"));return ft=t.version,js=t,ft}catch(n){return console.error("Failed to read version from package.json:",ke(n)),"0.0.0"}}c(Ms,"getVersion");var Bt=Ms(),bi=nr();z();async function yt(n){try{let{stdout:t}=await k(n,{timeout:5e3});return{success:!0,output:t.trim()}}catch{return{success:!1,output:""}}}c(yt,"execCommand");async function Fs(){let n=await yt("gh api user --jq .login");return n.success&&n.output||(n=await yt("git config --global github.user"),n.success&&n.output)?n.output:null}c(Fs,"detectGitHubUsername");async function Us(){let n=await yt("git config user.name");return n.success&&n.output?n.output:null}c(Us,"detectGitName");async function Xs(){let n=await yt("git config user.email");return n.success&&n.output?n.output:null}c(Xs,"detectGitEmail");async function or(){let[n,t,e]=await Promise.all([Fs(),Us(),Xs()]);return{github:n,email:e,name:t||n||"Unknown"}}c(or,"detect");function lr(n){let t=[],e=Tt.parse(n,t,{allowTrailingComma:!0,disallowComments:!1});if(t.length>0){let r=t[0];throw new SyntaxError(`JSON parse error at offset ${r.offset}: ${Tt.printParseErrorCode(r.error)}`)}return e}c(lr,"parseJsonc");var Yt=class{static{c(this,"ConfigManager")}async readConfig(t){try{let e=b.getLocalConfigPath(t),r=await zt.readFile(e,"utf-8");return lr(r)}catch(e){return N(e)||console.warn(`Warning: Could not read config at ${t}: ${Wt(e)}`),null}}async writeConfig(t,e){let r=b.getLocalConfigPath(t);await M(r,e)}async readGlobalConfig(t){try{let e=b.getGlobalProjectConfigPath(t),r=await zt.readFile(e,"utf-8");return lr(r)}catch(e){return N(e)||console.warn(`Warning: Could not read global config for ${t}: ${Wt(e)}`),null}}async writeGlobalConfig(t,e){let r=b.getGlobalProjectConfigPath(t);await M(r,e)}async ensureGlobalConfig(t){let e=await this.readGlobalConfig(t);if(!e){let r=f();e={projectId:t,authors:[],version:Bt,lastSync:r},await this.writeGlobalConfig(t,e)}return e}async createConfig(t,e){let r=b.generateProjectId(t),s=b.getGlobalProjectPath(r),o=b.getDisplayPath(s),i=f(),a={projectId:r,dataPath:o,showMetrics:!0};await this.writeConfig(t,a);let u={projectId:r,authors:[{name:e.name||"Unknown",email:e.email||"",github:e.github||"",firstContribution:i,lastActivity:i}],version:Bt,created:i,lastSync:i};return await this.writeGlobalConfig(r,u),a}async updateLastSync(t){let e=await this.getProjectId(t),r=await this.readGlobalConfig(e);r&&(r.lastSync=f(),await this.writeGlobalConfig(e,r))}validateConfig(t){return!(!t||!t.projectId||!t.dataPath)}async needsMigration(t){if(!await b.hasLegacyStructure(t))return!1;if(!await b.hasConfig(t))return!0;let s=await this.readConfig(t);if(!s||!s.projectId)return!0;let o=b.getGlobalProjectPath(s.projectId);try{return(await zt.readdir(Gs.join(o,"core"))).length===0}catch(i){return N(i),!0}}async getProjectId(t){let e=await this.readConfig(t);if(e?.projectId)return e.projectId;try{let{worktreeService:r}=await Promise.resolve().then(()=>(ur(),cr));if(await r.detect(t)){let o=await r.getMainWorktree(t);if(o!==t){let i=await this.readConfig(o);if(i?.projectId)return i.projectId}}}catch{}return b.generateProjectId(t)}async findAuthor(t,e){let r=await this.readGlobalConfig(t);return!r||!r.authors?null:r.authors.find(s=>s.github===e)||null}async addAuthor(t,e){let r=await this.ensureGlobalConfig(t);if(r.authors.some(i=>i.github===e.github))return;let o=f();r.authors.push({name:e.name||"Unknown",email:e.email||"",github:e.github||"",firstContribution:o,lastActivity:o}),r.lastSync=o,await this.writeGlobalConfig(t,r)}async updateAuthorActivity(t,e){let r=await this.readGlobalConfig(t);if(!r||!r.authors)return;let s=r.authors.find(o=>o.github===e);s&&(s.lastActivity=f(),r.lastSync=s.lastActivity,await this.writeGlobalConfig(t,r))}async getCurrentAuthor(t){let e=await or(),r=await this.getProjectId(t);return await this.addAuthor(r,{name:e.name??void 0,email:e.email??void 0,github:e.github??void 0}),e.github||e.name||"Unknown"}async isConfigured(t){let e=await this.readConfig(t);return this.validateConfig(e)}async getShowMetrics(t){return(await this.readConfig(t))?.showMetrics??!0}async setShowMetrics(t,e){let r=await this.readConfig(t);r&&(r.showMetrics=e,await this.writeConfig(t,r))}async getConfigWithDefaults(t){let e=await this.readConfig(t);if(e)return e;let r=b.generateProjectId(t);return{projectId:r,dataPath:b.getDisplayPath(b.getGlobalProjectPath(r))}}},Bs=new Yt,B=Bs;async function P(n){return B.getProjectId(n)}c(P,"resolveProjectId");function S(n,t){return async e=>{try{return await t(e)}catch(r){return Hs(r,n)}}}c(S,"safeMcpCall");function Hs(n,t){let e=n instanceof Error?n.message:String(n);return{content:[{type:"text",text:`[${t}] Error: ${e}`}],isError:!0}}c(Hs,"mcpError");function pr(n){let t=n;t.tool("prjct_impact_analysis","Given changed files, find affected files via import graph + affected domains",{projectPath:A.string().describe("Project directory path"),changedFiles:A.array(A.string()).describe("List of changed file paths (relative to project root)")},S("prjct_impact_analysis",async e=>{let r=await P(e.projectPath),s={added:[],modified:e.changedFiles,deleted:[],unchanged:[]},o=Qe(s,r),i=Ze(o.allAffected),a=["## Impact Analysis"];a.push(`
492
- ### Directly Changed (${o.directlyChanged.length})`);for(let u of o.directlyChanged)a.push(`- ${u}`);if(o.affectedByImports.length>0){a.push(`
493
- ### Affected via Imports (${o.affectedByImports.length})`);for(let u of o.affectedByImports)a.push(`- ${u}`)}return a.push(`
494
- ### Affected Domains`),a.push(i.size>0?Array.from(i).join(", "):"none detected"),a.push(`
495
- Total affected: ${o.allAffected.length} files`),{content:[{type:"text",text:a.join(`
496
- `)}]}})),t.tool("prjct_import_graph","Import graph stats + file neighbors (imports/importers). Pass a file for its neighbors, omit for graph stats.",{projectPath:A.string().describe("Project directory path"),file:A.string().optional().describe("File path to get neighbors for (omit for graph stats)"),rebuild:A.boolean().optional().default(!1).describe("Force rebuild the import graph")},S("prjct_import_graph",async e=>{let r=await P(e.projectPath),s=e.rebuild?null:rt(r);if(s||(s=await Ke(e.projectPath,r)),e.file){let i=s.forward[e.file]||[],a=s.reverse[e.file]||[];return{content:[{type:"text",text:[`## Import Neighbors: ${e.file}`,`
497
- ### Imports (${i.length})`,...i.map(p=>`- ${p}`),`
498
- ### Imported By (${a.length})`,...a.map(p=>`- ${p}`)].join(`
491
+ `);let e=new Set(t.prepare("SELECT version FROM _migrations").all().map(r=>r.version));for(let r of us)e.has(r.version)||t.transaction(()=>{r.up(t),t.prepare("INSERT INTO _migrations (version, name, applied_at) VALUES (?, ?, ?)").run(r.version,r.name,new Date().toISOString())})()}getMigrations(t){return this.getDb(t).prepare("SELECT * FROM _migrations ORDER BY version").all()}getSchemaVersion(t){return this.getDb(t).prepare("SELECT MAX(version) as version FROM _migrations").get()?.version??0}},y=new Dt,E=y;M();function ds(n){let t=[],e,r=new RegExp(me.source,"g");for(;(e=r.exec(n))!==null;){let s=e[1];(s.startsWith(".")||s.startsWith("@/"))&&t.push(s)}return t}c(ds,"extractImportSources");async function ps(n,t,e){let r;if(n.startsWith("@/"))r=q.join(e,"src",n.slice(2));else{let s=q.dirname(q.join(e,t));r=q.resolve(s,n)}for(let s of pe){let i=r+s;try{if((await qe.stat(i)).isFile())return q.relative(e,i)}catch{}}return null}c(ps,"resolveImport");async function ms(n){let t=await be(n),e={},r={},s=0,i=await Se(t,50,async o=>{try{let a=await qe.readFile(q.join(n,o),"utf-8"),u=ds(a),d=[];for(let m of u){let p=await ps(m,o,n);p&&p!==o&&d.push(p)}return d.length>0?{filePath:o,imports:d}:null}catch{return null}});for(let{filePath:o,imports:a}of i){e[o]=a,s+=a.length;for(let u of a)r[u]||(r[u]=[]),r[u].push(o)}return{forward:e,reverse:r,fileCount:t.length,edgeCount:s,builtAt:new Date().toISOString()}}c(ms,"buildGraph");function Ye(n,t,e=2){let r=new Set(n),s=new Map,i=[];for(let o of n){let a=t.forward[o]||[],u=t.reverse[o]||[];for(let d of[...a,...u])r.has(d)||i.push({file:d,depth:1})}for(;i.length>0;){let{file:o,depth:a}=i.shift();if(a>e)continue;let u=1/(a+1),d=s.get(o);if(d){u>d.score&&s.set(o,{score:u,depth:a});continue}if(s.set(o,{score:u,depth:a}),a<e){let m=t.forward[o]||[],p=t.reverse[o]||[];for(let g of[...m,...p])!r.has(g)&&!s.has(g)&&i.push({file:g,depth:a+1})}}return Array.from(s.entries()).map(([o,{score:a,depth:u}])=>({path:o,score:a,depth:u})).sort((o,a)=>a.score-o.score)}c(Ye,"scoreFromSeeds");var Lt="import-graph",lt=new Map;function gs(n,t){E.setDoc(n,Lt,t),lt.delete(n)}c(gs,"saveGraph");function Z(n){let t=E.get(n,"SELECT updated_at FROM kv_store WHERE key = ?",Lt);if(!t)return lt.delete(n),null;let e=lt.get(n);if(e&&e.updatedAt===t.updated_at)return e.graph;let r=E.getDoc(n,Lt);return r&&lt.set(n,{graph:r,updatedAt:t.updated_at}),r}c(Z,"loadGraph");async function ze(n,t){let e=await ms(n);return gs(t,e),e}c(ze,"indexImports");function Je(n,t){let e=[...n.added,...n.modified],r=new Set(e),s=new Set,i=Z(t);if(i)for(let u of e){let d=i.reverse[u];if(d)for(let m of d)r.has(m)||s.add(m)}let o=Array.from(s),a=[...e,...o];return{directlyChanged:e,affectedByImports:o,deleted:n.deleted,allAffected:a}}c(Je,"propagateChanges");function Ke(n){let t=new Set;for(let e of n){let r=e.toLowerCase();(r.endsWith(".tsx")||r.endsWith(".jsx")||r.endsWith(".css")||r.endsWith(".scss")||r.endsWith(".vue")||r.endsWith(".svelte")||r.includes("/components/")||r.includes("/pages/")||r.includes("/app/"))&&(t.add("frontend"),t.add("uxui")),(r.includes(".test.")||r.includes(".spec.")||r.includes("__tests__")||r.includes("/test/"))&&t.add("testing"),(r.includes("dockerfile")||r.includes("docker-compose")||r.includes(".dockerignore")||r.includes(".github/")||r.includes("ci/")||r.includes("cd/"))&&t.add("devops"),(r.endsWith(".sql")||r.includes("prisma")||r.includes("drizzle")||r.includes("migration")||r.includes("/db/"))&&t.add("database"),(r.endsWith(".ts")||r.endsWith(".js"))&&!r.includes(".test.")&&!r.includes(".spec.")&&!r.endsWith(".d.ts")&&t.add("backend")}return t}c(Ke,"affectedDomains");B();async function hs(n,t=100){try{let{stdout:e}=await k(`git log --name-only --pretty=format:'---COMMIT---' -${t}`,{cwd:n,maxBuffer:10485760}),r=[],s=null;for(let i of e.split(`
492
+ `)){let o=i.trim();o==="---COMMIT---"?(s&&s.size>0&&s.size<=30&&r.push(s),s=new Set):o&&s&&Ts(o)&&s.add(o)}return s&&s.size>0&&s.size<=30&&r.push(s),r}catch{return[]}}c(hs,"parseGitLog");function Ts(n){return/\.(ts|tsx|js|jsx|mjs|cjs|py|go|rs|java|cs|rb|php|vue|svelte)$/i.test(n)&&!n.includes("node_modules/")}c(Ts,"isSourceFile");async function ys(n,t=100){let e=await hs(n,t),r=new Map,s=new Map;for(let o of e){let a=Array.from(o);for(let u of a)r.set(u,(r.get(u)||0)+1);for(let u=0;u<a.length;u++)for(let d=u+1;d<a.length;d++){let m=Es(a[u],a[d]);s.set(m,(s.get(m)||0)+1)}}let i={};for(let[o,a]of s){let[u,d]=o.split("\0"),m=r.get(u)||0,p=r.get(d)||0;if(m<2||p<2)continue;let g=m+p-a,T=g>0?a/g:0;T<.1||(i[u]||(i[u]={}),i[d]||(i[d]={}),i[u][d]=T,i[d][u]=T)}return{matrix:i,commitsAnalyzed:e.length,filesAnalyzed:r.size,builtAt:new Date().toISOString()}}c(ys,"buildMatrix");function Es(n,t){return n<t?`${n}\0${t}`:`${t}\0${n}`}c(Es,"pairKey");function Mt(n,t){let e=new Set(n),r=new Map;for(let s of n){let i=t.matrix[s];if(i)for(let[o,a]of Object.entries(i)){if(e.has(o))continue;let u=r.get(o)||0;a>u&&r.set(o,a)}}return Array.from(r.entries()).map(([s,i])=>({path:s,score:i})).sort((s,i)=>i.score-s.score)}c(Mt,"scoreFromSeeds");var Ot="cochange-index",dt=new Map;function ks(n,t){E.setDoc(n,Ot,t),dt.delete(n)}c(ks,"saveMatrix");function jt(n){let t=E.get(n,"SELECT updated_at FROM kv_store WHERE key = ?",Ot);if(!t)return dt.delete(n),null;let e=dt.get(n);if(e&&e.updatedAt===t.updated_at)return e.matrix;let r=E.getDoc(n,Ot);return r&&dt.set(n,{matrix:r,updatedAt:t.updated_at}),r}c(jt,"loadMatrix");async function Ze(n,t,e=100){let r=await ys(n,e);return ks(t,r),r}c(Ze,"indexCoChanges");import Bt from"node:fs/promises";import Ps from"node:path";import*as ft from"jsonc-parser";var Ft=class extends Error{static{c(this,"PrjctError")}code;isOperational;constructor(t,e="PRJCT_ERROR"){super(t),this.name="PrjctError",this.code=e,this.isOperational=!0,Error.captureStackTrace?.(this,this.constructor)}};function ws(n){return n instanceof Ft}c(ws,"isPrjctError");function Ut(n){return ws(n)||n instanceof Error?n.message:typeof n=="string"?n:"Unknown error"}c(Ut,"getErrorMessage");U();M();U();import Xt from"node:fs";import mt from"node:path";var pt=null,tt=null;function tr(){if(tt)return tt;let n=__dirname;for(let t=0;t<5;t++){let e=mt.join(n,"package.json");if(Xt.existsSync(e))try{if(JSON.parse(Xt.readFileSync(e,"utf-8")).name==="prjct-cli")return tt=n,n}catch{}n=mt.dirname(n)}return tt=mt.join(__dirname,"..","..",".."),tt}c(tr,"getPackageRoot");function bs(){if(pt)return pt;try{let n=mt.join(tr(),"package.json");return pt=JSON.parse(Xt.readFileSync(n,"utf-8")).version,pt}catch(n){return console.error("Failed to read version from package.json:",he(n)),"0.0.0"}}c(bs,"getVersion");var $t=bs(),Hi=tr();B();async function gt(n){try{let{stdout:t}=await k(n,{timeout:5e3});return{success:!0,output:t.trim()}}catch{return{success:!1,output:""}}}c(gt,"execCommand");async function Ss(){let n=await gt("gh api user --jq .login");return n.success&&n.output||(n=await gt("git config --global github.user"),n.success&&n.output)?n.output:null}c(Ss,"detectGitHubUsername");async function vs(){let n=await gt("git config user.name");return n.success&&n.output?n.output:null}c(vs,"detectGitName");async function _s(){let n=await gt("git config user.email");return n.success&&n.output?n.output:null}c(_s,"detectGitEmail");async function er(){let[n,t,e]=await Promise.all([Ss(),vs(),_s()]);return{github:n,email:e,name:t||n||"Unknown"}}c(er,"detect");function or(n){let t=[],e=ft.parse(n,t,{allowTrailingComma:!0,disallowComments:!1});if(t.length>0){let r=t[0];throw new SyntaxError(`JSON parse error at offset ${r.offset}: ${ft.printParseErrorCode(r.error)}`)}return e}c(or,"parseJsonc");var Ht=class{static{c(this,"ConfigManager")}async readConfig(t){try{let e=w.getLocalConfigPath(t),r=await Bt.readFile(e,"utf-8");return or(r)}catch(e){return P(e)||console.warn(`Warning: Could not read config at ${t}: ${Ut(e)}`),null}}async writeConfig(t,e){let r=w.getLocalConfigPath(t);await L(r,e)}async readGlobalConfig(t){try{let e=w.getGlobalProjectConfigPath(t),r=await Bt.readFile(e,"utf-8");return or(r)}catch(e){return P(e)||console.warn(`Warning: Could not read global config for ${t}: ${Ut(e)}`),null}}async writeGlobalConfig(t,e){let r=w.getGlobalProjectConfigPath(t);await L(r,e)}async ensureGlobalConfig(t){let e=await this.readGlobalConfig(t);if(!e){let r=f();e={projectId:t,authors:[],version:$t,lastSync:r},await this.writeGlobalConfig(t,e)}return e}async createConfig(t,e){let r=w.generateProjectId(t),s=w.getGlobalProjectPath(r),i=w.getDisplayPath(s),o=f(),a={projectId:r,dataPath:i,showMetrics:!0};await this.writeConfig(t,a);let u={projectId:r,authors:[{name:e.name||"Unknown",email:e.email||"",github:e.github||"",firstContribution:o,lastActivity:o}],version:$t,created:o,lastSync:o};return await this.writeGlobalConfig(r,u),a}async updateLastSync(t){let e=await this.getProjectId(t),r=await this.readGlobalConfig(e);r&&(r.lastSync=f(),await this.writeGlobalConfig(e,r))}validateConfig(t){return!(!t||!t.projectId||!t.dataPath)}async needsMigration(t){if(!await w.hasLegacyStructure(t))return!1;if(!await w.hasConfig(t))return!0;let s=await this.readConfig(t);if(!s||!s.projectId)return!0;let i=w.getGlobalProjectPath(s.projectId);try{return(await Bt.readdir(Ps.join(i,"core"))).length===0}catch(o){return P(o),!0}}async getProjectId(t){let e=await this.readConfig(t);if(e?.projectId)return e.projectId;try{let{worktreeService:r}=await Promise.resolve().then(()=>(ir(),nr));if(await r.detect(t)){let i=await r.getMainWorktree(t);if(i!==t){let o=await this.readConfig(i);if(o?.projectId)return o.projectId}}}catch{}return w.generateProjectId(t)}async findAuthor(t,e){let r=await this.readGlobalConfig(t);return!r||!r.authors?null:r.authors.find(s=>s.github===e)||null}async addAuthor(t,e){let r=await this.ensureGlobalConfig(t);if(r.authors.some(o=>o.github===e.github))return;let i=f();r.authors.push({name:e.name||"Unknown",email:e.email||"",github:e.github||"",firstContribution:i,lastActivity:i}),r.lastSync=i,await this.writeGlobalConfig(t,r)}async updateAuthorActivity(t,e){let r=await this.readGlobalConfig(t);if(!r||!r.authors)return;let s=r.authors.find(i=>i.github===e);s&&(s.lastActivity=f(),r.lastSync=s.lastActivity,await this.writeGlobalConfig(t,r))}async getCurrentAuthor(t){let e=await er(),r=await this.getProjectId(t);return await this.addAuthor(r,{name:e.name??void 0,email:e.email??void 0,github:e.github??void 0}),e.github||e.name||"Unknown"}async isConfigured(t){let e=await this.readConfig(t);return this.validateConfig(e)}async getShowMetrics(t){return(await this.readConfig(t))?.showMetrics??!0}async setShowMetrics(t,e){let r=await this.readConfig(t);r&&(r.showMetrics=e,await this.writeConfig(t,r))}async getConfigWithDefaults(t){let e=await this.readConfig(t);if(e)return e;let r=w.generateProjectId(t);return{projectId:r,dataPath:w.getDisplayPath(w.getGlobalProjectPath(r))}}},As=new Ht,$=As;async function v(n){return $.getProjectId(n)}c(v,"resolveProjectId");function b(n,t){return async e=>{try{return await t(e)}catch(r){return Ns(r,n)}}}c(b,"safeMcpCall");function Ns(n,t){let e=n instanceof Error?n.message:String(n);return{content:[{type:"text",text:`[${t}] Error: ${e}`}],isError:!0}}c(Ns,"mcpError");function ar(n){let t=n;t.tool("prjct_impact_analysis","Given changed files, find affected files via import graph + affected domains",{projectPath:R.string().describe("Project directory path"),changedFiles:R.array(R.string()).describe("List of changed file paths (relative to project root)")},b("prjct_impact_analysis",async e=>{let r=await v(e.projectPath),s={added:[],modified:e.changedFiles,deleted:[],unchanged:[]},i=Je(s,r),o=Ke(i.allAffected),a=["## Impact Analysis"];a.push(`
493
+ ### Directly Changed (${i.directlyChanged.length})`);for(let u of i.directlyChanged)a.push(`- ${u}`);if(i.affectedByImports.length>0){a.push(`
494
+ ### Affected via Imports (${i.affectedByImports.length})`);for(let u of i.affectedByImports)a.push(`- ${u}`)}return a.push(`
495
+ ### Affected Domains`),a.push(o.size>0?Array.from(o).join(", "):"none detected"),a.push(`
496
+ Total affected: ${i.allAffected.length} files`),{content:[{type:"text",text:a.join(`
497
+ `)}]}})),t.tool("prjct_import_graph","Import graph stats + file neighbors (imports/importers). Pass a file for its neighbors, omit for graph stats.",{projectPath:R.string().describe("Project directory path"),file:R.string().optional().describe("File path to get neighbors for (omit for graph stats)"),rebuild:R.boolean().optional().default(!1).describe("Force rebuild the import graph")},b("prjct_import_graph",async e=>{let r=await v(e.projectPath),s=e.rebuild?null:Z(r);if(s||(s=await ze(e.projectPath,r)),e.file){let o=s.forward[e.file]||[],a=s.reverse[e.file]||[];return{content:[{type:"text",text:[`## Import Neighbors: ${e.file}`,`
498
+ ### Imports (${o.length})`,...o.map(d=>`- ${d}`),`
499
+ ### Imported By (${a.length})`,...a.map(d=>`- ${d}`)].join(`
499
500
  `)}]}}return{content:[{type:"text",text:["## Import Graph Stats",`Files: ${s.fileCount}`,`Edges: ${s.edgeCount}`,`Built: ${s.builtAt}`].join(`
500
- `)}]}})),t.tool("prjct_cochange","Files that historically change together (Jaccard similarity from git history)",{projectPath:A.string().describe("Project directory path"),seedFiles:A.array(A.string()).describe("Seed files to find co-change partners for"),rebuild:A.boolean().optional().default(!1).describe("Force rebuild the co-change matrix"),maxResults:A.number().optional().default(10).describe("Max results (default 10)")},S("prjct_cochange",async e=>{let r=await P(e.projectPath),s=e.rebuild?null:Xt(r);s||(s=await sr(e.projectPath,r));let o=Ut(e.seedFiles,s).slice(0,e.maxResults);if(o.length===0)return{content:[{type:"text",text:"No co-change partners found."}]};let i=["## Co-Change Partners",`Seeds: ${e.seedFiles.join(", ")}`,`Commits analyzed: ${s.commitsAnalyzed}`,""];for(let a of o)i.push(`- ${a.path} (similarity: ${Math.round(a.score*100)}%)`);return{content:[{type:"text",text:i.join(`
501
- `)}]}})),t.tool("prjct_related_context","Combined: import neighbors + co-change partners for seed files",{projectPath:A.string().describe("Project directory path"),seedFiles:A.array(A.string()).describe("Seed files to find related context for"),maxResults:A.number().optional().default(15).describe("Max results (default 15)")},S("prjct_related_context",async e=>{let r=await P(e.projectPath),s=rt(r),o=s?Je(e.seedFiles,s):[],i=Xt(r),a=i?Ut(e.seedFiles,i):[],u=new Map;for(let d of o)u.set(d.path,{importScore:d.score,cochangeScore:0});for(let d of a){let g=u.get(d.path);g?g.cochangeScore=d.score:u.set(d.path,{importScore:0,cochangeScore:d.score})}let p=Array.from(u.entries()).map(([d,g])=>({path:d,combined:g.importScore*.6+g.cochangeScore*.4,importScore:g.importScore,cochangeScore:g.cochangeScore})).sort((d,g)=>g.combined-d.combined).slice(0,e.maxResults);if(p.length===0)return{content:[{type:"text",text:"No related files found. Run `prjct sync` to build indexes."}]};let m=["## Related Context",`Seeds: ${e.seedFiles.join(", ")}`,""];for(let d of p){let g=[];d.importScore>0&&g.push(`import: ${d.importScore.toFixed(2)}`),d.cochangeScore>0&&g.push(`cochange: ${Math.round(d.cochangeScore*100)}%`),m.push(`- ${d.path} (${g.join(", ")})`)}return{content:[{type:"text",text:m.join(`
502
- `)}]}}))}c(pr,"registerCodeIntelTools");import{z as H}from"zod";import qs from"node:crypto";import{homedir as zs}from"node:os";import{join as Ys}from"node:path";function $(){return qs.randomUUID()}c($,"generateUUID");var na=Ys(zs(),".prjct-cli","projects");At();import{z as l}from"zod";var Js=l.enum(["low","medium","high","critical"]),Et=l.enum(["feature","bug","improvement","chore"]),Vs=l.enum(["active","backlog","previously_active"]),Ks=l.enum(["pending","in_progress","completed","blocked","paused","failed","skipped"]),Qs=l.enum(["task_completed","feature_shipped","idea_captured","session_started"]),Jt=l.object({title:l.string(),description:l.string(),filesChanged:l.array(l.object({path:l.string(),action:l.enum(["created","modified","deleted"])})),whatWasDone:l.array(l.string()).min(1),outputForNextAgent:l.string().min(1),notes:l.string().optional()}),mr=l.object({output:l.string().min(1,"Subtask output is required"),summary:Jt}),gr=l.object({id:l.string(),description:l.string(),domain:l.string(),agent:l.string(),status:Ks,dependsOn:l.array(l.string()),startedAt:l.string().optional(),completedAt:l.string().optional(),output:l.string().optional(),summary:Jt.optional(),skipReason:l.string().optional(),blockReason:l.string().optional(),estimatedPoints:l.number().optional(),estimatedMinutes:l.number().optional()}),fr=l.object({completed:l.number(),total:l.number(),percentage:l.number()}),Vt=l.object({id:l.string(),description:l.string(),type:Et.optional(),startedAt:l.string(),sessionId:l.string(),featureId:l.string().optional(),subtasks:l.array(gr).optional(),currentSubtaskIndex:l.number().optional(),subtaskProgress:fr.optional(),linearId:l.string().optional(),linearUuid:l.string().optional(),estimatedPoints:l.number().optional(),estimatedMinutes:l.number().optional(),modelMetadata:lt.optional(),tokensIn:l.number().optional(),tokensOut:l.number().optional(),parentDescription:l.string().optional(),branch:l.string().optional(),prUrl:l.string().optional()}),dr=l.object({id:l.string(),description:l.string(),status:l.literal("paused"),startedAt:l.string(),pausedAt:l.string(),pauseReason:l.string().optional(),type:Et.optional(),sessionId:l.string().optional(),featureId:l.string().optional(),subtasks:l.array(gr).optional(),currentSubtaskIndex:l.number().optional(),subtaskProgress:fr.optional(),linearId:l.string().optional(),linearUuid:l.string().optional(),estimatedPoints:l.number().optional(),estimatedMinutes:l.number().optional(),modelMetadata:lt.optional(),tokensIn:l.number().optional(),tokensOut:l.number().optional()}),Zs=l.object({stackConfirmed:l.array(l.string()).optional(),patternsDiscovered:l.array(l.string()).optional(),agentAccuracy:l.array(l.object({agent:l.string(),rating:l.enum(["helpful","neutral","inaccurate"]),note:l.string().optional()})).optional(),issuesEncountered:l.array(l.string()).optional()}),tn=l.object({taskId:l.string(),title:l.string(),classification:Et,startedAt:l.string(),completedAt:l.string(),subtaskCount:l.number(),subtaskSummaries:l.array(Jt),outcome:l.string(),branchName:l.string(),linearId:l.string().optional(),linearUuid:l.string().optional(),prUrl:l.string().optional(),feedback:Zs.optional(),tokensIn:l.number().optional(),tokensOut:l.number().optional()}),en=Vt.extend({workspaceId:l.string(),worktreePath:l.string().optional(),agentSessionId:l.string().optional(),jiraId:l.string().optional(),jiraUuid:l.string().optional(),dispatchedFrom:l.string().optional()}),hr=l.object({currentTask:Vt.nullable(),previousTask:dr.nullable().optional(),pausedTasks:l.array(dr).optional(),taskHistory:l.array(tn).optional(),activeTasks:l.array(en).optional(),lastUpdated:l.string()}),yr=l.object({id:l.string(),description:l.string(),body:l.string().optional(),priority:Js,type:Et,featureId:l.string().optional(),originFeature:l.string().optional(),completed:l.boolean(),completedAt:l.string().optional(),createdAt:l.string(),section:Vs,agent:l.string().optional(),groupName:l.string().optional(),groupId:l.string().optional()}),Tr=l.object({tasks:l.array(yr),lastUpdated:l.string()}),rn=l.object({tasksToday:l.number(),tasksThisWeek:l.number(),streak:l.number(),velocity:l.string(),avgDuration:l.string()}),sn=l.object({type:Qs,description:l.string(),timestamp:l.string(),duration:l.string().optional()}),ua=l.object({projectId:l.string(),currentTask:Vt.nullable(),queue:l.array(yr),stats:rn,recentActivity:l.array(sn),lastSync:l.string()});var nt={idle:{transitions:["task"],prompt:"prjct task <description> Start working",description:"No active task"},working:{transitions:["done","pause"],prompt:"prjct status done Complete task | prjct status paused Switch context",description:"Task in progress"},paused:{transitions:["resume","task","ship"],prompt:"prjct status active Continue | prjct task <new> Start different | prjct ship Ship directly",description:"Task paused"},completed:{transitions:["ship","task","pause","reopen"],prompt:"prjct ship Ship it | prjct task <next> Start next | prjct status active Reopen",description:"Task completed"},shipped:{transitions:["task"],prompt:"prjct task <description> Start new task",description:"Feature shipped"}},Kt=class{static{c(this,"WorkflowStateMachine")}getCurrentState(t,e){let r=null;if(e&&t?.activeTasks?.length&&(r=t.activeTasks.find(o=>o.workspaceId===e)),r||(r=t?.currentTask),!r)return(t?.pausedTasks?.length||0)>0||t?.previousTask?.status==="paused"?"paused":"idle";switch((typeof r.status=="string"?r.status:"").toLowerCase()){case"in_progress":case"working":return"working";case"paused":return"paused";case"completed":case"done":return"completed";case"shipped":return"shipped";default:return r?"working":"idle"}}canTransition(t,e){if(nt[t].transitions.includes(e))return{valid:!0};let s=this.formatNextSteps(t).join(" | ");return{valid:!1,error:`Cannot transition to '${e}' from '${t}' state`,suggestion:`Valid next steps: ${s}`}}getNextState(t,e){switch(e){case"task":return"working";case"done":return"completed";case"pause":return"paused";case"resume":return"working";case"ship":return"shipped";case"reopen":return"working";default:return t}}getStateInfo(t){return nt[t]}getPrompt(t){return nt[t].prompt}getValidCommands(t){return nt[t].transitions}formatNextSteps(t){return nt[t].transitions.map(r=>{switch(r){case"task":return"prjct task <desc> Start new task";case"done":return"prjct status done Complete current task";case"pause":return"prjct status paused Pause and switch context";case"resume":return"prjct status active Continue paused task";case"ship":return"prjct ship Ship the feature";case"reopen":return"prjct status active Reopen completed task";default:return`prjct ${r}`}})}},Qt=new Kt;var ot={SHIPPED_RETENTION_DAYS:90,IDEA_DORMANT_DAYS:180,QUEUE_COMPLETED_DAYS:7,PAUSED_TASK_DAYS:30,MEMORY_MAX_ENTRIES:500},Zt=class{static{c(this,"ArchiveStorage")}archive(t,e){let r=$(),s=f();return T.run(t,"INSERT INTO archives (id, entity_type, entity_id, entity_data, summary, archived_at, reason) VALUES (?, ?, ?, ?, ?, ?, ?)",r,e.entityType,e.entityId,JSON.stringify(e.entityData),e.summary??null,s,e.reason),r}archiveMany(t,e){if(e.length===0)return 0;let r=f();return T.transaction(t,s=>{let o=s.prepare("INSERT INTO archives (id, entity_type, entity_id, entity_data, summary, archived_at, reason) VALUES (?, ?, ?, ?, ?, ?, ?)");for(let i of e)o.run($(),i.entityType,i.entityId,JSON.stringify(i.entityData),i.summary??null,r,i.reason)}),e.length}getArchived(t,e,r=50){return e?T.query(t,"SELECT * FROM archives WHERE entity_type = ? ORDER BY archived_at DESC LIMIT ?",e,r):T.query(t,"SELECT * FROM archives ORDER BY archived_at DESC LIMIT ?",r)}getStats(t){let e=T.query(t,"SELECT entity_type, COUNT(*) as count FROM archives GROUP BY entity_type"),r={shipped:0,idea:0,queue_task:0,paused_task:0,memory_entry:0,total:0};for(let s of e){let o=s.entity_type;o in r&&(r[o]=s.count),r.total+=s.count}return r}restore(t,e){let r=T.get(t,"SELECT * FROM archives WHERE id = ?",e);return r?(T.run(t,"DELETE FROM archives WHERE id = ?",e),JSON.parse(r.entity_data)):null}pruneOldArchives(t,e){let r=new Date(Date.now()-e*24*60*60*1e3).toISOString(),s=this.getTotalCount(t);T.run(t,"DELETE FROM archives WHERE archived_at < ?",r);let o=this.getTotalCount(t);return s-o}getTotalCount(t){return T.get(t,"SELECT COUNT(*) as count FROM archives")?.count??0}},K=new Zt;U();var te=class{static{c(this,"SyncEventBus")}async publish(t){let e=b.getSyncPendingPath(t.projectId),r=await ut(e,[])??[],s=Array.isArray(r)?r:[];s.push(t),await M(e,s)}async getPending(t){let e=b.getSyncPendingPath(t),r=await ut(e,[])??[];return Array.isArray(r)?r:[]}async clearPending(t){let e=b.getSyncPendingPath(t);await M(e,[])}async updateLastSync(t){let e=b.getLastSyncPath(t),r={timestamp:f(),success:!0};await M(e,r)}async getLastSync(t){let e=b.getLastSyncPath(t);return await ut(e,null)}},Er=new te;Nt();var Q=class{static{c(this,"StorageManager")}filename;cache;constructor(t,e){this.filename=t,this.cache=new pt({ttl:5e3,maxSize:50})}getStoreKey(){return this.filename.replace(".json","")}async read(t){let e=this.cache.get(t);if(e!==null)return e;try{let r=T.getDoc(t,this.getStoreKey());if(r!==null)return this.cache.set(t,r),r}catch{}return this.getDefault()}async write(t,e){T.setDoc(t,this.getStoreKey(),e),this.cache.set(t,e)}async update(t,e){let r=await this.read(t),s=e(r);return await this.write(t,s),s}async publishEvent(t,e,r){let s={type:e,path:[this.filename.replace(".json","")],data:r,timestamp:f(),projectId:t};await Er.publish(s)}async publishEntityEvent(t,e,r,s){let o=`${e}.${r}`,i={...s,timestamp:f()};await this.publishEvent(t,o,i)}async exists(t){try{return T.hasDoc(t,this.getStoreKey())}catch{return!1}}clearCache(t){t?this.cache.delete(t):this.cache.clear()}getCacheStats(){return this.cache.stats()}};var ee=class extends Q{static{c(this,"StateStorage")}constructor(){super("state.json",hr)}getDefault(){return{currentTask:null,previousTask:null,pausedTasks:[],taskHistory:[],activeTasks:[],lastUpdated:""}}getEventType(t){return`state.${t}d`}validateTransition(t,e){let r=Qt.getCurrentState(t),s=Qt.canTransition(r,e);if(!s.valid)throw new Error(`${s.error}. ${s.suggestion||""}`.trim())}async getCurrentTask(t){return(await this.read(t)).currentTask}async getPausedTasks(t){let e=await this.read(t);return this.getPausedTasksFromState(e)}async startTask(t,e){let r=await this.read(t);this.validateTransition(r,"task");let s={...e,startedAt:f()};return await this.update(t,o=>({...o,currentTask:s,lastUpdated:f()})),await this.publishEvent(t,"task.started",{taskId:s.id,description:s.description,startedAt:s.startedAt,sessionId:s.sessionId}),s}async updateCurrentTask(t,e){let r=await this.read(t);if(!r.currentTask)return null;let s={...r.currentTask,...e};return await this.update(t,o=>({...o,currentTask:s,lastUpdated:f()})),s}async completeTask(t,e){let r=await this.read(t),s=r.currentTask;if(!s)return null;this.validateTransition(r,"done");let o=f(),i=this.createTaskHistoryEntry(s,o,e),a=this.getTaskHistoryFromState(r),u=[i,...a].slice(0,this.maxTaskHistory);return await this.update(t,p=>({...p,currentTask:null,previousTask:null,taskHistory:u,lastUpdated:o})),await this.publishEvent(t,"task.completed",{taskId:s.id,description:s.description,startedAt:s.startedAt,completedAt:o}),s}createTaskHistoryEntry(t,e,r){let s=(t.subtasks||[]).filter(a=>a.status==="completed"&&a.summary).map(a=>a.summary),o=s.length>0?s.map(a=>a.title).join(", "):"Task completed",i={taskId:t.id,title:t.parentDescription||t.description,classification:t.type||"improvement",startedAt:t.startedAt,completedAt:e,subtaskCount:t.subtasks?.length||0,subtaskSummaries:s,outcome:o,branchName:t.branch||"unknown",linearId:t.linearId,linearUuid:t.linearUuid,prUrl:t.prUrl};return r&&(i.feedback=r),t.tokensIn&&(i.tokensIn=t.tokensIn),t.tokensOut&&(i.tokensOut=t.tokensOut),i}maxPausedTasks=5;maxTaskHistory=20;stalenessThresholdDays=30;async pauseTask(t,e){let r=await this.read(t);if(!r.currentTask)return null;this.validateTransition(r,"pause");let s={...r.currentTask,status:"paused",pausedAt:f(),pauseReason:e},o=this.getPausedTasksFromState(r),i=[s,...o].slice(0,this.maxPausedTasks);return await this.update(t,a=>({...a,currentTask:null,previousTask:null,pausedTasks:i,lastUpdated:f()})),await this.publishEvent(t,"task.paused",{taskId:s.id,description:s.description,pausedAt:s.pausedAt,reason:e,pausedCount:i.length}),s}async resumeTask(t,e){let r=await this.read(t),s=this.getPausedTasksFromState(r);if(s.length===0)return null;this.validateTransition(r,"resume");let o=0;if(e&&(o=s.findIndex(y=>y.id===e),o===-1))return null;let i=s[o],a=s.filter((y,j)=>j!==o),{status:u,pausedAt:p,pauseReason:m,...d}=i,g={...d,startedAt:f(),sessionId:i.sessionId??$()};return await this.update(t,y=>({...y,currentTask:g,previousTask:null,pausedTasks:a,lastUpdated:f()})),await this.publishEvent(t,"task.resumed",{taskId:g.id,description:g.description,resumedAt:g.startedAt,remainingPaused:a.length}),g}getPausedTasksFromState(t){return Array.isArray(t.pausedTasks)&&t.pausedTasks.length>0?t.pausedTasks:t.previousTask?[t.previousTask]:[]}getTaskHistoryFromState(t){return t.taskHistory||[]}async getStalePausedTasks(t){let e=await this.read(t),r=this.getPausedTasksFromState(e),s=Date.now()-this.stalenessThresholdDays*24*60*60*1e3;return r.filter(o=>new Date(o.pausedAt).getTime()<s)}async archiveStalePausedTasks(t){let e=await this.read(t),r=this.getPausedTasksFromState(e),s=Date.now()-this.stalenessThresholdDays*24*60*60*1e3,o=r.filter(a=>new Date(a.pausedAt).getTime()<s),i=r.filter(a=>new Date(a.pausedAt).getTime()>=s);if(o.length===0)return[];K.archiveMany(t,o.map(a=>({entityType:"paused_task",entityId:a.id,entityData:a,summary:a.description,reason:"staleness"}))),await this.update(t,a=>({...a,pausedTasks:i,previousTask:null,lastUpdated:f()}));for(let a of o)await this.publishEvent(t,"task.archived",{taskId:a.id,description:a.description,pausedAt:a.pausedAt,reason:"staleness"});return o}async clearTask(t){await this.update(t,()=>({currentTask:null,previousTask:null,pausedTasks:[],activeTasks:[],lastUpdated:f()}))}async hasTask(t){let e=await this.read(t),r=this.getPausedTasksFromState(e);return e.currentTask!==null||r.length>0}async getPausedTask(t){let e=await this.read(t);return this.getPausedTasksFromState(e)[0]||null}async getAllPausedTasks(t){let e=await this.read(t);return this.getPausedTasksFromState(e)}async getTaskHistory(t){let e=await this.read(t);return this.getTaskHistoryFromState(e)}async getMostRecentTask(t){let e=await this.read(t);return this.getTaskHistoryFromState(e)[0]||null}async getTaskHistoryByType(t,e){let r=await this.read(t);return this.getTaskHistoryFromState(r).filter(o=>o.classification===e)}async getAggregatedFeedback(t){let r=(await this.getTaskHistory(t)).filter(g=>g.feedback),s=[],o=[],i=[],a=[];for(let g of r){let y=g.feedback;Array.isArray(y.stackConfirmed)&&s.push(...y.stackConfirmed),Array.isArray(y.patternsDiscovered)&&o.push(...y.patternsDiscovered),Array.isArray(y.agentAccuracy)&&i.push(...y.agentAccuracy),Array.isArray(y.issuesEncountered)&&a.push(...y.issuesEncountered)}let u=[...new Set(s)],p=[...new Set(o)],m=new Map;for(let g of a)m.set(g,(m.get(g)||0)+1);let d=[...m.entries()].filter(([g,y])=>y>=2).map(([g])=>g);return{stackConfirmed:u,patternsDiscovered:p,agentAccuracy:i,issuesEncountered:[...new Set(a)],knownGotchas:d}}async startTaskInWorkspace(t,e,r){let s={...e,workspaceId:r,startedAt:f()};return await this.update(t,o=>({...o,activeTasks:[...o.activeTasks||[],s],lastUpdated:f()})),await this.publishEvent(t,"task.started",{taskId:s.id,description:s.description,startedAt:s.startedAt,sessionId:s.sessionId,workspaceId:r}),s}async getCurrentTaskForWorkspace(t,e){return((await this.read(t)).activeTasks||[]).find(s=>s.workspaceId===e)??null}async completeTaskInWorkspace(t,e,r){let s=await this.read(t),i=(s.activeTasks||[]).find(d=>d.workspaceId===e);if(!i)return null;let a=f(),u=this.createTaskHistoryEntry(i,a,r),p=this.getTaskHistoryFromState(s),m=[u,...p].slice(0,this.maxTaskHistory);return await this.update(t,d=>({...d,activeTasks:(d.activeTasks||[]).filter(g=>g.workspaceId!==e),taskHistory:m,lastUpdated:a})),await this.publishEvent(t,"task.completed",{taskId:i.id,description:i.description,startedAt:i.startedAt,completedAt:a,workspaceId:e}),i}async getActiveTasks(t){return(await this.read(t)).activeTasks||[]}async getActiveTaskCount(t){return((await this.read(t)).activeTasks||[]).length}async updateWorkspaceTask(t,e,r){let o=(await this.read(t)).activeTasks||[],i=o.findIndex(u=>u.workspaceId===e);if(i===-1)return null;let a={...o[i],...r,workspaceId:e};return await this.update(t,u=>{let p=[...u.activeTasks||[]];return p[i]=a,{...u,activeTasks:p,lastUpdated:f()}}),a}async addTokens(t,e,r){let s=await this.read(t);if(!s.currentTask)return null;let o=(s.currentTask.tokensIn||0)+e,i=(s.currentTask.tokensOut||0)+r;return await this.update(t,a=>({...a,currentTask:{...a.currentTask,tokensIn:o,tokensOut:i},lastUpdated:f()})),{tokensIn:o,tokensOut:i}}async createSubtasks(t,e){let r=await this.read(t);if(!r.currentTask)return;let s=e.map((o,i)=>({...o,status:i===0?"in_progress":"pending",startedAt:i===0?f():void 0,dependsOn:o.dependsOn||[]}));await this.update(t,o=>({...o,currentTask:{...o.currentTask,subtasks:s,currentSubtaskIndex:0,subtaskProgress:{completed:0,total:s.length,percentage:0}},lastUpdated:f()})),await this.publishEvent(t,"subtasks.created",{taskId:r.currentTask.id,subtaskCount:s.length,subtasks:s.map(o=>({id:o.id,description:o.description,domain:o.domain}))})}async completeSubtask(t,e){let r=mr.safeParse(e);if(!r.success){let j=r.error.issues.map(at=>`${at.path.join(".")}: ${at.message}`);throw new Error(`Subtask completion requires handoff data:
503
- ${j.join(`
504
- `)}`)}let{output:s,summary:o}=r.data,i=await this.read(t);if(!i.currentTask?.subtasks)return null;let a=i.currentTask.currentSubtaskIndex||0,u=i.currentTask.subtasks[a];if(!u)return null;let p=[...i.currentTask.subtasks];p[a]={...u,status:"completed",completedAt:f(),output:s,summary:o};let m=p.filter(j=>j.status==="completed").length,d=p.length,g=Math.round(m/d*100),y=a+1;return y<p.length&&(p[y]={...p[y],status:"in_progress",startedAt:f()}),await this.update(t,j=>({...j,currentTask:{...j.currentTask,subtasks:p,currentSubtaskIndex:y<d?y:a,subtaskProgress:{completed:m,total:d,percentage:g}},lastUpdated:f()})),await this.publishEvent(t,"subtask.completed",{taskId:i.currentTask.id,subtaskId:u.id,description:u.description,output:s,handoff:o.outputForNextAgent,filesChanged:o.filesChanged.length,progress:{completed:m,total:d,percentage:g}}),y<d?p[y]:null}async getCurrentSubtask(t){let e=await this.read(t);if(!e.currentTask?.subtasks)return null;let r=e.currentTask.currentSubtaskIndex||0;return e.currentTask.subtasks[r]||null}async getNextSubtask(t){let e=await this.read(t);if(!e.currentTask?.subtasks)return null;let r=(e.currentTask.currentSubtaskIndex||0)+1;return e.currentTask.subtasks[r]||null}async getPreviousSubtask(t){let e=await this.read(t);if(!e.currentTask?.subtasks)return null;let r=(e.currentTask.currentSubtaskIndex||0)-1;return r<0?null:e.currentTask.subtasks[r]||null}async getPreviousHandoff(t){let e=await this.getPreviousSubtask(t);return e?.summary?.outputForNextAgent?{fromSubtask:e.description,outputForNextAgent:e.summary.outputForNextAgent,filesChanged:e.summary.filesChanged,whatWasDone:e.summary.whatWasDone}:null}async getSubtasks(t){return(await this.read(t)).currentTask?.subtasks||[]}async getSubtaskProgress(t){return(await this.read(t)).currentTask?.subtaskProgress||null}async hasSubtasks(t){return((await this.read(t)).currentTask?.subtasks?.length||0)>0}async areAllSubtasksComplete(t){let e=await this.read(t);return e.currentTask?.subtasks?e.currentTask.subtasks.every(r=>r.status==="completed"||r.status==="failed"||r.status==="skipped"):!0}async failSubtask(t,e){let r=await this.read(t);if(!r.currentTask?.subtasks)return null;let s=r.currentTask.currentSubtaskIndex||0,o=r.currentTask.subtasks[s];if(!o)return null;let i=[...r.currentTask.subtasks];i[s]={...o,status:"failed",completedAt:f(),output:`Failed: ${e}`};let a=s+1,u=i.length;a<u&&(i[a]={...i[a],status:"in_progress",startedAt:f()});let p=i.filter(d=>d.status==="completed"||d.status==="failed"||d.status==="skipped").length,m=Math.round(p/u*100);return await this.update(t,d=>({...d,currentTask:{...d.currentTask,subtasks:i,currentSubtaskIndex:a<u?a:s,subtaskProgress:{completed:p,total:u,percentage:m}},lastUpdated:f()})),await this.publishEvent(t,"subtask.failed",{taskId:r.currentTask.id,subtaskId:o.id,description:o.description,error:e}),a<u?i[a]:null}async skipSubtask(t,e){let r=await this.read(t);if(!r.currentTask?.subtasks)return null;let s=r.currentTask.currentSubtaskIndex||0,o=r.currentTask.subtasks[s];if(!o)return null;let i=[...r.currentTask.subtasks];i[s]={...o,status:"skipped",completedAt:f(),output:`Skipped: ${e}`,skipReason:e};let a=s+1,u=i.length;a<u&&(i[a]={...i[a],status:"in_progress",startedAt:f()});let p=i.filter(d=>d.status==="completed"||d.status==="failed"||d.status==="skipped").length,m=Math.round(p/u*100);return await this.update(t,d=>({...d,currentTask:{...d.currentTask,subtasks:i,currentSubtaskIndex:a<u?a:s,subtaskProgress:{completed:p,total:u,percentage:m}},lastUpdated:f()})),await this.publishEvent(t,"subtask.skipped",{taskId:r.currentTask.id,subtaskId:o.id,description:o.description,reason:e}),a<u?i[a]:null}async blockSubtask(t,e){let r=await this.read(t);if(!r.currentTask?.subtasks)return null;let s=r.currentTask.currentSubtaskIndex||0,o=r.currentTask.subtasks[s];if(!o)return null;let i=[...r.currentTask.subtasks];i[s]={...o,status:"blocked",output:`Blocked: ${e}`,blockReason:e};let a=s+1,u=i.length;return a<u&&(i[a]={...i[a],status:"in_progress",startedAt:f()}),await this.update(t,p=>({...p,currentTask:{...p.currentTask,subtasks:i,currentSubtaskIndex:a<u?a:s},lastUpdated:f()})),await this.publishEvent(t,"subtask.blocked",{taskId:r.currentTask.id,subtaskId:o.id,description:o.description,blocker:e}),a<u?i[a]:null}},Z=new ee;W();z();import nn from"node:fs/promises";import kt from"node:path";var on={frontend:["component","page","view","ui","layout","style","css","scss","sass","hook","context","store","redux","zustand","react","vue","svelte","angular","next","nuxt","app","client"],backend:["api","route","controller","service","middleware","handler","resolver","schema","model","entity","repository","server","socket","graphql","rest","trpc"],database:["migration","seed","schema","model","entity","repository","prisma","drizzle","sequelize","typeorm","mongoose","knex","sql","db"],auth:["auth","login","logout","session","token","jwt","oauth","passport","credential","permission","role","user","account"],testing:["test","spec","e2e","integration","unit","mock","fixture","stub","jest","vitest","cypress","playwright"],config:["config","env","setting","constant","option","tsconfig","eslint","prettier","vite","webpack","rollup"],infra:["docker","compose","kubernetes","k8s","ci","cd","github","gitlab","jenkins","terraform","ansible","deploy"],util:["util","helper","lib","common","shared","core","base","abstract"]},an=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".py",".go",".rs",".java",".kt",".swift",".rb",".php",".c",".cpp",".h",".hpp",".cs",".vue",".svelte"]),cn=new Set(["node_modules",".git","dist","build",".next",".nuxt",".output","coverage",".cache","__pycache__",".pytest_cache","vendor","target",".turbo",".vercel"]);async function kr(n,t,e={}){let r=Date.now(),s=e.maxFiles??30,o=e.minScore??.1,i=e.includeTests??!1,a=un(n),u=await ln(t),p=await pn(t),m=[];for(let g of u){if(!i&&mn(g))continue;let y=dn(g,a,p,e.historicalBoosts);y.score>=o&&m.push(y)}m.sort((g,y)=>y.score-g.score);let d=m.slice(0,s);return{files:d,metrics:{filesScanned:u.length,filesReturned:d.length,scanDuration:Date.now()-r}}}c(kr,"findRelevantFiles");function un(n){let t=n.toLowerCase().split(/[^a-z0-9]+/).filter(Boolean),e=new Set(["a","an","the","and","or","but","is","are","was","were","be","been","being","have","has","had","do","does","did","will","would","could","should","may","might","must","shall","can","need","to","of","in","for","on","with","at","by","from","as","into","through","during","before","after","above","below","between","under","again","further","then","once","here","there","when","where","why","how","all","each","few","more","most","other","some","such","no","nor","not","only","own","same","so","than","too","very","just","add","create","make","implement","fix","update","change","modify","remove","delete","new"]);return t.filter(r=>!e.has(r)&&r.length>2)}c(un,"extractKeywords");async function ln(n){let t=[];async function e(r,s=""){try{let o=await nn.readdir(r,{withFileTypes:!0});for(let i of o){let a=kt.join(r,i.name),u=kt.join(s,i.name);if(i.isDirectory()){if(cn.has(i.name)||i.name.startsWith("."))continue;await e(a,u)}else if(i.isFile()){let p=kt.extname(i.name).toLowerCase();an.has(p)&&t.push(u)}}}catch(o){N(o)}}return c(e,"walk"),await e(n),t}c(ln,"getAllCodeFiles");async function pn(n){let t=new Map;try{let{stdout:e}=await k(`git log -30 --pretty=format:"%H %ct" --name-only | awk '
501
+ `)}]}})),t.tool("prjct_cochange","Files that historically change together (Jaccard similarity from git history)",{projectPath:R.string().describe("Project directory path"),seedFiles:R.array(R.string()).describe("Seed files to find co-change partners for"),rebuild:R.boolean().optional().default(!1).describe("Force rebuild the co-change matrix"),maxResults:R.number().optional().default(10).describe("Max results (default 10)")},b("prjct_cochange",async e=>{let r=await v(e.projectPath),s=e.rebuild?null:jt(r);s||(s=await Ze(e.projectPath,r));let i=Mt(e.seedFiles,s).slice(0,e.maxResults);if(i.length===0)return{content:[{type:"text",text:"No co-change partners found."}]};let o=["## Co-Change Partners",`Seeds: ${e.seedFiles.join(", ")}`,`Commits analyzed: ${s.commitsAnalyzed}`,""];for(let a of i)o.push(`- ${a.path} (similarity: ${Math.round(a.score*100)}%)`);return{content:[{type:"text",text:o.join(`
502
+ `)}]}})),t.tool("prjct_related_context","Combined: import neighbors + co-change partners for seed files",{projectPath:R.string().describe("Project directory path"),seedFiles:R.array(R.string()).describe("Seed files to find related context for"),maxResults:R.number().optional().default(15).describe("Max results (default 15)")},b("prjct_related_context",async e=>{let r=await v(e.projectPath),s=Z(r),i=s?Ye(e.seedFiles,s):[],o=jt(r),a=o?Mt(e.seedFiles,o):[],u=new Map;for(let p of i)u.set(p.path,{importScore:p.score,cochangeScore:0});for(let p of a){let g=u.get(p.path);g?g.cochangeScore=p.score:u.set(p.path,{importScore:0,cochangeScore:p.score})}let d=Array.from(u.entries()).map(([p,g])=>({path:p,combined:g.importScore*.6+g.cochangeScore*.4,importScore:g.importScore,cochangeScore:g.cochangeScore})).sort((p,g)=>g.combined-p.combined).slice(0,e.maxResults);if(d.length===0)return{content:[{type:"text",text:"No related files found. Run `prjct sync` to build indexes."}]};let m=["## Related Context",`Seeds: ${e.seedFiles.join(", ")}`,""];for(let p of d){let g=[];p.importScore>0&&g.push(`import: ${p.importScore.toFixed(2)}`),p.cochangeScore>0&&g.push(`cochange: ${Math.round(p.cochangeScore*100)}%`),m.push(`- ${p.path} (${g.join(", ")})`)}return{content:[{type:"text",text:m.join(`
503
+ `)}]}}))}c(ar,"registerCodeIntelTools");import{z as W}from"zod";import Cs from"node:crypto";function F(){return Cs.randomUUID()}c(F,"generateUUID");Rt();import{z as l}from"zod";var Is=l.enum(["low","medium","high","critical"]),ht=l.enum(["feature","bug","improvement","chore"]),Ds=l.enum(["active","backlog","previously_active"]),Ls=l.enum(["pending","in_progress","completed","blocked","paused","failed","skipped"]),qt=l.object({title:l.string(),description:l.string(),filesChanged:l.array(l.object({path:l.string(),action:l.enum(["created","modified","deleted"])})),whatWasDone:l.array(l.string()).min(1),outputForNextAgent:l.string().min(1),notes:l.string().optional()}),ur=l.object({output:l.string().min(1,"Subtask output is required"),summary:qt}),lr=l.object({id:l.string(),description:l.string(),domain:l.string(),agent:l.string(),status:Ls,dependsOn:l.array(l.string()),startedAt:l.string().optional(),completedAt:l.string().optional(),output:l.string().optional(),summary:qt.optional(),skipReason:l.string().optional(),blockReason:l.string().optional(),estimatedPoints:l.number().optional(),estimatedMinutes:l.number().optional()}),dr=l.object({completed:l.number(),total:l.number(),percentage:l.number()}),pr=l.object({id:l.string(),description:l.string(),type:ht.optional(),startedAt:l.string(),sessionId:l.string(),featureId:l.string().optional(),subtasks:l.array(lr).optional(),currentSubtaskIndex:l.number().optional(),subtaskProgress:dr.optional(),linearId:l.string().optional(),linearUuid:l.string().optional(),estimatedPoints:l.number().optional(),estimatedMinutes:l.number().optional(),modelMetadata:xt.optional(),tokensIn:l.number().optional(),tokensOut:l.number().optional(),parentDescription:l.string().optional(),branch:l.string().optional(),prUrl:l.string().optional()}),cr=l.object({id:l.string(),description:l.string(),status:l.literal("paused"),startedAt:l.string(),pausedAt:l.string(),pauseReason:l.string().optional(),type:ht.optional(),sessionId:l.string().optional(),featureId:l.string().optional(),subtasks:l.array(lr).optional(),currentSubtaskIndex:l.number().optional(),subtaskProgress:dr.optional(),linearId:l.string().optional(),linearUuid:l.string().optional(),estimatedPoints:l.number().optional(),estimatedMinutes:l.number().optional(),modelMetadata:xt.optional(),tokensIn:l.number().optional(),tokensOut:l.number().optional()}),Os=l.object({stackConfirmed:l.array(l.string()).optional(),patternsDiscovered:l.array(l.string()).optional(),agentAccuracy:l.array(l.object({agent:l.string(),rating:l.enum(["helpful","neutral","inaccurate"]),note:l.string().optional()})).optional(),issuesEncountered:l.array(l.string()).optional()}),Ms=l.object({taskId:l.string(),title:l.string(),classification:ht,startedAt:l.string(),completedAt:l.string(),subtaskCount:l.number(),subtaskSummaries:l.array(qt),outcome:l.string(),branchName:l.string(),linearId:l.string().optional(),linearUuid:l.string().optional(),prUrl:l.string().optional(),feedback:Os.optional(),tokensIn:l.number().optional(),tokensOut:l.number().optional()}),js=pr.extend({workspaceId:l.string(),worktreePath:l.string().optional(),agentSessionId:l.string().optional(),jiraId:l.string().optional(),jiraUuid:l.string().optional(),dispatchedFrom:l.string().optional()}),mr=l.object({currentTask:pr.nullable(),previousTask:cr.nullable().optional(),pausedTasks:l.array(cr).optional(),taskHistory:l.array(Ms).optional(),activeTasks:l.array(js).optional(),lastUpdated:l.string()}),Fs=l.object({id:l.string(),description:l.string(),body:l.string().optional(),priority:Is,type:ht,featureId:l.string().optional(),originFeature:l.string().optional(),completed:l.boolean(),completedAt:l.string().optional(),createdAt:l.string(),section:Ds,agent:l.string().optional(),groupName:l.string().optional(),groupId:l.string().optional()}),gr=l.object({tasks:l.array(Fs),lastUpdated:l.string()});var et={idle:{transitions:["task"],prompt:"prjct task <description> Start working",description:"No active task"},working:{transitions:["done","pause"],prompt:"prjct status done Complete task | prjct status paused Switch context",description:"Task in progress"},paused:{transitions:["resume","task","ship"],prompt:"prjct status active Continue | prjct task <new> Start different | prjct ship Ship directly",description:"Task paused"},completed:{transitions:["ship","task","pause","reopen"],prompt:"prjct ship Ship it | prjct task <next> Start next | prjct status active Reopen",description:"Task completed"},shipped:{transitions:["task"],prompt:"prjct task <description> Start new task",description:"Feature shipped"}},Yt=class{static{c(this,"WorkflowStateMachine")}getCurrentState(t,e){let r=null;if(e&&t?.activeTasks?.length&&(r=t.activeTasks.find(i=>i.workspaceId===e)),r||(r=t?.currentTask),!r)return(t?.pausedTasks?.length||0)>0||t?.previousTask?.status==="paused"?"paused":"idle";switch((typeof r.status=="string"?r.status:"").toLowerCase()){case"in_progress":case"working":return"working";case"paused":return"paused";case"completed":case"done":return"completed";case"shipped":return"shipped";default:return r?"working":"idle"}}canTransition(t,e){if(et[t].transitions.includes(e))return{valid:!0};let s=this.formatNextSteps(t).join(" | ");return{valid:!1,error:`Cannot transition to '${e}' from '${t}' state`,suggestion:`Valid next steps: ${s}`}}getNextState(t,e){switch(e){case"task":return"working";case"done":return"completed";case"pause":return"paused";case"resume":return"working";case"ship":return"shipped";case"reopen":return"working";default:return t}}getStateInfo(t){return et[t]}getPrompt(t){return et[t].prompt}getValidCommands(t){return et[t].transitions}formatNextSteps(t){return et[t].transitions.map(r=>{switch(r){case"task":return"prjct task <desc> Start new task";case"done":return"prjct status done Complete current task";case"pause":return"prjct status paused Pause and switch context";case"resume":return"prjct status active Continue paused task";case"ship":return"prjct ship Ship the feature";case"reopen":return"prjct status active Reopen completed task";default:return`prjct ${r}`}})}},zt=new Yt;var rt={SHIPPED_RETENTION_DAYS:90,IDEA_DORMANT_DAYS:180,QUEUE_COMPLETED_DAYS:7,PAUSED_TASK_DAYS:30,MEMORY_MAX_ENTRIES:500},Jt=class{static{c(this,"ArchiveStorage")}archive(t,e){let r=F(),s=f();return y.run(t,"INSERT INTO archives (id, entity_type, entity_id, entity_data, summary, archived_at, reason) VALUES (?, ?, ?, ?, ?, ?, ?)",r,e.entityType,e.entityId,JSON.stringify(e.entityData),e.summary??null,s,e.reason),r}archiveMany(t,e){if(e.length===0)return 0;let r=f();return y.transaction(t,s=>{let i=s.prepare("INSERT INTO archives (id, entity_type, entity_id, entity_data, summary, archived_at, reason) VALUES (?, ?, ?, ?, ?, ?, ?)");for(let o of e)i.run(F(),o.entityType,o.entityId,JSON.stringify(o.entityData),o.summary??null,r,o.reason)}),e.length}getArchived(t,e,r=50){return e?y.query(t,"SELECT * FROM archives WHERE entity_type = ? ORDER BY archived_at DESC LIMIT ?",e,r):y.query(t,"SELECT * FROM archives ORDER BY archived_at DESC LIMIT ?",r)}getStats(t){let e=y.query(t,"SELECT entity_type, COUNT(*) as count FROM archives GROUP BY entity_type"),r={shipped:0,idea:0,queue_task:0,paused_task:0,memory_entry:0,total:0};for(let s of e){let i=s.entity_type;i in r&&(r[i]=s.count),r.total+=s.count}return r}restore(t,e){let r=y.get(t,"SELECT * FROM archives WHERE id = ?",e);return r?(y.run(t,"DELETE FROM archives WHERE id = ?",e),JSON.parse(r.entity_data)):null}pruneOldArchives(t,e){let r=new Date(Date.now()-e*24*60*60*1e3).toISOString(),s=this.getTotalCount(t);y.run(t,"DELETE FROM archives WHERE archived_at < ?",r);let i=this.getTotalCount(t);return s-i}getTotalCount(t){return y.get(t,"SELECT COUNT(*) as count FROM archives")?.count??0}},Y=new Jt;M();var Kt=class{static{c(this,"SyncEventBus")}async publish(t){let e=w.getSyncPendingPath(t.projectId),r=await ot(e,[])??[],s=Array.isArray(r)?r:[];s.push(t),await L(e,s)}async getPending(t){let e=w.getSyncPendingPath(t),r=await ot(e,[])??[];return Array.isArray(r)?r:[]}async clearPending(t){let e=w.getSyncPendingPath(t);await L(e,[])}async updateLastSync(t){let e=w.getLastSyncPath(t),r={timestamp:f(),success:!0};await L(e,r)}async getLastSync(t){let e=w.getLastSyncPath(t);return await ot(e,null)}},fr=new Kt;Pt();var z=class{static{c(this,"StorageManager")}filename;cache;constructor(t,e){this.filename=t,this.cache=new at({ttl:5e3,maxSize:50})}getStoreKey(){return this.filename.replace(".json","")}async read(t){let e=this.cache.get(t);if(e!==null)return e;try{let r=y.getDoc(t,this.getStoreKey());if(r!==null)return this.cache.set(t,r),r}catch{}return this.getDefault()}async write(t,e){y.setDoc(t,this.getStoreKey(),e),this.cache.set(t,e)}async update(t,e){let r=await this.read(t),s=e(r);return await this.write(t,s),s}async publishEvent(t,e,r){let s={type:e,path:[this.filename.replace(".json","")],data:r,timestamp:f(),projectId:t};await fr.publish(s)}async publishEntityEvent(t,e,r,s){let i=`${e}.${r}`,o={...s,timestamp:f()};await this.publishEvent(t,i,o)}async exists(t){try{return y.hasDoc(t,this.getStoreKey())}catch{return!1}}clearCache(t){t?this.cache.delete(t):this.cache.clear()}getCacheStats(){return this.cache.stats()}};var Vt=class extends z{static{c(this,"StateStorage")}constructor(){super("state.json",mr)}getDefault(){return{currentTask:null,previousTask:null,pausedTasks:[],taskHistory:[],activeTasks:[],lastUpdated:""}}getEventType(t){return`state.${t}d`}validateTransition(t,e){let r=zt.getCurrentState(t),s=zt.canTransition(r,e);if(!s.valid)throw new Error(`${s.error}. ${s.suggestion||""}`.trim())}async getCurrentTask(t){return(await this.read(t)).currentTask}async getPausedTasks(t){let e=await this.read(t);return this.getPausedTasksFromState(e)}async startTask(t,e){let r=await this.read(t);this.validateTransition(r,"task");let s={...e,startedAt:f()};return await this.update(t,i=>({...i,currentTask:s,lastUpdated:f()})),await this.publishEvent(t,"task.started",{taskId:s.id,description:s.description,startedAt:s.startedAt,sessionId:s.sessionId}),s}async updateCurrentTask(t,e){let r=await this.read(t);if(!r.currentTask)return null;let s={...r.currentTask,...e};return await this.update(t,i=>({...i,currentTask:s,lastUpdated:f()})),s}async completeTask(t,e){let r=await this.read(t),s=r.currentTask;if(!s)return null;this.validateTransition(r,"done");let i=f(),o=this.createTaskHistoryEntry(s,i,e),a=this.getTaskHistoryFromState(r),u=[o,...a].slice(0,this.maxTaskHistory);return await this.update(t,d=>({...d,currentTask:null,previousTask:null,taskHistory:u,lastUpdated:i})),await this.publishEvent(t,"task.completed",{taskId:s.id,description:s.description,startedAt:s.startedAt,completedAt:i}),s}createTaskHistoryEntry(t,e,r){let s=(t.subtasks||[]).filter(a=>a.status==="completed"&&a.summary).map(a=>a.summary),i=s.length>0?s.map(a=>a.title).join(", "):"Task completed",o={taskId:t.id,title:t.parentDescription||t.description,classification:t.type||"improvement",startedAt:t.startedAt,completedAt:e,subtaskCount:t.subtasks?.length||0,subtaskSummaries:s,outcome:i,branchName:t.branch||"unknown",linearId:t.linearId,linearUuid:t.linearUuid,prUrl:t.prUrl};return r&&(o.feedback=r),t.tokensIn&&(o.tokensIn=t.tokensIn),t.tokensOut&&(o.tokensOut=t.tokensOut),o}maxPausedTasks=5;maxTaskHistory=20;stalenessThresholdDays=30;async pauseTask(t,e){let r=await this.read(t);if(!r.currentTask)return null;this.validateTransition(r,"pause");let s={...r.currentTask,status:"paused",pausedAt:f(),pauseReason:e},i=this.getPausedTasksFromState(r),o=[s,...i].slice(0,this.maxPausedTasks);return await this.update(t,a=>({...a,currentTask:null,previousTask:null,pausedTasks:o,lastUpdated:f()})),await this.publishEvent(t,"task.paused",{taskId:s.id,description:s.description,pausedAt:s.pausedAt,reason:e,pausedCount:o.length}),s}async resumeTask(t,e){let r=await this.read(t),s=this.getPausedTasksFromState(r);if(s.length===0)return null;this.validateTransition(r,"resume");let i=0;if(e&&(i=s.findIndex(T=>T.id===e),i===-1))return null;let o=s[i],a=s.filter((T,D)=>D!==i),{status:u,pausedAt:d,pauseReason:m,...p}=o,g={...p,startedAt:f(),sessionId:o.sessionId??F()};return await this.update(t,T=>({...T,currentTask:g,previousTask:null,pausedTasks:a,lastUpdated:f()})),await this.publishEvent(t,"task.resumed",{taskId:g.id,description:g.description,resumedAt:g.startedAt,remainingPaused:a.length}),g}getPausedTasksFromState(t){return Array.isArray(t.pausedTasks)&&t.pausedTasks.length>0?t.pausedTasks:t.previousTask?[t.previousTask]:[]}getTaskHistoryFromState(t){return t.taskHistory||[]}async getStalePausedTasks(t){let e=await this.read(t),r=this.getPausedTasksFromState(e),s=Date.now()-this.stalenessThresholdDays*24*60*60*1e3;return r.filter(i=>new Date(i.pausedAt).getTime()<s)}async archiveStalePausedTasks(t){let e=await this.read(t),r=this.getPausedTasksFromState(e),s=Date.now()-this.stalenessThresholdDays*24*60*60*1e3,i=r.filter(a=>new Date(a.pausedAt).getTime()<s),o=r.filter(a=>new Date(a.pausedAt).getTime()>=s);if(i.length===0)return[];Y.archiveMany(t,i.map(a=>({entityType:"paused_task",entityId:a.id,entityData:a,summary:a.description,reason:"staleness"}))),await this.update(t,a=>({...a,pausedTasks:o,previousTask:null,lastUpdated:f()}));for(let a of i)await this.publishEvent(t,"task.archived",{taskId:a.id,description:a.description,pausedAt:a.pausedAt,reason:"staleness"});return i}async clearTask(t){await this.update(t,()=>({currentTask:null,previousTask:null,pausedTasks:[],activeTasks:[],lastUpdated:f()}))}async hasTask(t){let e=await this.read(t),r=this.getPausedTasksFromState(e);return e.currentTask!==null||r.length>0}async getPausedTask(t){let e=await this.read(t);return this.getPausedTasksFromState(e)[0]||null}async getAllPausedTasks(t){let e=await this.read(t);return this.getPausedTasksFromState(e)}async getTaskHistory(t){let e=await this.read(t);return this.getTaskHistoryFromState(e)}async getMostRecentTask(t){let e=await this.read(t);return this.getTaskHistoryFromState(e)[0]||null}async getTaskHistoryByType(t,e){let r=await this.read(t);return this.getTaskHistoryFromState(r).filter(i=>i.classification===e)}async getAggregatedFeedback(t){let r=(await this.getTaskHistory(t)).filter(g=>g.feedback),s=[],i=[],o=[],a=[];for(let g of r){let T=g.feedback;Array.isArray(T.stackConfirmed)&&s.push(...T.stackConfirmed),Array.isArray(T.patternsDiscovered)&&i.push(...T.patternsDiscovered),Array.isArray(T.agentAccuracy)&&o.push(...T.agentAccuracy),Array.isArray(T.issuesEncountered)&&a.push(...T.issuesEncountered)}let u=[...new Set(s)],d=[...new Set(i)],m=new Map;for(let g of a)m.set(g,(m.get(g)||0)+1);let p=[...m.entries()].filter(([g,T])=>T>=2).map(([g])=>g);return{stackConfirmed:u,patternsDiscovered:d,agentAccuracy:o,issuesEncountered:[...new Set(a)],knownGotchas:p}}async startTaskInWorkspace(t,e,r){let s={...e,workspaceId:r,startedAt:f()};return await this.update(t,i=>({...i,activeTasks:[...i.activeTasks||[],s],lastUpdated:f()})),await this.publishEvent(t,"task.started",{taskId:s.id,description:s.description,startedAt:s.startedAt,sessionId:s.sessionId,workspaceId:r}),s}async getCurrentTaskForWorkspace(t,e){return((await this.read(t)).activeTasks||[]).find(s=>s.workspaceId===e)??null}async completeTaskInWorkspace(t,e,r){let s=await this.read(t),o=(s.activeTasks||[]).find(p=>p.workspaceId===e);if(!o)return null;let a=f(),u=this.createTaskHistoryEntry(o,a,r),d=this.getTaskHistoryFromState(s),m=[u,...d].slice(0,this.maxTaskHistory);return await this.update(t,p=>({...p,activeTasks:(p.activeTasks||[]).filter(g=>g.workspaceId!==e),taskHistory:m,lastUpdated:a})),await this.publishEvent(t,"task.completed",{taskId:o.id,description:o.description,startedAt:o.startedAt,completedAt:a,workspaceId:e}),o}async getActiveTasks(t){return(await this.read(t)).activeTasks||[]}async getActiveTaskCount(t){return((await this.read(t)).activeTasks||[]).length}async updateWorkspaceTask(t,e,r){let i=(await this.read(t)).activeTasks||[],o=i.findIndex(u=>u.workspaceId===e);if(o===-1)return null;let a={...i[o],...r,workspaceId:e};return await this.update(t,u=>{let d=[...u.activeTasks||[]];return d[o]=a,{...u,activeTasks:d,lastUpdated:f()}}),a}async addTokens(t,e,r){let s=await this.read(t);if(!s.currentTask)return null;let i=(s.currentTask.tokensIn||0)+e,o=(s.currentTask.tokensOut||0)+r;return await this.update(t,a=>({...a,currentTask:{...a.currentTask,tokensIn:i,tokensOut:o},lastUpdated:f()})),{tokensIn:i,tokensOut:o}}async createSubtasks(t,e){let r=await this.read(t);if(!r.currentTask)return;let s=e.map((i,o)=>({...i,status:o===0?"in_progress":"pending",startedAt:o===0?f():void 0,dependsOn:i.dependsOn||[]}));await this.update(t,i=>({...i,currentTask:{...i.currentTask,subtasks:s,currentSubtaskIndex:0,subtaskProgress:{completed:0,total:s.length,percentage:0}},lastUpdated:f()})),await this.publishEvent(t,"subtasks.created",{taskId:r.currentTask.id,subtaskCount:s.length,subtasks:s.map(i=>({id:i.id,description:i.description,domain:i.domain}))})}async completeSubtask(t,e){let r=ur.safeParse(e);if(!r.success){let D=r.error.issues.map(nt=>`${nt.path.join(".")}: ${nt.message}`);throw new Error(`Subtask completion requires handoff data:
504
+ ${D.join(`
505
+ `)}`)}let{output:s,summary:i}=r.data,o=await this.read(t);if(!o.currentTask?.subtasks)return null;let a=o.currentTask.currentSubtaskIndex||0,u=o.currentTask.subtasks[a];if(!u)return null;let d=[...o.currentTask.subtasks];d[a]={...u,status:"completed",completedAt:f(),output:s,summary:i};let m=d.filter(D=>D.status==="completed").length,p=d.length,g=Math.round(m/p*100),T=a+1;return T<d.length&&(d[T]={...d[T],status:"in_progress",startedAt:f()}),await this.update(t,D=>({...D,currentTask:{...D.currentTask,subtasks:d,currentSubtaskIndex:T<p?T:a,subtaskProgress:{completed:m,total:p,percentage:g}},lastUpdated:f()})),await this.publishEvent(t,"subtask.completed",{taskId:o.currentTask.id,subtaskId:u.id,description:u.description,output:s,handoff:i.outputForNextAgent,filesChanged:i.filesChanged.length,progress:{completed:m,total:p,percentage:g}}),T<p?d[T]:null}async getCurrentSubtask(t){let e=await this.read(t);if(!e.currentTask?.subtasks)return null;let r=e.currentTask.currentSubtaskIndex||0;return e.currentTask.subtasks[r]||null}async getNextSubtask(t){let e=await this.read(t);if(!e.currentTask?.subtasks)return null;let r=(e.currentTask.currentSubtaskIndex||0)+1;return e.currentTask.subtasks[r]||null}async getPreviousSubtask(t){let e=await this.read(t);if(!e.currentTask?.subtasks)return null;let r=(e.currentTask.currentSubtaskIndex||0)-1;return r<0?null:e.currentTask.subtasks[r]||null}async getPreviousHandoff(t){let e=await this.getPreviousSubtask(t);return e?.summary?.outputForNextAgent?{fromSubtask:e.description,outputForNextAgent:e.summary.outputForNextAgent,filesChanged:e.summary.filesChanged,whatWasDone:e.summary.whatWasDone}:null}async getSubtasks(t){return(await this.read(t)).currentTask?.subtasks||[]}async getSubtaskProgress(t){return(await this.read(t)).currentTask?.subtaskProgress||null}async hasSubtasks(t){return((await this.read(t)).currentTask?.subtasks?.length||0)>0}async areAllSubtasksComplete(t){let e=await this.read(t);return e.currentTask?.subtasks?e.currentTask.subtasks.every(r=>r.status==="completed"||r.status==="failed"||r.status==="skipped"):!0}async failSubtask(t,e){let r=await this.read(t);if(!r.currentTask?.subtasks)return null;let s=r.currentTask.currentSubtaskIndex||0,i=r.currentTask.subtasks[s];if(!i)return null;let o=[...r.currentTask.subtasks];o[s]={...i,status:"failed",completedAt:f(),output:`Failed: ${e}`};let a=s+1,u=o.length;a<u&&(o[a]={...o[a],status:"in_progress",startedAt:f()});let d=o.filter(p=>p.status==="completed"||p.status==="failed"||p.status==="skipped").length,m=Math.round(d/u*100);return await this.update(t,p=>({...p,currentTask:{...p.currentTask,subtasks:o,currentSubtaskIndex:a<u?a:s,subtaskProgress:{completed:d,total:u,percentage:m}},lastUpdated:f()})),await this.publishEvent(t,"subtask.failed",{taskId:r.currentTask.id,subtaskId:i.id,description:i.description,error:e}),a<u?o[a]:null}async skipSubtask(t,e){let r=await this.read(t);if(!r.currentTask?.subtasks)return null;let s=r.currentTask.currentSubtaskIndex||0,i=r.currentTask.subtasks[s];if(!i)return null;let o=[...r.currentTask.subtasks];o[s]={...i,status:"skipped",completedAt:f(),output:`Skipped: ${e}`,skipReason:e};let a=s+1,u=o.length;a<u&&(o[a]={...o[a],status:"in_progress",startedAt:f()});let d=o.filter(p=>p.status==="completed"||p.status==="failed"||p.status==="skipped").length,m=Math.round(d/u*100);return await this.update(t,p=>({...p,currentTask:{...p.currentTask,subtasks:o,currentSubtaskIndex:a<u?a:s,subtaskProgress:{completed:d,total:u,percentage:m}},lastUpdated:f()})),await this.publishEvent(t,"subtask.skipped",{taskId:r.currentTask.id,subtaskId:i.id,description:i.description,reason:e}),a<u?o[a]:null}async blockSubtask(t,e){let r=await this.read(t);if(!r.currentTask?.subtasks)return null;let s=r.currentTask.currentSubtaskIndex||0,i=r.currentTask.subtasks[s];if(!i)return null;let o=[...r.currentTask.subtasks];o[s]={...i,status:"blocked",output:`Blocked: ${e}`,blockReason:e};let a=s+1,u=o.length;return a<u&&(o[a]={...o[a],status:"in_progress",startedAt:f()}),await this.update(t,d=>({...d,currentTask:{...d.currentTask,subtasks:o,currentSubtaskIndex:a<u?a:s},lastUpdated:f()})),await this.publishEvent(t,"subtask.blocked",{taskId:r.currentTask.id,subtaskId:i.id,description:i.description,blocker:e}),a<u?o[a]:null}},J=new Vt;U();B();import Us from"node:fs/promises";import Tt from"node:path";var Xs={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"]},$s=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".py",".go",".rs",".java",".kt",".swift",".rb",".php",".c",".cpp",".h",".hpp",".cs",".vue",".svelte"]),Ws=new Set(["node_modules",".git","dist","build",".next",".nuxt",".output","coverage",".cache","__pycache__",".pytest_cache","vendor","target",".turbo",".vercel"]);async function hr(n,t,e={}){let r=Date.now(),s=e.maxFiles??30,i=e.minScore??.1,o=e.includeTests??!1,a=Gs(n),u=await Bs(t),d=await Hs(t),m=[];for(let g of u){if(!o&&Ys(g))continue;let T=qs(g,a,d,e.historicalBoosts);T.score>=i&&m.push(T)}m.sort((g,T)=>T.score-g.score);let p=m.slice(0,s);return{files:p,metrics:{filesScanned:u.length,filesReturned:p.length,scanDuration:Date.now()-r}}}c(hr,"findRelevantFiles");function Gs(n){let t=n.toLowerCase().split(/[^a-z0-9]+/).filter(Boolean),e=new Set(["a","an","the","and","or","but","is","are","was","were","be","been","being","have","has","had","do","does","did","will","would","could","should","may","might","must","shall","can","need","to","of","in","for","on","with","at","by","from","as","into","through","during","before","after","above","below","between","under","again","further","then","once","here","there","when","where","why","how","all","each","few","more","most","other","some","such","no","nor","not","only","own","same","so","than","too","very","just","add","create","make","implement","fix","update","change","modify","remove","delete","new"]);return t.filter(r=>!e.has(r)&&r.length>2)}c(Gs,"extractKeywords");async function Bs(n){let t=[];async function e(r,s=""){try{let i=await Us.readdir(r,{withFileTypes:!0});for(let o of i){let a=Tt.join(r,o.name),u=Tt.join(s,o.name);if(o.isDirectory()){if(Ws.has(o.name)||o.name.startsWith("."))continue;await e(a,u)}else if(o.isFile()){let d=Tt.extname(o.name).toLowerCase();$s.has(d)&&t.push(u)}}}catch(i){P(i)}}return c(e,"walk"),await e(n),t}c(Bs,"getAllCodeFiles");async function Hs(n){let t=new Map;try{let{stdout:e}=await k(`git log -30 --pretty=format:"%H %ct" --name-only | awk '
505
506
  /^[a-f0-9]{40}/ { commit=$1; timestamp=$2; next }
506
507
  NF { files[$0]++; if (!lastmod[$0]) lastmod[$0]=timestamp }
507
508
  END { for (f in files) print files[f], lastmod[f], f }
508
509
  '`,{cwd:n,maxBuffer:10485760}),r=Math.floor(Date.now()/1e3),s=e.trim().split(`
509
- `).filter(Boolean);for(let o of s){let i=o.match(/^(\d+)\s+(\d+)\s+(.+)$/);if(i){let a=parseInt(i[1],10),u=parseInt(i[2],10),p=i[3],m=Math.floor((r-u)/86400);t.set(p,{commits:a,daysAgo:m})}}}catch{}return t}c(pn,"getGitRecency");function dn(n,t,e,r){let s=[],o=0,i=0,a=0,u=0,p=0,m=n.toLowerCase(),d=m.split("/").join(" ").split(/[^a-z0-9]+/);for(let R of t){m.includes(R)&&(o+=.3,s.push(`keyword:${R}`));for(let et of d)if(et.includes(R)||R.includes(et)){o+=.15;break}}o=Math.min(1,o);for(let[R,et]of Object.entries(on))for(let Gr of et)if(m.includes(Gr)&&t.some(xt=>et.includes(xt)||xt.includes(R)||R.includes(xt))){i+=.4,s.push(`domain:${R}`);break}i=Math.min(1,i);let g=e.get(n);g&&(g.daysAgo<=1?(a=1,s.push("recent:1d")):g.daysAgo<=3?(a=.8,s.push("recent:3d")):g.daysAgo<=7?(a=.6,s.push("recent:1w")):g.daysAgo<=30&&(a=.3,s.push("recent:1m")),g.commits>=5&&(a=Math.min(1,a+.2)));let y=kt.basename(n).toLowerCase();if((y.includes("index")||y.includes("main")||y.includes("app")||y.includes("entry"))&&(u=.5,s.push("import:0")),(m.includes("/core/")||m.includes("/shared/")||m.includes("/lib/"))&&(u=Math.max(u,.3),s.some(R=>R.startsWith("import:"))||s.push("import:1")),r){let R=r.get(n);R!==void 0&&(p=(R+1)/2,R>0?s.push("history:boosted"):R<0&&s.push("history:penalized"))}let at=r&&r.size>0?o*.54+i*.18+a*.13+u*.05+p*.1:o*.6+i*.2+a*.15+u*.05;return{path:n,score:Math.min(1,at),reasons:[...new Set(s)]}}c(dn,"scoreFile");function mn(n){let t=n.toLowerCase();return t.includes(".test.")||t.includes(".spec.")||t.includes("__tests__")||t.includes("__mocks__")||t.includes("/tests/")||t.includes("/test/")||t.endsWith("_test.go")||t.endsWith("_test.py")}c(mn,"isTestFile");W();import Tn from"node:fs/promises";import tt from"node:path";var fn={"claude-opus-4.5":{input:.005,output:.025},"claude-sonnet-4.5":{input:.003,output:.015},"claude-haiku-4.5":{input:.001,output:.005},"claude-opus-4":{input:.015,output:.075},"claude-opus-4-6":{input:.015,output:.075},"gpt-4o":{input:.0025,output:.01},"gpt-4-turbo":{input:.01,output:.03},"gpt-4o-mini":{input:15e-5,output:6e-4},"gemini-1.5-pro":{input:.00125,output:.005},"gemini-1.5-flash":{input:75e-6,output:3e-4}},hn="claude-sonnet-4.5";function re(n){return!n||n.length===0?0:Math.ceil(n.length/4)}c(re,"countTokens");var br=["claude-sonnet-4.5","claude-opus-4.5","claude-opus-4-6","gpt-4o","gemini-1.5-pro"];function wr(n,t){let e=fn[t],r=n/1e3*e.input,s=n/1e3*e.output*.3;return{inputSaved:r,outputPotential:s,total:r+s}}c(wr,"calculateModelCost");function yn(n){return n<.001?"<$0.01":n<.01?`$${n.toFixed(3)}`:`$${n.toFixed(2)}`}c(yn,"formatCostSaved");function Sr(n,t){let e=re(n),r=re(t),s=Math.max(0,e-r),o=e>0?(e-r)/e:0,i=wr(s,hn),a=br.map(u=>({model:u,...wr(s,u)}));return{tokens:{original:e,filtered:r,saved:s},compression:Math.max(0,Math.min(1,o)),cost:{saved:i.total,formatted:yn(i.total),byModel:a}}}c(Sr,"measureCompression");function wt(n){let t=re(n);return{tokens:{original:t,filtered:t,saved:0},compression:0,cost:{saved:0,formatted:"$0.00",byModel:br.map(e=>({model:e,inputSaved:0,outputPotential:0,total:0}))}}}c(wt,"noCompression");var En={".ts":"typescript",".tsx":"typescript",".js":"javascript",".jsx":"javascript",".mjs":"javascript",".cjs":"javascript",".py":"python",".go":"go",".rs":"rust",".java":"java",".cs":"csharp",".php":"php",".rb":"ruby"},xr=[{type:"function",pattern:/^export\s+(?:async\s+)?function\s+(\w+)\s*(<[^>]*>)?\s*\(([^)]*)\)\s*(?::\s*([^{;]+))?/gm,nameIndex:1,exported:!0},{type:"function",pattern:/^export\s+const\s+(\w+)\s*(?::\s*[^=]+)?\s*=\s*(?:async\s+)?\([^)]*\)\s*(?::\s*[^=]+)?\s*=>/gm,nameIndex:1,exported:!0},{type:"function",pattern:/^(?:async\s+)?function\s+(\w+)\s*(<[^>]*>)?\s*\(([^)]*)\)\s*(?::\s*([^{;]+))?/gm,nameIndex:1},{type:"function",pattern:/^const\s+(\w+)\s*(?::\s*[^=]+)?\s*=\s*(?:async\s+)?\([^)]*\)\s*(?::\s*[^=]+)?\s*=>/gm,nameIndex:1},{type:"interface",pattern:/^export\s+interface\s+(\w+)(?:<[^>]+>)?\s*(?:extends\s+[^{]+)?\s*\{/gm,nameIndex:1,exported:!0},{type:"interface",pattern:/^interface\s+(\w+)(?:<[^>]+>)?\s*(?:extends\s+[^{]+)?\s*\{/gm,nameIndex:1},{type:"type",pattern:/^export\s+type\s+(\w+)(?:<[^>]+>)?\s*=/gm,nameIndex:1,exported:!0},{type:"type",pattern:/^type\s+(\w+)(?:<[^>]+>)?\s*=/gm,nameIndex:1},{type:"class",pattern:/^export\s+(?:abstract\s+)?class\s+(\w+)(?:<[^>]+>)?(?:\s+extends\s+[^{]+)?(?:\s+implements\s+[^{]+)?\s*\{/gm,nameIndex:1,exported:!0},{type:"class",pattern:/^(?:abstract\s+)?class\s+(\w+)(?:<[^>]+>)?(?:\s+extends\s+[^{]+)?(?:\s+implements\s+[^{]+)?\s*\{/gm,nameIndex:1},{type:"enum",pattern:/^export\s+enum\s+(\w+)\s*\{/gm,nameIndex:1,exported:!0},{type:"enum",pattern:/^enum\s+(\w+)\s*\{/gm,nameIndex:1},{type:"const",pattern:/^export\s+const\s+(\w+)\s*(?::\s*([^=]+))?\s*=/gm,nameIndex:1,exported:!0}],kn=[{type:"function",pattern:/^def\s+(\w+)\s*\(([^)]*)\)\s*(?:->\s*([^:]+))?\s*:/gm,nameIndex:1},{type:"function",pattern:/^async\s+def\s+(\w+)\s*\(([^)]*)\)\s*(?:->\s*([^:]+))?\s*:/gm,nameIndex:1},{type:"class",pattern:/^class\s+(\w+)(?:\(([^)]*)\))?\s*:/gm,nameIndex:1}],wn=[{type:"function",pattern:/^func\s+(\w+)\s*\(([^)]*)\)\s*(?:\(([^)]*)\)|([^\s{]+))?\s*\{/gm,nameIndex:1},{type:"method",pattern:/^func\s+\([^)]+\)\s+(\w+)\s*\(([^)]*)\)\s*(?:\(([^)]*)\)|([^\s{]+))?\s*\{/gm,nameIndex:1},{type:"type",pattern:/^type\s+(\w+)\s+(?:struct|interface)\s*\{/gm,nameIndex:1}],bn=[{type:"function",pattern:/^pub\s+(?:async\s+)?fn\s+(\w+)(?:<[^>]+>)?\s*\(([^)]*)\)\s*(?:->\s*([^{]+))?\s*\{/gm,nameIndex:1,exported:!0},{type:"function",pattern:/^(?:async\s+)?fn\s+(\w+)(?:<[^>]+>)?\s*\(([^)]*)\)\s*(?:->\s*([^{]+))?\s*\{/gm,nameIndex:1},{type:"class",pattern:/^pub\s+struct\s+(\w+)(?:<[^>]+>)?\s*(?:\{|;)/gm,nameIndex:1,exported:!0},{type:"class",pattern:/^struct\s+(\w+)(?:<[^>]+>)?\s*(?:\{|;)/gm,nameIndex:1},{type:"interface",pattern:/^pub\s+trait\s+(\w+)(?:<[^>]+>)?\s*(?:\{|:)/gm,nameIndex:1,exported:!0},{type:"interface",pattern:/^trait\s+(\w+)(?:<[^>]+>)?\s*(?:\{|:)/gm,nameIndex:1},{type:"enum",pattern:/^pub\s+enum\s+(\w+)(?:<[^>]+>)?\s*\{/gm,nameIndex:1,exported:!0},{type:"enum",pattern:/^enum\s+(\w+)(?:<[^>]+>)?\s*\{/gm,nameIndex:1}],vr=[{type:"class",pattern:/^(?:public\s+)?(?:abstract\s+)?(?:final\s+)?class\s+(\w+)(?:<[^>]+>)?(?:\s+extends\s+\w+)?(?:\s+implements\s+[^{]+)?\s*\{/gm,nameIndex:1,exported:!0},{type:"interface",pattern:/^(?:public\s+)?interface\s+(\w+)(?:<[^>]+>)?(?:\s+extends\s+[^{]+)?\s*\{/gm,nameIndex:1,exported:!0},{type:"method",pattern:/^\s+(?:public|private|protected)?\s*(?:static\s+)?(?:final\s+)?(?:synchronized\s+)?(?:<[^>]+>\s+)?(\w+(?:<[^>]+>)?)\s+(\w+)\s*\([^)]*\)\s*(?:throws\s+[^{]+)?\s*\{/gm,nameIndex:2}],Sn={typescript:xr,javascript:xr,python:kn,go:wn,rust:bn,java:vr,csharp:vr,php:[],ruby:[],unknown:[]};async function _r(n,t=process.cwd()){let e=tt.isAbsolute(n)?n:tt.join(t,n),r=tt.resolve(t),s=tt.resolve(e);if(!s.startsWith(r+tt.sep)&&s!==r)return{file:n,language:"unknown",signatures:[],fallback:!0,fallbackReason:"Path traversal denied: file is outside project directory",metrics:wt("")};let o;try{o=await Tn.readFile(e,"utf-8")}catch(d){if(N(d))return{file:n,language:"unknown",signatures:[],fallback:!0,fallbackReason:"File not found",metrics:wt("")};throw d}let i=tt.extname(n).toLowerCase(),a=En[i]||"unknown",u=Sn[a];if(!u||u.length===0)return{file:n,language:a,signatures:[],fallback:!0,fallbackReason:`No extraction patterns for ${a}`,metrics:wt(o)};let p=xn(o,u),m=p.map(d=>`${d.exported?"export ":""}${d.type} ${d.name}: ${d.signature}`).join(`
510
- `);return{file:n,language:a,signatures:p,fallback:!1,metrics:Sr(o,m)}}c(_r,"extractSignatures");function xn(n,t){let e=[],r=n.split(`
511
- `),s=new Set;for(let o of t){o.pattern.lastIndex=0;let i;for(;(i=o.pattern.exec(n))!==null;){let a=i[o.nameIndex];if(!a)continue;let u=`${o.type}:${a}`;if(s.has(u))continue;s.add(u);let p=i.index,m=n.substring(0,p).split(`
512
- `).length,d=i[0].trim(),g;if(m>1){let y=r[m-2]?.trim();(y?.startsWith("/**")||y?.startsWith("///")||y?.startsWith("#"))&&(g=y)}e.push({type:o.type,name:a,signature:vn(d),exported:o.exported||!1,line:m,docstring:g})}}return e.sort((o,i)=>o.line-i.line)}c(xn,"extractFromContent");function vn(n){return n.replace(/\{$/,"").replace(/\s+/g," ").trim()}c(vn,"cleanSignature");function Pr(n){let t=n;t.tool("prjct_relevant_files","BM25-ranked files relevant to a query",{projectPath:H.string().describe("Project directory path"),query:H.string().describe("Task or query to find relevant files for"),maxFiles:H.number().optional().default(10).describe("Max files to return")},S("prjct_relevant_files",async e=>{let r=await kr(e.query,e.projectPath,{maxFiles:e.maxFiles,minScore:.1});if(r.files.length===0)return{content:[{type:"text",text:"No relevant files found."}]};let s=r.files.map(i=>`- \`${i.path}\` (score: ${Math.round(i.score*100)}%) \u2014 ${i.reasons.join(", ")}`);return{content:[{type:"text",text:`## Relevant Files (${r.files.length}/${r.metrics.filesScanned} scanned)
510
+ `).filter(Boolean);for(let i of s){let o=i.match(/^(\d+)\s+(\d+)\s+(.+)$/);if(o){let a=parseInt(o[1],10),u=parseInt(o[2],10),d=o[3],m=Math.floor((r-u)/86400);t.set(d,{commits:a,daysAgo:m})}}}catch{}return t}c(Hs,"getGitRecency");function qs(n,t,e,r){let s=[],i=0,o=0,a=0,u=0,d=0,m=n.toLowerCase(),p=m.split("/").join(" ").split(/[^a-z0-9]+/);for(let x of t){m.includes(x)&&(i+=.3,s.push(`keyword:${x}`));for(let V of p)if(V.includes(x)||x.includes(V)){i+=.15;break}}i=Math.min(1,i);for(let[x,V]of Object.entries(Xs))for(let Ur of V)if(m.includes(Ur)&&t.some(wt=>V.includes(wt)||wt.includes(x)||x.includes(wt))){o+=.4,s.push(`domain:${x}`);break}o=Math.min(1,o);let g=e.get(n);g&&(g.daysAgo<=1?(a=1,s.push("recent:1d")):g.daysAgo<=3?(a=.8,s.push("recent:3d")):g.daysAgo<=7?(a=.6,s.push("recent:1w")):g.daysAgo<=30&&(a=.3,s.push("recent:1m")),g.commits>=5&&(a=Math.min(1,a+.2)));let T=Tt.basename(n).toLowerCase();if((T.includes("index")||T.includes("main")||T.includes("app")||T.includes("entry"))&&(u=.5,s.push("import:0")),(m.includes("/core/")||m.includes("/shared/")||m.includes("/lib/"))&&(u=Math.max(u,.3),s.some(x=>x.startsWith("import:"))||s.push("import:1")),r){let x=r.get(n);x!==void 0&&(d=(x+1)/2,x>0?s.push("history:boosted"):x<0&&s.push("history:penalized"))}let nt=r&&r.size>0?i*.54+o*.18+a*.13+u*.05+d*.1:i*.6+o*.2+a*.15+u*.05;return{path:n,score:Math.min(1,nt),reasons:[...new Set(s)]}}c(qs,"scoreFile");function Ys(n){let t=n.toLowerCase();return t.includes(".test.")||t.includes(".spec.")||t.includes("__tests__")||t.includes("__mocks__")||t.includes("/tests/")||t.includes("/test/")||t.endsWith("_test.go")||t.endsWith("_test.py")}c(Ys,"isTestFile");U();import Qs from"node:fs/promises";import K from"node:path";var Js={"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}},Ks="claude-sonnet-4.5";function Qt(n){return!n||n.length===0?0:Math.ceil(n.length/4)}c(Qt,"countTokens");var yr=["claude-sonnet-4.5","claude-opus-4.5","claude-opus-4-6","gpt-4o","gemini-1.5-pro"];function Tr(n,t){let e=Js[t],r=n/1e3*e.input,s=n/1e3*e.output*.3;return{inputSaved:r,outputPotential:s,total:r+s}}c(Tr,"calculateModelCost");function Vs(n){return n<.001?"<$0.01":n<.01?`$${n.toFixed(3)}`:`$${n.toFixed(2)}`}c(Vs,"formatCostSaved");function Er(n,t){let e=Qt(n),r=Qt(t),s=Math.max(0,e-r),i=e>0?(e-r)/e:0,o=Tr(s,Ks),a=yr.map(u=>({model:u,...Tr(s,u)}));return{tokens:{original:e,filtered:r,saved:s},compression:Math.max(0,Math.min(1,i)),cost:{saved:o.total,formatted:Vs(o.total),byModel:a}}}c(Er,"measureCompression");function yt(n){let t=Qt(n);return{tokens:{original:t,filtered:t,saved:0},compression:0,cost:{saved:0,formatted:"$0.00",byModel:yr.map(e=>({model:e,inputSaved:0,outputPotential:0,total:0}))}}}c(yt,"noCompression");var Zs={".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"},kr=[{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}],tn=[{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}],en=[{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}],rn=[{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}],wr=[{type:"class",pattern:/^(?:public\s+)?(?:abstract\s+)?(?:final\s+)?class\s+(\w+)(?:<[^>]+>)?(?:\s+extends\s+\w+)?(?:\s+implements\s+[^{]+)?\s*\{/gm,nameIndex:1,exported:!0},{type:"interface",pattern:/^(?:public\s+)?interface\s+(\w+)(?:<[^>]+>)?(?:\s+extends\s+[^{]+)?\s*\{/gm,nameIndex:1,exported:!0},{type:"method",pattern:/^\s+(?:public|private|protected)?\s*(?:static\s+)?(?:final\s+)?(?:synchronized\s+)?(?:<[^>]+>\s+)?(\w+(?:<[^>]+>)?)\s+(\w+)\s*\([^)]*\)\s*(?:throws\s+[^{]+)?\s*\{/gm,nameIndex:2}],sn={typescript:kr,javascript:kr,python:tn,go:en,rust:rn,java:wr,csharp:wr,php:[],ruby:[],unknown:[]};async function br(n,t=process.cwd()){let e=K.isAbsolute(n)?n:K.join(t,n),r=K.resolve(t),s=K.resolve(e);if(!s.startsWith(r+K.sep)&&s!==r)return{file:n,language:"unknown",signatures:[],fallback:!0,fallbackReason:"Path traversal denied: file is outside project directory",metrics:yt("")};let i;try{i=await Qs.readFile(e,"utf-8")}catch(p){if(P(p))return{file:n,language:"unknown",signatures:[],fallback:!0,fallbackReason:"File not found",metrics:yt("")};throw p}let o=K.extname(n).toLowerCase(),a=Zs[o]||"unknown",u=sn[a];if(!u||u.length===0)return{file:n,language:a,signatures:[],fallback:!0,fallbackReason:`No extraction patterns for ${a}`,metrics:yt(i)};let d=nn(i,u),m=d.map(p=>`${p.exported?"export ":""}${p.type} ${p.name}: ${p.signature}`).join(`
511
+ `);return{file:n,language:a,signatures:d,fallback:!1,metrics:Er(i,m)}}c(br,"extractSignatures");function nn(n,t){let e=[],r=n.split(`
512
+ `),s=new Set;for(let i of t){i.pattern.lastIndex=0;let o;for(;(o=i.pattern.exec(n))!==null;){let a=o[i.nameIndex];if(!a)continue;let u=`${i.type}:${a}`;if(s.has(u))continue;s.add(u);let d=o.index,m=n.substring(0,d).split(`
513
+ `).length,p=o[0].trim(),g;if(m>1){let T=r[m-2]?.trim();(T?.startsWith("/**")||T?.startsWith("///")||T?.startsWith("#"))&&(g=T)}e.push({type:i.type,name:a,signature:on(p),exported:i.exported||!1,line:m,docstring:g})}}return e.sort((i,o)=>i.line-o.line)}c(nn,"extractFromContent");function on(n){return n.replace(/\{$/,"").replace(/\s+/g," ").trim()}c(on,"cleanSignature");function Sr(n){let t=n;t.tool("prjct_relevant_files","BM25-ranked files relevant to a query",{projectPath:W.string().describe("Project directory path"),query:W.string().describe("Task or query to find relevant files for"),maxFiles:W.number().optional().default(10).describe("Max files to return")},b("prjct_relevant_files",async e=>{let r=await hr(e.query,e.projectPath,{maxFiles:e.maxFiles,minScore:.1});if(r.files.length===0)return{content:[{type:"text",text:"No relevant files found."}]};let s=r.files.map(o=>`- \`${o.path}\` (score: ${Math.round(o.score*100)}%) \u2014 ${o.reasons.join(", ")}`);return{content:[{type:"text",text:`## Relevant Files (${r.files.length}/${r.metrics.filesScanned} scanned)
513
514
 
514
515
  ${s.join(`
515
- `)}`}]}})),t.tool("prjct_signatures","Code signatures from a file (90% token reduction vs full content)",{projectPath:H.string().describe("Project directory path"),filePath:H.string().describe("Relative file path to extract signatures from")},S("prjct_signatures",async e=>{let r=await _r(e.filePath,e.projectPath);if(r.signatures.length===0)return{content:[{type:"text",text:r.fallback?`No signatures extracted: ${r.fallbackReason}`:"No signatures found."}]};let s=r.signatures.map(a=>`${a.exported?"export ":""}${a.type} ${a.name}: ${a.signature}${a.docstring?` // ${a.docstring}`:""}`),o=r.metrics?.compression?` (${Math.round(r.metrics.compression*100)}% reduction)`:"";return{content:[{type:"text",text:`## ${r.file} (${r.language})
516
+ `)}`}]}})),t.tool("prjct_signatures","Code signatures from a file (90% token reduction vs full content)",{projectPath:W.string().describe("Project directory path"),filePath:W.string().describe("Relative file path to extract signatures from")},b("prjct_signatures",async e=>{let r=await br(e.filePath,e.projectPath);if(r.signatures.length===0)return{content:[{type:"text",text:r.fallback?`No signatures extracted: ${r.fallbackReason}`:"No signatures found."}]};let s=r.signatures.map(a=>`${a.exported?"export ":""}${a.type} ${a.name}: ${a.signature}${a.docstring?` // ${a.docstring}`:""}`),i=r.metrics?.compression?` (${Math.round(r.metrics.compression*100)}% reduction)`:"";return{content:[{type:"text",text:`## ${r.file} (${r.language})
516
517
  \`\`\`
517
518
  ${s.join(`
518
519
  `)}
519
- \`\`\`${o}`}]}})),t.tool("prjct_history","Recent completed tasks with outcomes",{projectPath:H.string().describe("Project directory path"),limit:H.number().optional().default(10).describe("Max results")},S("prjct_history",async e=>{let r=await P(e.projectPath),s=await Z.getTaskHistory(r);if(s.length===0)return{content:[{type:"text",text:"No task history."}]};let i=s.slice(-e.limit).reverse().map(u=>{let p=[`- **${u.title}**`];return u.completedAt&&p.push(`completed: ${u.completedAt}`),u.classification&&p.push(`type: ${u.classification}`),p.join(" | ")});return{content:[{type:"text",text:`## Task History (${s.length} total)
520
-
521
- ${i.join(`
522
- `)}`}]}}))}c(Pr,"registerFileTools");import{z as v}from"zod";var se=class{static{c(this,"MemoryService")}async log(t,e,r,s){try{let o=await B.getProjectId(t);if(!o)return;E.appendEvent(o,`memory.${e}`,{...r,author:s})}catch(o){console.error(`Memory log error: ${o instanceof Error?o.message:String(o)}`)}}async getRecent(t,e=100){try{let r=await B.getProjectId(t);return r?E.query(r,"SELECT type, data, timestamp FROM events WHERE type LIKE 'memory.%' ORDER BY id DESC LIMIT ?",e).reverse().map(o=>{let i=JSON.parse(o.data),{author:a,...u}=i;return{timestamp:o.timestamp,action:o.type.replace("memory.",""),data:u,author:a}}):[]}catch(r){return console.error(`Memory read error: ${r instanceof Error?r.message:String(r)}`),[]}}async search(t,e,r=50){let s=await this.getRecent(t,1e3),o=e.toLowerCase();return s.filter(i=>{let a=i.action.toLowerCase().includes(o),u=JSON.stringify(i.data).toLowerCase().includes(o);return a||u}).slice(-r)}async getByAction(t,e,r=50){try{let s=await B.getProjectId(t);return s?E.query(s,"SELECT type, data, timestamp FROM events WHERE type = ? ORDER BY id DESC LIMIT ?",`memory.${e}`,r).reverse().map(i=>{let a=JSON.parse(i.data),{author:u,...p}=a;return{timestamp:i.timestamp,action:i.type.replace("memory.",""),data:p,author:u}}):[]}catch(s){return console.error(`Memory read error: ${s instanceof Error?s.message:String(s)}`),[]}}async clear(t){try{let e=await B.getProjectId(t);if(!e)return;E.run(e,"DELETE FROM events WHERE type LIKE 'memory.%'")}catch(e){console.error(`Memory clear error: ${e instanceof Error?e.message:String(e)}`)}}async getRecentEvents(t,e=100){try{return E.query(t,"SELECT type, data, timestamp FROM events WHERE type LIKE 'memory.%' ORDER BY id DESC LIMIT ?",e).reverse().map(s=>{let o=JSON.parse(s.data);return{timestamp:s.timestamp,action:s.type.replace("memory.",""),...o}})}catch(r){return console.error(`Memory read error: ${r instanceof Error?r.message:String(r)}`),[]}}async capEntries(t){try{let r=E.get(t,"SELECT COUNT(*) as cnt FROM events WHERE type LIKE 'memory.%'")?.cnt??0;if(r<=ot.MEMORY_MAX_ENTRIES)return 0;let s=r-ot.MEMORY_MAX_ENTRIES,o=E.query(t,"SELECT id, type, data, timestamp FROM events WHERE type LIKE 'memory.%' ORDER BY id ASC LIMIT ?",s);K.archiveMany(t,o.map((a,u)=>({entityType:"memory_entry",entityId:`memory-${a.timestamp||u}`,entityData:{type:a.type,data:JSON.parse(a.data),timestamp:a.timestamp},summary:a.type.replace("memory.",""),reason:"overflow"})));let i=o[o.length-1]?.id;return i!==void 0&&E.run(t,"DELETE FROM events WHERE type LIKE 'memory.%' AND id <= ?",i),s}catch(e){return console.error(`Memory cap error: ${e instanceof Error?e.message:String(e)}`),0}}},Rr=new se;var Ar="memory.",ne="remember.",oe=`${Ar}${ne}`,dc=`${Ar}task.tagged`;var Nr=["fact","decision","learning","gotcha","pattern","anti-pattern","shipped","inbox","todo","idea","insight","question","source","person"];var _n=25,Pn=4,Rn=100;function Cr(n,t){try{return JSON.parse(n)}catch{return t}}c(Cr,"safeJson");function An(n){let t=n.type.slice(oe.length),e=Cr(n.data,{});return{id:`mem_${n.id}`,type:t,content:e.content??"",tags:e.tags??{},rememberedAt:n.timestamp,source:e.source,provenance:e.provenance??"declared"}}c(An,"rowToEntry");function Nn(n){let t=n.data?Cr(n.data,{}):{},e=t.tags??{};return n.type&&(e.type=n.type),{id:`ship_${n.id}`,type:"shipped",content:n.name,tags:e,rememberedAt:n.shipped_at,source:t.taskId,provenance:"extracted"}}c(Nn,"shippedRowToEntry");function Cn(n,t){let e=t.toLowerCase();if(n.content.toLowerCase().includes(e))return!0;for(let r of Object.values(n.tags))if(r.toLowerCase().includes(e))return!0;return!1}c(Cn,"matchesTopic");function In(n,t){for(let[e,r]of Object.entries(t))if(n.tags[e]!==r)return!1;return!0}c(In,"matchesTags");var q={async remember(n,t){await Rr.log(n,`${ne}${t.type}`,{content:t.content,tags:t.tags??{},source:t.source,provenance:t.provenance??"declared"})},recall(n,t={}){let e=t.limit??_n,r=Math.max(e*Pn,Rn),s=E.query(n,"SELECT id, type, data, timestamp FROM events WHERE type LIKE ? ORDER BY id DESC LIMIT ?",`${oe}%`,r),o=E.query(n,"SELECT id, name, type, shipped_at, data FROM shipped_features ORDER BY shipped_at DESC LIMIT ?",r),i=[...s.map(An),...o.map(Nn)];if(t.types&&t.types.length>0){let a=new Set(t.types);i=i.filter(u=>a.has(u.type))}return t.tags&&(i=i.filter(a=>In(a,t.tags??{}))),t.topic&&(i=i.filter(a=>Cn(a,t.topic))),i.sort((a,u)=>u.rememberedAt.localeCompare(a.rememberedAt)),i.slice(0,e)},similar(n,t,e=10){let r=t.toLowerCase().split(/[^a-z0-9]+/).filter(i=>i.length>3);return r.length===0?[]:q.recall(n,{limit:200}).map(i=>{let a=`${i.content} ${Object.values(i.tags).join(" ")}`.toLowerCase(),u=r.reduce((p,m)=>a.includes(m)?p+1:p,0);return{entry:i,hits:u}}).filter(i=>i.hits>0).sort((i,a)=>a.hits-i.hits).slice(0,e).map(i=>i.entry)}};function it(n){if(n.length===0)return"> No matching memory entries.";let t=new Map;for(let o of n){let i=t.get(o.type)??[];i.push(o),t.set(o.type,i)}let e=["decision","learning","anti-pattern","gotcha","pattern","fact","shipped"],r=[],s={declared:"DECL",extracted:"EXTR",inferred:"INFR",ambiguous:"AMBG"};for(let o of e){let i=t.get(o);if(!(!i||i.length===0)){r.push(`### ${o.toUpperCase()}`);for(let a of i){let u=Object.entries(a.tags).map(([d,g])=>`${d}=${g}`).join(" "),p=u?` _(${u})_`:"",m=s[a.provenance];r.push(`- \`${m}\` [${a.id}] ${a.content}${p}`)}r.push("")}}return r.join(`
523
- `).trim()}c(it,"formatMemoryMd");var Dn=[{name:"sk-\u2026 token",re:/\bsk-[A-Za-z0-9_-]{16,}/},{name:"GitHub PAT",re:/\bghp_[A-Za-z0-9]{30,}/},{name:"GitHub server PAT",re:/\bghs_[A-Za-z0-9]{30,}/},{name:"AWS access key",re:/\bAKIA[0-9A-Z]{16}\b/},{name:"Slack token",re:/\bxox[abps]-[A-Za-z0-9-]{10,}/},{name:"bearer JWT-ish",re:/\beyJ[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}\b/}];function Ir(n){let t=[];for(let{name:e,re:r}of Dn)r.test(n)&&t.push(e);return t}c(Ir,"scanForSecrets");var Dr=`Base types: ${Nr.join(", ")}. Any lowercase identifier is accepted (e.g. "recipe", "okr").`;function Lr(n){let t=n;t.tool("prjct_mem_save",`Save a memory entry. ${Dr} Secret-like content is refused unless force=true.`,{projectPath:v.string().describe("Project directory path"),type:v.string().describe("Memory type (fact/decision/learning/... or user-defined)"),content:v.string().describe("The memory content. Freeform text."),tags:v.record(v.string(),v.string()).optional().describe('Key:value tags (e.g. {domain: "auth"})'),source:v.string().optional().describe("Task id this memory came from, if any"),force:v.boolean().optional().describe("Bypass the secret-like-content refusal. Default false.")},S("prjct_mem_save",async e=>{await P(e.projectPath);let r=e.type.toLowerCase().trim();if(!r||!/^[a-z][a-z0-9-]*$/.test(r))return{content:[{type:"text",text:`Invalid type '${e.type}'. Lowercase letters + dashes only. ${Dr}`}]};let s=Ir(e.content);return s.length>0&&!e.force?{content:[{type:"text",text:`Refused \u2014 content looks like a secret (${s.join(", ")}). Re-call with force=true if intentional.`}]}:(await q.remember(e.projectPath,{type:r,content:e.content,tags:e.tags??{},source:e.source}),{content:[{type:"text",text:`Saved ${r}: ${e.content.slice(0,80)}`}]})})),t.tool("prjct_mem_list","Recall memory entries. Optional filters: topic (keyword across content + tag values), types, tags, limit.",{projectPath:v.string().describe("Project directory path"),topic:v.string().optional().describe("Keyword to match over content + tag values"),types:v.array(v.string()).optional().describe("Restrict to these types"),tags:v.record(v.string(),v.string()).optional().describe("Require exact match on these k:v pairs"),limit:v.number().optional().default(25).describe("Max entries (default 25)")},S("prjct_mem_list",async e=>{let r=await P(e.projectPath),s=q.recall(r,{topic:e.topic,types:e.types,tags:e.tags,limit:e.limit});return{content:[{type:"text",text:it(s)}]}})),t.tool("prjct_mem_similar","Find memory entries similar to a free-text description. Keyword-based, best-effort.",{projectPath:v.string().describe("Project directory path"),description:v.string().describe("Free-text description to find similar memories for"),limit:v.number().optional().default(10).describe("Max results (default 10)")},S("prjct_mem_similar",async e=>{let r=await P(e.projectPath),s=q.similar(r,e.description,e.limit);return s.length===0?{content:[{type:"text",text:"No similar memories found."}]}:{content:[{type:"text",text:it(s)}]}})),t.tool("prjct_mem_forget","Remove a memory entry by id. Ids are stable \u2014 pull them from `prjct_mem_list`.",{projectPath:v.string().describe("Project directory path"),id:v.string().describe('Memory id (e.g. "mem_42" or "ship_7")')},S("prjct_mem_forget",async e=>({content:[{type:"text",text:"Forget is not implemented in the projectMemory API yet. Entries persist event-sourced \u2014 filter them out client-side, or drop the underlying event manually."}]})))}c(Lr,"registerMemoryTools");import{z as ce}from"zod";var ie=class{static{c(this,"LLMAnalysisStorage")}save(t,e){let r=T.getDb(t),s=f();r.transaction(()=>{r.prepare("UPDATE llm_analysis SET status = 'superseded', superseded_at = ? WHERE status = 'active'").run(s),r.prepare("INSERT INTO llm_analysis (commit_hash, status, analysis, analyzed_at) VALUES (?, ?, ?, ?)").run(e.commitHash??null,"active",JSON.stringify(e),e.analyzedAt)})()}getActive(t){let e=T.get(t,"SELECT analysis FROM llm_analysis WHERE status = 'active' LIMIT 1");return e?JSON.parse(e.analysis):null}getActiveSummary(t){let e=this.getActive(t);return e?{commitHash:e.commitHash,architectureStyle:e.architecture.style,patternCount:e.patterns.length,antiPatternCount:e.antiPatterns.length,analyzedAt:e.analyzedAt}:null}isCurrent(t,e){return e?T.get(t,"SELECT commit_hash FROM llm_analysis WHERE status = 'active' LIMIT 1")?.commit_hash===e:!1}getAllFull(t){return T.query(t,"SELECT id, commit_hash, status, analyzed_at, superseded_at, analysis FROM llm_analysis ORDER BY id DESC").map(r=>({id:r.id,status:r.status,commitHash:r.commit_hash,analyzedAt:r.analyzed_at,supersededAt:r.superseded_at,analysis:JSON.parse(r.analysis)}))}getHistory(t,e=10){return T.query(t,"SELECT id, commit_hash, status, analyzed_at, analysis FROM llm_analysis ORDER BY id DESC LIMIT ?",e).map(s=>{let o=JSON.parse(s.analysis);return{id:s.id,commitHash:s.commit_hash,status:s.status,analyzedAt:s.analyzed_at,patternCount:o.patterns.length}})}},Ln=new ie,Or=Ln;var jr={critical:0,high:1,medium:2,low:3},Mr={active:0,previously_active:1,backlog:2};function Fr(n){return[...n].sort((t,e)=>{let r=Mr[t.section]-Mr[e.section];return r!==0?r:jr[t.priority]-jr[e.priority]})}c(Fr,"sortBySectionAndPriority");var ae=class extends Q{static{c(this,"QueueStorage")}constructor(){super("queue.json",Tr)}getDefault(){return{tasks:[],lastUpdated:""}}getEventType(t){return`queue.${t}d`}async getTasks(t){return(await this.read(t)).tasks}async getActiveTasks(t){return(await this.read(t)).tasks.filter(r=>r.section==="active"&&!r.completed)}async getBacklog(t){return(await this.read(t)).tasks.filter(r=>r.section==="backlog"&&!r.completed)}async getNextTask(t){let e=await this.getActiveTasks(t);return Fr(e)[0]||null}async addTask(t,e){let r={...e,id:$(),createdAt:f(),completed:!1};return await this.update(t,s=>({tasks:[...s.tasks,r],lastUpdated:f()})),await this.publishEvent(t,"queue.task_added",{taskId:r.id,description:r.description,priority:r.priority,section:r.section}),r}async addTasks(t,e){let r=f(),s=e.map(o=>({...o,id:$(),createdAt:r,completed:!1}));return await this.update(t,o=>({tasks:[...o.tasks,...s],lastUpdated:r})),await this.publishEvent(t,"queue.tasks_added",{count:s.length,tasks:s.map(o=>({id:o.id,description:o.description}))}),s}async removeTask(t,e){await this.update(t,r=>({tasks:r.tasks.filter(s=>s.id!==e),lastUpdated:f()})),await this.publishEvent(t,"queue.task_removed",{taskId:e})}async completeTask(t,e){let r=null;if(await this.update(t,s=>({tasks:s.tasks.map(i=>i.id===e?(r={...i,completed:!0,completedAt:f()},r):i),lastUpdated:f()})),r){let s=r;await this.publishEvent(t,"queue.task_completed",{taskId:e,description:s.description,completedAt:s.completedAt})}return r}async moveToSection(t,e,r){await this.update(t,s=>({tasks:s.tasks.map(o=>o.id===e?{...o,section:r}:o),lastUpdated:f()}))}async setPriority(t,e,r){await this.update(t,s=>({tasks:s.tasks.map(o=>o.id===e?{...o,priority:r}:o),lastUpdated:f()}))}async getTask(t,e){return(await this.read(t)).tasks.find(s=>s.id===e)||null}async updateTask(t,e,r){let s=null;return await this.update(t,o=>({tasks:o.tasks.map(i=>i.id===e?(s={...i,...r},s):i),lastUpdated:f()})),s&&await this.publishEvent(t,"queue.task_updated",{taskId:e}),s}async clearCompleted(t){let r=(await this.read(t)).tasks.filter(s=>s.completed).length;return await this.update(t,s=>({tasks:s.tasks.filter(o=>!o.completed),lastUpdated:f()})),r}async removeStaleCompleted(t){let e=await this.read(t),r=Ee(ot.QUEUE_COMPLETED_DAYS),s=e.tasks.filter(i=>i.completed&&i.completedAt&&new Date(i.completedAt)<r);if(s.length===0)return 0;K.archiveMany(t,s.map(i=>({entityType:"queue_task",entityId:i.id,entityData:i,summary:i.description,reason:"age"})));let o=new Set(s.map(i=>i.id));return await this.update(t,i=>({tasks:i.tasks.filter(a=>!o.has(a.id)),lastUpdated:f()})),await this.publishEvent(t,"queue.stale_removed",{count:s.length}),s.length}},Ur=new ae;function Xr(n){let t=n;t.tool("prjct_task_status","Current task, duration, subtasks, and queue",{projectPath:ce.string().describe("Project directory path")},S("prjct_task_status",async e=>{let r=await P(e.projectPath),s=await Z.getCurrentTask(r),o=await Ur.getActiveTasks(r),i=[];if(s?(i.push(`## Active Task
524
- **${s.description}**`),s.branch&&i.push(`Branch: ${s.branch}`),i.push(`Started: ${s.startedAt}`)):i.push("No active task."),o.length>0){i.push(`
525
- ## Queue (${o.length} tasks)`);for(let a of o.slice(0,10))i.push(`- ${a.description} [${a.priority||"medium"}]`)}return{content:[{type:"text",text:i.join(`
526
- `)}]}})),t.tool("prjct_analysis","LLM analysis: stack, patterns, anti-patterns, conventions",{projectPath:ce.string().describe("Project directory path")},S("prjct_analysis",async e=>{let r=await P(e.projectPath),s=Or.getActive(r);if(!s)return{content:[{type:"text",text:"No analysis available. Run `prjct sync`."}]};let o=["## Project Analysis"];if(s.stack&&(o.push(`
527
- ### Stack`),s.stack.languages?.length&&o.push(`Languages: ${s.stack.languages.join(", ")}`),s.stack.frameworks?.length&&o.push(`Frameworks: ${s.stack.frameworks.join(", ")}`),s.stack.packageManager&&o.push(`Package Manager: ${s.stack.packageManager}`)),s.patterns?.length){o.push(`
528
- ### Patterns (${s.patterns.length})`);for(let i of s.patterns)o.push(`- **${i.name}**: ${i.description}`)}if(s.antiPatterns?.length){o.push(`
529
- ### Anti-Patterns (${s.antiPatterns.length})`);for(let i of s.antiPatterns)o.push(`- **${i.issue}**: ${i.suggestion}`)}if(s.conventions?.length){o.push(`
530
- ### Conventions (${s.conventions.length})`);for(let i of s.conventions)o.push(`- [${i.category}] ${i.rule}`)}return{content:[{type:"text",text:o.join(`
531
- `)}]}})),t.tool("prjct_patterns","Project memory grouped by type (decision / pattern / anti-pattern / gotcha). Powered by projectMemory \u2014 same source the CLI memory verbs read.",{projectPath:ce.string().describe("Project directory path")},S("prjct_patterns",async e=>{let r=await P(e.projectPath),s=q.recall(r,{types:["decision","pattern","anti-pattern","gotcha"],limit:50});return s.length===0?{content:[{type:"text",text:"No decisions or patterns captured yet."}]}:{content:[{type:"text",text:it(s)}]}}))}c(Xr,"registerProjectTools");import{z as St}from"zod";var ue=class{static{c(this,"CustomWorkflowStorage")}createWorkflow(t,e){let r=new Date().toISOString();E.run(t,`INSERT INTO custom_workflows (name, description, created_at, updated_at, is_builtin, enabled, metadata)
532
- VALUES (?, ?, ?, ?, 0, 1, ?)`,e.name,e.description??null,r,r,e.metadata?JSON.stringify(e.metadata):null);let s=E.get(t,"SELECT id FROM custom_workflows WHERE name = ?",e.name);if(!s)throw new Error(`Failed to create workflow: ${e.name}`);return s.id}getWorkflow(t,e){let r=E.get(t,"SELECT * FROM custom_workflows WHERE name = ?",e);return r?this.rowToWorkflow(r):null}getAllWorkflows(t,e=!1){let r=e?"SELECT * FROM custom_workflows ORDER BY is_builtin DESC, name ASC":"SELECT * FROM custom_workflows WHERE enabled = 1 ORDER BY is_builtin DESC, name ASC";return E.query(t,r).map(o=>this.rowToWorkflow(o))}updateWorkflow(t,e,r){if(!this.getWorkflow(t,e))return!1;let o=new Date().toISOString(),i=[],a=[];return r.description!==void 0&&(i.push("description = ?"),a.push(r.description)),r.enabled!==void 0&&(i.push("enabled = ?"),a.push(r.enabled?1:0)),r.metadata!==void 0&&(i.push("metadata = ?"),a.push(JSON.stringify(r.metadata))),i.length===0?!1:(i.push("updated_at = ?"),a.push(o),a.push(e),E.run(t,`UPDATE custom_workflows SET ${i.join(", ")} WHERE name = ?`,...a),!0)}deleteWorkflow(t,e){let r=this.getWorkflow(t,e);if(!r)return!1;if(r.isBuiltin)throw new Error(`Cannot delete built-in workflow: ${e}`);return E.run(t,"UPDATE custom_workflows SET enabled = 0 WHERE name = ?",e),!0}isBuiltin(t,e){return this.getWorkflow(t,e)?.isBuiltin??!1}isReservedName(t){let e=["task","done","ship","sync"],r=["add","rm","gate","list","create","delete","run","help","reset","init"];return e.includes(t)||r.includes(t)}isValidName(t){return/^[a-z0-9-]+$/.test(t)}rowToWorkflow(t){return{id:t.id,name:t.name,description:t.description,createdAt:t.created_at,updatedAt:t.updated_at,isBuiltin:t.is_builtin===1,enabled:t.enabled===1,metadata:t.metadata?JSON.parse(t.metadata):null}}},bt=new ue;function le(n){let t=n.trust_source==="imported"?"imported":"local";return{id:n.id,type:n.type,command:n.command,position:n.position,action:n.action,description:n.description,enabled:n.enabled===1,timeoutMs:n.timeout_ms,createdAt:n.created_at,sortOrder:n.sort_order,whenExpr:n.when_expr??null,parallel:n.parallel===null?!0:n.parallel===1,trustSource:t}}c(le,"rowToRule");var pe=class{static{c(this,"WorkflowRuleStorage")}addRule(t,e){let r=T.get(t,"SELECT MAX(sort_order) as m FROM workflow_rules WHERE command = ?",e.command),s=e.sortOrder||(r?.m??-1)+1;return T.run(t,`INSERT INTO workflow_rules (type, command, position, action, description, enabled, timeout_ms, created_at, sort_order, when_expr, parallel, trust_source)
533
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,e.type,e.command,e.position,e.action,e.description??null,e.enabled?1:0,e.timeoutMs,e.createdAt,s,e.whenExpr??null,e.parallel===!1?0:1,e.trustSource??"local"),T.get(t,"SELECT last_insert_rowid() as id")?.id??0}removeRule(t,e){return T.get(t,"SELECT id FROM workflow_rules WHERE id = ?",e)?(T.run(t,"DELETE FROM workflow_rules WHERE id = ?",e),!0):!1}updateRule(t,e,r){if(!T.get(t,"SELECT id FROM workflow_rules WHERE id = ?",e))return!1;let o={type:{column:"type"},command:{column:"command"},position:{column:"position"},action:{column:"action"},description:{column:"description"},enabled:{column:"enabled",transform:c(u=>u?1:0,"transform")},timeoutMs:{column:"timeout_ms"},createdAt:{column:"created_at"},sortOrder:{column:"sort_order"},whenExpr:{column:"when_expr"},parallel:{column:"parallel",transform:c(u=>u===!1?0:1,"transform")},trustSource:{column:"trust_source"}},i=[],a=[];for(let[u,p]of Object.entries(r)){let m=o[u];if(!m)continue;i.push(`${m.column} = ?`);let d=p;a.push(m.transform?m.transform(d):d)}return i.length===0||(a.push(e),T.run(t,`UPDATE workflow_rules SET ${i.join(", ")} WHERE id = ?`,...a)),!0}getRuleById(t,e){let r=T.get(t,"SELECT * FROM workflow_rules WHERE id = ?",e);return r?le(r):null}getRulesForCommand(t,e){let r=bt.getWorkflow(t,e);return!r||!r.enabled?[]:T.query(t,"SELECT * FROM workflow_rules WHERE command = ? AND enabled = 1 ORDER BY sort_order ASC",e).map(le)}getAllRules(t){return T.query(t,"SELECT * FROM workflow_rules ORDER BY command ASC, sort_order ASC").map(le)}resetRules(t){let e=T.get(t,"SELECT COUNT(*) as c FROM workflow_rules");return T.run(t,"DELETE FROM workflow_rules"),e?.c??0}},de=new pe;function $r(n){let t=n;t.tool("prjct_workflow_rules","Get workflow rules for a command (gates, hooks, steps, instructions)",{projectPath:St.string().describe("Project directory path"),command:St.string().describe("Command name (task, done, ship, sync, etc.)")},S("prjct_workflow_rules",async e=>{let r=await P(e.projectPath),s=de.getRulesForCommand(r,e.command);if(s.length===0)return{content:[{type:"text",text:`No workflow rules for \`${e.command}\`.`}]};let o={};for(let a of s){let u=`${a.type}:${a.position}`;o[u]||(o[u]=[]),o[u].push(a)}let i=[`## Workflow Rules for \`${e.command}\``];for(let[a,u]of Object.entries(o)){i.push(`
534
- ### ${a}`);for(let p of u){let m=p.enabled?"":" (disabled)";i.push(`- ${p.action}${p.description?` \u2014 ${p.description}`:""}${m}`)}}return{content:[{type:"text",text:i.join(`
535
- `)}]}})),t.tool("prjct_workflow_list","List all workflows for this project (built-in + custom)",{projectPath:St.string().describe("Project directory path")},S("prjct_workflow_list",async e=>{let r=await P(e.projectPath),s=bt.getAllWorkflows(r);if(s.length===0)return{content:[{type:"text",text:"No workflows configured."}]};let o=s.map(i=>{let a=i.isBuiltin?"(built-in)":"(custom)",u=i.enabled?"":" [disabled]";return`- **${i.name}** ${a}${u}${i.description?`: ${i.description}`:""}`});return{content:[{type:"text",text:`## Workflows (${s.length})
520
+ \`\`\`${i}`}]}})),t.tool("prjct_history","Recent completed tasks with outcomes",{projectPath:W.string().describe("Project directory path"),limit:W.number().optional().default(10).describe("Max results")},b("prjct_history",async e=>{let r=await v(e.projectPath),s=await J.getTaskHistory(r);if(s.length===0)return{content:[{type:"text",text:"No task history."}]};let o=s.slice(-e.limit).reverse().map(u=>{let d=[`- **${u.title}**`];return u.completedAt&&d.push(`completed: ${u.completedAt}`),u.classification&&d.push(`type: ${u.classification}`),d.join(" | ")});return{content:[{type:"text",text:`## Task History (${s.length} total)
536
521
 
537
522
  ${o.join(`
538
- `)}`}]}})),t.tool("prjct_workflow_status","Current workflow execution state + active rules",{projectPath:St.string().describe("Project directory path")},S("prjct_workflow_status",async e=>{let r=await P(e.projectPath),s=await Z.getCurrentTask(r),o=de.getAllRules(r),i=["## Workflow Status"];s?(i.push(`
539
- Active task: **${s.description}**`),i.push(`Started: ${s.startedAt}`)):i.push(`
540
- No active task.`);let a=o.filter(u=>u.enabled);if(a.length>0){i.push(`
541
- ### Active Rules (${a.length})`);for(let u of a)i.push(`- [${u.type}] ${u.command}:${u.position} \u2192 ${u.action}`)}else i.push(`
542
- No active workflow rules.`);return{content:[{type:"text",text:i.join(`
543
- `)}]}}))}c($r,"registerWorkflowTools");var jn=`# prjct \u2014 persona-aware context broker
523
+ `)}`}]}}))}c(Sr,"registerFileTools");import{z as S}from"zod";var Zt=class{static{c(this,"MemoryService")}async log(t,e,r,s){try{let i=await $.getProjectId(t);if(!i)return;E.appendEvent(i,`memory.${e}`,{...r,author:s})}catch(i){console.error(`Memory log error: ${i instanceof Error?i.message:String(i)}`)}}async getRecent(t,e=100){try{let r=await $.getProjectId(t);return r?E.query(r,"SELECT type, data, timestamp FROM events WHERE type LIKE 'memory.%' ORDER BY id DESC LIMIT ?",e).reverse().map(i=>{let o=JSON.parse(i.data),{author:a,...u}=o;return{timestamp:i.timestamp,action:i.type.replace("memory.",""),data:u,author:a}}):[]}catch(r){return console.error(`Memory read error: ${r instanceof Error?r.message:String(r)}`),[]}}async search(t,e,r=50){let s=await this.getRecent(t,1e3),i=e.toLowerCase();return s.filter(o=>{let a=o.action.toLowerCase().includes(i),u=JSON.stringify(o.data).toLowerCase().includes(i);return a||u}).slice(-r)}async getByAction(t,e,r=50){try{let s=await $.getProjectId(t);return s?E.query(s,"SELECT type, data, timestamp FROM events WHERE type = ? ORDER BY id DESC LIMIT ?",`memory.${e}`,r).reverse().map(o=>{let a=JSON.parse(o.data),{author:u,...d}=a;return{timestamp:o.timestamp,action:o.type.replace("memory.",""),data:d,author:u}}):[]}catch(s){return console.error(`Memory read error: ${s instanceof Error?s.message:String(s)}`),[]}}async clear(t){try{let e=await $.getProjectId(t);if(!e)return;E.run(e,"DELETE FROM events WHERE type LIKE 'memory.%'")}catch(e){console.error(`Memory clear error: ${e instanceof Error?e.message:String(e)}`)}}async getRecentEvents(t,e=100){try{return E.query(t,"SELECT type, data, timestamp FROM events WHERE type LIKE 'memory.%' ORDER BY id DESC LIMIT ?",e).reverse().map(s=>{let i=JSON.parse(s.data);return{timestamp:s.timestamp,action:s.type.replace("memory.",""),...i}})}catch(r){return console.error(`Memory read error: ${r instanceof Error?r.message:String(r)}`),[]}}async capEntries(t){try{let r=E.get(t,"SELECT COUNT(*) as cnt FROM events WHERE type LIKE 'memory.%'")?.cnt??0;if(r<=rt.MEMORY_MAX_ENTRIES)return 0;let s=r-rt.MEMORY_MAX_ENTRIES,i=E.query(t,"SELECT id, type, data, timestamp FROM events WHERE type LIKE 'memory.%' ORDER BY id ASC LIMIT ?",s);Y.archiveMany(t,i.map((a,u)=>({entityType:"memory_entry",entityId:`memory-${a.timestamp||u}`,entityData:{type:a.type,data:JSON.parse(a.data),timestamp:a.timestamp},summary:a.type.replace("memory.",""),reason:"overflow"})));let o=i[i.length-1]?.id;return o!==void 0&&E.run(t,"DELETE FROM events WHERE type LIKE 'memory.%' AND id <= ?",o),s}catch(e){return console.error(`Memory cap error: ${e instanceof Error?e.message:String(e)}`),0}}},vr=new Zt;var _r="memory.",te="remember.",ee=`${_r}${te}`,Ia=`${_r}task.tagged`;var xr=["fact","decision","learning","gotcha","pattern","anti-pattern","shipped","inbox","todo","idea","insight","question","source","person"];var an=25,cn=4,un=100;function Rr(n,t){try{return JSON.parse(n)}catch{return t}}c(Rr,"safeJson");function ln(n){let t=n.type.slice(ee.length),e=Rr(n.data,{});return{id:`mem_${n.id}`,type:t,content:e.content??"",tags:e.tags??{},rememberedAt:n.timestamp,source:e.source,provenance:e.provenance??"declared"}}c(ln,"rowToEntry");function dn(n){let t=n.data?Rr(n.data,{}):{},e=t.tags??{};return n.type&&(e.type=n.type),{id:`ship_${n.id}`,type:"shipped",content:n.name,tags:e,rememberedAt:n.shipped_at,source:t.taskId,provenance:"extracted"}}c(dn,"shippedRowToEntry");function pn(n,t){let e=t.toLowerCase();if(n.content.toLowerCase().includes(e))return!0;for(let r of Object.values(n.tags))if(r.toLowerCase().includes(e))return!0;return!1}c(pn,"matchesTopic");function mn(n,t){for(let[e,r]of Object.entries(t))if(n.tags[e]!==r)return!1;return!0}c(mn,"matchesTags");var G={async remember(n,t){await vr.log(n,`${te}${t.type}`,{content:t.content,tags:t.tags??{},source:t.source,provenance:t.provenance??"declared"})},recall(n,t={}){let e=t.limit??an,r=Math.max(e*cn,un),s=E.query(n,"SELECT id, type, data, timestamp FROM events WHERE type LIKE ? ORDER BY id DESC LIMIT ?",`${ee}%`,r),i=E.query(n,"SELECT id, name, type, shipped_at, data FROM shipped_features ORDER BY shipped_at DESC LIMIT ?",r),o=[...s.map(ln),...i.map(dn)];if(t.types&&t.types.length>0){let a=new Set(t.types);o=o.filter(u=>a.has(u.type))}return t.tags&&(o=o.filter(a=>mn(a,t.tags??{}))),t.topic&&(o=o.filter(a=>pn(a,t.topic))),o.sort((a,u)=>u.rememberedAt.localeCompare(a.rememberedAt)),o.slice(0,e)},similar(n,t,e=10){let r=t.toLowerCase().split(/[^a-z0-9]+/).filter(o=>o.length>3);return r.length===0?[]:G.recall(n,{limit:200}).map(o=>{let a=`${o.content} ${Object.values(o.tags).join(" ")}`.toLowerCase(),u=r.reduce((d,m)=>a.includes(m)?d+1:d,0);return{entry:o,hits:u}}).filter(o=>o.hits>0).sort((o,a)=>a.hits-o.hits).slice(0,e).map(o=>o.entry)}};function st(n){if(n.length===0)return"> No matching memory entries.";let t=new Map;for(let i of n){let o=t.get(i.type)??[];o.push(i),t.set(i.type,o)}let e=["decision","learning","anti-pattern","gotcha","pattern","fact","shipped"],r=[],s={declared:"DECL",extracted:"EXTR",inferred:"INFR",ambiguous:"AMBG"};for(let i of e){let o=t.get(i);if(!(!o||o.length===0)){r.push(`### ${i.toUpperCase()}`);for(let a of o){let u=Object.entries(a.tags).map(([p,g])=>`${p}=${g}`).join(" "),d=u?` _(${u})_`:"",m=s[a.provenance];r.push(`- \`${m}\` [${a.id}] ${a.content}${d}`)}r.push("")}}return r.join(`
524
+ `).trim()}c(st,"formatMemoryMd");var gn=[{name:"sk-\u2026 token",re:/\bsk-[A-Za-z0-9_-]{16,}/},{name:"GitHub PAT",re:/\bghp_[A-Za-z0-9]{30,}/},{name:"GitHub server PAT",re:/\bghs_[A-Za-z0-9]{30,}/},{name:"AWS access key",re:/\bAKIA[0-9A-Z]{16}\b/},{name:"Slack token",re:/\bxox[abps]-[A-Za-z0-9-]{10,}/},{name:"bearer JWT-ish",re:/\beyJ[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}\b/}];function Pr(n){let t=[];for(let{name:e,re:r}of gn)r.test(n)&&t.push(e);return t}c(Pr,"scanForSecrets");var Ar=`Base types: ${xr.join(", ")}. Any lowercase identifier is accepted (e.g. "recipe", "okr").`;function Nr(n){let t=n;t.tool("prjct_mem_save",`Save a memory entry. ${Ar} Secret-like content is refused unless force=true.`,{projectPath:S.string().describe("Project directory path"),type:S.string().describe("Memory type (fact/decision/learning/... or user-defined)"),content:S.string().describe("The memory content. Freeform text."),tags:S.record(S.string(),S.string()).optional().describe('Key:value tags (e.g. {domain: "auth"})'),source:S.string().optional().describe("Task id this memory came from, if any"),force:S.boolean().optional().describe("Bypass the secret-like-content refusal. Default false.")},b("prjct_mem_save",async e=>{await v(e.projectPath);let r=e.type.toLowerCase().trim();if(!r||!/^[a-z][a-z0-9-]*$/.test(r))return{content:[{type:"text",text:`Invalid type '${e.type}'. Lowercase letters + dashes only. ${Ar}`}]};let s=Pr(e.content);return s.length>0&&!e.force?{content:[{type:"text",text:`Refused \u2014 content looks like a secret (${s.join(", ")}). Re-call with force=true if intentional.`}]}:(await G.remember(e.projectPath,{type:r,content:e.content,tags:e.tags??{},source:e.source}),{content:[{type:"text",text:`Saved ${r}: ${e.content.slice(0,80)}`}]})})),t.tool("prjct_mem_list","Recall memory entries. Optional filters: topic (keyword across content + tag values), types, tags, limit.",{projectPath:S.string().describe("Project directory path"),topic:S.string().optional().describe("Keyword to match over content + tag values"),types:S.array(S.string()).optional().describe("Restrict to these types"),tags:S.record(S.string(),S.string()).optional().describe("Require exact match on these k:v pairs"),limit:S.number().optional().default(25).describe("Max entries (default 25)")},b("prjct_mem_list",async e=>{let r=await v(e.projectPath),s=G.recall(r,{topic:e.topic,types:e.types,tags:e.tags,limit:e.limit});return{content:[{type:"text",text:st(s)}]}})),t.tool("prjct_mem_similar","Find memory entries similar to a free-text description. Keyword-based, best-effort.",{projectPath:S.string().describe("Project directory path"),description:S.string().describe("Free-text description to find similar memories for"),limit:S.number().optional().default(10).describe("Max results (default 10)")},b("prjct_mem_similar",async e=>{let r=await v(e.projectPath),s=G.similar(r,e.description,e.limit);return s.length===0?{content:[{type:"text",text:"No similar memories found."}]}:{content:[{type:"text",text:st(s)}]}})),t.tool("prjct_mem_forget","Remove a memory entry by id. Ids are stable \u2014 pull them from `prjct_mem_list`.",{projectPath:S.string().describe("Project directory path"),id:S.string().describe('Memory id (e.g. "mem_42" or "ship_7")')},b("prjct_mem_forget",async e=>({content:[{type:"text",text:"Forget is not implemented in the projectMemory API yet. Entries persist event-sourced \u2014 filter them out client-side, or drop the underlying event manually."}]})))}c(Nr,"registerMemoryTools");import{z as ne}from"zod";var re=class{static{c(this,"LLMAnalysisStorage")}save(t,e){let r=y.getDb(t),s=f();r.transaction(()=>{r.prepare("UPDATE llm_analysis SET status = 'superseded', superseded_at = ? WHERE status = 'active'").run(s),r.prepare("INSERT INTO llm_analysis (commit_hash, status, analysis, analyzed_at) VALUES (?, ?, ?, ?)").run(e.commitHash??null,"active",JSON.stringify(e),e.analyzedAt)})()}getActive(t){let e=y.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?y.get(t,"SELECT commit_hash FROM llm_analysis WHERE status = 'active' LIMIT 1")?.commit_hash===e:!1}getAllFull(t){return y.query(t,"SELECT id, commit_hash, status, analyzed_at, superseded_at, analysis FROM llm_analysis ORDER BY id DESC").map(r=>({id:r.id,status:r.status,commitHash:r.commit_hash,analyzedAt:r.analyzed_at,supersededAt:r.superseded_at,analysis:JSON.parse(r.analysis)}))}getHistory(t,e=10){return y.query(t,"SELECT id, commit_hash, status, analyzed_at, analysis FROM llm_analysis ORDER BY id DESC LIMIT ?",e).map(s=>{let i=JSON.parse(s.analysis);return{id:s.id,commitHash:s.commit_hash,status:s.status,analyzedAt:s.analyzed_at,patternCount:i.patterns.length}})}},fn=new re,Cr=fn;var Ir={critical:0,high:1,medium:2,low:3},Dr={active:0,previously_active:1,backlog:2};function Lr(n){return[...n].sort((t,e)=>{let r=Dr[t.section]-Dr[e.section];return r!==0?r:Ir[t.priority]-Ir[e.priority]})}c(Lr,"sortBySectionAndPriority");var se=class extends z{static{c(this,"QueueStorage")}constructor(){super("queue.json",gr)}getDefault(){return{tasks:[],lastUpdated:""}}getEventType(t){return`queue.${t}d`}async getTasks(t){return(await this.read(t)).tasks}async getActiveTasks(t){return(await this.read(t)).tasks.filter(r=>r.section==="active"&&!r.completed)}async getBacklog(t){return(await this.read(t)).tasks.filter(r=>r.section==="backlog"&&!r.completed)}async getNextTask(t){let e=await this.getActiveTasks(t);return Lr(e)[0]||null}async addTask(t,e){let r={...e,id:F(),createdAt:f(),completed:!1};return await this.update(t,s=>({tasks:[...s.tasks,r],lastUpdated:f()})),await this.publishEvent(t,"queue.task_added",{taskId:r.id,description:r.description,priority:r.priority,section:r.section}),r}async addTasks(t,e){let r=f(),s=e.map(i=>({...i,id:F(),createdAt:r,completed:!1}));return await this.update(t,i=>({tasks:[...i.tasks,...s],lastUpdated:r})),await this.publishEvent(t,"queue.tasks_added",{count:s.length,tasks:s.map(i=>({id:i.id,description:i.description}))}),s}async removeTask(t,e){await this.update(t,r=>({tasks:r.tasks.filter(s=>s.id!==e),lastUpdated:f()})),await this.publishEvent(t,"queue.task_removed",{taskId:e})}async completeTask(t,e){let r=null;if(await this.update(t,s=>({tasks:s.tasks.map(o=>o.id===e?(r={...o,completed:!0,completedAt:f()},r):o),lastUpdated:f()})),r){let s=r;await this.publishEvent(t,"queue.task_completed",{taskId:e,description:s.description,completedAt:s.completedAt})}return r}async moveToSection(t,e,r){await this.update(t,s=>({tasks:s.tasks.map(i=>i.id===e?{...i,section:r}:i),lastUpdated:f()}))}async setPriority(t,e,r){await this.update(t,s=>({tasks:s.tasks.map(i=>i.id===e?{...i,priority:r}:i),lastUpdated:f()}))}async getTask(t,e){return(await this.read(t)).tasks.find(s=>s.id===e)||null}async updateTask(t,e,r){let s=null;return await this.update(t,i=>({tasks:i.tasks.map(o=>o.id===e?(s={...o,...r},s):o),lastUpdated:f()})),s&&await this.publishEvent(t,"queue.task_updated",{taskId:e}),s}async clearCompleted(t){let r=(await this.read(t)).tasks.filter(s=>s.completed).length;return await this.update(t,s=>({tasks:s.tasks.filter(i=>!i.completed),lastUpdated:f()})),r}async removeStaleCompleted(t){let e=await this.read(t),r=fe(rt.QUEUE_COMPLETED_DAYS),s=e.tasks.filter(o=>o.completed&&o.completedAt&&new Date(o.completedAt)<r);if(s.length===0)return 0;Y.archiveMany(t,s.map(o=>({entityType:"queue_task",entityId:o.id,entityData:o,summary:o.description,reason:"age"})));let i=new Set(s.map(o=>o.id));return await this.update(t,o=>({tasks:o.tasks.filter(a=>!i.has(a.id)),lastUpdated:f()})),await this.publishEvent(t,"queue.stale_removed",{count:s.length}),s.length}},Or=new se;function Mr(n){let t=n;t.tool("prjct_task_status","Current task, duration, subtasks, and queue",{projectPath:ne.string().describe("Project directory path")},b("prjct_task_status",async e=>{let r=await v(e.projectPath),s=await J.getCurrentTask(r),i=await Or.getActiveTasks(r),o=[];if(s?(o.push(`## Active Task
525
+ **${s.description}**`),s.branch&&o.push(`Branch: ${s.branch}`),o.push(`Started: ${s.startedAt}`)):o.push("No active task."),i.length>0){o.push(`
526
+ ## Queue (${i.length} tasks)`);for(let a of i.slice(0,10))o.push(`- ${a.description} [${a.priority||"medium"}]`)}return{content:[{type:"text",text:o.join(`
527
+ `)}]}})),t.tool("prjct_analysis","LLM analysis: stack, patterns, anti-patterns, conventions",{projectPath:ne.string().describe("Project directory path")},b("prjct_analysis",async e=>{let r=await v(e.projectPath),s=Cr.getActive(r);if(!s)return{content:[{type:"text",text:"No analysis available. Run `prjct sync`."}]};let i=["## Project Analysis"];if(s.stack&&(i.push(`
528
+ ### Stack`),s.stack.languages?.length&&i.push(`Languages: ${s.stack.languages.join(", ")}`),s.stack.frameworks?.length&&i.push(`Frameworks: ${s.stack.frameworks.join(", ")}`),s.stack.packageManager&&i.push(`Package Manager: ${s.stack.packageManager}`)),s.patterns?.length){i.push(`
529
+ ### Patterns (${s.patterns.length})`);for(let o of s.patterns)i.push(`- **${o.name}**: ${o.description}`)}if(s.antiPatterns?.length){i.push(`
530
+ ### Anti-Patterns (${s.antiPatterns.length})`);for(let o of s.antiPatterns)i.push(`- **${o.issue}**: ${o.suggestion}`)}if(s.conventions?.length){i.push(`
531
+ ### Conventions (${s.conventions.length})`);for(let o of s.conventions)i.push(`- [${o.category}] ${o.rule}`)}return{content:[{type:"text",text:i.join(`
532
+ `)}]}})),t.tool("prjct_patterns","Project memory grouped by type (decision / pattern / anti-pattern / gotcha). Powered by projectMemory \u2014 same source the CLI memory verbs read.",{projectPath:ne.string().describe("Project directory path")},b("prjct_patterns",async e=>{let r=await v(e.projectPath),s=G.recall(r,{types:["decision","pattern","anti-pattern","gotcha"],limit:50});return s.length===0?{content:[{type:"text",text:"No decisions or patterns captured yet."}]}:{content:[{type:"text",text:st(s)}]}}))}c(Mr,"registerProjectTools");import{z as kt}from"zod";var ie=class{static{c(this,"CustomWorkflowStorage")}createWorkflow(t,e){let r=new Date().toISOString();E.run(t,`INSERT INTO custom_workflows (name, description, created_at, updated_at, is_builtin, enabled, metadata)
533
+ VALUES (?, ?, ?, ?, 0, 1, ?)`,e.name,e.description??null,r,r,e.metadata?JSON.stringify(e.metadata):null);let s=E.get(t,"SELECT id FROM custom_workflows WHERE name = ?",e.name);if(!s)throw new Error(`Failed to create workflow: ${e.name}`);return s.id}getWorkflow(t,e){let r=E.get(t,"SELECT * FROM custom_workflows WHERE name = ?",e);return r?this.rowToWorkflow(r):null}getAllWorkflows(t,e=!1){let r=e?"SELECT * FROM custom_workflows ORDER BY is_builtin DESC, name ASC":"SELECT * FROM custom_workflows WHERE enabled = 1 ORDER BY is_builtin DESC, name ASC";return E.query(t,r).map(i=>this.rowToWorkflow(i))}updateWorkflow(t,e,r){if(!this.getWorkflow(t,e))return!1;let i=new Date().toISOString(),o=[],a=[];return r.description!==void 0&&(o.push("description = ?"),a.push(r.description)),r.enabled!==void 0&&(o.push("enabled = ?"),a.push(r.enabled?1:0)),r.metadata!==void 0&&(o.push("metadata = ?"),a.push(JSON.stringify(r.metadata))),o.length===0?!1:(o.push("updated_at = ?"),a.push(i),a.push(e),E.run(t,`UPDATE custom_workflows SET ${o.join(", ")} WHERE name = ?`,...a),!0)}deleteWorkflow(t,e){let r=this.getWorkflow(t,e);if(!r)return!1;if(r.isBuiltin)throw new Error(`Cannot delete built-in workflow: ${e}`);return E.run(t,"UPDATE custom_workflows SET enabled = 0 WHERE name = ?",e),!0}isBuiltin(t,e){return this.getWorkflow(t,e)?.isBuiltin??!1}isReservedName(t){let e=["task","done","ship","sync"],r=["add","rm","gate","list","create","delete","run","help","reset","init"];return e.includes(t)||r.includes(t)}isValidName(t){return/^[a-z0-9-]+$/.test(t)}rowToWorkflow(t){return{id:t.id,name:t.name,description:t.description,createdAt:t.created_at,updatedAt:t.updated_at,isBuiltin:t.is_builtin===1,enabled:t.enabled===1,metadata:t.metadata?JSON.parse(t.metadata):null}}},Et=new ie;function oe(n){let t=n.trust_source==="imported"?"imported":"local";return{id:n.id,type:n.type,command:n.command,position:n.position,action:n.action,description:n.description,enabled:n.enabled===1,timeoutMs:n.timeout_ms,createdAt:n.created_at,sortOrder:n.sort_order,whenExpr:n.when_expr??null,parallel:n.parallel===null?!0:n.parallel===1,trustSource:t}}c(oe,"rowToRule");var ae=class{static{c(this,"WorkflowRuleStorage")}addRule(t,e){let r=y.get(t,"SELECT MAX(sort_order) as m FROM workflow_rules WHERE command = ?",e.command),s=e.sortOrder||(r?.m??-1)+1;return y.run(t,`INSERT INTO workflow_rules (type, command, position, action, description, enabled, timeout_ms, created_at, sort_order, when_expr, parallel, trust_source)
534
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,e.type,e.command,e.position,e.action,e.description??null,e.enabled?1:0,e.timeoutMs,e.createdAt,s,e.whenExpr??null,e.parallel===!1?0:1,e.trustSource??"local"),y.get(t,"SELECT last_insert_rowid() as id")?.id??0}removeRule(t,e){return y.get(t,"SELECT id FROM workflow_rules WHERE id = ?",e)?(y.run(t,"DELETE FROM workflow_rules WHERE id = ?",e),!0):!1}updateRule(t,e,r){if(!y.get(t,"SELECT id FROM workflow_rules WHERE id = ?",e))return!1;let i={type:{column:"type"},command:{column:"command"},position:{column:"position"},action:{column:"action"},description:{column:"description"},enabled:{column:"enabled",transform:c(u=>u?1:0,"transform")},timeoutMs:{column:"timeout_ms"},createdAt:{column:"created_at"},sortOrder:{column:"sort_order"},whenExpr:{column:"when_expr"},parallel:{column:"parallel",transform:c(u=>u===!1?0:1,"transform")},trustSource:{column:"trust_source"}},o=[],a=[];for(let[u,d]of Object.entries(r)){let m=i[u];if(!m)continue;o.push(`${m.column} = ?`);let p=d;a.push(m.transform?m.transform(p):p)}return o.length===0||(a.push(e),y.run(t,`UPDATE workflow_rules SET ${o.join(", ")} WHERE id = ?`,...a)),!0}getRuleById(t,e){let r=y.get(t,"SELECT * FROM workflow_rules WHERE id = ?",e);return r?oe(r):null}getRulesForCommand(t,e){let r=Et.getWorkflow(t,e);return!r||!r.enabled?[]:y.query(t,"SELECT * FROM workflow_rules WHERE command = ? AND enabled = 1 ORDER BY sort_order ASC",e).map(oe)}getAllRules(t){return y.query(t,"SELECT * FROM workflow_rules ORDER BY command ASC, sort_order ASC").map(oe)}resetRules(t){let e=y.get(t,"SELECT COUNT(*) as c FROM workflow_rules");return y.run(t,"DELETE FROM workflow_rules"),e?.c??0}},ce=new ae;function jr(n){let t=n;t.tool("prjct_workflow_rules","Get workflow rules for a command (gates, hooks, steps, instructions)",{projectPath:kt.string().describe("Project directory path"),command:kt.string().describe("Command name (task, done, ship, sync, etc.)")},b("prjct_workflow_rules",async e=>{let r=await v(e.projectPath),s=ce.getRulesForCommand(r,e.command);if(s.length===0)return{content:[{type:"text",text:`No workflow rules for \`${e.command}\`.`}]};let i={};for(let a of s){let u=`${a.type}:${a.position}`;i[u]||(i[u]=[]),i[u].push(a)}let o=[`## Workflow Rules for \`${e.command}\``];for(let[a,u]of Object.entries(i)){o.push(`
535
+ ### ${a}`);for(let d of u){let m=d.enabled?"":" (disabled)";o.push(`- ${d.action}${d.description?` \u2014 ${d.description}`:""}${m}`)}}return{content:[{type:"text",text:o.join(`
536
+ `)}]}})),t.tool("prjct_workflow_list","List all workflows for this project (built-in + custom)",{projectPath:kt.string().describe("Project directory path")},b("prjct_workflow_list",async e=>{let r=await v(e.projectPath),s=Et.getAllWorkflows(r);if(s.length===0)return{content:[{type:"text",text:"No workflows configured."}]};let i=s.map(o=>{let a=o.isBuiltin?"(built-in)":"(custom)",u=o.enabled?"":" [disabled]";return`- **${o.name}** ${a}${u}${o.description?`: ${o.description}`:""}`});return{content:[{type:"text",text:`## Workflows (${s.length})
537
+
538
+ ${i.join(`
539
+ `)}`}]}})),t.tool("prjct_workflow_status","Current workflow execution state + active rules",{projectPath:kt.string().describe("Project directory path")},b("prjct_workflow_status",async e=>{let r=await v(e.projectPath),s=await J.getCurrentTask(r),i=ce.getAllRules(r),o=["## Workflow Status"];s?(o.push(`
540
+ Active task: **${s.description}**`),o.push(`Started: ${s.startedAt}`)):o.push(`
541
+ No active task.`);let a=i.filter(u=>u.enabled);if(a.length>0){o.push(`
542
+ ### Active Rules (${a.length})`);for(let u of a)o.push(`- [${u.type}] ${u.command}:${u.position} \u2192 ${u.action}`)}else o.push(`
543
+ No active workflow rules.`);return{content:[{type:"text",text:o.join(`
544
+ `)}]}}))}c(jr,"registerWorkflowTools");var Tn=`# prjct \u2014 persona-aware context broker
544
545
 
545
546
  Use when you want prior project memory, state, or a registered workflow. You decide whether any of it is relevant to the current turn.
546
547
 
@@ -555,4 +556,4 @@ Use when you want prior project memory, state, or a registered workflow. You dec
555
556
  - Memory is best-effort \u2014 never assume recall returned everything; it's a query, not a lookup.
556
557
  - Topic keys are free-form strings; don't invent new vocabularies when existing ones fit.
557
558
  - Not every project defines every memory type \u2014 if one is empty, that's fine.
558
- - Saving a secret-looking string is refused by default. Re-save with a scrubbed version.`;function Wr(){let n=new On({name:"prjct",version:"1.0.0"},{instructions:jn});return Lr(n),Xr(n),Pr(n),$r(n),pr(n),n}c(Wr,"createServer");async function Fn(){let n=Wr(),t=new Mn;await n.connect(t)}c(Fn,"main");Fn().catch(n=>{console.error("prjct MCP server failed:",n),process.exit(1)});
559
+ - Saving a secret-looking string is refused by default. Re-save with a scrubbed version.`;function Fr(){let n=new hn({name:"prjct",version:"1.0.0"},{instructions:Tn});return Nr(n),Mr(n),Sr(n),jr(n),ar(n),n}c(Fr,"createServer");async function En(){let n=Fr(),t=new yn;await n.connect(t)}c(En,"main");En().catch(n=>{console.error("prjct MCP server failed:",n),process.exit(1)});