prjct-cli 3.24.2 → 3.24.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 CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [3.24.3] - 2026-07-03
6
+
7
+ ### Bug Fixes
8
+
9
+ - completion no longer clobbers measured task tokens with zero (#516)
10
+
11
+
5
12
  ## [3.24.2] - 2026-07-03
6
13
 
7
14
  ### Bug Fixes
@@ -17,7 +17,7 @@ ${e}`,action:"appended"};let o=n.substring(0,n.indexOf(t)),i=n.substring(n.index
17
17
  `)}
18
18
  `}var qj,Kk,Xj,Vj,yn,zk,Yk,Zk,eE,nE,rE,sE=h(()=>{"use strict";Ms();uc();qj=Hd.join("/"),Kk="Generated with [p/](https://www.prjct.app/)",Xj="<!-- prjct:start - DO NOT REMOVE THIS MARKER -->",Vj="<!-- prjct:end - DO NOT REMOVE THIS MARKER -->",yn={rag:"prjct is a RAG-backed project memory harness; do not preload project history.",entrypoint:'`prjct work "<intent>" --md` is the single entrypoint \u2014 recognize intent and run the verb yourself.',pull:"Pull only what surfaces: `prjct search` / `prjct context memory <topic>` / `prjct guard <file>` / MCP `prjct_*` \u2014 not something to load wholesale.",remember:'Save synthesized memory in English: `prjct remember <decision|learning|gotcha|context> "<text>"`.',kb:`KB facets (\`${qj}\`): \`prjct remember <facet>\` / \`prjct context memory <facet>\` \u2014 pulled on demand, never injected here.`,ship:"Ship only after the user OKs: `prjct ship --md`."};a(Jk,"buildCompactSkill");zk=Jk,Yk=Jk;a(Qk,"buildGlobalConfig");Zk=a(()=>Qk("Gemini"),"buildGeminiConfig"),eE=a(()=>Qk("Antigravity"),"buildAntigravityConfig");a(tE,"buildIdePointer");nE=a(()=>tE(`description: "prjct \u2014 pull project memory + workflow on demand"
19
19
  alwaysApply: true`),"buildCursorRule"),rE=a(()=>tE(`trigger: always_on
20
- description: "prjct \u2014 pull project memory + workflow on demand"`),"buildWindsurfRule")});var Ws={};x(Ws,{PACKAGE_ROOT:()=>Kt,VERSION:()=>le,getPackageRoot:()=>Vd,getVersion:()=>Hr,resetPackageRoot:()=>Kd});import Xd from"node:fs";import dc from"node:path";function Vd(){if(Hs)return Hs;let n=__dirname;for(let e=0;e<5;e++){let t=dc.join(n,"package.json");if(Xd.existsSync(t))try{if(JSON.parse(Xd.readFileSync(t,"utf-8")).name==="prjct-cli")return Hs=n,n}catch{}n=dc.dirname(n)}return Hs=dc.join(__dirname,"..","..",".."),Hs}function Hr(){if(Ur)return Ur;let n="3.24.2";if(n&&/^\d+\.\d+\.\d+/.test(n))return Ur=n,Ur;try{let e=dc.join(Vd(),"package.json");return Ur=JSON.parse(Xd.readFileSync(e,"utf-8")).version,Ur}catch(e){return process.env.PRJCT_DEBUG==="1"&&console.error("Failed to read version from package.json:",y(e)),"0.0.0"}}function Kd(n){Hs=n,Ur=null}var Ur,Hs,le,Kt,Ue=h(()=>{"use strict";F();Ur=null,Hs=null;a(Vd,"getPackageRoot");a(Hr,"getVersion");a(Kd,"resetPackageRoot");le=Hr(),Kt=Vd()});var gc={};x(gc,{default:()=>n0,getTemplateContent:()=>Qe,listTemplates:()=>fc,resetBundle:()=>Zj});import zd from"node:fs";import Kj from"node:fs/promises";import mc from"node:path";function Yd(){if(Jd)return pc;Jd=!0;let n=mc.join(Kt,"dist","templates.json");try{let e=zd.readFileSync(n,"utf-8");return pc=JSON.parse(e),pc}catch{return null}}function zj(n){let e=Wr.indexOf(n);e>-1&&Wr.splice(e,1),Wr.push(n)}function Yj(){for(;Gs.size>=Jj&&Wr.length>0;){let n=Wr.shift();n&&Gs.delete(n)}}function oE(n){let e=/^---\n([\s\S]+?)\n---\n([\s\S]*)$/,t=n.match(e);if(!t)return{frontmatter:{},content:n.trim()};let[,r,s]=t,o={};return r.split(`
20
+ description: "prjct \u2014 pull project memory + workflow on demand"`),"buildWindsurfRule")});var Ws={};x(Ws,{PACKAGE_ROOT:()=>Kt,VERSION:()=>le,getPackageRoot:()=>Vd,getVersion:()=>Hr,resetPackageRoot:()=>Kd});import Xd from"node:fs";import dc from"node:path";function Vd(){if(Hs)return Hs;let n=__dirname;for(let e=0;e<5;e++){let t=dc.join(n,"package.json");if(Xd.existsSync(t))try{if(JSON.parse(Xd.readFileSync(t,"utf-8")).name==="prjct-cli")return Hs=n,n}catch{}n=dc.dirname(n)}return Hs=dc.join(__dirname,"..","..",".."),Hs}function Hr(){if(Ur)return Ur;let n="3.24.3";if(n&&/^\d+\.\d+\.\d+/.test(n))return Ur=n,Ur;try{let e=dc.join(Vd(),"package.json");return Ur=JSON.parse(Xd.readFileSync(e,"utf-8")).version,Ur}catch(e){return process.env.PRJCT_DEBUG==="1"&&console.error("Failed to read version from package.json:",y(e)),"0.0.0"}}function Kd(n){Hs=n,Ur=null}var Ur,Hs,le,Kt,Ue=h(()=>{"use strict";F();Ur=null,Hs=null;a(Vd,"getPackageRoot");a(Hr,"getVersion");a(Kd,"resetPackageRoot");le=Hr(),Kt=Vd()});var gc={};x(gc,{default:()=>n0,getTemplateContent:()=>Qe,listTemplates:()=>fc,resetBundle:()=>Zj});import zd from"node:fs";import Kj from"node:fs/promises";import mc from"node:path";function Yd(){if(Jd)return pc;Jd=!0;let n=mc.join(Kt,"dist","templates.json");try{let e=zd.readFileSync(n,"utf-8");return pc=JSON.parse(e),pc}catch{return null}}function zj(n){let e=Wr.indexOf(n);e>-1&&Wr.splice(e,1),Wr.push(n)}function Yj(){for(;Gs.size>=Jj&&Wr.length>0;){let n=Wr.shift();n&&Gs.delete(n)}}function oE(n){let e=/^---\n([\s\S]+?)\n---\n([\s\S]*)$/,t=n.match(e);if(!t)return{frontmatter:{},content:n.trim()};let[,r,s]=t,o={};return r.split(`
21
21
  `).forEach(i=>{let[c,...l]=i.split(":");if(c&&l.length>0){let u=l.join(":").trim();u.startsWith("[")&&u.endsWith("]")?o[c.trim()]=u.slice(1,-1).split(",").map(d=>d.trim()):o[c.trim()]=u.replace(/^["']|["']$/g,"")}}),{frontmatter:o,content:s.trim()}}async function iE(n){if(Gs.has(n))return zj(n),Gs.get(n);let e,t=Yd();if(t){let s=`commands/${n}.md`;e=t[s]}if(!e){let s=mc.join(Kt,"templates","commands",`${n}.md`);try{e=await Kj.readFile(s,"utf-8")}catch{throw sc.notFound(n)}}let r=oE(e);return Yj(),Gs.set(n,r),Wr.push(n),r}async function Qj(n){return(await iE(n)).frontmatter["allowed-tools"]||[]}function aE(){Gs.clear(),Wr.length=0}function Zj(){pc=null,Jd=!1,aE()}function Qe(n){let e=Yd();if(e?.[n])return e[n];let t=e0(n);if(t)return t;let r=mc.join(Kt,"templates",n);try{return zd.readFileSync(r,"utf-8")}catch{return null}}function e0(n){switch(n){case"codex/SKILL.md":return zk();case"antigravity/SKILL.md":return Yk();case"global/GEMINI.md":return Zk();case"global/ANTIGRAVITY.md":return eE();case"global/CURSOR.mdc":return nE();case"global/WINDSURF.md":return rE();default:return null}}function fc(n){let e=Yd();if(e)return Object.keys(e).filter(r=>r.startsWith(n));let t=mc.join(Kt,"templates",n);try{return zd.readdirSync(t).map(s=>`${n}${s}`)}catch{return[]}}var Jj,Gs,Wr,pc,Jd,t0,n0,sn=h(()=>{"use strict";Ln();sE();Ue();Jj=50,Gs=new Map,Wr=[],pc=null,Jd=!1;a(Yd,"loadBundle");a(zj,"updateLruOrder");a(Yj,"evictLru");a(oE,"parseFrontmatter");a(iE,"load");a(Qj,"getAllowedTools");a(aE,"clearCache");a(Zj,"resetBundle");a(Qe,"getTemplateContent");a(e0,"getGeneratedTemplateContent");a(fc,"listTemplates");t0={load:iE,parseFrontmatter:oE,getAllowedTools:Qj,clearCache:aE,getTemplateContent:Qe,listTemplates:fc},n0=t0});var hc=h(()=>{"use strict"});var lE={};x(lE,{resolveUserHome:()=>ur,resolveUserPath:()=>Ae});import r0 from"node:os";import cE from"node:path";function ur(){let n=process.env.HOME?.trim()||process.env.USERPROFILE?.trim();return n?cE.resolve(n):r0.homedir()}function Ae(...n){return cE.join(ur(),...n)}var dr=h(()=>{"use strict";a(ur,"resolveUserHome");a(Ae,"resolveUserPath")});var uE,dE,pE,Qd=h(()=>{"use strict";uE=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"]),dE=["",".ts",".tsx",".js",".jsx","/index.ts","/index.js"],pE=/(?:import|from)\s+['"]([^'"]+)['"]/g});import gE from"node:fs/promises";async function hE(n,e){let t;try{t=await gE.readFile(n,"utf-8")}catch(o){if(Y(o))return null;throw o}let r;try{r=JSON.parse(t)}catch{return await mE(n,t),fE(n,"Malformed JSON"),null}let s=e.safeParse(r);return s.success?r:(await mE(n,t),fE(n,s0(s.error)),null)}async function mE(n,e){let t=`${n}.backup`;try{await gE.writeFile(t,e,{encoding:"utf-8",flag:"wx"})}catch{}}function fE(n,e){console.error(`[prjct] Warning: Corrupted storage file: ${n}`),console.error(`[prjct] Reason: ${e}`),console.error("[prjct] A .backup file has been created. Returning defaults.")}function s0(n){return n.issues.slice(0,3).map(e=>`${e.path.join(".")}: ${e.message}`).join("; ")}var yE=h(()=>{"use strict";F();a(hE,"safeRead");a(mE,"createBackup");a(fE,"logCorruption");a(s0,"formatZodError")});var Jt={};x(Jt,{batchProcess:()=>Un,dirExists:()=>Ge,ensureDir:()=>At,fileExists:()=>v,listFiles:()=>Wn,readFile:()=>Mt,readJson:()=>xe,walkDir:()=>Fn,writeFile:()=>Hn,writeFileAtomic:()=>Gr,writeJson:()=>he});import _t from"node:fs/promises";import oi from"node:path";async function Zd(n,e,t){try{return await t()}catch(r){throw Bd(r)||Gd(r)?new Error(Fs(r,n,e)):r}}async function Fn(n,e={}){let t=[],r=e.maxFiles??1/0,s=e.dotfileAllowlist?new Set(e.dotfileAllowlist):null;async function o(i){if(t.length>=r)return;let c=await _t.readdir(i,{withFileTypes:!0}).catch(()=>[]);for(let l of c){if(t.length>=r)break;let u=String(l.name);if(uE.has(u)||e.skipDotfiles&&u.startsWith(".")&&(!s||!s.has(u)))continue;let d=oi.join(i,u);l.isDirectory()?await o(d):l.isFile()&&t.push(oi.relative(n,d))}}return a(o,"walk"),await o(n),t}async function Un(n,e,t){let r=[];for(let s=0;s<n.length;s+=e){let o=await Promise.all(n.slice(s,s+e).map(t));for(let i of o)i!==null&&r.push(i)}return r}async function xe(n,e=null,t){if(t)return await hE(n,t)??e;try{let r=await _t.readFile(n,"utf-8");return JSON.parse(r)}catch(r){if(Y(r))return e;throw r}}async function he(n,e,t=2){await Zd(n,"config",async()=>{let r=oi.dirname(n);await _t.mkdir(r,{recursive:!0});let s=`${JSON.stringify(e,null,t)}
22
22
  `;await _t.writeFile(n,s,"utf-8")})}async function Mt(n,e=""){try{return await _t.readFile(n,"utf-8")}catch(t){if(Y(t))return e;throw t}}async function Hn(n,e){await Zd(n,"file",async()=>{let t=oi.dirname(n);await _t.mkdir(t,{recursive:!0}),await _t.writeFile(n,e,"utf-8")})}async function Gr(n,e){await Zd(n,"file",async()=>{let t=oi.dirname(n);await _t.mkdir(t,{recursive:!0});let r=`${n}.tmp`;await _t.writeFile(r,e,"utf-8"),await _t.rename(r,n)})}async function v(n){try{return await _t.access(n),!0}catch(e){if(Y(e))return!1;throw e}}async function Ge(n){try{return(await _t.stat(n)).isDirectory()}catch(e){if(Y(e))return!1;throw e}}async function At(n){await _t.mkdir(n,{recursive:!0})}async function Wn(n,e={}){try{let r=await _t.readdir(n,{withFileTypes:!0});return e.filesOnly&&(r=r.filter(s=>s.isFile())),e.dirsOnly&&(r=r.filter(s=>s.isDirectory())),e.extension&&(r=r.filter(s=>s.name.endsWith(e.extension))),r.map(s=>s.name)}catch(t){if(Y(t))return[];throw t}}var Q=h(()=>{"use strict";Qd();yE();F();a(Zd,"withWriteErrorContext");a(Fn,"walkDir");a(Un,"batchProcess");a(xe,"readJson");a(he,"writeJson");a(Mt,"readFile");a(Hn,"writeFile");a(Gr,"writeFileAtomic");a(v,"fileExists");a(Ge,"dirExists");a(At,"ensureDir");a(Wn,"listFiles")});var ep,wE=h(()=>{"use strict";ep="mcp-remote@0.1.38"});import o0 from"node:fs";import i0 from"node:fs/promises";import kE from"node:os";import Gn from"node:path";function a0(){let n=c0();if(n)return{command:n,args:["mcp-server"],description:tp};try{let e=Gn.dirname($t.resolve("prjct-cli/package.json"));return{command:Gn.join(e,"bin","prjct"),args:["mcp-server"],description:tp}}catch{return{command:"npx",args:["-y","prjct-cli","mcp-server"],description:tp}}}function c0(){let n=process.argv[1],e=[n?Gn.resolve(Gn.dirname(n),"prjct"):"",n?Gn.resolve(Gn.dirname(n),"..","bin","prjct"):"",Gn.resolve(process.cwd(),"bin","prjct")].filter(Boolean);for(let t of e)if(o0.existsSync(t))return t;return null}function Bs(){return process.env.PRJCT_TEST_MODE==="1"?Gn.join(kE.tmpdir(),"prjct-context7-test","mcp.json"):Gn.join(kE.homedir(),".claude","mcp.json")}async function EE(n=Bs()){try{let e=await i0.readFile(n,"utf-8");return JSON.parse(e)}catch(e){let t=y(e).toLowerCase();if(t.includes("no such file")||t.includes("enoent"))return{};throw new Error(`Failed to read MCP config at ${n}: ${y(e)}`)}}async function l0(n,e=Bs()){await he(e,n)}async function ii(n,e,t=Bs()){let r=await EE(t),s={...r.mcpServers||{}},o=s[n];s[n]=e,r.mcpServers=s;let i=JSON.stringify(o)!==JSON.stringify(e);return await l0(r,t),{path:t,changed:i}}async function SE(n,e=Bs()){return!!(await EE(e)).mcpServers?.[n]}var tp,wn,ai=h(()=>{"use strict";F();Q();wE();tp="prjct: AI Agile OS with project memory, workflow gates, intent briefs, and performance context. Use prjct_task_start as the MCP entrypoint for a work cycle; prjct retrieves focused context, persists evidence stations, and keeps humans in the loop for risky gates. Agents resume from prjct_task_status/workflow output, create or link reviewed intent/spec briefs when required, and persist synthesized learning instead of raw transcript fragments.";a(a0,"getPrjctMcpConfig");a(c0,"resolveLocalPrjctBin");wn={context7:{command:"npx",args:["-y","@upstash/context7-mcp@latest"],description:"Library documentation lookup"},prjct:a0(),linear:{command:"npx",args:["-y",ep,"https://mcp.linear.app/mcp"],description:"Linear MCP server (OAuth)"},jira:{command:"npx",args:["-y",ep,"https://mcp.atlassian.com/v1/mcp"],description:"Atlassian MCP server for Jira (OAuth)"}};a(Bs,"getClaudeMcpConfigPath");a(EE,"readMcpConfig");a(l0,"writeMcpConfig");a(ii,"upsertMcpServer");a(SE,"hasMcpServer")});import Br from"node:fs/promises";import np from"node:path";function ci(){return process.env.PRJCT_TEST_MODE==="1"?np.join(Ae(".prjct-tests"),"codex","config.toml"):Ae(".codex","config.toml")}function yc(n){return`"${n.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`}function _E(n,e,t,r){let s=(e.args??[]).map(yc).join(", ");return[t,`[mcp_servers.${n}]`,`command = ${yc(e.command)}`,`args = [${s}]`,r,""].join(`
23
23
  `)}function u0(n=wn.prjct){return _E("prjct",n,TE,vE)}function d0(n=wn.context7){return _E("context7",n,bE,CE)}function AE(n,e,t,r,s){let o=n.indexOf(t),i=n.indexOf(r);if(o!==-1&&i!==-1&&i>o){let c=n.slice(0,o),l=n.slice(i+r.length);return l.startsWith(`
@@ -1384,8 +1384,8 @@ ${c.join(`
1384
1384
  started_at = COALESCE(excluded.started_at, tasks.started_at),
1385
1385
  completed_at = excluded.completed_at,
1386
1386
  pr_url = COALESCE(excluded.pr_url, tasks.pr_url),
1387
- tokens_in = excluded.tokens_in,
1388
- tokens_out = excluded.tokens_out,
1387
+ tokens_in = CASE WHEN excluded.tokens_in > 0 THEN excluded.tokens_in ELSE tasks.tokens_in END,
1388
+ tokens_out = CASE WHEN excluded.tokens_out > 0 THEN excluded.tokens_out ELSE tasks.tokens_out END,
1389
1389
  data = excluded.data`,t.taskId,t.title,t.classification,t.branchName==="unknown"?null:t.branchName,t.linearId??null,t.prUrl??null,t.startedAt,t.completedAt,t.tokensIn??0,t.tokensOut??0,r)}catch{}}async updateCurrentTask(e,t){let r=null;return await this.update(e,s=>s.currentTask?(r={...s.currentTask,...t},{...s,currentTask:r,lastUpdated:A()}):s),r}async completeTask(e,t){let r=A(),s={};if(await this.update(e,i=>i.currentTask?(this.validateTransition(i,"done"),s.completedTask=i.currentTask,{...i,currentTask:null,previousTask:null,lastUpdated:r}):i),!s.completedTask)return null;let o=s.completedTask;return this.mirrorTaskRow(e,o,"completed",{completedAt:r}),this.mirrorHistoryEntry(e,this.createTaskHistoryEntry(o,r,t)),await this.publishEvent(e,"task.completed",{taskId:o.id,description:o.description,startedAt:o.startedAt,completedAt:r}),o}createTaskHistoryEntry(e,t,r){let s=(e.subtasks||[]).filter(c=>c.status==="completed"&&c.summary).map(c=>c.summary),o=s.length>0?s.map(c=>c.title).join(", "):"Task completed",i={taskId:e.id,title:e.parentDescription||e.description,classification:e.type||"improvement",startedAt:e.startedAt,completedAt:t,subtaskCount:e.subtasks?.length||0,subtaskSummaries:s,outcome:o,branchName:e.branch||"unknown",linearId:e.linearId,linearUuid:e.linearUuid,prUrl:e.prUrl,harness:e.harness};return r&&(i.feedback=r),e.tokensIn&&(i.tokensIn=e.tokensIn),e.tokensOut&&(i.tokensOut=e.tokensOut),i}maxPausedTasks=5;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(e,t){let r=await UT(this.lifecycleBackend(),e,t);return r&&this.mirrorTaskRow(e,r,"paused",{pausedAt:r.pausedAt,pauseReason:r.pauseReason}),r}async resumeTask(e,t){let r=await HT(this.lifecycleBackend(),e,t);return r&&this.mirrorTaskRow(e,r,"in_progress"),r}getPausedTasksFromState(e){return Array.isArray(e.pausedTasks)&&e.pausedTasks.length>0?e.pausedTasks:e.previousTask?[e.previousTask]:[]}async getStalePausedTasks(e){return WT(this.lifecycleBackend(),e)}async archiveStalePausedTasks(e){return GT(this.lifecycleBackend(),e)}queryBackend(){return{read:this.read.bind(this),update:this.update.bind(this),getPausedTasksFromState:this.getPausedTasksFromState.bind(this)}}async clearTask(e){return qT(this.queryBackend(),e)}async hasTask(e){return XT(this.queryBackend(),e)}async getPausedTask(e){return VT(this.queryBackend(),e)}async getAllPausedTasks(e){return KT(this.queryBackend(),e)}async getTaskHistory(e){return Lm(this.queryBackend(),e)}async getMostRecentTask(e){return JT(this.queryBackend(),e)}async getTaskHistoryByType(e,t){return zT(this.queryBackend(),e,t)}async getAggregatedFeedback(e){return YT(this.queryBackend(),e)}workspaceBackend(){return{read:this.read.bind(this),update:this.update.bind(this),publish:this.publishEvent.bind(this),createTaskHistoryEntry:this.createTaskHistoryEntry.bind(this),persistHistoryEntry:this.mirrorHistoryEntry.bind(this)}}async startTaskInWorkspace(e,t,r){let s=await this.read(e);this.validateTransition(s,"task",r);let o=await fv(this.workspaceBackend(),e,t,r);return this.mirrorTaskRow(e,o,"in_progress"),o}async getCurrentTaskForWorkspace(e,t){return gv(this.workspaceBackend(),e,t)}async completeTaskInWorkspace(e,t,r){let s=await hv(this.workspaceBackend(),e,t,r);return s&&this.mirrorTaskRow(e,s,"completed",{completedAt:A()}),s}async getActiveTasks(e){return yv(this.workspaceBackend(),e)}async getActiveTaskCount(e){return wv(this.workspaceBackend(),e)}async updateWorkspaceTask(e,t,r){return kv(this.workspaceBackend(),e,t,r)}async addTokens(e,t,r,s){return Ev(this.workspaceBackend(),e,t,r,s)}subtaskBackend(){return{read:this.read.bind(this),update:this.update.bind(this),publish:this.publishEvent.bind(this)}}async createSubtasks(e,t){return tv(this.subtaskBackend(),e,t)}async completeSubtask(e,t){return nv(this.subtaskBackend(),e,t)}async getCurrentSubtask(e){return rv(this.subtaskBackend(),e)}async getNextSubtask(e){return sv(this.subtaskBackend(),e)}async getPreviousSubtask(e){return Fm(this.subtaskBackend(),e)}async getPreviousHandoff(e){return ov(this.subtaskBackend(),e)}async getSubtasks(e){return iv(this.subtaskBackend(),e)}async getSubtaskProgress(e){return av(this.subtaskBackend(),e)}async hasSubtasks(e){return cv(this.subtaskBackend(),e)}async areAllSubtasksComplete(e){return lv(this.subtaskBackend(),e)}async failSubtask(e,t){return uv(this.subtaskBackend(),e,t)}async skipSubtask(e,t){return dv(this.subtaskBackend(),e,t)}async blockSubtask(e,t){return pv(this.subtaskBackend(),e,t)}},X=new Um});var Tv,vv=h(()=>{"use strict";yr();st();Tv={async upsert(n,e){let t=e.id||"";if(!t)return;let r=e.status||"";if(r==="completed"||r==="shipped"){await X.update(n,s=>s.currentTask?.id===t?{...s,currentTask:null}:s);return}if(r==="active"||e.started_at||e.startedAt){await X.update(n,s=>({...s,currentTask:{id:t,description:e.description,startedAt:e.started_at||e.startedAt||new Date().toISOString(),sessionId:e.session_id||e.sessionId||""}}));return}(e.description||"").trim()&&await ut.upsertTask(n,{id:t,description:e.description,...e.priority?{priority:e.priority}:{},...e.type?{type:e.type}:{}})},async delete(n,e){}}});var bv,Cv=h(()=>{"use strict";U();bv={async upsert(n,e){let t=Number(e.id);!Number.isFinite(t)||t<=0||w.run(n,`INSERT OR REPLACE INTO workflow_rules
1390
1390
  (id, type, command, position, action, description, enabled, timeout_ms,
1391
1391
  created_at, sort_order, when_expr, parallel, trust_source)
@@ -2530,7 +2530,7 @@ ${js.dim("Providers:")}`}var OX,Sk=h(()=>{"use strict";OX={ready:js.green("\u271
2530
2530
  ${s.dim("Run 'prjct start' to configure global/runtime adapters")}
2531
2531
  ${s.dim("Run 'prjct init' or 'prjct sync' to refresh AGENTS.md and project-level rules")}
2532
2532
  ${s.cyan("https://prjct.app")}
2533
- `)}else return!1;return!0}var tj=h(()=>{"use strict";a($X,"runBinCommand")});var nj=Sj((Uwe,MX)=>{MX.exports={name:"prjct-cli",version:"3.24.2",description:"Project memory and workflow context for AI coding agents.",main:"dist/bin/prjct.mjs",bin:{prjct:"bin/prjct.cjs"},publishConfig:{access:"public",registry:"https://registry.npmjs.org"},scripts:{build:"node scripts/build.js","build:node":"node scripts/build.js",release:"node scripts/release.js","release:patch":"node scripts/release.js patch","release:minor":"node scripts/release.js minor","release:major":"node scripts/release.js major",prepare:"lefthook install","update-commands":`bun -e "const installer = require('./core/infrastructure/command-installer'); installer.syncCommands().then(r => console.log('Commands updated:', r)).catch(e => console.error('Error:', e.message))"`,"install-global":"./scripts/install.sh",update:"./scripts/update.sh",test:"bun test","test:watch":"bun test --watch","test:coverage":"bun test --coverage",typecheck:"tsc --noEmit -p core/tsconfig.json","typecheck:watch":"tsc --noEmit -p core/tsconfig.json --watch",validate:"bun scripts/validate-commands.js",lint:"biome lint .","lint:fix":"biome lint --write .",knip:"knip","lint:meta":"bun core/cli/lint-meta-commentary.ts",format:"biome format --write .","format:check":"biome format .",check:"biome check .","check:fix":"biome check --write .","test:e2e":"bun test core/__tests__/e2e/","bench:ab":"bun scripts/bench-ab.ts"},keywords:["claude-code","gemini-cli","ai-agents","context-layer","developer-tools","ai-assistant","productivity","mcp","llm","coding-agents"],author:"prjct.app",license:"MIT",dependencies:{"@clack/prompts":"1.0.0","@modelcontextprotocol/sdk":"1.29.0",chalk:"4.1.2",chokidar:"5.0.0","jsonc-parser":"3.3.1",zod:"3.25.76"},overrides:{"path-to-regexp":"8.4.0","brace-expansion":"5.0.5","fast-uri":">=3.1.2",hono:"4.12.27","ip-address":">=10.1.1",qs:"6.15.2"},devDependencies:{"@biomejs/biome":"2.3.13","@types/bun":"latest","@types/chokidar":"2.1.7","@types/node":"^22",esbuild:"0.28.1",knip:"6.3.1",lefthook:"2.1.0",typescript:"5.9.3"},repository:{type:"git",url:"git+https://github.com/jlopezlira/prjct-cli.git"},bugs:{url:"https://github.com/jlopezlira/prjct-cli/issues"},homepage:"https://cli.prjct.app",packageManager:"bun@1.2.23",engines:{bun:">=1.0.0",node:">=22.5.0"},files:["assets/","bin/prjct","bin/prjct.cjs","dist/","templates/","scripts/install.sh","LICENSE","README.md","CHANGELOG.md"],prepublishOnly:"node scripts/build.js"}});var GX={};import rj from"node:os";import jd from"node:path";import Ds from"chalk";async function LX(){let[n,...e]=process.argv.slice(2);if(["-v","--version","version"].includes(n)){let r=await Promise.resolve().then(()=>Tj(nj()));await HX(r.version),process.exit(0)}if(["-h","--help",void 0].includes(n)&&(WX(),process.exit(0)),n&&ba(n)&&!Ve.getByName(n)){let r=va[n];r&&(g.failWithHint({message:`'prjct ${n}' was removed in v2. ${r.note}`,hint:`Use: ${r.replacement}`}),process.exit(1))}if(n&&!Ve.getByName(n)&&!(e.length===0&&Fa(n)!==null)){let s=[n,...e.filter(i=>!i.startsWith("-"))].join(" "),o=e.filter(i=>i.startsWith("-"));n="capture",e=[s,...o]}let t=e.includes("--md");t||g.start();try{let r=Ve.getByName(n);if(!r){let m=Fa(n),f=m?`Did you mean 'prjct ${m}'? Run 'prjct --help' for all commands`:"Run 'prjct --help' to see available commands";g.failWithHint(di("UNKNOWN_COMMAND",{message:`Unknown command: ${n}`,hint:f})),t||g.end(),process.exit(1)}if(r.deprecated){let m=r.replacedBy?`Use 'prjct ${r.replacedBy}' instead`:"Run 'prjct --help' to see available commands";g.failWithHint({message:`Command '${n}' is deprecated`,hint:m}),t||g.end(),process.exit(1)}r.implemented||(g.failWithHint({message:`Command '${n}' is not yet implemented`,hint:"Run 'prjct --help' to see available commands",docs:"https://github.com/jlopezlira/prjct-cli"}),t||g.end(),process.exit(1));let{parsedArgs:s,options:o}=UX(r,e),i=!process.stdin.isTTY||o.md===!0||o.json===!0;r.requiresLlm&&!i&&(g.failWithHint({message:`'prjct ${n}' requires an AI agent to process its output`,hint:`Use 'p. ${n}' inside Claude/Cursor, or add --md flag`}),t||g.end(),process.exit(1));let c=FX(r,s);c&&(g.failWithHint(c),t||g.end(),process.exit(1));let l=null,u=Date.now();try{l=await _.getProjectId(process.cwd()),l&&(await Ts.expireIfStale(l),await Ts.touch(l))}catch{}let d=new _s,p;if(n==="analyze")p=await d.analyze(o);else if(n==="setup")p=await d.setup(o);else if(n==="update"||n==="upgrade")p=await d.update(o);else{let m=s.join(" ")||null,f=o.md===!0,k=Ve.getByName(n);if(k?.optionSchema)p=await Ve.executeWithOptions(n,m,process.cwd(),_d(o,k.optionSchema));else{let T={spec:a(b=>Ua(d,(b??"").trim().split(/\s+/).filter(Boolean),o,process.cwd()),"spec"),intent:a(b=>Ua(d,(b??"").trim().split(/\s+/).filter(Boolean),o,process.cwd()),"intent"),"audit-spec":a(b=>b?d.specAudit(b,process.cwd(),{md:f,lenses:o.lenses?String(o.lenses):void 0}):Promise.resolve({success:!1,error:"audit-spec requires a spec id"}),"audit-spec"),init:a(b=>d.init({idea:b,yes:o.yes===!0,pack:o.pack?String(o.pack):void 0,persona:o.persona?String(o.persona):void 0}),"init"),sync:a(()=>d.sync(process.cwd(),{preview:o.preview===!0||o["dry-run"]===!0,yes:o.yes===!0,json:o.json===!0,md:f,package:o.package?String(o.package):void 0,full:o.full===!0}),"sync"),"analysis-save-llm":a(b=>b?d.saveLlmAnalysis(b,process.cwd(),{md:f}):Promise.resolve({success:!1,error:"analysis-save-llm requires analysis text, JSON, or a file path"}),"analysis-save-llm"),start:a(()=>d.start(),"start"),login:a(()=>d.login({md:f}),"login"),logout:a(()=>d.logout(),"logout"),auth:a(b=>d.auth(b,{md:f}),"auth")}[n];if(T)p=await T(m);else throw new Error(`Command '${n}' has no handler`)}}if(l){let m=Date.now()-u;try{await Ts.trackCommand(l,n,m)}catch{}try{await Ca.recordTiming(l,"command_duration",m,{command:n});let f=globalThis.__perfStartNs;if(f){let k=Number(process.hrtime.bigint()-f)/1e6;await Ca.recordTiming(l,"startup_time",k)}await Ca.recordMemory(l,{command:n})}catch{}}p?.message?console.log(p.message):p?.error&&console.error(p.error),t||g.end(),process.exit(p?.success?0:1)}catch(r){console.error("Error:",y(r)),process.env.DEBUG&&console.error(qd(r)),t||g.end(),process.exit(1)}}function FX(n,e){if(!n.params)return null;let r=n.params.replace(/\[[^\]]*\]/g,"").match(/<[^>]+>/g);if(!r||r.length===0)return null;if(e.length<r.length){let s=r.map(i=>i.slice(1,-1)).join(", "),o=n.usage.terminal||`prjct ${n.name} ${n.params}`;return di("MISSING_PARAM",{message:`Missing required parameter: ${s}`,hint:`Usage: ${o}`})}return null}function UX(n,e){let t=[],r={};for(let s=0;s<e.length;s++){let o=e[s];if(o.startsWith("--")){let i=o.slice(2);s+1<e.length&&!e[s+1].startsWith("--")?r[i]=e[++s]:r[i]=!0}else t.push(o)}return{parsedArgs:t,options:r}}async function HX(n){let e=await Xr(),t=jd.join(rj.homedir(),".claude","commands","p.md"),r=jd.join(rj.homedir(),".gemini","commands","p.toml"),[s,o,i,c]=await Promise.all([v(t),v(r),v(jd.join(process.cwd(),".cursor","commands","sync.md")),v(jd.join(process.cwd(),".cursor"))]),l=await mi();console.log(Ek(n)),console.log(Ko("Claude Code",e.claude.installed?s?"ready":"installed":"missing",e.claude.version?Ds.dim(` (v${e.claude.version})`):"")),console.log(Ko("Gemini CLI",e.gemini.installed?o?"ready":"installed":"missing",e.gemini.version?Ds.dim(` (v${e.gemini.version})`):"")),console.log(Ko("Antigravity",l.installed?l.skillInstalled?"ready":"detected":"missing",l.installed&&!l.skillInstalled?` ${Ds.dim("(run prjct start)")}`:"")),console.log(Ko("Cursor IDE",i?"ready":c?"detected":"missing",i?` ${Ds.dim("(use prjct router)")}`:c?` ${Ds.dim("(run prjct init)")}`:"","\u25CB no .cursor/ folder")),console.log(`
2533
+ `)}else return!1;return!0}var tj=h(()=>{"use strict";a($X,"runBinCommand")});var nj=Sj((Uwe,MX)=>{MX.exports={name:"prjct-cli",version:"3.24.3",description:"Project memory and workflow context for AI coding agents.",main:"dist/bin/prjct.mjs",bin:{prjct:"bin/prjct.cjs"},publishConfig:{access:"public",registry:"https://registry.npmjs.org"},scripts:{build:"node scripts/build.js","build:node":"node scripts/build.js",release:"node scripts/release.js","release:patch":"node scripts/release.js patch","release:minor":"node scripts/release.js minor","release:major":"node scripts/release.js major",prepare:"lefthook install","update-commands":`bun -e "const installer = require('./core/infrastructure/command-installer'); installer.syncCommands().then(r => console.log('Commands updated:', r)).catch(e => console.error('Error:', e.message))"`,"install-global":"./scripts/install.sh",update:"./scripts/update.sh",test:"bun test","test:watch":"bun test --watch","test:coverage":"bun test --coverage",typecheck:"tsc --noEmit -p core/tsconfig.json","typecheck:watch":"tsc --noEmit -p core/tsconfig.json --watch",validate:"bun scripts/validate-commands.js",lint:"biome lint .","lint:fix":"biome lint --write .",knip:"knip","lint:meta":"bun core/cli/lint-meta-commentary.ts",format:"biome format --write .","format:check":"biome format .",check:"biome check .","check:fix":"biome check --write .","test:e2e":"bun test core/__tests__/e2e/","bench:ab":"bun scripts/bench-ab.ts"},keywords:["claude-code","gemini-cli","ai-agents","context-layer","developer-tools","ai-assistant","productivity","mcp","llm","coding-agents"],author:"prjct.app",license:"MIT",dependencies:{"@clack/prompts":"1.0.0","@modelcontextprotocol/sdk":"1.29.0",chalk:"4.1.2",chokidar:"5.0.0","jsonc-parser":"3.3.1",zod:"3.25.76"},overrides:{"path-to-regexp":"8.4.0","brace-expansion":"5.0.5","fast-uri":">=3.1.2",hono:"4.12.27","ip-address":">=10.1.1",qs:"6.15.2"},devDependencies:{"@biomejs/biome":"2.3.13","@types/bun":"latest","@types/chokidar":"2.1.7","@types/node":"^22",esbuild:"0.28.1",knip:"6.3.1",lefthook:"2.1.0",typescript:"5.9.3"},repository:{type:"git",url:"git+https://github.com/jlopezlira/prjct-cli.git"},bugs:{url:"https://github.com/jlopezlira/prjct-cli/issues"},homepage:"https://cli.prjct.app",packageManager:"bun@1.2.23",engines:{bun:">=1.0.0",node:">=22.5.0"},files:["assets/","bin/prjct","bin/prjct.cjs","dist/","templates/","scripts/install.sh","LICENSE","README.md","CHANGELOG.md"],prepublishOnly:"node scripts/build.js"}});var GX={};import rj from"node:os";import jd from"node:path";import Ds from"chalk";async function LX(){let[n,...e]=process.argv.slice(2);if(["-v","--version","version"].includes(n)){let r=await Promise.resolve().then(()=>Tj(nj()));await HX(r.version),process.exit(0)}if(["-h","--help",void 0].includes(n)&&(WX(),process.exit(0)),n&&ba(n)&&!Ve.getByName(n)){let r=va[n];r&&(g.failWithHint({message:`'prjct ${n}' was removed in v2. ${r.note}`,hint:`Use: ${r.replacement}`}),process.exit(1))}if(n&&!Ve.getByName(n)&&!(e.length===0&&Fa(n)!==null)){let s=[n,...e.filter(i=>!i.startsWith("-"))].join(" "),o=e.filter(i=>i.startsWith("-"));n="capture",e=[s,...o]}let t=e.includes("--md");t||g.start();try{let r=Ve.getByName(n);if(!r){let m=Fa(n),f=m?`Did you mean 'prjct ${m}'? Run 'prjct --help' for all commands`:"Run 'prjct --help' to see available commands";g.failWithHint(di("UNKNOWN_COMMAND",{message:`Unknown command: ${n}`,hint:f})),t||g.end(),process.exit(1)}if(r.deprecated){let m=r.replacedBy?`Use 'prjct ${r.replacedBy}' instead`:"Run 'prjct --help' to see available commands";g.failWithHint({message:`Command '${n}' is deprecated`,hint:m}),t||g.end(),process.exit(1)}r.implemented||(g.failWithHint({message:`Command '${n}' is not yet implemented`,hint:"Run 'prjct --help' to see available commands",docs:"https://github.com/jlopezlira/prjct-cli"}),t||g.end(),process.exit(1));let{parsedArgs:s,options:o}=UX(r,e),i=!process.stdin.isTTY||o.md===!0||o.json===!0;r.requiresLlm&&!i&&(g.failWithHint({message:`'prjct ${n}' requires an AI agent to process its output`,hint:`Use 'p. ${n}' inside Claude/Cursor, or add --md flag`}),t||g.end(),process.exit(1));let c=FX(r,s);c&&(g.failWithHint(c),t||g.end(),process.exit(1));let l=null,u=Date.now();try{l=await _.getProjectId(process.cwd()),l&&(await Ts.expireIfStale(l),await Ts.touch(l))}catch{}let d=new _s,p;if(n==="analyze")p=await d.analyze(o);else if(n==="setup")p=await d.setup(o);else if(n==="update"||n==="upgrade")p=await d.update(o);else{let m=s.join(" ")||null,f=o.md===!0,k=Ve.getByName(n);if(k?.optionSchema)p=await Ve.executeWithOptions(n,m,process.cwd(),_d(o,k.optionSchema));else{let T={spec:a(b=>Ua(d,(b??"").trim().split(/\s+/).filter(Boolean),o,process.cwd()),"spec"),intent:a(b=>Ua(d,(b??"").trim().split(/\s+/).filter(Boolean),o,process.cwd()),"intent"),"audit-spec":a(b=>b?d.specAudit(b,process.cwd(),{md:f,lenses:o.lenses?String(o.lenses):void 0}):Promise.resolve({success:!1,error:"audit-spec requires a spec id"}),"audit-spec"),init:a(b=>d.init({idea:b,yes:o.yes===!0,pack:o.pack?String(o.pack):void 0,persona:o.persona?String(o.persona):void 0}),"init"),sync:a(()=>d.sync(process.cwd(),{preview:o.preview===!0||o["dry-run"]===!0,yes:o.yes===!0,json:o.json===!0,md:f,package:o.package?String(o.package):void 0,full:o.full===!0}),"sync"),"analysis-save-llm":a(b=>b?d.saveLlmAnalysis(b,process.cwd(),{md:f}):Promise.resolve({success:!1,error:"analysis-save-llm requires analysis text, JSON, or a file path"}),"analysis-save-llm"),start:a(()=>d.start(),"start"),login:a(()=>d.login({md:f}),"login"),logout:a(()=>d.logout(),"logout"),auth:a(b=>d.auth(b,{md:f}),"auth")}[n];if(T)p=await T(m);else throw new Error(`Command '${n}' has no handler`)}}if(l){let m=Date.now()-u;try{await Ts.trackCommand(l,n,m)}catch{}try{await Ca.recordTiming(l,"command_duration",m,{command:n});let f=globalThis.__perfStartNs;if(f){let k=Number(process.hrtime.bigint()-f)/1e6;await Ca.recordTiming(l,"startup_time",k)}await Ca.recordMemory(l,{command:n})}catch{}}p?.message?console.log(p.message):p?.error&&console.error(p.error),t||g.end(),process.exit(p?.success?0:1)}catch(r){console.error("Error:",y(r)),process.env.DEBUG&&console.error(qd(r)),t||g.end(),process.exit(1)}}function FX(n,e){if(!n.params)return null;let r=n.params.replace(/\[[^\]]*\]/g,"").match(/<[^>]+>/g);if(!r||r.length===0)return null;if(e.length<r.length){let s=r.map(i=>i.slice(1,-1)).join(", "),o=n.usage.terminal||`prjct ${n.name} ${n.params}`;return di("MISSING_PARAM",{message:`Missing required parameter: ${s}`,hint:`Usage: ${o}`})}return null}function UX(n,e){let t=[],r={};for(let s=0;s<e.length;s++){let o=e[s];if(o.startsWith("--")){let i=o.slice(2);s+1<e.length&&!e[s+1].startsWith("--")?r[i]=e[++s]:r[i]=!0}else t.push(o)}return{parsedArgs:t,options:r}}async function HX(n){let e=await Xr(),t=jd.join(rj.homedir(),".claude","commands","p.md"),r=jd.join(rj.homedir(),".gemini","commands","p.toml"),[s,o,i,c]=await Promise.all([v(t),v(r),v(jd.join(process.cwd(),".cursor","commands","sync.md")),v(jd.join(process.cwd(),".cursor"))]),l=await mi();console.log(Ek(n)),console.log(Ko("Claude Code",e.claude.installed?s?"ready":"installed":"missing",e.claude.version?Ds.dim(` (v${e.claude.version})`):"")),console.log(Ko("Gemini CLI",e.gemini.installed?o?"ready":"installed":"missing",e.gemini.version?Ds.dim(` (v${e.gemini.version})`):"")),console.log(Ko("Antigravity",l.installed?l.skillInstalled?"ready":"detected":"missing",l.installed&&!l.skillInstalled?` ${Ds.dim("(run prjct start)")}`:"")),console.log(Ko("Cursor IDE",i?"ready":c?"detected":"missing",i?` ${Ds.dim("(use prjct router)")}`:c?` ${Ds.dim("(run prjct init)")}`:"","\u25CB no .cursor/ folder")),console.log(`
2534
2534
  ${Ds.dim("Run 'prjct start' for Claude/Gemini, 'prjct init' for Cursor")}
2535
2535
  ${Ds.cyan("https://prjct.app")}
2536
2536
  `)}function WX(){console.log(`
@@ -1166,7 +1166,7 @@ CREATE TABLE velocity_sprints (
1166
1166
  name TEXT NOT NULL,
1167
1167
  applied_at TEXT NOT NULL
1168
1168
  )
1169
- `);let r=new Set(e.prepare("SELECT version FROM _migrations").all().map(i=>i.version)),s=ai.filter(i=>!r.has(i.version));if(s.length!==0){if(t&&r.size>0)try{let i=`${t}.pre-migrate.bak`;Yr.existsSync(i)&&Yr.rmSync(i,{force:!0}),e.prepare("VACUUM INTO ?").run(i)}catch(i){console.warn(`prjct: pre-migration backup failed (continuing): ${i?.message??i}`)}for(let i of s)$a(e,()=>{i.up(e),e.prepare("INSERT INTO _migrations (version, name, applied_at) VALUES (?, ?, ?)").run(i.version,i.name,new Date().toISOString())})}}getMigrations(e){return this.getDb(e).prepare("SELECT * FROM _migrations ORDER BY version").all()}getSchemaVersion(e){return this.getDb(e).prepare("SELECT MAX(version) as version FROM _migrations").get()?.version??0}},y=new ci,h=y});function Cp(n){let e=n.toLowerCase();return e.includes("github")?"github":e.includes("gitlab")?"gitlab":e.includes("bitbucket")?"bitbucket":"other"}function Ua(n){let e=n.trim();if(!e)return{};let t=e.match(/^[^/@]+@([^:/]+):(.+?)(?:\.git)?\/?$/);if(t)return{provider:Cp(t[1]),repoSlug:t[2]};try{let r=new URL(e),s=r.pathname.replace(/^\/+/,"").replace(/\.git$/,"").replace(/\/+$/,"");return!r.host||!s?{}:{provider:Cp(r.host),repoSlug:s}}catch{return{}}}async function BS(n){try{let{stdout:e}=await W("git",["remote","get-url","origin"],{cwd:n});return e.trim()||void 0}catch{return}}async function GS(n){try{let{stdout:e}=await W("git",["symbolic-ref","--short","refs/remotes/origin/HEAD"],{cwd:n});return e.trim().replace(/^origin\//,"")||void 0}catch{return}}function Tn(n){return typeof n=="string"&&n.length>0?n:void 0}function Ap(n){return typeof n=="number"&&Number.isFinite(n)?n:void 0}function XS(n){return Object.fromEntries(Object.entries(n).filter(([,e])=>e!==void 0))}async function xp(n){let e=y.getDoc(n,"project")||{},t=Tn(e.repoPath),{provider:r,repoSlug:s}=t?Ua(await BS(t)||""):{},i=t?await GS(t):void 0,o=Array.isArray(e.techStack)?e.techStack.filter(c=>typeof c=="string"):void 0;return XS({provider:r,repoSlug:s,currentBranch:Tn(e.currentBranch),defaultBranch:i,stack:Tn(e.stack),techStack:o&&o.length>0?o:void 0,version:Tn(e.version),commitCount:Ap(e.commitCount),fileCount:Ap(e.fileCount),lastCommit:Tn(e.lastSyncCommit),hasUncommitted:typeof e.hasUncommittedChanges=="boolean"?e.hasUncommittedChanges:void 0,cliVersion:Tn(e.cliVersion),syncedAt:Tn(e.lastSync)})}var Ha=g(()=>{"use strict";N();se();a(Cp,"providerForHost");a(Ua,"parseRemote");a(BS,"gitRemoteUrl");a(GS,"gitDefaultBranch");a(Tn,"str");a(Ap,"num");a(XS,"compact");a(xp,"buildProjectMeta")});import{execFile as qS}from"node:child_process";import VS from"node:crypto";import{promisify as KS}from"node:util";function zS(n,e=JS){let t=Buffer.from(e.replace(/-/g,""),"hex"),s=VS.createHash("sha1").update(t).update(n,"utf8").digest().subarray(0,16);s[6]=s[6]&15|80,s[8]=s[8]&63|128;let i=s.toString("hex");return`${i.slice(0,8)}-${i.slice(8,12)}-${i.slice(12,16)}-${i.slice(16,20)}-${i.slice(20,32)}`}async function QS(n){let e;try{let{stdout:s}=await YS("git",["remote","get-url","origin"],{cwd:n});e=s.trim()||void 0}catch{return null}if(!e)return null;let{provider:t,repoSlug:r}=Ua(e);return!t||!r?null:`${t}:${r}`.toLowerCase()}async function Np(n){let e=await QS(n);return e?zS(e):null}var YS,JS,Ip=g(()=>{"use strict";Ha();YS=KS(qS),JS="6f9b2c1a-3d4e-5f60-8a7b-1c2d3e4f5a6b";a(zS,"uuidv5");a(QS,"repoKey");a(Np,"deriveProjectId")});var Ga={};M(Ga,{PACKAGE_ROOT:()=>Pt,VERSION:()=>Ae,getPackageRoot:()=>Ba,getVersion:()=>ui,resetPackageRoot:()=>ZS});import Wa from"node:fs";import li from"node:path";function Ba(){if(nr)return nr;let n=__dirname;for(let e=0;e<5;e++){let t=li.join(n,"package.json");if(Wa.existsSync(t))try{if(JSON.parse(Wa.readFileSync(t,"utf-8")).name==="prjct-cli")return nr=n,n}catch{}n=li.dirname(n)}return nr=li.join(__dirname,"..","..",".."),nr}function ui(){if(kn)return kn;let n="3.24.2";if(n&&/^\d+\.\d+\.\d+/.test(n))return kn=n,kn;try{let e=li.join(Ba(),"package.json");return kn=JSON.parse(Wa.readFileSync(e,"utf-8")).version,kn}catch(e){return process.env.PRJCT_DEBUG==="1"&&console.error("Failed to read version from package.json:",S(e)),"0.0.0"}}function ZS(n){nr=n,kn=null}var kn,nr,Ae,Pt,it=g(()=>{"use strict";Y();kn=null,nr=null;a(Ba,"getPackageRoot");a(ui,"getVersion");a(ZS,"resetPackageRoot");Ae=ui(),Pt=Ba()});async function di(n){try{let{stdout:e}=await I(n,{timeout:5e3});return{success:!0,output:e.trim()}}catch{return{success:!1,output:""}}}async function ev(){let n=await di("gh api user --jq .login");return n.success&&n.output||(n=await di("git config --global github.user"),n.success&&n.output)?n.output:null}async function tv(){let n=await di("git config user.name");return n.success&&n.output?n.output:null}async function nv(){let n=await di("git config user.email");return n.success&&n.output?n.output:null}async function rr(){let[n,e,t]=await Promise.all([ev(),tv(),nv()]);return{github:n,email:t,name:e||n||"Unknown"}}var pi=g(()=>{"use strict";se();a(di,"execCommand");a(ev,"detectGitHubUsername");a(tv,"detectGitName");a(nv,"detectGitEmail");a(rr,"detect")});var Ka={};M(Ka,{worktreeService:()=>rv});import qa from"node:fs/promises";import yt from"node:path";var Pp,Va,rv,Ya=g(()=>{"use strict";se();X();Pp=".worktrees",Va=class{static{a(this,"WorktreeService")}async create(e,t,r={}){let s=await this.getMainWorktree(e),i=yt.join(s,Pp,t),o=r.branch||`feat/${t}`;await qa.mkdir(yt.join(s,Pp),{recursive:!0});let c=r.baseBranch?` ${r.baseBranch}`:"";await I(`git worktree add "${i}" -b "${o}"${c}`,{cwd:s});let{stdout:l}=await I("git rev-parse HEAD",{cwd:i});return{path:i,branch:o,commit:l.trim(),isMain:!1,slug:t}}async remove(e,t=!1){let r=await this.getMainWorktree(e),s;if(t)try{let{stdout:i}=await I("git rev-parse --abbrev-ref HEAD",{cwd:e});s=i.trim()}catch{}if(await I(`git worktree remove "${e}" --force`,{cwd:r}),t&&s&&s!=="main"&&s!=="master")try{await I(`git branch -D "${s}"`,{cwd:r})}catch{}}async list(e){let t=await this.getMainWorktree(e),{stdout:r}=await I("git worktree list --porcelain",{cwd:t});return this.parsePorcelainOutput(r,t)}async detect(e){try{let{stdout:t}=await I("git rev-parse --git-common-dir",{cwd:e}),{stdout:r}=await I("git rev-parse --git-dir",{cwd:e}),s=yt.resolve(e,t.trim()),i=yt.resolve(e,r.trim());if(s!==i){let{stdout:o}=await I("git rev-parse --abbrev-ref HEAD",{cwd:e}),{stdout:c}=await I("git rev-parse HEAD",{cwd:e}),{stdout:l}=await I("git rev-parse --show-toplevel",{cwd:e}),u=l.trim(),d=yt.basename(u);return{path:u,branch:o.trim(),commit:c.trim(),isMain:!1,slug:d}}return null}catch{return null}}async getMainWorktree(e){try{let{stdout:r}=await I("git worktree list --porcelain",{cwd:e}),s=r.split(`
1169
+ `);let r=new Set(e.prepare("SELECT version FROM _migrations").all().map(i=>i.version)),s=ai.filter(i=>!r.has(i.version));if(s.length!==0){if(t&&r.size>0)try{let i=`${t}.pre-migrate.bak`;Yr.existsSync(i)&&Yr.rmSync(i,{force:!0}),e.prepare("VACUUM INTO ?").run(i)}catch(i){console.warn(`prjct: pre-migration backup failed (continuing): ${i?.message??i}`)}for(let i of s)$a(e,()=>{i.up(e),e.prepare("INSERT INTO _migrations (version, name, applied_at) VALUES (?, ?, ?)").run(i.version,i.name,new Date().toISOString())})}}getMigrations(e){return this.getDb(e).prepare("SELECT * FROM _migrations ORDER BY version").all()}getSchemaVersion(e){return this.getDb(e).prepare("SELECT MAX(version) as version FROM _migrations").get()?.version??0}},y=new ci,h=y});function Cp(n){let e=n.toLowerCase();return e.includes("github")?"github":e.includes("gitlab")?"gitlab":e.includes("bitbucket")?"bitbucket":"other"}function Ua(n){let e=n.trim();if(!e)return{};let t=e.match(/^[^/@]+@([^:/]+):(.+?)(?:\.git)?\/?$/);if(t)return{provider:Cp(t[1]),repoSlug:t[2]};try{let r=new URL(e),s=r.pathname.replace(/^\/+/,"").replace(/\.git$/,"").replace(/\/+$/,"");return!r.host||!s?{}:{provider:Cp(r.host),repoSlug:s}}catch{return{}}}async function BS(n){try{let{stdout:e}=await W("git",["remote","get-url","origin"],{cwd:n});return e.trim()||void 0}catch{return}}async function GS(n){try{let{stdout:e}=await W("git",["symbolic-ref","--short","refs/remotes/origin/HEAD"],{cwd:n});return e.trim().replace(/^origin\//,"")||void 0}catch{return}}function Tn(n){return typeof n=="string"&&n.length>0?n:void 0}function Ap(n){return typeof n=="number"&&Number.isFinite(n)?n:void 0}function XS(n){return Object.fromEntries(Object.entries(n).filter(([,e])=>e!==void 0))}async function xp(n){let e=y.getDoc(n,"project")||{},t=Tn(e.repoPath),{provider:r,repoSlug:s}=t?Ua(await BS(t)||""):{},i=t?await GS(t):void 0,o=Array.isArray(e.techStack)?e.techStack.filter(c=>typeof c=="string"):void 0;return XS({provider:r,repoSlug:s,currentBranch:Tn(e.currentBranch),defaultBranch:i,stack:Tn(e.stack),techStack:o&&o.length>0?o:void 0,version:Tn(e.version),commitCount:Ap(e.commitCount),fileCount:Ap(e.fileCount),lastCommit:Tn(e.lastSyncCommit),hasUncommitted:typeof e.hasUncommittedChanges=="boolean"?e.hasUncommittedChanges:void 0,cliVersion:Tn(e.cliVersion),syncedAt:Tn(e.lastSync)})}var Ha=g(()=>{"use strict";N();se();a(Cp,"providerForHost");a(Ua,"parseRemote");a(BS,"gitRemoteUrl");a(GS,"gitDefaultBranch");a(Tn,"str");a(Ap,"num");a(XS,"compact");a(xp,"buildProjectMeta")});import{execFile as qS}from"node:child_process";import VS from"node:crypto";import{promisify as KS}from"node:util";function zS(n,e=JS){let t=Buffer.from(e.replace(/-/g,""),"hex"),s=VS.createHash("sha1").update(t).update(n,"utf8").digest().subarray(0,16);s[6]=s[6]&15|80,s[8]=s[8]&63|128;let i=s.toString("hex");return`${i.slice(0,8)}-${i.slice(8,12)}-${i.slice(12,16)}-${i.slice(16,20)}-${i.slice(20,32)}`}async function QS(n){let e;try{let{stdout:s}=await YS("git",["remote","get-url","origin"],{cwd:n});e=s.trim()||void 0}catch{return null}if(!e)return null;let{provider:t,repoSlug:r}=Ua(e);return!t||!r?null:`${t}:${r}`.toLowerCase()}async function Np(n){let e=await QS(n);return e?zS(e):null}var YS,JS,Ip=g(()=>{"use strict";Ha();YS=KS(qS),JS="6f9b2c1a-3d4e-5f60-8a7b-1c2d3e4f5a6b";a(zS,"uuidv5");a(QS,"repoKey");a(Np,"deriveProjectId")});var Ga={};M(Ga,{PACKAGE_ROOT:()=>Pt,VERSION:()=>Ae,getPackageRoot:()=>Ba,getVersion:()=>ui,resetPackageRoot:()=>ZS});import Wa from"node:fs";import li from"node:path";function Ba(){if(nr)return nr;let n=__dirname;for(let e=0;e<5;e++){let t=li.join(n,"package.json");if(Wa.existsSync(t))try{if(JSON.parse(Wa.readFileSync(t,"utf-8")).name==="prjct-cli")return nr=n,n}catch{}n=li.dirname(n)}return nr=li.join(__dirname,"..","..",".."),nr}function ui(){if(kn)return kn;let n="3.24.3";if(n&&/^\d+\.\d+\.\d+/.test(n))return kn=n,kn;try{let e=li.join(Ba(),"package.json");return kn=JSON.parse(Wa.readFileSync(e,"utf-8")).version,kn}catch(e){return process.env.PRJCT_DEBUG==="1"&&console.error("Failed to read version from package.json:",S(e)),"0.0.0"}}function ZS(n){nr=n,kn=null}var kn,nr,Ae,Pt,it=g(()=>{"use strict";Y();kn=null,nr=null;a(Ba,"getPackageRoot");a(ui,"getVersion");a(ZS,"resetPackageRoot");Ae=ui(),Pt=Ba()});async function di(n){try{let{stdout:e}=await I(n,{timeout:5e3});return{success:!0,output:e.trim()}}catch{return{success:!1,output:""}}}async function ev(){let n=await di("gh api user --jq .login");return n.success&&n.output||(n=await di("git config --global github.user"),n.success&&n.output)?n.output:null}async function tv(){let n=await di("git config user.name");return n.success&&n.output?n.output:null}async function nv(){let n=await di("git config user.email");return n.success&&n.output?n.output:null}async function rr(){let[n,e,t]=await Promise.all([ev(),tv(),nv()]);return{github:n,email:t,name:e||n||"Unknown"}}var pi=g(()=>{"use strict";se();a(di,"execCommand");a(ev,"detectGitHubUsername");a(tv,"detectGitName");a(nv,"detectGitEmail");a(rr,"detect")});var Ka={};M(Ka,{worktreeService:()=>rv});import qa from"node:fs/promises";import yt from"node:path";var Pp,Va,rv,Ya=g(()=>{"use strict";se();X();Pp=".worktrees",Va=class{static{a(this,"WorktreeService")}async create(e,t,r={}){let s=await this.getMainWorktree(e),i=yt.join(s,Pp,t),o=r.branch||`feat/${t}`;await qa.mkdir(yt.join(s,Pp),{recursive:!0});let c=r.baseBranch?` ${r.baseBranch}`:"";await I(`git worktree add "${i}" -b "${o}"${c}`,{cwd:s});let{stdout:l}=await I("git rev-parse HEAD",{cwd:i});return{path:i,branch:o,commit:l.trim(),isMain:!1,slug:t}}async remove(e,t=!1){let r=await this.getMainWorktree(e),s;if(t)try{let{stdout:i}=await I("git rev-parse --abbrev-ref HEAD",{cwd:e});s=i.trim()}catch{}if(await I(`git worktree remove "${e}" --force`,{cwd:r}),t&&s&&s!=="main"&&s!=="master")try{await I(`git branch -D "${s}"`,{cwd:r})}catch{}}async list(e){let t=await this.getMainWorktree(e),{stdout:r}=await I("git worktree list --porcelain",{cwd:t});return this.parsePorcelainOutput(r,t)}async detect(e){try{let{stdout:t}=await I("git rev-parse --git-common-dir",{cwd:e}),{stdout:r}=await I("git rev-parse --git-dir",{cwd:e}),s=yt.resolve(e,t.trim()),i=yt.resolve(e,r.trim());if(s!==i){let{stdout:o}=await I("git rev-parse --abbrev-ref HEAD",{cwd:e}),{stdout:c}=await I("git rev-parse HEAD",{cwd:e}),{stdout:l}=await I("git rev-parse --show-toplevel",{cwd:e}),u=l.trim(),d=yt.basename(u);return{path:u,branch:o.trim(),commit:c.trim(),isMain:!1,slug:d}}return null}catch{return null}}async getMainWorktree(e){try{let{stdout:r}=await I("git worktree list --porcelain",{cwd:e}),s=r.split(`
1170
1170
  `)[0];if(s?.startsWith("worktree "))return s.replace("worktree ","").trim()}catch{}let{stdout:t}=await I("git rev-parse --show-toplevel",{cwd:e});return t.trim()}async setup(e,t){let r=yt.join(t,".env");await v(r)&&await qa.copyFile(r,yt.join(e,".env"));let s=yt.join(t,".prjct"),i=yt.join(e,".prjct");await v(s)&&!await v(i)&&await qa.symlink(s,i,"dir")}async teardown(e){}async clean(e){let t=await this.list(e),r=[],s=await this.getMainWorktree(e);await I("git worktree prune",{cwd:s});for(let i of t)i.isMain||await v(i.path)||r.push(i.slug);return r}parsePorcelainOutput(e,t){let r=[],s=e.trim().split(`
1171
1171
 
1172
1172
  `);for(let i of s){if(!i.trim())continue;let o=i.trim().split(`
@@ -1331,8 +1331,8 @@ ${c.join(`
1331
1331
  started_at = COALESCE(excluded.started_at, tasks.started_at),
1332
1332
  completed_at = excluded.completed_at,
1333
1333
  pr_url = COALESCE(excluded.pr_url, tasks.pr_url),
1334
- tokens_in = excluded.tokens_in,
1335
- tokens_out = excluded.tokens_out,
1334
+ tokens_in = CASE WHEN excluded.tokens_in > 0 THEN excluded.tokens_in ELSE tasks.tokens_in END,
1335
+ tokens_out = CASE WHEN excluded.tokens_out > 0 THEN excluded.tokens_out ELSE tasks.tokens_out END,
1336
1336
  data = excluded.data`,t.taskId,t.title,t.classification,t.branchName==="unknown"?null:t.branchName,t.linearId??null,t.prUrl??null,t.startedAt,t.completedAt,t.tokensIn??0,t.tokensOut??0,r)}catch{}}async updateCurrentTask(e,t){let r=null;return await this.update(e,s=>s.currentTask?(r={...s.currentTask,...t},{...s,currentTask:r,lastUpdated:k()}):s),r}async completeTask(e,t){let r=k(),s={};if(await this.update(e,o=>o.currentTask?(this.validateTransition(o,"done"),s.completedTask=o.currentTask,{...o,currentTask:null,previousTask:null,lastUpdated:r}):o),!s.completedTask)return null;let i=s.completedTask;return this.mirrorTaskRow(e,i,"completed",{completedAt:r}),this.mirrorHistoryEntry(e,this.createTaskHistoryEntry(i,r,t)),await this.publishEvent(e,"task.completed",{taskId:i.id,description:i.description,startedAt:i.startedAt,completedAt:r}),i}createTaskHistoryEntry(e,t,r){let s=(e.subtasks||[]).filter(c=>c.status==="completed"&&c.summary).map(c=>c.summary),i=s.length>0?s.map(c=>c.title).join(", "):"Task completed",o={taskId:e.id,title:e.parentDescription||e.description,classification:e.type||"improvement",startedAt:e.startedAt,completedAt:t,subtaskCount:e.subtasks?.length||0,subtaskSummaries:s,outcome:i,branchName:e.branch||"unknown",linearId:e.linearId,linearUuid:e.linearUuid,prUrl:e.prUrl,harness:e.harness};return r&&(o.feedback=r),e.tokensIn&&(o.tokensIn=e.tokensIn),e.tokensOut&&(o.tokensOut=e.tokensOut),o}maxPausedTasks=5;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(e,t){let r=await tg(this.lifecycleBackend(),e,t);return r&&this.mirrorTaskRow(e,r,"paused",{pausedAt:r.pausedAt,pauseReason:r.pauseReason}),r}async resumeTask(e,t){let r=await ng(this.lifecycleBackend(),e,t);return r&&this.mirrorTaskRow(e,r,"in_progress"),r}getPausedTasksFromState(e){return Array.isArray(e.pausedTasks)&&e.pausedTasks.length>0?e.pausedTasks:e.previousTask?[e.previousTask]:[]}async getStalePausedTasks(e){return rg(this.lifecycleBackend(),e)}async archiveStalePausedTasks(e){return sg(this.lifecycleBackend(),e)}queryBackend(){return{read:this.read.bind(this),update:this.update.bind(this),getPausedTasksFromState:this.getPausedTasksFromState.bind(this)}}async clearTask(e){return og(this.queryBackend(),e)}async hasTask(e){return ag(this.queryBackend(),e)}async getPausedTask(e){return cg(this.queryBackend(),e)}async getAllPausedTasks(e){return lg(this.queryBackend(),e)}async getTaskHistory(e){return Xc(this.queryBackend(),e)}async getMostRecentTask(e){return ug(this.queryBackend(),e)}async getTaskHistoryByType(e,t){return dg(this.queryBackend(),e,t)}async getAggregatedFeedback(e){return pg(this.queryBackend(),e)}workspaceBackend(){return{read:this.read.bind(this),update:this.update.bind(this),publish:this.publishEvent.bind(this),createTaskHistoryEntry:this.createTaskHistoryEntry.bind(this),persistHistoryEntry:this.mirrorHistoryEntry.bind(this)}}async startTaskInWorkspace(e,t,r){let s=await this.read(e);this.validateTransition(s,"task",r);let i=await xg(this.workspaceBackend(),e,t,r);return this.mirrorTaskRow(e,i,"in_progress"),i}async getCurrentTaskForWorkspace(e,t){return Ng(this.workspaceBackend(),e,t)}async completeTaskInWorkspace(e,t,r){let s=await Ig(this.workspaceBackend(),e,t,r);return s&&this.mirrorTaskRow(e,s,"completed",{completedAt:k()}),s}async getActiveTasks(e){return Pg(this.workspaceBackend(),e)}async getActiveTaskCount(e){return Dg(this.workspaceBackend(),e)}async updateWorkspaceTask(e,t,r){return Og(this.workspaceBackend(),e,t,r)}async addTokens(e,t,r,s){return Lg(this.workspaceBackend(),e,t,r,s)}subtaskBackend(){return{read:this.read.bind(this),update:this.update.bind(this),publish:this.publishEvent.bind(this)}}async createSubtasks(e,t){return hg(this.subtaskBackend(),e,t)}async completeSubtask(e,t){return yg(this.subtaskBackend(),e,t)}async getCurrentSubtask(e){return Eg(this.subtaskBackend(),e)}async getNextSubtask(e){return Tg(this.subtaskBackend(),e)}async getPreviousSubtask(e){return qc(this.subtaskBackend(),e)}async getPreviousHandoff(e){return kg(this.subtaskBackend(),e)}async getSubtasks(e){return wg(this.subtaskBackend(),e)}async getSubtaskProgress(e){return Sg(this.subtaskBackend(),e)}async hasSubtasks(e){return vg(this.subtaskBackend(),e)}async areAllSubtasksComplete(e){return bg(this.subtaskBackend(),e)}async failSubtask(e,t){return _g(this.subtaskBackend(),e,t)}async skipSubtask(e,t){return Rg(this.subtaskBackend(),e,t)}async blockSubtask(e,t){return Cg(this.subtaskBackend(),e,t)}},O=new Vc});var Mg,Fg=g(()=>{"use strict";Jt();Je();Mg={async upsert(n,e){let t=e.id||"";if(!t)return;let r=e.status||"";if(r==="completed"||r==="shipped"){await O.update(n,s=>s.currentTask?.id===t?{...s,currentTask:null}:s);return}if(r==="active"||e.started_at||e.startedAt){await O.update(n,s=>({...s,currentTask:{id:t,description:e.description,startedAt:e.started_at||e.startedAt||new Date().toISOString(),sessionId:e.session_id||e.sessionId||""}}));return}(e.description||"").trim()&&await xe.upsertTask(n,{id:t,description:e.description,...e.priority?{priority:e.priority}:{},...e.type?{type:e.type}:{}})},async delete(n,e){}}});var $g,Ug=g(()=>{"use strict";N();$g={async upsert(n,e){let t=Number(e.id);!Number.isFinite(t)||t<=0||h.run(n,`INSERT OR REPLACE INTO workflow_rules
1337
1337
  (id, type, command, position, action, description, enabled, timeout_ms,
1338
1338
  created_at, sort_order, when_expr, parallel, trust_source)