prjct-cli 2.14.1 → 2.14.3

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,227 +5,227 @@ import { dirname as __pathDirname } from 'path';
5
5
  var require = __createRequire(import.meta.url);
6
6
  var __filename = __fileURLToPath(import.meta.url);
7
7
  var __dirname = __pathDirname(__filename);
8
- var at=Object.defineProperty;var Xr=Object.getOwnPropertyDescriptor;var $r=Object.getOwnPropertyNames;var Wr=Object.prototype.hasOwnProperty;var c=(n,t)=>at(n,"name",{value:t,configurable:!0}),ge=(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 N=(n,t)=>()=>(n&&(t=n(n=0)),t);var fe=(n,t)=>{for(var e in t)at(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&&at(n,s,{get:()=>t[s],enumerable:!(r=Xr(t,s))||r.enumerable});return n};var vt=n=>Gr(at({},"__esModule",{value:!0}),n);var he,Te,ye,_t=N(()=>{"use strict";he=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"]),Te=["",".ts",".tsx",".js",".jsx","/index.ts","/index.js"],ye=/(?:import|from)\s+['"]([^'"]+)['"]/g});function Hr(n){return n instanceof Error&&"code"in n}function R(n){return Hr(n)&&n.code==="ENOENT"}function we(n){return n instanceof Error?n.message:typeof n=="string"?n:"Unknown error"}var U=N(()=>{"use strict";c(Hr,"isNodeError");c(R,"isNotFoundError");c(we,"getErrorMessage")});import ve from"node:fs/promises";async function _e(n,t){let e;try{e=await ve.readFile(n,"utf-8")}catch(i){if(R(i))return null;throw i}let r;try{r=JSON.parse(e)}catch{return await be(n,e),Se(n,"Malformed JSON"),null}let s=t.safeParse(r);return s.success?r:(await be(n,e),Se(n,qr(s.error)),null)}async function be(n,t){let e=`${n}.backup`;try{await ve.writeFile(e,t,"utf-8")}catch{}}function Se(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 xe=N(()=>{"use strict";U();c(_e,"safeRead");c(be,"createBackup");c(Se,"logCorruption");c(qr,"formatZodError")});import X from"node:fs/promises";import xt from"node:path";async function Pe(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(he.has(d)||t.skipDotfiles&&d.startsWith(".")&&(!s||!s.has(d)))continue;let m=xt.join(o,d);u.isDirectory()?await i(m):u.isFile()&&e.push(xt.relative(n,m))}}return c(i,"walk"),await i(n),e}async function Re(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 ct(n,t=null,e){if(e)return await _e(n,e)??t;try{let r=await X.readFile(n,"utf-8");return JSON.parse(r)}catch(r){if(R(r))return t;throw r}}async function L(n,t,e=2){let r=xt.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(R(t))return!1;throw t}}async function Pt(n){try{return(await X.stat(n)).isDirectory()}catch(t){if(R(t))return!1;throw t}}async function O(n){await X.mkdir(n,{recursive:!0})}var M=N(()=>{"use strict";_t();xe();U();c(Pe,"walkDir");c(Re,"batchProcess");c(ct,"readJson");c(L,"writeJson");c(_,"fileExists");c(Pt,"dirExists");c(O,"ensureDir")});var Ne=N(()=>{"use strict"});import{z as Z}from"zod";function Ce(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 Rt,At=N(()=>{"use strict";Rt=Z.object({provider:Z.string(),model:Z.string(),cliVersion:Z.string().optional(),recordedAt:Z.string()});c(Ce,"compareSemver")});import{exec as Yr,execFile as zr}from"node:child_process";import{promisify as Ie}from"node:util";var k,qn,B=N(()=>{"use strict";k=Ie(Yr),qn=Ie(zr)});function De(n,t){let e=typeof n=="string"?new Date(n).getTime():n;return Date.now()-e>t}var ut,Nt=N(()=>{"use strict";c(De,"isExpired");ut=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 Le from"node:path";async function Me(){try{let n=await Jr.readFile(Oe,"utf-8"),t=JSON.parse(n);return!t.timestamp||!t.detection||!t.detection.claude||!t.detection.gemini||!t.detection.codex||De(t.timestamp,Qr)?null:t.detection}catch{return null}}async function je(n){let t={timestamp:new Date().toISOString(),detection:n};await L(Oe,t)}var Vr,Oe,Qr,Fe=N(()=>{"use strict";Nt();M();Vr=Le.join(Kr.homedir(),".prjct-cli","cache"),Oe=Le.join(Vr,"providers.json"),Qr=10*60*1e3;c(Me,"readProviderCache");c(je,"writeProviderCache")});var dt={};fe(dt,{ClaudeProvider:()=>lt,CursorProvider:()=>$e,GeminiProvider:()=>It,Providers:()=>tt,detectAllProviders:()=>Dt,detectAntigravity:()=>ss,detectCodex:()=>He,detectProvider:()=>Ct,getActiveProvider:()=>es,getProviderBranding:()=>rs,selectProvider:()=>ns,validateCliVersion:()=>Be});import j from"node:os";import C from"node:path";async function Ge(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 Ct(n){let t=tt[n];if(!t.cliCommand)return{installed:!1};let e=await Ge(t.cliCommand);if(!e)return{installed:!1};let r=await ts(t.cliCommand),s=Be(n,r||void 0);return{installed:!0,version:r||void 0,path:e,versionWarning:s||void 0}}function Be(n,t){let e=tt[n];return!e.minCliVersion||!t?null:Ce(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 Dt(n=!1){if(!n){let o=await Me();if(o)return o}let[t,e,r]=await Promise.all([Ct("claude"),Ct("gemini"),He()]),s={installed:r.installed},i={claude:t,gemini:e,codex:s};return await je(i).catch(()=>{}),i}async function es(n){if(n&&tt[n])return tt[n];let t=await Dt();return t.claude.installed&&!t.gemini.installed?lt:t.gemini.installed&&!t.claude.installed?It:lt}function rs(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 ss(){let n=Xe.configDir;if(!n)return{installed:!1,skillInstalled:!1};let t=C.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 He(){let n=We.configDir;if(!n)return{installed:!1,skillInstalled:!1};let t=await Ge("codex"),e=C.join(n,"skills","prjct","SKILL.md"),r=await _(e),s=!!t;return{installed:s,skillInstalled:r,configPath:s?n:void 0}}async function ns(){let n=await Dt(),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 lt,It,Xe,$e,Zr,We,tt,pt=N(()=>{"use strict";Ne();At();B();M();Fe();lt={name:"claude",displayName:"Claude Code",cliCommand:"claude",configDir:C.join(j.homedir(),".claude"),contextFile:"CLAUDE.md",skillsDir:C.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"},It={name:"gemini",displayName:"Gemini CLI",cliCommand:"gemini",configDir:C.join(j.homedir(),".gemini"),contextFile:"GEMINI.md",skillsDir:C.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"},Xe={name:"antigravity",displayName:"Google Antigravity",cliCommand:null,configDir:C.join(j.homedir(),".gemini","antigravity"),contextFile:"ANTIGRAVITY.md",skillsDir:C.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"},$e={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"},We={name:"codex",displayName:"OpenAI Codex",cliCommand:"codex",configDir:C.join(j.homedir(),".codex"),contextFile:"AGENTS.md",skillsDir:C.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"},tt={claude:lt,gemini:It,cursor:$e,antigravity:Xe,windsurf:Zr,codex:We};c(Ge,"whichCommand");c(ts,"getCliVersion");c(Ct,"detectProvider");c(Be,"validateCliVersion");c(Dt,"detectAllProviders");c(es,"getActiveProvider");c(rs,"getProviderBranding");c(ss,"detectAntigravity");c(He,"detectCodex");c(ns,"selectProvider")});var Mt={};fe(Mt,{default:()=>is,worktreeService:()=>Ye});import Lt from"node:fs/promises";import I from"node:path";var qe,Ot,Ye,is,jt=N(()=>{"use strict";B();M();qe=".worktrees",Ot=class{static{c(this,"WorktreeService")}async create(t,e,r={}){let s=await this.getMainWorktree(t),i=I.join(s,qe,e),o=r.branch||`feat/${e}`;await Lt.mkdir(I.join(s,qe),{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 Lt.copyFile(r,I.join(t,".env"));let s=I.join(e,".prjct"),i=I.join(t,".prjct");await _(s)&&!await _(i)&&await Lt.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(`
11
-
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}},Ye=new Ot,is=Ye});import{StdioServerTransport as kn}from"@modelcontextprotocol/sdk/server/stdio.js";import{McpServer as yn}from"@modelcontextprotocol/sdk/server/mcp.js";import{z as P}from"zod";_t();import Ke from"node:fs/promises";import q from"node:path";import Ut from"node:fs";import Je from"node:path";import os from"node:crypto";import D from"node:fs/promises";import H from"node:os";import h from"node:path";import{globSync as as}from"glob";import{formatDistanceToNowStrict as xn}from"date-fns";function Ee(n){return{year:n.getFullYear().toString(),month:(n.getMonth()+1).toString().padStart(2,"0"),day:n.getDate().toString().padStart(2,"0")}}c(Ee,"getYearMonthDay");function f(){return new Date().toISOString()}c(f,"getTimestamp");function ke(n){let t=new Date;return t.setDate(t.getDate()-n),t}c(ke,"getDaysAgo");M();var Ft=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 os.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 Pt(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}=Ee(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 D.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 D.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 D.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 D.readdir(this.globalProjectsDir,{withFileTypes:!0})).filter(e=>e.isDirectory()).map(e=>e.name)}catch{return[]}}async projectExists(t){let e=this.getGlobalProjectPath(t);return await Pt(e)}getDisplayPath(t){let e=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(pt(),vt(dt)).getActiveProvider()).configDir}async getAgentSettingsPath(){let t=await(pt(),vt(dt)).getActiveProvider();return(pt(),vt(dt)).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")}async getWikiPath(t,e){if(e&&e.trim().length>0)return this.resolveVaultOverride(t,e);let r=await this.resolveProjectRootPath(t),i=h.basename(h.resolve(r)).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"project";return h.join(H.homedir(),"Documents","prjct",i)}async resolveProjectRootPath(t){try{let{worktreeService:e}=await Promise.resolve().then(()=>(jt(),Mt));return await e.detect(t)&&await e.getMainWorktree(t)||t}catch{return t}}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 D.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 D.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 D.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 D.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 D.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=as(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 D.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}},cs=new Ft,w=cs;function us(){return typeof globalThis<"u"&&"Bun"in globalThis?"bun":"node"}c(us,"detectRuntime");function ze(){return us()==="bun"}c(ze,"isBun");function ls(n){if(ze()){let{Database:s}=ge("bun:sqlite");return new s(n,{create:!0})}let t=ge("better-sqlite3"),e=new t(n),r=e.exec.bind(e);return e.run=s=>r(s),e}c(ls,"openDatabase");var ds=[{version:1,name:"initial-schema",up:c(n=>{n.run(`
15
- -- =======================================================================
16
- -- Document storage (backward-compatible with JSON file pattern)
17
- -- =======================================================================
18
- -- Each row replaces one JSON file (state.json, queue.json, etc.)
19
- -- StorageManager reads/writes entire documents via key lookup.
20
- CREATE TABLE kv_store (
21
- key TEXT PRIMARY KEY,
22
- data TEXT NOT NULL,
23
- updated_at TEXT NOT NULL
24
- );
25
-
26
- -- =======================================================================
27
- -- Normalized: Tasks
28
- -- =======================================================================
29
- CREATE TABLE tasks (
30
- id TEXT PRIMARY KEY,
31
- description TEXT NOT NULL,
32
- type TEXT,
33
- status TEXT NOT NULL,
34
- parent_description TEXT,
35
- branch TEXT,
36
- linear_id TEXT,
37
- linear_uuid TEXT,
38
- session_id TEXT,
39
- feature_id TEXT,
40
- started_at TEXT NOT NULL,
41
- completed_at TEXT,
42
- shipped_at TEXT,
43
- paused_at TEXT,
44
- pause_reason TEXT,
45
- pr_url TEXT,
46
- expected_value TEXT,
47
- data TEXT
48
- );
49
-
50
- CREATE INDEX idx_tasks_status ON tasks(status);
51
- CREATE INDEX idx_tasks_type ON tasks(type);
52
- CREATE INDEX idx_tasks_branch ON tasks(branch);
53
- CREATE INDEX idx_tasks_linear_id ON tasks(linear_id);
54
-
55
- -- =======================================================================
56
- -- Normalized: Subtasks
57
- -- =======================================================================
58
- CREATE TABLE subtasks (
59
- id TEXT PRIMARY KEY,
60
- task_id TEXT NOT NULL,
61
- description TEXT NOT NULL,
62
- status TEXT NOT NULL,
63
- domain TEXT,
64
- agent TEXT,
65
- sort_order INTEGER NOT NULL,
66
- depends_on TEXT,
67
- started_at TEXT,
68
- completed_at TEXT,
69
- output TEXT,
70
- summary TEXT,
71
- FOREIGN KEY (task_id) REFERENCES tasks(id)
72
- );
73
-
74
- CREATE INDEX idx_subtasks_task_id ON subtasks(task_id);
75
- CREATE INDEX idx_subtasks_status ON subtasks(status);
76
-
77
- -- =======================================================================
78
- -- Normalized: Queue Tasks
79
- -- =======================================================================
80
- CREATE TABLE queue_tasks (
81
- id TEXT PRIMARY KEY,
82
- description TEXT NOT NULL,
83
- type TEXT,
84
- priority TEXT,
85
- section TEXT,
86
- created_at TEXT NOT NULL,
87
- completed INTEGER DEFAULT 0,
88
- completed_at TEXT,
89
- feature_id TEXT,
90
- feature_name TEXT
91
- );
92
-
93
- CREATE INDEX idx_queue_tasks_section ON queue_tasks(section);
94
- CREATE INDEX idx_queue_tasks_priority ON queue_tasks(priority);
95
- CREATE INDEX idx_queue_tasks_completed ON queue_tasks(completed);
96
-
97
- -- =======================================================================
98
- -- Normalized: Ideas
99
- -- =======================================================================
100
- CREATE TABLE ideas (
101
- id TEXT PRIMARY KEY,
102
- text TEXT NOT NULL,
103
- status TEXT NOT NULL DEFAULT 'pending',
104
- priority TEXT NOT NULL DEFAULT 'medium',
105
- tags TEXT,
106
- added_at TEXT NOT NULL,
107
- converted_to TEXT,
108
- details TEXT,
109
- data TEXT
110
- );
111
-
112
- CREATE INDEX idx_ideas_status ON ideas(status);
113
- CREATE INDEX idx_ideas_priority ON ideas(priority);
114
-
115
- -- =======================================================================
116
- -- Normalized: Shipped Features
117
- -- =======================================================================
118
- CREATE TABLE shipped_features (
119
- id TEXT PRIMARY KEY,
120
- name TEXT NOT NULL,
121
- shipped_at TEXT NOT NULL,
122
- version TEXT NOT NULL,
123
- description TEXT,
124
- type TEXT,
125
- duration TEXT,
126
- data TEXT
127
- );
128
-
129
- CREATE INDEX idx_shipped_version ON shipped_features(version);
130
- CREATE INDEX idx_shipped_at ON shipped_features(shipped_at);
131
-
132
- -- =======================================================================
133
- -- Events (replaces events.jsonl)
134
- -- =======================================================================
135
- CREATE TABLE events (
136
- id INTEGER PRIMARY KEY AUTOINCREMENT,
137
- type TEXT NOT NULL,
138
- task_id TEXT,
139
- data TEXT,
140
- timestamp TEXT NOT NULL
141
- );
142
-
143
- CREATE INDEX idx_events_type ON events(type);
144
- CREATE INDEX idx_events_task_id ON events(task_id);
145
- CREATE INDEX idx_events_timestamp ON events(timestamp);
146
-
147
- -- =======================================================================
148
- -- Analysis (draft + sealed)
149
- -- =======================================================================
150
- CREATE TABLE analysis (
151
- id TEXT PRIMARY KEY,
152
- status TEXT NOT NULL,
153
- commit_hash TEXT,
154
- signature TEXT,
155
- sealed_at TEXT,
156
- analyzed_at TEXT,
157
- data TEXT NOT NULL
158
- );
159
-
160
- -- =======================================================================
161
- -- Index: File scores and checksums
162
- -- =======================================================================
163
- CREATE TABLE index_files (
164
- path TEXT PRIMARY KEY,
165
- score REAL,
166
- size INTEGER,
167
- mtime TEXT,
168
- language TEXT,
169
- categories TEXT,
170
- domain TEXT
171
- );
172
-
173
- CREATE INDEX idx_index_files_domain ON index_files(domain);
174
- CREATE INDEX idx_index_files_score ON index_files(score);
175
-
176
- CREATE TABLE index_checksums (
177
- path TEXT PRIMARY KEY,
178
- checksum TEXT NOT NULL,
179
- size INTEGER,
180
- mtime TEXT
181
- );
182
-
183
- -- =======================================================================
184
- -- Index: Metadata (project-index, domains, categories-cache)
185
- -- =======================================================================
186
- CREATE TABLE index_meta (
187
- key TEXT PRIMARY KEY,
188
- data TEXT NOT NULL,
189
- updated_at TEXT NOT NULL
190
- );
191
-
192
- -- =======================================================================
193
- -- Memory (key-value with domain tagging)
194
- -- =======================================================================
195
- CREATE TABLE memory (
196
- key TEXT PRIMARY KEY,
197
- domain TEXT,
198
- value TEXT,
199
- confidence REAL DEFAULT 1.0,
200
- updated_at TEXT NOT NULL
201
- );
202
-
203
- CREATE INDEX idx_memory_domain ON memory(domain);
204
-
205
- -- =======================================================================
206
- -- Metrics: Daily stats for trend analysis
207
- -- =======================================================================
208
- CREATE TABLE metrics_daily (
209
- date TEXT PRIMARY KEY,
210
- tokens_saved INTEGER NOT NULL DEFAULT 0,
211
- syncs INTEGER NOT NULL DEFAULT 0,
212
- avg_compression_rate REAL NOT NULL DEFAULT 0,
213
- total_duration INTEGER NOT NULL DEFAULT 0
214
- );
215
-
216
- -- =======================================================================
217
- -- Velocity: Sprint data
218
- -- =======================================================================
219
- CREATE TABLE velocity_sprints (
220
- sprint_number INTEGER PRIMARY KEY,
221
- points_completed REAL NOT NULL DEFAULT 0,
222
- tasks_completed INTEGER NOT NULL DEFAULT 0,
223
- estimation_accuracy REAL NOT NULL DEFAULT 0,
224
- avg_variance REAL NOT NULL DEFAULT 0,
225
- started_at TEXT,
226
- ended_at TEXT
227
- );
228
- `)},"up")},{version:2,name:"archives-table",up:c(n=>{n.run(`
8
+ var ct=Object.defineProperty;var Ms=Object.getOwnPropertyDescriptor;var js=Object.getOwnPropertyNames;var Fs=Object.prototype.hasOwnProperty;var c=(s,t)=>ct(s,"name",{value:t,configurable:!0}),Se=(s=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(s,{get:(t,e)=>(typeof require<"u"?require:t)[e]}):s)(function(s){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+s+'" is not supported')});var C=(s,t)=>()=>(s&&(t=s(s=0)),t);var xe=(s,t)=>{for(var e in t)ct(s,e,{get:t[e],enumerable:!0})},Us=(s,t,e,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of js(t))!Fs.call(s,n)&&n!==e&&ct(s,n,{get:()=>t[n],enumerable:!(r=Ms(t,n))||r.enumerable});return s};var Pt=s=>Us(ct({},"__esModule",{value:!0}),s);var ve,Pe,_e,_t=C(()=>{"use strict";ve=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"],_e=/(?:import|from)\s+['"]([^'"]+)['"]/g});function Ws(s){return s instanceof Error&&"code"in s}function A(s){return Ws(s)&&s.code==="ENOENT"}function Ne(s){return s instanceof Error?s.message:typeof s=="string"?s:"Unknown error"}var X=C(()=>{"use strict";c(Ws,"isNodeError");c(A,"isNotFoundError");c(Ne,"getErrorMessage")});import De from"node:fs/promises";async function Le(s,t){let e;try{e=await De.readFile(s,"utf-8")}catch(o){if(A(o))return null;throw o}let r;try{r=JSON.parse(e)}catch{return await Ce(s,e),Ie(s,"Malformed JSON"),null}let n=t.safeParse(r);return n.success?r:(await Ce(s,e),Ie(s,$s(n.error)),null)}async function Ce(s,t){let e=`${s}.backup`;try{await De.writeFile(e,t,"utf-8")}catch{}}function Ie(s,t){console.error(`[prjct] Warning: Corrupted storage file: ${s}`),console.error(`[prjct] Reason: ${t}`),console.error("[prjct] A .backup file has been created. Returning defaults.")}function $s(s){return s.issues.slice(0,3).map(t=>`${t.path.join(".")}: ${t.message}`).join("; ")}var Oe=C(()=>{"use strict";X();c(Le,"safeRead");c(Ce,"createBackup");c(Ie,"logCorruption");c($s,"formatZodError")});import W from"node:fs/promises";import Rt from"node:path";async function Me(s,t={}){let e=[],r=t.maxFiles??1/0,n=t.dotfileAllowlist?new Set(t.dotfileAllowlist):null;async function o(i){if(e.length>=r)return;let a=await W.readdir(i,{withFileTypes:!0}).catch(()=>[]);for(let u of a){if(e.length>=r)break;let p=String(u.name);if(ve.has(p)||t.skipDotfiles&&p.startsWith(".")&&(!n||!n.has(p)))continue;let m=Rt.join(i,p);u.isDirectory()?await o(m):u.isFile()&&e.push(Rt.relative(s,m))}}return c(o,"walk"),await o(s),e}async function je(s,t,e){let r=[];for(let n=0;n<s.length;n+=t){let o=await Promise.all(s.slice(n,n+t).map(e));for(let i of o)i!==null&&r.push(i)}return r}async function ut(s,t=null,e){if(e)return await Le(s,e)??t;try{let r=await W.readFile(s,"utf-8");return JSON.parse(r)}catch(r){if(A(r))return t;throw r}}async function O(s,t,e=2){let r=Rt.dirname(s);await W.mkdir(r,{recursive:!0});let n=`${JSON.stringify(t,null,e)}
9
+ `;await W.writeFile(s,n,"utf-8")}async function v(s){try{return await W.access(s),!0}catch(t){if(A(t))return!1;throw t}}async function At(s){try{return(await W.stat(s)).isDirectory()}catch(t){if(A(t))return!1;throw t}}async function j(s){await W.mkdir(s,{recursive:!0})}var M=C(()=>{"use strict";_t();Oe();X();c(Me,"walkDir");c(je,"batchProcess");c(ut,"readJson");c(O,"writeJson");c(v,"fileExists");c(At,"dirExists");c(j,"ensureDir")});import{exec as Hs,execFile as Gs}from"node:child_process";import{promisify as Xe}from"node:util";var E,Go,q=C(()=>{"use strict";E=Xe(Hs),Go=Xe(Gs)});var Ot={};xe(Ot,{default:()=>qs,worktreeService:()=>$e});import Dt from"node:fs/promises";import I from"node:path";var We,Lt,$e,qs,Mt=C(()=>{"use strict";q();M();We=".worktrees",Lt=class{static{c(this,"WorktreeService")}async create(t,e,r={}){let n=await this.getMainWorktree(t),o=I.join(n,We,e),i=r.branch||`feat/${e}`;await Dt.mkdir(I.join(n,We),{recursive:!0});let a=r.baseBranch?` ${r.baseBranch}`:"";await E(`git worktree add "${o}" -b "${i}"${a}`,{cwd:n});let{stdout:u}=await E("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),n;if(e)try{let{stdout:o}=await E("git rev-parse --abbrev-ref HEAD",{cwd:t});n=o.trim()}catch{}if(await E(`git worktree remove "${t}" --force`,{cwd:r}),e&&n&&n!=="main"&&n!=="master")try{await E(`git branch -D "${n}"`,{cwd:r})}catch{}}async list(t){let e=await this.getMainWorktree(t),{stdout:r}=await E("git worktree list --porcelain",{cwd:e});return this.parsePorcelainOutput(r,e)}async detect(t){try{let{stdout:e}=await E("git rev-parse --git-common-dir",{cwd:t}),{stdout:r}=await E("git rev-parse --git-dir",{cwd:t}),n=I.resolve(t,e.trim()),o=I.resolve(t,r.trim());if(n!==o){let{stdout:i}=await E("git rev-parse --abbrev-ref HEAD",{cwd:t}),{stdout:a}=await E("git rev-parse HEAD",{cwd:t}),{stdout:u}=await E("git rev-parse --show-toplevel",{cwd:t}),p=u.trim(),m=I.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 E("git worktree list --porcelain",{cwd:t}),n=r.split(`
10
+ `)[0];if(n?.startsWith("worktree "))return n.replace("worktree ","").trim()}catch{}let{stdout:e}=await E("git rev-parse --show-toplevel",{cwd:t});return e.trim()}async setup(t,e){let r=I.join(e,".env");await v(r)&&await Dt.copyFile(r,I.join(t,".env"));let n=I.join(e,".prjct"),o=I.join(t,".prjct");await v(n)&&!await v(o)&&await Dt.symlink(n,o,"dir")}async teardown(t){}async clean(t){let e=await this.list(t),r=[],n=await this.getMainWorktree(t);await E("git worktree prune",{cwd:n});for(let o of e)o.isMain||await v(o.path)||r.push(o.slug);return r}parsePorcelainOutput(t,e){let r=[],n=t.trim().split(`
11
+
12
+ `);for(let o of n){if(!o.trim())continue;let i=o.trim().split(`
13
+ `),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":I.basename(a)})}}return r}},$e=new Lt,qs=$e});var qe=C(()=>{"use strict"});import{z as tt}from"zod";function Je(s,t){let e=s.split(".").map(Number),r=t.split(".").map(Number);for(let n=0;n<3;n++){let o=e[n]??0,i=r[n]??0;if(o<i)return-1;if(o>i)return 1}return 0}var Ft,Ut=C(()=>{"use strict";Ft=tt.object({provider:tt.string(),model:tt.string(),cliVersion:tt.string().optional(),recordedAt:tt.string()});c(Je,"compareSemver")});function Ye(s,t){let e=typeof s=="string"?new Date(s).getTime():s;return Date.now()-e>t}var lt,Xt=C(()=>{"use strict";c(Ye,"isExpired");lt=class{static{c(this,"TTLCache")}cache=new Map;ttl;maxSize;constructor(t={}){this.ttl=t.ttl??5e3,this.maxSize=t.maxSize??50}isValid(t){let e=this.cache.get(t);return e?Date.now()-e.timestamp<this.ttl:!1}get(t){let e=this.cache.get(t);return e?this.isValid(t)?e.data:(this.cache.delete(t),null):null}set(t,e){this.cache.set(t,{data:e,timestamp:Date.now()}),this.evictOldEntries()}delete(t){this.cache.delete(t)}clear(){this.cache.clear()}has(t){return this.cache.has(t)}get size(){return this.cache.size}evictOldEntries(){if(this.cache.size<=this.maxSize)return;let e=Array.from(this.cache.entries()).sort((r,n)=>r[1].timestamp-n[1].timestamp).slice(0,this.cache.size-this.maxSize);for(let[r]of e)this.cache.delete(r)}stats(){return{size:this.cache.size,maxSize:this.maxSize,ttl:this.ttl}}prune(){let t=0;for(let e of this.cache.keys())this.isValid(e)||(this.cache.delete(e),t++);return t}}});import zs from"node:fs/promises";import Ks from"node:os";import ze from"node:path";async function Ve(){try{let s=await zs.readFile(Ke,"utf-8"),t=JSON.parse(s);return!t.timestamp||!t.detection||!t.detection.claude||!t.detection.gemini||!t.detection.codex||Ye(t.timestamp,Qs)?null:t.detection}catch{return null}}async function Qe(s){let t={timestamp:new Date().toISOString(),detection:s};await O(Ke,t)}var Vs,Ke,Qs,Ze=C(()=>{"use strict";Xt();M();Vs=ze.join(Ks.homedir(),".prjct-cli","cache"),Ke=ze.join(Vs,"providers.json"),Qs=10*60*1e3;c(Ve,"readProviderCache");c(Qe,"writeProviderCache")});var dt={};xe(dt,{ClaudeProvider:()=>pt,CursorProvider:()=>rr,GeminiProvider:()=>$t,Providers:()=>et,detectAllProviders:()=>Bt,detectAntigravity:()=>sn,detectCodex:()=>ir,detectProvider:()=>Wt,getActiveProvider:()=>en,getProviderBranding:()=>rn,selectProvider:()=>nn,validateCliVersion:()=>or});import F from"node:os";import L from"node:path";async function nr(s){try{let{stdout:t}=await E(`which ${s}`,{timeout:2e3});return t.trim()}catch{return null}}async function tn(s){try{let{stdout:t}=await E(`${s} --version`,{timeout:2e3}),e=t.match(/\d+\.\d+\.\d+/);return e?e[0]:t.trim()}catch{return null}}async function Wt(s){let t=et[s];if(!t.cliCommand)return{installed:!1};let e=await nr(t.cliCommand);if(!e)return{installed:!1};let r=await tn(t.cliCommand),n=or(s,r||void 0);return{installed:!0,version:r||void 0,path:e,versionWarning:n||void 0}}function or(s,t){let e=et[s];return!e.minCliVersion||!t?null:Je(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 Bt(s=!1){if(!s){let i=await Ve();if(i)return i}let[t,e,r]=await Promise.all([Wt("claude"),Wt("gemini"),ir()]),n={installed:r.installed},o={claude:t,gemini:e,codex:n};return await Qe(o).catch(()=>{}),o}async function en(s){if(s&&et[s])return et[s];let t=await Bt();return t.claude.installed&&!t.gemini.installed?pt:t.gemini.installed&&!t.claude.installed?$t:pt}function rn(s){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"}[s]||"\u26A1 prjct"}}async function sn(){let s=er.configDir;if(!s)return{installed:!1,skillInstalled:!1};let t=L.join(s,"skills","prjct","SKILL.md"),[e,r]=await Promise.all([v(s),v(t)]);return{installed:e,skillInstalled:r,configPath:e?s:void 0}}async function ir(){let s=sr.configDir;if(!s)return{installed:!1,skillInstalled:!1};let t=await nr("codex"),e=L.join(s,"skills","prjct","SKILL.md"),r=await v(e),n=!!t;return{installed:n,skillInstalled:r,configPath:n?s:void 0}}async function nn(){let s=await Bt(),t=s.claude.installed,e=s.gemini.installed;return!t&&!e?{provider:"claude",userSelected:!1,detection:s}:t&&!e?{provider:"claude",userSelected:!1,detection:s}:e&&!t?{provider:"gemini",userSelected:!1,detection:s}:{provider:"claude",userSelected:!0,detection:s}}var pt,$t,er,rr,Zs,sr,et,mt=C(()=>{"use strict";qe();Ut();q();M();Ze();pt={name:"claude",displayName:"Claude Code",cliCommand:"claude",configDir:L.join(F.homedir(),".claude"),contextFile:"CLAUDE.md",skillsDir:L.join(F.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"},$t={name:"gemini",displayName:"Gemini CLI",cliCommand:"gemini",configDir:L.join(F.homedir(),".gemini"),contextFile:"GEMINI.md",skillsDir:L.join(F.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"},er={name:"antigravity",displayName:"Google Antigravity",cliCommand:null,configDir:L.join(F.homedir(),".gemini","antigravity"),contextFile:"ANTIGRAVITY.md",skillsDir:L.join(F.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"},rr={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"},Zs={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"},sr={name:"codex",displayName:"OpenAI Codex",cliCommand:"codex",configDir:L.join(F.homedir(),".codex"),contextFile:"AGENTS.md",skillsDir:L.join(F.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"},et={claude:pt,gemini:$t,cursor:rr,antigravity:er,windsurf:Zs,codex:sr};c(nr,"whichCommand");c(tn,"getCliVersion");c(Wt,"detectProvider");c(or,"validateCliVersion");c(Bt,"detectAllProviders");c(en,"getActiveProvider");c(rn,"getProviderBranding");c(sn,"detectAntigravity");c(ir,"detectCodex");c(nn,"selectProvider")});import{StdioServerTransport as To}from"@modelcontextprotocol/sdk/server/stdio.js";import{McpServer as ho}from"@modelcontextprotocol/sdk/server/mcp.js";import{z as R}from"zod";_t();import dr from"node:fs/promises";import J from"node:path";import qt from"node:fs";import pr from"node:path";import on from"node:crypto";import gt from"node:fs/promises";import Ht from"node:os";import T from"node:path";import{formatDistanceToNowStrict as xo}from"date-fns";function Re(s){return{year:s.getFullYear().toString(),month:(s.getMonth()+1).toString().padStart(2,"0"),day:s.getDate().toString().padStart(2,"0")}}c(Re,"getYearMonthDay");function f(){return new Date().toISOString()}c(f,"getTimestamp");function Ae(s){let t=new Date;return t.setDate(t.getDate()-s),t}c(Ae,"getDaysAgo");M();M();import G from"node:fs/promises";import _ from"node:path";import{globSync as Bs}from"glob";async function Ct(s){let t={isMonorepo:!1,type:null,rootPath:s,packages:[]},e=[{file:"pnpm-workspace.yaml",type:"pnpm"},{file:"lerna.json",type:"lerna"},{file:"nx.json",type:"nx"},{file:"rush.json",type:"rush"},{file:"turbo.json",type:"turborepo"}];for(let r of e)if(await v(_.join(s,r.file))){t.isMonorepo=!0,t.type=r.type;break}if(!t.isMonorepo){let r=_.join(s,"package.json");if(await v(r))try{JSON.parse(await G.readFile(r,"utf-8")).workspaces&&(t.isMonorepo=!0,t.type="npm")}catch{}}return t.isMonorepo&&(t.packages=await It(s,t.type)),t}c(Ct,"detectMonorepo");async function It(s,t){let e=[],r=[];try{if(t==="pnpm"){let o=(await G.readFile(_.join(s,"pnpm-workspace.yaml"),"utf-8")).match(/packages:\s*\n((?:\s*-\s*.+\n?)+)/);o&&(r=o[1].split(`
14
+ `).map(i=>i.replace(/^\s*-\s*['"]?|['"]?\s*$/g,"")).filter(Boolean))}else if(t==="npm"||t==="lerna"){let n=_.join(s,"package.json"),o=JSON.parse(await G.readFile(n,"utf-8"));if(Array.isArray(o.workspaces)?r=o.workspaces:o.workspaces?.packages&&(r=o.workspaces.packages),t==="lerna"){let i=_.join(s,"lerna.json");if(await v(i)){let a=JSON.parse(await G.readFile(i,"utf-8"));a.packages&&(r=a.packages)}}}else if(t==="nx")r=["apps/*","libs/*","packages/*"];else if(t==="turborepo"){let n=_.join(s,"package.json"),o=JSON.parse(await G.readFile(n,"utf-8"));Array.isArray(o.workspaces)&&(r=o.workspaces)}r.length===0&&(r=["packages/*","apps/*","libs/*"]);for(let n of r){if(n.startsWith("!"))continue;let o=Bs(n,{cwd:s,absolute:!1});for(let i of o){let a=_.join(s,i),u=_.join(a,"package.json");if(await v(u))try{let p=JSON.parse(await G.readFile(u,"utf-8")),m=_.join(a,"PRJCT.md");e.push({name:p.name||_.basename(i),path:a,relativePath:i,hasPrjctMd:await v(m)})}catch{}}}}catch{}return e}c(It,"discoverMonorepoPackages");async function Fe(s,t){if(!t.isMonorepo)return null;let e=_.resolve(s);for(let r of t.packages){let n=_.resolve(r.path);if(e.startsWith(n))return r}return null}c(Fe,"findContainingPackage");async function Ue(s){let t=_.resolve(s),e=_.parse(t).root;for(;t!==e;){if((await Ct(t)).isMonorepo)return t;t=_.dirname(t)}return null}c(Ue,"findMonorepoRoot");import jt from"node:os";import D from"node:path";async function Be(s,t){if(t&&t.trim().length>0)return Ys(s,t);let e=await Js(s),n=D.basename(D.resolve(e)).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"project";return D.join(jt.homedir(),"Documents","prjct",n)}c(Be,"getWikiPath");function He(s,t){let r=D.basename(D.resolve(s)).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"project",n=t.replace(/-/g,"").slice(0,8);return D.join(jt.homedir(),"Documents","prjct",`${r}-${n}`)}c(He,"getWikiPathWithProjectHash");function Ge(s){return D.join(s,".prjct","wiki")}c(Ge,"getLegacyWikiPath");async function Js(s){try{let{worktreeService:t}=await Promise.resolve().then(()=>(Mt(),Ot));return await t.detect(s)&&await t.getMainWorktree(s)||s}catch{return s}}c(Js,"resolveProjectRootPath");function Ys(s,t){let e=t.trim();return(e.startsWith("~/")||e==="~")&&(e=D.join(jt.homedir(),e.slice(1))),D.isAbsolute(e)||(e=D.resolve(s,e)),e}c(Ys,"resolveVaultOverride");var Gt=class{static{c(this,"PathManager")}globalBaseDir;globalProjectsDir;globalConfigDir;constructor(){let t=process.env.PRJCT_CLI_HOME?.trim();this.globalBaseDir=t?T.resolve(t):T.join(Ht.homedir(),".prjct-cli"),this.globalProjectsDir=T.join(this.globalBaseDir,"projects"),this.globalConfigDir=T.join(this.globalBaseDir,"config")}setGlobalBaseDir(t){this.globalBaseDir=T.resolve(t),this.globalProjectsDir=T.join(this.globalBaseDir,"projects"),this.globalConfigDir=T.join(this.globalBaseDir,"config")}generateProjectId(t){return on.randomUUID()}getGlobalBasePath(){return this.globalBaseDir}getGlobalProjectPath(t){return T.join(this.globalProjectsDir,t)}getLocalConfigPath(t){return T.join(t,".prjct","prjct.config.json")}getGlobalProjectConfigPath(t){return T.join(this.getGlobalProjectPath(t),"project.json")}getLegacyPrjctPath(t){return T.join(t,".prjct")}async hasLegacyStructure(t){return await At(this.getLegacyPrjctPath(t))}async hasConfig(t){return await v(this.getLocalConfigPath(t))}async ensureGlobalStructure(){await j(this.globalBaseDir),await j(this.globalProjectsDir),await j(this.globalConfigDir)}async ensureProjectStructure(t){await this.ensureGlobalStructure();let e=this.getGlobalProjectPath(t),r=["core","progress","planning","analysis","memory"];for(let n of r)await j(T.join(e,n));return await j(T.join(e,"planning","tasks")),await j(T.join(e,"sessions")),e}getSessionPath(t,e=new Date){let{year:r,month:n,day:o}=Re(e);return T.join(this.getGlobalProjectPath(t),"sessions",r,n,o)}getCurrentSessionPath(t){return this.getSessionPath(t,new Date)}async ensureSessionPath(t,e=new Date){let r=this.getSessionPath(t,e);return await j(r),r}async listSessions(t,e=null,r=null){let n=T.join(this.getGlobalProjectPath(t),"sessions"),o=[];try{let i=await gt.readdir(n,{withFileTypes:!0});for(let a of i){if(!a.isDirectory()||e&&a.name!==e.toString())continue;let u=T.join(n,a.name),p=await gt.readdir(u,{withFileTypes:!0});for(let m of p){if(!m.isDirectory()||r&&m.name!==r.toString().padStart(2,"0"))continue;let d=T.join(u,m.name),g=await gt.readdir(d,{withFileTypes:!0});for(let h of g)h.isDirectory()&&o.push({year:a.name,month:m.name,day:h.name,path:T.join(d,h.name),date:new Date(`${a.name}-${m.name}-${h.name}`)})}}return o.sort((a,u)=>u.date.getTime()-a.date.getTime()),o}catch{return[]}}async getSessionsInRange(t,e,r=new Date){return(await this.listSessions(t)).filter(o=>o.date>=e&&o.date<=r)}getFilePath(t,e,r){return T.join(this.getGlobalProjectPath(t),e,r)}async listProjects(){try{return await this.ensureGlobalStructure(),(await gt.readdir(this.globalProjectsDir,{withFileTypes:!0})).filter(e=>e.isDirectory()).map(e=>e.name)}catch{return[]}}async projectExists(t){return await At(this.getGlobalProjectPath(t))}getDisplayPath(t){let e=Ht.homedir();return t.startsWith(e)?t.replace(e,"~"):t}getAuthConfigPath(){return T.join(this.globalConfigDir,"auth.json")}getSyncPendingPath(t){return T.join(this.getGlobalProjectPath(t),"sync","pending.json")}getLastSyncPath(t){return T.join(this.getGlobalProjectPath(t),"sync","last-sync.json")}getRunningStatusPath(){return T.join(this.globalBaseDir,".running")}getDocsPath(){return T.join(this.globalBaseDir,"docs")}async getAgentDir(){return(await(mt(),Pt(dt)).getActiveProvider()).configDir}async getAgentSettingsPath(){let t=await(mt(),Pt(dt)).getActiveProvider();return(mt(),Pt(dt)).getGlobalSettingsPath(t.name)}getClaudeDir(){return T.join(Ht.homedir(),".claude")}getClaudeSettingsPath(){return T.join(this.getClaudeDir(),"settings.json")}getStoragePath(t,e){return T.join(this.getGlobalProjectPath(t),"storage",e)}getContextPath(t){return T.join(this.getGlobalProjectPath(t),"context")}async getWikiPath(t,e){return Be(t,e)}getWikiPathWithProjectHash(t,e){return He(t,e)}getLegacyWikiPath(t){return Ge(t)}async detectMonorepo(t){return Ct(t)}async discoverMonorepoPackages(t,e){return It(t,e)}async findContainingPackage(t,e){return Fe(t,e)}async findMonorepoRoot(t){return Ue(t)}},an=new Gt,b=an;var ar=`
15
+ -- =======================================================================
16
+ -- Document storage (backward-compatible with JSON file pattern)
17
+ -- =======================================================================
18
+ -- Each row replaces one JSON file (state.json, queue.json, etc.)
19
+ -- StorageManager reads/writes entire documents via key lookup.
20
+ CREATE TABLE kv_store (
21
+ key TEXT PRIMARY KEY,
22
+ data TEXT NOT NULL,
23
+ updated_at TEXT NOT NULL
24
+ );
25
+
26
+ -- =======================================================================
27
+ -- Normalized: Tasks
28
+ -- =======================================================================
29
+ CREATE TABLE tasks (
30
+ id TEXT PRIMARY KEY,
31
+ description TEXT NOT NULL,
32
+ type TEXT,
33
+ status TEXT NOT NULL,
34
+ parent_description TEXT,
35
+ branch TEXT,
36
+ linear_id TEXT,
37
+ linear_uuid TEXT,
38
+ session_id TEXT,
39
+ feature_id TEXT,
40
+ started_at TEXT NOT NULL,
41
+ completed_at TEXT,
42
+ shipped_at TEXT,
43
+ paused_at TEXT,
44
+ pause_reason TEXT,
45
+ pr_url TEXT,
46
+ expected_value TEXT,
47
+ data TEXT
48
+ );
49
+
50
+ CREATE INDEX idx_tasks_status ON tasks(status);
51
+ CREATE INDEX idx_tasks_type ON tasks(type);
52
+ CREATE INDEX idx_tasks_branch ON tasks(branch);
53
+ CREATE INDEX idx_tasks_linear_id ON tasks(linear_id);
54
+
55
+ -- =======================================================================
56
+ -- Normalized: Subtasks
57
+ -- =======================================================================
58
+ CREATE TABLE subtasks (
59
+ id TEXT PRIMARY KEY,
60
+ task_id TEXT NOT NULL,
61
+ description TEXT NOT NULL,
62
+ status TEXT NOT NULL,
63
+ domain TEXT,
64
+ agent TEXT,
65
+ sort_order INTEGER NOT NULL,
66
+ depends_on TEXT,
67
+ started_at TEXT,
68
+ completed_at TEXT,
69
+ output TEXT,
70
+ summary TEXT,
71
+ FOREIGN KEY (task_id) REFERENCES tasks(id)
72
+ );
73
+
74
+ CREATE INDEX idx_subtasks_task_id ON subtasks(task_id);
75
+ CREATE INDEX idx_subtasks_status ON subtasks(status);
76
+
77
+ -- =======================================================================
78
+ -- Normalized: Queue Tasks
79
+ -- =======================================================================
80
+ CREATE TABLE queue_tasks (
81
+ id TEXT PRIMARY KEY,
82
+ description TEXT NOT NULL,
83
+ type TEXT,
84
+ priority TEXT,
85
+ section TEXT,
86
+ created_at TEXT NOT NULL,
87
+ completed INTEGER DEFAULT 0,
88
+ completed_at TEXT,
89
+ feature_id TEXT,
90
+ feature_name TEXT
91
+ );
92
+
93
+ CREATE INDEX idx_queue_tasks_section ON queue_tasks(section);
94
+ CREATE INDEX idx_queue_tasks_priority ON queue_tasks(priority);
95
+ CREATE INDEX idx_queue_tasks_completed ON queue_tasks(completed);
96
+
97
+ -- =======================================================================
98
+ -- Normalized: Ideas
99
+ -- =======================================================================
100
+ CREATE TABLE ideas (
101
+ id TEXT PRIMARY KEY,
102
+ text TEXT NOT NULL,
103
+ status TEXT NOT NULL DEFAULT 'pending',
104
+ priority TEXT NOT NULL DEFAULT 'medium',
105
+ tags TEXT,
106
+ added_at TEXT NOT NULL,
107
+ converted_to TEXT,
108
+ details TEXT,
109
+ data TEXT
110
+ );
111
+
112
+ CREATE INDEX idx_ideas_status ON ideas(status);
113
+ CREATE INDEX idx_ideas_priority ON ideas(priority);
114
+
115
+ -- =======================================================================
116
+ -- Normalized: Shipped Features
117
+ -- =======================================================================
118
+ CREATE TABLE shipped_features (
119
+ id TEXT PRIMARY KEY,
120
+ name TEXT NOT NULL,
121
+ shipped_at TEXT NOT NULL,
122
+ version TEXT NOT NULL,
123
+ description TEXT,
124
+ type TEXT,
125
+ duration TEXT,
126
+ data TEXT
127
+ );
128
+
129
+ CREATE INDEX idx_shipped_version ON shipped_features(version);
130
+ CREATE INDEX idx_shipped_at ON shipped_features(shipped_at);
131
+
132
+ -- =======================================================================
133
+ -- Events (replaces events.jsonl)
134
+ -- =======================================================================
135
+ CREATE TABLE events (
136
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
137
+ type TEXT NOT NULL,
138
+ task_id TEXT,
139
+ data TEXT,
140
+ timestamp TEXT NOT NULL
141
+ );
142
+
143
+ CREATE INDEX idx_events_type ON events(type);
144
+ CREATE INDEX idx_events_task_id ON events(task_id);
145
+ CREATE INDEX idx_events_timestamp ON events(timestamp);
146
+
147
+ -- =======================================================================
148
+ -- Analysis (draft + sealed)
149
+ -- =======================================================================
150
+ CREATE TABLE analysis (
151
+ id TEXT PRIMARY KEY,
152
+ status TEXT NOT NULL,
153
+ commit_hash TEXT,
154
+ signature TEXT,
155
+ sealed_at TEXT,
156
+ analyzed_at TEXT,
157
+ data TEXT NOT NULL
158
+ );
159
+
160
+ -- =======================================================================
161
+ -- Index: File scores and checksums
162
+ -- =======================================================================
163
+ CREATE TABLE index_files (
164
+ path TEXT PRIMARY KEY,
165
+ score REAL,
166
+ size INTEGER,
167
+ mtime TEXT,
168
+ language TEXT,
169
+ categories TEXT,
170
+ domain TEXT
171
+ );
172
+
173
+ CREATE INDEX idx_index_files_domain ON index_files(domain);
174
+ CREATE INDEX idx_index_files_score ON index_files(score);
175
+
176
+ CREATE TABLE index_checksums (
177
+ path TEXT PRIMARY KEY,
178
+ checksum TEXT NOT NULL,
179
+ size INTEGER,
180
+ mtime TEXT
181
+ );
182
+
183
+ -- =======================================================================
184
+ -- Index: Metadata (project-index, domains, categories-cache)
185
+ -- =======================================================================
186
+ CREATE TABLE index_meta (
187
+ key TEXT PRIMARY KEY,
188
+ data TEXT NOT NULL,
189
+ updated_at TEXT NOT NULL
190
+ );
191
+
192
+ -- =======================================================================
193
+ -- Memory (key-value with domain tagging)
194
+ -- =======================================================================
195
+ CREATE TABLE memory (
196
+ key TEXT PRIMARY KEY,
197
+ domain TEXT,
198
+ value TEXT,
199
+ confidence REAL DEFAULT 1.0,
200
+ updated_at TEXT NOT NULL
201
+ );
202
+
203
+ CREATE INDEX idx_memory_domain ON memory(domain);
204
+
205
+ -- =======================================================================
206
+ -- Metrics: Daily stats for trend analysis
207
+ -- =======================================================================
208
+ CREATE TABLE metrics_daily (
209
+ date TEXT PRIMARY KEY,
210
+ tokens_saved INTEGER NOT NULL DEFAULT 0,
211
+ syncs INTEGER NOT NULL DEFAULT 0,
212
+ avg_compression_rate REAL NOT NULL DEFAULT 0,
213
+ total_duration INTEGER NOT NULL DEFAULT 0
214
+ );
215
+
216
+ -- =======================================================================
217
+ -- Velocity: Sprint data
218
+ -- =======================================================================
219
+ CREATE TABLE velocity_sprints (
220
+ sprint_number INTEGER PRIMARY KEY,
221
+ points_completed REAL NOT NULL DEFAULT 0,
222
+ tasks_completed INTEGER NOT NULL DEFAULT 0,
223
+ estimation_accuracy REAL NOT NULL DEFAULT 0,
224
+ avg_variance REAL NOT NULL DEFAULT 0,
225
+ started_at TEXT,
226
+ ended_at TEXT
227
+ );
228
+ `;var cr=[{version:1,name:"initial-schema",up:c(s=>{s.run(ar)},"up")},{version:2,name:"archives-table",up:c(s=>{s.run(`
229
229
  -- =======================================================================
230
230
  -- Archives: Stale data moved out of active storage (PRJ-267)
231
231
  -- =======================================================================
@@ -242,7 +242,7 @@ var at=Object.defineProperty;var Xr=Object.getOwnPropertyDescriptor;var $r=Objec
242
242
  CREATE INDEX idx_archives_entity_type ON archives(entity_type);
243
243
  CREATE INDEX idx_archives_archived_at ON archives(archived_at);
244
244
  CREATE INDEX idx_archives_entity_id ON archives(entity_id);
245
- `)},"up")},{version:3,name:"workflow-rules-table",up:c(n=>{n.run(`
245
+ `)},"up")},{version:3,name:"workflow-rules-table",up:c(s=>{s.run(`
246
246
  -- =======================================================================
247
247
  -- Workflow Rules: hooks, gates, and custom steps (Phase 2)
248
248
  -- =======================================================================
@@ -260,7 +260,7 @@ var at=Object.defineProperty;var Xr=Object.getOwnPropertyDescriptor;var $r=Objec
260
260
  );
261
261
 
262
262
  CREATE INDEX idx_workflow_rules_command ON workflow_rules(command);
263
- `)},"up")},{version:4,name:"custom-workflows-table",up:c(n=>{n.run(`
263
+ `)},"up")},{version:4,name:"custom-workflows-table",up:c(s=>{s.run(`
264
264
  -- =======================================================================
265
265
  -- Custom Workflows: User-defined workflows with agentic auto-config
266
266
  -- =======================================================================
@@ -285,7 +285,7 @@ var at=Object.defineProperty;var Xr=Object.getOwnPropertyDescriptor;var $r=Objec
285
285
  ('done', 'Complete current task/subtask', 1, 1, datetime('now'), datetime('now')),
286
286
  ('ship', 'Ship feature with version bump and PR', 1, 1, datetime('now'), datetime('now')),
287
287
  ('sync', 'Analyze project and regenerate context', 1, 1, datetime('now'), datetime('now'));
288
- `)},"up")},{version:5,name:"llm-analysis-table",up:c(n=>{n.run(`
288
+ `)},"up")},{version:5,name:"llm-analysis-table",up:c(s=>{s.run(`
289
289
  -- =======================================================================
290
290
  -- LLM Analysis: Structured findings from hybrid sync pipeline
291
291
  -- Pipeline: CLI (collect) \u2192 LLM (analyze) \u2192 CLI (store)
@@ -301,7 +301,7 @@ var at=Object.defineProperty;var Xr=Object.getOwnPropertyDescriptor;var $r=Objec
301
301
 
302
302
  CREATE INDEX idx_llm_analysis_status ON llm_analysis(status);
303
303
  CREATE INDEX idx_llm_analysis_commit ON llm_analysis(commit_hash);
304
- `)},"up")},{version:6,name:"context-feedback-table",up:c(n=>{n.run(`
304
+ `)},"up")},{version:6,name:"context-feedback-table",up:c(s=>{s.run(`
305
305
  -- =======================================================================
306
306
  -- Context Feedback: RL loop for file suggestion improvement
307
307
  -- Records suggested vs actual files per task for scoring boosts
@@ -319,7 +319,7 @@ var at=Object.defineProperty;var Xr=Object.getOwnPropertyDescriptor;var $r=Objec
319
319
  );
320
320
 
321
321
  CREATE INDEX idx_cf_task ON context_feedback(task_id);
322
- `)},"up")},{version:7,name:"sessions-table",up:c(n=>{n.run(`
322
+ `)},"up")},{version:7,name:"sessions-table",up:c(s=>{s.run(`
323
323
  -- =======================================================================
324
324
  -- Sessions: Task lifecycle tracking (replaces current.json + archive/)
325
325
  -- =======================================================================
@@ -339,13 +339,13 @@ var at=Object.defineProperty;var Xr=Object.getOwnPropertyDescriptor;var $r=Objec
339
339
  CREATE INDEX idx_sessions_project ON sessions(project_id);
340
340
  CREATE INDEX idx_sessions_status ON sessions(status);
341
341
  CREATE INDEX idx_sessions_completed ON sessions(completed_at);
342
- `)},"up")},{version:8,name:"task-token-tracking",up:c(n=>{n.run(`
342
+ `)},"up")},{version:8,name:"task-token-tracking",up:c(s=>{s.run(`
343
343
  -- =======================================================================
344
344
  -- Token usage tracking per task (input + output)
345
345
  -- =======================================================================
346
346
  ALTER TABLE tasks ADD COLUMN tokens_in INTEGER DEFAULT 0;
347
347
  ALTER TABLE tasks ADD COLUMN tokens_out INTEGER DEFAULT 0;
348
- `)},"up")},{version:9,name:"context-health-tables",up:c(n=>{n.run(`
348
+ `)},"up")},{version:9,name:"context-health-tables",up:c(s=>{s.run(`
349
349
  -- =======================================================================
350
350
  -- Context Zone Events: Track zone transitions for health analytics
351
351
  -- =======================================================================
@@ -375,7 +375,7 @@ var at=Object.defineProperty;var Xr=Object.getOwnPropertyDescriptor;var $r=Objec
375
375
  );
376
376
 
377
377
  CREATE INDEX idx_cc_project ON context_compactions(project_id);
378
- `)},"up")},{version:10,name:"fts5-memories",up:c(n=>{n.run(`
378
+ `)},"up")},{version:10,name:"fts5-memories",up:c(s=>{s.run(`
379
379
  -- =======================================================================
380
380
  -- Memories: Tagged, searchable memory store (replaces memories.json)
381
381
  -- =======================================================================
@@ -424,11 +424,11 @@ var at=Object.defineProperty;var Xr=Object.getOwnPropertyDescriptor;var $r=Objec
424
424
  INSERT INTO memories_fts(rowid, title, content, tags)
425
425
  VALUES (NEW.rowid, NEW.title, NEW.content, NEW.tags);
426
426
  END;
427
- `);try{let t=n.prepare("SELECT data FROM kv_store WHERE key = 'memory:memories'").get();if(t){let e=JSON.parse(t.data);if(e.memories&&e.memories.length>0){let r=n.prepare(`
427
+ `);try{let t=s.prepare("SELECT data FROM kv_store WHERE key = 'memory:memories'").get();if(t){let e=JSON.parse(t.data);if(e.memories&&e.memories.length>0){let r=s.prepare(`
428
428
  INSERT OR IGNORE INTO memories
429
429
  (id, project_id, title, content, tags, content_hash, user_triggered, confidence, observation_count, created_at, updated_at)
430
430
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
431
- `);for(let s of e.memories)r.run(s.id,"_migrated",s.title,s.content,(s.tags||[]).join(","),null,s.userTriggered?1:0,s.confidence??null,s.observationCount??0,s.createdAt,s.updatedAt)}}}catch{}},"up")},{version:11,name:"agent-sessions",up:c(n=>{n.run(`
431
+ `);for(let n of e.memories)r.run(n.id,"_migrated",n.title,n.content,(n.tags||[]).join(","),null,n.userTriggered?1:0,n.confidence??null,n.observationCount??0,n.createdAt,n.updatedAt)}}}catch{}},"up")},{version:11,name:"agent-sessions",up:c(s=>{s.run(`
432
432
  -- =======================================================================
433
433
  -- Agent Sessions: Track AI agent work sessions across compactions
434
434
  -- =======================================================================
@@ -461,7 +461,7 @@ var at=Object.defineProperty;var Xr=Object.getOwnPropertyDescriptor;var $r=Objec
461
461
 
462
462
  CREATE INDEX IF NOT EXISTS idx_user_prompts_project ON user_prompts(project_id);
463
463
  CREATE INDEX IF NOT EXISTS idx_user_prompts_session ON user_prompts(session_id);
464
- `);try{n.run("ALTER TABLE memories ADD COLUMN session_id TEXT")}catch{}},"up")},{version:12,name:"task-body-and-comments",up:c(n=>{try{n.run("ALTER TABLE queue_tasks ADD COLUMN body TEXT")}catch{}n.run(`
464
+ `);try{s.run("ALTER TABLE memories ADD COLUMN session_id TEXT")}catch{}},"up")},{version:12,name:"task-body-and-comments",up:c(s=>{try{s.run("ALTER TABLE queue_tasks ADD COLUMN body TEXT")}catch{}s.run(`
465
465
  CREATE TABLE IF NOT EXISTS queue_task_comments (
466
466
  id TEXT PRIMARY KEY,
467
467
  task_id TEXT NOT NULL,
@@ -472,7 +472,7 @@ var at=Object.defineProperty;var Xr=Object.getOwnPropertyDescriptor;var $r=Objec
472
472
  );
473
473
 
474
474
  CREATE INDEX IF NOT EXISTS idx_qtc_task_id ON queue_task_comments(task_id);
475
- `)},"up")},{version:13,name:"workflow-rules-v2",up:c(n=>{try{n.run("ALTER TABLE workflow_rules ADD COLUMN when_expr TEXT")}catch{}try{n.run("ALTER TABLE workflow_rules ADD COLUMN parallel INTEGER NOT NULL DEFAULT 1")}catch{}n.run(`
475
+ `)},"up")},{version:13,name:"workflow-rules-v2",up:c(s=>{try{s.run("ALTER TABLE workflow_rules ADD COLUMN when_expr TEXT")}catch{}try{s.run("ALTER TABLE workflow_rules ADD COLUMN parallel INTEGER NOT NULL DEFAULT 1")}catch{}s.run(`
476
476
  CREATE TABLE IF NOT EXISTS workflow_rule_cache (
477
477
  rule_id INTEGER NOT NULL,
478
478
  context_hash TEXT NOT NULL,
@@ -482,66 +482,66 @@ var at=Object.defineProperty;var Xr=Object.getOwnPropertyDescriptor;var $r=Objec
482
482
  );
483
483
 
484
484
  CREATE INDEX IF NOT EXISTS idx_wrc_rule ON workflow_rule_cache(rule_id);
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")}],ps=3,Xt=class{static{c(this,"PrjctDatabase")}connections=new Map;accessOrder=[];statementCache=new WeakMap;prepareCached(t,e){let r=this.statementCache.get(t);r||(r=new Map,this.statementCache.set(t,r));let s=r.get(e);if(s)return s;let i=t.prepare(e);return r.set(e,i),i}getDbPath(t){return Je.join(w.getGlobalProjectPath(t),"prjct.db")}getDb(t){let e=this.connections.get(t);if(e)return this.touchAccessOrder(t),e;this.connections.size>=ps&&this.evictLru();let r=this.getDbPath(t),s=Je.dirname(r);Ut.existsSync(s)||Ut.mkdirSync(s,{recursive:!0});let i=ls(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 Ut.existsSync(this.getDbPath(t))}getDoc(t,e){let r=this.getDb(t),s=this.prepareCached(r,"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();this.prepareCached(s,"INSERT OR REPLACE INTO kv_store (key, data, updated_at) VALUES (?, ?, ?)").run(e,i,o)}deleteDoc(t,e){let r=this.getDb(t);this.prepareCached(r,"DELETE FROM kv_store WHERE key = ?").run(e)}hasDoc(t,e){let r=this.getDb(t);return this.prepareCached(r,"SELECT 1 FROM kv_store WHERE key = ?").get(e)!==null}appendEvent(t,e,r,s){let i=this.getDb(t),o=new Date().toISOString();this.prepareCached(i,"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?this.prepareCached(s,"SELECT * FROM events WHERE type = ? ORDER BY id DESC LIMIT ?").all(e,r):this.prepareCached(s,"SELECT * FROM events ORDER BY id DESC LIMIT ?").all(r)}query(t,e,...r){let s=this.getDb(t);return this.prepareCached(s,e).all(...r)}run(t,e,...r){let s=this.getDb(t);this.prepareCached(s,e).run(...r)}get(t,e,...r){let s=this.getDb(t);return this.prepareCached(s,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(s=>{try{s.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(s=>{let e=["pause","resume","reopen","next","dash","bug","idea","linear","jira","tokens","velocity","plan"].map(r=>`'${r}'`).join(",");s.run(`UPDATE workflow_rules SET enabled = 0 WHERE command IN (${e}) AND enabled = 1`)},"up")}];function cn(){return typeof globalThis<"u"&&"Bun"in globalThis?"bun":"node"}c(cn,"detectRuntime");function ur(){return cn()==="bun"}c(ur,"isBun");function lr(s){if(ur()){let{Database:n}=Se("bun:sqlite");return new n(s,{create:!0})}let t=Se("better-sqlite3"),e=new t(s),r=e.exec.bind(e);return e.run=n=>r(n),e}c(lr,"openDatabase");var un=3,Jt=class{static{c(this,"PrjctDatabase")}connections=new Map;accessOrder=[];statementCache=new WeakMap;prepareCached(t,e){let r=this.statementCache.get(t);r||(r=new Map,this.statementCache.set(t,r));let n=r.get(e);if(n)return n;let o=t.prepare(e);return r.set(e,o),o}getDbPath(t){return pr.join(b.getGlobalProjectPath(t),"prjct.db")}getDb(t){let e=this.connections.get(t);if(e)return this.touchAccessOrder(t),e;this.connections.size>=un&&this.evictLru();let r=this.getDbPath(t),n=pr.dirname(r);qt.existsSync(n)||qt.mkdirSync(n,{recursive:!0});let o=lr(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 qt.existsSync(this.getDbPath(t))}getDoc(t,e){let r=this.getDb(t),n=this.prepareCached(r,"SELECT data FROM kv_store WHERE key = ?").get(e);return n?JSON.parse(n.data):null}setDoc(t,e,r){let n=this.getDb(t),o=JSON.stringify(r),i=new Date().toISOString();this.prepareCached(n,"INSERT OR REPLACE INTO kv_store (key, data, updated_at) VALUES (?, ?, ?)").run(e,o,i)}deleteDoc(t,e){let r=this.getDb(t);this.prepareCached(r,"DELETE FROM kv_store WHERE key = ?").run(e)}hasDoc(t,e){let r=this.getDb(t);return this.prepareCached(r,"SELECT 1 FROM kv_store WHERE key = ?").get(e)!==null}appendEvent(t,e,r,n){let o=this.getDb(t),i=new Date().toISOString();this.prepareCached(o,"INSERT INTO events (type, task_id, data, timestamp) VALUES (?, ?, ?, ?)").run(e,n??null,JSON.stringify(r),i)}getEvents(t,e,r=100){let n=this.getDb(t);return e?this.prepareCached(n,"SELECT * FROM events WHERE type = ? ORDER BY id DESC LIMIT ?").all(e,r):this.prepareCached(n,"SELECT * FROM events ORDER BY id DESC LIMIT ?").all(r)}query(t,e,...r){let n=this.getDb(t);return this.prepareCached(n,e).all(...r)}run(t,e,...r){let n=this.getDb(t);this.prepareCached(n,e).run(...r)}get(t,e,...r){let n=this.getDb(t);return this.prepareCached(n,e).get(...r)??null}transaction(t,e){let r=this.getDb(t);return r.transaction(e)(r)}runMigrations(t){t.run(`
486
486
  CREATE TABLE IF NOT EXISTS _migrations (
487
487
  version INTEGER PRIMARY KEY,
488
488
  name TEXT NOT NULL,
489
489
  applied_at TEXT NOT NULL
490
490
  )
491
- `);let e=new Set(t.prepare("SELECT version FROM _migrations").all().map(r=>r.version));for(let r of ds)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 Xt,E=y;M();function ms(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(ms,"extractImportSources");async function gs(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 Te){let i=r+s;try{if((await Ke.stat(i)).isFile())return q.relative(e,i)}catch{}}return null}c(gs,"resolveImport");async function fs(n){let t=await Pe(n),e={},r={},s=0,i=await Re(t,50,async o=>{try{let a=await Ke.readFile(q.join(n,o),"utf-8"),u=ms(a),d=[];for(let m of u){let p=await gs(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(fs,"buildGraph");function Ve(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(Ve,"scoreFromSeeds");var $t="import-graph",mt=new Map;function hs(n,t){E.setDoc(n,$t,t),mt.delete(n)}c(hs,"saveGraph");function et(n){let t=E.get(n,"SELECT updated_at FROM kv_store WHERE key = ?",$t);if(!t)return mt.delete(n),null;let e=mt.get(n);if(e&&e.updatedAt===t.updated_at)return e.graph;let r=E.getDoc(n,$t);return r&&mt.set(n,{graph:r,updatedAt:t.updated_at}),r}c(et,"loadGraph");async function Qe(n,t){let e=await fs(n);return hs(t,e),e}c(Qe,"indexImports");function Ze(n,t){let e=[...n.added,...n.modified],r=new Set(e),s=new Set,i=et(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(Ze,"propagateChanges");function tr(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(tr,"affectedDomains");B();async function ys(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&&Es(o)&&s.add(o)}return s&&s.size>0&&s.size<=30&&r.push(s),r}catch{return[]}}c(ys,"parseGitLog");function Es(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(Es,"isSourceFile");async function ks(n,t=100){let e=await ys(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=ws(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(ks,"buildMatrix");function ws(n,t){return n<t?`${n}\0${t}`:`${t}\0${n}`}c(ws,"pairKey");function Gt(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(Gt,"scoreFromSeeds");var Wt="cochange-index",gt=new Map;function bs(n,t){E.setDoc(n,Wt,t),gt.delete(n)}c(bs,"saveMatrix");function Bt(n){let t=E.get(n,"SELECT updated_at FROM kv_store WHERE key = ?",Wt);if(!t)return gt.delete(n),null;let e=gt.get(n);if(e&&e.updatedAt===t.updated_at)return e.matrix;let r=E.getDoc(n,Wt);return r&&gt.set(n,{matrix:r,updatedAt:t.updated_at}),r}c(Bt,"loadMatrix");async function sr(n,t,e=100){let r=await ks(n,e);return bs(t,r),r}c(sr,"indexCoChanges");import Jt from"node:fs/promises";import As from"node:path";import*as Tt from"jsonc-parser";var Ht=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 Ss(n){return n instanceof Ht}c(Ss,"isPrjctError");function qt(n){return Ss(n)||n instanceof Error?n.message:typeof n=="string"?n:"Unknown error"}c(qt,"getErrorMessage");U();M();U();import Yt from"node:fs";import ft from"node:path";var Y=null,rt=null;function nr(){if(rt)return rt;let n=__dirname;for(let t=0;t<5;t++){let e=ft.join(n,"package.json");if(Yt.existsSync(e))try{if(JSON.parse(Yt.readFileSync(e,"utf-8")).name==="prjct-cli")return rt=n,n}catch{}n=ft.dirname(n)}return rt=ft.join(__dirname,"..","..",".."),rt}c(nr,"getPackageRoot");function vs(){if(Y)return Y;let n=process.env.PRJCT_VERSION;if(n&&/^\d+\.\d+\.\d+/.test(n))return Y=n,Y;try{let t=ft.join(nr(),"package.json");return Y=JSON.parse(Yt.readFileSync(t,"utf-8")).version,Y}catch(t){return process.env.PRJCT_DEBUG==="1"&&console.error("Failed to read version from package.json:",we(t)),"0.0.0"}}c(vs,"getVersion");var zt=vs(),Qi=nr();B();async function ht(n){try{let{stdout:t}=await k(n,{timeout:5e3});return{success:!0,output:t.trim()}}catch{return{success:!1,output:""}}}c(ht,"execCommand");async function _s(){let n=await ht("gh api user --jq .login");return n.success&&n.output||(n=await ht("git config --global github.user"),n.success&&n.output)?n.output:null}c(_s,"detectGitHubUsername");async function xs(){let n=await ht("git config user.name");return n.success&&n.output?n.output:null}c(xs,"detectGitName");async function Ps(){let n=await ht("git config user.email");return n.success&&n.output?n.output:null}c(Ps,"detectGitEmail");async function ir(){let[n,t,e]=await Promise.all([_s(),xs(),Ps()]);return{github:n,email:e,name:t||n||"Unknown"}}c(ir,"detect");function or(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(or,"parseJsonc");var Kt=class{static{c(this,"ConfigManager")}async readConfig(t){try{let e=w.getLocalConfigPath(t),r=await Jt.readFile(e,"utf-8");return or(r)}catch(e){return R(e)||console.warn(`Warning: Could not read config at ${t}: ${qt(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 Jt.readFile(e,"utf-8");return or(r)}catch(e){return R(e)||console.warn(`Warning: Could not read global config for ${t}: ${qt(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:zt,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:zt,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 Jt.readdir(As.join(i,"core"))).length===0}catch(o){return R(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(()=>(jt(),Mt));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 ir(),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))}}},Ns=new Kt,$=Ns;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 Cs(r,n)}}}c(b,"safeMcpCall");function Cs(n,t){let e=n instanceof Error?n.message:String(n);return{content:[{type:"text",text:`[${t}] Error: ${e}`}],isError:!0}}c(Cs,"mcpError");function ar(n){let t=n;t.tool("prjct_impact_analysis","Given changed files, find affected files via import graph + affected domains",{projectPath:P.string().describe("Project directory path"),changedFiles:P.array(P.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=Ze(s,r),o=tr(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:P.string().describe("Project directory path"),file:P.string().optional().describe("File path to get neighbors for (omit for graph stats)"),rebuild:P.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:et(r);if(s||(s=await Qe(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(`
500
- `)}]}}return{content:[{type:"text",text:["## Import Graph Stats",`Files: ${s.fileCount}`,`Edges: ${s.edgeCount}`,`Built: ${s.builtAt}`].join(`
501
- `)}]}})),t.tool("prjct_cochange","Files that historically change together (Jaccard similarity from git history)",{projectPath:P.string().describe("Project directory path"),seedFiles:P.array(P.string()).describe("Seed files to find co-change partners for"),rebuild:P.boolean().optional().default(!1).describe("Force rebuild the co-change matrix"),maxResults:P.number().optional().default(10).describe("Max results (default 10)")},b("prjct_cochange",async e=>{let r=await v(e.projectPath),s=e.rebuild?null:Bt(r);s||(s=await sr(e.projectPath,r));let i=Gt(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:P.string().describe("Project directory path"),seedFiles:P.array(P.string()).describe("Seed files to find related context for"),maxResults:P.number().optional().default(15).describe("Max results (default 15)")},b("prjct_related_context",async e=>{let r=await v(e.projectPath),s=et(r),i=s?Ve(e.seedFiles,s):[],o=Bt(r),a=o?Gt(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 Is from"node:crypto";function F(){return Is.randomUUID()}c(F,"generateUUID");At();import{z as l}from"zod";var Ds=l.enum(["low","medium","high","critical"]),yt=l.enum(["feature","bug","improvement","chore"]),Ls=l.enum(["active","backlog","previously_active"]),Os=l.enum(["pending","in_progress","completed","blocked","paused","failed","skipped"]),Vt=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:Vt}),lr=l.object({id:l.string(),description:l.string(),domain:l.string(),agent:l.string(),status:Os,dependsOn:l.array(l.string()),startedAt:l.string().optional(),completedAt:l.string().optional(),output:l.string().optional(),summary:Vt.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:yt.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:Rt.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:yt.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:Rt.optional(),tokensIn:l.number().optional(),tokensOut:l.number().optional()}),Ms=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()}),js=l.object({taskId:l.string(),title:l.string(),classification:yt,startedAt:l.string(),completedAt:l.string(),subtaskCount:l.number(),subtaskSummaries:l.array(Vt),outcome:l.string(),branchName:l.string(),linearId:l.string().optional(),linearUuid:l.string().optional(),prUrl:l.string().optional(),feedback:Ms.optional(),tokensIn:l.number().optional(),tokensOut:l.number().optional()}),Fs=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(js).optional(),activeTasks:l.array(Fs).optional(),lastUpdated:l.string()}),Us=l.object({id:l.string(),description:l.string(),body:l.string().optional(),priority:Ds,type:yt,featureId:l.string().optional(),originFeature:l.string().optional(),completed:l.boolean(),completedAt:l.string().optional(),createdAt:l.string(),section:Ls,agent:l.string().optional(),groupName:l.string().optional(),groupId:l.string().optional()}),gr=l.object({tasks:l.array(Us),lastUpdated:l.string()});var st={idle:{transitions:["task"],prompt:"prjct task <description> Start working",description:"No active task"},working:{transitions:["done","pause"],prompt:"prjct status done Complete task | prjct status paused Switch context",description:"Task in progress"},paused:{transitions:["resume","task","ship"],prompt:"prjct status active Continue | prjct task <new> Start different | prjct ship Ship directly",description:"Task paused"},completed:{transitions:["ship","task","pause","reopen"],prompt:"prjct ship Ship it | prjct task <next> Start next | prjct status active Reopen",description:"Task completed"},shipped:{transitions:["task"],prompt:"prjct task <description> Start new task",description:"Feature shipped"}},Qt=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(st[t].transitions.includes(e))return{valid:!0};let s=this.formatNextSteps(t).join(" | ");return{valid:!1,error:`Cannot transition to '${e}' from '${t}' state`,suggestion:`Valid next steps: ${s}`}}getNextState(t,e){switch(e){case"task":return"working";case"done":return"completed";case"pause":return"paused";case"resume":return"working";case"ship":return"shipped";case"reopen":return"working";default:return t}}getStateInfo(t){return st[t]}getPrompt(t){return st[t].prompt}getValidCommands(t){return st[t].transitions}formatNextSteps(t){return st[t].transitions.map(r=>{switch(r){case"task":return"prjct task <desc> Start new task";case"done":return"prjct status done Complete current task";case"pause":return"prjct status paused Pause and switch context";case"resume":return"prjct status active Continue paused task";case"ship":return"prjct ship Ship the feature";case"reopen":return"prjct status active Reopen completed task";default:return`prjct ${r}`}})}},Zt=new Qt;var nt={SHIPPED_RETENTION_DAYS:90,IDEA_DORMANT_DAYS:180,QUEUE_COMPLETED_DAYS:7,PAUSED_TASK_DAYS:30,MEMORY_MAX_ENTRIES:500},te=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}},z=new te;M();var ee=class{static{c(this,"SyncEventBus")}async publish(t){let e=w.getSyncPendingPath(t.projectId),r=await ct(e,[])??[],s=Array.isArray(r)?r:[];s.push(t),await L(e,s)}async getPending(t){let e=w.getSyncPendingPath(t),r=await ct(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 ct(e,null)}},fr=new ee;Nt();var J=class{static{c(this,"StorageManager")}filename;cache;constructor(t,e){this.filename=t,this.cache=new ut({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 re=class extends J{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,A)=>A!==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[];z.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 A=r.error.issues.map(ot=>`${ot.path.join(".")}: ${ot.message}`);throw new Error(`Subtask completion requires handoff data:
504
- ${A.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(A=>A.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,A=>({...A,currentTask:{...A.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}},K=new re;U();B();import Xs from"node:fs/promises";import Et from"node:path";var $s={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"]},Ws=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".py",".go",".rs",".java",".kt",".swift",".rb",".php",".c",".cpp",".h",".hpp",".cs",".vue",".svelte"]),Gs=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=Bs(n),u=await Hs(t),d=await qs(t),m=[];for(let g of u){if(!o&&zs(g))continue;let T=Ys(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 Bs(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(Bs,"extractKeywords");async function Hs(n){let t=[];async function e(r,s=""){try{let i=await Xs.readdir(r,{withFileTypes:!0});for(let o of i){let a=Et.join(r,o.name),u=Et.join(s,o.name);if(o.isDirectory()){if(Gs.has(o.name)||o.name.startsWith("."))continue;await e(a,u)}else if(o.isFile()){let d=Et.extname(o.name).toLowerCase();Ws.has(d)&&t.push(u)}}}catch(i){R(i)}}return c(e,"walk"),await e(n),t}c(Hs,"getAllCodeFiles");async function qs(n){let t=new Map;try{let{stdout:e}=await k(`git log -30 --pretty=format:"%H %ct" --name-only | awk '
491
+ `);let e=new Set(t.prepare("SELECT version FROM _migrations").all().map(r=>r.version));for(let r of cr)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 Jt,k=y;M();function ln(s){let t=[],e,r=new RegExp(_e.source,"g");for(;(e=r.exec(s))!==null;){let n=e[1];(n.startsWith(".")||n.startsWith("@/"))&&t.push(n)}return t}c(ln,"extractImportSources");async function pn(s,t,e){let r;if(s.startsWith("@/"))r=J.join(e,"src",s.slice(2));else{let n=J.dirname(J.join(e,t));r=J.resolve(n,s)}for(let n of Pe){let o=r+n;try{if((await dr.stat(o)).isFile())return J.relative(e,o)}catch{}}return null}c(pn,"resolveImport");async function dn(s){let t=await Me(s),e={},r={},n=0,o=await je(t,50,async i=>{try{let a=await dr.readFile(J.join(s,i),"utf-8"),u=ln(a),p=[];for(let m of u){let d=await pn(m,i,s);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,n+=a.length;for(let u of a)r[u]||(r[u]=[]),r[u].push(i)}return{forward:e,reverse:r,fileCount:t.length,edgeCount:n,builtAt:new Date().toISOString()}}c(dn,"buildGraph");function mr(s,t,e=2){let r=new Set(s),n=new Map,o=[];for(let i of s){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=n.get(i);if(p){u>p.score&&n.set(i,{score:u,depth:a});continue}if(n.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)&&!n.has(g)&&o.push({file:g,depth:a+1})}}return Array.from(n.entries()).map(([i,{score:a,depth:u}])=>({path:i,score:a,depth:u})).sort((i,a)=>a.score-i.score)}c(mr,"scoreFromSeeds");var Yt="import-graph",ft=new Map;function mn(s,t){k.setDoc(s,Yt,t),ft.delete(s)}c(mn,"saveGraph");function rt(s){let t=k.get(s,"SELECT updated_at FROM kv_store WHERE key = ?",Yt);if(!t)return ft.delete(s),null;let e=ft.get(s);if(e&&e.updatedAt===t.updated_at)return e.graph;let r=k.getDoc(s,Yt);return r&&ft.set(s,{graph:r,updatedAt:t.updated_at}),r}c(rt,"loadGraph");async function gr(s,t){let e=await dn(s);return mn(t,e),e}c(gr,"indexImports");function fr(s,t){let e=[...s.added,...s.modified],r=new Set(e),n=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)||n.add(m)}let i=Array.from(n),a=[...e,...i];return{directlyChanged:e,affectedByImports:i,deleted:s.deleted,allAffected:a}}c(fr,"propagateChanges");function hr(s){let t=new Set;for(let e of s){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(hr,"affectedDomains");q();async function fn(s,t=100){try{let{stdout:e}=await E(`git log --name-only --pretty=format:'---COMMIT---' -${t}`,{cwd:s,maxBuffer:10485760}),r=[],n=null;for(let o of e.split(`
492
+ `)){let i=o.trim();i==="---COMMIT---"?(n&&n.size>0&&n.size<=30&&r.push(n),n=new Set):i&&n&&hn(i)&&n.add(i)}return n&&n.size>0&&n.size<=30&&r.push(n),r}catch{return[]}}c(fn,"parseGitLog");function hn(s){return/\.(ts|tsx|js|jsx|mjs|cjs|py|go|rs|java|cs|rb|php|vue|svelte)$/i.test(s)&&!s.includes("node_modules/")}c(hn,"isSourceFile");async function yn(s,t=100){let e=await fn(s,t),r=new Map,n=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=Tn(a[u],a[p]);n.set(m,(n.get(m)||0)+1)}}let o={};for(let[i,a]of n){let[u,p]=i.split("\0"),m=r.get(u)||0,d=r.get(p)||0;if(m<2||d<2)continue;let g=m+d-a,h=g>0?a/g:0;h<.1||(o[u]||(o[u]={}),o[p]||(o[p]={}),o[u][p]=h,o[p][u]=h)}return{matrix:o,commitsAnalyzed:e.length,filesAnalyzed:r.size,builtAt:new Date().toISOString()}}c(yn,"buildMatrix");function Tn(s,t){return s<t?`${s}\0${t}`:`${t}\0${s}`}c(Tn,"pairKey");function Kt(s,t){let e=new Set(s),r=new Map;for(let n of s){let o=t.matrix[n];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(([n,o])=>({path:n,score:o})).sort((n,o)=>o.score-n.score)}c(Kt,"scoreFromSeeds");var zt="cochange-index",ht=new Map;function kn(s,t){k.setDoc(s,zt,t),ht.delete(s)}c(kn,"saveMatrix");function Vt(s){let t=k.get(s,"SELECT updated_at FROM kv_store WHERE key = ?",zt);if(!t)return ht.delete(s),null;let e=ht.get(s);if(e&&e.updatedAt===t.updated_at)return e.matrix;let r=k.getDoc(s,zt);return r&&ht.set(s,{matrix:r,updatedAt:t.updated_at}),r}c(Vt,"loadMatrix");async function kr(s,t,e=100){let r=await yn(s,e);return kn(t,r),r}c(kr,"indexCoChanges");import re from"node:fs/promises";import Pn from"node:path";import*as kt from"jsonc-parser";var Qt=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 En(s){return s instanceof Qt}c(En,"isPrjctError");function Zt(s){return En(s)||s instanceof Error?s.message:typeof s=="string"?s:"Unknown error"}c(Zt,"getErrorMessage");X();M();X();import te from"node:fs";import yt from"node:path";var Y=null,st=null;function Er(){if(st)return st;let s=__dirname;for(let t=0;t<5;t++){let e=yt.join(s,"package.json");if(te.existsSync(e))try{if(JSON.parse(te.readFileSync(e,"utf-8")).name==="prjct-cli")return st=s,s}catch{}s=yt.dirname(s)}return st=yt.join(__dirname,"..","..",".."),st}c(Er,"getPackageRoot");function bn(){if(Y)return Y;let s=process.env.PRJCT_VERSION;if(s&&/^\d+\.\d+\.\d+/.test(s))return Y=s,Y;try{let t=yt.join(Er(),"package.json");return Y=JSON.parse(te.readFileSync(t,"utf-8")).version,Y}catch(t){return process.env.PRJCT_DEBUG==="1"&&console.error("Failed to read version from package.json:",Ne(t)),"0.0.0"}}c(bn,"getVersion");var ee=bn(),ga=Er();q();async function Tt(s){try{let{stdout:t}=await E(s,{timeout:5e3});return{success:!0,output:t.trim()}}catch{return{success:!1,output:""}}}c(Tt,"execCommand");async function wn(){let s=await Tt("gh api user --jq .login");return s.success&&s.output||(s=await Tt("git config --global github.user"),s.success&&s.output)?s.output:null}c(wn,"detectGitHubUsername");async function Sn(){let s=await Tt("git config user.name");return s.success&&s.output?s.output:null}c(Sn,"detectGitName");async function xn(){let s=await Tt("git config user.email");return s.success&&s.output?s.output:null}c(xn,"detectGitEmail");async function br(){let[s,t,e]=await Promise.all([wn(),Sn(),xn()]);return{github:s,email:e,name:t||s||"Unknown"}}c(br,"detect");function wr(s){let t=[],e=kt.parse(s,t,{allowTrailingComma:!0,disallowComments:!1});if(t.length>0){let r=t[0];throw new SyntaxError(`JSON parse error at offset ${r.offset}: ${kt.printParseErrorCode(r.error)}`)}return e}c(wr,"parseJsonc");var se=class{static{c(this,"ConfigManager")}async readConfig(t){try{let e=b.getLocalConfigPath(t),r=await re.readFile(e,"utf-8");return wr(r)}catch(e){return A(e)||console.warn(`Warning: Could not read config at ${t}: ${Zt(e)}`),null}}async writeConfig(t,e){let r=b.getLocalConfigPath(t);await O(r,e)}async readGlobalConfig(t){try{let e=b.getGlobalProjectConfigPath(t),r=await re.readFile(e,"utf-8");return wr(r)}catch(e){return A(e)||console.warn(`Warning: Could not read global config for ${t}: ${Zt(e)}`),null}}async writeGlobalConfig(t,e){let r=b.getGlobalProjectConfigPath(t);await O(r,e)}async ensureGlobalConfig(t){let e=await this.readGlobalConfig(t);if(!e){let r=f();e={projectId:t,authors:[],version:ee,lastSync:r},await this.writeGlobalConfig(t,e)}return e}async createConfig(t,e){let r=b.generateProjectId(t),n=b.getGlobalProjectPath(r),o=b.getDisplayPath(n),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:ee,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 n=await this.readConfig(t);if(!n||!n.projectId)return!0;let o=b.getGlobalProjectPath(n.projectId);try{return(await re.readdir(Pn.join(o,"core"))).length===0}catch(i){return A(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(()=>(Mt(),Ot));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(n=>n.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 n=r.authors.find(o=>o.github===e);n&&(n.lastActivity=f(),r.lastSync=n.lastActivity,await this.writeGlobalConfig(t,r))}async getCurrentAuthor(t){let e=await br(),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))}}},_n=new se,$=_n;async function x(s){return $.getProjectId(s)}c(x,"resolveProjectId");function w(s,t){return async e=>{try{return await t(e)}catch(r){return Rn(r,s)}}}c(w,"safeMcpCall");function Rn(s,t){let e=s instanceof Error?s.message:String(s);return{content:[{type:"text",text:`[${t}] Error: ${e}`}],isError:!0}}c(Rn,"mcpError");function Sr(s){let t=s;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)")},w("prjct_impact_analysis",async e=>{let r=await x(e.projectPath),n={added:[],modified:e.changedFiles,deleted:[],unchanged:[]},o=fr(n,r),i=hr(o.allAffected),a=["## Impact Analysis"];a.push(`
493
+ ### Directly Changed (${o.directlyChanged.length})`);for(let u of o.directlyChanged)a.push(`- ${u}`);if(o.affectedByImports.length>0){a.push(`
494
+ ### Affected via Imports (${o.affectedByImports.length})`);for(let u of o.affectedByImports)a.push(`- ${u}`)}return a.push(`
495
+ ### Affected Domains`),a.push(i.size>0?Array.from(i).join(", "):"none detected"),a.push(`
496
+ Total affected: ${o.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")},w("prjct_import_graph",async e=>{let r=await x(e.projectPath),n=e.rebuild?null:rt(r);if(n||(n=await gr(e.projectPath,r)),e.file){let i=n.forward[e.file]||[],a=n.reverse[e.file]||[];return{content:[{type:"text",text:[`## Import Neighbors: ${e.file}`,`
498
+ ### Imports (${i.length})`,...i.map(p=>`- ${p}`),`
499
+ ### Imported By (${a.length})`,...a.map(p=>`- ${p}`)].join(`
500
+ `)}]}}return{content:[{type:"text",text:["## Import Graph Stats",`Files: ${n.fileCount}`,`Edges: ${n.edgeCount}`,`Built: ${n.builtAt}`].join(`
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)")},w("prjct_cochange",async e=>{let r=await x(e.projectPath),n=e.rebuild?null:Vt(r);n||(n=await kr(e.projectPath,r));let o=Kt(e.seedFiles,n).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: ${n.commitsAnalyzed}`,""];for(let a of o)i.push(`- ${a.path} (similarity: ${Math.round(a.score*100)}%)`);return{content:[{type:"text",text:i.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)")},w("prjct_related_context",async e=>{let r=await x(e.projectPath),n=rt(r),o=n?mr(e.seedFiles,n):[],i=Vt(r),a=i?Kt(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(`
503
+ `)}]}}))}c(Sr,"registerCodeIntelTools");import{z as B}from"zod";Ut();import{z as l}from"zod";var An=l.enum(["low","medium","high","critical"]),Et=l.enum(["feature","bug","improvement","chore"]),Nn=l.enum(["active","backlog","previously_active"]),Cn=l.enum(["pending","in_progress","completed","blocked","paused","failed","skipped"]),ne=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()}),vr=l.object({output:l.string().min(1,"Subtask output is required"),summary:ne}),Pr=l.object({id:l.string(),description:l.string(),domain:l.string(),agent:l.string(),status:Cn,dependsOn:l.array(l.string()),startedAt:l.string().optional(),completedAt:l.string().optional(),output:l.string().optional(),summary:ne.optional(),skipReason:l.string().optional(),blockReason:l.string().optional(),estimatedPoints:l.number().optional(),estimatedMinutes:l.number().optional()}),_r=l.object({completed:l.number(),total:l.number(),percentage:l.number()}),Rr=l.object({id:l.string(),description:l.string(),type:Et.optional(),startedAt:l.string(),sessionId:l.string(),featureId:l.string().optional(),subtasks:l.array(Pr).optional(),currentSubtaskIndex:l.number().optional(),subtaskProgress:_r.optional(),linearId:l.string().optional(),linearUuid:l.string().optional(),estimatedPoints:l.number().optional(),estimatedMinutes:l.number().optional(),modelMetadata:Ft.optional(),tokensIn:l.number().optional(),tokensOut:l.number().optional(),parentDescription:l.string().optional(),branch:l.string().optional(),prUrl:l.string().optional()}),xr=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(Pr).optional(),currentSubtaskIndex:l.number().optional(),subtaskProgress:_r.optional(),linearId:l.string().optional(),linearUuid:l.string().optional(),estimatedPoints:l.number().optional(),estimatedMinutes:l.number().optional(),modelMetadata:Ft.optional(),tokensIn:l.number().optional(),tokensOut:l.number().optional()}),In=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()}),Dn=l.object({taskId:l.string(),title:l.string(),classification:Et,startedAt:l.string(),completedAt:l.string(),subtaskCount:l.number(),subtaskSummaries:l.array(ne),outcome:l.string(),branchName:l.string(),linearId:l.string().optional(),linearUuid:l.string().optional(),prUrl:l.string().optional(),feedback:In.optional(),tokensIn:l.number().optional(),tokensOut:l.number().optional()}),Ln=Rr.extend({workspaceId:l.string(),worktreePath:l.string().optional(),agentSessionId:l.string().optional(),jiraId:l.string().optional(),jiraUuid:l.string().optional(),dispatchedFrom:l.string().optional()}),Ar=l.object({currentTask:Rr.nullable(),previousTask:xr.nullable().optional(),pausedTasks:l.array(xr).optional(),taskHistory:l.array(Dn).optional(),activeTasks:l.array(Ln).optional(),lastUpdated:l.string()}),On=l.object({id:l.string(),description:l.string(),body:l.string().optional(),priority:An,type:Et,featureId:l.string().optional(),originFeature:l.string().optional(),completed:l.boolean(),completedAt:l.string().optional(),createdAt:l.string(),section:Nn,agent:l.string().optional(),groupName:l.string().optional(),groupId:l.string().optional()}),Nr=l.object({tasks:l.array(On),lastUpdated: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"}},oe=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 n=this.formatNextSteps(t).join(" | ");return{valid:!1,error:`Cannot transition to '${e}' from '${t}' state`,suggestion:`Valid next steps: ${n}`}}getNextState(t,e){switch(e){case"task":return"working";case"done":return"completed";case"pause":return"paused";case"resume":return"working";case"ship":return"shipped";case"reopen":return"working";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}`}})}},ie=new oe;import Mn from"node:crypto";function U(){return Mn.randomUUID()}c(U,"generateUUID");var ot={SHIPPED_RETENTION_DAYS:90,IDEA_DORMANT_DAYS:180,QUEUE_COMPLETED_DAYS:7,PAUSED_TASK_DAYS:30,MEMORY_MAX_ENTRIES:500},ae=class{static{c(this,"ArchiveStorage")}archive(t,e){let r=U(),n=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,n,e.reason),r}archiveMany(t,e){if(e.length===0)return 0;let r=f();return y.transaction(t,n=>{let o=n.prepare("INSERT INTO archives (id, entity_type, entity_id, entity_data, summary, archived_at, reason) VALUES (?, ?, ?, ?, ?, ?, ?)");for(let i of e)o.run(U(),i.entityType,i.entityId,JSON.stringify(i.entityData),i.summary??null,r,i.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 n of e){let o=n.entity_type;o in r&&(r[o]=n.count),r.total+=n.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(),n=this.getTotalCount(t);y.run(t,"DELETE FROM archives WHERE archived_at < ?",r);let o=this.getTotalCount(t);return n-o}getTotalCount(t){return y.get(t,"SELECT COUNT(*) as count FROM archives")?.count??0}},z=new ae;async function Cr(s,t,e){let r=await s.read(t);if(!r.currentTask)return null;s.validateTransition(r,"pause");let n={...r.currentTask,status:"paused",pausedAt:f(),pauseReason:e},o=s.getPausedTasksFromState(r),i=[n,...o].slice(0,s.maxPausedTasks);return await s.update(t,a=>({...a,currentTask:null,previousTask:null,pausedTasks:i,lastUpdated:f()})),await s.publish(t,"task.paused",{taskId:n.id,description:n.description,pausedAt:n.pausedAt,reason:e,pausedCount:i.length}),n}c(Cr,"pauseTask");async function Ir(s,t,e){let r=await s.read(t),n=s.getPausedTasksFromState(r);if(n.length===0)return null;s.validateTransition(r,"resume");let o=0;if(e&&(o=n.findIndex(h=>h.id===e),o===-1))return null;let i=n[o],a=n.filter((h,N)=>N!==o),{status:u,pausedAt:p,pauseReason:m,...d}=i,g={...d,startedAt:f(),sessionId:i.sessionId??U()};return await s.update(t,h=>({...h,currentTask:g,previousTask:null,pausedTasks:a,lastUpdated:f()})),await s.publish(t,"task.resumed",{taskId:g.id,description:g.description,resumedAt:g.startedAt,remainingPaused:a.length}),g}c(Ir,"resumeTask");async function Dr(s,t){let e=await s.read(t),r=s.getPausedTasksFromState(e),n=Date.now()-s.stalenessThresholdDays*24*60*60*1e3;return r.filter(o=>new Date(o.pausedAt).getTime()<n)}c(Dr,"getStalePausedTasks");async function Lr(s,t){let e=await s.read(t),r=s.getPausedTasksFromState(e),n=Date.now()-s.stalenessThresholdDays*24*60*60*1e3,o=r.filter(a=>new Date(a.pausedAt).getTime()<n),i=r.filter(a=>new Date(a.pausedAt).getTime()>=n);if(o.length===0)return[];z.archiveMany(t,o.map(a=>({entityType:"paused_task",entityId:a.id,entityData:a,summary:a.description,reason:"staleness"}))),await s.update(t,a=>({...a,pausedTasks:i,previousTask:null,lastUpdated:f()}));for(let a of o)await s.publish(t,"task.archived",{taskId:a.id,description:a.description,pausedAt:a.pausedAt,reason:"staleness"});return o}c(Lr,"archiveStalePausedTasks");async function Or(s,t){await s.update(t,()=>({currentTask:null,previousTask:null,pausedTasks:[],activeTasks:[],lastUpdated:f()}))}c(Or,"clearTask");async function Mr(s,t){let e=await s.read(t),r=s.getPausedTasksFromState(e);return e.currentTask!==null||r.length>0}c(Mr,"hasTask");async function jr(s,t){let e=await s.read(t);return s.getPausedTasksFromState(e)[0]||null}c(jr,"getPausedTask");async function Fr(s,t){let e=await s.read(t);return s.getPausedTasksFromState(e)}c(Fr,"getAllPausedTasks");async function ce(s,t){let e=await s.read(t);return s.getTaskHistoryFromState(e)}c(ce,"getTaskHistory");async function Ur(s,t){let e=await s.read(t);return s.getTaskHistoryFromState(e)[0]||null}c(Ur,"getMostRecentTask");async function Xr(s,t,e){let r=await s.read(t);return s.getTaskHistoryFromState(r).filter(o=>o.classification===e)}c(Xr,"getTaskHistoryByType");async function Wr(s,t){let r=(await ce(s,t)).filter(g=>g.feedback),n=[],o=[],i=[],a=[];for(let g of r){let h=g.feedback;Array.isArray(h.stackConfirmed)&&n.push(...h.stackConfirmed),Array.isArray(h.patternsDiscovered)&&o.push(...h.patternsDiscovered),Array.isArray(h.agentAccuracy)&&i.push(...h.agentAccuracy),Array.isArray(h.issuesEncountered)&&a.push(...h.issuesEncountered)}let u=[...new Set(n)],p=[...new Set(o)],m=new Map;for(let g of a)m.set(g,(m.get(g)||0)+1);let d=[...m.entries()].filter(([g,h])=>h>=2).map(([g])=>g);return{stackConfirmed:u,patternsDiscovered:p,agentAccuracy:i,issuesEncountered:[...new Set(a)],knownGotchas:d}}c(Wr,"getAggregatedFeedback");async function $r(s,t,e){let r=await s.read(t);if(!r.currentTask)return;let n=e.map((o,i)=>({...o,status:i===0?"in_progress":"pending",startedAt:i===0?f():void 0,dependsOn:o.dependsOn||[]}));await s.update(t,o=>({...o,currentTask:{...o.currentTask,subtasks:n,currentSubtaskIndex:0,subtaskProgress:{completed:0,total:n.length,percentage:0}},lastUpdated:f()})),await s.publish(t,"subtasks.created",{taskId:r.currentTask.id,subtaskCount:n.length,subtasks:n.map(o=>({id:o.id,description:o.description,domain:o.domain}))})}c($r,"createSubtasks");async function Br(s,t,e){let r=vr.safeParse(e);if(!r.success){let N=r.error.issues.map(at=>`${at.path.join(".")}: ${at.message}`);throw new Error(`Subtask completion requires handoff data:
504
+ ${N.join(`
505
+ `)}`)}let{output:n,summary:o}=r.data,i=await s.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:n,summary:o};let m=p.filter(N=>N.status==="completed").length,d=p.length,g=Math.round(m/d*100),h=a+1;return h<p.length&&(p[h]={...p[h],status:"in_progress",startedAt:f()}),await s.update(t,N=>({...N,currentTask:{...N.currentTask,subtasks:p,currentSubtaskIndex:h<d?h:a,subtaskProgress:{completed:m,total:d,percentage:g}},lastUpdated:f()})),await s.publish(t,"subtask.completed",{taskId:i.currentTask.id,subtaskId:u.id,description:u.description,output:n,handoff:o.outputForNextAgent,filesChanged:o.filesChanged.length,progress:{completed:m,total:d,percentage:g}}),h<d?p[h]:null}c(Br,"completeSubtask");async function Hr(s,t){let e=await s.read(t);if(!e.currentTask?.subtasks)return null;let r=e.currentTask.currentSubtaskIndex||0;return e.currentTask.subtasks[r]||null}c(Hr,"getCurrentSubtask");async function Gr(s,t){let e=await s.read(t);if(!e.currentTask?.subtasks)return null;let r=(e.currentTask.currentSubtaskIndex||0)+1;return e.currentTask.subtasks[r]||null}c(Gr,"getNextSubtask");async function ue(s,t){let e=await s.read(t);if(!e.currentTask?.subtasks)return null;let r=(e.currentTask.currentSubtaskIndex||0)-1;return r<0?null:e.currentTask.subtasks[r]||null}c(ue,"getPreviousSubtask");async function qr(s,t){let e=await ue(s,t);return e?.summary?.outputForNextAgent?{fromSubtask:e.description,outputForNextAgent:e.summary.outputForNextAgent,filesChanged:e.summary.filesChanged,whatWasDone:e.summary.whatWasDone}:null}c(qr,"getPreviousHandoff");async function Jr(s,t){return(await s.read(t)).currentTask?.subtasks||[]}c(Jr,"getSubtasks");async function Yr(s,t){return(await s.read(t)).currentTask?.subtaskProgress||null}c(Yr,"getSubtaskProgress");async function zr(s,t){return((await s.read(t)).currentTask?.subtasks?.length||0)>0}c(zr,"hasSubtasks");async function Kr(s,t){let e=await s.read(t);return e.currentTask?.subtasks?e.currentTask.subtasks.every(r=>r.status==="completed"||r.status==="failed"||r.status==="skipped"):!0}c(Kr,"areAllSubtasksComplete");async function Vr(s,t,e){let r=await s.read(t);if(!r.currentTask?.subtasks)return null;let n=r.currentTask.currentSubtaskIndex||0,o=r.currentTask.subtasks[n];if(!o)return null;let i=[...r.currentTask.subtasks];i[n]={...o,status:"failed",completedAt:f(),output:`Failed: ${e}`};let a=n+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 s.update(t,d=>({...d,currentTask:{...d.currentTask,subtasks:i,currentSubtaskIndex:a<u?a:n,subtaskProgress:{completed:p,total:u,percentage:m}},lastUpdated:f()})),await s.publish(t,"subtask.failed",{taskId:r.currentTask.id,subtaskId:o.id,description:o.description,error:e}),a<u?i[a]:null}c(Vr,"failSubtask");async function Qr(s,t,e){let r=await s.read(t);if(!r.currentTask?.subtasks)return null;let n=r.currentTask.currentSubtaskIndex||0,o=r.currentTask.subtasks[n];if(!o)return null;let i=[...r.currentTask.subtasks];i[n]={...o,status:"skipped",completedAt:f(),output:`Skipped: ${e}`,skipReason:e};let a=n+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 s.update(t,d=>({...d,currentTask:{...d.currentTask,subtasks:i,currentSubtaskIndex:a<u?a:n,subtaskProgress:{completed:p,total:u,percentage:m}},lastUpdated:f()})),await s.publish(t,"subtask.skipped",{taskId:r.currentTask.id,subtaskId:o.id,description:o.description,reason:e}),a<u?i[a]:null}c(Qr,"skipSubtask");async function Zr(s,t,e){let r=await s.read(t);if(!r.currentTask?.subtasks)return null;let n=r.currentTask.currentSubtaskIndex||0,o=r.currentTask.subtasks[n];if(!o)return null;let i=[...r.currentTask.subtasks];i[n]={...o,status:"blocked",output:`Blocked: ${e}`,blockReason:e};let a=n+1,u=i.length;return a<u&&(i[a]={...i[a],status:"in_progress",startedAt:f()}),await s.update(t,p=>({...p,currentTask:{...p.currentTask,subtasks:i,currentSubtaskIndex:a<u?a:n},lastUpdated:f()})),await s.publish(t,"subtask.blocked",{taskId:r.currentTask.id,subtaskId:o.id,description:o.description,blocker:e}),a<u?i[a]:null}c(Zr,"blockSubtask");async function ts(s,t,e,r){let n={...e,workspaceId:r,startedAt:f()};return await s.update(t,o=>({...o,activeTasks:[...o.activeTasks||[],n],lastUpdated:f()})),await s.publish(t,"task.started",{taskId:n.id,description:n.description,startedAt:n.startedAt,sessionId:n.sessionId,workspaceId:r}),n}c(ts,"startTaskInWorkspace");async function es(s,t,e){return((await s.read(t)).activeTasks||[]).find(n=>n.workspaceId===e)??null}c(es,"getCurrentTaskForWorkspace");async function rs(s,t,e,r){let n=await s.read(t),i=(n.activeTasks||[]).find(d=>d.workspaceId===e);if(!i)return null;let a=f(),u=s.createTaskHistoryEntry(i,a,r),p=s.getTaskHistoryFromState(n),m=[u,...p].slice(0,s.maxTaskHistory);return await s.update(t,d=>({...d,activeTasks:(d.activeTasks||[]).filter(g=>g.workspaceId!==e),taskHistory:m,lastUpdated:a})),await s.publish(t,"task.completed",{taskId:i.id,description:i.description,startedAt:i.startedAt,completedAt:a,workspaceId:e}),i}c(rs,"completeTaskInWorkspace");async function ss(s,t){return(await s.read(t)).activeTasks||[]}c(ss,"getActiveTasks");async function ns(s,t){return((await s.read(t)).activeTasks||[]).length}c(ns,"getActiveTaskCount");async function os(s,t,e,r){let o=(await s.read(t)).activeTasks||[],i=o.findIndex(u=>u.workspaceId===e);if(i===-1)return null;let a={...o[i],...r,workspaceId:e};return await s.update(t,u=>{let p=[...u.activeTasks||[]];return p[i]=a,{...u,activeTasks:p,lastUpdated:f()}}),a}c(os,"updateWorkspaceTask");async function is(s,t,e,r){let n=await s.read(t);if(!n.currentTask)return null;let o=(n.currentTask.tokensIn||0)+e,i=(n.currentTask.tokensOut||0)+r;return await s.update(t,a=>({...a,currentTask:{...a.currentTask,tokensIn:o,tokensOut:i},lastUpdated:f()})),{tokensIn:o,tokensOut:i}}c(is,"addTokens");M();var le=class{static{c(this,"SyncEventBus")}async publish(t){let e=b.getSyncPendingPath(t.projectId),r=await ut(e,[])??[],n=Array.isArray(r)?r:[];n.push(t),await O(e,n)}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 O(e,[])}async updateLastSync(t){let e=b.getLastSyncPath(t),r={timestamp:f(),success:!0};await O(e,r)}async getLastSync(t){let e=b.getLastSyncPath(t);return await ut(e,null)}},as=new le;Xt();var K=class{static{c(this,"StorageManager")}filename;cache;constructor(t,e){this.filename=t,this.cache=new lt({ttl:5e3,maxSize:50})}getStoreKey(){return this.filename.replace(".json","")}async read(t){let e=this.cache.get(t);if(e!==null)return e;try{let r=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),n=e(r);return await this.write(t,n),n}async publishEvent(t,e,r){let n={type:e,path:[this.filename.replace(".json","")],data:r,timestamp:f(),projectId:t};await as.publish(n)}async publishEntityEvent(t,e,r,n){let o=`${e}.${r}`,i={...n,timestamp:f()};await this.publishEvent(t,o,i)}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 pe=class extends K{static{c(this,"StateStorage")}constructor(){super("state.json",Ar)}getDefault(){return{currentTask:null,previousTask:null,pausedTasks:[],taskHistory:[],activeTasks:[],lastUpdated:""}}getEventType(t){return`state.${t}d`}validateTransition(t,e){let r=ie.getCurrentState(t),n=ie.canTransition(r,e);if(!n.valid)throw new Error(`${n.error}. ${n.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 n={...e,startedAt:f()};return await this.update(t,o=>({...o,currentTask:n,lastUpdated:f()})),await this.publishEvent(t,"task.started",{taskId:n.id,description:n.description,startedAt:n.startedAt,sessionId:n.sessionId}),n}async updateCurrentTask(t,e){let r=await this.read(t);if(!r.currentTask)return null;let n={...r.currentTask,...e};return await this.update(t,o=>({...o,currentTask:n,lastUpdated:f()})),n}async completeTask(t,e){let r=await this.read(t),n=r.currentTask;if(!n)return null;this.validateTransition(r,"done");let o=f(),i=this.createTaskHistoryEntry(n,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:n.id,description:n.description,startedAt:n.startedAt,completedAt:o}),n}createTaskHistoryEntry(t,e,r){let n=(t.subtasks||[]).filter(a=>a.status==="completed"&&a.summary).map(a=>a.summary),o=n.length>0?n.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:n,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;lifecycleBackend(){return{read:this.read.bind(this),update:this.update.bind(this),publish:this.publishEvent.bind(this),validateTransition:this.validateTransition.bind(this),getPausedTasksFromState:this.getPausedTasksFromState.bind(this),maxPausedTasks:this.maxPausedTasks,stalenessThresholdDays:this.stalenessThresholdDays}}async pauseTask(t,e){return Cr(this.lifecycleBackend(),t,e)}async resumeTask(t,e){return Ir(this.lifecycleBackend(),t,e)}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){return Dr(this.lifecycleBackend(),t)}async archiveStalePausedTasks(t){return Lr(this.lifecycleBackend(),t)}queryBackend(){return{read:this.read.bind(this),update:this.update.bind(this),getPausedTasksFromState:this.getPausedTasksFromState.bind(this),getTaskHistoryFromState:this.getTaskHistoryFromState.bind(this)}}async clearTask(t){return Or(this.queryBackend(),t)}async hasTask(t){return Mr(this.queryBackend(),t)}async getPausedTask(t){return jr(this.queryBackend(),t)}async getAllPausedTasks(t){return Fr(this.queryBackend(),t)}async getTaskHistory(t){return ce(this.queryBackend(),t)}async getMostRecentTask(t){return Ur(this.queryBackend(),t)}async getTaskHistoryByType(t,e){return Xr(this.queryBackend(),t,e)}async getAggregatedFeedback(t){return Wr(this.queryBackend(),t)}workspaceBackend(){return{read:this.read.bind(this),update:this.update.bind(this),publish:this.publishEvent.bind(this),createTaskHistoryEntry:this.createTaskHistoryEntry.bind(this),getTaskHistoryFromState:this.getTaskHistoryFromState.bind(this),maxTaskHistory:this.maxTaskHistory}}async startTaskInWorkspace(t,e,r){return ts(this.workspaceBackend(),t,e,r)}async getCurrentTaskForWorkspace(t,e){return es(this.workspaceBackend(),t,e)}async completeTaskInWorkspace(t,e,r){return rs(this.workspaceBackend(),t,e,r)}async getActiveTasks(t){return ss(this.workspaceBackend(),t)}async getActiveTaskCount(t){return ns(this.workspaceBackend(),t)}async updateWorkspaceTask(t,e,r){return os(this.workspaceBackend(),t,e,r)}async addTokens(t,e,r){return is(this.workspaceBackend(),t,e,r)}subtaskBackend(){return{read:this.read.bind(this),update:this.update.bind(this),publish:this.publishEvent.bind(this)}}async createSubtasks(t,e){return $r(this.subtaskBackend(),t,e)}async completeSubtask(t,e){return Br(this.subtaskBackend(),t,e)}async getCurrentSubtask(t){return Hr(this.subtaskBackend(),t)}async getNextSubtask(t){return Gr(this.subtaskBackend(),t)}async getPreviousSubtask(t){return ue(this.subtaskBackend(),t)}async getPreviousHandoff(t){return qr(this.subtaskBackend(),t)}async getSubtasks(t){return Jr(this.subtaskBackend(),t)}async getSubtaskProgress(t){return Yr(this.subtaskBackend(),t)}async hasSubtasks(t){return zr(this.subtaskBackend(),t)}async areAllSubtasksComplete(t){return Kr(this.subtaskBackend(),t)}async failSubtask(t,e){return Vr(this.subtaskBackend(),t,e)}async skipSubtask(t,e){return Qr(this.subtaskBackend(),t,e)}async blockSubtask(t,e){return Zr(this.subtaskBackend(),t,e)}},V=new pe;X();q();import Wn from"node:fs/promises";import bt from"node:path";var cs={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"]},us=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".py",".go",".rs",".java",".kt",".swift",".rb",".php",".c",".cpp",".h",".hpp",".cs",".vue",".svelte"]),ls=new Set(["node_modules",".git","dist","build",".next",".nuxt",".output","coverage",".cache","__pycache__",".pytest_cache","vendor","target",".turbo",".vercel"]),ps=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"]);async function ds(s,t,e={}){let r=Date.now(),n=e.maxFiles??30,o=e.minScore??.1,i=e.includeTests??!1,a=$n(s),u=await Bn(t),p=await Hn(t),m=[];for(let g of u){if(!i&&qn(g))continue;let h=Gn(g,a,p,e.historicalBoosts);h.score>=o&&m.push(h)}m.sort((g,h)=>h.score-g.score);let d=m.slice(0,n);return{files:d,metrics:{filesScanned:u.length,filesReturned:d.length,scanDuration:Date.now()-r}}}c(ds,"findRelevantFiles");function $n(s){return s.toLowerCase().split(/[^a-z0-9]+/).filter(Boolean).filter(e=>!ps.has(e)&&e.length>2)}c($n,"extractKeywords");async function Bn(s){let t=[];async function e(r,n=""){try{let o=await Wn.readdir(r,{withFileTypes:!0});for(let i of o){let a=bt.join(r,i.name),u=bt.join(n,i.name);if(i.isDirectory()){if(ls.has(i.name)||i.name.startsWith("."))continue;await e(a,u)}else if(i.isFile()){let p=bt.extname(i.name).toLowerCase();us.has(p)&&t.push(u)}}}catch(o){A(o)}}return c(e,"walk"),await e(s),t}c(Bn,"getAllCodeFiles");async function Hn(s){let t=new Map;try{let{stdout:e}=await E(`git log -30 --pretty=format:"%H %ct" --name-only | awk '
506
506
  /^[a-f0-9]{40}/ { commit=$1; timestamp=$2; next }
507
507
  NF { files[$0]++; if (!lastmod[$0]) lastmod[$0]=timestamp }
508
508
  END { for (f in files) print files[f], lastmod[f], f }
509
- '`,{cwd:n,maxBuffer:10485760}),r=Math.floor(Date.now()/1e3),s=e.trim().split(`
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(qs,"getGitRecency");function Ys(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 Q of p)if(Q.includes(x)||x.includes(Q)){i+=.15;break}}i=Math.min(1,i);for(let[x,Q]of Object.entries($s))for(let Ur of Q)if(m.includes(Ur)&&t.some(St=>Q.includes(St)||St.includes(x)||x.includes(St))){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=Et.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 ot=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,ot),reasons:[...new Set(s)]}}c(Ys,"scoreFile");function zs(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(zs,"isTestFile");U();import Zs from"node:fs/promises";import V from"node:path";var Ks={"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}},Vs="claude-sonnet-4.5";function se(n){return!n||n.length===0?0:Math.ceil(n.length/4)}c(se,"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=Ks[t],r=n/1e3*e.input,s=n/1e3*e.output*.3;return{inputSaved:r,outputPotential:s,total:r+s}}c(Tr,"calculateModelCost");function Qs(n){return n<.001?"<$0.01":n<.01?`$${n.toFixed(3)}`:`$${n.toFixed(2)}`}c(Qs,"formatCostSaved");function Er(n,t){let e=se(n),r=se(t),s=Math.max(0,e-r),i=e>0?(e-r)/e:0,o=Tr(s,Vs),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:Qs(o.total),byModel:a}}}c(Er,"measureCompression");function kt(n){let t=se(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(kt,"noCompression");var tn={".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}],en=[{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}],rn=[{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}],sn=[{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}],nn={typescript:kr,javascript:kr,python:en,go:rn,rust:sn,java:wr,csharp:wr,php:[],ruby:[],unknown:[]};async function br(n,t=process.cwd()){let e=V.isAbsolute(n)?n:V.join(t,n),r=V.resolve(t),s=V.resolve(e);if(!s.startsWith(r+V.sep)&&s!==r)return{file:n,language:"unknown",signatures:[],fallback:!0,fallbackReason:"Path traversal denied: file is outside project directory",metrics:kt("")};let i;try{i=await Zs.readFile(e,"utf-8")}catch(p){if(R(p))return{file:n,language:"unknown",signatures:[],fallback:!0,fallbackReason:"File not found",metrics:kt("")};throw p}let o=V.extname(n).toLowerCase(),a=tn[o]||"unknown",u=nn[a];if(!u||u.length===0)return{file:n,language:a,signatures:[],fallback:!0,fallbackReason:`No extraction patterns for ${a}`,metrics:kt(i)};let d=on(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 on(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:an(p),exported:i.exported||!1,line:m,docstring:g})}}return e.sort((i,o)=>i.line-o.line)}c(on,"extractFromContent");function an(n){return n.replace(/\{$/,"").replace(/\s+/g," ").trim()}c(an,"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)
514
-
515
- ${s.join(`
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})
509
+ '`,{cwd:s,maxBuffer:10485760}),r=Math.floor(Date.now()/1e3),n=e.trim().split(`
510
+ `).filter(Boolean);for(let o of n){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(Hn,"getGitRecency");function Gn(s,t,e,r){let n=[],o=0,i=0,a=0,u=0,p=0,m=s.toLowerCase(),d=m.split("/").join(" ").split(/[^a-z0-9]+/);for(let P of t){m.includes(P)&&(o+=.3,n.push(`keyword:${P}`));for(let Z of d)if(Z.includes(P)||P.includes(Z)){o+=.15;break}}o=Math.min(1,o);for(let[P,Z]of Object.entries(cs))for(let Os of Z)if(m.includes(Os)&&t.some(vt=>Z.includes(vt)||vt.includes(P)||P.includes(vt))){i+=.4,n.push(`domain:${P}`);break}i=Math.min(1,i);let g=e.get(s);g&&(g.daysAgo<=1?(a=1,n.push("recent:1d")):g.daysAgo<=3?(a=.8,n.push("recent:3d")):g.daysAgo<=7?(a=.6,n.push("recent:1w")):g.daysAgo<=30&&(a=.3,n.push("recent:1m")),g.commits>=5&&(a=Math.min(1,a+.2)));let h=bt.basename(s).toLowerCase();if((h.includes("index")||h.includes("main")||h.includes("app")||h.includes("entry"))&&(u=.5,n.push("import:0")),(m.includes("/core/")||m.includes("/shared/")||m.includes("/lib/"))&&(u=Math.max(u,.3),n.some(P=>P.startsWith("import:"))||n.push("import:1")),r){let P=r.get(s);P!==void 0&&(p=(P+1)/2,P>0?n.push("history:boosted"):P<0&&n.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:s,score:Math.min(1,at),reasons:[...new Set(n)]}}c(Gn,"scoreFile");function qn(s){let t=s.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(qn,"isTestFile");X();import Vn from"node:fs/promises";import Q from"node:path";var Yn={"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}},zn="claude-sonnet-4.5";function de(s){return!s||s.length===0?0:Math.ceil(s.length/4)}c(de,"countTokens");var gs=["claude-sonnet-4.5","claude-opus-4.5","claude-opus-4-6","gpt-4o","gemini-1.5-pro"];function ms(s,t){let e=Yn[t],r=s/1e3*e.input,n=s/1e3*e.output*.3;return{inputSaved:r,outputPotential:n,total:r+n}}c(ms,"calculateModelCost");function Kn(s){return s<.001?"<$0.01":s<.01?`$${s.toFixed(3)}`:`$${s.toFixed(2)}`}c(Kn,"formatCostSaved");function fs(s,t){let e=de(s),r=de(t),n=Math.max(0,e-r),o=e>0?(e-r)/e:0,i=ms(n,zn),a=gs.map(u=>({model:u,...ms(n,u)}));return{tokens:{original:e,filtered:r,saved:n},compression:Math.max(0,Math.min(1,o)),cost:{saved:i.total,formatted:Kn(i.total),byModel:a}}}c(fs,"measureCompression");function wt(s){let t=de(s);return{tokens:{original:t,filtered:t,saved:0},compression:0,cost:{saved:0,formatted:"$0.00",byModel:gs.map(e=>({model:e,inputSaved:0,outputPotential:0,total:0}))}}}c(wt,"noCompression");var Qn={".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"},hs=[{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}],Zn=[{type:"function",pattern:/^def\s+(\w+)\s*\(([^)]*)\)\s*(?:->\s*([^:]+))?\s*:/gm,nameIndex:1},{type:"function",pattern:/^async\s+def\s+(\w+)\s*\(([^)]*)\)\s*(?:->\s*([^:]+))?\s*:/gm,nameIndex:1},{type:"class",pattern:/^class\s+(\w+)(?:\(([^)]*)\))?\s*:/gm,nameIndex:1}],to=[{type:"function",pattern:/^func\s+(\w+)\s*\(([^)]*)\)\s*(?:\(([^)]*)\)|([^\s{]+))?\s*\{/gm,nameIndex:1},{type:"method",pattern:/^func\s+\([^)]+\)\s+(\w+)\s*\(([^)]*)\)\s*(?:\(([^)]*)\)|([^\s{]+))?\s*\{/gm,nameIndex:1},{type:"type",pattern:/^type\s+(\w+)\s+(?:struct|interface)\s*\{/gm,nameIndex:1}],eo=[{type:"function",pattern:/^pub\s+(?:async\s+)?fn\s+(\w+)(?:<[^>]+>)?\s*\(([^)]*)\)\s*(?:->\s*([^{]+))?\s*\{/gm,nameIndex:1,exported:!0},{type:"function",pattern:/^(?:async\s+)?fn\s+(\w+)(?:<[^>]+>)?\s*\(([^)]*)\)\s*(?:->\s*([^{]+))?\s*\{/gm,nameIndex:1},{type:"class",pattern:/^pub\s+struct\s+(\w+)(?:<[^>]+>)?\s*(?:\{|;)/gm,nameIndex:1,exported:!0},{type:"class",pattern:/^struct\s+(\w+)(?:<[^>]+>)?\s*(?:\{|;)/gm,nameIndex:1},{type:"interface",pattern:/^pub\s+trait\s+(\w+)(?:<[^>]+>)?\s*(?:\{|:)/gm,nameIndex:1,exported:!0},{type:"interface",pattern:/^trait\s+(\w+)(?:<[^>]+>)?\s*(?:\{|:)/gm,nameIndex:1},{type:"enum",pattern:/^pub\s+enum\s+(\w+)(?:<[^>]+>)?\s*\{/gm,nameIndex:1,exported:!0},{type:"enum",pattern:/^enum\s+(\w+)(?:<[^>]+>)?\s*\{/gm,nameIndex:1}],ys=[{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}],ro={typescript:hs,javascript:hs,python:Zn,go:to,rust:eo,java:ys,csharp:ys,php:[],ruby:[],unknown:[]};async function Ts(s,t=process.cwd()){let e=Q.isAbsolute(s)?s:Q.join(t,s),r=Q.resolve(t),n=Q.resolve(e);if(!n.startsWith(r+Q.sep)&&n!==r)return{file:s,language:"unknown",signatures:[],fallback:!0,fallbackReason:"Path traversal denied: file is outside project directory",metrics:wt("")};let o;try{o=await Vn.readFile(e,"utf-8")}catch(d){if(A(d))return{file:s,language:"unknown",signatures:[],fallback:!0,fallbackReason:"File not found",metrics:wt("")};throw d}let i=Q.extname(s).toLowerCase(),a=Qn[i]||"unknown",u=ro[a];if(!u||u.length===0)return{file:s,language:a,signatures:[],fallback:!0,fallbackReason:`No extraction patterns for ${a}`,metrics:wt(o)};let p=so(o,u),m=p.map(d=>`${d.exported?"export ":""}${d.type} ${d.name}: ${d.signature}`).join(`
511
+ `);return{file:s,language:a,signatures:p,fallback:!1,metrics:fs(o,m)}}c(Ts,"extractSignatures");function so(s,t){let e=[],r=s.split(`
512
+ `),n=new Set;for(let o of t){o.pattern.lastIndex=0;let i;for(;(i=o.pattern.exec(s))!==null;){let a=i[o.nameIndex];if(!a)continue;let u=`${o.type}:${a}`;if(n.has(u))continue;n.add(u);let p=i.index,m=s.substring(0,p).split(`
513
+ `).length,d=i[0].trim(),g;if(m>1){let h=r[m-2]?.trim();(h?.startsWith("/**")||h?.startsWith("///")||h?.startsWith("#"))&&(g=h)}e.push({type:o.type,name:a,signature:no(d),exported:o.exported||!1,line:m,docstring:g})}}return e.sort((o,i)=>o.line-i.line)}c(so,"extractFromContent");function no(s){return s.replace(/\{$/,"").replace(/\s+/g," ").trim()}c(no,"cleanSignature");function ks(s){let t=s;t.tool("prjct_relevant_files","BM25-ranked files relevant to a query",{projectPath:B.string().describe("Project directory path"),query:B.string().describe("Task or query to find relevant files for"),maxFiles:B.number().optional().default(10).describe("Max files to return")},w("prjct_relevant_files",async e=>{let r=await ds(e.query,e.projectPath,{maxFiles:e.maxFiles,minScore:.1});if(r.files.length===0)return{content:[{type:"text",text:"No relevant files found."}]};let n=r.files.map(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)
514
+
515
+ ${n.join(`
516
+ `)}`}]}})),t.tool("prjct_signatures","Code signatures from a file (90% token reduction vs full content)",{projectPath:B.string().describe("Project directory path"),filePath:B.string().describe("Relative file path to extract signatures from")},w("prjct_signatures",async e=>{let r=await Ts(e.filePath,e.projectPath);if(r.signatures.length===0)return{content:[{type:"text",text:r.fallback?`No signatures extracted: ${r.fallbackReason}`:"No signatures found."}]};let n=r.signatures.map(a=>`${a.exported?"export ":""}${a.type} ${a.name}: ${a.signature}${a.docstring?` // ${a.docstring}`:""}`),o=r.metrics?.compression?` (${Math.round(r.metrics.compression*100)}% reduction)`:"";return{content:[{type:"text",text:`## ${r.file} (${r.language})
517
517
  \`\`\`
518
- ${s.join(`
518
+ ${n.join(`
519
519
  `)}
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 K.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)
521
-
522
- ${o.join(`
523
- `)}`}]}}))}c(Sr,"registerFileTools");import{z as S}from"zod";var ne=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<=nt.MEMORY_MAX_ENTRIES)return 0;let s=r-nt.MEMORY_MAX_ENTRIES,i=E.query(t,"SELECT id, type, data, timestamp FROM events WHERE type LIKE 'memory.%' ORDER BY id ASC LIMIT ?",s);z.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 ne;var _r="memory.",ie="remember.",oe=`${_r}${ie}`,La=`${_r}task.tagged`;var xr=["fact","decision","learning","gotcha","pattern","anti-pattern","shipped","inbox","todo","idea","insight","question","source","person"];var cn=25,un=4,ln=100;function Pr(n,t){try{return JSON.parse(n)}catch{return t}}c(Pr,"safeJson");function dn(n){let t=n.type.slice(oe.length),e=Pr(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(dn,"rowToEntry");function pn(n){let t=n.data?Pr(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(pn,"shippedRowToEntry");function mn(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(mn,"matchesTopic");function gn(n,t){for(let[e,r]of Object.entries(t))if(n.tags[e]!==r)return!1;return!0}c(gn,"matchesTags");function fn(n){let t=new Set,e=[];for(let r of n){let s=r.tags.key;if(!s){e.push(r);continue}let i=`${r.type}::${s}`;t.has(i)||(t.add(i),e.push(r))}return e}c(fn,"dedupeLatestByKey");var G={async remember(n,t){await vr.log(n,`${ie}${t.type}`,{content:t.content,tags:t.tags??{},source:t.source,provenance:t.provenance??"declared"})},recall(n,t={}){let e=t.limit??cn,r=Math.max(e*un,ln),s=E.query(n,"SELECT id, type, data, timestamp FROM events WHERE type LIKE ? ORDER BY id DESC LIMIT ?",`${oe}%`,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(dn),...i.map(pn)];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=>gn(a,t.tags??{}))),t.topic&&(o=o.filter(a=>mn(a,t.topic))),o.sort((a,u)=>u.rememberedAt.localeCompare(a.rememberedAt)),t.dedupeByKey!==!1&&(o=fn(o)),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 it(n){if(n.length===0)return"> No matching memory entries.";let t=new Map;for(let a of n){let u=t.get(a.type)??[];u.push(a),t.set(a.type,u)}let e=["decision","learning","anti-pattern","gotcha","pattern","fact","inbox","todo","idea","insight","question","source","person","shipped"],r=[],s={declared:"DECL",extracted:"EXTR",inferred:"INFR",ambiguous:"AMBG"},i=c((a,u)=>{if(u.length!==0){r.push(`### ${a.toUpperCase()}`);for(let d of u){let m=Object.entries(d.tags).map(([T,A])=>`${T}=${A}`).join(" "),p=m?` _(${m})_`:"",g=s[d.provenance];r.push(`- \`${g}\` [${d.id}] ${d.content}${p}`)}r.push("")}},"renderGroup"),o=new Set;for(let a of e){let u=t.get(a);!u||u.length===0||(i(a,u),o.add(a))}for(let[a,u]of t)o.has(a)||i(a,u);return r.join(`
524
- `).trim()}c(it,"formatMemoryMd");var hn=[{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 Rr(n){let t=[];for(let{name:e,re:r}of hn)r.test(n)&&t.push(e);return t}c(Rr,"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=Rr(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:it(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:it(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 ue}from"zod";var ae=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}})}},Tn=new ae,Cr=Tn;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 ce=class extends J{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=ke(nt.QUEUE_COMPLETED_DAYS),s=e.tasks.filter(o=>o.completed&&o.completedAt&&new Date(o.completedAt)<r);if(s.length===0)return 0;z.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 ce;function Mr(n){let t=n;t.tool("prjct_task_status","Current task, duration, subtasks, and queue",{projectPath:ue.string().describe("Project directory path")},b("prjct_task_status",async e=>{let r=await v(e.projectPath),s=await K.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:ue.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:ue.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:it(s)}]}}))}c(Mr,"registerProjectTools");import{z as bt}from"zod";var le=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}}},wt=new le;function de(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(de,"rowToRule");var pe=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?de(r):null}getRulesForCommand(t,e){let r=wt.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(de)}getAllRules(t){return y.query(t,"SELECT * FROM workflow_rules ORDER BY command ASC, sort_order ASC").map(de)}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}},me=new pe;function jr(n){let t=n;t.tool("prjct_workflow_rules","Get workflow rules for a command (gates, hooks, steps, instructions)",{projectPath:bt.string().describe("Project directory path"),command:bt.string().describe("Command name (task, done, ship, sync, etc.)")},b("prjct_workflow_rules",async e=>{let r=await v(e.projectPath),s=me.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:bt.string().describe("Project directory path")},b("prjct_workflow_list",async e=>{let r=await v(e.projectPath),s=wt.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})
520
+ \`\`\`${o}`}]}})),t.tool("prjct_history","Recent completed tasks with outcomes",{projectPath:B.string().describe("Project directory path"),limit:B.number().optional().default(10).describe("Max results")},w("prjct_history",async e=>{let r=await x(e.projectPath),n=await V.getTaskHistory(r);if(n.length===0)return{content:[{type:"text",text:"No task history."}]};let i=n.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 (${n.length} total)
537
521
 
538
522
  ${i.join(`
539
- `)}`}]}})),t.tool("prjct_workflow_status","Current workflow execution state + active rules",{projectPath:bt.string().describe("Project directory path")},b("prjct_workflow_status",async e=>{let r=await v(e.projectPath),s=await K.getCurrentTask(r),i=me.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 En=`# prjct \u2014 persona-aware context broker
523
+ `)}`}]}}))}c(ks,"registerFileTools");import{z as S}from"zod";var me=class{static{c(this,"MemoryService")}async log(t,e,r,n){try{let o=await $.getProjectId(t);if(!o)return;k.appendEvent(o,`memory.${e}`,{...r,author:n})}catch(o){console.error(`Memory log error: ${o instanceof Error?o.message:String(o)}`)}}async getRecent(t,e=100){try{let r=await $.getProjectId(t);return r?k.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 n=await this.getRecent(t,1e3),o=e.toLowerCase();return n.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 n=await $.getProjectId(t);return n?k.query(n,"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(n){return console.error(`Memory read error: ${n instanceof Error?n.message:String(n)}`),[]}}async clear(t){try{let e=await $.getProjectId(t);if(!e)return;k.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 k.query(t,"SELECT type, data, timestamp FROM events WHERE type LIKE 'memory.%' ORDER BY id DESC LIMIT ?",e).reverse().map(n=>{let o=JSON.parse(n.data);return{timestamp:n.timestamp,action:n.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=k.get(t,"SELECT COUNT(*) as cnt FROM events WHERE type LIKE 'memory.%'")?.cnt??0;if(r<=ot.MEMORY_MAX_ENTRIES)return 0;let n=r-ot.MEMORY_MAX_ENTRIES,o=k.query(t,"SELECT id, type, data, timestamp FROM events WHERE type LIKE 'memory.%' ORDER BY id ASC LIMIT ?",n);z.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&&k.run(t,"DELETE FROM events WHERE type LIKE 'memory.%' AND id <= ?",i),n}catch(e){return console.error(`Memory cap error: ${e instanceof Error?e.message:String(e)}`),0}}},Es=new me;var bs="memory.",ge="remember.",fe=`${bs}${ge}`,iu=`${bs}task.tagged`;var ws=["fact","decision","learning","gotcha","pattern","anti-pattern","shipped","inbox","todo","idea","insight","question","source","person"];var oo=25,io=4,ao=100;function Ss(s,t){try{return JSON.parse(s)}catch{return t}}c(Ss,"safeJson");function co(s){let t=s.type.slice(fe.length),e=Ss(s.data,{});return{id:`mem_${s.id}`,type:t,content:e.content??"",tags:e.tags??{},rememberedAt:s.timestamp,source:e.source,provenance:e.provenance??"declared"}}c(co,"rowToEntry");function uo(s){let t=s.data?Ss(s.data,{}):{},e=t.tags??{};return s.type&&(e.type=s.type),{id:`ship_${s.id}`,type:"shipped",content:s.name,tags:e,rememberedAt:s.shipped_at,source:t.taskId,provenance:"extracted"}}c(uo,"shippedRowToEntry");function lo(s,t){let e=t.toLowerCase();if(s.content.toLowerCase().includes(e))return!0;for(let r of Object.values(s.tags))if(r.toLowerCase().includes(e))return!0;return!1}c(lo,"matchesTopic");function po(s,t){for(let[e,r]of Object.entries(t))if(s.tags[e]!==r)return!1;return!0}c(po,"matchesTags");function mo(s){let t=new Set,e=[];for(let r of s){let n=r.tags.key;if(!n){e.push(r);continue}let o=`${r.type}::${n}`;t.has(o)||(t.add(o),e.push(r))}return e}c(mo,"dedupeLatestByKey");var H={async remember(s,t){await Es.log(s,`${ge}${t.type}`,{content:t.content,tags:t.tags??{},source:t.source,provenance:t.provenance??"declared"})},recall(s,t={}){let e=t.limit??oo,r=Math.max(e*io,ao),n=k.query(s,"SELECT id, type, data, timestamp FROM events WHERE type LIKE ? ORDER BY id DESC LIMIT ?",`${fe}%`,r),o=k.query(s,"SELECT id, name, type, shipped_at, data FROM shipped_features ORDER BY shipped_at DESC LIMIT ?",r),i=[...n.map(co),...o.map(uo)];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=>po(a,t.tags??{}))),t.topic&&(i=i.filter(a=>lo(a,t.topic))),i.sort((a,u)=>u.rememberedAt.localeCompare(a.rememberedAt)),t.dedupeByKey!==!1&&(i=mo(i)),i.slice(0,e)},similar(s,t,e=10){let r=t.toLowerCase().split(/[^a-z0-9]+/).filter(i=>i.length>3);return r.length===0?[]:H.recall(s,{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(s){if(s.length===0)return"> No matching memory entries.";let t=new Map;for(let a of s){let u=t.get(a.type)??[];u.push(a),t.set(a.type,u)}let e=["decision","learning","anti-pattern","gotcha","pattern","fact","inbox","todo","idea","insight","question","source","person","shipped"],r=[],n={declared:"DECL",extracted:"EXTR",inferred:"INFR",ambiguous:"AMBG"},o=c((a,u)=>{if(u.length!==0){r.push(`### ${a.toUpperCase()}`);for(let p of u){let m=Object.entries(p.tags).map(([h,N])=>`${h}=${N}`).join(" "),d=m?` _(${m})_`:"",g=n[p.provenance];r.push(`- \`${g}\` [${p.id}] ${p.content}${d}`)}r.push("")}},"renderGroup"),i=new Set;for(let a of e){let u=t.get(a);!u||u.length===0||(o(a,u),i.add(a))}for(let[a,u]of t)i.has(a)||o(a,u);return r.join(`
524
+ `).trim()}c(it,"formatMemoryMd");var go=[{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 xs(s){let t=[];for(let{name:e,re:r}of go)r.test(s)&&t.push(e);return t}c(xs,"scanForSecrets");var vs=`Base types: ${ws.join(", ")}. Any lowercase identifier is accepted (e.g. "recipe", "okr").`;function Ps(s){let t=s;t.tool("prjct_mem_save",`Save a memory entry. ${vs} 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.")},w("prjct_mem_save",async e=>{await x(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. ${vs}`}]};let n=xs(e.content);return n.length>0&&!e.force?{content:[{type:"text",text:`Refused \u2014 content looks like a secret (${n.join(", ")}). Re-call with force=true if intentional.`}]}:(await H.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)")},w("prjct_mem_list",async e=>{let r=await x(e.projectPath),n=H.recall(r,{topic:e.topic,types:e.types,tags:e.tags,limit:e.limit});return{content:[{type:"text",text:it(n)}]}})),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)")},w("prjct_mem_similar",async e=>{let r=await x(e.projectPath),n=H.similar(r,e.description,e.limit);return n.length===0?{content:[{type:"text",text:"No similar memories found."}]}:{content:[{type:"text",text:it(n)}]}})),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")')},w("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(Ps,"registerMemoryTools");import{z as Te}from"zod";var he=class{static{c(this,"LLMAnalysisStorage")}save(t,e){let r=y.getDb(t),n=f();r.transaction(()=>{r.prepare("UPDATE llm_analysis SET status = 'superseded', superseded_at = ? WHERE status = 'active'").run(n),r.prepare("INSERT INTO llm_analysis (commit_hash, status, analysis, analyzed_at) VALUES (?, ?, ?, ?)").run(e.commitHash??null,"active",JSON.stringify(e),e.analyzedAt)})()}getActive(t){let e=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(n=>{let o=JSON.parse(n.analysis);return{id:n.id,commitHash:n.commit_hash,status:n.status,analyzedAt:n.analyzed_at,patternCount:o.patterns.length}})}},fo=new he,_s=fo;var Rs={critical:0,high:1,medium:2,low:3},As={active:0,previously_active:1,backlog:2};function Ns(s){return[...s].sort((t,e)=>{let r=As[t.section]-As[e.section];return r!==0?r:Rs[t.priority]-Rs[e.priority]})}c(Ns,"sortBySectionAndPriority");var ye=class extends K{static{c(this,"QueueStorage")}constructor(){super("queue.json",Nr)}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 Ns(e)[0]||null}async addTask(t,e){let r={...e,id:U(),createdAt:f(),completed:!1};return await this.update(t,n=>({tasks:[...n.tasks,r],lastUpdated:f()})),await this.publishEvent(t,"queue.task_added",{taskId:r.id,description:r.description,priority:r.priority,section:r.section}),r}async addTasks(t,e){let r=f(),n=e.map(o=>({...o,id:U(),createdAt:r,completed:!1}));return await this.update(t,o=>({tasks:[...o.tasks,...n],lastUpdated:r})),await this.publishEvent(t,"queue.tasks_added",{count:n.length,tasks:n.map(o=>({id:o.id,description:o.description}))}),n}async removeTask(t,e){await this.update(t,r=>({tasks:r.tasks.filter(n=>n.id!==e),lastUpdated:f()})),await this.publishEvent(t,"queue.task_removed",{taskId:e})}async completeTask(t,e){let r=null;if(await this.update(t,n=>({tasks:n.tasks.map(i=>i.id===e?(r={...i,completed:!0,completedAt:f()},r):i),lastUpdated:f()})),r){let n=r;await this.publishEvent(t,"queue.task_completed",{taskId:e,description:n.description,completedAt:n.completedAt})}return r}async moveToSection(t,e,r){await this.update(t,n=>({tasks:n.tasks.map(o=>o.id===e?{...o,section:r}:o),lastUpdated:f()}))}async setPriority(t,e,r){await this.update(t,n=>({tasks:n.tasks.map(o=>o.id===e?{...o,priority:r}:o),lastUpdated:f()}))}async getTask(t,e){return(await this.read(t)).tasks.find(n=>n.id===e)||null}async updateTask(t,e,r){let n=null;return await this.update(t,o=>({tasks:o.tasks.map(i=>i.id===e?(n={...i,...r},n):i),lastUpdated:f()})),n&&await this.publishEvent(t,"queue.task_updated",{taskId:e}),n}async clearCompleted(t){let r=(await this.read(t)).tasks.filter(n=>n.completed).length;return await this.update(t,n=>({tasks:n.tasks.filter(o=>!o.completed),lastUpdated:f()})),r}async removeStaleCompleted(t){let e=await this.read(t),r=Ae(ot.QUEUE_COMPLETED_DAYS),n=e.tasks.filter(i=>i.completed&&i.completedAt&&new Date(i.completedAt)<r);if(n.length===0)return 0;z.archiveMany(t,n.map(i=>({entityType:"queue_task",entityId:i.id,entityData:i,summary:i.description,reason:"age"})));let o=new Set(n.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:n.length}),n.length}},Cs=new ye;function Is(s){let t=s;t.tool("prjct_task_status","Current task, duration, subtasks, and queue",{projectPath:Te.string().describe("Project directory path")},w("prjct_task_status",async e=>{let r=await x(e.projectPath),n=await V.getCurrentTask(r),o=await Cs.getActiveTasks(r),i=[];if(n?(i.push(`## Active Task
525
+ **${n.description}**`),n.branch&&i.push(`Branch: ${n.branch}`),i.push(`Started: ${n.startedAt}`)):i.push("No active task."),o.length>0){i.push(`
526
+ ## 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(`
527
+ `)}]}})),t.tool("prjct_analysis","LLM analysis: stack, patterns, anti-patterns, conventions",{projectPath:Te.string().describe("Project directory path")},w("prjct_analysis",async e=>{let r=await x(e.projectPath),n=_s.getActive(r);if(!n)return{content:[{type:"text",text:"No analysis available. Run `prjct sync`."}]};let o=["## Project Analysis"];if(n.stack&&(o.push(`
528
+ ### Stack`),n.stack.languages?.length&&o.push(`Languages: ${n.stack.languages.join(", ")}`),n.stack.frameworks?.length&&o.push(`Frameworks: ${n.stack.frameworks.join(", ")}`),n.stack.packageManager&&o.push(`Package Manager: ${n.stack.packageManager}`)),n.patterns?.length){o.push(`
529
+ ### Patterns (${n.patterns.length})`);for(let i of n.patterns)o.push(`- **${i.name}**: ${i.description}`)}if(n.antiPatterns?.length){o.push(`
530
+ ### Anti-Patterns (${n.antiPatterns.length})`);for(let i of n.antiPatterns)o.push(`- **${i.issue}**: ${i.suggestion}`)}if(n.conventions?.length){o.push(`
531
+ ### Conventions (${n.conventions.length})`);for(let i of n.conventions)o.push(`- [${i.category}] ${i.rule}`)}return{content:[{type:"text",text:o.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:Te.string().describe("Project directory path")},w("prjct_patterns",async e=>{let r=await x(e.projectPath),n=H.recall(r,{types:["decision","pattern","anti-pattern","gotcha"],limit:50});return n.length===0?{content:[{type:"text",text:"No decisions or patterns captured yet."}]}:{content:[{type:"text",text:it(n)}]}}))}c(Is,"registerProjectTools");import{z as xt}from"zod";var ke=class{static{c(this,"CustomWorkflowStorage")}createWorkflow(t,e){let r=new Date().toISOString();k.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 n=k.get(t,"SELECT id FROM custom_workflows WHERE name = ?",e.name);if(!n)throw new Error(`Failed to create workflow: ${e.name}`);return n.id}getWorkflow(t,e){let r=k.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 k.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),k.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 k.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}}},St=new ke;function Ee(s){let t=s.trust_source==="imported"?"imported":"local";return{id:s.id,type:s.type,command:s.command,position:s.position,action:s.action,description:s.description,enabled:s.enabled===1,timeoutMs:s.timeout_ms,createdAt:s.created_at,sortOrder:s.sort_order,whenExpr:s.when_expr??null,parallel:s.parallel===null?!0:s.parallel===1,trustSource:t}}c(Ee,"rowToRule");var be=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),n=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,n,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 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),y.run(t,`UPDATE workflow_rules SET ${i.join(", ")} WHERE id = ?`,...a)),!0}getRuleById(t,e){let r=y.get(t,"SELECT * FROM workflow_rules WHERE id = ?",e);return r?Ee(r):null}getRulesForCommand(t,e){let r=St.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(Ee)}getAllRules(t){return y.query(t,"SELECT * FROM workflow_rules ORDER BY command ASC, sort_order ASC").map(Ee)}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}},we=new be;function Ds(s){let t=s;t.tool("prjct_workflow_rules","Get workflow rules for a command (gates, hooks, steps, instructions)",{projectPath:xt.string().describe("Project directory path"),command:xt.string().describe("Command name (task, done, ship, sync, etc.)")},w("prjct_workflow_rules",async e=>{let r=await x(e.projectPath),n=we.getRulesForCommand(r,e.command);if(n.length===0)return{content:[{type:"text",text:`No workflow rules for \`${e.command}\`.`}]};let o={};for(let a of n){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(`
535
+ ### ${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(`
536
+ `)}]}})),t.tool("prjct_workflow_list","List all workflows for this project (built-in + custom)",{projectPath:xt.string().describe("Project directory path")},w("prjct_workflow_list",async e=>{let r=await x(e.projectPath),n=St.getAllWorkflows(r);if(n.length===0)return{content:[{type:"text",text:"No workflows configured."}]};let o=n.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 (${n.length})
537
+
538
+ ${o.join(`
539
+ `)}`}]}})),t.tool("prjct_workflow_status","Current workflow execution state + active rules",{projectPath:xt.string().describe("Project directory path")},w("prjct_workflow_status",async e=>{let r=await x(e.projectPath),n=await V.getCurrentTask(r),o=we.getAllRules(r),i=["## Workflow Status"];n?(i.push(`
540
+ Active task: **${n.description}**`),i.push(`Started: ${n.startedAt}`)):i.push(`
541
+ No active task.`);let a=o.filter(u=>u.enabled);if(a.length>0){i.push(`
542
+ ### Active Rules (${a.length})`);for(let u of a)i.push(`- [${u.type}] ${u.command}:${u.position} \u2192 ${u.action}`)}else i.push(`
543
+ No active workflow rules.`);return{content:[{type:"text",text:i.join(`
544
+ `)}]}}))}c(Ds,"registerWorkflowTools");var yo=`# prjct \u2014 persona-aware context broker
545
545
 
546
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.
547
547
 
@@ -556,4 +556,4 @@ Use when you want prior project memory, state, or a registered workflow. You dec
556
556
  - Memory is best-effort \u2014 never assume recall returned everything; it's a query, not a lookup.
557
557
  - Topic keys are free-form strings; don't invent new vocabularies when existing ones fit.
558
558
  - Not every project defines every memory type \u2014 if one is empty, that's fine.
559
- - Saving a secret-looking string is refused by default. Re-save with a scrubbed version.`;function Fr(){let n=new yn({name:"prjct",version:"1.0.0"},{instructions:En});return Nr(n),Mr(n),Sr(n),jr(n),ar(n),n}c(Fr,"createServer");async function wn(){let n=Fr(),t=new kn;await n.connect(t)}c(wn,"main");wn().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 Ls(){let s=new ho({name:"prjct",version:"1.0.0"},{instructions:yo});return Ps(s),Is(s),ks(s),Ds(s),Sr(s),s}c(Ls,"createServer");async function ko(){let s=Ls(),t=new To;await s.connect(t)}c(ko,"main");ko().catch(s=>{console.error("prjct MCP server failed:",s),process.exit(1)});