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.
@@ -1169,7 +1169,7 @@ CREATE TABLE velocity_sprints (
1169
1169
  `);let n=new Set(e.prepare("SELECT version FROM _migrations").all().map(i=>i.version)),s=Hs.filter(i=>!n.has(i.version));if(s.length!==0){if(t&&n.size>0)try{let i=`${t}.pre-migrate.bak`;jn.existsSync(i)&&jn.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)ta(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 Ws,h=y});import ra from"node:fs/promises";import ir from"node:path";function Md(r){let e=[],t,n=new RegExp(Yu.source,"g");for(;(t=n.exec(r))!==null;){let s=t[1];(s.startsWith(".")||s.startsWith("@/"))&&e.push(s)}return e}async function Fd(r,e,t){let n;if(r.startsWith("@/"))n=ir.join(t,"src",r.slice(2));else{let s=ir.dirname(ir.join(t,e));n=ir.resolve(s,r)}for(let s of Ku){let i=n+s;try{if((await ra.stat(i)).isFile())return ir.relative(t,i)}catch{}}return null}async function $k(r){let e=await Ot(r),t={},n={},s=0,i=await jt(e,50,async o=>{try{let c=await ra.readFile(ir.join(r,o),"utf-8"),l=Md(c),u=[];for(let d of l){let p=await Fd(d,o,r);p&&p!==o&&u.push(p)}return u.length>0?{filePath:o,imports:u}:null}catch{return null}});for(let{filePath:o,imports:c}of i){t[o]=c,s+=c.length;for(let l of c)n[l]||(n[l]=[]),n[l].push(o)}return{forward:t,reverse:n,fileCount:e.length,edgeCount:s,builtAt:new Date().toISOString()}}function Xs(r,e,t=2){let n=new Set(r),s=new Map,i=[];for(let o of r){let c=e.forward[o]||[],l=e.reverse[o]||[];for(let u of[...c,...l])n.has(u)||i.push({file:u,depth:1})}for(let o=0;o<i.length;o++){let{file:c,depth:l}=i[o];if(l>t)continue;let u=1/(l+1),d=s.get(c);if(d){u>d.score&&s.set(c,{score:u,depth:l});continue}if(s.set(c,{score:u,depth:l}),l<t){let p=e.forward[c]||[],m=e.reverse[c]||[];for(let g of[...p,...m])!n.has(g)&&!s.has(g)&&i.push({file:g,depth:l+1})}}return Array.from(s.entries()).map(([o,{score:c,depth:l}])=>({path:o,score:c,depth:l})).sort((o,c)=>c.score-o.score)}function Uk(r){return Object.values(r).reduce((e,t)=>e+t.length,0)}function Hk(r,e){let t=r.forward[e]||[];delete r.forward[e];for(let n of t){let s=(r.reverse[n]||[]).filter(i=>i!==e);s.length===0?delete r.reverse[n]:r.reverse[n]=s}}function Wk(r,e){let t=r.reverse[e]||[];delete r.reverse[e];let n=[];for(let s of t){let i=(r.forward[s]||[]).filter(o=>o!==e);i.length===0?delete r.forward[s]:r.forward[s]=i,n.push(s)}return n}function Bk(r,e,t){if(t.length===0)return;let n=Array.from(new Set(t));r.forward[e]=n;for(let s of n)r.reverse[s]||(r.reverse[s]=[]),r.reverse[s].includes(e)||r.reverse[s].push(e)}async function Gk(r,e){try{let t=await ra.readFile(ir.join(r,e),"utf-8"),n=Md(t),s=[];for(let i of n){let o=await Fd(i,e,r);o&&o!==e&&s.push(o)}return{filePath:e,imports:s}}catch{return null}}function $d(r){return{schemaVersion:2,fileCount:r.fileCount,edgeCount:r.edgeCount,builtAt:r.builtAt}}function Xk(r,e){try{h.transaction(r,t=>{t.prepare("DELETE FROM import_graph_edges").run();let n=t.prepare("INSERT INTO import_graph_edges (from_path, to_path, sort_order) VALUES (?, ?, ?)");for(let[s,i]of Object.entries(e.forward))for(let[o,c]of i.entries())n.run(s,c,o)})}catch{}}function qk(r,e,t,n){try{h.transaction(r,s=>{let i=s.prepare("DELETE FROM import_graph_edges WHERE from_path = ?"),o=s.prepare("INSERT INTO import_graph_edges (from_path, to_path, sort_order) VALUES (?, ?, ?)");for(let c of new Set([...t,...n]))i.run(c);for(let c of t){let l=e.forward[c]||[];for(let[u,d]of l.entries())o.run(c,d,u)}})}catch{}}function Vk(r,e,t){try{let n=h.query(r,"SELECT from_path, to_path FROM import_graph_edges ORDER BY from_path, sort_order, to_path");if(n.length===0){if(t?.edgeCount===0){let l={forward:{},reverse:{},fileCount:t.fileCount,edgeCount:0,builtAt:t.builtAt};return or.set(r,{graph:l,updatedAt:e}),l}return null}let s={},i={};for(let l of n)s[l.from_path]||(s[l.from_path]=[]),s[l.from_path].push(l.to_path),i[l.to_path]||(i[l.to_path]=[]),i[l.to_path].push(l.from_path);let o=new Set;for(let[l,u]of Object.entries(s)){o.add(l);for(let d of u)o.add(d)}let c={forward:s,reverse:i,fileCount:t?.fileCount??o.size,edgeCount:n.length,builtAt:t?.builtAt??e};return or.set(r,{graph:c,updatedAt:e}),c}catch{return null}}function Kk(r,e){h.setDoc(r,Gs,$d(e)),Xk(r,e),or.delete(r)}function Yk(r,e,t,n){h.setDoc(r,Gs,$d(e)),qk(r,e,t,n),or.delete(r)}function et(r){let e=h.get(r,"SELECT updated_at FROM kv_store WHERE key = ?",Gs);if(!e)return or.delete(r),null;let t=or.get(r);if(t&&t.updatedAt===e.updated_at)return t.graph;let n=h.getDoc(r,Gs),s=Vk(r,e.updated_at,n);if(s)return s;if(!n?.forward||!n?.reverse)return null;let i={forward:n.forward,reverse:n.reverse,fileCount:n.fileCount,edgeCount:n.edgeCount,builtAt:n.builtAt};return or.set(r,{graph:i,updatedAt:e.updated_at}),i}async function Ln(r,e){let t=await $k(r);return Kk(e,t),t}async function Ud(r,e,t,n=[]){let s=et(e);if(!s)return Ln(r,e);let i=new Set([...t,...n]);for(let l of i)Hk(s,l);let o=new Set;for(let l of n)for(let u of Wk(s,l))o.add(u);let c=await jt(t,50,l=>Gk(r,l));for(let l of c)Bk(s,l.filePath,l.imports);return s.edgeCount=Uk(s.forward),s.builtAt=new Date().toISOString(),Yk(e,s,[...t,...o],n),s}var Gs,or,Hr=f(()=>{"use strict";Fo();I();J();a(Md,"extractImportSources");a(Fd,"resolveImport");a($k,"buildGraph");a(Xs,"scoreFromSeeds");Gs="import-graph",or=new Map;a(Uk,"countEdges");a(Hk,"removeOutgoingEdges");a(Wk,"removeIncomingEdges");a(Bk,"addEdges");a(Gk,"importsForFile");a($d,"graphMetadata");a(Xk,"replacePerFileEdges");a(qk,"updatePerFileEdges");a(Vk,"loadGraphFromPerFileEdges");a(Kk,"saveGraph");a(Yk,"saveGraphUpdate");a(et,"loadGraph");a(Ln,"indexImports");a(Ud,"updateImportGraph")});function qs(r,e){let t=[...r.added,...r.modified],n=new Set(t),s=new Set,i=et(e);if(i)for(let l of t){let u=i.reverse[l];if(u)for(let d of u)n.has(d)||s.add(d)}let o=Array.from(s),c=[...t,...o];return{directlyChanged:t,affectedByImports:o,deleted:r.deleted,allAffected:c}}function Vs(r){let e=new Set;for(let t of r){let n=t.toLowerCase();(n.endsWith(".tsx")||n.endsWith(".jsx")||n.endsWith(".css")||n.endsWith(".scss")||n.endsWith(".vue")||n.endsWith(".svelte")||n.includes("/components/")||n.includes("/pages/")||n.includes("/app/"))&&(e.add("frontend"),e.add("uxui")),(n.includes(".test.")||n.includes(".spec.")||n.includes("__tests__")||n.includes("/test/"))&&e.add("testing"),(n.includes("dockerfile")||n.includes("docker-compose")||n.includes(".dockerignore")||n.includes(".github/")||n.includes("ci/")||n.includes("cd/"))&&e.add("devops"),(n.endsWith(".sql")||n.includes("prisma")||n.includes("drizzle")||n.includes("migration")||n.includes("/db/"))&&e.add("database"),(n.endsWith(".ts")||n.endsWith(".js"))&&!n.includes(".test.")&&!n.includes(".spec.")&&!n.endsWith(".d.ts")&&e.add("backend")}return e}var na=f(()=>{"use strict";Hr();a(qs,"propagateChanges");a(Vs,"affectedDomains")});var sa=f(()=>{"use strict"});async function Jk(r,e=100){try{let{stdout:t}=await N(`git log --name-only --pretty=format:'---COMMIT---' -${e}`,{cwd:r,maxBuffer:10485760}),n=[],s=null;for(let i of t.split(`
1170
1170
  `)){let o=i.trim();o==="---COMMIT---"?(s&&s.size>0&&s.size<=30&&n.push(s),s=new Set):o&&s&&Qk(o)&&s.add(o)}return s&&s.size>0&&s.size<=30&&n.push(s),n}catch{return[]}}function Qk(r){return/\.(ts|tsx|js|jsx|mjs|cjs|py|go|rs|java|cs|rb|php|vue|svelte)$/i.test(r)&&!r.includes("node_modules/")}async function Zk(r,e=100){let t=await Jk(r,e),n=new Map,s=new Map;for(let o of t){let c=Array.from(o);for(let l of c)n.set(l,(n.get(l)||0)+1);for(let l=0;l<c.length;l++)for(let u=l+1;u<c.length;u++){let d=ew(c[l],c[u]);s.set(d,(s.get(d)||0)+1)}}let i={};for(let[o,c]of s){let[l,u]=o.split("\0"),d=n.get(l)||0,p=n.get(u)||0;if(d<2||p<2)continue;let m=d+p-c,g=m>0?c/m:0;g<.1||(i[l]||(i[l]={}),i[u]||(i[u]={}),i[l][u]=g,i[u][l]=g)}return{matrix:i,commitsAnalyzed:t.length,filesAnalyzed:n.size,builtAt:new Date().toISOString()}}function ew(r,e){return r<e?`${r}\0${e}`:`${e}\0${r}`}function Mn(r,e){let t=new Set(r),n=new Map;for(let s of r){let i=e.matrix[s];if(i)for(let[o,c]of Object.entries(i)){if(t.has(o))continue;let l=n.get(o)||0;c>l&&n.set(o,c)}}return Array.from(n.entries()).map(([s,i])=>({path:s,score:i})).sort((s,i)=>i.score-s.score)}function tw(r,e){h.setDoc(r,ia,e),Ks.delete(r)}function St(r){let e=h.get(r,"SELECT updated_at FROM kv_store WHERE key = ?",ia);if(!e)return Ks.delete(r),null;let t=Ks.get(r);if(t&&t.updatedAt===e.updated_at)return t.matrix;let n=h.getDoc(r,ia);return n&&Ks.set(r,{matrix:n,updatedAt:e.updated_at}),n}async function rw(r,e){try{let{stdout:t}=await N(`git rev-list --max-count=${e} HEAD`,{cwd:r,maxBuffer:1048576}),n=t.split(`
1171
1171
  `).map(s=>s.trim()).filter(Boolean);return n.length>0?n.join(`
1172
- `):null}catch{return null}}async function Ys(r,e,t=100){let n=await rw(r,t),s=n?St(e):null;if(s?.historyFingerprint===n)return s;let i=await Zk(r,t);return n&&(i.historyFingerprint=n),tw(e,i),i}var ia,Ks,Fn=f(()=>{"use strict";sa();I();le();a(Jk,"parseGitLog");a(Qk,"isSourceFile");a(Zk,"buildMatrix");a(ew,"pairKey");a(Mn,"scoreFromSeeds");ia="cochange-index",Ks=new Map;a(tw,"saveMatrix");a(St,"loadMatrix");a(rw,"recentHistoryFingerprint");a(Ys,"indexCoChanges")});function nw(r){return r instanceof $n}function Ee(r){return nw(r)||r instanceof Error?r.message:typeof r=="string"?r:"Unknown error"}var $n,zs,Un,bt=f(()=>{"use strict";$n=class extends Error{static{a(this,"PrjctError")}code;isOperational;constructor(e,t="PRJCT_ERROR"){super(e),this.name="PrjctError",this.code=t,this.isOperational=!0,Error.captureStackTrace?.(this,this.constructor)}},zs=class r extends $n{static{a(this,"ProjectError")}constructor(e,t="PROJECT_ERROR"){super(e,t),this.name="ProjectError"}static notInitialized(){return new r("Project not initialized. Run p. init first.","PROJECT_NOT_INIT")}static notFound(e){return new r(`Project not found: ${e}`,"PROJECT_NOT_FOUND")}static invalidId(e){return new r(`Invalid project ID: ${e}`,"PROJECT_INVALID_ID")}},Un=class r extends $n{static{a(this,"AgentError")}constructor(e,t="AGENT_ERROR"){super(e,t),this.name="AgentError"}static notSupported(e){return new r(`Unsupported agent type: ${e}`,"AGENT_NOT_SUPPORTED")}static initFailed(e){return new r(`Agent initialization failed: ${e}`,"AGENT_INIT_FAILED")}};a(nw,"isPrjctError");a(Ee,"getErrorMessage")});function Bd(r){let e=r.toLowerCase();return e.includes("github")?"github":e.includes("gitlab")?"gitlab":e.includes("bitbucket")?"bitbucket":"other"}function oa(r){let e=r.trim();if(!e)return{};let t=e.match(/^[^/@]+@([^:/]+):(.+?)(?:\.git)?\/?$/);if(t)return{provider:Bd(t[1]),repoSlug:t[2]};try{let n=new URL(e),s=n.pathname.replace(/^\/+/,"").replace(/\.git$/,"").replace(/\/+$/,"");return!n.host||!s?{}:{provider:Bd(n.host),repoSlug:s}}catch{return{}}}async function sw(r){try{let{stdout:e}=await V("git",["remote","get-url","origin"],{cwd:r});return e.trim()||void 0}catch{return}}async function iw(r){try{let{stdout:e}=await V("git",["symbolic-ref","--short","refs/remotes/origin/HEAD"],{cwd:r});return e.trim().replace(/^origin\//,"")||void 0}catch{return}}function ar(r){return typeof r=="string"&&r.length>0?r:void 0}function Gd(r){return typeof r=="number"&&Number.isFinite(r)?r:void 0}function ow(r){return Object.fromEntries(Object.entries(r).filter(([,e])=>e!==void 0))}async function Xd(r){let e=y.getDoc(r,"project")||{},t=ar(e.repoPath),{provider:n,repoSlug:s}=t?oa(await sw(t)||""):{},i=t?await iw(t):void 0,o=Array.isArray(e.techStack)?e.techStack.filter(c=>typeof c=="string"):void 0;return ow({provider:n,repoSlug:s,currentBranch:ar(e.currentBranch),defaultBranch:i,stack:ar(e.stack),techStack:o&&o.length>0?o:void 0,version:ar(e.version),commitCount:Gd(e.commitCount),fileCount:Gd(e.fileCount),lastCommit:ar(e.lastSyncCommit),hasUncommitted:typeof e.hasUncommittedChanges=="boolean"?e.hasUncommittedChanges:void 0,cliVersion:ar(e.cliVersion),syncedAt:ar(e.lastSync)})}var aa=f(()=>{"use strict";I();le();a(Bd,"providerForHost");a(oa,"parseRemote");a(sw,"gitRemoteUrl");a(iw,"gitDefaultBranch");a(ar,"str");a(Gd,"num");a(ow,"compact");a(Xd,"buildProjectMeta")});import{execFile as aw}from"node:child_process";import cw from"node:crypto";import{promisify as lw}from"node:util";function pw(r,e=dw){let t=Buffer.from(e.replace(/-/g,""),"hex"),s=cw.createHash("sha1").update(t).update(r,"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 mw(r){let e;try{let{stdout:s}=await uw("git",["remote","get-url","origin"],{cwd:r});e=s.trim()||void 0}catch{return null}if(!e)return null;let{provider:t,repoSlug:n}=oa(e);return!t||!n?null:`${t}:${n}`.toLowerCase()}async function qd(r){let e=await mw(r);return e?pw(e):null}var uw,dw,Vd=f(()=>{"use strict";aa();uw=lw(aw),dw="6f9b2c1a-3d4e-5f60-8a7b-1c2d3e4f5a6b";a(pw,"uuidv5");a(mw,"repoKey");a(qd,"deriveProjectId")});var ua={};Q(ua,{PACKAGE_ROOT:()=>Bt,VERSION:()=>Wt,getPackageRoot:()=>la,getVersion:()=>Qs,resetPackageRoot:()=>gw});import ca from"node:fs";import Js from"node:path";function la(){if(Wr)return Wr;let r=__dirname;for(let e=0;e<5;e++){let t=Js.join(r,"package.json");if(ca.existsSync(t))try{if(JSON.parse(ca.readFileSync(t,"utf-8")).name==="prjct-cli")return Wr=r,r}catch{}r=Js.dirname(r)}return Wr=Js.join(__dirname,"..","..",".."),Wr}function Qs(){if(cr)return cr;let r="3.24.2";if(r&&/^\d+\.\d+\.\d+/.test(r))return cr=r,cr;try{let e=Js.join(la(),"package.json");return cr=JSON.parse(ca.readFileSync(e,"utf-8")).version,cr}catch(e){return process.env.PRJCT_DEBUG==="1"&&console.error("Failed to read version from package.json:",w(e)),"0.0.0"}}function gw(r){Wr=r,cr=null}var cr,Wr,Wt,Bt,vt=f(()=>{"use strict";z();cr=null,Wr=null;a(la,"getPackageRoot");a(Qs,"getVersion");a(gw,"resetPackageRoot");Wt=Qs(),Bt=la()});async function Zs(r){try{let{stdout:e}=await N(r,{timeout:5e3});return{success:!0,output:e.trim()}}catch{return{success:!1,output:""}}}async function fw(){let r=await Zs("gh api user --jq .login");return r.success&&r.output||(r=await Zs("git config --global github.user"),r.success&&r.output)?r.output:null}async function hw(){let r=await Zs("git config user.name");return r.success&&r.output?r.output:null}async function yw(){let r=await Zs("git config user.email");return r.success&&r.output?r.output:null}async function Br(){let[r,e,t]=await Promise.all([fw(),hw(),yw()]);return{github:r,email:t,name:e||r||"Unknown"}}var ei=f(()=>{"use strict";le();a(Zs,"execCommand");a(fw,"detectGitHubUsername");a(hw,"detectGitName");a(yw,"detectGitEmail");a(Br,"detect")});var ga={};Q(ga,{worktreeService:()=>Ew});import pa from"node:fs/promises";import dt from"node:path";var Kd,ma,Ew,fa=f(()=>{"use strict";le();J();Kd=".worktrees",ma=class{static{a(this,"WorktreeService")}async create(e,t,n={}){let s=await this.getMainWorktree(e),i=dt.join(s,Kd,t),o=n.branch||`feat/${t}`;await pa.mkdir(dt.join(s,Kd),{recursive:!0});let c=n.baseBranch?` ${n.baseBranch}`:"";await N(`git worktree add "${i}" -b "${o}"${c}`,{cwd:s});let{stdout:l}=await N("git rev-parse HEAD",{cwd:i});return{path:i,branch:o,commit:l.trim(),isMain:!1,slug:t}}async remove(e,t=!1){let n=await this.getMainWorktree(e),s;if(t)try{let{stdout:i}=await N("git rev-parse --abbrev-ref HEAD",{cwd:e});s=i.trim()}catch{}if(await N(`git worktree remove "${e}" --force`,{cwd:n}),t&&s&&s!=="main"&&s!=="master")try{await N(`git branch -D "${s}"`,{cwd:n})}catch{}}async list(e){let t=await this.getMainWorktree(e),{stdout:n}=await N("git worktree list --porcelain",{cwd:t});return this.parsePorcelainOutput(n,t)}async detect(e){try{let{stdout:t}=await N("git rev-parse --git-common-dir",{cwd:e}),{stdout:n}=await N("git rev-parse --git-dir",{cwd:e}),s=dt.resolve(e,t.trim()),i=dt.resolve(e,n.trim());if(s!==i){let{stdout:o}=await N("git rev-parse --abbrev-ref HEAD",{cwd:e}),{stdout:c}=await N("git rev-parse HEAD",{cwd:e}),{stdout:l}=await N("git rev-parse --show-toplevel",{cwd:e}),u=l.trim(),d=dt.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:n}=await N("git worktree list --porcelain",{cwd:e}),s=n.split(`
1172
+ `):null}catch{return null}}async function Ys(r,e,t=100){let n=await rw(r,t),s=n?St(e):null;if(s?.historyFingerprint===n)return s;let i=await Zk(r,t);return n&&(i.historyFingerprint=n),tw(e,i),i}var ia,Ks,Fn=f(()=>{"use strict";sa();I();le();a(Jk,"parseGitLog");a(Qk,"isSourceFile");a(Zk,"buildMatrix");a(ew,"pairKey");a(Mn,"scoreFromSeeds");ia="cochange-index",Ks=new Map;a(tw,"saveMatrix");a(St,"loadMatrix");a(rw,"recentHistoryFingerprint");a(Ys,"indexCoChanges")});function nw(r){return r instanceof $n}function Ee(r){return nw(r)||r instanceof Error?r.message:typeof r=="string"?r:"Unknown error"}var $n,zs,Un,bt=f(()=>{"use strict";$n=class extends Error{static{a(this,"PrjctError")}code;isOperational;constructor(e,t="PRJCT_ERROR"){super(e),this.name="PrjctError",this.code=t,this.isOperational=!0,Error.captureStackTrace?.(this,this.constructor)}},zs=class r extends $n{static{a(this,"ProjectError")}constructor(e,t="PROJECT_ERROR"){super(e,t),this.name="ProjectError"}static notInitialized(){return new r("Project not initialized. Run p. init first.","PROJECT_NOT_INIT")}static notFound(e){return new r(`Project not found: ${e}`,"PROJECT_NOT_FOUND")}static invalidId(e){return new r(`Invalid project ID: ${e}`,"PROJECT_INVALID_ID")}},Un=class r extends $n{static{a(this,"AgentError")}constructor(e,t="AGENT_ERROR"){super(e,t),this.name="AgentError"}static notSupported(e){return new r(`Unsupported agent type: ${e}`,"AGENT_NOT_SUPPORTED")}static initFailed(e){return new r(`Agent initialization failed: ${e}`,"AGENT_INIT_FAILED")}};a(nw,"isPrjctError");a(Ee,"getErrorMessage")});function Bd(r){let e=r.toLowerCase();return e.includes("github")?"github":e.includes("gitlab")?"gitlab":e.includes("bitbucket")?"bitbucket":"other"}function oa(r){let e=r.trim();if(!e)return{};let t=e.match(/^[^/@]+@([^:/]+):(.+?)(?:\.git)?\/?$/);if(t)return{provider:Bd(t[1]),repoSlug:t[2]};try{let n=new URL(e),s=n.pathname.replace(/^\/+/,"").replace(/\.git$/,"").replace(/\/+$/,"");return!n.host||!s?{}:{provider:Bd(n.host),repoSlug:s}}catch{return{}}}async function sw(r){try{let{stdout:e}=await V("git",["remote","get-url","origin"],{cwd:r});return e.trim()||void 0}catch{return}}async function iw(r){try{let{stdout:e}=await V("git",["symbolic-ref","--short","refs/remotes/origin/HEAD"],{cwd:r});return e.trim().replace(/^origin\//,"")||void 0}catch{return}}function ar(r){return typeof r=="string"&&r.length>0?r:void 0}function Gd(r){return typeof r=="number"&&Number.isFinite(r)?r:void 0}function ow(r){return Object.fromEntries(Object.entries(r).filter(([,e])=>e!==void 0))}async function Xd(r){let e=y.getDoc(r,"project")||{},t=ar(e.repoPath),{provider:n,repoSlug:s}=t?oa(await sw(t)||""):{},i=t?await iw(t):void 0,o=Array.isArray(e.techStack)?e.techStack.filter(c=>typeof c=="string"):void 0;return ow({provider:n,repoSlug:s,currentBranch:ar(e.currentBranch),defaultBranch:i,stack:ar(e.stack),techStack:o&&o.length>0?o:void 0,version:ar(e.version),commitCount:Gd(e.commitCount),fileCount:Gd(e.fileCount),lastCommit:ar(e.lastSyncCommit),hasUncommitted:typeof e.hasUncommittedChanges=="boolean"?e.hasUncommittedChanges:void 0,cliVersion:ar(e.cliVersion),syncedAt:ar(e.lastSync)})}var aa=f(()=>{"use strict";I();le();a(Bd,"providerForHost");a(oa,"parseRemote");a(sw,"gitRemoteUrl");a(iw,"gitDefaultBranch");a(ar,"str");a(Gd,"num");a(ow,"compact");a(Xd,"buildProjectMeta")});import{execFile as aw}from"node:child_process";import cw from"node:crypto";import{promisify as lw}from"node:util";function pw(r,e=dw){let t=Buffer.from(e.replace(/-/g,""),"hex"),s=cw.createHash("sha1").update(t).update(r,"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 mw(r){let e;try{let{stdout:s}=await uw("git",["remote","get-url","origin"],{cwd:r});e=s.trim()||void 0}catch{return null}if(!e)return null;let{provider:t,repoSlug:n}=oa(e);return!t||!n?null:`${t}:${n}`.toLowerCase()}async function qd(r){let e=await mw(r);return e?pw(e):null}var uw,dw,Vd=f(()=>{"use strict";aa();uw=lw(aw),dw="6f9b2c1a-3d4e-5f60-8a7b-1c2d3e4f5a6b";a(pw,"uuidv5");a(mw,"repoKey");a(qd,"deriveProjectId")});var ua={};Q(ua,{PACKAGE_ROOT:()=>Bt,VERSION:()=>Wt,getPackageRoot:()=>la,getVersion:()=>Qs,resetPackageRoot:()=>gw});import ca from"node:fs";import Js from"node:path";function la(){if(Wr)return Wr;let r=__dirname;for(let e=0;e<5;e++){let t=Js.join(r,"package.json");if(ca.existsSync(t))try{if(JSON.parse(ca.readFileSync(t,"utf-8")).name==="prjct-cli")return Wr=r,r}catch{}r=Js.dirname(r)}return Wr=Js.join(__dirname,"..","..",".."),Wr}function Qs(){if(cr)return cr;let r="3.24.3";if(r&&/^\d+\.\d+\.\d+/.test(r))return cr=r,cr;try{let e=Js.join(la(),"package.json");return cr=JSON.parse(ca.readFileSync(e,"utf-8")).version,cr}catch(e){return process.env.PRJCT_DEBUG==="1"&&console.error("Failed to read version from package.json:",w(e)),"0.0.0"}}function gw(r){Wr=r,cr=null}var cr,Wr,Wt,Bt,vt=f(()=>{"use strict";z();cr=null,Wr=null;a(la,"getPackageRoot");a(Qs,"getVersion");a(gw,"resetPackageRoot");Wt=Qs(),Bt=la()});async function Zs(r){try{let{stdout:e}=await N(r,{timeout:5e3});return{success:!0,output:e.trim()}}catch{return{success:!1,output:""}}}async function fw(){let r=await Zs("gh api user --jq .login");return r.success&&r.output||(r=await Zs("git config --global github.user"),r.success&&r.output)?r.output:null}async function hw(){let r=await Zs("git config user.name");return r.success&&r.output?r.output:null}async function yw(){let r=await Zs("git config user.email");return r.success&&r.output?r.output:null}async function Br(){let[r,e,t]=await Promise.all([fw(),hw(),yw()]);return{github:r,email:t,name:e||r||"Unknown"}}var ei=f(()=>{"use strict";le();a(Zs,"execCommand");a(fw,"detectGitHubUsername");a(hw,"detectGitName");a(yw,"detectGitEmail");a(Br,"detect")});var ga={};Q(ga,{worktreeService:()=>Ew});import pa from"node:fs/promises";import dt from"node:path";var Kd,ma,Ew,fa=f(()=>{"use strict";le();J();Kd=".worktrees",ma=class{static{a(this,"WorktreeService")}async create(e,t,n={}){let s=await this.getMainWorktree(e),i=dt.join(s,Kd,t),o=n.branch||`feat/${t}`;await pa.mkdir(dt.join(s,Kd),{recursive:!0});let c=n.baseBranch?` ${n.baseBranch}`:"";await N(`git worktree add "${i}" -b "${o}"${c}`,{cwd:s});let{stdout:l}=await N("git rev-parse HEAD",{cwd:i});return{path:i,branch:o,commit:l.trim(),isMain:!1,slug:t}}async remove(e,t=!1){let n=await this.getMainWorktree(e),s;if(t)try{let{stdout:i}=await N("git rev-parse --abbrev-ref HEAD",{cwd:e});s=i.trim()}catch{}if(await N(`git worktree remove "${e}" --force`,{cwd:n}),t&&s&&s!=="main"&&s!=="master")try{await N(`git branch -D "${s}"`,{cwd:n})}catch{}}async list(e){let t=await this.getMainWorktree(e),{stdout:n}=await N("git worktree list --porcelain",{cwd:t});return this.parsePorcelainOutput(n,t)}async detect(e){try{let{stdout:t}=await N("git rev-parse --git-common-dir",{cwd:e}),{stdout:n}=await N("git rev-parse --git-dir",{cwd:e}),s=dt.resolve(e,t.trim()),i=dt.resolve(e,n.trim());if(s!==i){let{stdout:o}=await N("git rev-parse --abbrev-ref HEAD",{cwd:e}),{stdout:c}=await N("git rev-parse HEAD",{cwd:e}),{stdout:l}=await N("git rev-parse --show-toplevel",{cwd:e}),u=l.trim(),d=dt.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:n}=await N("git worktree list --porcelain",{cwd:e}),s=n.split(`
1173
1173
  `)[0];if(s?.startsWith("worktree "))return s.replace("worktree ","").trim()}catch{}let{stdout:t}=await N("git rev-parse --show-toplevel",{cwd:e});return t.trim()}async setup(e,t){let n=dt.join(t,".env");await v(n)&&await pa.copyFile(n,dt.join(e,".env"));let s=dt.join(t,".prjct"),i=dt.join(e,".prjct");await v(s)&&!await v(i)&&await pa.symlink(s,i,"dir")}async teardown(e){}async clean(e){let t=await this.list(e),n=[],s=await this.getMainWorktree(e);await N("git worktree prune",{cwd:s});for(let i of t)i.isMain||await v(i.path)||n.push(i.slug);return n}parsePorcelainOutput(e,t){let n=[],s=e.trim().split(`
1174
1174
 
1175
1175
  `);for(let i of s){if(!i.trim())continue;let o=i.trim().split(`
@@ -1299,8 +1299,8 @@ ${c.join(`
1299
1299
  started_at = COALESCE(excluded.started_at, tasks.started_at),
1300
1300
  completed_at = excluded.completed_at,
1301
1301
  pr_url = COALESCE(excluded.pr_url, tasks.pr_url),
1302
- tokens_in = excluded.tokens_in,
1303
- tokens_out = excluded.tokens_out,
1302
+ tokens_in = CASE WHEN excluded.tokens_in > 0 THEN excluded.tokens_in ELSE tasks.tokens_in END,
1303
+ tokens_out = CASE WHEN excluded.tokens_out > 0 THEN excluded.tokens_out ELSE tasks.tokens_out END,
1304
1304
  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,n)}catch{}}async updateCurrentTask(e,t){let n=null;return await this.update(e,s=>s.currentTask?(n={...s.currentTask,...t},{...s,currentTask:n,lastUpdated:T()}):s),n}async completeTask(e,t){let n=T(),s={};if(await this.update(e,o=>o.currentTask?(this.validateTransition(o,"done"),s.completedTask=o.currentTask,{...o,currentTask:null,previousTask:null,lastUpdated:n}):o),!s.completedTask)return null;let i=s.completedTask;return this.mirrorTaskRow(e,i,"completed",{completedAt:n}),this.mirrorHistoryEntry(e,this.createTaskHistoryEntry(i,n,t)),await this.publishEvent(e,"task.completed",{taskId:i.id,description:i.description,startedAt:i.startedAt,completedAt:n}),i}createTaskHistoryEntry(e,t,n){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 n&&(o.feedback=n),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 n=await fp(this.lifecycleBackend(),e,t);return n&&this.mirrorTaskRow(e,n,"paused",{pausedAt:n.pausedAt,pauseReason:n.pauseReason}),n}async resumeTask(e,t){let n=await hp(this.lifecycleBackend(),e,t);return n&&this.mirrorTaskRow(e,n,"in_progress"),n}getPausedTasksFromState(e){return Array.isArray(e.pausedTasks)&&e.pausedTasks.length>0?e.pausedTasks:e.previousTask?[e.previousTask]:[]}async getStalePausedTasks(e){return yp(this.lifecycleBackend(),e)}async archiveStalePausedTasks(e){return Ep(this.lifecycleBackend(),e)}queryBackend(){return{read:this.read.bind(this),update:this.update.bind(this),getPausedTasksFromState:this.getPausedTasksFromState.bind(this)}}async clearTask(e){return kp(this.queryBackend(),e)}async hasTask(e){return wp(this.queryBackend(),e)}async getPausedTask(e){return Sp(this.queryBackend(),e)}async getAllPausedTasks(e){return bp(this.queryBackend(),e)}async getTaskHistory(e){return Ha(this.queryBackend(),e)}async getMostRecentTask(e){return vp(this.queryBackend(),e)}async getTaskHistoryByType(e,t){return _p(this.queryBackend(),e,t)}async getAggregatedFeedback(e){return Rp(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,n){let s=await this.read(e);this.validateTransition(s,"task",n);let i=await Bp(this.workspaceBackend(),e,t,n);return this.mirrorTaskRow(e,i,"in_progress"),i}async getCurrentTaskForWorkspace(e,t){return Gp(this.workspaceBackend(),e,t)}async completeTaskInWorkspace(e,t,n){let s=await Xp(this.workspaceBackend(),e,t,n);return s&&this.mirrorTaskRow(e,s,"completed",{completedAt:T()}),s}async getActiveTasks(e){return qp(this.workspaceBackend(),e)}async getActiveTaskCount(e){return Vp(this.workspaceBackend(),e)}async updateWorkspaceTask(e,t,n){return Kp(this.workspaceBackend(),e,t,n)}async addTokens(e,t,n,s){return Yp(this.workspaceBackend(),e,t,n,s)}subtaskBackend(){return{read:this.read.bind(this),update:this.update.bind(this),publish:this.publishEvent.bind(this)}}async createSubtasks(e,t){return Np(this.subtaskBackend(),e,t)}async completeSubtask(e,t){return Ip(this.subtaskBackend(),e,t)}async getCurrentSubtask(e){return Pp(this.subtaskBackend(),e)}async getNextSubtask(e){return Dp(this.subtaskBackend(),e)}async getPreviousSubtask(e){return Wa(this.subtaskBackend(),e)}async getPreviousHandoff(e){return Op(this.subtaskBackend(),e)}async getSubtasks(e){return jp(this.subtaskBackend(),e)}async getSubtaskProgress(e){return Lp(this.subtaskBackend(),e)}async hasSubtasks(e){return Mp(this.subtaskBackend(),e)}async areAllSubtasksComplete(e){return Fp(this.subtaskBackend(),e)}async failSubtask(e,t){return $p(this.subtaskBackend(),e,t)}async skipSubtask(e,t){return Up(this.subtaskBackend(),e,t)}async blockSubtask(e,t){return Hp(this.subtaskBackend(),e,t)}},$=new Ba});function mS(){let r=process.env.PRJCT_DEBUG||process.env.DEBUG||"";if(!r)return{level:-1,name:"disabled"};if(pS.has(r)||r.includes("prjct"))return{level:qr.debug,name:"debug"};let e=qr[r]??-1,t=e>=0?r:"disabled";return{level:e,name:t}}function mi(r,e,t){return Jp>=r?(...n)=>console[t](e,...n):fS}var qr,pS,Jp,gS,fS,hS,P,Ye=f(()=>{"use strict";qr={error:0,warn:1,info:2,debug:3},pS=new Set(["1","true","*"]);a(mS,"getLogLevel");({level:Jp,name:gS}=mS()),fS=a(()=>{},"noop");a(mi,"createLogMethod");hS={error:mi(qr.error,"[prjct:error]","error"),warn:mi(qr.warn,"[prjct:warn]","warn"),info:mi(qr.info,"[prjct:info]","log"),debug:mi(qr.debug,"[prjct:debug]","log"),isEnabled:a(()=>Jp>=0,"isEnabled"),level:a(()=>gS,"level")},P=hS});var Qp,Zp,em,tm,rm=f(()=>{"use strict";Qp={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"]},Zp=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".py",".go",".rs",".java",".kt",".swift",".rb",".php",".c",".cpp",".h",".hpp",".cs",".vue",".svelte"]),em=new Set(["node_modules",".git","dist","build",".next",".nuxt",".output","coverage",".cache","__pycache__",".pytest_cache","vendor","target",".turbo",".vercel"]),tm=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 yS from"node:fs/promises";import gi from"node:path";async function fi(r,e,t={}){let n=Date.now(),s=t.maxFiles??30,i=t.minScore??.1,o=t.includeTests??!1,c=ES(r),l=await TS(e),u=await kS(e),d=[];for(let m of l){if(!o&&SS(m))continue;let g=wS(m,c,u,t.historicalBoosts);g.score>=i&&d.push(g)}d.sort((m,g)=>g.score-m.score);let p=d.slice(0,s);return{files:p,metrics:{filesScanned:l.length,filesReturned:p.length,scanDuration:Date.now()-n}}}function ES(r){return r.toLowerCase().split(/[^a-z0-9]+/).filter(Boolean).filter(t=>!tm.has(t)&&t.length>2)}async function TS(r){let e=[];async function t(n,s=""){try{let i=await yS.readdir(n,{withFileTypes:!0});for(let o of i){let c=gi.join(n,o.name),l=gi.join(s,o.name);if(o.isDirectory()){if(em.has(o.name)||o.name.startsWith("."))continue;await t(c,l)}else if(o.isFile()){let u=gi.extname(o.name).toLowerCase();Zp.has(u)&&e.push(l)}}}catch(i){D(i)||P.debug(`files-tool: skipped unreadable path during walk: ${w(i)}`)}}return a(t,"walk"),await t(r),e}async function kS(r){let e=new Map;try{let{stdout:t}=await N(`git log -30 --pretty=format:"%H %ct" --name-only | awk '
1305
1305
  /^[a-f0-9]{40}/ { commit=$1; timestamp=$2; next }
1306
1306
  NF { files[$0]++; if (!lastmod[$0]) lastmod[$0]=timestamp }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prjct-cli",
3
- "version": "3.24.2",
3
+ "version": "3.24.3",
4
4
  "description": "Project memory and workflow context for AI coding agents.",
5
5
  "main": "dist/bin/prjct.mjs",
6
6
  "bin": {