prjct-cli 3.49.0 → 3.49.1

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.
@@ -1212,7 +1212,7 @@ CREATE TABLE velocity_sprints (
1212
1212
  `);let n=new Set(e.prepare("SELECT version FROM _migrations").all().map(i=>i.version)),s=Gi.filter(i=>!n.has(i.version));if(s.length!==0){if(r&&n.size>0)try{let i=`${r}.pre-migrate.bak`;_s.existsSync(i)&&_s.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)_c(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}},E=new Xi,h=E});import xc from"node:fs/promises";import Ir from"node:path";function ig(t){let e=[],r,n=new RegExp(hm.source,"g");for(;(r=n.exec(t))!==null;){let s=r[1];(s.startsWith(".")||s.startsWith("@/"))&&e.push(s)}return e}async function og(t,e,r){let n;if(t.startsWith("@/"))n=Ir.join(r,"src",t.slice(2));else{let s=Ir.dirname(Ir.join(r,e));n=Ir.resolve(s,t)}for(let s of fm){let i=n+s;try{if((await xc.stat(i)).isFile())return Ir.relative(r,i)}catch{}}return null}async function qv(t){let e=await xt(t),r={},n={},s=0,i=await or(e,50,async o=>{try{let c=await xc.readFile(Ir.join(t,o),"utf-8"),l=ig(c),u=[];for(let d of l){let p=await og(d,o,t);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){r[o]=c,s+=c.length;for(let l of c)n[l]||(n[l]=[]),n[l].push(o)}return{forward:r,reverse:n,fileCount:e.length,edgeCount:s,builtAt:new Date().toISOString()}}function En(t,e,r=2){let n=new Set(t),s=new Map,i=[];for(let o of t){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>r)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<r){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 Vv(t){return Object.values(t).reduce((e,r)=>e+r.length,0)}function Jv(t,e){let r=t.forward[e]||[];delete t.forward[e];for(let n of r){let s=(t.reverse[n]||[]).filter(i=>i!==e);s.length===0?delete t.reverse[n]:t.reverse[n]=s}}function Kv(t,e){let r=t.reverse[e]||[];delete t.reverse[e];let n=[];for(let s of r){let i=(t.forward[s]||[]).filter(o=>o!==e);i.length===0?delete t.forward[s]:t.forward[s]=i,n.push(s)}return n}function Yv(t,e,r){if(r.length===0)return;let n=Array.from(new Set(r));t.forward[e]=n;for(let s of n)t.reverse[s]||(t.reverse[s]=[]),t.reverse[s].includes(e)||t.reverse[s].push(e)}async function zv(t,e){try{let r=await xc.readFile(Ir.join(t,e),"utf-8"),n=ig(r),s=[];for(let i of n){let o=await og(i,e,t);o&&o!==e&&s.push(o)}return{filePath:e,imports:s}}catch{return null}}function ag(t){return{schemaVersion:2,fileCount:t.fileCount,edgeCount:t.edgeCount,builtAt:t.builtAt}}function Qv(t,e){try{h.transaction(t,r=>{r.prepare("DELETE FROM import_graph_edges").run();let n=r.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 Zv(t,e,r,n){try{h.transaction(t,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([...r,...n]))i.run(c);for(let c of r){let l=e.forward[c]||[];for(let[u,d]of l.entries())o.run(c,d,u)}})}catch{}}function e_(t,e,r){try{let n=h.query(t,"SELECT from_path, to_path FROM import_graph_edges ORDER BY from_path, sort_order, to_path");if(n.length===0){if(r?.edgeCount===0){let l={forward:{},reverse:{},fileCount:r.fileCount,edgeCount:0,builtAt:r.builtAt};return Pr.set(t,{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:r?.fileCount??o.size,edgeCount:n.length,builtAt:r?.builtAt??e};return Pr.set(t,{graph:c,updatedAt:e}),c}catch{return null}}function t_(t,e){h.setDoc(t,Vi,ag(e)),Qv(t,e),Pr.delete(t)}function r_(t,e,r,n){h.setDoc(t,Vi,ag(e)),Zv(t,e,r,n),Pr.delete(t)}function Je(t){let e=h.get(t,"SELECT updated_at FROM kv_store WHERE key = ?",Vi);if(!e)return Pr.delete(t),null;let r=Pr.get(t);if(r&&r.updatedAt===e.updated_at)return r.graph;let n=h.getDoc(t,Vi),s=e_(t,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 Pr.set(t,{graph:i,updatedAt:e.updated_at}),i}async function xs(t,e){let r=await qv(t);return t_(e,r),r}async function cg(t,e,r,n=[]){let s=Je(e);if(!s)return xs(t,e);let i=new Set([...r,...n]);for(let l of i)Jv(s,l);let o=new Set;for(let l of n)for(let u of Kv(s,l))o.add(u);let c=await or(r,50,l=>zv(t,l));for(let l of c)Yv(s,l.filePath,l.imports);return s.edgeCount=Vv(s.forward),s.builtAt=new Date().toISOString(),r_(e,s,[...r,...o],n),s}var Vi,Pr,Dr=f(()=>{"use strict";ac();j();re();a(ig,"extractImportSources");a(og,"resolveImport");a(qv,"buildGraph");a(En,"scoreFromSeeds");Vi="import-graph",Pr=new Map;a(Vv,"countEdges");a(Jv,"removeOutgoingEdges");a(Kv,"removeIncomingEdges");a(Yv,"addEdges");a(zv,"importsForFile");a(ag,"graphMetadata");a(Qv,"replacePerFileEdges");a(Zv,"updatePerFileEdges");a(e_,"loadGraphFromPerFileEdges");a(t_,"saveGraph");a(r_,"saveGraphUpdate");a(Je,"loadGraph");a(xs,"indexImports");a(cg,"updateImportGraph")});function Ji(t,e){let r=[...t.added,...t.modified],n=new Set(r),s=new Set,i=Je(e);if(i)for(let l of r){let u=i.reverse[l];if(u)for(let d of u)n.has(d)||s.add(d)}let o=Array.from(s),c=[...r,...o];return{directlyChanged:r,affectedByImports:o,deleted:t.deleted,allAffected:c}}function Ki(t){let e=new Set;for(let r of t){let n=r.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 Rc=f(()=>{"use strict";Dr();a(Ji,"propagateChanges");a(Ki,"affectedDomains")});var Ac=f(()=>{"use strict"});async function s_(t,e=100){try{let{stdout:r}=await M(`git log --name-only --pretty=format:'---COMMIT---' -${e}`,{cwd:t,maxBuffer:10485760}),n=[],s=null;for(let i of r.split(`
1213
1213
  `)){let o=i.trim();o==="---COMMIT---"?(s&&s.size>0&&s.size<=30&&n.push(s),s=new Set):o&&s&&i_(o)&&s.add(o)}return s&&s.size>0&&s.size<=30&&n.push(s),n}catch{return[]}}function i_(t){return/\.(ts|tsx|js|jsx|mjs|cjs|py|go|rs|java|cs|rb|php|vue|svelte)$/i.test(t)&&!t.includes("node_modules/")}async function o_(t,e=100){let r=await s_(t,e),n=new Map,s=new Map;for(let o of r){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=a_(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:r.length,filesAnalyzed:n.size,builtAt:new Date().toISOString()}}function a_(t,e){return t<e?`${t}\0${e}`:`${e}\0${t}`}function Or(t,e){let r=new Set(t),n=new Map;for(let s of t){let i=e.matrix[s];if(i)for(let[o,c]of Object.entries(i)){if(r.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 c_(t,e){h.setDoc(t,Cc,e),Yi.delete(t)}function dt(t){let e=h.get(t,"SELECT updated_at FROM kv_store WHERE key = ?",Cc);if(!e)return Yi.delete(t),null;let r=Yi.get(t);if(r&&r.updatedAt===e.updated_at)return r.matrix;let n=h.getDoc(t,Cc);return n&&Yi.set(t,{matrix:n,updatedAt:e.updated_at}),n}async function l_(t,e){try{let{stdout:r}=await M(`git rev-list --max-count=${e} HEAD`,{cwd:t,maxBuffer:1048576}),n=r.split(`
1214
1214
  `).map(s=>s.trim()).filter(Boolean);return n.length>0?n.join(`
1215
- `):null}catch{return null}}async function zi(t,e,r=100){let n=await l_(t,r),s=n?dt(e):null;if(s?.historyFingerprint===n)return s;let i=await o_(t,r);return n&&(i.historyFingerprint=n),c_(e,i),i}var Cc,Yi,kn=f(()=>{"use strict";Ac();j();pe();a(s_,"parseGitLog");a(i_,"isSourceFile");a(o_,"buildMatrix");a(a_,"pairKey");a(Or,"scoreFromSeeds");Cc="cochange-index",Yi=new Map;a(c_,"saveMatrix");a(dt,"loadMatrix");a(l_,"recentHistoryFingerprint");a(zi,"indexCoChanges")});function u_(t){return t instanceof Rs}function Re(t){return u_(t)||t instanceof Error?t.message:typeof t=="string"?t:"Unknown error"}var Rs,Qi,As,Wt=f(()=>{"use strict";Rs=class extends Error{static{a(this,"PrjctError")}code;isOperational;constructor(e,r="PRJCT_ERROR"){super(e),this.name="PrjctError",this.code=r,this.isOperational=!0,Error.captureStackTrace?.(this,this.constructor)}},Qi=class t extends Rs{static{a(this,"ProjectError")}constructor(e,r="PROJECT_ERROR"){super(e,r),this.name="ProjectError"}static notInitialized(){return new t("Project not initialized. Run p. init first.","PROJECT_NOT_INIT")}static notFound(e){return new t(`Project not found: ${e}`,"PROJECT_NOT_FOUND")}static invalidId(e){return new t(`Invalid project ID: ${e}`,"PROJECT_INVALID_ID")}},As=class t extends Rs{static{a(this,"AgentError")}constructor(e,r="AGENT_ERROR"){super(e,r),this.name="AgentError"}static notSupported(e){return new t(`Unsupported agent type: ${e}`,"AGENT_NOT_SUPPORTED")}static initFailed(e){return new t(`Agent initialization failed: ${e}`,"AGENT_INIT_FAILED")}};a(u_,"isPrjctError");a(Re,"getErrorMessage")});function dg(t){let e=t.toLowerCase();return e.includes("github")?"github":e.includes("gitlab")?"gitlab":e.includes("bitbucket")?"bitbucket":"other"}function Nc(t){let e=t.trim();if(!e)return{};let r=e.match(/^[^/@]+@([^:/]+):(.+?)(?:\.git)?\/?$/);if(r)return{provider:dg(r[1]),repoSlug:r[2]};try{let n=new URL(e),s=n.pathname.replace(/^\/+/,"").replace(/\.git$/,"").replace(/\/+$/,"");return!n.host||!s?{}:{provider:dg(n.host),repoSlug:s}}catch{return{}}}async function d_(t){try{let{stdout:e}=await G("git",["remote","get-url","origin"],{cwd:t});return e.trim()||void 0}catch{return}}async function p_(t){try{let{stdout:e}=await G("git",["symbolic-ref","--short","refs/remotes/origin/HEAD"],{cwd:t});return e.trim().replace(/^origin\//,"")||void 0}catch{return}}function Lr(t){return typeof t=="string"&&t.length>0?t:void 0}function pg(t){return typeof t=="number"&&Number.isFinite(t)?t:void 0}function m_(t){return Object.fromEntries(Object.entries(t).filter(([,e])=>e!==void 0))}async function mg(t){let e=E.getDoc(t,"project")||{},r=Lr(e.repoPath),{provider:n,repoSlug:s}=r?Nc(await d_(r)||""):{},i=r?await p_(r):void 0,o=Array.isArray(e.techStack)?e.techStack.filter(c=>typeof c=="string"):void 0;return m_({provider:n,repoSlug:s,currentBranch:Lr(e.currentBranch),defaultBranch:i,stack:Lr(e.stack),techStack:o&&o.length>0?o:void 0,version:Lr(e.version),commitCount:pg(e.commitCount),fileCount:pg(e.fileCount),lastCommit:Lr(e.lastSyncCommit),hasUncommitted:typeof e.hasUncommittedChanges=="boolean"?e.hasUncommittedChanges:void 0,cliVersion:Lr(e.cliVersion),syncedAt:Lr(e.lastSync)})}var Ic=f(()=>{"use strict";j();pe();a(dg,"providerForHost");a(Nc,"parseRemote");a(d_,"gitRemoteUrl");a(p_,"gitDefaultBranch");a(Lr,"str");a(pg,"num");a(m_,"compact");a(mg,"buildProjectMeta")});import{execFile as g_}from"node:child_process";import f_ from"node:crypto";import{promisify as h_}from"node:util";function k_(t,e=E_){let r=Buffer.from(e.replace(/-/g,""),"hex"),s=f_.createHash("sha1").update(r).update(t,"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 T_(t){let e;try{let{stdout:s}=await y_("git",["remote","get-url","origin"],{cwd:t});e=s.trim()||void 0}catch{return null}if(!e)return null;let{provider:r,repoSlug:n}=Nc(e);return!r||!n?null:`${r}:${n}`.toLowerCase()}async function gg(t){let e=await T_(t);return e?k_(e):null}var y_,E_,fg=f(()=>{"use strict";Ic();y_=h_(g_),E_="6f9b2c1a-3d4e-5f60-8a7b-1c2d3e4f5a6b";a(k_,"uuidv5");a(T_,"repoKey");a(gg,"deriveProjectId")});var Oc={};L(Oc,{PACKAGE_ROOT:()=>gr,VERSION:()=>mr,getPackageRoot:()=>Dc,getVersion:()=>eo,resetPackageRoot:()=>w_});import Pc from"node:fs";import Zi from"node:path";function Dc(){if(Tn)return Tn;let t=__dirname;for(let e=0;e<5;e++){let r=Zi.join(t,"package.json");if(Pc.existsSync(r))try{if(JSON.parse(Pc.readFileSync(r,"utf-8")).name==="prjct-cli")return Tn=t,t}catch{}t=Zi.dirname(t)}return Tn=Zi.join(__dirname,"..","..",".."),Tn}function eo(){if(jr)return jr;let t="3.49.0";if(t&&/^\d+\.\d+\.\d+/.test(t))return jr=t,jr;try{let e=Zi.join(Dc(),"package.json");return jr=JSON.parse(Pc.readFileSync(e,"utf-8")).version,jr}catch(e){return process.env.PRJCT_DEBUG==="1"&&console.error("Failed to read version from package.json:",_(e)),"0.0.0"}}function w_(t){Tn=t,jr=null}var jr,Tn,mr,gr,Bt=f(()=>{"use strict";ne();jr=null,Tn=null;a(Dc,"getPackageRoot");a(eo,"getVersion");a(w_,"resetPackageRoot");mr=eo(),gr=Dc()});async function to(t){try{let{stdout:e}=await M(t,{timeout:5e3});return{success:!0,output:e.trim()}}catch{return{success:!1,output:""}}}async function S_(){let t=await to("gh api user --jq .login");return t.success&&t.output||(t=await to("git config --global github.user"),t.success&&t.output)?t.output:null}async function b_(){let t=await to("git config user.name");return t.success&&t.output?t.output:null}async function v_(){let t=await to("git config user.email");return t.success&&t.output?t.output:null}async function wn(){let[t,e,r]=await Promise.all([S_(),b_(),v_()]);return{github:t,email:r,name:e||t||"Unknown"}}var ro=f(()=>{"use strict";pe();a(to,"execCommand");a(S_,"detectGitHubUsername");a(b_,"detectGitName");a(v_,"detectGitEmail");a(wn,"detect")});var no={};L(no,{worktreeService:()=>__});import jc from"node:fs/promises";import At from"node:path";var hg,Mc,__,so=f(()=>{"use strict";pe();re();hg=".worktrees",Mc=class{static{a(this,"WorktreeService")}async create(e,r,n={}){let s=await this.getMainWorktree(e),i=At.join(s,hg,r),o=n.branch||`feat/${r}`;await jc.mkdir(At.join(s,hg),{recursive:!0});let c=n.baseBranch?` ${n.baseBranch}`:"";await M(`git worktree add "${i}" -b "${o}"${c}`,{cwd:s});let{stdout:l}=await M("git rev-parse HEAD",{cwd:i});return{path:i,branch:o,commit:l.trim(),isMain:!1,slug:r}}async remove(e,r=!1){let n=await this.getMainWorktree(e),s;if(r)try{let{stdout:i}=await M("git rev-parse --abbrev-ref HEAD",{cwd:e});s=i.trim()}catch{}if(await M(`git worktree remove "${e}" --force`,{cwd:n}),r&&s&&s!=="main"&&s!=="master")try{await M(`git branch -D "${s}"`,{cwd:n})}catch{}}async list(e){let r=await this.getMainWorktree(e),{stdout:n}=await M("git worktree list --porcelain",{cwd:r});return this.parsePorcelainOutput(n,r)}async detect(e){try{let{stdout:r}=await M("git rev-parse --git-common-dir",{cwd:e}),{stdout:n}=await M("git rev-parse --git-dir",{cwd:e}),s=At.resolve(e,r.trim()),i=At.resolve(e,n.trim());if(s!==i){let{stdout:o}=await M("git rev-parse --abbrev-ref HEAD",{cwd:e}),{stdout:c}=await M("git rev-parse HEAD",{cwd:e}),{stdout:l}=await M("git rev-parse --show-toplevel",{cwd:e}),u=l.trim(),d=At.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 M("git worktree list --porcelain",{cwd:e}),s=n.split(`
1215
+ `):null}catch{return null}}async function zi(t,e,r=100){let n=await l_(t,r),s=n?dt(e):null;if(s?.historyFingerprint===n)return s;let i=await o_(t,r);return n&&(i.historyFingerprint=n),c_(e,i),i}var Cc,Yi,kn=f(()=>{"use strict";Ac();j();pe();a(s_,"parseGitLog");a(i_,"isSourceFile");a(o_,"buildMatrix");a(a_,"pairKey");a(Or,"scoreFromSeeds");Cc="cochange-index",Yi=new Map;a(c_,"saveMatrix");a(dt,"loadMatrix");a(l_,"recentHistoryFingerprint");a(zi,"indexCoChanges")});function u_(t){return t instanceof Rs}function Re(t){return u_(t)||t instanceof Error?t.message:typeof t=="string"?t:"Unknown error"}var Rs,Qi,As,Wt=f(()=>{"use strict";Rs=class extends Error{static{a(this,"PrjctError")}code;isOperational;constructor(e,r="PRJCT_ERROR"){super(e),this.name="PrjctError",this.code=r,this.isOperational=!0,Error.captureStackTrace?.(this,this.constructor)}},Qi=class t extends Rs{static{a(this,"ProjectError")}constructor(e,r="PROJECT_ERROR"){super(e,r),this.name="ProjectError"}static notInitialized(){return new t("Project not initialized. Run p. init first.","PROJECT_NOT_INIT")}static notFound(e){return new t(`Project not found: ${e}`,"PROJECT_NOT_FOUND")}static invalidId(e){return new t(`Invalid project ID: ${e}`,"PROJECT_INVALID_ID")}},As=class t extends Rs{static{a(this,"AgentError")}constructor(e,r="AGENT_ERROR"){super(e,r),this.name="AgentError"}static notSupported(e){return new t(`Unsupported agent type: ${e}`,"AGENT_NOT_SUPPORTED")}static initFailed(e){return new t(`Agent initialization failed: ${e}`,"AGENT_INIT_FAILED")}};a(u_,"isPrjctError");a(Re,"getErrorMessage")});function dg(t){let e=t.toLowerCase();return e.includes("github")?"github":e.includes("gitlab")?"gitlab":e.includes("bitbucket")?"bitbucket":"other"}function Nc(t){let e=t.trim();if(!e)return{};let r=e.match(/^[^/@]+@([^:/]+):(.+?)(?:\.git)?\/?$/);if(r)return{provider:dg(r[1]),repoSlug:r[2]};try{let n=new URL(e),s=n.pathname.replace(/^\/+/,"").replace(/\.git$/,"").replace(/\/+$/,"");return!n.host||!s?{}:{provider:dg(n.host),repoSlug:s}}catch{return{}}}async function d_(t){try{let{stdout:e}=await G("git",["remote","get-url","origin"],{cwd:t});return e.trim()||void 0}catch{return}}async function p_(t){try{let{stdout:e}=await G("git",["symbolic-ref","--short","refs/remotes/origin/HEAD"],{cwd:t});return e.trim().replace(/^origin\//,"")||void 0}catch{return}}function Lr(t){return typeof t=="string"&&t.length>0?t:void 0}function pg(t){return typeof t=="number"&&Number.isFinite(t)?t:void 0}function m_(t){return Object.fromEntries(Object.entries(t).filter(([,e])=>e!==void 0))}async function mg(t){let e=E.getDoc(t,"project")||{},r=Lr(e.repoPath),{provider:n,repoSlug:s}=r?Nc(await d_(r)||""):{},i=r?await p_(r):void 0,o=Array.isArray(e.techStack)?e.techStack.filter(c=>typeof c=="string"):void 0;return m_({provider:n,repoSlug:s,currentBranch:Lr(e.currentBranch),defaultBranch:i,stack:Lr(e.stack),techStack:o&&o.length>0?o:void 0,version:Lr(e.version),commitCount:pg(e.commitCount),fileCount:pg(e.fileCount),lastCommit:Lr(e.lastSyncCommit),hasUncommitted:typeof e.hasUncommittedChanges=="boolean"?e.hasUncommittedChanges:void 0,cliVersion:Lr(e.cliVersion),syncedAt:Lr(e.lastSync)})}var Ic=f(()=>{"use strict";j();pe();a(dg,"providerForHost");a(Nc,"parseRemote");a(d_,"gitRemoteUrl");a(p_,"gitDefaultBranch");a(Lr,"str");a(pg,"num");a(m_,"compact");a(mg,"buildProjectMeta")});import{execFile as g_}from"node:child_process";import f_ from"node:crypto";import{promisify as h_}from"node:util";function k_(t,e=E_){let r=Buffer.from(e.replace(/-/g,""),"hex"),s=f_.createHash("sha1").update(r).update(t,"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 T_(t){let e;try{let{stdout:s}=await y_("git",["remote","get-url","origin"],{cwd:t});e=s.trim()||void 0}catch{return null}if(!e)return null;let{provider:r,repoSlug:n}=Nc(e);return!r||!n?null:`${r}:${n}`.toLowerCase()}async function gg(t){let e=await T_(t);return e?k_(e):null}var y_,E_,fg=f(()=>{"use strict";Ic();y_=h_(g_),E_="6f9b2c1a-3d4e-5f60-8a7b-1c2d3e4f5a6b";a(k_,"uuidv5");a(T_,"repoKey");a(gg,"deriveProjectId")});var Oc={};L(Oc,{PACKAGE_ROOT:()=>gr,VERSION:()=>mr,getPackageRoot:()=>Dc,getVersion:()=>eo,resetPackageRoot:()=>w_});import Pc from"node:fs";import Zi from"node:path";function Dc(){if(Tn)return Tn;let t=__dirname;for(let e=0;e<5;e++){let r=Zi.join(t,"package.json");if(Pc.existsSync(r))try{if(JSON.parse(Pc.readFileSync(r,"utf-8")).name==="prjct-cli")return Tn=t,t}catch{}t=Zi.dirname(t)}return Tn=Zi.join(__dirname,"..","..",".."),Tn}function eo(){if(jr)return jr;let t="3.49.1";if(t&&/^\d+\.\d+\.\d+/.test(t))return jr=t,jr;try{let e=Zi.join(Dc(),"package.json");return jr=JSON.parse(Pc.readFileSync(e,"utf-8")).version,jr}catch(e){return process.env.PRJCT_DEBUG==="1"&&console.error("Failed to read version from package.json:",_(e)),"0.0.0"}}function w_(t){Tn=t,jr=null}var jr,Tn,mr,gr,Bt=f(()=>{"use strict";ne();jr=null,Tn=null;a(Dc,"getPackageRoot");a(eo,"getVersion");a(w_,"resetPackageRoot");mr=eo(),gr=Dc()});async function to(t){try{let{stdout:e}=await M(t,{timeout:5e3});return{success:!0,output:e.trim()}}catch{return{success:!1,output:""}}}async function S_(){let t=await to("gh api user --jq .login");return t.success&&t.output||(t=await to("git config --global github.user"),t.success&&t.output)?t.output:null}async function b_(){let t=await to("git config user.name");return t.success&&t.output?t.output:null}async function v_(){let t=await to("git config user.email");return t.success&&t.output?t.output:null}async function wn(){let[t,e,r]=await Promise.all([S_(),b_(),v_()]);return{github:t,email:r,name:e||t||"Unknown"}}var ro=f(()=>{"use strict";pe();a(to,"execCommand");a(S_,"detectGitHubUsername");a(b_,"detectGitName");a(v_,"detectGitEmail");a(wn,"detect")});var no={};L(no,{worktreeService:()=>__});import jc from"node:fs/promises";import At from"node:path";var hg,Mc,__,so=f(()=>{"use strict";pe();re();hg=".worktrees",Mc=class{static{a(this,"WorktreeService")}async create(e,r,n={}){let s=await this.getMainWorktree(e),i=At.join(s,hg,r),o=n.branch||`feat/${r}`;await jc.mkdir(At.join(s,hg),{recursive:!0});let c=n.baseBranch?` ${n.baseBranch}`:"";await M(`git worktree add "${i}" -b "${o}"${c}`,{cwd:s});let{stdout:l}=await M("git rev-parse HEAD",{cwd:i});return{path:i,branch:o,commit:l.trim(),isMain:!1,slug:r}}async remove(e,r=!1){let n=await this.getMainWorktree(e),s;if(r)try{let{stdout:i}=await M("git rev-parse --abbrev-ref HEAD",{cwd:e});s=i.trim()}catch{}if(await M(`git worktree remove "${e}" --force`,{cwd:n}),r&&s&&s!=="main"&&s!=="master")try{await M(`git branch -D "${s}"`,{cwd:n})}catch{}}async list(e){let r=await this.getMainWorktree(e),{stdout:n}=await M("git worktree list --porcelain",{cwd:r});return this.parsePorcelainOutput(n,r)}async detect(e){try{let{stdout:r}=await M("git rev-parse --git-common-dir",{cwd:e}),{stdout:n}=await M("git rev-parse --git-dir",{cwd:e}),s=At.resolve(e,r.trim()),i=At.resolve(e,n.trim());if(s!==i){let{stdout:o}=await M("git rev-parse --abbrev-ref HEAD",{cwd:e}),{stdout:c}=await M("git rev-parse HEAD",{cwd:e}),{stdout:l}=await M("git rev-parse --show-toplevel",{cwd:e}),u=l.trim(),d=At.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 M("git worktree list --porcelain",{cwd:e}),s=n.split(`
1216
1216
  `)[0];if(s?.startsWith("worktree "))return s.replace("worktree ","").trim()}catch{}let{stdout:r}=await M("git rev-parse --show-toplevel",{cwd:e});return r.trim()}async setup(e,r){let n=At.join(r,".env");await R(n)&&await jc.copyFile(n,At.join(e,".env"));let s=At.join(r,".prjct"),i=At.join(e,".prjct");await R(s)&&!await R(i)&&await jc.symlink(s,i,"dir")}async teardown(e){}async clean(e){let r=await this.list(e),n=[],s=await this.getMainWorktree(e);await M("git worktree prune",{cwd:s});for(let i of r)i.isMain||await R(i.path)||n.push(i.slug);return n}parsePorcelainOutput(e,r){let n=[],s=e.trim().split(`
1217
1217
 
1218
1218
  `);for(let i of s){if(!i.trim())continue;let o=i.trim().split(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prjct-cli",
3
- "version": "3.49.0",
3
+ "version": "3.49.1",
4
4
  "description": "Project memory and workflow context for AI coding agents.",
5
5
  "main": "dist/bin/prjct.mjs",
6
6
  "bin": {