prjct-cli 2.23.2 → 2.23.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.
- package/CHANGELOG.md +11 -93
- package/README.md +220 -9
- package/dist/bin/prjct-core.mjs +323 -318
- package/dist/daemon/entry.mjs +214 -209
- package/dist/mcp/server.mjs +36 -36
- package/package.json +1 -1
package/dist/mcp/server.mjs
CHANGED
|
@@ -5,13 +5,13 @@ import { dirname as __pathDirname } from 'path';
|
|
|
5
5
|
var require = __createRequire(import.meta.url);
|
|
6
6
|
var __filename = __fileURLToPath(import.meta.url);
|
|
7
7
|
var __dirname = __pathDirname(__filename);
|
|
8
|
-
var
|
|
9
|
-
`;await tt.writeFile(r,n,"utf-8")}async function N(r){try{return await tt.access(r),!0}catch(t){if(L(t))return!1;throw t}}async function re(r){try{return(await tt.stat(r)).isDirectory()}catch(t){if(L(t))return!1;throw t}}async function U(r){await tt.mkdir(r,{recursive:!0})}var $=k(()=>{"use strict";ee();
|
|
10
|
-
`).map(o=>o.replace(/^\s*-\s*['"]?|['"]?\s*$/g,"")).filter(Boolean))}else if(t==="npm"||t==="lerna"){let n=I.join(r,"package.json"),i=JSON.parse(await rt.readFile(n,"utf-8"));if(Array.isArray(i.workspaces)?s=i.workspaces:i.workspaces?.packages&&(s=i.workspaces.packages),t==="lerna"){let o=I.join(r,"lerna.json");if(await N(o)){let a=JSON.parse(await rt.readFile(o,"utf-8"));a.packages&&(s=a.packages)}}}else if(t==="nx")s=["apps/*","libs/*","packages/*"];else if(t==="turborepo"){let n=I.join(r,"package.json"),i=JSON.parse(await rt.readFile(n,"utf-8"));Array.isArray(i.workspaces)&&(s=i.workspaces)}s.length===0&&(s=["packages/*","apps/*","libs/*"]);for(let n of s){if(n.startsWith("!"))continue;let i=
|
|
8
|
+
var xt=Object.defineProperty;var Jn=Object.getOwnPropertyDescriptor;var zn=Object.getOwnPropertyNames;var Kn=Object.prototype.hasOwnProperty;var c=(r,t)=>xt(r,"name",{value:t,configurable:!0}),cs=(r=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(r,{get:(t,e)=>(typeof require<"u"?require:t)[e]}):r)(function(r){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+r+'" is not supported')});var k=(r,t)=>()=>(r&&(t=r(r=0)),t);var Q=(r,t)=>{for(var e in t)xt(r,e,{get:t[e],enumerable:!0})},Vn=(r,t,e,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of zn(t))!Kn.call(r,n)&&n!==e&&xt(r,n,{get:()=>t[n],enumerable:!(s=Jn(t,n))||s.enumerable});return r};var te=r=>Vn(xt({},"__esModule",{value:!0}),r);var us,ls,ps,ee=k(()=>{"use strict";us=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"]),ls=["",".ts",".tsx",".js",".jsx","/index.ts","/index.js"],ps=/(?:import|from)\s+['"]([^'"]+)['"]/g});import{formatDistanceToNowStrict as la}from"date-fns";function ds(r){return{year:r.getFullYear().toString(),month:(r.getMonth()+1).toString().padStart(2,"0"),day:r.getDate().toString().padStart(2,"0")}}function g(){return new Date().toISOString()}function ms(r){let t=new Date;return t.setDate(t.getDate()-r),t}var C=k(()=>{"use strict";c(ds,"getYearMonthDay");c(g,"getTimestamp");c(ms,"getDaysAgo")});function Zn(r){return r instanceof Error&&"code"in r}function L(r){return Zn(r)&&r.code==="ENOENT"}function gs(r){return r instanceof Error?r.message:typeof r=="string"?r:"Unknown error"}var Z=k(()=>{"use strict";c(Zn,"isNodeError");c(L,"isNotFoundError");c(gs,"getErrorMessage")});import ys from"node:fs/promises";async function Ts(r,t){let e;try{e=await ys.readFile(r,"utf-8")}catch(i){if(L(i))return null;throw i}let s;try{s=JSON.parse(e)}catch{return await fs(r,e),hs(r,"Malformed JSON"),null}let n=t.safeParse(s);return n.success?s:(await fs(r,e),hs(r,ti(n.error)),null)}async function fs(r,t){let e=`${r}.backup`;try{await ys.writeFile(e,t,{encoding:"utf-8",flag:"wx"})}catch{}}function hs(r,t){console.error(`[prjct] Warning: Corrupted storage file: ${r}`),console.error(`[prjct] Reason: ${t}`),console.error("[prjct] A .backup file has been created. Returning defaults.")}function ti(r){return r.issues.slice(0,3).map(t=>`${t.path.join(".")}: ${t.message}`).join("; ")}var ks=k(()=>{"use strict";Z();c(Ts,"safeRead");c(fs,"createBackup");c(hs,"logCorruption");c(ti,"formatZodError")});import tt from"node:fs/promises";import se from"node:path";async function Es(r,t={}){let e=[],s=t.maxFiles??1/0,n=t.dotfileAllowlist?new Set(t.dotfileAllowlist):null;async function i(o){if(e.length>=s)return;let a=await tt.readdir(o,{withFileTypes:!0}).catch(()=>[]);for(let u of a){if(e.length>=s)break;let p=String(u.name);if(us.has(p)||t.skipDotfiles&&p.startsWith(".")&&(!n||!n.has(p)))continue;let m=se.join(o,p);u.isDirectory()?await i(m):u.isFile()&&e.push(se.relative(r,m))}}return c(i,"walk"),await i(r),e}async function Ss(r,t,e){let s=[];for(let n=0;n<r.length;n+=t){let i=await Promise.all(r.slice(n,n+t).map(e));for(let o of i)o!==null&&s.push(o)}return s}async function Pt(r,t=null,e){if(e)return await Ts(r,e)??t;try{let s=await tt.readFile(r,"utf-8");return JSON.parse(s)}catch(s){if(L(s))return t;throw s}}async function F(r,t,e=2){let s=se.dirname(r);await tt.mkdir(s,{recursive:!0});let n=`${JSON.stringify(t,null,e)}
|
|
9
|
+
`;await tt.writeFile(r,n,"utf-8")}async function N(r){try{return await tt.access(r),!0}catch(t){if(L(t))return!1;throw t}}async function re(r){try{return(await tt.stat(r)).isDirectory()}catch(t){if(L(t))return!1;throw t}}async function U(r){await tt.mkdir(r,{recursive:!0})}var $=k(()=>{"use strict";ee();ks();Z();c(Es,"walkDir");c(Ss,"batchProcess");c(Pt,"readJson");c(F,"writeJson");c(N,"fileExists");c(re,"dirExists");c(U,"ensureDir")});import rt from"node:fs/promises";import I from"node:path";import{globSync as ei}from"glob";async function ne(r){let t={isMonorepo:!1,type:null,rootPath:r,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 s of e)if(await N(I.join(r,s.file))){t.isMonorepo=!0,t.type=s.type;break}if(!t.isMonorepo){let s=I.join(r,"package.json");if(await N(s))try{JSON.parse(await rt.readFile(s,"utf-8")).workspaces&&(t.isMonorepo=!0,t.type="npm")}catch{}}return t.isMonorepo&&(t.packages=await ie(r,t.type)),t}async function ie(r,t){let e=[],s=[];try{if(t==="pnpm"){let i=(await rt.readFile(I.join(r,"pnpm-workspace.yaml"),"utf-8")).match(/packages:\s*\n((?:\s*-\s*.+\n?)+)/);i&&(s=i[1].split(`
|
|
10
|
+
`).map(o=>o.replace(/^\s*-\s*['"]?|['"]?\s*$/g,"")).filter(Boolean))}else if(t==="npm"||t==="lerna"){let n=I.join(r,"package.json"),i=JSON.parse(await rt.readFile(n,"utf-8"));if(Array.isArray(i.workspaces)?s=i.workspaces:i.workspaces?.packages&&(s=i.workspaces.packages),t==="lerna"){let o=I.join(r,"lerna.json");if(await N(o)){let a=JSON.parse(await rt.readFile(o,"utf-8"));a.packages&&(s=a.packages)}}}else if(t==="nx")s=["apps/*","libs/*","packages/*"];else if(t==="turborepo"){let n=I.join(r,"package.json"),i=JSON.parse(await rt.readFile(n,"utf-8"));Array.isArray(i.workspaces)&&(s=i.workspaces)}s.length===0&&(s=["packages/*","apps/*","libs/*"]);for(let n of s){if(n.startsWith("!"))continue;let i=ei(n,{cwd:r,absolute:!1});for(let o of i){let a=I.join(r,o),u=I.join(a,"package.json");if(await N(u))try{let p=JSON.parse(await rt.readFile(u,"utf-8")),m=I.join(a,"PRJCT.md");e.push({name:p.name||I.basename(o),path:a,relativePath:o,hasPrjctMd:await N(m)})}catch{}}}}catch{}return e}async function ws(r,t){if(!t.isMonorepo)return null;let e=I.resolve(r);for(let s of t.packages){let n=I.resolve(s.path);if(e.startsWith(n))return s}return null}async function bs(r){let t=I.resolve(r),e=I.parse(t).root;for(;t!==e;){if((await ne(t)).isMonorepo)return t;t=I.dirname(t)}return null}var _s=k(()=>{"use strict";$();c(ne,"detectMonorepo");c(ie,"discoverMonorepoPackages");c(ws,"findContainingPackage");c(bs,"findMonorepoRoot")});import{exec as si,execFile as ri}from"node:child_process";import{promisify as vs}from"node:util";var _,Na,nt=k(()=>{"use strict";_=vs(si),Na=vs(ri)});var ce={};Q(ce,{default:()=>ni,worktreeService:()=>Ps});import oe from"node:fs/promises";import X from"node:path";var xs,ae,Ps,ni,ue=k(()=>{"use strict";nt();$();xs=".worktrees",ae=class{static{c(this,"WorktreeService")}async create(t,e,s={}){let n=await this.getMainWorktree(t),i=X.join(n,xs,e),o=s.branch||`feat/${e}`;await oe.mkdir(X.join(n,xs),{recursive:!0});let a=s.baseBranch?` ${s.baseBranch}`:"";await _(`git worktree add "${i}" -b "${o}"${a}`,{cwd:n});let{stdout:u}=await _("git rev-parse HEAD",{cwd:i});return{path:i,branch:o,commit:u.trim(),isMain:!1,slug:e}}async remove(t,e=!1){let s=await this.getMainWorktree(t),n;if(e)try{let{stdout:i}=await _("git rev-parse --abbrev-ref HEAD",{cwd:t});n=i.trim()}catch{}if(await _(`git worktree remove "${t}" --force`,{cwd:s}),e&&n&&n!=="main"&&n!=="master")try{await _(`git branch -D "${n}"`,{cwd:s})}catch{}}async list(t){let e=await this.getMainWorktree(t),{stdout:s}=await _("git worktree list --porcelain",{cwd:e});return this.parsePorcelainOutput(s,e)}async detect(t){try{let{stdout:e}=await _("git rev-parse --git-common-dir",{cwd:t}),{stdout:s}=await _("git rev-parse --git-dir",{cwd:t}),n=X.resolve(t,e.trim()),i=X.resolve(t,s.trim());if(n!==i){let{stdout:o}=await _("git rev-parse --abbrev-ref HEAD",{cwd:t}),{stdout:a}=await _("git rev-parse HEAD",{cwd:t}),{stdout:u}=await _("git rev-parse --show-toplevel",{cwd:t}),p=u.trim(),m=X.basename(p);return{path:p,branch:o.trim(),commit:a.trim(),isMain:!1,slug:m}}return null}catch{return null}}async getMainWorktree(t){try{let{stdout:s}=await _("git worktree list --porcelain",{cwd:t}),n=s.split(`
|
|
11
11
|
`)[0];if(n?.startsWith("worktree "))return n.replace("worktree ","").trim()}catch{}let{stdout:e}=await _("git rev-parse --show-toplevel",{cwd:t});return e.trim()}async setup(t,e){let s=X.join(e,".env");await N(s)&&await oe.copyFile(s,X.join(t,".env"));let n=X.join(e,".prjct"),i=X.join(t,".prjct");await N(n)&&!await N(i)&&await oe.symlink(n,i,"dir")}async teardown(t){}async clean(t){let e=await this.list(t),s=[],n=await this.getMainWorktree(t);await _("git worktree prune",{cwd:n});for(let i of e)i.isMain||await N(i.path)||s.push(i.slug);return s}parsePorcelainOutput(t,e){let s=[],n=t.trim().split(`
|
|
12
12
|
|
|
13
13
|
`);for(let i of n){if(!i.trim())continue;let o=i.trim().split(`
|
|
14
|
-
`),a="",u="",p="",m=!1;for(let d of o)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;s.push({path:a,branch:p,commit:u,isMain:d,slug:d?"main":X.basename(a)})}}return s}},xs=new ae,ri=xs});import le from"node:os";import W from"node:path";async function Ps(r,t){if(t&&t.trim().length>0)return ii(r,t);let e=await ni(r),n=W.basename(W.resolve(e)).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"project";return W.join(le.homedir(),"Documents","prjct",n)}function Rs(r,t){let s=W.basename(W.resolve(r)).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"project",n=t.replace(/-/g,"").slice(0,8);return W.join(le.homedir(),"Documents","prjct",`${s}-${n}`)}function As(r){return W.join(r,".prjct","wiki")}async function ni(r){try{let{worktreeService:t}=await Promise.resolve().then(()=>(ue(),ce));return await t.detect(r)&&await t.getMainWorktree(r)||r}catch{return r}}function ii(r,t){let e=t.trim();return(e.startsWith("~/")||e==="~")&&(e=W.join(le.homedir(),e.slice(1))),W.isAbsolute(e)||(e=W.resolve(r,e)),e}var Cs=k(()=>{"use strict";c(Ps,"getWikiPath");c(Rs,"getWikiPathWithProjectHash");c(As,"getLegacyWikiPath");c(ni,"resolveProjectRootPath");c(ii,"resolveVaultOverride")});var Ns=k(()=>{"use strict"});import{z as gt}from"zod";function Is(r,t){let e=r.split(".").map(Number),s=t.split(".").map(Number);for(let n=0;n<3;n++){let i=e[n]??0,o=s[n]??0;if(i<o)return-1;if(i>o)return 1}return 0}var pe,de=k(()=>{"use strict";pe=gt.object({provider:gt.string(),model:gt.string(),cliVersion:gt.string().optional(),recordedAt:gt.string()});c(Is,"compareSemver")});function Ds(r,t){let e=typeof r=="string"?new Date(r).getTime():r;return Date.now()-e>t}var Rt,me=k(()=>{"use strict";c(Ds,"isExpired");Rt=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((s,n)=>s[1].timestamp-n[1].timestamp).slice(0,this.cache.size-this.maxSize);for(let[s]of e)this.cache.delete(s)}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 oi from"node:fs/promises";import ai from"node:path";async function Os(){try{let r=await oi.readFile(Ls(),"utf-8"),t=JSON.parse(r);return!t.timestamp||!t.detection||!t.detection.claude||!t.detection.gemini||!t.detection.codex||Ds(t.timestamp,ci)?null:t.detection}catch{return null}}async function js(r){let t={timestamp:new Date().toISOString(),detection:r};await F(Ls(),t)}var Ls,ci,Ms=k(()=>{"use strict";it();me();$();Ls=c(()=>ai.join(v.getCachePath(),"providers.json"),"cacheFile"),ci=10*60*1e3;c(Os,"readProviderCache");c(js,"writeProviderCache")});var Ct={};Q(Ct,{ClaudeProvider:()=>At,CursorProvider:()=>$s,GeminiProvider:()=>fe,Providers:()=>ft,detectAllProviders:()=>he,detectAntigravity:()=>mi,detectCodex:()=>Hs,detectProvider:()=>ge,getActiveProvider:()=>pi,getProviderBranding:()=>di,selectProvider:()=>gi,validateCliVersion:()=>Bs});import K from"node:os";import B from"node:path";async function Ws(r){try{let{stdout:t}=await _(`which ${r}`,{timeout:2e3});return t.trim()}catch{return null}}async function li(r){try{let{stdout:t}=await _(`${r} --version`,{timeout:2e3}),e=t.match(/\d+\.\d+\.\d+/);return e?e[0]:t.trim()}catch{return null}}async function ge(r){let t=ft[r];if(!t.cliCommand)return{installed:!1};let e=await Ws(t.cliCommand);if(!e)return{installed:!1};let s=await li(t.cliCommand),n=Bs(r,s||void 0);return{installed:!0,version:s||void 0,path:e,versionWarning:n||void 0}}function Bs(r,t){let e=ft[r];return!e.minCliVersion||!t?null:Is(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 he(r=!1){if(!r){let o=await Os();if(o)return o}let[t,e,s]=await Promise.all([ge("claude"),ge("gemini"),Hs()]),n={installed:s.installed},i={claude:t,gemini:e,codex:n};return await js(i).catch(()=>{}),i}async function pi(r){if(r&&ft[r])return ft[r];let t=await he();return t.claude.installed&&!t.gemini.installed?At:t.gemini.installed&&!t.claude.installed?fe:At}function di(r){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"}[r]||"\u26A1 prjct"}}async function mi(){let r=Us.configDir;if(!r)return{installed:!1,skillInstalled:!1};let t=B.join(r,"skills","prjct","SKILL.md"),[e,s]=await Promise.all([N(r),N(t)]);return{installed:e,skillInstalled:s,configPath:e?r:void 0}}async function Hs(){let r=Xs.configDir;if(!r)return{installed:!1,skillInstalled:!1};let t=await Ws("codex"),e=B.join(r,"skills","prjct","SKILL.md"),s=await N(e),n=!!t;return{installed:n,skillInstalled:s,configPath:n?r:void 0}}async function gi(){let r=await he(),t=r.claude.installed,e=r.gemini.installed;return!t&&!e?{provider:"claude",userSelected:!1,detection:r}:t&&!e?{provider:"claude",userSelected:!1,detection:r}:e&&!t?{provider:"gemini",userSelected:!1,detection:r}:{provider:"claude",userSelected:!0,detection:r}}var At,fe,Us,$s,ui,Xs,ft,Nt=k(()=>{"use strict";Ns();de();nt();$();Ms();At={name:"claude",displayName:"Claude Code",cliCommand:"claude",configDir:B.join(K.homedir(),".claude"),contextFile:"CLAUDE.md",skillsDir:B.join(K.homedir(),".claude","skills"),commandsDir:".claude/commands",commandFormat:"md",settingsFile:"settings.json",projectSettingsFile:"settings.local.json",ignoreFile:".claudeignore",websiteUrl:"https://www.anthropic.com/claude",docsUrl:"https://docs.anthropic.com/claude-code",defaultModel:"sonnet",supportedModels:["opus","sonnet","haiku"],minCliVersion:"1.0.0",capabilityTier:"full"},fe={name:"gemini",displayName:"Gemini CLI",cliCommand:"gemini",configDir:B.join(K.homedir(),".gemini"),contextFile:"GEMINI.md",skillsDir:B.join(K.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"},Us={name:"antigravity",displayName:"Google Antigravity",cliCommand:null,configDir:B.join(K.homedir(),".gemini","antigravity"),contextFile:"ANTIGRAVITY.md",skillsDir:B.join(K.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"},$s={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"},ui={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"},Xs={name:"codex",displayName:"OpenAI Codex",cliCommand:"codex",configDir:B.join(K.homedir(),".codex"),contextFile:"AGENTS.md",skillsDir:B.join(K.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"},ft={claude:At,gemini:fe,cursor:$s,antigravity:Us,windsurf:ui,codex:Xs};c(Ws,"whichCommand");c(li,"getCliVersion");c(ge,"detectProvider");c(Bs,"validateCliVersion");c(he,"detectAllProviders");c(pi,"getActiveProvider");c(di,"getProviderBranding");c(mi,"detectAntigravity");c(Hs,"detectCodex");c(gi,"selectProvider")});import fi from"node:crypto";import It from"node:fs/promises";import ye from"node:os";import S from"node:path";var Te,hi,v,it=k(()=>{"use strict";C();$();bs();Cs();Te=class{static{c(this,"PathManager")}globalBaseDir;globalProjectsDir;globalConfigDir;constructor(){let t=process.env.PRJCT_CLI_HOME?.trim();this.globalBaseDir=t?S.resolve(t):S.join(ye.homedir(),".prjct-cli"),this.globalProjectsDir=S.join(this.globalBaseDir,"projects"),this.globalConfigDir=S.join(this.globalBaseDir,"config")}setGlobalBaseDir(t){this.globalBaseDir=S.resolve(t),this.globalProjectsDir=S.join(this.globalBaseDir,"projects"),this.globalConfigDir=S.join(this.globalBaseDir,"config")}generateProjectId(t){return fi.randomUUID()}getGlobalBasePath(){return this.globalBaseDir}getGlobalProjectPath(t){return S.join(this.globalProjectsDir,t)}getLocalConfigPath(t){return S.join(t,".prjct","prjct.config.json")}getGlobalProjectConfigPath(t){return S.join(this.getGlobalProjectPath(t),"project.json")}getLegacyPrjctPath(t){return S.join(t,".prjct")}async hasLegacyStructure(t){return await re(this.getLegacyPrjctPath(t))}async hasConfig(t){return await N(this.getLocalConfigPath(t))}async ensureGlobalStructure(){await U(this.globalBaseDir),await U(this.globalProjectsDir),await U(this.globalConfigDir)}async ensureProjectStructure(t){await this.ensureGlobalStructure();let e=this.getGlobalProjectPath(t),s=["core","progress","planning","analysis","memory"];for(let n of s)await U(S.join(e,n));return await U(S.join(e,"planning","tasks")),await U(S.join(e,"sessions")),e}getSessionPath(t,e=new Date){let{year:s,month:n,day:i}=ps(e);return S.join(this.getGlobalProjectPath(t),"sessions",s,n,i)}getCurrentSessionPath(t){return this.getSessionPath(t,new Date)}async ensureSessionPath(t,e=new Date){let s=this.getSessionPath(t,e);return await U(s),s}async listSessions(t,e=null,s=null){let n=S.join(this.getGlobalProjectPath(t),"sessions"),i=[];try{let o=await It.readdir(n,{withFileTypes:!0});for(let a of o){if(!a.isDirectory()||e&&a.name!==e.toString())continue;let u=S.join(n,a.name),p=await It.readdir(u,{withFileTypes:!0});for(let m of p){if(!m.isDirectory()||s&&m.name!==s.toString().padStart(2,"0"))continue;let d=S.join(u,m.name),f=await It.readdir(d,{withFileTypes:!0});for(let y of f)y.isDirectory()&&i.push({year:a.name,month:m.name,day:y.name,path:S.join(d,y.name),date:new Date(`${a.name}-${m.name}-${y.name}`)})}}return i.sort((a,u)=>u.date.getTime()-a.date.getTime()),i}catch{return[]}}async getSessionsInRange(t,e,s=new Date){return(await this.listSessions(t)).filter(i=>i.date>=e&&i.date<=s)}getFilePath(t,e,s){return S.join(this.getGlobalProjectPath(t),e,s)}async listProjects(){try{return await this.ensureGlobalStructure(),(await It.readdir(this.globalProjectsDir,{withFileTypes:!0})).filter(e=>e.isDirectory()).map(e=>e.name)}catch{return[]}}async projectExists(t){return await re(this.getGlobalProjectPath(t))}getDisplayPath(t){let e=ye.homedir();return t.startsWith(e)?t.replace(e,"~"):t}getAuthConfigPath(){return S.join(this.globalConfigDir,"auth.json")}getSyncPendingPath(t){return S.join(this.getGlobalProjectPath(t),"sync","pending.json")}getLastSyncPath(t){return S.join(this.getGlobalProjectPath(t),"sync","last-sync.json")}getRunningStatusPath(){return S.join(this.globalBaseDir,".running")}getDocsPath(){return S.join(this.globalBaseDir,"docs")}getCachePath(){return S.join(this.globalBaseDir,"cache")}getStatePath(){return S.join(this.globalBaseDir,"state")}getStatusLinePath(){return S.join(this.globalBaseDir,"statusline")}async getAgentDir(){return(await(Nt(),te(Ct)).getActiveProvider()).configDir}async getAgentSettingsPath(){let t=await(Nt(),te(Ct)).getActiveProvider();return(Nt(),te(Ct)).getGlobalSettingsPath(t.name)}getClaudeDir(){return S.join(ye.homedir(),".claude")}getClaudeSettingsPath(){return S.join(this.getClaudeDir(),"settings.json")}getStoragePath(t,e){return S.join(this.getGlobalProjectPath(t),"storage",e)}getContextPath(t){return S.join(this.getGlobalProjectPath(t),"context")}async getWikiPath(t,e){return Ps(t,e)}getWikiPathWithProjectHash(t,e){return Rs(t,e)}getLegacyWikiPath(t){return As(t)}async detectMonorepo(t){return ne(t)}async discoverMonorepoPackages(t,e){return ie(t,e)}async findContainingPackage(t,e){return Ss(t,e)}async findMonorepoRoot(t){return ws(t)}},hi=new Te,v=hi});var qs,Gs=k(()=>{"use strict";qs=`
|
|
14
|
+
`),a="",u="",p="",m=!1;for(let d of o)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;s.push({path:a,branch:p,commit:u,isMain:d,slug:d?"main":X.basename(a)})}}return s}},Ps=new ae,ni=Ps});import le from"node:os";import W from"node:path";async function Rs(r,t){if(t&&t.trim().length>0)return oi(r,t);let e=await ii(r),n=W.basename(W.resolve(e)).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"project";return W.join(le.homedir(),"Documents","prjct",n)}function As(r,t){let s=W.basename(W.resolve(r)).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"project",n=t.replace(/-/g,"").slice(0,8);return W.join(le.homedir(),"Documents","prjct",`${s}-${n}`)}function Cs(r){return W.join(r,".prjct","wiki")}async function ii(r){try{let{worktreeService:t}=await Promise.resolve().then(()=>(ue(),ce));return await t.detect(r)&&await t.getMainWorktree(r)||r}catch{return r}}function oi(r,t){let e=t.trim();return(e.startsWith("~/")||e==="~")&&(e=W.join(le.homedir(),e.slice(1))),W.isAbsolute(e)||(e=W.resolve(r,e)),e}var Ns=k(()=>{"use strict";c(Rs,"getWikiPath");c(As,"getWikiPathWithProjectHash");c(Cs,"getLegacyWikiPath");c(ii,"resolveProjectRootPath");c(oi,"resolveVaultOverride")});var Is=k(()=>{"use strict"});import{z as gt}from"zod";function Ds(r,t){let e=r.split(".").map(Number),s=t.split(".").map(Number);for(let n=0;n<3;n++){let i=e[n]??0,o=s[n]??0;if(i<o)return-1;if(i>o)return 1}return 0}var pe,de=k(()=>{"use strict";pe=gt.object({provider:gt.string(),model:gt.string(),cliVersion:gt.string().optional(),recordedAt:gt.string()});c(Ds,"compareSemver")});function Ls(r,t){let e=typeof r=="string"?new Date(r).getTime():r;return Date.now()-e>t}var At,me=k(()=>{"use strict";c(Ls,"isExpired");At=class{static{c(this,"TTLCache")}cache=new Map;ttl;maxSize;constructor(t={}){this.ttl=t.ttl??5e3,this.maxSize=t.maxSize??50}isValid(t){let e=this.cache.get(t);return e?Date.now()-e.timestamp<this.ttl:!1}get(t){let e=this.cache.get(t);return e?this.isValid(t)?e.data:(this.cache.delete(t),null):null}set(t,e){this.cache.set(t,{data:e,timestamp:Date.now()}),this.evictOldEntries()}delete(t){this.cache.delete(t)}clear(){this.cache.clear()}has(t){return this.cache.has(t)}get size(){return this.cache.size}evictOldEntries(){if(this.cache.size<=this.maxSize)return;let e=Array.from(this.cache.entries()).sort((s,n)=>s[1].timestamp-n[1].timestamp).slice(0,this.cache.size-this.maxSize);for(let[s]of e)this.cache.delete(s)}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 ai from"node:fs/promises";import ci from"node:path";async function Ms(){try{let r=await ai.readFile(Os(),"utf-8"),t=JSON.parse(r);return!t.timestamp||!t.detection||!t.detection.claude||!t.detection.gemini||!t.detection.codex||Ls(t.timestamp,ui)?null:t.detection}catch{return null}}async function js(r){let t={timestamp:new Date().toISOString(),detection:r};await F(Os(),t)}var Os,ui,Fs=k(()=>{"use strict";it();me();$();Os=c(()=>ci.join(v.getCachePath(),"providers.json"),"cacheFile"),ui=10*60*1e3;c(Ms,"readProviderCache");c(js,"writeProviderCache")});var Nt={};Q(Nt,{ClaudeProvider:()=>Ct,CursorProvider:()=>Xs,GeminiProvider:()=>fe,Providers:()=>ft,detectAllProviders:()=>he,detectAntigravity:()=>gi,detectCodex:()=>qs,detectProvider:()=>ge,getActiveProvider:()=>di,getProviderBranding:()=>mi,selectProvider:()=>fi,validateCliVersion:()=>Hs});import K from"node:os";import B from"node:path";async function Bs(r){try{let{stdout:t}=await _(`which ${r}`,{timeout:2e3});return t.trim()}catch{return null}}async function pi(r){try{let{stdout:t}=await _(`${r} --version`,{timeout:2e3}),e=t.match(/\d+\.\d+\.\d+/);return e?e[0]:t.trim()}catch{return null}}async function ge(r){let t=ft[r];if(!t.cliCommand)return{installed:!1};let e=await Bs(t.cliCommand);if(!e)return{installed:!1};let s=await pi(t.cliCommand),n=Hs(r,s||void 0);return{installed:!0,version:s||void 0,path:e,versionWarning:n||void 0}}function Hs(r,t){let e=ft[r];return!e.minCliVersion||!t?null:Ds(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 he(r=!1){if(!r){let o=await Ms();if(o)return o}let[t,e,s]=await Promise.all([ge("claude"),ge("gemini"),qs()]),n={installed:s.installed},i={claude:t,gemini:e,codex:n};return await js(i).catch(()=>{}),i}async function di(r){if(r&&ft[r])return ft[r];let t=await he();return t.claude.installed&&!t.gemini.installed?Ct:t.gemini.installed&&!t.claude.installed?fe:Ct}function mi(r){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"}[r]||"\u26A1 prjct"}}async function gi(){let r=$s.configDir;if(!r)return{installed:!1,skillInstalled:!1};let t=B.join(r,"skills","prjct","SKILL.md"),[e,s]=await Promise.all([N(r),N(t)]);return{installed:e,skillInstalled:s,configPath:e?r:void 0}}async function qs(){let r=Ws.configDir;if(!r)return{installed:!1,skillInstalled:!1};let t=await Bs("codex"),e=B.join(r,"skills","prjct","SKILL.md"),s=await N(e),n=!!t;return{installed:n,skillInstalled:s,configPath:n?r:void 0}}async function fi(){let r=await he(),t=r.claude.installed,e=r.gemini.installed;return!t&&!e?{provider:"claude",userSelected:!1,detection:r}:t&&!e?{provider:"claude",userSelected:!1,detection:r}:e&&!t?{provider:"gemini",userSelected:!1,detection:r}:{provider:"claude",userSelected:!0,detection:r}}var Ct,fe,$s,Xs,li,Ws,ft,It=k(()=>{"use strict";Is();de();nt();$();Fs();Ct={name:"claude",displayName:"Claude Code",cliCommand:"claude",configDir:B.join(K.homedir(),".claude"),contextFile:"CLAUDE.md",skillsDir:B.join(K.homedir(),".claude","skills"),commandsDir:".claude/commands",commandFormat:"md",settingsFile:"settings.json",projectSettingsFile:"settings.local.json",ignoreFile:".claudeignore",websiteUrl:"https://www.anthropic.com/claude",docsUrl:"https://docs.anthropic.com/claude-code",defaultModel:"sonnet",supportedModels:["opus","sonnet","haiku"],minCliVersion:"1.0.0",capabilityTier:"full"},fe={name:"gemini",displayName:"Gemini CLI",cliCommand:"gemini",configDir:B.join(K.homedir(),".gemini"),contextFile:"GEMINI.md",skillsDir:B.join(K.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"},$s={name:"antigravity",displayName:"Google Antigravity",cliCommand:null,configDir:B.join(K.homedir(),".gemini","antigravity"),contextFile:"ANTIGRAVITY.md",skillsDir:B.join(K.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"},Xs={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"},li={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"},Ws={name:"codex",displayName:"OpenAI Codex",cliCommand:"codex",configDir:B.join(K.homedir(),".codex"),contextFile:"AGENTS.md",skillsDir:B.join(K.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"},ft={claude:Ct,gemini:fe,cursor:Xs,antigravity:$s,windsurf:li,codex:Ws};c(Bs,"whichCommand");c(pi,"getCliVersion");c(ge,"detectProvider");c(Hs,"validateCliVersion");c(he,"detectAllProviders");c(di,"getActiveProvider");c(mi,"getProviderBranding");c(gi,"detectAntigravity");c(qs,"detectCodex");c(fi,"selectProvider")});import hi from"node:crypto";import Dt from"node:fs/promises";import ye from"node:os";import S from"node:path";var Te,yi,v,it=k(()=>{"use strict";C();$();_s();Ns();Te=class{static{c(this,"PathManager")}globalBaseDir;globalProjectsDir;globalConfigDir;constructor(){let t=process.env.PRJCT_CLI_HOME?.trim();this.globalBaseDir=t?S.resolve(t):S.join(ye.homedir(),".prjct-cli"),this.globalProjectsDir=S.join(this.globalBaseDir,"projects"),this.globalConfigDir=S.join(this.globalBaseDir,"config")}setGlobalBaseDir(t){this.globalBaseDir=S.resolve(t),this.globalProjectsDir=S.join(this.globalBaseDir,"projects"),this.globalConfigDir=S.join(this.globalBaseDir,"config")}generateProjectId(t){return hi.randomUUID()}getGlobalBasePath(){return this.globalBaseDir}getGlobalProjectPath(t){return S.join(this.globalProjectsDir,t)}getLocalConfigPath(t){return S.join(t,".prjct","prjct.config.json")}getGlobalProjectConfigPath(t){return S.join(this.getGlobalProjectPath(t),"project.json")}getLegacyPrjctPath(t){return S.join(t,".prjct")}async hasLegacyStructure(t){return await re(this.getLegacyPrjctPath(t))}async hasConfig(t){return await N(this.getLocalConfigPath(t))}async ensureGlobalStructure(){await U(this.globalBaseDir),await U(this.globalProjectsDir),await U(this.globalConfigDir)}async ensureProjectStructure(t){await this.ensureGlobalStructure();let e=this.getGlobalProjectPath(t),s=["core","progress","planning","analysis","memory"];for(let n of s)await U(S.join(e,n));return await U(S.join(e,"planning","tasks")),await U(S.join(e,"sessions")),e}getSessionPath(t,e=new Date){let{year:s,month:n,day:i}=ds(e);return S.join(this.getGlobalProjectPath(t),"sessions",s,n,i)}getCurrentSessionPath(t){return this.getSessionPath(t,new Date)}async ensureSessionPath(t,e=new Date){let s=this.getSessionPath(t,e);return await U(s),s}async listSessions(t,e=null,s=null){let n=S.join(this.getGlobalProjectPath(t),"sessions"),i=[];try{let o=await Dt.readdir(n,{withFileTypes:!0});for(let a of o){if(!a.isDirectory()||e&&a.name!==e.toString())continue;let u=S.join(n,a.name),p=await Dt.readdir(u,{withFileTypes:!0});for(let m of p){if(!m.isDirectory()||s&&m.name!==s.toString().padStart(2,"0"))continue;let d=S.join(u,m.name),f=await Dt.readdir(d,{withFileTypes:!0});for(let T of f)T.isDirectory()&&i.push({year:a.name,month:m.name,day:T.name,path:S.join(d,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,s=new Date){return(await this.listSessions(t)).filter(i=>i.date>=e&&i.date<=s)}getFilePath(t,e,s){return S.join(this.getGlobalProjectPath(t),e,s)}async listProjects(){try{return await this.ensureGlobalStructure(),(await Dt.readdir(this.globalProjectsDir,{withFileTypes:!0})).filter(e=>e.isDirectory()).map(e=>e.name)}catch{return[]}}async projectExists(t){return await re(this.getGlobalProjectPath(t))}getDisplayPath(t){let e=ye.homedir();return t.startsWith(e)?t.replace(e,"~"):t}getAuthConfigPath(){return S.join(this.globalConfigDir,"auth.json")}getSyncPendingPath(t){return S.join(this.getGlobalProjectPath(t),"sync","pending.json")}getLastSyncPath(t){return S.join(this.getGlobalProjectPath(t),"sync","last-sync.json")}getRunningStatusPath(){return S.join(this.globalBaseDir,".running")}getDocsPath(){return S.join(this.globalBaseDir,"docs")}getCachePath(){return S.join(this.globalBaseDir,"cache")}getStatePath(){return S.join(this.globalBaseDir,"state")}getStatusLinePath(){return S.join(this.globalBaseDir,"statusline")}async getAgentDir(){return(await(It(),te(Nt)).getActiveProvider()).configDir}async getAgentSettingsPath(){let t=await(It(),te(Nt)).getActiveProvider();return(It(),te(Nt)).getGlobalSettingsPath(t.name)}getClaudeDir(){return S.join(ye.homedir(),".claude")}getClaudeSettingsPath(){return S.join(this.getClaudeDir(),"settings.json")}getStoragePath(t,e){return S.join(this.getGlobalProjectPath(t),"storage",e)}getContextPath(t){return S.join(this.getGlobalProjectPath(t),"context")}async getWikiPath(t,e){return Rs(t,e)}getWikiPathWithProjectHash(t,e){return As(t,e)}getLegacyWikiPath(t){return Cs(t)}async detectMonorepo(t){return ne(t)}async discoverMonorepoPackages(t,e){return ie(t,e)}async findContainingPackage(t,e){return ws(t,e)}async findMonorepoRoot(t){return bs(t)}},yi=new Te,v=yi});var Gs,Ys=k(()=>{"use strict";Gs=`
|
|
15
15
|
-- =======================================================================
|
|
16
16
|
-- Document storage (backward-compatible with JSON file pattern)
|
|
17
17
|
-- =======================================================================
|
|
@@ -225,7 +225,7 @@ CREATE TABLE velocity_sprints (
|
|
|
225
225
|
started_at TEXT,
|
|
226
226
|
ended_at TEXT
|
|
227
227
|
);
|
|
228
|
-
`});var Js,
|
|
228
|
+
`});var Js,zs=k(()=>{"use strict";Ys();Js=[{version:1,name:"initial-schema",up:c(r=>{r.run(Gs)},"up")},{version:2,name:"archives-table",up:c(r=>{r.run(`
|
|
229
229
|
-- =======================================================================
|
|
230
230
|
-- Archives: Stale data moved out of active storage (PRJ-267)
|
|
231
231
|
-- =======================================================================
|
|
@@ -531,86 +531,86 @@ CREATE TABLE velocity_sprints (
|
|
|
531
531
|
applied_at TEXT NOT NULL,
|
|
532
532
|
PRIMARY KEY (entity_type, entity_id)
|
|
533
533
|
);
|
|
534
|
-
`)},"up")}]});function
|
|
534
|
+
`)},"up")}]});function Ti(){return typeof globalThis<"u"&&"Bun"in globalThis?"bun":"node"}function Ks(){return Ti()==="bun"}var Vs=k(()=>{"use strict";c(Ti,"detectRuntime");c(Ks,"isBun")});function Qs(r){let t=ki(r);return t.run("PRAGMA journal_mode = WAL"),t.run("PRAGMA busy_timeout = 5000"),t}function ki(r){if(Ks()){let{Database:n}=cs("bun:sqlite");return new n(r,{create:!0})}let t=cs("better-sqlite3"),e=new t(r),s=e.exec.bind(e);return e.run=n=>s(n),e}var Zs=k(()=>{"use strict";Vs();c(Qs,"openDatabase");c(ki,"openRaw")});import ke from"node:fs";import tr from"node:path";function er(r,t){let e=r.transaction(t);return typeof e.immediate=="function"?e.immediate(r):e(r)}var Ei,Ee,E,y,j=k(()=>{"use strict";it();zs();Zs();c(er,"runImmediate");Ei=3,Ee=class{static{c(this,"PrjctDatabase")}connections=new Map;accessOrder=[];statementCache=new WeakMap;prepareCached(t,e){let s=this.statementCache.get(t);s||(s=new Map,this.statementCache.set(t,s));let n=s.get(e);if(n)return n;let i=t.prepare(e);return s.set(e,i),i}getDbPath(t){return tr.join(v.getGlobalProjectPath(t),"prjct.db")}getDb(t){let e=this.connections.get(t);if(e)return this.touchAccessOrder(t),e;this.connections.size>=Ei&&this.evictLru();let s=this.getDbPath(t),n=tr.dirname(s);ke.existsSync(n)||ke.mkdirSync(n,{recursive:!0});let i=Qs(s);return 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&&(this.statementCache.delete(e),e.close(),this.connections.delete(t),this.accessOrder=this.accessOrder.filter(s=>s!==t))}else this.connections.forEach(e=>{this.statementCache.delete(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&&(this.statementCache.delete(e),e.close(),this.connections.delete(t))}checkpointAll(){for(let[t,e]of this.connections)try{this.prepareCached(e,"PRAGMA wal_checkpoint(PASSIVE)").get()}catch{}}exists(t){return ke.existsSync(this.getDbPath(t))}getDoc(t,e){let s=this.getDb(t),n=this.prepareCached(s,"SELECT data FROM kv_store WHERE key = ?").get(e);return n?JSON.parse(n.data):null}setDoc(t,e,s){let n=this.getDb(t),i=JSON.stringify(s),o=new Date().toISOString();this.prepareCached(n,"INSERT OR REPLACE INTO kv_store (key, data, updated_at) VALUES (?, ?, ?)").run(e,i,o)}getDocWithStamp(t,e){let s=this.getDb(t),n=this.prepareCached(s,"SELECT data, updated_at FROM kv_store WHERE key = ?").get(e);return n?{data:JSON.parse(n.data),updatedAt:n.updated_at}:null}nextKvStamp(t,e){let s=this.prepareCached(t,"SELECT updated_at FROM kv_store WHERE key = ?").get(e),n=new Date().toISOString(),i=s?.updated_at;return!i||n>i?n:new Date(new Date(i).getTime()+1).toISOString()}casSetDoc(t,e,s,n){let i=this.getDb(t),o=JSON.stringify(s),a=this.nextKvStamp(i,e);return n===null?this.prepareCached(i,"INSERT INTO kv_store (key, data, updated_at) VALUES (?, ?, ?) ON CONFLICT(key) DO NOTHING").run(e,o,a).changes===1:this.prepareCached(i,"UPDATE kv_store SET data = ?, updated_at = ? WHERE key = ? AND updated_at = ?").run(o,a,e,n).changes===1}deleteDoc(t,e){let s=this.getDb(t);this.prepareCached(s,"DELETE FROM kv_store WHERE key = ?").run(e)}hasDoc(t,e){let s=this.getDb(t);return this.prepareCached(s,"SELECT 1 FROM kv_store WHERE key = ?").get(e)!==null}listDocsByPrefix(t,e){let s=this.getDb(t);return this.prepareCached(s,"SELECT key, data FROM kv_store WHERE key LIKE ? || '%' ORDER BY key").all(e).map(i=>({key:i.key,data:JSON.parse(i.data)}))}appendEvent(t,e,s,n){let i=this.getDb(t),o=new Date().toISOString();this.prepareCached(i,"INSERT INTO events (type, task_id, data, timestamp) VALUES (?, ?, ?, ?)").run(e,n??null,JSON.stringify(s),o)}getEvents(t,e,s=100){let n=this.getDb(t);return e?this.prepareCached(n,"SELECT * FROM events WHERE type = ? ORDER BY id DESC LIMIT ?").all(e,s):this.prepareCached(n,"SELECT * FROM events ORDER BY id DESC LIMIT ?").all(s)}query(t,e,...s){let n=this.getDb(t);return this.prepareCached(n,e).all(...s)}run(t,e,...s){let n=this.getDb(t);return this.prepareCached(n,e).run(...s)}get(t,e,...s){let n=this.getDb(t);return this.prepareCached(n,e).get(...s)??null}transaction(t,e){let s=this.getDb(t);return er(s,e)}runMigrations(t){t.run(`
|
|
535
535
|
CREATE TABLE IF NOT EXISTS _migrations (
|
|
536
536
|
version INTEGER PRIMARY KEY,
|
|
537
537
|
name TEXT NOT NULL,
|
|
538
538
|
applied_at TEXT NOT NULL
|
|
539
539
|
)
|
|
540
|
-
`);let e=new Set(t.prepare("SELECT version FROM _migrations").all().map(s=>s.version));for(let s of Js)e.has(s.version)||tr(t,()=>{s.up(t),t.prepare("INSERT INTO _migrations (version, name, applied_at) VALUES (?, ?, ?)").run(s.version,s.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}},E=new Ee,T=E});function Ci(r){return r instanceof ve}function xe(r){return Ci(r)||r instanceof Error?r.message:typeof r=="string"?r:"Unknown error"}var ve,ur=k(()=>{"use strict";ve=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)}};c(Ci,"isPrjctError");c(xe,"getErrorMessage")});import Pe from"node:fs";import Ot from"node:path";function lr(){if(yt)return yt;let r=__dirname;for(let t=0;t<5;t++){let e=Ot.join(r,"package.json");if(Pe.existsSync(e))try{if(JSON.parse(Pe.readFileSync(e,"utf-8")).name==="prjct-cli")return yt=r,r}catch{}r=Ot.dirname(r)}return yt=Ot.join(__dirname,"..","..",".."),yt}function Ni(){if(at)return at;let r=process.env.PRJCT_VERSION;if(r&&/^\d+\.\d+\.\d+/.test(r))return at=r,at;try{let t=Ot.join(lr(),"package.json");return at=JSON.parse(Pe.readFileSync(t,"utf-8")).version,at}catch(t){return process.env.PRJCT_DEBUG==="1"&&console.error("Failed to read version from package.json:",ms(t)),"0.0.0"}}var at,yt,Re,Zc,pr=k(()=>{"use strict";Z();at=null,yt=null;c(lr,"getPackageRoot");c(Ni,"getVersion");Re=Ni(),Zc=lr()});async function jt(r){try{let{stdout:t}=await _(r,{timeout:5e3});return{success:!0,output:t.trim()}}catch{return{success:!1,output:""}}}async function Ii(){let r=await jt("gh api user --jq .login");return r.success&&r.output||(r=await jt("git config --global github.user"),r.success&&r.output)?r.output:null}async function Di(){let r=await jt("git config user.name");return r.success&&r.output?r.output:null}async function Li(){let r=await jt("git config user.email");return r.success&&r.output?r.output:null}async function dr(){let[r,t,e]=await Promise.all([Ii(),Di(),Li()]);return{github:r,email:e,name:t||r||"Unknown"}}var mr=k(()=>{"use strict";nt();c(jt,"execCommand");c(Ii,"detectGitHubUsername");c(Di,"detectGitName");c(Li,"detectGitEmail");c(dr,"detect")});var fr={};Q(fr,{default:()=>H});import Ae from"node:fs/promises";import ji from"node:path";import*as Mt from"jsonc-parser";function gr(r){let t=[],e=Mt.parse(r,t,{allowTrailingComma:!0,disallowComments:!1});if(t.length>0){let s=t[0];throw new SyntaxError(`JSON parse error at offset ${s.offset}: ${Mt.printParseErrorCode(s.error)}`)}return e}var Ce,Mi,H,Tt=k(()=>{"use strict";ur();Z();C();$();pr();mr();it();c(gr,"parseJsonc");Ce=class{static{c(this,"ConfigManager")}async readConfig(t){try{let e=v.getLocalConfigPath(t),s=await Ae.readFile(e,"utf-8");return gr(s)}catch(e){return L(e)||console.warn(`Warning: Could not read config at ${t}: ${xe(e)}`),null}}async writeConfig(t,e){let s=v.getLocalConfigPath(t);await F(s,e)}async readGlobalConfig(t){try{let e=v.getGlobalProjectConfigPath(t),s=await Ae.readFile(e,"utf-8");return gr(s)}catch(e){return L(e)||console.warn(`Warning: Could not read global config for ${t}: ${xe(e)}`),null}}async writeGlobalConfig(t,e){let s=v.getGlobalProjectConfigPath(t);await F(s,e)}async ensureGlobalConfig(t){let e=await this.readGlobalConfig(t);if(!e){let s=g();e={projectId:t,authors:[],version:Re,lastSync:s},await this.writeGlobalConfig(t,e)}return e}async createConfig(t,e){let s=v.generateProjectId(t),n=v.getGlobalProjectPath(s),i=v.getDisplayPath(n),o=g(),a={projectId:s,dataPath:i,showMetrics:!0};await this.writeConfig(t,a);let u={projectId:s,authors:[{name:e.name||"Unknown",email:e.email||"",github:e.github||"",firstContribution:o,lastActivity:o}],version:Re,created:o,lastSync:o};return await this.writeGlobalConfig(s,u),a}async updateLastSync(t){let e=await this.getProjectId(t),s=await this.readGlobalConfig(e);s&&(s.lastSync=g(),await this.writeGlobalConfig(e,s))}validateConfig(t){return!(!t||!t.projectId||!t.dataPath)}async needsMigration(t){if(!await v.hasLegacyStructure(t))return!1;if(!await v.hasConfig(t))return!0;let n=await this.readConfig(t);if(!n||!n.projectId)return!0;let i=v.getGlobalProjectPath(n.projectId);try{return(await Ae.readdir(ji.join(i,"core"))).length===0}catch(o){return L(o),!0}}async getProjectId(t){let e=await this.readConfig(t);if(e?.projectId)return e.projectId;try{let{worktreeService:s}=await Promise.resolve().then(()=>(ue(),ce));if(await s.detect(t)){let i=await s.getMainWorktree(t);if(i!==t){let o=await this.readConfig(i);if(o?.projectId)return o.projectId}}}catch{}return""}async findAuthor(t,e){let s=await this.readGlobalConfig(t);return!s||!s.authors?null:s.authors.find(n=>n.github===e)||null}async addAuthor(t,e){let s=await this.ensureGlobalConfig(t);if(s.authors.some(o=>o.github===e.github))return;let i=g();s.authors.push({name:e.name||"Unknown",email:e.email||"",github:e.github||"",firstContribution:i,lastActivity:i}),s.lastSync=i,await this.writeGlobalConfig(t,s)}async updateAuthorActivity(t,e){let s=await this.readGlobalConfig(t);if(!s||!s.authors)return;let n=s.authors.find(i=>i.github===e);n&&(n.lastActivity=g(),s.lastSync=n.lastActivity,await this.writeGlobalConfig(t,s))}async getCurrentAuthor(t){let e=await dr(),s=await this.getProjectId(t);return await this.addAuthor(s,{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 s=await this.readConfig(t);s&&(s.showMetrics=e,await this.writeConfig(t,s))}async getConfigWithDefaults(t){let e=await this.readConfig(t);if(e)return e;let s=v.generateProjectId(t);return{projectId:s,dataPath:v.getDisplayPath(v.getGlobalProjectPath(s))}}},Mi=new Ce,H=Mi});import{z as l}from"zod";var Ui,Ft,$i,Xi,Ne,Tr,kr,Er,Sr,yr,Wi,Bi,Hi,wr,qi,br,Ut=k(()=>{"use strict";de();Ui=l.enum(["low","medium","high","critical"]),Ft=l.enum(["feature","bug","improvement","chore"]),$i=l.enum(["active","backlog","previously_active"]),Xi=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()}),Tr=l.object({output:l.string().min(1,"Subtask output is required"),summary:Ne}),kr=l.object({id:l.string(),description:l.string(),domain:l.string(),agent:l.string(),status:Xi,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()}),Er=l.object({completed:l.number(),total:l.number(),percentage:l.number()}),Sr=l.object({id:l.string(),description:l.string(),type:Ft.optional(),startedAt:l.string(),sessionId:l.string(),featureId:l.string().optional(),subtasks:l.array(kr).optional(),currentSubtaskIndex:l.number().optional(),subtaskProgress:Er.optional(),linearId:l.string().optional(),linearUuid:l.string().optional(),linkedSpecId:l.string().optional(),estimatedPoints:l.number().optional(),estimatedMinutes:l.number().optional(),modelMetadata:pe.optional(),tokensIn:l.number().optional(),tokensOut:l.number().optional(),parentDescription:l.string().optional(),branch:l.string().optional(),prUrl:l.string().optional()}),yr=l.object({id:l.string(),description:l.string(),status:l.literal("paused"),startedAt:l.string(),pausedAt:l.string(),pauseReason:l.string().optional(),type:Ft.optional(),sessionId:l.string().optional(),featureId:l.string().optional(),subtasks:l.array(kr).optional(),currentSubtaskIndex:l.number().optional(),subtaskProgress:Er.optional(),linearId:l.string().optional(),linearUuid:l.string().optional(),estimatedPoints:l.number().optional(),estimatedMinutes:l.number().optional(),modelMetadata:pe.optional(),tokensIn:l.number().optional(),tokensOut:l.number().optional()}),Wi=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()}),Bi=l.object({taskId:l.string(),title:l.string(),classification:Ft,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:Wi.optional(),tokensIn:l.number().optional(),tokensOut:l.number().optional()}),Hi=Sr.extend({workspaceId:l.string(),worktreePath:l.string().optional(),agentSessionId:l.string().optional(),jiraId:l.string().optional(),jiraUuid:l.string().optional(),dispatchedFrom:l.string().optional()}),wr=l.object({currentTask:Sr.nullable(),previousTask:yr.nullable().optional(),pausedTasks:l.array(yr).optional(),taskHistory:l.array(Bi).optional(),activeTasks:l.array(Hi).optional(),lastUpdated:l.string()}),qi=l.object({id:l.string(),description:l.string(),body:l.string().optional(),priority:Ui,type:Ft,featureId:l.string().optional(),originFeature:l.string().optional(),completed:l.boolean(),completedAt:l.string().optional(),createdAt:l.string(),section:$i,agent:l.string().optional(),groupName:l.string().optional(),groupId:l.string().optional()}),br=l.object({tasks:l.array(qi),lastUpdated:l.string()})});import Gi from"node:crypto";function q(){return Gi.randomUUID()}var Et=k(()=>{"use strict";c(q,"generateUUID")});var Le,et,_r=k(()=>{"use strict";C();M();Le=class{static{c(this,"SyncPendingStorage")}append(t,e){let s=g(),n=JSON.stringify(e);return e.entityType&&e.entityId&&e.contentHash&&T.run(t,`DELETE FROM sync_pending
|
|
540
|
+
`);let e=new Set(t.prepare("SELECT version FROM _migrations").all().map(s=>s.version));for(let s of Js)e.has(s.version)||er(t,()=>{s.up(t),t.prepare("INSERT INTO _migrations (version, name, applied_at) VALUES (?, ?, ?)").run(s.version,s.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}},E=new Ee,y=E});function Ni(r){return r instanceof ve}function xe(r){return Ni(r)||r instanceof Error?r.message:typeof r=="string"?r:"Unknown error"}var ve,lr=k(()=>{"use strict";ve=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)}};c(Ni,"isPrjctError");c(xe,"getErrorMessage")});import Pe from"node:fs";import Mt from"node:path";function pr(){if(yt)return yt;let r=__dirname;for(let t=0;t<5;t++){let e=Mt.join(r,"package.json");if(Pe.existsSync(e))try{if(JSON.parse(Pe.readFileSync(e,"utf-8")).name==="prjct-cli")return yt=r,r}catch{}r=Mt.dirname(r)}return yt=Mt.join(__dirname,"..","..",".."),yt}function Ii(){if(at)return at;let r=process.env.PRJCT_VERSION;if(r&&/^\d+\.\d+\.\d+/.test(r))return at=r,at;try{let t=Mt.join(pr(),"package.json");return at=JSON.parse(Pe.readFileSync(t,"utf-8")).version,at}catch(t){return process.env.PRJCT_DEBUG==="1"&&console.error("Failed to read version from package.json:",gs(t)),"0.0.0"}}var at,yt,Re,tu,dr=k(()=>{"use strict";Z();at=null,yt=null;c(pr,"getPackageRoot");c(Ii,"getVersion");Re=Ii(),tu=pr()});async function jt(r){try{let{stdout:t}=await _(r,{timeout:5e3});return{success:!0,output:t.trim()}}catch{return{success:!1,output:""}}}async function Di(){let r=await jt("gh api user --jq .login");return r.success&&r.output||(r=await jt("git config --global github.user"),r.success&&r.output)?r.output:null}async function Li(){let r=await jt("git config user.name");return r.success&&r.output?r.output:null}async function Oi(){let r=await jt("git config user.email");return r.success&&r.output?r.output:null}async function mr(){let[r,t,e]=await Promise.all([Di(),Li(),Oi()]);return{github:r,email:e,name:t||r||"Unknown"}}var gr=k(()=>{"use strict";nt();c(jt,"execCommand");c(Di,"detectGitHubUsername");c(Li,"detectGitName");c(Oi,"detectGitEmail");c(mr,"detect")});var hr={};Q(hr,{default:()=>H});import Ae from"node:fs/promises";import ji from"node:path";import*as Ft from"jsonc-parser";function fr(r){let t=[],e=Ft.parse(r,t,{allowTrailingComma:!0,disallowComments:!1});if(t.length>0){let s=t[0];throw new SyntaxError(`JSON parse error at offset ${s.offset}: ${Ft.printParseErrorCode(s.error)}`)}return e}var Ce,Fi,H,Tt=k(()=>{"use strict";lr();Z();C();$();dr();gr();it();c(fr,"parseJsonc");Ce=class{static{c(this,"ConfigManager")}async readConfig(t){try{let e=v.getLocalConfigPath(t),s=await Ae.readFile(e,"utf-8");return fr(s)}catch(e){return L(e)||console.warn(`Warning: Could not read config at ${t}: ${xe(e)}`),null}}async writeConfig(t,e){let s=v.getLocalConfigPath(t);await F(s,e)}async readGlobalConfig(t){try{let e=v.getGlobalProjectConfigPath(t),s=await Ae.readFile(e,"utf-8");return fr(s)}catch(e){return L(e)||console.warn(`Warning: Could not read global config for ${t}: ${xe(e)}`),null}}async writeGlobalConfig(t,e){let s=v.getGlobalProjectConfigPath(t);await F(s,e)}async ensureGlobalConfig(t){let e=await this.readGlobalConfig(t);if(!e){let s=g();e={projectId:t,authors:[],version:Re,lastSync:s},await this.writeGlobalConfig(t,e)}return e}async createConfig(t,e){let s=v.generateProjectId(t),n=v.getGlobalProjectPath(s),i=v.getDisplayPath(n),o=g(),a={projectId:s,dataPath:i,showMetrics:!0};await this.writeConfig(t,a);let u={projectId:s,authors:[{name:e.name||"Unknown",email:e.email||"",github:e.github||"",firstContribution:o,lastActivity:o}],version:Re,created:o,lastSync:o};return await this.writeGlobalConfig(s,u),a}async updateLastSync(t){let e=await this.getProjectId(t),s=await this.readGlobalConfig(e);s&&(s.lastSync=g(),await this.writeGlobalConfig(e,s))}validateConfig(t){return!(!t||!t.projectId||!t.dataPath)}async needsMigration(t){if(!await v.hasLegacyStructure(t))return!1;if(!await v.hasConfig(t))return!0;let n=await this.readConfig(t);if(!n||!n.projectId)return!0;let i=v.getGlobalProjectPath(n.projectId);try{return(await Ae.readdir(ji.join(i,"core"))).length===0}catch(o){return L(o),!0}}async getProjectId(t){let e=await this.readConfig(t);if(e?.projectId)return e.projectId;try{let{worktreeService:s}=await Promise.resolve().then(()=>(ue(),ce));if(await s.detect(t)){let i=await s.getMainWorktree(t);if(i!==t){let o=await this.readConfig(i);if(o?.projectId)return o.projectId}}}catch{}return""}async findAuthor(t,e){let s=await this.readGlobalConfig(t);return!s||!s.authors?null:s.authors.find(n=>n.github===e)||null}async addAuthor(t,e){let s=await this.ensureGlobalConfig(t);if(s.authors.some(o=>o.github===e.github))return;let i=g();s.authors.push({name:e.name||"Unknown",email:e.email||"",github:e.github||"",firstContribution:i,lastActivity:i}),s.lastSync=i,await this.writeGlobalConfig(t,s)}async updateAuthorActivity(t,e){let s=await this.readGlobalConfig(t);if(!s||!s.authors)return;let n=s.authors.find(i=>i.github===e);n&&(n.lastActivity=g(),s.lastSync=n.lastActivity,await this.writeGlobalConfig(t,s))}async getCurrentAuthor(t){let e=await mr(),s=await this.getProjectId(t);return await this.addAuthor(s,{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 s=await this.readConfig(t);s&&(s.showMetrics=e,await this.writeConfig(t,s))}async getConfigWithDefaults(t){let e=await this.readConfig(t);if(e)return e;let s=v.generateProjectId(t);return{projectId:s,dataPath:v.getDisplayPath(v.getGlobalProjectPath(s))}}},Fi=new Ce,H=Fi});import{z as l}from"zod";var $i,Ut,Xi,Wi,Ne,kr,Er,Sr,wr,Tr,Bi,Hi,qi,br,Gi,_r,$t=k(()=>{"use strict";de();$i=l.enum(["low","medium","high","critical"]),Ut=l.enum(["feature","bug","improvement","chore"]),Xi=l.enum(["active","backlog","previously_active"]),Wi=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()}),kr=l.object({output:l.string().min(1,"Subtask output is required"),summary:Ne}),Er=l.object({id:l.string(),description:l.string(),domain:l.string(),agent:l.string(),status:Wi,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()}),Sr=l.object({completed:l.number(),total:l.number(),percentage:l.number()}),wr=l.object({id:l.string(),description:l.string(),type:Ut.optional(),startedAt:l.string(),sessionId:l.string(),featureId:l.string().optional(),subtasks:l.array(Er).optional(),currentSubtaskIndex:l.number().optional(),subtaskProgress:Sr.optional(),linearId:l.string().optional(),linearUuid:l.string().optional(),linkedSpecId:l.string().optional(),estimatedPoints:l.number().optional(),estimatedMinutes:l.number().optional(),modelMetadata:pe.optional(),tokensIn:l.number().optional(),tokensOut:l.number().optional(),parentDescription:l.string().optional(),branch:l.string().optional(),prUrl:l.string().optional()}),Tr=l.object({id:l.string(),description:l.string(),status:l.literal("paused"),startedAt:l.string(),pausedAt:l.string(),pauseReason:l.string().optional(),type:Ut.optional(),sessionId:l.string().optional(),featureId:l.string().optional(),subtasks:l.array(Er).optional(),currentSubtaskIndex:l.number().optional(),subtaskProgress:Sr.optional(),linearId:l.string().optional(),linearUuid:l.string().optional(),estimatedPoints:l.number().optional(),estimatedMinutes:l.number().optional(),modelMetadata:pe.optional(),tokensIn:l.number().optional(),tokensOut:l.number().optional()}),Bi=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()}),Hi=l.object({taskId:l.string(),title:l.string(),classification:Ut,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:Bi.optional(),tokensIn:l.number().optional(),tokensOut:l.number().optional()}),qi=wr.extend({workspaceId:l.string(),worktreePath:l.string().optional(),agentSessionId:l.string().optional(),jiraId:l.string().optional(),jiraUuid:l.string().optional(),dispatchedFrom:l.string().optional()}),br=l.object({currentTask:wr.nullable(),previousTask:Tr.nullable().optional(),pausedTasks:l.array(Tr).optional(),taskHistory:l.array(Hi).optional(),activeTasks:l.array(qi).optional(),lastUpdated:l.string()}),Gi=l.object({id:l.string(),description:l.string(),body:l.string().optional(),priority:$i,type:Ut,featureId:l.string().optional(),originFeature:l.string().optional(),completed:l.boolean(),completedAt:l.string().optional(),createdAt:l.string(),section:Xi,agent:l.string().optional(),groupName:l.string().optional(),groupId:l.string().optional()}),_r=l.object({tasks:l.array(Gi),lastUpdated:l.string()})});import Yi from"node:crypto";function q(){return Yi.randomUUID()}var Et=k(()=>{"use strict";c(q,"generateUUID")});var Le,et,vr=k(()=>{"use strict";C();j();Le=class{static{c(this,"SyncPendingStorage")}append(t,e){let s=g(),n=JSON.stringify(e);return e.entityType&&e.entityId&&e.contentHash&&y.run(t,`DELETE FROM sync_pending
|
|
541
541
|
WHERE project_id = ?
|
|
542
542
|
AND entity_type = ?
|
|
543
543
|
AND entity_id = ?
|
|
544
|
-
AND content_hash = ?`,t,e.entityType,e.entityId,e.contentHash),
|
|
544
|
+
AND content_hash = ?`,t,e.entityType,e.entityId,e.contentHash),y.run(t,`INSERT INTO sync_pending
|
|
545
545
|
(project_id, entity_type, entity_id, event_type, content_hash, payload, enqueued_at)
|
|
546
|
-
VALUES (?, ?, ?, ?, ?, ?, ?)`,t,e.entityType??null,e.entityId??null,e.eventType??null,e.contentHash??null,n,s),{id:T.get(t,"SELECT last_insert_rowid() AS id")?.id??0,event:e,enqueuedAt:s}}list(t,e){let s=e?"SELECT * FROM sync_pending WHERE project_id = ? ORDER BY id ASC LIMIT ?":"SELECT * FROM sync_pending WHERE project_id = ? ORDER BY id ASC";return(e?T.query(t,s,t,e):T.query(t,s,t)).map(i=>this.rowToEntry(i))}count(t){return T.get(t,"SELECT COUNT(*) AS n FROM sync_pending WHERE project_id = ?",t)?.n??0}clearUpTo(t,e){if(e<=0)return 0;let s=this.count(t);return T.run(t,"DELETE FROM sync_pending WHERE project_id = ? AND id <= ?",t,e),s-this.count(t)}clearAll(t){T.run(t,"DELETE FROM sync_pending WHERE project_id = ?",t)}clearByIds(t,e){if(e.length===0)return;let s=e.map(()=>"?").join(",");T.run(t,`DELETE FROM sync_pending WHERE project_id = ? AND id IN (${s})`,t,...e)}rowToEntry(t){let e;try{e=JSON.parse(t.payload)}catch{e={type:"unknown.corrupt",path:[],data:null,timestamp:t.enqueued_at,projectId:t.project_id}}return{id:t.id,event:e,enqueuedAt:t.enqueued_at}}},et=new Le});var Oe,$t,je=k(()=>{"use strict";it();_r();C();$();Oe=class{static{c(this,"SyncEventBus")}async publish(t){et.append(t.projectId,t)}async getPending(t){return et.list(t).map(e=>e.event)}async clearPending(t){et.clearAll(t)}async getPendingEntries(t){return et.list(t)}async clearPendingUpTo(t,e){return et.clearUpTo(t,e)}async clearPendingByIds(t,e){et.clearByIds(t,e)}async updateLastSync(t){let e=v.getLastSyncPath(t),s={timestamp:g(),success:!0};await F(e,s)}async getLastSync(t){let e=v.getLastSyncPath(t);return await xt(e,null)}},$t=new Oe});var Fe={};Q(Fe,{default:()=>Ki});import Ji from"node:crypto";import vr from"node:fs/promises";import xr from"node:os";import Yi from"node:path";function Rr(){return Ji.randomUUID()}var Ar,Pr,Me,zi,Ki,Ue=k(()=>{"use strict";it();$();Ar="https://api.prjct.app",Pr={apiKey:null,apiUrl:Ar,userId:null,email:null,lastAuth:null};c(Rr,"freshDeviceId");Me=class{static{c(this,"AuthConfigManager")}configPath;cachedConfig=null;constructor(){this.configPath=v.getAuthConfigPath()}getConfigPath(){return this.configPath}async read(){if(this.cachedConfig)return this.cachedConfig;let t=await xt(this.configPath),e=t??{...Pr},s=!1;if(e.deviceId||(e.deviceId=Rr(),s=!0),e.hostname||(e.hostname=xr.hostname(),s=!0),this.cachedConfig=e,s&&t)try{await F(this.configPath,this.cachedConfig),await vr.chmod(this.configPath,384)}catch{}return this.cachedConfig}async getDeviceId(){return(await this.read()).deviceId??Rr()}async getHostname(){return(await this.read()).hostname??xr.hostname()}async write(t){let s={...await this.read(),...t,lastAuth:new Date().toISOString()};await U(Yi.dirname(this.configPath)),await F(this.configPath,s),await vr.chmod(this.configPath,384),this.cachedConfig=s}async hasAuth(){let t=await this.read();return t.apiKey!==null&&t.apiKey.length>0}async getApiKey(){return(await this.read()).apiKey}async getApiUrl(){return(await this.read()).apiUrl||Ar}async saveAuth(t,e,s){await this.write({apiKey:t,userId:e,email:s})}async clearAuth(){this.cachedConfig={...Pr},await F(this.configPath,this.cachedConfig)}async getStatus(){let t=await this.read();return{authenticated:t.apiKey!==null,email:t.email,apiKeyPrefix:t.apiKey?`${t.apiKey.substring(0,12)}...`:null,lastAuth:t.lastAuth}}clearCache(){this.cachedConfig=null}},zi=new Me,Ki=zi});var Nr={};Q(Nr,{_resetPublishHelperCache:()=>so,publishCRUD:()=>Cr,publishCRUDSync:()=>G});import Vi from"node:crypto";function Zi(r){let t=r&&typeof r=="object"&&!Array.isArray(r)?JSON.stringify(to(r)):JSON.stringify(r);return Vi.createHash("sha256").update(t).digest("hex")}function to(r){let t={};for(let e of Object.keys(r).sort())t[e]=r[e];return t}async function eo(){if(Xt)return Xt;try{let{default:r}=await Promise.resolve().then(()=>(Ue(),Fe)),t=r;if(typeof t.getDeviceId=="function"){let e=await t.getDeviceId();return Xt=e,e}return"unknown-device"}catch{return"unknown-device"}}function so(){Xt=null}async function Cr(r){try{let t=await eo(),e=Zi(r.data),s={type:`${r.entityType}.${Qi[r.eventType]}`,path:[r.entityType,r.entityId],data:r.data,timestamp:new Date().toISOString(),projectId:r.projectId,entityType:r.entityType,entityId:r.entityId,eventType:r.eventType,contentHash:e,deviceId:t,originDeviceId:r.originDeviceId??t,revisionCount:r.revisionCount??1};await $t.publish(s)}catch{}}function G(r){Cr(r)}var Qi,Xt,St=k(()=>{"use strict";je();Qi={upsert:"updated",delete:"deleted"};c(Zi,"hashPayload");c(to,"sortKeys");Xt=null;c(eo,"resolveDeviceId");c(so,"_resetPublishHelperCache");c(Cr,"publishCRUD");c(G,"publishCRUDSync")});var wt,$e,ct,Wt=k(()=>{"use strict";Et();St();C();M();wt={SHIPPED_RETENTION_DAYS:90,IDEA_DORMANT_DAYS:180,QUEUE_COMPLETED_DAYS:7,PAUSED_TASK_DAYS:30,MEMORY_MAX_ENTRIES:500},$e=class{static{c(this,"ArchiveStorage")}archive(t,e){let s=q(),n=g();return E.run(t,"INSERT INTO archives (id, entity_type, entity_id, entity_data, summary, archived_at, reason) VALUES (?, ?, ?, ?, ?, ?, ?)",s,e.entityType,e.entityId,JSON.stringify(e.entityData),e.summary??null,n,e.reason),G({projectId:t,entityType:"archives",entityId:s,eventType:"upsert",data:{id:s,entity_type:e.entityType,entity_id:e.entityId,summary:e.summary??null,reason:e.reason,archived_at:n}}),s}archiveMany(t,e){if(e.length===0)return 0;let s=g();return E.transaction(t,n=>{let i=n.prepare("INSERT INTO archives (id, entity_type, entity_id, entity_data, summary, archived_at, reason) VALUES (?, ?, ?, ?, ?, ?, ?)");for(let o of e)i.run(q(),o.entityType,o.entityId,JSON.stringify(o.entityData),o.summary??null,s,o.reason)}),e.length}getArchived(t,e,s=50){return e?E.query(t,"SELECT * FROM archives WHERE entity_type = ? ORDER BY archived_at DESC LIMIT ?",e,s):E.query(t,"SELECT * FROM archives ORDER BY archived_at DESC LIMIT ?",s)}getStats(t){let e=E.query(t,"SELECT entity_type, COUNT(*) as count FROM archives GROUP BY entity_type"),s={shipped:0,idea:0,queue_task:0,paused_task:0,memory_entry:0,total:0};for(let n of e){let i=n.entity_type;i in s&&(s[i]=n.count),s.total+=n.count}return s}restore(t,e){let s=E.get(t,"SELECT * FROM archives WHERE id = ?",e);return s?(E.run(t,"DELETE FROM archives WHERE id = ?",e),JSON.parse(s.entity_data)):null}pruneOldArchives(t,e){let s=new Date(Date.now()-e*24*60*60*1e3).toISOString(),n=this.getTotalCount(t);E.run(t,"DELETE FROM archives WHERE archived_at < ?",s);let i=this.getTotalCount(t);return n-i}getTotalCount(t){return E.get(t,"SELECT COUNT(*) as count FROM archives")?.count??0}},ct=new $e});import ao from"node:crypto";function co(r){let[t,e]=r.split(".");return t?{entityType:t.endsWith("s")?t:`${t}s`,eventType:e==="deleted"||e==="archived"||e==="removed"?"delete":"upsert"}:{}}function uo(r){if(!r||typeof r!="object")return;let t=r;for(let e of["taskId","task_id","id","feature_id","featureId","specId","spec_id"]){let s=t[e];if(typeof s=="string"&&s.length>0)return s}}function lo(r){let t=r&&typeof r=="object"&&!Array.isArray(r)?JSON.stringify(po(r)):JSON.stringify(r);return ao.createHash("sha256").update(t).digest("hex")}function po(r){let t={};for(let e of Object.keys(r).sort())t[e]=r[e];return t}async function mo(){if(Bt)return Bt;try{let{default:r}=await Promise.resolve().then(()=>(Ue(),Fe)),t=r;return typeof t.getDeviceId=="function"?(Bt=await t.getDeviceId(),Bt):"unknown-device"}catch{return"unknown-device"}}var Bt,ut,Be=k(()=>{"use strict";je();me();C();M();c(co,"deriveEntityShape");c(uo,"entityIdOf");c(lo,"hashPayload");c(po,"sortKeys");Bt=null;c(mo,"_resolveDeviceId");ut=class{static{c(this,"StorageManager")}filename;cache;constructor(t,e){this.filename=t,this.cache=new Rt({ttl:5e3,maxSize:50})}getStoreKey(){return this.filename.replace(".json","")}async read(t){if(!(process.env.PRJCT_IN_DAEMON==="1"||process.env.PRJCT_DAEMON==="1")){let s=this.cache.get(t);if(s!==null)return s}try{let s=E.getDoc(t,this.getStoreKey());if(s!==null)return this.cache.set(t,s),s}catch{}return this.getDefault()}async write(t,e){E.setDoc(t,this.getStoreKey(),e),this.cache.set(t,e)}async update(t,e){let s=this.getStoreKey(),n=8;for(let i=1;i<=n;i++){let o=E.getDocWithStamp(t,s),a=o?o.data:this.getDefault(),u=e(a);if(E.casSetDoc(t,s,u,o?.updatedAt??null))return this.cache.set(t,u),u}throw new Error(`StorageManager.update: unresolved write contention after ${n} attempts (key=${s})`)}async publishEvent(t,e,s){let n=co(e),i={type:e,path:[this.filename.replace(".json","")],data:s,timestamp:g(),projectId:t,entityType:n.entityType,entityId:uo(s),eventType:n.eventType,contentHash:lo(s),deviceId:await mo(),revisionCount:1};await $t.publish(i)}async publishEntityEvent(t,e,s,n){let i=`${e}.${s}`,o={...n,timestamp:g()};await this.publishEvent(t,i,o)}async exists(t){try{return E.hasDoc(t,this.getStoreKey())}catch{return!1}}clearCache(t){t?this.cache.delete(t):this.cache.clear()}getCacheStats(){return this.cache.stats()}}});var un,ln,pn,dn,mn=k(()=>{"use strict";un={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"]},ln=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".py",".go",".rs",".java",".kt",".swift",".rb",".php",".c",".cpp",".h",".hpp",".cs",".vue",".svelte"]),pn=new Set(["node_modules",".git","dist","build",".next",".nuxt",".output","coverage",".cache","__pycache__",".pytest_cache","vendor","target",".turbo",".vercel"]),dn=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"])});import go from"node:fs/promises";import Ht from"node:path";async function qt(r,t,e={}){let s=Date.now(),n=e.maxFiles??30,i=e.minScore??.1,o=e.includeTests??!1,a=fo(r),u=await ho(t),p=await yo(t),m=[];for(let f of u){if(!o&&ko(f))continue;let y=To(f,a,p,e.historicalBoosts);y.score>=i&&m.push(y)}m.sort((f,y)=>y.score-f.score);let d=m.slice(0,n);return{files:d,metrics:{filesScanned:u.length,filesReturned:d.length,scanDuration:Date.now()-s}}}function fo(r){return r.toLowerCase().split(/[^a-z0-9]+/).filter(Boolean).filter(e=>!dn.has(e)&&e.length>2)}async function ho(r){let t=[];async function e(s,n=""){try{let i=await go.readdir(s,{withFileTypes:!0});for(let o of i){let a=Ht.join(s,o.name),u=Ht.join(n,o.name);if(o.isDirectory()){if(pn.has(o.name)||o.name.startsWith("."))continue;await e(a,u)}else if(o.isFile()){let p=Ht.extname(o.name).toLowerCase();ln.has(p)&&t.push(u)}}}catch(i){L(i)}}return c(e,"walk"),await e(r),t}async function yo(r){let t=new Map;try{let{stdout:e}=await _(`git log -30 --pretty=format:"%H %ct" --name-only | awk '
|
|
546
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)`,t,e.entityType??null,e.entityId??null,e.eventType??null,e.contentHash??null,n,s),{id:y.get(t,"SELECT last_insert_rowid() AS id")?.id??0,event:e,enqueuedAt:s}}list(t,e){let s=e?"SELECT * FROM sync_pending WHERE project_id = ? ORDER BY id ASC LIMIT ?":"SELECT * FROM sync_pending WHERE project_id = ? ORDER BY id ASC";return(e?y.query(t,s,t,e):y.query(t,s,t)).map(i=>this.rowToEntry(i))}count(t){return y.get(t,"SELECT COUNT(*) AS n FROM sync_pending WHERE project_id = ?",t)?.n??0}clearUpTo(t,e){if(e<=0)return 0;let s=this.count(t);return y.run(t,"DELETE FROM sync_pending WHERE project_id = ? AND id <= ?",t,e),s-this.count(t)}clearAll(t){y.run(t,"DELETE FROM sync_pending WHERE project_id = ?",t)}clearByIds(t,e){if(e.length===0)return;let s=e.map(()=>"?").join(",");y.run(t,`DELETE FROM sync_pending WHERE project_id = ? AND id IN (${s})`,t,...e)}rowToEntry(t){let e;try{e=JSON.parse(t.payload)}catch{e={type:"unknown.corrupt",path:[],data:null,timestamp:t.enqueued_at,projectId:t.project_id}}return{id:t.id,event:e,enqueuedAt:t.enqueued_at}}},et=new Le});var Oe,Xt,Me=k(()=>{"use strict";it();vr();C();$();Oe=class{static{c(this,"SyncEventBus")}async publish(t){et.append(t.projectId,t)}async getPending(t){return et.list(t).map(e=>e.event)}async clearPending(t){et.clearAll(t)}async getPendingEntries(t){return et.list(t)}async clearPendingUpTo(t,e){return et.clearUpTo(t,e)}async clearPendingByIds(t,e){et.clearByIds(t,e)}async updateLastSync(t){let e=v.getLastSyncPath(t),s={timestamp:g(),success:!0};await F(e,s)}async getLastSync(t){let e=v.getLastSyncPath(t);return await Pt(e,null)}},Xt=new Oe});var Fe={};Q(Fe,{default:()=>Vi});import Ji from"node:crypto";import xr from"node:fs/promises";import Pr from"node:os";import zi from"node:path";function Ar(){return Ji.randomUUID()}var Cr,Rr,je,Ki,Vi,Ue=k(()=>{"use strict";it();$();Cr="https://api.prjct.app",Rr={apiKey:null,apiUrl:Cr,userId:null,email:null,lastAuth:null};c(Ar,"freshDeviceId");je=class{static{c(this,"AuthConfigManager")}configPath;cachedConfig=null;constructor(){this.configPath=v.getAuthConfigPath()}getConfigPath(){return this.configPath}async read(){if(this.cachedConfig)return this.cachedConfig;let t=await Pt(this.configPath),e=t??{...Rr},s=!1;if(e.deviceId||(e.deviceId=Ar(),s=!0),e.hostname||(e.hostname=Pr.hostname(),s=!0),this.cachedConfig=e,s&&t)try{await F(this.configPath,this.cachedConfig),await xr.chmod(this.configPath,384)}catch{}return this.cachedConfig}async getDeviceId(){return(await this.read()).deviceId??Ar()}async getHostname(){return(await this.read()).hostname??Pr.hostname()}async write(t){let s={...await this.read(),...t,lastAuth:new Date().toISOString()};await U(zi.dirname(this.configPath)),await F(this.configPath,s),await xr.chmod(this.configPath,384),this.cachedConfig=s}async hasAuth(){let t=await this.read();return t.apiKey!==null&&t.apiKey.length>0}async getApiKey(){return(await this.read()).apiKey}async getApiUrl(){return(await this.read()).apiUrl||Cr}async saveAuth(t,e,s){await this.write({apiKey:t,userId:e,email:s})}async clearAuth(){this.cachedConfig={...Rr},await F(this.configPath,this.cachedConfig)}async getStatus(){let t=await this.read();return{authenticated:t.apiKey!==null,email:t.email,apiKeyPrefix:t.apiKey?`${t.apiKey.substring(0,12)}...`:null,lastAuth:t.lastAuth}}clearCache(){this.cachedConfig=null}},Ki=new je,Vi=Ki});var Ir={};Q(Ir,{_resetPublishHelperCache:()=>ro,publishCRUD:()=>Nr,publishCRUDSync:()=>G});import Qi from"node:crypto";function to(r){let t=r&&typeof r=="object"&&!Array.isArray(r)?JSON.stringify(eo(r)):JSON.stringify(r);return Qi.createHash("sha256").update(t).digest("hex")}function eo(r){let t={};for(let e of Object.keys(r).sort())t[e]=r[e];return t}async function so(){if(Wt)return Wt;try{let{default:r}=await Promise.resolve().then(()=>(Ue(),Fe)),t=r;if(typeof t.getDeviceId=="function"){let e=await t.getDeviceId();return Wt=e,e}return"unknown-device"}catch{return"unknown-device"}}function ro(){Wt=null}async function Nr(r){try{let t=await so(),e=to(r.data),s={type:`${r.entityType}.${Zi[r.eventType]}`,path:[r.entityType,r.entityId],data:r.data,timestamp:new Date().toISOString(),projectId:r.projectId,entityType:r.entityType,entityId:r.entityId,eventType:r.eventType,contentHash:e,deviceId:t,originDeviceId:r.originDeviceId??t,revisionCount:r.revisionCount??1};await Xt.publish(s)}catch{}}function G(r){Nr(r)}var Zi,Wt,St=k(()=>{"use strict";Me();Zi={upsert:"updated",delete:"deleted"};c(to,"hashPayload");c(eo,"sortKeys");Wt=null;c(so,"resolveDeviceId");c(ro,"_resetPublishHelperCache");c(Nr,"publishCRUD");c(G,"publishCRUDSync")});var wt,$e,ct,Bt=k(()=>{"use strict";Et();St();C();j();wt={SHIPPED_RETENTION_DAYS:90,IDEA_DORMANT_DAYS:180,QUEUE_COMPLETED_DAYS:7,PAUSED_TASK_DAYS:30,MEMORY_MAX_ENTRIES:500},$e=class{static{c(this,"ArchiveStorage")}archive(t,e){let s=q(),n=g();return E.run(t,"INSERT INTO archives (id, entity_type, entity_id, entity_data, summary, archived_at, reason) VALUES (?, ?, ?, ?, ?, ?, ?)",s,e.entityType,e.entityId,JSON.stringify(e.entityData),e.summary??null,n,e.reason),G({projectId:t,entityType:"archives",entityId:s,eventType:"upsert",data:{id:s,entity_type:e.entityType,entity_id:e.entityId,summary:e.summary??null,reason:e.reason,archived_at:n}}),s}archiveMany(t,e){if(e.length===0)return 0;let s=g();return E.transaction(t,n=>{let i=n.prepare("INSERT INTO archives (id, entity_type, entity_id, entity_data, summary, archived_at, reason) VALUES (?, ?, ?, ?, ?, ?, ?)");for(let o of e)i.run(q(),o.entityType,o.entityId,JSON.stringify(o.entityData),o.summary??null,s,o.reason)}),e.length}getArchived(t,e,s=50){return e?E.query(t,"SELECT * FROM archives WHERE entity_type = ? ORDER BY archived_at DESC LIMIT ?",e,s):E.query(t,"SELECT * FROM archives ORDER BY archived_at DESC LIMIT ?",s)}getStats(t){let e=E.query(t,"SELECT entity_type, COUNT(*) as count FROM archives GROUP BY entity_type"),s={shipped:0,idea:0,queue_task:0,paused_task:0,memory_entry:0,total:0};for(let n of e){let i=n.entity_type;i in s&&(s[i]=n.count),s.total+=n.count}return s}restore(t,e){let s=E.get(t,"SELECT * FROM archives WHERE id = ?",e);return s?(E.run(t,"DELETE FROM archives WHERE id = ?",e),JSON.parse(s.entity_data)):null}pruneOldArchives(t,e){let s=new Date(Date.now()-e*24*60*60*1e3).toISOString(),n=this.getTotalCount(t);E.run(t,"DELETE FROM archives WHERE archived_at < ?",s);let i=this.getTotalCount(t);return n-i}getTotalCount(t){return E.get(t,"SELECT COUNT(*) as count FROM archives")?.count??0}},ct=new $e});import co from"node:crypto";function uo(r){let[t,e]=r.split(".");return t?{entityType:t.endsWith("s")?t:`${t}s`,eventType:e==="deleted"||e==="archived"||e==="removed"?"delete":"upsert"}:{}}function lo(r){if(!r||typeof r!="object")return;let t=r;for(let e of["taskId","task_id","id","feature_id","featureId","specId","spec_id"]){let s=t[e];if(typeof s=="string"&&s.length>0)return s}}function po(r){let t=r&&typeof r=="object"&&!Array.isArray(r)?JSON.stringify(mo(r)):JSON.stringify(r);return co.createHash("sha256").update(t).digest("hex")}function mo(r){let t={};for(let e of Object.keys(r).sort())t[e]=r[e];return t}async function go(){if(Ht)return Ht;try{let{default:r}=await Promise.resolve().then(()=>(Ue(),Fe)),t=r;return typeof t.getDeviceId=="function"?(Ht=await t.getDeviceId(),Ht):"unknown-device"}catch{return"unknown-device"}}var Ht,ut,Be=k(()=>{"use strict";Me();me();C();j();c(uo,"deriveEntityShape");c(lo,"entityIdOf");c(po,"hashPayload");c(mo,"sortKeys");Ht=null;c(go,"_resolveDeviceId");ut=class{static{c(this,"StorageManager")}filename;cache;constructor(t,e){this.filename=t,this.cache=new At({ttl:5e3,maxSize:50})}getStoreKey(){return this.filename.replace(".json","")}async read(t){if(!(process.env.PRJCT_IN_DAEMON==="1"||process.env.PRJCT_DAEMON==="1")){let s=this.cache.get(t);if(s!==null)return s}try{let s=E.getDoc(t,this.getStoreKey());if(s!==null)return this.cache.set(t,s),s}catch{}return this.getDefault()}async write(t,e){E.setDoc(t,this.getStoreKey(),e),this.cache.set(t,e)}async update(t,e){let s=this.getStoreKey(),n=8;for(let i=1;i<=n;i++){let o=E.getDocWithStamp(t,s),a=o?o.data:this.getDefault(),u=e(a);if(E.casSetDoc(t,s,u,o?.updatedAt??null))return this.cache.set(t,u),u}throw new Error(`StorageManager.update: unresolved write contention after ${n} attempts (key=${s})`)}async publishEvent(t,e,s){let n=uo(e),i={type:e,path:[this.filename.replace(".json","")],data:s,timestamp:g(),projectId:t,entityType:n.entityType,entityId:lo(s),eventType:n.eventType,contentHash:po(s),deviceId:await go(),revisionCount:1};await Xt.publish(i)}async publishEntityEvent(t,e,s,n){let i=`${e}.${s}`,o={...n,timestamp:g()};await this.publishEvent(t,i,o)}async exists(t){try{return E.hasDoc(t,this.getStoreKey())}catch{return!1}}clearCache(t){t?this.cache.delete(t):this.cache.clear()}getCacheStats(){return this.cache.stats()}}});var ln,pn,dn,mn,gn=k(()=>{"use strict";ln={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"]},pn=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".py",".go",".rs",".java",".kt",".swift",".rb",".php",".c",".cpp",".h",".hpp",".cs",".vue",".svelte"]),dn=new Set(["node_modules",".git","dist","build",".next",".nuxt",".output","coverage",".cache","__pycache__",".pytest_cache","vendor","target",".turbo",".vercel"]),mn=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"])});import fo from"node:fs/promises";import qt from"node:path";async function Gt(r,t,e={}){let s=Date.now(),n=e.maxFiles??30,i=e.minScore??.1,o=e.includeTests??!1,a=ho(r),u=await yo(t),p=await To(t),m=[];for(let f of u){if(!o&&Eo(f))continue;let T=ko(f,a,p,e.historicalBoosts);T.score>=i&&m.push(T)}m.sort((f,T)=>T.score-f.score);let d=m.slice(0,n);return{files:d,metrics:{filesScanned:u.length,filesReturned:d.length,scanDuration:Date.now()-s}}}function ho(r){return r.toLowerCase().split(/[^a-z0-9]+/).filter(Boolean).filter(e=>!mn.has(e)&&e.length>2)}async function yo(r){let t=[];async function e(s,n=""){try{let i=await fo.readdir(s,{withFileTypes:!0});for(let o of i){let a=qt.join(s,o.name),u=qt.join(n,o.name);if(o.isDirectory()){if(dn.has(o.name)||o.name.startsWith("."))continue;await e(a,u)}else if(o.isFile()){let p=qt.extname(o.name).toLowerCase();pn.has(p)&&t.push(u)}}}catch(i){L(i)}}return c(e,"walk"),await e(r),t}async function To(r){let t=new Map;try{let{stdout:e}=await _(`git log -30 --pretty=format:"%H %ct" --name-only | awk '
|
|
547
547
|
/^[a-f0-9]{40}/ { commit=$1; timestamp=$2; next }
|
|
548
548
|
NF { files[$0]++; if (!lastmod[$0]) lastmod[$0]=timestamp }
|
|
549
549
|
END { for (f in files) print files[f], lastmod[f], f }
|
|
550
550
|
'`,{cwd:r,maxBuffer:10485760}),s=Math.floor(Date.now()/1e3),n=e.trim().split(`
|
|
551
|
-
`).filter(Boolean);for(let i of n){let o=i.match(/^(\d+)\s+(\d+)\s+(.+)$/);if(o){let a=parseInt(o[1],10),u=parseInt(o[2],10),p=o[3],m=Math.floor((s-u)/86400);t.set(p,{commits:a,daysAgo:m})}}}catch{}return t}function
|
|
552
|
-
`).trim()}var
|
|
553
|
-
VALUES (?, ?, 'draft', ?, ?, ?, ?)`,s,e.title,JSON.stringify(i),e.tags?JSON.stringify(e.tags):null,n,n),{id:s,title:e.title,status:"draft",content:i,tags:e.tags??{},createdAt:n,updatedAt:n,shippedAt:null,shippedPr:null,shippedSha:null,archivedAt:null}}get(t,e){let s=
|
|
554
|
-
`)}function
|
|
555
|
-
`)}var
|
|
556
|
-
`)){let o=i.trim();o==="---COMMIT---"?(n&&n.size>0&&n.size<=30&&s.push(n),n=new Set):o&&n&&
|
|
551
|
+
`).filter(Boolean);for(let i of n){let o=i.match(/^(\d+)\s+(\d+)\s+(.+)$/);if(o){let a=parseInt(o[1],10),u=parseInt(o[2],10),p=o[3],m=Math.floor((s-u)/86400);t.set(p,{commits:a,daysAgo:m})}}}catch{}return t}function ko(r,t,e,s){let n=[],i=0,o=0,a=0,u=0,p=0,m=r.toLowerCase(),d=m.split("/").join(" ").split(/[^a-z0-9]+/);for(let A of t){m.includes(A)&&(i+=.3,n.push(`keyword:${A}`));for(let V of d)if(V.includes(A)||A.includes(V)){i+=.15;break}}i=Math.min(1,i);for(let[A,V]of Object.entries(ln))for(let Qt of V)if(m.includes(Qt)&&t.some(Zt=>V.includes(Zt)||Zt.includes(A)||A.includes(Zt))){o+=.4,n.push(`domain:${A}`);break}o=Math.min(1,o);let f=e.get(r);f&&(f.daysAgo<=1?(a=1,n.push("recent:1d")):f.daysAgo<=3?(a=.8,n.push("recent:3d")):f.daysAgo<=7?(a=.6,n.push("recent:1w")):f.daysAgo<=30&&(a=.3,n.push("recent:1m")),f.commits>=5&&(a=Math.min(1,a+.2)));let T=qt.basename(r).toLowerCase();if((T.includes("index")||T.includes("main")||T.includes("app")||T.includes("entry"))&&(u=.5,n.push("import:0")),(m.includes("/core/")||m.includes("/shared/")||m.includes("/lib/"))&&(u=Math.max(u,.3),n.some(A=>A.startsWith("import:"))||n.push("import:1")),s){let A=s.get(r);A!==void 0&&(p=(A+1)/2,A>0?n.push("history:boosted"):A<0&&n.push("history:penalized"))}let z=s&&s.size>0?i*.54+o*.18+a*.13+u*.05+p*.1:i*.6+o*.2+a*.15+u*.05;return{path:r,score:Math.min(1,z),reasons:[...new Set(n)]}}function Eo(r){let t=r.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")}var qe=k(()=>{"use strict";Z();nt();gn();c(Gt,"findRelevantFiles");c(ho,"extractKeywords");c(yo,"getAllCodeFiles");c(To,"getGitRecency");c(ko,"scoreFile");c(Eo,"isTestFile")});var Ye,wn,bn=k(()=>{"use strict";Tt();Bt();j();Ye=class{static{c(this,"MemoryService")}async log(t,e,s,n){try{let i=await H.getProjectId(t);if(!i)return;y.appendEvent(i,`memory.${e}`,{...s,author:n})}catch(i){console.error(`Memory log error: ${i instanceof Error?i.message:String(i)}`)}}async getRecent(t,e=100){try{let s=await H.getProjectId(t);return s?y.query(s,"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(s){return console.error(`Memory read error: ${s instanceof Error?s.message:String(s)}`),[]}}async search(t,e,s=50){let n=await this.getRecent(t,1e3),i=e.toLowerCase();return n.filter(o=>{let a=o.action.toLowerCase().includes(i),u=JSON.stringify(o.data).toLowerCase().includes(i);return a||u}).slice(-s)}async getByAction(t,e,s=50){try{let n=await H.getProjectId(t);return n?y.query(n,"SELECT type, data, timestamp FROM events WHERE type = ? ORDER BY id DESC LIMIT ?",`memory.${e}`,s).reverse().map(o=>{let a=JSON.parse(o.data),{author:u,...p}=a;return{timestamp:o.timestamp,action:o.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 H.getProjectId(t);if(!e)return;y.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 y.query(t,"SELECT type, data, timestamp FROM events WHERE type LIKE 'memory.%' ORDER BY id DESC LIMIT ?",e).reverse().map(n=>{let i=JSON.parse(n.data);return{timestamp:n.timestamp,action:n.type.replace("memory.",""),...i}})}catch(s){return console.error(`Memory read error: ${s instanceof Error?s.message:String(s)}`),[]}}async capEntries(t){try{let s=y.get(t,"SELECT COUNT(*) as cnt FROM events WHERE type LIKE 'memory.%'")?.cnt??0;if(s<=wt.MEMORY_MAX_ENTRIES)return 0;let n=s-wt.MEMORY_MAX_ENTRIES,i=y.query(t,"SELECT id, type, data, timestamp FROM events WHERE type LIKE 'memory.%' ORDER BY id ASC LIMIT ?",n);ct.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&&y.run(t,"DELETE FROM events WHERE type LIKE 'memory.%' AND id <= ?",o),n}catch(e){return console.error(`Memory cap error: ${e instanceof Error?e.message:String(e)}`),0}}},wn=new Ye});var _n,Je,bt,ap,vn=k(()=>{"use strict";_n="memory.",Je="remember.",bt=`${_n}${Je}`,ap=`${_n}task.tagged`});function An(r,t){try{return JSON.parse(r)}catch{return t}}function ze(r){let t=r.type.slice(bt.length),e=An(r.data,{});return{id:`mem_${r.id}`,type:t,content:e.content??"",tags:e.tags??{},rememberedAt:r.timestamp,source:e.source,provenance:e.provenance??"declared"}}function xn(r){let t=r.data?An(r.data,{}):{},e=t.tags??{};return r.type&&(e.type=r.type),{id:`ship_${r.id}`,type:"shipped",content:r.name,tags:e,rememberedAt:r.shipped_at,source:t.taskId,provenance:"extracted"}}function Mo(r,t){let e=t.toLowerCase();if(r.content.toLowerCase().includes(e))return!0;for(let s of Object.values(r.tags))if(s.toLowerCase().includes(e))return!0;return!1}function jo(r,t){for(let[e,s]of Object.entries(t))if(r.tags[e]!==s)return!1;return!0}function Fo(r){let t=new Set,e=[];for(let s of r){let n=s.tags.key;if(!n){e.push(s);continue}let i=`${s.type}::${n}`;t.has(i)||(t.add(i),e.push(s))}return e}function Uo(r){return r.replace(/[[\]|]/g,"").replace(/\s+/g," ").trim()}function Pn(r,t){return r.replace(/\[\[(mem[_-]\d+)\]\]/gi,"$1").replace(/\bmem[_-](\d+)\b/g,(e,s)=>{let n=`mem_${s}`,i=t?.idTypeIndex?.get(n),o=t?.idTitleIndex?.get(n),a=o?Uo(o):n;return i&&t?.perEntryTypes?.has(i)?`[[${n}|${a}]]`:i?`[[${i}#^mem-${s}|${a}]]`:o?`[[${n}|${a}]]`:`\`${n}\``})}function _t(r,t){if(r.length===0)return"> No matching memory entries.";let e=new Map;for(let u of r){let p=e.get(u.type)??[];p.push(u),e.set(u.type,p)}let s=["decision","learning","anti-pattern","gotcha","pattern","fact","inbox","todo","idea","insight","question","source","person","shipped"],n=[],i={declared:"DECL",extracted:"EXTR",inferred:"INFR",ambiguous:"AMBG"},o=c((u,p)=>{if(p.length!==0){n.push(`### ${u.toUpperCase()}`);for(let m of p){let d=Object.entries(m.tags).map(([V,Qt])=>`${V}=${Qt}`).join(" "),f=i[m.provenance],T=t?.vault?Pn(m.content,t):m.content,M=d?` _(${t?.vault?Pn(d,t):d})_`:"",z=m.id.replace(/^mem[_-]/,""),A=t?.vault?` ^mem-${z}`:"";n.push(`- \`${f}\` [${m.id} \xB7 ${m.type}] ${T}${M}${A}`)}n.push("")}},"renderGroup"),a=new Set;for(let u of s){let p=e.get(u);!p||p.length===0||(o(u,p),a.add(u))}for(let[u,p]of e)a.has(u)||o(u,p);return n.join(`
|
|
552
|
+
`).trim()}var Rn,Do,Lo,Oo,O,dt=k(()=>{"use strict";bn();j();vn();Rn=["fact","decision","learning","gotcha","pattern","anti-pattern","shipped","inbox","todo","idea","insight","question","source","person","spec"],Do=25,Lo=4,Oo=100;c(An,"safeJson");c(ze,"rowToEntry");c(xn,"shippedRowToEntry");c(Mo,"matchesTopic");c(jo,"matchesTags");c(Fo,"dedupeLatestByKey");O={async remember(r,t){await wn.log(r,`${Je}${t.type}`,{content:t.content,tags:t.tags??{},source:t.source,provenance:t.provenance??"declared"});try{let{default:e}=await Promise.resolve().then(()=>(Tt(),hr)),n=(await e.readConfig(r))?.projectId;if(!n)return;let{publishCRUD:i}=await Promise.resolve().then(()=>(St(),Ir)),o=t.tags?.spec_id??t.tags?.task_id??t.tags?.id??t.source??`mem-${Date.now()}-${Math.random().toString(36).slice(2,8)}`;await i({projectId:n,entityType:"memories",entityId:o,eventType:"upsert",data:{id:o,type:t.type,content:t.content,tags:t.tags??{},source:t.source??null,provenance:t.provenance??"declared",rememberedAt:new Date().toISOString()}})}catch{}},recall(r,t={}){let e=t.limit??Do,s=Math.max(e*Lo,Oo),n=y.query(r,"SELECT id, type, data, timestamp FROM events WHERE type LIKE ? ORDER BY id DESC LIMIT ?",`${bt}%`,s),i=y.query(r,"SELECT id, name, type, shipped_at, data FROM shipped_features ORDER BY shipped_at DESC LIMIT ?",s),o=[...n.map(ze),...i.map(xn)];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=>jo(a,t.tags??{}))),t.topic&&(o=o.filter(a=>Mo(a,t.topic))),o.sort((a,u)=>u.rememberedAt.localeCompare(a.rememberedAt)),t.dedupeByKey!==!1&&(o=Fo(o)),o.slice(0,e)},getById(r,t){let e=String(t).trim().match(/^(?:mem[_-])?(\d+)$/i);if(!e)return null;let s=Number(e[1]);try{let n=y.get(r,"SELECT id, type, data, timestamp FROM events WHERE id = ? AND type LIKE ?",s,`${bt}%`);return n?ze(n):null}catch{return null}},allEntriesForIndex(r){try{let t=y.query(r,"SELECT id, type, data, timestamp FROM events WHERE type LIKE ? ORDER BY id DESC",`${bt}%`),e=y.query(r,"SELECT id, name, type, shipped_at, data FROM shipped_features ORDER BY shipped_at DESC");return[...t.map(ze),...e.map(xn)]}catch{return[]}},similar(r,t,e=10){let s=t.toLowerCase().split(/[^a-z0-9]+/).filter(o=>o.length>3);return s.length===0?[]:O.recall(r,{limit:200}).map(o=>{let a=`${o.content} ${Object.values(o.tags).join(" ")}`.toLowerCase(),u=s.reduce((p,m)=>a.includes(m)?p+1:p,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)}};c(Uo,"linkLabel");c(Pn,"linkifyMemRefs");c(_t,"formatMemoryMd")});function jn(r){return[...r].sort((t,e)=>{let s=Mn[t.section]-Mn[e.section];return s!==0?s:On[t.priority]-On[e.priority]})}var On,Mn,Fn=k(()=>{"use strict";On={critical:0,high:1,medium:2,low:3},Mn={active:0,previously_active:1,backlog:2};c(jn,"sortBySectionAndPriority")});var Ve,vt,Qe=k(()=>{"use strict";Et();$t();Fn();C();Bt();Be();Ve=class extends ut{static{c(this,"QueueStorage")}constructor(){super("queue.json",_r)}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(s=>s.section==="active"&&!s.completed)}async getBacklog(t){return(await this.read(t)).tasks.filter(s=>s.section==="backlog"&&!s.completed)}async getNextTask(t){let e=await this.getActiveTasks(t);return jn(e)[0]||null}async addTask(t,e){let s={...e,id:q(),createdAt:g(),completed:!1};return await this.update(t,n=>({tasks:[...n.tasks,s],lastUpdated:g()})),await this.publishEvent(t,"queue.task_added",{taskId:s.id,description:s.description,priority:s.priority,section:s.section}),s}async addTasks(t,e){let s=g(),n=e.map(i=>({...i,id:q(),createdAt:s,completed:!1}));return await this.update(t,i=>({tasks:[...i.tasks,...n],lastUpdated:s})),await this.publishEvent(t,"queue.tasks_added",{count:n.length,tasks:n.map(i=>({id:i.id,description:i.description}))}),n}async removeTask(t,e){await this.update(t,s=>({tasks:s.tasks.filter(n=>n.id!==e),lastUpdated:g()})),await this.publishEvent(t,"queue.task_removed",{taskId:e})}async deleteByFeatureId(t,e){let s=0;return await this.update(t,n=>{let i=n.tasks.length,o=n.tasks.filter(a=>a.featureId!==e);return s=i-o.length,{tasks:o,lastUpdated:g()}}),s>0&&await this.publishEvent(t,"queue.tasks_removed_by_feature",{featureId:e,count:s}),s}async completeTask(t,e){let s=null;if(await this.update(t,n=>({tasks:n.tasks.map(o=>o.id===e?(s={...o,completed:!0,completedAt:g()},s):o),lastUpdated:g()})),s){let n=s;await this.publishEvent(t,"queue.task_completed",{taskId:e,description:n.description,completedAt:n.completedAt})}return s}async moveToSection(t,e,s){await this.update(t,n=>({tasks:n.tasks.map(i=>i.id===e?{...i,section:s}:i),lastUpdated:g()}))}async setPriority(t,e,s){await this.update(t,n=>({tasks:n.tasks.map(i=>i.id===e?{...i,priority:s}:i),lastUpdated:g()}))}async getTask(t,e){return(await this.read(t)).tasks.find(n=>n.id===e)||null}async updateTask(t,e,s){let n=null;return await this.update(t,i=>({tasks:i.tasks.map(o=>o.id===e?(n={...o,...s},n):o),lastUpdated:g()})),n&&await this.publishEvent(t,"queue.task_updated",{taskId:e}),n}async clearCompleted(t){let s=(await this.read(t)).tasks.filter(n=>n.completed).length;return await this.update(t,n=>({tasks:n.tasks.filter(i=>!i.completed),lastUpdated:g()})),s}async removeStaleCompleted(t){let e=await this.read(t),s=ms(wt.QUEUE_COMPLETED_DAYS),n=e.tasks.filter(o=>o.completed&&o.completedAt&&new Date(o.completedAt)<s);if(n.length===0)return 0;ct.archiveMany(t,n.map(o=>({entityType:"queue_task",entityId:o.id,entityData:o,summary:o.description,reason:"age"})));let i=new Set(n.map(o=>o.id));return await this.update(t,o=>({tasks:o.tasks.filter(a=>!i.has(a.id)),lastUpdated:g()})),await this.publishEvent(t,"queue.stale_removed",{count:n.length}),n.length}},vt=new Ve});import{z as b}from"zod";var mt,es,ts,Xo,Y,Jt=k(()=>{"use strict";mt=["draft","reviewed","in_progress","shipped","archived"],es=["strategic","architecture","design"],ts=b.object({verdict:b.enum(["pass","fail"]),notes:b.string(),ts:b.string()}),Xo=b.object({risk:b.string().min(1),mitigation:b.string().min(1)}),Y=b.object({goal:b.string().min(1),eli10:b.string().default(""),stakes:b.string().default(""),acceptance_criteria:b.array(b.string().min(1)).default([]),scope:b.array(b.string()).default([]),out_of_scope:b.array(b.string()).default([]),risks:b.array(Xo).default([]),test_plan:b.array(b.string()).default([]),reviews:b.object({strategic:ts.optional(),architecture:ts.optional(),design:ts.optional()}).optional(),linked_tasks:b.array(b.string()).default([]),notes:b.string().default(""),tasks_created_at:b.string().nullable().default(null)})});var ss,x,zt=k(()=>{"use strict";Et();Jt();C();j();ss=class{static{c(this,"SpecStorage")}nextUpdatedAt(t,e){let s=g(),i=y.get(t,"SELECT updated_at FROM specs WHERE id = ?",e)?.updated_at;return!i||s>i?s:new Date(new Date(i).getTime()+1).toISOString()}create(t,e){let s=q(),n=g(),i=Y.parse(e.content);return y.run(t,`INSERT INTO specs (id, title, status, content, tags, created_at, updated_at)
|
|
553
|
+
VALUES (?, ?, 'draft', ?, ?, ?, ?)`,s,e.title,JSON.stringify(i),e.tags?JSON.stringify(e.tags):null,n,n),{id:s,title:e.title,status:"draft",content:i,tags:e.tags??{},createdAt:n,updatedAt:n,shippedAt:null,shippedPr:null,shippedSha:null,archivedAt:null}}get(t,e){let s=y.get(t,"SELECT * FROM specs WHERE id = ?",e);return s?this.rowToSpec(s):null}list(t,e={}){let s="SELECT * FROM specs WHERE 1=1",n=[];return e.status&&(s+=" AND status = ?",n.push(e.status)),!e.includeArchived&&!e.status&&(s+=" AND status != 'archived'"),s+=" ORDER BY created_at DESC",y.query(t,s,...n).map(o=>this.rowToSpec(o))}search(t,e){let s=`%${e}%`;return y.query(t,"SELECT * FROM specs WHERE title LIKE ? OR content LIKE ? ORDER BY created_at DESC",s,s).map(i=>this.rowToSpec(i))}updateContent(t,e,s){let n=Y.parse(s),i=this.nextUpdatedAt(t,e);return y.run(t,"UPDATE specs SET content = ?, updated_at = ? WHERE id = ?",JSON.stringify(n),i,e),this.get(t,e)}casUpdate(t,e,s,n){let i=Y.parse(s),o=this.nextUpdatedAt(t,e);return y.run(t,"UPDATE specs SET content = ?, updated_at = ? WHERE id = ? AND updated_at = ?",JSON.stringify(i),o,e,n).changes===1}setStatus(t,e,s){if(!mt.includes(s))throw new Error(`invalid spec status: ${s}`);let n=this.nextUpdatedAt(t,e),i=[],o=[s,n];s==="shipped"&&(i.push("shipped_at = ?"),o.push(n)),s==="archived"&&(i.push("archived_at = ?"),o.push(n));let a=["status = ?","updated_at = ?",...i].join(", ");return o.push(e),y.run(t,`UPDATE specs SET ${a} WHERE id = ?`,...o),this.get(t,e)}setShippedPr(t,e,s){return y.run(t,"UPDATE specs SET shipped_pr = ?, updated_at = ? WHERE id = ?",s,this.nextUpdatedAt(t,e),e),this.get(t,e)}setShippedSha(t,e,s){return y.run(t,"UPDATE specs SET shipped_sha = ?, updated_at = ? WHERE id = ?",s,this.nextUpdatedAt(t,e),e),this.get(t,e)}linkTask(t,e,s){let n=this.get(t,e);if(!n)return null;if(n.content.linked_tasks.includes(s))return n;let i={...n.content,linked_tasks:[...n.content.linked_tasks,s]};return this.updateContent(t,e,i)}delete(t,e){return this.get(t,e)?(y.run(t,"DELETE FROM specs WHERE id = ?",e),!0):!1}count(t){let e=y.query(t,"SELECT status, COUNT(*) AS n FROM specs GROUP BY status"),s={total:0,draft:0,shipped:0};for(let n of e)s.total+=n.n,n.status==="draft"&&(s.draft=n.n),n.status==="shipped"&&(s.shipped=n.n);return s}rowToSpec(t){return{id:t.id,title:t.title,status:mt.includes(t.status)?t.status:"draft",content:Y.parse(JSON.parse(t.content)),tags:t.tags?JSON.parse(t.tags):{},createdAt:t.created_at,updatedAt:t.updated_at,shippedAt:t.shipped_at,shippedPr:t.shipped_pr,shippedSha:t.shipped_sha,archivedAt:t.archived_at}}},x=new ss});var Xn={};Q(Xn,{inferSpecContext:()=>Ho,warnNoContextMatch:()=>Yo});async function Ho(r,t,e){let[s,n]=await Promise.all([Gt(r,e,{maxFiles:$n*4,minScore:Bo}).catch(()=>({files:[]})),Promise.resolve(O.recall(t,{topic:r,limit:Wo})).catch(()=>[])]),i=qo(s.files.map(u=>u.path),$n);return i.length===0&&n.length===0?{notesBlock:"",paths:[],memoryHits:0,empty:!0}:{notesBlock:Go(r,i,n),paths:i,memoryHits:n.length,empty:!1}}function qo(r,t){let e=new Set,s=[];for(let n of r){let i=n.split("/").slice(0,2).join("/");if(!e.has(i)&&(e.add(i),s.push(n),s.length>=t))break}return s}function Go(r,t,e){let s=[];if(s.push("<!-- auto-context:tentative -->"),s.push("## Existing context (auto-inferred)"),s.push(""),s.push(`_Inferred from title "${r}". Validate before audit \u2014 entries tagged tentative._`),s.push(""),t.length>0){s.push("### Likely paths");for(let n of t)s.push(`- \`${n}\``);s.push("")}if(e.length>0){s.push("### Relevant prior memory");for(let n of e){let i=n.content.length>140?`${n.content.slice(0,137)}\u2026`:n.content,o=Object.entries(n.tags).map(([a,u])=>`${a}:${u}`).join(" ");s.push(`- **${n.type}**${o?` _(${o})_`:""} \u2014 ${i}`)}s.push("")}return s.push("<!-- /auto-context -->"),s.join(`
|
|
554
|
+
`)}function Yo(r,t){let e={level:"warn",code:"no_context_match",message:`No codebase or memory context matched "${r}"`,suggestion:t??"Fill spec.notes manually or run with `--skip-context` next time."};process.stderr.write(`${JSON.stringify(e)}
|
|
555
|
+
`)}var $n,Wo,Bo,Wn=k(()=>{"use strict";dt();qe();$n=5,Wo=8,Bo=.15;c(Ho,"inferSpecContext");c(qo,"dedupeTopDirs");c(Go,"buildNotesBlock");c(Yo,"warnNoContextMatch")});var Bn={};Q(Bn,{breakdownSpecToTasks:()=>Jo});async function Jo(r,t,e){let s=e.content.acceptance_criteria;if(s.length===0)return{taskIds:[],skippedReason:"no_acceptance_criteria"};if(e.content.tasks_created_at!==null)return{taskIds:[],skippedReason:"already_broken_down"};let n=!1;if(e.content.linked_tasks.length>0){n=!0,await vt.deleteByFeatureId(r,e.id);let a={...e.content,linked_tasks:[]};x.updateContent(r,e.id,a)}let i=await vt.addTasks(r,s.map(a=>({description:zo(a),body:a,priority:"medium",type:"feature",section:"backlog",featureId:e.id,groupId:e.id,groupName:e.title})));for(let a of i)x.linkTask(r,e.id,a.id);let o=x.get(r,e.id);if(o){let a={...o.content,tasks_created_at:g()};x.updateContent(r,e.id,a)}return await O.remember(t,{type:"spec",content:`Auto-breakdown: ${i.length} tasks created from ${e.title}${n?" (recovered from partial)":""}`,tags:{spec_id:e.id,event:"auto_breakdown",task_count:String(i.length),...n?{recovered:"partial"}:{}},source:e.id}),{taskIds:i.map(a=>a.id),...n?{recoveredFromPartial:!0}:{}}}function zo(r){let t=r.replace(/\s+/g," ").trim();return t.length<=140?t:`${t.slice(0,137)}\u2026`}var Hn=k(()=>{"use strict";dt();Qe();zt();C();c(Jo,"breakdownSpecToTasks");c(zo,"truncateForDescription")});import{StdioServerTransport as na}from"@modelcontextprotocol/sdk/server/stdio.js";import{McpServer as sa}from"@modelcontextprotocol/sdk/server/mcp.js";import{z as D}from"zod";ee();j();$();import sr from"node:fs/promises";import ot from"node:path";function Si(r){let t=[],e,s=new RegExp(ps.source,"g");for(;(e=s.exec(r))!==null;){let n=e[1];(n.startsWith(".")||n.startsWith("@/"))&&t.push(n)}return t}c(Si,"extractImportSources");async function wi(r,t,e){let s;if(r.startsWith("@/"))s=ot.join(e,"src",r.slice(2));else{let n=ot.dirname(ot.join(e,t));s=ot.resolve(n,r)}for(let n of ls){let i=s+n;try{if((await sr.stat(i)).isFile())return ot.relative(e,i)}catch{}}return null}c(wi,"resolveImport");async function bi(r){let t=await Es(r),e={},s={},n=0,i=await Ss(t,50,async o=>{try{let a=await sr.readFile(ot.join(r,o),"utf-8"),u=Si(a),p=[];for(let m of u){let d=await wi(m,o,r);d&&d!==o&&p.push(d)}return p.length>0?{filePath:o,imports:p}:null}catch{return null}});for(let{filePath:o,imports:a}of i){e[o]=a,n+=a.length;for(let u of a)s[u]||(s[u]=[]),s[u].push(o)}return{forward:e,reverse:s,fileCount:t.length,edgeCount:n,builtAt:new Date().toISOString()}}c(bi,"buildGraph");function rr(r,t,e=2){let s=new Set(r),n=new Map,i=[];for(let o of r){let a=t.forward[o]||[],u=t.reverse[o]||[];for(let p of[...a,...u])s.has(p)||i.push({file:p,depth:1})}for(;i.length>0;){let{file:o,depth:a}=i.shift();if(a>e)continue;let u=1/(a+1),p=n.get(o);if(p){u>p.score&&n.set(o,{score:u,depth:a});continue}if(n.set(o,{score:u,depth:a}),a<e){let m=t.forward[o]||[],d=t.reverse[o]||[];for(let f of[...m,...d])!s.has(f)&&!n.has(f)&&i.push({file:f,depth:a+1})}}return Array.from(n.entries()).map(([o,{score:a,depth:u}])=>({path:o,score:a,depth:u})).sort((o,a)=>a.score-o.score)}c(rr,"scoreFromSeeds");var Se="import-graph",Lt=new Map;function _i(r,t){y.setDoc(r,Se,t),Lt.delete(r)}c(_i,"saveGraph");function ht(r){let t=y.get(r,"SELECT updated_at FROM kv_store WHERE key = ?",Se);if(!t)return Lt.delete(r),null;let e=Lt.get(r);if(e&&e.updatedAt===t.updated_at)return e.graph;let s=y.getDoc(r,Se);return s&&Lt.set(r,{graph:s,updatedAt:t.updated_at}),s}c(ht,"loadGraph");async function nr(r,t){let e=await bi(r);return _i(t,e),e}c(nr,"indexImports");function ir(r,t){let e=[...r.added,...r.modified],s=new Set(e),n=new Set,i=ht(t);if(i)for(let u of e){let p=i.reverse[u];if(p)for(let m of p)s.has(m)||n.add(m)}let o=Array.from(n),a=[...e,...o];return{directlyChanged:e,affectedByImports:o,deleted:r.deleted,allAffected:a}}c(ir,"propagateChanges");function or(r){let t=new Set;for(let e of r){let s=e.toLowerCase();(s.endsWith(".tsx")||s.endsWith(".jsx")||s.endsWith(".css")||s.endsWith(".scss")||s.endsWith(".vue")||s.endsWith(".svelte")||s.includes("/components/")||s.includes("/pages/")||s.includes("/app/"))&&(t.add("frontend"),t.add("uxui")),(s.includes(".test.")||s.includes(".spec.")||s.includes("__tests__")||s.includes("/test/"))&&t.add("testing"),(s.includes("dockerfile")||s.includes("docker-compose")||s.includes(".dockerignore")||s.includes(".github/")||s.includes("ci/")||s.includes("cd/"))&&t.add("devops"),(s.endsWith(".sql")||s.includes("prisma")||s.includes("drizzle")||s.includes("migration")||s.includes("/db/"))&&t.add("database"),(s.endsWith(".ts")||s.endsWith(".js"))&&!s.includes(".test.")&&!s.includes(".spec.")&&!s.endsWith(".d.ts")&&t.add("backend")}return t}c(or,"affectedDomains");j();nt();async function xi(r,t=100){try{let{stdout:e}=await _(`git log --name-only --pretty=format:'---COMMIT---' -${t}`,{cwd:r,maxBuffer:10485760}),s=[],n=null;for(let i of e.split(`
|
|
556
|
+
`)){let o=i.trim();o==="---COMMIT---"?(n&&n.size>0&&n.size<=30&&s.push(n),n=new Set):o&&n&&Pi(o)&&n.add(o)}return n&&n.size>0&&n.size<=30&&s.push(n),s}catch{return[]}}c(xi,"parseGitLog");function Pi(r){return/\.(ts|tsx|js|jsx|mjs|cjs|py|go|rs|java|cs|rb|php|vue|svelte)$/i.test(r)&&!r.includes("node_modules/")}c(Pi,"isSourceFile");async function Ri(r,t=100){let e=await xi(r,t),s=new Map,n=new Map;for(let o of e){let a=Array.from(o);for(let u of a)s.set(u,(s.get(u)||0)+1);for(let u=0;u<a.length;u++)for(let p=u+1;p<a.length;p++){let m=Ai(a[u],a[p]);n.set(m,(n.get(m)||0)+1)}}let i={};for(let[o,a]of n){let[u,p]=o.split("\0"),m=s.get(u)||0,d=s.get(p)||0;if(m<2||d<2)continue;let f=m+d-a,T=f>0?a/f:0;T<.1||(i[u]||(i[u]={}),i[p]||(i[p]={}),i[u][p]=T,i[p][u]=T)}return{matrix:i,commitsAnalyzed:e.length,filesAnalyzed:s.size,builtAt:new Date().toISOString()}}c(Ri,"buildMatrix");function Ai(r,t){return r<t?`${r}\0${t}`:`${t}\0${r}`}c(Ai,"pairKey");function be(r,t){let e=new Set(r),s=new Map;for(let n of r){let i=t.matrix[n];if(i)for(let[o,a]of Object.entries(i)){if(e.has(o))continue;let u=s.get(o)||0;a>u&&s.set(o,a)}}return Array.from(s.entries()).map(([n,i])=>({path:n,score:i})).sort((n,i)=>i.score-n.score)}c(be,"scoreFromSeeds");var we="cochange-index",Ot=new Map;function Ci(r,t){y.setDoc(r,we,t),Ot.delete(r)}c(Ci,"saveMatrix");function _e(r){let t=y.get(r,"SELECT updated_at FROM kv_store WHERE key = ?",we);if(!t)return Ot.delete(r),null;let e=Ot.get(r);if(e&&e.updatedAt===t.updated_at)return e.matrix;let s=y.getDoc(r,we);return s&&Ot.set(r,{matrix:s,updatedAt:t.updated_at}),s}c(_e,"loadMatrix");async function ur(r,t,e=100){let s=await Ri(r,e);return Ci(t,s),s}c(ur,"indexCoChanges");Tt();async function P(r){return H.getProjectId(r)}c(P,"resolveProjectId");function w(r,t){return async e=>{try{return await t(e)}catch(s){return Ui(s,r)}}}c(w,"safeMcpCall");function Ui(r,t){let e=r instanceof Error?r.message:String(r);return{content:[{type:"text",text:`[${t}] Error: ${e}`}],isError:!0}}c(Ui,"mcpError");function yr(r){let t=r;t.tool("prjct_impact_analysis","Given changed files, find affected files via import graph + affected domains",{projectPath:D.string().describe("Project directory path"),changedFiles:D.array(D.string()).describe("List of changed file paths (relative to project root)")},w("prjct_impact_analysis",async e=>{let s=await P(e.projectPath),n={added:[],modified:e.changedFiles,deleted:[],unchanged:[]},i=ir(n,s),o=or(i.allAffected),a=["## Impact Analysis"];a.push(`
|
|
557
557
|
### Directly Changed (${i.directlyChanged.length})`);for(let u of i.directlyChanged)a.push(`- ${u}`);if(i.affectedByImports.length>0){a.push(`
|
|
558
558
|
### Affected via Imports (${i.affectedByImports.length})`);for(let u of i.affectedByImports)a.push(`- ${u}`)}return a.push(`
|
|
559
559
|
### Affected Domains`),a.push(o.size>0?Array.from(o).join(", "):"none detected"),a.push(`
|
|
560
560
|
Total affected: ${i.allAffected.length} files`),{content:[{type:"text",text:a.join(`
|
|
561
|
-
`)}]}})),t.tool("prjct_import_graph","Import graph stats + file neighbors (imports/importers). Pass a file for its neighbors, omit for graph stats.",{projectPath:D.string().describe("Project directory path"),file:D.string().optional().describe("File path to get neighbors for (omit for graph stats)"),rebuild:D.boolean().optional().default(!1).describe("Force rebuild the import graph")},w("prjct_import_graph",async e=>{let s=await P(e.projectPath),n=e.rebuild?null:ht(s);if(n||(n=await
|
|
561
|
+
`)}]}})),t.tool("prjct_import_graph","Import graph stats + file neighbors (imports/importers). Pass a file for its neighbors, omit for graph stats.",{projectPath:D.string().describe("Project directory path"),file:D.string().optional().describe("File path to get neighbors for (omit for graph stats)"),rebuild:D.boolean().optional().default(!1).describe("Force rebuild the import graph")},w("prjct_import_graph",async e=>{let s=await P(e.projectPath),n=e.rebuild?null:ht(s);if(n||(n=await nr(e.projectPath,s)),e.file){let o=n.forward[e.file]||[],a=n.reverse[e.file]||[];return{content:[{type:"text",text:[`## Import Neighbors: ${e.file}`,`
|
|
562
562
|
### Imports (${o.length})`,...o.map(p=>`- ${p}`),`
|
|
563
563
|
### Imported By (${a.length})`,...a.map(p=>`- ${p}`)].join(`
|
|
564
564
|
`)}]}}return{content:[{type:"text",text:["## Import Graph Stats",`Files: ${n.fileCount}`,`Edges: ${n.edgeCount}`,`Built: ${n.builtAt}`].join(`
|
|
565
|
-
`)}]}})),t.tool("prjct_cochange","Files that historically change together (Jaccard similarity from git history)",{projectPath:D.string().describe("Project directory path"),seedFiles:D.array(D.string()).describe("Seed files to find co-change partners for"),rebuild:D.boolean().optional().default(!1).describe("Force rebuild the co-change matrix"),maxResults:D.number().optional().default(10).describe("Max results (default 10)")},w("prjct_cochange",async e=>{let s=await P(e.projectPath),n=e.rebuild?null:_e(s);n||(n=await
|
|
566
|
-
`)}]}})),t.tool("prjct_related_context","Combined: import neighbors + co-change partners for seed files",{projectPath:D.string().describe("Project directory path"),seedFiles:D.array(D.string()).describe("Seed files to find related context for"),maxResults:D.number().optional().default(15).describe("Max results (default 15)")},w("prjct_related_context",async e=>{let s=await P(e.projectPath),n=ht(s),i=n?
|
|
567
|
-
`)}]}}))}c(
|
|
568
|
-
${
|
|
569
|
-
`)}`)}let{output:n,summary:i}=s.data,o=await r.read(t);if(!o.currentTask?.subtasks)return null;let a=o.currentTask.currentSubtaskIndex||0,u=o.currentTask.subtasks[a];if(!u)return null;let p=[...o.currentTask.subtasks];p[a]={...u,status:"completed",completedAt:g(),output:n,summary:i};let m=p.filter(j=>j.status==="completed").length,d=p.length,f=Math.round(m/d*100),y=a+1;return y<p.length&&(p[y]={...p[y],status:"in_progress",startedAt:g()}),await r.update(t,j=>({...j,currentTask:{...j.currentTask,subtasks:p,currentSubtaskIndex:y<d?y:a,subtaskProgress:{completed:m,total:d,percentage:f}},lastUpdated:g()})),await r.publish(t,"subtask.completed",{taskId:o.currentTask.id,subtaskId:u.id,description:u.description,output:n,handoff:i.outputForNextAgent,filesChanged:i.filesChanged.length,progress:{completed:m,total:d,percentage:f}}),y<d?p[y]:null}c(Hr,"completeSubtask");async function qr(r,t){let e=await r.read(t);if(!e.currentTask?.subtasks)return null;let s=e.currentTask.currentSubtaskIndex||0;return e.currentTask.subtasks[s]||null}c(qr,"getCurrentSubtask");async function Gr(r,t){let e=await r.read(t);if(!e.currentTask?.subtasks)return null;let s=(e.currentTask.currentSubtaskIndex||0)+1;return e.currentTask.subtasks[s]||null}c(Gr,"getNextSubtask");async function We(r,t){let e=await r.read(t);if(!e.currentTask?.subtasks)return null;let s=(e.currentTask.currentSubtaskIndex||0)-1;return s<0?null:e.currentTask.subtasks[s]||null}c(We,"getPreviousSubtask");async function Jr(r,t){let e=await We(r,t);return e?.summary?.outputForNextAgent?{fromSubtask:e.description,outputForNextAgent:e.summary.outputForNextAgent,filesChanged:e.summary.filesChanged,whatWasDone:e.summary.whatWasDone}:null}c(Jr,"getPreviousHandoff");async function Yr(r,t){return(await r.read(t)).currentTask?.subtasks||[]}c(Yr,"getSubtasks");async function zr(r,t){return(await r.read(t)).currentTask?.subtaskProgress||null}c(zr,"getSubtaskProgress");async function Kr(r,t){return((await r.read(t)).currentTask?.subtasks?.length||0)>0}c(Kr,"hasSubtasks");async function Vr(r,t){let e=await r.read(t);return e.currentTask?.subtasks?e.currentTask.subtasks.every(s=>s.status==="completed"||s.status==="failed"||s.status==="skipped"):!0}c(Vr,"areAllSubtasksComplete");async function Qr(r,t,e){let s=await r.read(t);if(!s.currentTask?.subtasks)return null;let n=s.currentTask.currentSubtaskIndex||0,i=s.currentTask.subtasks[n];if(!i)return null;let o=[...s.currentTask.subtasks];o[n]={...i,status:"failed",completedAt:g(),output:`Failed: ${e}`};let a=n+1,u=o.length;a<u&&(o[a]={...o[a],status:"in_progress",startedAt:g()});let p=o.filter(d=>d.status==="completed"||d.status==="failed"||d.status==="skipped").length,m=Math.round(p/u*100);return await r.update(t,d=>({...d,currentTask:{...d.currentTask,subtasks:o,currentSubtaskIndex:a<u?a:n,subtaskProgress:{completed:p,total:u,percentage:m}},lastUpdated:g()})),await r.publish(t,"subtask.failed",{taskId:s.currentTask.id,subtaskId:i.id,description:i.description,error:e}),a<u?o[a]:null}c(Qr,"failSubtask");async function Zr(r,t,e){let s=await r.read(t);if(!s.currentTask?.subtasks)return null;let n=s.currentTask.currentSubtaskIndex||0,i=s.currentTask.subtasks[n];if(!i)return null;let o=[...s.currentTask.subtasks];o[n]={...i,status:"skipped",completedAt:g(),output:`Skipped: ${e}`,skipReason:e};let a=n+1,u=o.length;a<u&&(o[a]={...o[a],status:"in_progress",startedAt:g()});let p=o.filter(d=>d.status==="completed"||d.status==="failed"||d.status==="skipped").length,m=Math.round(p/u*100);return await r.update(t,d=>({...d,currentTask:{...d.currentTask,subtasks:o,currentSubtaskIndex:a<u?a:n,subtaskProgress:{completed:p,total:u,percentage:m}},lastUpdated:g()})),await r.publish(t,"subtask.skipped",{taskId:s.currentTask.id,subtaskId:i.id,description:i.description,reason:e}),a<u?o[a]:null}c(Zr,"skipSubtask");async function tn(r,t,e){let s=await r.read(t);if(!s.currentTask?.subtasks)return null;let n=s.currentTask.currentSubtaskIndex||0,i=s.currentTask.subtasks[n];if(!i)return null;let o=[...s.currentTask.subtasks];o[n]={...i,status:"blocked",output:`Blocked: ${e}`,blockReason:e};let a=n+1,u=o.length;return a<u&&(o[a]={...o[a],status:"in_progress",startedAt:g()}),await r.update(t,p=>({...p,currentTask:{...p.currentTask,subtasks:o,currentSubtaskIndex:a<u?a:n},lastUpdated:g()})),await r.publish(t,"subtask.blocked",{taskId:s.currentTask.id,subtaskId:i.id,description:i.description,blocker:e}),a<u?o[a]:null}c(tn,"blockSubtask");C();async function en(r,t,e,s){let n={...e,workspaceId:s,startedAt:g()};return await r.update(t,i=>({...i,activeTasks:[...i.activeTasks||[],n],lastUpdated:g()})),await r.publish(t,"task.started",{taskId:n.id,description:n.description,startedAt:n.startedAt,sessionId:n.sessionId,workspaceId:s}),n}c(en,"startTaskInWorkspace");async function sn(r,t,e){return((await r.read(t)).activeTasks||[]).find(n=>n.workspaceId===e)??null}c(sn,"getCurrentTaskForWorkspace");async function rn(r,t,e,s){let n=await r.read(t),o=(n.activeTasks||[]).find(d=>d.workspaceId===e);if(!o)return null;let a=g(),u=r.createTaskHistoryEntry(o,a,s),p=r.getTaskHistoryFromState(n),m=[u,...p].slice(0,r.maxTaskHistory);return await r.update(t,d=>({...d,activeTasks:(d.activeTasks||[]).filter(f=>f.workspaceId!==e),taskHistory:m,lastUpdated:a})),await r.publish(t,"task.completed",{taskId:o.id,description:o.description,startedAt:o.startedAt,completedAt:a,workspaceId:e}),o}c(rn,"completeTaskInWorkspace");async function nn(r,t){return(await r.read(t)).activeTasks||[]}c(nn,"getActiveTasks");async function on(r,t){return((await r.read(t)).activeTasks||[]).length}c(on,"getActiveTaskCount");async function an(r,t,e,s){let i=(await r.read(t)).activeTasks||[],o=i.findIndex(u=>u.workspaceId===e);if(o===-1)return null;let a={...i[o],...s,workspaceId:e};return await r.update(t,u=>{let p=[...u.activeTasks||[]];return p[o]=a,{...u,activeTasks:p,lastUpdated:g()}}),a}c(an,"updateWorkspaceTask");async function cn(r,t,e,s){let n=await r.read(t);if(!n.currentTask)return null;let i=(n.currentTask.tokensIn||0)+e,o=(n.currentTask.tokensOut||0)+s;return await r.update(t,a=>({...a,currentTask:{...a.currentTask,tokensIn:i,tokensOut:o},lastUpdated:g()})),{tokensIn:i,tokensOut:o}}c(cn,"addTokens");Be();var He=class extends ut{static{c(this,"StateStorage")}constructor(){super("state.json",wr)}getDefault(){return{currentTask:null,previousTask:null,pausedTasks:[],taskHistory:[],activeTasks:[],lastUpdated:""}}getEventType(t){return`state.${t}d`}validateTransition(t,e){let s=De.getCurrentState(t),n=De.canTransition(s,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 s=await this.read(t);this.validateTransition(s,"task");let n={...e,startedAt:g()};return await this.update(t,i=>({...i,currentTask:n,lastUpdated:g()})),await this.publishEvent(t,"task.started",{taskId:n.id,description:n.description,startedAt:n.startedAt,sessionId:n.sessionId}),n}async updateCurrentTask(t,e){let s=await this.read(t);if(!s.currentTask)return null;let n={...s.currentTask,...e};return await this.update(t,i=>({...i,currentTask:n,lastUpdated:g()})),n}async completeTask(t,e){let s=await this.read(t),n=s.currentTask;if(!n)return null;this.validateTransition(s,"done");let i=g(),o=this.createTaskHistoryEntry(n,i,e),a=this.getTaskHistoryFromState(s),u=[o,...a].slice(0,this.maxTaskHistory);return await this.update(t,p=>({...p,currentTask:null,previousTask:null,taskHistory:u,lastUpdated:i})),await this.publishEvent(t,"task.completed",{taskId:n.id,description:n.description,startedAt:n.startedAt,completedAt:i}),n}createTaskHistoryEntry(t,e,s){let n=(t.subtasks||[]).filter(a=>a.status==="completed"&&a.summary).map(a=>a.summary),i=n.length>0?n.map(a=>a.title).join(", "):"Task completed",o={taskId:t.id,title:t.parentDescription||t.description,classification:t.type||"improvement",startedAt:t.startedAt,completedAt:e,subtaskCount:t.subtasks?.length||0,subtaskSummaries:n,outcome:i,branchName:t.branch||"unknown",linearId:t.linearId,linearUuid:t.linearUuid,prUrl:t.prUrl};return s&&(o.feedback=s),t.tokensIn&&(o.tokensIn=t.tokensIn),t.tokensOut&&(o.tokensOut=t.tokensOut),o}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 Ir(this.lifecycleBackend(),t,e)}async resumeTask(t,e){return Dr(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 Lr(this.lifecycleBackend(),t)}async archiveStalePausedTasks(t){return Or(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 jr(this.queryBackend(),t)}async hasTask(t){return Mr(this.queryBackend(),t)}async getPausedTask(t){return Fr(this.queryBackend(),t)}async getAllPausedTasks(t){return Ur(this.queryBackend(),t)}async getTaskHistory(t){return Xe(this.queryBackend(),t)}async getMostRecentTask(t){return $r(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,s){return en(this.workspaceBackend(),t,e,s)}async getCurrentTaskForWorkspace(t,e){return sn(this.workspaceBackend(),t,e)}async completeTaskInWorkspace(t,e,s){return rn(this.workspaceBackend(),t,e,s)}async getActiveTasks(t){return nn(this.workspaceBackend(),t)}async getActiveTaskCount(t){return on(this.workspaceBackend(),t)}async updateWorkspaceTask(t,e,s){return an(this.workspaceBackend(),t,e,s)}async addTokens(t,e,s){return cn(this.workspaceBackend(),t,e,s)}subtaskBackend(){return{read:this.read.bind(this),update:this.update.bind(this),publish:this.publishEvent.bind(this)}}async createSubtasks(t,e){return Br(this.subtaskBackend(),t,e)}async completeSubtask(t,e){return Hr(this.subtaskBackend(),t,e)}async getCurrentSubtask(t){return qr(this.subtaskBackend(),t)}async getNextSubtask(t){return Gr(this.subtaskBackend(),t)}async getPreviousSubtask(t){return We(this.subtaskBackend(),t)}async getPreviousHandoff(t){return Jr(this.subtaskBackend(),t)}async getSubtasks(t){return Yr(this.subtaskBackend(),t)}async getSubtaskProgress(t){return zr(this.subtaskBackend(),t)}async hasSubtasks(t){return Kr(this.subtaskBackend(),t)}async areAllSubtasksComplete(t){return Vr(this.subtaskBackend(),t)}async failSubtask(t,e){return Qr(this.subtaskBackend(),t,e)}async skipSubtask(t,e){return Zr(this.subtaskBackend(),t,e)}async blockSubtask(t,e){return tn(this.subtaskBackend(),t,e)}},lt=new He;qe();Z();import _o from"node:fs/promises";import pt from"node:path";var So={"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}},wo="claude-sonnet-4.5";function Ge(r){return!r||r.length===0?0:Math.ceil(r.length/4)}c(Ge,"countTokens");var fn=["claude-sonnet-4.5","claude-opus-4.5","claude-opus-4-6","gpt-4o","gemini-1.5-pro"];function gn(r,t){let e=So[t],s=r/1e3*e.input,n=r/1e3*e.output*.3;return{inputSaved:s,outputPotential:n,total:s+n}}c(gn,"calculateModelCost");function bo(r){return r<.001?"<$0.01":r<.01?`$${r.toFixed(3)}`:`$${r.toFixed(2)}`}c(bo,"formatCostSaved");function hn(r,t){let e=Ge(r),s=Ge(t),n=Math.max(0,e-s),i=e>0?(e-s)/e:0,o=gn(n,wo),a=fn.map(u=>({model:u,...gn(n,u)}));return{tokens:{original:e,filtered:s,saved:n},compression:Math.max(0,Math.min(1,i)),cost:{saved:o.total,formatted:bo(o.total),byModel:a}}}c(hn,"measureCompression");function Gt(r){let t=Ge(r);return{tokens:{original:t,filtered:t,saved:0},compression:0,cost:{saved:0,formatted:"$0.00",byModel:fn.map(e=>({model:e,inputSaved:0,outputPotential:0,total:0}))}}}c(Gt,"noCompression");var vo={".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"},yn=[{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}],xo=[{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}],Po=[{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}],Ro=[{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}],Tn=[{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}],Ao={typescript:yn,javascript:yn,python:xo,go:Po,rust:Ro,java:Tn,csharp:Tn,php:[],ruby:[],unknown:[]};async function kn(r,t=process.cwd()){let e=pt.isAbsolute(r)?r:pt.join(t,r),s=pt.resolve(t),n=pt.resolve(e);if(!n.startsWith(s+pt.sep)&&n!==s)return{file:r,language:"unknown",signatures:[],fallback:!0,fallbackReason:"Path traversal denied: file is outside project directory",metrics:Gt("")};let i;try{i=await _o.readFile(e,"utf-8")}catch(d){if(L(d))return{file:r,language:"unknown",signatures:[],fallback:!0,fallbackReason:"File not found",metrics:Gt("")};throw d}let o=pt.extname(r).toLowerCase(),a=vo[o]||"unknown",u=Ao[a];if(!u||u.length===0)return{file:r,language:a,signatures:[],fallback:!0,fallbackReason:`No extraction patterns for ${a}`,metrics:Gt(i)};let p=Co(i,u),m=p.map(d=>`${d.exported?"export ":""}${d.type} ${d.name}: ${d.signature}`).join(`
|
|
570
|
-
`);return{file:r,language:a,signatures:p,fallback:!1,metrics:
|
|
565
|
+
`)}]}})),t.tool("prjct_cochange","Files that historically change together (Jaccard similarity from git history)",{projectPath:D.string().describe("Project directory path"),seedFiles:D.array(D.string()).describe("Seed files to find co-change partners for"),rebuild:D.boolean().optional().default(!1).describe("Force rebuild the co-change matrix"),maxResults:D.number().optional().default(10).describe("Max results (default 10)")},w("prjct_cochange",async e=>{let s=await P(e.projectPath),n=e.rebuild?null:_e(s);n||(n=await ur(e.projectPath,s));let i=be(e.seedFiles,n).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: ${n.commitsAnalyzed}`,""];for(let a of i)o.push(`- ${a.path} (similarity: ${Math.round(a.score*100)}%)`);return{content:[{type:"text",text:o.join(`
|
|
566
|
+
`)}]}})),t.tool("prjct_related_context","Combined: import neighbors + co-change partners for seed files",{projectPath:D.string().describe("Project directory path"),seedFiles:D.array(D.string()).describe("Seed files to find related context for"),maxResults:D.number().optional().default(15).describe("Max results (default 15)")},w("prjct_related_context",async e=>{let s=await P(e.projectPath),n=ht(s),i=n?rr(e.seedFiles,n):[],o=_e(s),a=o?be(e.seedFiles,o):[],u=new Map;for(let d of i)u.set(d.path,{importScore:d.score,cochangeScore:0});for(let d of a){let f=u.get(d.path);f?f.cochangeScore=d.score:u.set(d.path,{importScore:0,cochangeScore:d.score})}let p=Array.from(u.entries()).map(([d,f])=>({path:d,combined:f.importScore*.6+f.cochangeScore*.4,importScore:f.importScore,cochangeScore:f.cochangeScore})).sort((d,f)=>f.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 f=[];d.importScore>0&&f.push(`import: ${d.importScore.toFixed(2)}`),d.cochangeScore>0&&f.push(`cochange: ${Math.round(d.cochangeScore*100)}%`),m.push(`- ${d.path} (${f.join(", ")})`)}return{content:[{type:"text",text:m.join(`
|
|
567
|
+
`)}]}}))}c(yr,"registerCodeIntelTools");import{z as st}from"zod";$t();C();var kt={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"}},Ie=class{static{c(this,"WorkflowStateMachine")}getCurrentState(t,e){let s=null;if(e&&t?.activeTasks?.length&&(s=t.activeTasks.find(i=>i.workspaceId===e)),s||(s=t?.currentTask),!s)return(t?.pausedTasks?.length||0)>0||t?.previousTask?.status==="paused"?"paused":"idle";switch((typeof s.status=="string"?s.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 s?"working":"idle"}}canTransition(t,e){if(kt[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 kt[t]}getPrompt(t){return kt[t].prompt}getValidCommands(t){return kt[t].transitions}formatNextSteps(t){return kt[t].transitions.map(s=>{switch(s){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 ${s}`}})}},De=new Ie;Et();C();Bt();async function Dr(r,t,e){let s=await r.read(t);if(!s.currentTask)return null;r.validateTransition(s,"pause");let n={...s.currentTask,status:"paused",pausedAt:g(),pauseReason:e},i=r.getPausedTasksFromState(s),o=[n,...i].slice(0,r.maxPausedTasks);return await r.update(t,a=>({...a,currentTask:null,previousTask:null,pausedTasks:o,lastUpdated:g()})),await r.publish(t,"task.paused",{taskId:n.id,description:n.description,pausedAt:n.pausedAt,reason:e,pausedCount:o.length}),n}c(Dr,"pauseTask");async function Lr(r,t,e){let s=await r.read(t),n=r.getPausedTasksFromState(s);if(n.length===0)return null;r.validateTransition(s,"resume");let i=0;if(e&&(i=n.findIndex(T=>T.id===e),i===-1))return null;let o=n[i],a=n.filter((T,M)=>M!==i),{status:u,pausedAt:p,pauseReason:m,...d}=o,f={...d,startedAt:g(),sessionId:o.sessionId??q()};return await r.update(t,T=>({...T,currentTask:f,previousTask:null,pausedTasks:a,lastUpdated:g()})),await r.publish(t,"task.resumed",{taskId:f.id,description:f.description,resumedAt:f.startedAt,remainingPaused:a.length}),f}c(Lr,"resumeTask");async function Or(r,t){let e=await r.read(t),s=r.getPausedTasksFromState(e),n=Date.now()-r.stalenessThresholdDays*24*60*60*1e3;return s.filter(i=>new Date(i.pausedAt).getTime()<n)}c(Or,"getStalePausedTasks");async function Mr(r,t){let e=await r.read(t),s=r.getPausedTasksFromState(e),n=Date.now()-r.stalenessThresholdDays*24*60*60*1e3,i=s.filter(a=>new Date(a.pausedAt).getTime()<n),o=s.filter(a=>new Date(a.pausedAt).getTime()>=n);if(i.length===0)return[];ct.archiveMany(t,i.map(a=>({entityType:"paused_task",entityId:a.id,entityData:a,summary:a.description,reason:"staleness"}))),await r.update(t,a=>({...a,pausedTasks:o,previousTask:null,lastUpdated:g()}));for(let a of i)await r.publish(t,"task.archived",{taskId:a.id,description:a.description,pausedAt:a.pausedAt,reason:"staleness"});return i}c(Mr,"archiveStalePausedTasks");C();async function jr(r,t){await r.update(t,()=>({currentTask:null,previousTask:null,pausedTasks:[],activeTasks:[],lastUpdated:g()}))}c(jr,"clearTask");async function Fr(r,t){let e=await r.read(t),s=r.getPausedTasksFromState(e);return e.currentTask!==null||s.length>0}c(Fr,"hasTask");async function Ur(r,t){let e=await r.read(t);return r.getPausedTasksFromState(e)[0]||null}c(Ur,"getPausedTask");async function $r(r,t){let e=await r.read(t);return r.getPausedTasksFromState(e)}c($r,"getAllPausedTasks");async function Xe(r,t){let e=await r.read(t);return r.getTaskHistoryFromState(e)}c(Xe,"getTaskHistory");async function Xr(r,t){let e=await r.read(t);return r.getTaskHistoryFromState(e)[0]||null}c(Xr,"getMostRecentTask");async function Wr(r,t,e){let s=await r.read(t);return r.getTaskHistoryFromState(s).filter(i=>i.classification===e)}c(Wr,"getTaskHistoryByType");async function Br(r,t){let s=(await Xe(r,t)).filter(f=>f.feedback),n=[],i=[],o=[],a=[];for(let f of s){let T=f.feedback;Array.isArray(T.stackConfirmed)&&n.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(n)],p=[...new Set(i)],m=new Map;for(let f of a)m.set(f,(m.get(f)||0)+1);let d=[...m.entries()].filter(([f,T])=>T>=2).map(([f])=>f);return{stackConfirmed:u,patternsDiscovered:p,agentAccuracy:o,issuesEncountered:[...new Set(a)],knownGotchas:d}}c(Br,"getAggregatedFeedback");$t();C();async function Hr(r,t,e){let s=await r.read(t);if(!s.currentTask)return;let n=e.map((i,o)=>({...i,status:o===0?"in_progress":"pending",startedAt:o===0?g():void 0,dependsOn:i.dependsOn||[]}));await r.update(t,i=>({...i,currentTask:{...i.currentTask,subtasks:n,currentSubtaskIndex:0,subtaskProgress:{completed:0,total:n.length,percentage:0}},lastUpdated:g()})),await r.publish(t,"subtasks.created",{taskId:s.currentTask.id,subtaskCount:n.length,subtasks:n.map(i=>({id:i.id,description:i.description,domain:i.domain}))})}c(Hr,"createSubtasks");async function qr(r,t,e){let s=kr.safeParse(e);if(!s.success){let M=s.error.issues.map(z=>`${z.path.join(".")}: ${z.message}`);throw new Error(`Subtask completion requires handoff data:
|
|
568
|
+
${M.join(`
|
|
569
|
+
`)}`)}let{output:n,summary:i}=s.data,o=await r.read(t);if(!o.currentTask?.subtasks)return null;let a=o.currentTask.currentSubtaskIndex||0,u=o.currentTask.subtasks[a];if(!u)return null;let p=[...o.currentTask.subtasks];p[a]={...u,status:"completed",completedAt:g(),output:n,summary:i};let m=p.filter(M=>M.status==="completed").length,d=p.length,f=Math.round(m/d*100),T=a+1;return T<p.length&&(p[T]={...p[T],status:"in_progress",startedAt:g()}),await r.update(t,M=>({...M,currentTask:{...M.currentTask,subtasks:p,currentSubtaskIndex:T<d?T:a,subtaskProgress:{completed:m,total:d,percentage:f}},lastUpdated:g()})),await r.publish(t,"subtask.completed",{taskId:o.currentTask.id,subtaskId:u.id,description:u.description,output:n,handoff:i.outputForNextAgent,filesChanged:i.filesChanged.length,progress:{completed:m,total:d,percentage:f}}),T<d?p[T]:null}c(qr,"completeSubtask");async function Gr(r,t){let e=await r.read(t);if(!e.currentTask?.subtasks)return null;let s=e.currentTask.currentSubtaskIndex||0;return e.currentTask.subtasks[s]||null}c(Gr,"getCurrentSubtask");async function Yr(r,t){let e=await r.read(t);if(!e.currentTask?.subtasks)return null;let s=(e.currentTask.currentSubtaskIndex||0)+1;return e.currentTask.subtasks[s]||null}c(Yr,"getNextSubtask");async function We(r,t){let e=await r.read(t);if(!e.currentTask?.subtasks)return null;let s=(e.currentTask.currentSubtaskIndex||0)-1;return s<0?null:e.currentTask.subtasks[s]||null}c(We,"getPreviousSubtask");async function Jr(r,t){let e=await We(r,t);return e?.summary?.outputForNextAgent?{fromSubtask:e.description,outputForNextAgent:e.summary.outputForNextAgent,filesChanged:e.summary.filesChanged,whatWasDone:e.summary.whatWasDone}:null}c(Jr,"getPreviousHandoff");async function zr(r,t){return(await r.read(t)).currentTask?.subtasks||[]}c(zr,"getSubtasks");async function Kr(r,t){return(await r.read(t)).currentTask?.subtaskProgress||null}c(Kr,"getSubtaskProgress");async function Vr(r,t){return((await r.read(t)).currentTask?.subtasks?.length||0)>0}c(Vr,"hasSubtasks");async function Qr(r,t){let e=await r.read(t);return e.currentTask?.subtasks?e.currentTask.subtasks.every(s=>s.status==="completed"||s.status==="failed"||s.status==="skipped"):!0}c(Qr,"areAllSubtasksComplete");async function Zr(r,t,e){let s=await r.read(t);if(!s.currentTask?.subtasks)return null;let n=s.currentTask.currentSubtaskIndex||0,i=s.currentTask.subtasks[n];if(!i)return null;let o=[...s.currentTask.subtasks];o[n]={...i,status:"failed",completedAt:g(),output:`Failed: ${e}`};let a=n+1,u=o.length;a<u&&(o[a]={...o[a],status:"in_progress",startedAt:g()});let p=o.filter(d=>d.status==="completed"||d.status==="failed"||d.status==="skipped").length,m=Math.round(p/u*100);return await r.update(t,d=>({...d,currentTask:{...d.currentTask,subtasks:o,currentSubtaskIndex:a<u?a:n,subtaskProgress:{completed:p,total:u,percentage:m}},lastUpdated:g()})),await r.publish(t,"subtask.failed",{taskId:s.currentTask.id,subtaskId:i.id,description:i.description,error:e}),a<u?o[a]:null}c(Zr,"failSubtask");async function tn(r,t,e){let s=await r.read(t);if(!s.currentTask?.subtasks)return null;let n=s.currentTask.currentSubtaskIndex||0,i=s.currentTask.subtasks[n];if(!i)return null;let o=[...s.currentTask.subtasks];o[n]={...i,status:"skipped",completedAt:g(),output:`Skipped: ${e}`,skipReason:e};let a=n+1,u=o.length;a<u&&(o[a]={...o[a],status:"in_progress",startedAt:g()});let p=o.filter(d=>d.status==="completed"||d.status==="failed"||d.status==="skipped").length,m=Math.round(p/u*100);return await r.update(t,d=>({...d,currentTask:{...d.currentTask,subtasks:o,currentSubtaskIndex:a<u?a:n,subtaskProgress:{completed:p,total:u,percentage:m}},lastUpdated:g()})),await r.publish(t,"subtask.skipped",{taskId:s.currentTask.id,subtaskId:i.id,description:i.description,reason:e}),a<u?o[a]:null}c(tn,"skipSubtask");async function en(r,t,e){let s=await r.read(t);if(!s.currentTask?.subtasks)return null;let n=s.currentTask.currentSubtaskIndex||0,i=s.currentTask.subtasks[n];if(!i)return null;let o=[...s.currentTask.subtasks];o[n]={...i,status:"blocked",output:`Blocked: ${e}`,blockReason:e};let a=n+1,u=o.length;return a<u&&(o[a]={...o[a],status:"in_progress",startedAt:g()}),await r.update(t,p=>({...p,currentTask:{...p.currentTask,subtasks:o,currentSubtaskIndex:a<u?a:n},lastUpdated:g()})),await r.publish(t,"subtask.blocked",{taskId:s.currentTask.id,subtaskId:i.id,description:i.description,blocker:e}),a<u?o[a]:null}c(en,"blockSubtask");C();async function sn(r,t,e,s){let n={...e,workspaceId:s,startedAt:g()};return await r.update(t,i=>({...i,activeTasks:[...i.activeTasks||[],n],lastUpdated:g()})),await r.publish(t,"task.started",{taskId:n.id,description:n.description,startedAt:n.startedAt,sessionId:n.sessionId,workspaceId:s}),n}c(sn,"startTaskInWorkspace");async function rn(r,t,e){return((await r.read(t)).activeTasks||[]).find(n=>n.workspaceId===e)??null}c(rn,"getCurrentTaskForWorkspace");async function nn(r,t,e,s){let n=await r.read(t),o=(n.activeTasks||[]).find(d=>d.workspaceId===e);if(!o)return null;let a=g(),u=r.createTaskHistoryEntry(o,a,s),p=r.getTaskHistoryFromState(n),m=[u,...p].slice(0,r.maxTaskHistory);return await r.update(t,d=>({...d,activeTasks:(d.activeTasks||[]).filter(f=>f.workspaceId!==e),taskHistory:m,lastUpdated:a})),await r.publish(t,"task.completed",{taskId:o.id,description:o.description,startedAt:o.startedAt,completedAt:a,workspaceId:e}),o}c(nn,"completeTaskInWorkspace");async function on(r,t){return(await r.read(t)).activeTasks||[]}c(on,"getActiveTasks");async function an(r,t){return((await r.read(t)).activeTasks||[]).length}c(an,"getActiveTaskCount");async function cn(r,t,e,s){let i=(await r.read(t)).activeTasks||[],o=i.findIndex(u=>u.workspaceId===e);if(o===-1)return null;let a={...i[o],...s,workspaceId:e};return await r.update(t,u=>{let p=[...u.activeTasks||[]];return p[o]=a,{...u,activeTasks:p,lastUpdated:g()}}),a}c(cn,"updateWorkspaceTask");async function un(r,t,e,s){let n=await r.read(t);if(!n.currentTask)return null;let i=(n.currentTask.tokensIn||0)+e,o=(n.currentTask.tokensOut||0)+s;return await r.update(t,a=>({...a,currentTask:{...a.currentTask,tokensIn:i,tokensOut:o},lastUpdated:g()})),{tokensIn:i,tokensOut:o}}c(un,"addTokens");Be();var He=class extends ut{static{c(this,"StateStorage")}constructor(){super("state.json",br)}getDefault(){return{currentTask:null,previousTask:null,pausedTasks:[],taskHistory:[],activeTasks:[],lastUpdated:""}}getEventType(t){return`state.${t}d`}validateTransition(t,e){let s=De.getCurrentState(t),n=De.canTransition(s,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 s=await this.read(t);this.validateTransition(s,"task");let n={...e,startedAt:g()};return await this.update(t,i=>({...i,currentTask:n,lastUpdated:g()})),await this.publishEvent(t,"task.started",{taskId:n.id,description:n.description,startedAt:n.startedAt,sessionId:n.sessionId}),n}async updateCurrentTask(t,e){let s=await this.read(t);if(!s.currentTask)return null;let n={...s.currentTask,...e};return await this.update(t,i=>({...i,currentTask:n,lastUpdated:g()})),n}async completeTask(t,e){let s=await this.read(t),n=s.currentTask;if(!n)return null;this.validateTransition(s,"done");let i=g(),o=this.createTaskHistoryEntry(n,i,e),a=this.getTaskHistoryFromState(s),u=[o,...a].slice(0,this.maxTaskHistory);return await this.update(t,p=>({...p,currentTask:null,previousTask:null,taskHistory:u,lastUpdated:i})),await this.publishEvent(t,"task.completed",{taskId:n.id,description:n.description,startedAt:n.startedAt,completedAt:i}),n}createTaskHistoryEntry(t,e,s){let n=(t.subtasks||[]).filter(a=>a.status==="completed"&&a.summary).map(a=>a.summary),i=n.length>0?n.map(a=>a.title).join(", "):"Task completed",o={taskId:t.id,title:t.parentDescription||t.description,classification:t.type||"improvement",startedAt:t.startedAt,completedAt:e,subtaskCount:t.subtasks?.length||0,subtaskSummaries:n,outcome:i,branchName:t.branch||"unknown",linearId:t.linearId,linearUuid:t.linearUuid,prUrl:t.prUrl};return s&&(o.feedback=s),t.tokensIn&&(o.tokensIn=t.tokensIn),t.tokensOut&&(o.tokensOut=t.tokensOut),o}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 Dr(this.lifecycleBackend(),t,e)}async resumeTask(t,e){return Lr(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 Or(this.lifecycleBackend(),t)}async archiveStalePausedTasks(t){return Mr(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 jr(this.queryBackend(),t)}async hasTask(t){return Fr(this.queryBackend(),t)}async getPausedTask(t){return Ur(this.queryBackend(),t)}async getAllPausedTasks(t){return $r(this.queryBackend(),t)}async getTaskHistory(t){return Xe(this.queryBackend(),t)}async getMostRecentTask(t){return Xr(this.queryBackend(),t)}async getTaskHistoryByType(t,e){return Wr(this.queryBackend(),t,e)}async getAggregatedFeedback(t){return Br(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,s){return sn(this.workspaceBackend(),t,e,s)}async getCurrentTaskForWorkspace(t,e){return rn(this.workspaceBackend(),t,e)}async completeTaskInWorkspace(t,e,s){return nn(this.workspaceBackend(),t,e,s)}async getActiveTasks(t){return on(this.workspaceBackend(),t)}async getActiveTaskCount(t){return an(this.workspaceBackend(),t)}async updateWorkspaceTask(t,e,s){return cn(this.workspaceBackend(),t,e,s)}async addTokens(t,e,s){return un(this.workspaceBackend(),t,e,s)}subtaskBackend(){return{read:this.read.bind(this),update:this.update.bind(this),publish:this.publishEvent.bind(this)}}async createSubtasks(t,e){return Hr(this.subtaskBackend(),t,e)}async completeSubtask(t,e){return qr(this.subtaskBackend(),t,e)}async getCurrentSubtask(t){return Gr(this.subtaskBackend(),t)}async getNextSubtask(t){return Yr(this.subtaskBackend(),t)}async getPreviousSubtask(t){return We(this.subtaskBackend(),t)}async getPreviousHandoff(t){return Jr(this.subtaskBackend(),t)}async getSubtasks(t){return zr(this.subtaskBackend(),t)}async getSubtaskProgress(t){return Kr(this.subtaskBackend(),t)}async hasSubtasks(t){return Vr(this.subtaskBackend(),t)}async areAllSubtasksComplete(t){return Qr(this.subtaskBackend(),t)}async failSubtask(t,e){return Zr(this.subtaskBackend(),t,e)}async skipSubtask(t,e){return tn(this.subtaskBackend(),t,e)}async blockSubtask(t,e){return en(this.subtaskBackend(),t,e)}},lt=new He;qe();Z();import vo from"node:fs/promises";import pt from"node:path";var wo={"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}},bo="claude-sonnet-4.5";function Ge(r){return!r||r.length===0?0:Math.ceil(r.length/4)}c(Ge,"countTokens");var hn=["claude-sonnet-4.5","claude-opus-4.5","claude-opus-4-6","gpt-4o","gemini-1.5-pro"];function fn(r,t){let e=wo[t],s=r/1e3*e.input,n=r/1e3*e.output*.3;return{inputSaved:s,outputPotential:n,total:s+n}}c(fn,"calculateModelCost");function _o(r){return r<.001?"<$0.01":r<.01?`$${r.toFixed(3)}`:`$${r.toFixed(2)}`}c(_o,"formatCostSaved");function yn(r,t){let e=Ge(r),s=Ge(t),n=Math.max(0,e-s),i=e>0?(e-s)/e:0,o=fn(n,bo),a=hn.map(u=>({model:u,...fn(n,u)}));return{tokens:{original:e,filtered:s,saved:n},compression:Math.max(0,Math.min(1,i)),cost:{saved:o.total,formatted:_o(o.total),byModel:a}}}c(yn,"measureCompression");function Yt(r){let t=Ge(r);return{tokens:{original:t,filtered:t,saved:0},compression:0,cost:{saved:0,formatted:"$0.00",byModel:hn.map(e=>({model:e,inputSaved:0,outputPotential:0,total:0}))}}}c(Yt,"noCompression");var xo={".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"},Tn=[{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}],Po=[{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}],Ro=[{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}],Ao=[{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}],kn=[{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}],Co={typescript:Tn,javascript:Tn,python:Po,go:Ro,rust:Ao,java:kn,csharp:kn,php:[],ruby:[],unknown:[]};async function En(r,t=process.cwd()){let e=pt.isAbsolute(r)?r:pt.join(t,r),s=pt.resolve(t),n=pt.resolve(e);if(!n.startsWith(s+pt.sep)&&n!==s)return{file:r,language:"unknown",signatures:[],fallback:!0,fallbackReason:"Path traversal denied: file is outside project directory",metrics:Yt("")};let i;try{i=await vo.readFile(e,"utf-8")}catch(d){if(L(d))return{file:r,language:"unknown",signatures:[],fallback:!0,fallbackReason:"File not found",metrics:Yt("")};throw d}let o=pt.extname(r).toLowerCase(),a=xo[o]||"unknown",u=Co[a];if(!u||u.length===0)return{file:r,language:a,signatures:[],fallback:!0,fallbackReason:`No extraction patterns for ${a}`,metrics:Yt(i)};let p=No(i,u),m=p.map(d=>`${d.exported?"export ":""}${d.type} ${d.name}: ${d.signature}`).join(`
|
|
570
|
+
`);return{file:r,language:a,signatures:p,fallback:!1,metrics:yn(i,m)}}c(En,"extractSignatures");function No(r,t){let e=[],s=r.split(`
|
|
571
571
|
`),n=new Set;for(let i of t){i.pattern.lastIndex=0;let o;for(;(o=i.pattern.exec(r))!==null;){let a=o[i.nameIndex];if(!a)continue;let u=`${i.type}:${a}`;if(n.has(u))continue;n.add(u);let p=o.index,m=r.substring(0,p).split(`
|
|
572
|
-
`).length,d=o[0].trim(),f;if(m>1){let
|
|
572
|
+
`).length,d=o[0].trim(),f;if(m>1){let T=s[m-2]?.trim();(T?.startsWith("/**")||T?.startsWith("///")||T?.startsWith("#"))&&(f=T)}e.push({type:i.type,name:a,signature:Io(d),exported:i.exported||!1,line:m,docstring:f})}}return e.sort((i,o)=>i.line-o.line)}c(No,"extractFromContent");function Io(r){return r.replace(/\{$/,"").replace(/\s+/g," ").trim()}c(Io,"cleanSignature");function Sn(r){let t=r;t.tool("prjct_relevant_files","BM25-ranked files relevant to a query",{projectPath:st.string().describe("Project directory path"),query:st.string().describe("Task or query to find relevant files for"),maxFiles:st.number().optional().default(10).describe("Max files to return")},w("prjct_relevant_files",async e=>{let s=await Gt(e.query,e.projectPath,{maxFiles:e.maxFiles,minScore:.1});if(s.files.length===0)return{content:[{type:"text",text:"No relevant files found."}]};let n=s.files.map(o=>`- \`${o.path}\` (score: ${Math.round(o.score*100)}%) \u2014 ${o.reasons.join(", ")}`);return{content:[{type:"text",text:`## Relevant Files (${s.files.length}/${s.metrics.filesScanned} scanned)
|
|
573
573
|
|
|
574
574
|
${n.join(`
|
|
575
|
-
`)}`}]}})),t.tool("prjct_signatures","Code signatures from a file (90% token reduction vs full content)",{projectPath:st.string().describe("Project directory path"),filePath:st.string().describe("Relative file path to extract signatures from")},w("prjct_signatures",async e=>{let s=await
|
|
575
|
+
`)}`}]}})),t.tool("prjct_signatures","Code signatures from a file (90% token reduction vs full content)",{projectPath:st.string().describe("Project directory path"),filePath:st.string().describe("Relative file path to extract signatures from")},w("prjct_signatures",async e=>{let s=await En(e.filePath,e.projectPath);if(s.signatures.length===0)return{content:[{type:"text",text:s.fallback?`No signatures extracted: ${s.fallbackReason}`:"No signatures found."}]};let n=s.signatures.map(a=>`${a.exported?"export ":""}${a.type} ${a.name}: ${a.signature}${a.docstring?` // ${a.docstring}`:""}`),i=s.metrics?.compression?` (${Math.round(s.metrics.compression*100)}% reduction)`:"";return{content:[{type:"text",text:`## ${s.file} (${s.language})
|
|
576
576
|
\`\`\`
|
|
577
577
|
${n.join(`
|
|
578
578
|
`)}
|
|
579
579
|
\`\`\`${i}`}]}})),t.tool("prjct_history","Recent completed tasks with outcomes",{projectPath:st.string().describe("Project directory path"),limit:st.number().optional().default(10).describe("Max results")},w("prjct_history",async e=>{let s=await P(e.projectPath),n=await lt.getTaskHistory(s);if(n.length===0)return{content:[{type:"text",text:"No task history."}]};let o=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)
|
|
580
580
|
|
|
581
581
|
${o.join(`
|
|
582
|
-
`)}`}]}}))}c(
|
|
582
|
+
`)}`}]}}))}c(Sn,"registerFileTools");dt();import{z as R}from"zod";var Cn=[{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/}],gp=Cn.map(r=>r.name);function Nn(r){let t=[];for(let{name:e,re:s}of Cn)s.test(r)&&t.push(e);return t}c(Nn,"scanForSecrets");var In=`Base types: ${Rn.join(", ")}. Any lowercase identifier is accepted (e.g. "recipe", "okr").`;function Dn(r){let t=r;t.tool("prjct_mem_save",`Save a memory entry. ${In} Secret-like content is refused unless force=true.`,{projectPath:R.string().describe("Project directory path"),type:R.string().describe("Memory type (fact/decision/learning/... or user-defined)"),content:R.string().describe("The memory content. Freeform text."),tags:R.record(R.string(),R.string()).optional().describe('Key:value tags (e.g. {domain: "auth"})'),source:R.string().optional().describe("Task id this memory came from, if any"),force:R.boolean().optional().describe("Bypass the secret-like-content refusal. Default false.")},w("prjct_mem_save",async e=>{await P(e.projectPath);let s=e.type.toLowerCase().trim();if(!s||!/^[a-z][a-z0-9-]*$/.test(s))return{content:[{type:"text",text:`Invalid type '${e.type}'. Lowercase letters + dashes only. ${In}`}]};let n=Nn(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 O.remember(e.projectPath,{type:s,content:e.content,tags:e.tags??{},source:e.source}),{content:[{type:"text",text:`Saved ${s}: ${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:R.string().describe("Project directory path"),topic:R.string().optional().describe("Keyword to match over content + tag values"),types:R.array(R.string()).optional().describe("Restrict to these types"),tags:R.record(R.string(),R.string()).optional().describe("Require exact match on these k:v pairs"),limit:R.number().optional().default(25).describe("Max entries (default 25)")},w("prjct_mem_list",async e=>{let s=await P(e.projectPath),n=O.recall(s,{topic:e.topic,types:e.types,tags:e.tags,limit:e.limit});return{content:[{type:"text",text:_t(n)}]}})),t.tool("prjct_mem_similar","Find memory entries similar to a free-text description. Keyword-based, best-effort.",{projectPath:R.string().describe("Project directory path"),description:R.string().describe("Free-text description to find similar memories for"),limit:R.number().optional().default(10).describe("Max results (default 10)")},w("prjct_mem_similar",async e=>{let s=await P(e.projectPath),n=O.similar(s,e.description,e.limit);return n.length===0?{content:[{type:"text",text:"No similar memories found."}]}:{content:[{type:"text",text:_t(n)}]}})),t.tool("prjct_mem_forget","Remove a memory entry by id. Ids are stable \u2014 pull them from `prjct_mem_list`.",{projectPath:R.string().describe("Project directory path"),id:R.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(Dn,"registerMemoryTools");dt();import{z as Ze}from"zod";C();j();var Ke=class{static{c(this,"LLMAnalysisStorage")}save(t,e){let s=E.getDb(t),n=g();s.transaction(()=>{s.prepare("UPDATE llm_analysis SET status = 'superseded', superseded_at = ? WHERE status = 'active'").run(n),s.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=E.get(t,"SELECT analysis FROM llm_analysis WHERE status = 'active' LIMIT 1");return e?JSON.parse(e.analysis):null}getActiveSummary(t){let e=this.getActive(t);return e?{commitHash:e.commitHash,architectureStyle:e.architecture.style,patternCount:e.patterns.length,antiPatternCount:e.antiPatterns.length,analyzedAt:e.analyzedAt}:null}isCurrent(t,e){return e?E.get(t,"SELECT commit_hash FROM llm_analysis WHERE status = 'active' LIMIT 1")?.commit_hash===e:!1}getAllFull(t){return E.query(t,"SELECT id, commit_hash, status, analyzed_at, superseded_at, analysis FROM llm_analysis ORDER BY id DESC").map(s=>({id:s.id,status:s.status,commitHash:s.commit_hash,analyzedAt:s.analyzed_at,supersededAt:s.superseded_at,analysis:JSON.parse(s.analysis)}))}getHistory(t,e=10){return E.query(t,"SELECT id, commit_hash, status, analyzed_at, analysis FROM llm_analysis ORDER BY id DESC LIMIT ?",e).map(n=>{let i=JSON.parse(n.analysis);return{id:n.id,commitHash:n.commit_hash,status:n.status,analyzedAt:n.analyzed_at,patternCount:i.patterns.length}})}},$o=new Ke,Ln=$o;Qe();function Un(r){let t=r;t.tool("prjct_task_status","Current task, duration, subtasks, and queue",{projectPath:Ze.string().describe("Project directory path")},w("prjct_task_status",async e=>{let s=await P(e.projectPath),n=await lt.getCurrentTask(s),i=await vt.getActiveTasks(s),o=[];if(n?(o.push(`## Active Task
|
|
583
583
|
**${n.description}**`),n.branch&&o.push(`Branch: ${n.branch}`),o.push(`Started: ${n.startedAt}`)):o.push("No active task."),i.length>0){o.push(`
|
|
584
584
|
## 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(`
|
|
585
|
-
`)}]}})),t.tool("prjct_analysis","LLM analysis: stack, patterns, anti-patterns, conventions",{projectPath:
|
|
585
|
+
`)}]}})),t.tool("prjct_analysis","LLM analysis: stack, patterns, anti-patterns, conventions",{projectPath:Ze.string().describe("Project directory path")},w("prjct_analysis",async e=>{let s=await P(e.projectPath),n=Ln.getActive(s);if(!n)return{content:[{type:"text",text:"No analysis available. Run `prjct sync`."}]};let i=["## Project Analysis"];if(n.stack&&(i.push(`
|
|
586
586
|
### Stack`),n.stack.languages?.length&&i.push(`Languages: ${n.stack.languages.join(", ")}`),n.stack.frameworks?.length&&i.push(`Frameworks: ${n.stack.frameworks.join(", ")}`),n.stack.packageManager&&i.push(`Package Manager: ${n.stack.packageManager}`)),n.patterns?.length){i.push(`
|
|
587
587
|
### Patterns (${n.patterns.length})`);for(let o of n.patterns)i.push(`- **${o.name}**: ${o.description}`)}if(n.antiPatterns?.length){i.push(`
|
|
588
588
|
### Anti-Patterns (${n.antiPatterns.length})`);for(let o of n.antiPatterns)i.push(`- **${o.issue}**: ${o.suggestion}`)}if(n.conventions?.length){i.push(`
|
|
589
589
|
### Conventions (${n.conventions.length})`);for(let o of n.conventions)i.push(`- [${o.category}] ${o.rule}`)}return{content:[{type:"text",text:i.join(`
|
|
590
|
-
`)}]}})),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:
|
|
590
|
+
`)}]}})),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:Ze.string().describe("Project directory path")},w("prjct_patterns",async e=>{let s=await P(e.projectPath),n=O.recall(s,{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:_t(n)}]}}))}c(Un,"registerProjectTools");import{z as h}from"zod";Tt();dt();zt();Jt();C();import{execFile as Ko}from"node:child_process";import{promisify as Vo}from"node:util";var Qo=Vo(Ko);async function Zo(r){try{let{stdout:t}=await Qo("git",["rev-parse","HEAD"],{cwd:r}),e=t.trim();return/^[0-9a-f]{7,40}$/.test(e)?e:null}catch{return null}}c(Zo,"readGitHead");var rs=class{static{c(this,"SpecService")}async create(t,e){let s=await this.requireProjectId(t),n=e.content.notes??"";if(e.autoContext!==!1&&!n.trim()){let{inferSpecContext:u,warnNoContextMatch:p}=await Promise.resolve().then(()=>(Wn(),Xn)),m=await u(e.title,s,t);m.empty?p(e.title):n=m.notesBlock}let o=Y.parse({goal:e.content.goal,eli10:e.content.eli10??"",stakes:e.content.stakes??"",acceptance_criteria:e.content.acceptance_criteria??[],scope:e.content.scope??[],out_of_scope:e.content.out_of_scope??[],risks:e.content.risks??[],test_plan:e.content.test_plan??[],reviews:e.content.reviews,linked_tasks:e.content.linked_tasks??[],notes:n}),a=x.create(s,{title:e.title,content:o,tags:e.tags});return await O.remember(t,{type:"spec",content:`${a.title}
|
|
591
591
|
|
|
592
|
-
Goal: ${a.content.goal}`,tags:{...e.tags??{},spec_id:a.id,status:a.status},source:a.id,provenance:"declared"}),a}async get(t,e){let s=await this.requireProjectId(t);return x.get(s,e)}async list(t,e={}){let s=await this.requireProjectId(t);return x.list(s,e)}async setStatus(t,e,s){let n=await this.requireProjectId(t),i=x.setStatus(n,e,s);return i&&await O.remember(t,{type:"spec",content:`Spec status \u2192 ${s}: ${i.title}`,tags:{spec_id:e,status:s,event:"status_change"},source:e}),i}async update(t,e,s){let n=await this.requireProjectId(t);return x.updateContent(n,e,s)}async recordReview(t,e,s,n){let i=await this.requireProjectId(t),o=3,a=50,u=0,p=!1,m=null;for(;u<o;){let d=x.get(i,e);if(!d)return null;let f={...n,ts:g()},
|
|
592
|
+
Goal: ${a.content.goal}`,tags:{...e.tags??{},spec_id:a.id,status:a.status},source:a.id,provenance:"declared"}),a}async get(t,e){let s=await this.requireProjectId(t);return x.get(s,e)}async list(t,e={}){let s=await this.requireProjectId(t);return x.list(s,e)}async setStatus(t,e,s){let n=await this.requireProjectId(t),i=x.setStatus(n,e,s);return i&&await O.remember(t,{type:"spec",content:`Spec status \u2192 ${s}: ${i.title}`,tags:{spec_id:e,status:s,event:"status_change"},source:e}),i}async update(t,e,s){let n=await this.requireProjectId(t);return x.updateContent(n,e,s)}async recordReview(t,e,s,n){let i=await this.requireProjectId(t),o=3,a=50,u=0,p=!1,m=null;for(;u<o;){let d=x.get(i,e);if(!d)return null;let f={...n,ts:g()},T={...d.content,reviews:{...d.content.reviews??{},[s]:f}};if(x.casUpdate(i,e,T,d.updatedAt)){p=!0,m=x.get(i,e);break}u++,u<o&&await new Promise(z=>setTimeout(z,a))}if(!p)throw new Error(`SPEC_RECORD_REVIEW_CONFLICT_RETRY_EXHAUSTED: ${o} retries failed for spec ${e}`);if(m&&this.allReviewsPass(m.content)&&m.status==="draft"){let d=x.setStatus(i,e,"reviewed");if(d){let{breakdownSpecToTasks:f}=await Promise.resolve().then(()=>(Hn(),Bn));return await f(i,t,d),x.get(i,e)}return d}return m}async linkTask(t,e,s){let n=await this.requireProjectId(t);return x.linkTask(n,e,s)}async ship(t,e,s){let n=await this.requireProjectId(t);s!==void 0&&x.setShippedPr(n,e,s);let i=await Zo(t);return i&&x.setShippedSha(n,e,i),x.setStatus(n,e,"shipped")}unmetCriteria(t,e=new Set){return t.content.acceptance_criteria.filter(s=>!e.has(s))}allReviewsPass(t){let e=t.reviews;return e?e.strategic?.verdict==="pass"&&e.architecture?.verdict==="pass"&&e.design?.verdict==="pass":!1}async requireProjectId(t){let e=await H.readConfig(t);if(!e?.projectId)throw new Error("not a prjct project (run `prjct init` first)");return e.projectId}},J=new rs;zt();Jt();function qn(r){let t=r;t.tool("prjct_spec_create",'CALL THIS when the user describes a feature, fix, or initiative WITH goals or stakes attached (e.g. "we need rate limiting on auth", "fix onboarding", "let\'s build SDD"). Drafts a spec \u2014 Goal/ELI10/Stakes/Acceptance criteria/Scope/Out-of-scope/Risks/Test plan. The structured fields default to empty; populate them by calling `prjct_spec_update` once you have the answers. Skip this tool only for routine work (single-file fix, doc tweak, GTD capture) \u2014 for that, use `prjct_capture` or the matching memory tool.',{projectPath:h.string().describe("Project directory path"),title:h.string().describe("One-line title (what you'd say to a coworker walking by)"),goal:h.string().describe("What success looks like, 1-3 sentences. Concrete, observable."),eli10:h.string().optional().describe("Plain English a 16-year-old follows, 2-4 sentences"),stakes:h.string().optional().describe("What breaks if we ship the wrong thing"),acceptance_criteria:h.array(h.string()).optional().describe("Testable, observable list. Each item ends in a verifiable claim."),scope:h.array(h.string()).optional().describe("What's IN \u2014 file paths, modules, surfaces"),out_of_scope:h.array(h.string()).optional().describe("What's OUT \u2014 anti-creep shield"),risks:h.array(h.object({risk:h.string(),mitigation:h.string()})).optional().describe("Each risk has a mitigation; a risk without one is just a complaint"),test_plan:h.array(h.string()).optional().describe("How you prove acceptance criteria"),tags:h.record(h.string(),h.string()).optional().describe('Key:value tags (e.g. {domain: "auth", priority: "high"})')},w("prjct_spec_create",async e=>{let s=await J.create(e.projectPath,{title:e.title,content:{goal:e.goal,eli10:e.eli10,stakes:e.stakes,acceptance_criteria:e.acceptance_criteria,scope:e.scope,out_of_scope:e.out_of_scope,risks:e.risks,test_plan:e.test_plan},tags:e.tags});return{content:[{type:"text",text:[`\u2713 spec drafted: ${s.title}`,"",`id: ${s.id}`,`status: ${s.status}`,`goal: ${s.content.goal}`,"","Next: `prjct_spec_audit` to dispatch the three review subagents (strategic / architecture / design) in parallel."].join(`
|
|
593
593
|
`)}]}})),t.tool("prjct_spec_list","List specs in this project. Use to check what specs exist before drafting a new one (avoid duplicates) or to find the right spec to link a task to.",{projectPath:h.string().describe("Project directory path"),status:h.enum(mt).optional().describe("Filter by status: draft|reviewed|in_progress|shipped|archived"),includeArchived:h.boolean().optional().describe("Include archived specs (default: false)")},w("prjct_spec_list",async e=>{let s=await P(e.projectPath),n=x.list(s,{status:e.status,includeArchived:e.includeArchived});if(n.length===0)return{content:[{type:"text",text:"_No specs match. Start one with `prjct_spec_create`._"}]};let i=["# Specs",""];for(let o of n){let a=o.content.acceptance_criteria.length,u=o.content.linked_tasks.length;i.push(`## ${o.title}
|
|
594
594
|
- id: \`${o.id}\`
|
|
595
595
|
- status: ${o.status}
|
|
596
596
|
- acceptance criteria: ${a}
|
|
597
597
|
- linked tasks: ${u}
|
|
598
598
|
- created: ${o.createdAt}`),i.push("")}return{content:[{type:"text",text:i.join(`
|
|
599
|
-
`)}]}})),t.tool("prjct_spec_get","Fetch one spec by id, including all structured fields (goal, acceptance criteria, scope, risks, reviews, linked tasks).",{projectPath:h.string().describe("Project directory path"),id:h.string().describe("Spec id")},w("prjct_spec_get",async e=>{let s=await
|
|
600
|
-
`)}c(
|
|
601
|
-
`)}c(
|
|
602
|
-
VALUES (?, ?, ?, ?, 0, 1, ?)`,e.name,e.description??null,s,s,e.metadata?JSON.stringify(e.metadata):null);let n=
|
|
603
|
-
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");let o=E.get(t,"SELECT last_insert_rowid() as id")?.id??0;return o>0&&G({projectId:t,entityType:"workflow_rules",entityId:String(o),eventType:"upsert",data:{id:o,type:e.type,command:e.command,position:e.position,action:e.action,description:e.description??null,enabled:e.enabled?1:0,timeout_ms:e.timeoutMs,sort_order:n,when_expr:e.whenExpr??null,parallel:e.parallel===!1?0:1,trust_source:e.trustSource??"local",created_at:e.createdAt}}),o}removeRule(t,e){return E.get(t,"SELECT id FROM workflow_rules WHERE id = ?",e)?(E.run(t,"DELETE FROM workflow_rules WHERE id = ?",e),G({projectId:t,entityType:"workflow_rules",entityId:String(e),eventType:"delete",data:{id:e}}),!0):!1}updateRule(t,e,s){if(!E.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,p]of Object.entries(s)){let m=i[u];if(!m)continue;o.push(`${m.column} = ?`);let d=p;a.push(m.transform?m.transform(d):d)}return o.length===0||(a.push(e),E.run(t,`UPDATE workflow_rules SET ${o.join(", ")} WHERE id = ?`,...a)),!0}getRuleById(t,e){let s=E.get(t,"SELECT * FROM workflow_rules WHERE id = ?",e);return s?
|
|
599
|
+
`)}]}})),t.tool("prjct_spec_get","Fetch one spec by id, including all structured fields (goal, acceptance criteria, scope, risks, reviews, linked tasks).",{projectPath:h.string().describe("Project directory path"),id:h.string().describe("Spec id")},w("prjct_spec_get",async e=>{let s=await J.get(e.projectPath,e.id);return s?{content:[{type:"text",text:ta(s)}]}:{content:[{type:"text",text:`_Spec not found: ${e.id}_`}]}})),t.tool("prjct_spec_update","Replace a spec's structured content. Pass the FULL content object (this is a replace, not a merge) \u2014 when filling in acceptance_criteria for the first time, fetch with `prjct_spec_get` first and merge in your changes.",{projectPath:h.string().describe("Project directory path"),id:h.string().describe("Spec id"),content:h.object({goal:h.string(),eli10:h.string().optional(),stakes:h.string().optional(),acceptance_criteria:h.array(h.string()).optional(),scope:h.array(h.string()).optional(),out_of_scope:h.array(h.string()).optional(),risks:h.array(h.object({risk:h.string(),mitigation:h.string()})).optional(),test_plan:h.array(h.string()).optional(),notes:h.string().optional(),linked_tasks:h.array(h.string()).optional()}).describe("Full SpecContent shape \u2014 Zod-validated server-side")},w("prjct_spec_update",async e=>{let s=Y.parse(e.content),n=await J.update(e.projectPath,e.id,s);return n?{content:[{type:"text",text:`\u2713 spec updated: ${n.title}`}]}:{content:[{type:"text",text:`_Spec not found: ${e.id}_`}]}})),t.tool("prjct_spec_set_status","Promote / demote a spec lifecycle state. Reviewers passing is auto-promoting (draft \u2192 reviewed); use this tool to mark a spec `in_progress` when work starts, `archived` when superseded, or `shipped` (use `prjct_spec_ship` instead when shipping for the first time, since it also records the PR).",{projectPath:h.string().describe("Project directory path"),id:h.string().describe("Spec id"),status:h.enum(mt).describe("Target status")},w("prjct_spec_set_status",async e=>await J.setStatus(e.projectPath,e.id,e.status)?{content:[{type:"text",text:`\u2713 spec ${e.id} \u2192 ${e.status}`}]}:{content:[{type:"text",text:`_Spec not found: ${e.id}_`}]})),t.tool("prjct_spec_audit","CALL THIS before any implementation work begins on a spec. Returns a dispatch prompt for THREE review subagents (strategic / architecture / design). RUN ALL THREE IN PARALLEL via your Agent / Task tool \u2014 one tool-use block per reviewer in the SAME message. Each returns a verdict (pass | fail) + notes. Persist each via `prjct_spec_record_review`. All three pass \u2192 the spec auto-promotes draft \u2192 reviewed and is safe to start a task against.",{projectPath:h.string().describe("Project directory path"),id:h.string().describe("Spec id to audit")},w("prjct_spec_audit",async e=>{let s=await J.get(e.projectPath,e.id);return s?{content:[{type:"text",text:ea(s.id,s.title,s.content)}]}:{content:[{type:"text",text:`_Spec not found: ${e.id}_`}]}})),t.tool("prjct_spec_record_review","Persist one reviewer's verdict from `prjct_spec_audit` dispatch. Call once per reviewer (strategic, architecture, design). When all three are recorded with verdict=pass, the spec auto-promotes draft \u2192 reviewed.",{projectPath:h.string().describe("Project directory path"),id:h.string().describe("Spec id"),reviewer:h.enum(es).describe("Which reviewer"),verdict:h.enum(["pass","fail"]).describe("Verdict"),notes:h.string().describe("2-4 sentence notes from the subagent")},w("prjct_spec_record_review",async e=>{let s=await J.recordReview(e.projectPath,e.id,e.reviewer,{verdict:e.verdict,notes:e.notes});if(!s)return{content:[{type:"text",text:`_Spec not found: ${e.id}_`}]};let n=s.status==="reviewed"?" (all reviewers passed \u2192 status: reviewed)":"";return{content:[{type:"text",text:`\u2713 ${e.reviewer} \u2192 ${e.verdict}${n}`}]}})),t.tool("prjct_spec_link_task","Link a task to its spec. Call this AFTER starting the task (when the user begins implementation) so `prjct_ship` later knows which spec to gate against. Idempotent \u2014 re-linking the same task is a no-op.",{projectPath:h.string().describe("Project directory path"),specId:h.string().describe("Spec id"),taskId:h.string().describe("Task id (from `prjct_session_start_task` or stateStorage)")},w("prjct_spec_link_task",async e=>await J.linkTask(e.projectPath,e.specId,e.taskId)?{content:[{type:"text",text:`\u2713 linked task ${e.taskId} to spec ${e.specId}`}]}:{content:[{type:"text",text:`_Spec not found: ${e.specId}_`}]})),t.tool("prjct_spec_ship","Mark a spec as shipped (after the linked PR merges). Records the PR number on the spec for provenance.",{projectPath:h.string().describe("Project directory path"),id:h.string().describe("Spec id"),pr:h.number().optional().describe("PR / MR number that delivered the spec")},w("prjct_spec_ship",async e=>{let s=await J.ship(e.projectPath,e.id,e.pr);return s?{content:[{type:"text",text:`\u2713 spec shipped: ${s.title}${e.pr?` (PR #${e.pr})`:""}`}]}:{content:[{type:"text",text:`_Spec not found: ${e.id}_`}]}}))}c(qn,"registerSpecTools");function ta(r){let t=r.content,e=[`# ${r.title}`,"",`**id:** \`${r.id}\` \xB7 **status:** ${r.status} \xB7 **created:** ${r.createdAt}`,"","## Goal",t.goal];if(t.eli10&&e.push("","## ELI10",t.eli10),t.stakes&&e.push("","## Stakes",t.stakes),t.acceptance_criteria.length>0){e.push("","## Acceptance criteria");for(let s of t.acceptance_criteria)e.push(`- [ ] ${s}`)}if(t.scope.length>0){e.push("","## Scope");for(let s of t.scope)e.push(`- ${s}`)}if(t.out_of_scope.length>0){e.push("","## Out of scope");for(let s of t.out_of_scope)e.push(`- ${s}`)}if(t.risks.length>0){e.push("","## Risks");for(let s of t.risks)e.push(`- **${s.risk}** \u2014 ${s.mitigation}`)}if(t.test_plan.length>0){e.push("","## Test plan");for(let s of t.test_plan)e.push(`- ${s}`)}if(t.reviews){e.push("","## Reviews");for(let s of es){let n=t.reviews[s];n&&e.push(`- **${s}:** ${n.verdict} \u2014 ${n.notes} _(${n.ts})_`)}}return t.linked_tasks.length>0&&e.push("","## Linked tasks",...t.linked_tasks.map(s=>`- ${s}`)),t.notes&&e.push("","## Notes",t.notes),e.join(`
|
|
600
|
+
`)}c(ta,"renderSpecMarkdown");function ea(r,t,e){let s=JSON.stringify(e);return[`# audit-spec dispatch \u2014 ${t}`,"",`Spec id: \`${r}\``,"","Run three review subagents IN PARALLEL via your Agent / Task tool \u2014 one tool-use block per reviewer, all in the SAME message so they run concurrently. Each subagent reads the spec body and applies its rubric, then returns a structured verdict (pass | fail + 2-4 sentence notes).","","## Reviewer A \u2014 strategic (scope sanity)",'Subagent prompt: "Review this spec for strategic soundness. Does it solve a real problem? Is the goal worth the cost? Is out_of_scope coherent with goal? Is the spec OVER- or UNDER-scoped? Return verdict (pass|fail) and 2-4 sentence notes."',"","## Reviewer B \u2014 architecture (eng feasibility)",'Subagent prompt: "Review this spec for engineering feasibility. Can this be built? Is the data flow / state machine implicit in the acceptance criteria coherent? What failure modes / dependencies / edge cases are missing? Include a short ASCII diagram of the proposed architecture in notes if applicable. Return verdict (pass|fail) and 2-4 sentence notes."',"","## Reviewer C \u2014 design (UX/DX)",'Subagent prompt: "Review this spec for design quality. Rate 0-10 across {clarity, ergonomics, consistency, accessibility} for the user-facing or developer-facing surface this spec defines. Note the lowest-scoring dimension and why. Return verdict (pass if all dimensions \u22656, fail otherwise) and notes including the four scores."',"","## Spec body (verbatim, pass to each reviewer)","```json",s,"```","","## After dispatch","For each reviewer that returns:",` Call \`prjct_spec_record_review\` with id="${r}", reviewer=<strategic|architecture|design>, verdict=<pass|fail>, notes="<their notes>"`,"","When all three are recorded with verdict=pass, the spec auto-promotes from `draft` \u2192 `reviewed`."].join(`
|
|
601
|
+
`)}c(ea,"renderAuditDispatch");import{z as Vt}from"zod";St();j();var ns=class{static{c(this,"CustomWorkflowStorage")}createWorkflow(t,e){let s=new Date().toISOString();y.run(t,`INSERT INTO custom_workflows (name, description, created_at, updated_at, is_builtin, enabled, metadata)
|
|
602
|
+
VALUES (?, ?, ?, ?, 0, 1, ?)`,e.name,e.description??null,s,s,e.metadata?JSON.stringify(e.metadata):null);let n=y.get(t,"SELECT id FROM custom_workflows WHERE name = ?",e.name);if(!n)throw new Error(`Failed to create workflow: ${e.name}`);return G({projectId:t,entityType:"custom_workflows",entityId:String(n.id),eventType:"upsert",data:{id:n.id,name:e.name,description:e.description??null,metadata:e.metadata??null,created_at:s,updated_at:s,is_builtin:0,enabled:1}}),n.id}getWorkflow(t,e){let s=y.get(t,"SELECT * FROM custom_workflows WHERE name = ?",e);return s?this.rowToWorkflow(s):null}getAllWorkflows(t,e=!1){let s=e?"SELECT * FROM custom_workflows ORDER BY is_builtin DESC, name ASC":"SELECT * FROM custom_workflows WHERE enabled = 1 ORDER BY is_builtin DESC, name ASC";return y.query(t,s).map(i=>this.rowToWorkflow(i))}updateWorkflow(t,e,s){if(!this.getWorkflow(t,e))return!1;let i=new Date().toISOString(),o=[],a=[];if(s.description!==void 0&&(o.push("description = ?"),a.push(s.description)),s.enabled!==void 0&&(o.push("enabled = ?"),a.push(s.enabled?1:0)),s.metadata!==void 0&&(o.push("metadata = ?"),a.push(JSON.stringify(s.metadata))),o.length===0)return!1;o.push("updated_at = ?"),a.push(i),a.push(e),y.run(t,`UPDATE custom_workflows SET ${o.join(", ")} WHERE name = ?`,...a);let u=this.getWorkflow(t,e);return u&&G({projectId:t,entityType:"custom_workflows",entityId:String(u.id),eventType:"upsert",data:{id:u.id,name:u.name,description:u.description??null,enabled:u.enabled?1:0,metadata:u.metadata??null,updated_at:i}}),!0}deleteWorkflow(t,e){let s=this.getWorkflow(t,e);if(!s)return!1;if(s.isBuiltin)throw new Error(`Cannot delete built-in workflow: ${e}`);return y.run(t,"UPDATE custom_workflows SET enabled = 0 WHERE name = ?",e),G({projectId:t,entityType:"custom_workflows",entityId:String(s.id),eventType:"delete",data:{id:s.id,name:e}}),!0}isBuiltin(t,e){return this.getWorkflow(t,e)?.isBuiltin??!1}isReservedName(t){let e=["task","done","ship","sync"],s=["add","rm","gate","list","create","delete","run","help","reset","init"];return e.includes(t)||s.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}}},Kt=new ns;St();j();function is(r){let t=r.trust_source==="imported"?"imported":"local";return{id:r.id,type:r.type,command:r.command,position:r.position,action:r.action,description:r.description,enabled:r.enabled===1,timeoutMs:r.timeout_ms,createdAt:r.created_at,sortOrder:r.sort_order,whenExpr:r.when_expr??null,parallel:r.parallel===null?!0:r.parallel===1,trustSource:t}}c(is,"rowToRule");var os=class{static{c(this,"WorkflowRuleStorage")}addRule(t,e){let s=E.get(t,"SELECT MAX(sort_order) as m FROM workflow_rules WHERE command = ?",e.command),n=e.sortOrder||(s?.m??-1)+1;E.run(t,`INSERT INTO workflow_rules (type, command, position, action, description, enabled, timeout_ms, created_at, sort_order, when_expr, parallel, trust_source)
|
|
603
|
+
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");let o=E.get(t,"SELECT last_insert_rowid() as id")?.id??0;return o>0&&G({projectId:t,entityType:"workflow_rules",entityId:String(o),eventType:"upsert",data:{id:o,type:e.type,command:e.command,position:e.position,action:e.action,description:e.description??null,enabled:e.enabled?1:0,timeout_ms:e.timeoutMs,sort_order:n,when_expr:e.whenExpr??null,parallel:e.parallel===!1?0:1,trust_source:e.trustSource??"local",created_at:e.createdAt}}),o}removeRule(t,e){return E.get(t,"SELECT id FROM workflow_rules WHERE id = ?",e)?(E.run(t,"DELETE FROM workflow_rules WHERE id = ?",e),G({projectId:t,entityType:"workflow_rules",entityId:String(e),eventType:"delete",data:{id:e}}),!0):!1}updateRule(t,e,s){if(!E.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,p]of Object.entries(s)){let m=i[u];if(!m)continue;o.push(`${m.column} = ?`);let d=p;a.push(m.transform?m.transform(d):d)}return o.length===0||(a.push(e),E.run(t,`UPDATE workflow_rules SET ${o.join(", ")} WHERE id = ?`,...a)),!0}getRuleById(t,e){let s=E.get(t,"SELECT * FROM workflow_rules WHERE id = ?",e);return s?is(s):null}getRulesForCommand(t,e){let s=Kt.getWorkflow(t,e);return!s||!s.enabled?[]:E.query(t,"SELECT * FROM workflow_rules WHERE command = ? AND enabled = 1 ORDER BY sort_order ASC",e).map(is)}getAllRules(t){return E.query(t,"SELECT * FROM workflow_rules ORDER BY command ASC, sort_order ASC").map(is)}resetRules(t){let e=E.get(t,"SELECT COUNT(*) as c FROM workflow_rules");return E.run(t,"DELETE FROM workflow_rules"),e?.c??0}},as=new os;function Gn(r){let t=r;t.tool("prjct_workflow_rules","Get workflow rules for a command (gates, hooks, steps, instructions)",{projectPath:Vt.string().describe("Project directory path"),command:Vt.string().describe("Command name (task, done, ship, sync, etc.)")},w("prjct_workflow_rules",async e=>{let s=await P(e.projectPath),n=as.getRulesForCommand(s,e.command);if(n.length===0)return{content:[{type:"text",text:`No workflow rules for \`${e.command}\`.`}]};let i={};for(let a of n){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(`
|
|
604
604
|
### ${a}`);for(let p of u){let m=p.enabled?"":" (disabled)";o.push(`- ${p.action}${p.description?` \u2014 ${p.description}`:""}${m}`)}}return{content:[{type:"text",text:o.join(`
|
|
605
605
|
`)}]}})),t.tool("prjct_workflow_list","List all workflows for this project (built-in + custom)",{projectPath:Vt.string().describe("Project directory path")},w("prjct_workflow_list",async e=>{let s=await P(e.projectPath),n=Kt.getAllWorkflows(s);if(n.length===0)return{content:[{type:"text",text:"No workflows configured."}]};let i=n.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 (${n.length})
|
|
606
606
|
|
|
607
607
|
${i.join(`
|
|
608
|
-
`)}`}]}})),t.tool("prjct_workflow_status","Current workflow execution state + active rules",{projectPath:Vt.string().describe("Project directory path")},w("prjct_workflow_status",async e=>{let s=await P(e.projectPath),n=await lt.getCurrentTask(s),i=
|
|
608
|
+
`)}`}]}})),t.tool("prjct_workflow_status","Current workflow execution state + active rules",{projectPath:Vt.string().describe("Project directory path")},w("prjct_workflow_status",async e=>{let s=await P(e.projectPath),n=await lt.getCurrentTask(s),i=as.getAllRules(s),o=["## Workflow Status"];n?(o.push(`
|
|
609
609
|
Active task: **${n.description}**`),o.push(`Started: ${n.startedAt}`)):o.push(`
|
|
610
610
|
No active task.`);let a=i.filter(u=>u.enabled);if(a.length>0){o.push(`
|
|
611
611
|
### Active Rules (${a.length})`);for(let u of a)o.push(`- [${u.type}] ${u.command}:${u.position} \u2192 ${u.action}`)}else o.push(`
|
|
612
612
|
No active workflow rules.`);return{content:[{type:"text",text:o.join(`
|
|
613
|
-
`)}]}}))}c(
|
|
613
|
+
`)}]}}))}c(Gn,"registerWorkflowTools");var ra=`# prjct \u2014 Spec-Driven Development + project memory
|
|
614
614
|
|
|
615
615
|
Use when the user describes work, asks for project memory, or wants to run a registered workflow. **Recognize intent \u2014 don't wait for the user to type prjct commands.**
|
|
616
616
|
|
|
@@ -645,4 +645,4 @@ Skip the SDD flow only for: routine captures, single-file fixes, doc tweaks, con
|
|
|
645
645
|
- Topic keys are free-form strings; don't invent new vocabularies when existing ones fit.
|
|
646
646
|
- Not every project defines every memory type \u2014 if one is empty, that's fine.
|
|
647
647
|
- Saving a secret-looking string is refused by default. Re-save with a scrubbed version.
|
|
648
|
-
- A spec without acceptance_criteria is just an inbox item \u2014 fill them.`;function
|
|
648
|
+
- A spec without acceptance_criteria is just an inbox item \u2014 fill them.`;function Yn(){let r=new sa({name:"prjct",version:"1.0.0"},{instructions:ra});return Dn(r),Un(r),Sn(r),Gn(r),yr(r),qn(r),r}c(Yn,"createServer");async function ia(){let r=Yn(),t=new na;await r.connect(t)}c(ia,"main");ia().catch(r=>{console.error("prjct MCP server failed:",r),process.exit(1)});
|