@rulemetric/cli 0.7.37 → 0.7.39

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.
Files changed (36) hide show
  1. package/dist/{chunk-42XJZBQD.js → chunk-6Q4GWZQV.js} +1 -1
  2. package/dist/{chunk-MDPN46EY.js → chunk-6QKI756T.js} +1 -1
  3. package/dist/{chunk-XA4KSQEC.js → chunk-G6XGDHGC.js} +1 -1
  4. package/dist/{chunk-3HSEVXMQ.js → chunk-GWDZNGUP.js} +1 -1
  5. package/dist/{chunk-IYDADY62.js → chunk-PBPNIKQA.js} +1 -1
  6. package/dist/{chunk-7SI6KWSX.js → chunk-QV4A73AC.js} +1 -1
  7. package/dist/chunk-QXPYGN7I.js +1 -0
  8. package/dist/chunk-SHYP27B7.js +2 -0
  9. package/dist/{chunk-JIJKIPE6.js → chunk-TYL5LNTJ.js} +1 -1
  10. package/dist/{chunk-BUWWFHGO.js → chunk-W2MOTOQE.js} +1 -1
  11. package/dist/{chunk-CRIFP3QP.js → chunk-WFYQ6SPJ.js} +1 -1
  12. package/dist/commands/capture/scope.js +2 -2
  13. package/dist/commands/diagnostics.js +1 -1
  14. package/dist/commands/evals/agent.js +1 -1
  15. package/dist/commands/hooks/run.js +3 -3
  16. package/dist/commands/sessions/delete.js +1 -0
  17. package/dist/commands/sessions/list.js +1 -1
  18. package/dist/dashboard/Dashboard.js +1 -1
  19. package/dist/dashboard/data.js +1 -1
  20. package/dist/dashboard/launcher/LauncherOverlay.js +1 -1
  21. package/dist/{dist-BC6GMBXV.js → dist-FAVALJ5C.js} +1 -1
  22. package/dist/lib/agent-loop.js +1 -1
  23. package/dist/lib/capture-scope-config.js +1 -1
  24. package/dist/lib/codex-capture-scope.js +1 -1
  25. package/dist/lib/handlers/process-announcement.js +1 -1
  26. package/dist/lib/handlers/process-insights.js +1 -1
  27. package/dist/lib/handlers/process-launch.js +1 -1
  28. package/dist/lib/handlers/process-run-cleanup.js +1 -1
  29. package/dist/lib/hooks-capture-gate.js +1 -0
  30. package/dist/lib/transcript-sync.js +1 -1
  31. package/dist/lib/worktree.js +1 -1
  32. package/oclif.manifest.json +74 -5
  33. package/package.json +6 -6
  34. package/dist/chunk-RUZ36O55.js +0 -2
  35. package/dist/chunk-VX2GJCQ4.js +0 -1
  36. /package/dist/{chunk-5DIOZDDZ.js → chunk-7DFNBRLY.js} +0 -0
@@ -1 +1 @@
1
- import{a as j}from"./chunk-RDET7CKR.js";import{b as I,c as P,d as v}from"./chunk-ZR3MUNLS.js";import{a as E}from"./chunk-X23L2MF6.js";import{a as J}from"./chunk-B22HYCBV.js";import{d as T}from"./chunk-NJ5UED3H.js";import{a as b}from"./chunk-ZLLER3HP.js";import{useEffect as R,useState as i}from"react";import{Box as l,Text as s,useInput as Z}from"ink";import{jsx as t,jsxs as a}from"react/jsx-runtime";function K({onClose:A,activeOrg:F,defaultProjectPath:y,width:_}){let{jobs:u,error:L,loading:$,refetch:S}=j(20),[M,C]=i([]),[d,m]=i("list"),[f,w]=i(0),[h,g]=i(null),[x,B]=i(null),[p,c]=i(null);R(()=>{v().then(C).catch(o=>{let r=o instanceof Error?o.message:String(o);c(`couldn't load launchers: ${r}`),C([{tool:"claude_code",capabilities:{headless:!0,interactive:!0,remoteSpawn:!0}}])})},[]),R(()=>{if(!p)return;let o=setTimeout(()=>c(null),5e3);return()=>clearTimeout(o)},[p]),Z((o,r)=>{if(h){if(o==="y"||o==="Y"){let e=h.id;g(null),P(e).then(()=>{S(),c(`cancelled ${e.slice(0,8)}`)}).catch(n=>c(`cancel failed: ${n instanceof Error?n.message:String(n)}`))}else(o==="n"||o==="N"||r.escape)&&g(null);return}if(r.escape){if(d!=="none"){m("none");return}A();return}if(r.tab){m(e=>e==="list"?"form":e==="form"?"none":"list");return}if(o!=="q"&&d==="list"){if(r.upArrow)w(e=>Math.max(0,e-1));else if(r.downArrow)w(e=>Math.min(u.length-1,e+1));else if(o==="c"){let e=u[f];e&&(e.status==="running"||e.status==="queued"||e.status==="pending")&&g(e)}else if(o==="r"){let e=u[f],n=e?.result?.externalSessionId;e&&e.tool==="claude_code"&&n?(B({tool:"claude_code",projectPath:e.config.projectPath,resumeSessionId:n}),m("form")):c("resume needs a Claude Code session with a session id")}else if(o==="o"){let n=u[f]?.result?.externalSessionId;if(n){let O=process.env.RULEMETRIC_WEB_URL??"http://localhost:5174";import("node:child_process").then(({spawn:U})=>{U("open",[`${O}/sessions/${n}`],{detached:!0,stdio:"ignore"}).unref()})}}}});async function N(o){await I(o),B(null),m("list"),c("launched"),S()}return b(N,"handleSubmit"),a(l,{flexDirection:"column",borderStyle:"round",borderColor:T,width:_,paddingX:1,children:[a(l,{children:[t(s,{bold:!0,color:T,children:"Launcher"}),t(s,{dimColor:!0,children:" active org: "}),t(s,{children:F??"(none)"}),$&&t(s,{dimColor:!0,children:" loading\u2026"}),L&&a(s,{color:"#F55B5B",children:[" \u26A0 ",L]})]}),t(l,{marginTop:1,children:t(E,{jobs:u,selectedIndex:f,focused:d==="list"})}),t(l,{marginTop:1,children:t(J,{launchers:M,defaultProjectPath:x?.projectPath??y,defaultTool:x?.tool,defaultResumeSessionId:x?.resumeSessionId,focused:d==="form",onSubmit:N})}),h&&t(l,{marginTop:1,children:a(s,{color:"#FFD700",children:["Cancel job ",h.id.slice(0,8),"? (y/n)"]})}),p&&t(l,{marginTop:1,children:a(s,{dimColor:!0,children:["\xB7 ",p]})}),t(l,{marginTop:1,children:a(s,{dimColor:!0,children:["\u2191\u2193 select tab focus c cancel r resume o open esc ",d==="none"?"close":"back"]})})]})}b(K,"LauncherOverlay");export{K as a};
1
+ import{a as J}from"./chunk-B22HYCBV.js";import{a as j}from"./chunk-RDET7CKR.js";import{b as I,c as P,d as v}from"./chunk-ZR3MUNLS.js";import{a as E}from"./chunk-X23L2MF6.js";import{d as T}from"./chunk-NJ5UED3H.js";import{a as b}from"./chunk-ZLLER3HP.js";import{useEffect as R,useState as i}from"react";import{Box as l,Text as s,useInput as Z}from"ink";import{jsx as t,jsxs as a}from"react/jsx-runtime";function K({onClose:A,activeOrg:F,defaultProjectPath:y,width:_}){let{jobs:u,error:L,loading:$,refetch:S}=j(20),[M,C]=i([]),[d,m]=i("list"),[f,w]=i(0),[h,g]=i(null),[x,B]=i(null),[p,c]=i(null);R(()=>{v().then(C).catch(o=>{let r=o instanceof Error?o.message:String(o);c(`couldn't load launchers: ${r}`),C([{tool:"claude_code",capabilities:{headless:!0,interactive:!0,remoteSpawn:!0}}])})},[]),R(()=>{if(!p)return;let o=setTimeout(()=>c(null),5e3);return()=>clearTimeout(o)},[p]),Z((o,r)=>{if(h){if(o==="y"||o==="Y"){let e=h.id;g(null),P(e).then(()=>{S(),c(`cancelled ${e.slice(0,8)}`)}).catch(n=>c(`cancel failed: ${n instanceof Error?n.message:String(n)}`))}else(o==="n"||o==="N"||r.escape)&&g(null);return}if(r.escape){if(d!=="none"){m("none");return}A();return}if(r.tab){m(e=>e==="list"?"form":e==="form"?"none":"list");return}if(o!=="q"&&d==="list"){if(r.upArrow)w(e=>Math.max(0,e-1));else if(r.downArrow)w(e=>Math.min(u.length-1,e+1));else if(o==="c"){let e=u[f];e&&(e.status==="running"||e.status==="queued"||e.status==="pending")&&g(e)}else if(o==="r"){let e=u[f],n=e?.result?.externalSessionId;e&&e.tool==="claude_code"&&n?(B({tool:"claude_code",projectPath:e.config.projectPath,resumeSessionId:n}),m("form")):c("resume needs a Claude Code session with a session id")}else if(o==="o"){let n=u[f]?.result?.externalSessionId;if(n){let O=process.env.RULEMETRIC_WEB_URL??"http://localhost:5174";import("node:child_process").then(({spawn:U})=>{U("open",[`${O}/sessions/${n}`],{detached:!0,stdio:"ignore"}).unref()})}}}});async function N(o){await I(o),B(null),m("list"),c("launched"),S()}return b(N,"handleSubmit"),a(l,{flexDirection:"column",borderStyle:"round",borderColor:T,width:_,paddingX:1,children:[a(l,{children:[t(s,{bold:!0,color:T,children:"Launcher"}),t(s,{dimColor:!0,children:" active org: "}),t(s,{children:F??"(none)"}),$&&t(s,{dimColor:!0,children:" loading\u2026"}),L&&a(s,{color:"#F55B5B",children:[" \u26A0 ",L]})]}),t(l,{marginTop:1,children:t(E,{jobs:u,selectedIndex:f,focused:d==="list"})}),t(l,{marginTop:1,children:t(J,{launchers:M,defaultProjectPath:x?.projectPath??y,defaultTool:x?.tool,defaultResumeSessionId:x?.resumeSessionId,focused:d==="form",onSubmit:N})}),h&&t(l,{marginTop:1,children:a(s,{color:"#FFD700",children:["Cancel job ",h.id.slice(0,8),"? (y/n)"]})}),p&&t(l,{marginTop:1,children:a(s,{dimColor:!0,children:["\xB7 ",p]})}),t(l,{marginTop:1,children:a(s,{dimColor:!0,children:["\u2191\u2193 select tab focus c cancel r resume o open esc ",d==="none"?"close":"back"]})})]})}b(K,"LauncherOverlay");export{K as a};
@@ -1,2 +1,2 @@
1
- import{y as w}from"./chunk-5DIOZDDZ.js";import{a as m}from"./chunk-N7ODX6PO.js";import{a as s}from"./chunk-ZLLER3HP.js";import{spawn as g}from"node:child_process";import d from"node:fs";import b from"node:path";function c(e,t){return new Promise((r,n)=>{let o=g("git",e,{cwd:t,stdio:["ignore","pipe","pipe"],env:m()}),i="",f="";o.stdout.on("data",a=>{i+=a.toString()}),o.stderr.on("data",a=>{f+=a.toString()}),o.on("error",a=>n(new Error(`git ${e.join(" ")} failed to spawn: ${a.message}`))),o.on("close",a=>{a===0?r({code:a,stdout:i,stderr:f}):n(new Error(`git ${e.join(" ")} exited ${a}: ${f.trim()||i.trim()}`))})})}s(c,"runGit");async function k(e,t){if(!t||!t.trim())throw new Error('invalid branch name "": branch must be a non-empty git refname');if(t.startsWith("-"))throw new Error(`invalid branch name "${t}": must not start with "-" (git would parse it as an option)`);if(/\s/.test(t))throw new Error(`invalid branch name "${t}": must not contain whitespace`);try{await c(["check-ref-format","--branch",t],e)}catch{throw new Error(`invalid branch name "${t}": not a valid git refname`)}}s(k,"assertValidBranch");function h(e){let t=b.resolve(e);try{return d.realpathSync(t)}catch{return t}}s(h,"canonical");function y(e){let t=[],r=null;for(let n of e.split(`
1
+ import{y as w}from"./chunk-7DFNBRLY.js";import{a as m}from"./chunk-N7ODX6PO.js";import{a as s}from"./chunk-ZLLER3HP.js";import{spawn as g}from"node:child_process";import d from"node:fs";import b from"node:path";function c(e,t){return new Promise((r,n)=>{let o=g("git",e,{cwd:t,stdio:["ignore","pipe","pipe"],env:m()}),i="",f="";o.stdout.on("data",a=>{i+=a.toString()}),o.stderr.on("data",a=>{f+=a.toString()}),o.on("error",a=>n(new Error(`git ${e.join(" ")} failed to spawn: ${a.message}`))),o.on("close",a=>{a===0?r({code:a,stdout:i,stderr:f}):n(new Error(`git ${e.join(" ")} exited ${a}: ${f.trim()||i.trim()}`))})})}s(c,"runGit");async function k(e,t){if(!t||!t.trim())throw new Error('invalid branch name "": branch must be a non-empty git refname');if(t.startsWith("-"))throw new Error(`invalid branch name "${t}": must not start with "-" (git would parse it as an option)`);if(/\s/.test(t))throw new Error(`invalid branch name "${t}": must not contain whitespace`);try{await c(["check-ref-format","--branch",t],e)}catch{throw new Error(`invalid branch name "${t}": not a valid git refname`)}}s(k,"assertValidBranch");function h(e){let t=b.resolve(e);try{return d.realpathSync(t)}catch{return t}}s(h,"canonical");function y(e){let t=[],r=null;for(let n of e.split(`
2
2
  `))n.startsWith("worktree ")?(r&&t.push(r),r={path:n.slice(9).trim()}):n.startsWith("branch ")&&r&&(r.branch=n.slice(7).trim().replace(/^refs\/heads\//,""));return r&&t.push(r),t}s(y,"parseWorktreeList");async function v(e,t){try{return await c(["show-ref","--verify","--quiet",`refs/heads/${t}`],e),!0}catch{return!1}}s(v,"branchExists");async function B(e){let{repoRoot:t,branch:r,baseRef:n,allowExistingBranch:o=!1}=e;await k(t,r);let i=w({repoRoot:t,branch:r,basePath:e.basePath}),f=await c(["worktree","list","--porcelain"],t),a=y(f.stdout),p=a.find(u=>u.branch===r);if(p)return{path:h(p.path),branch:r,created:!1};let l=a.find(u=>h(u.path)===i);if(l)return{path:h(l.path),branch:l.branch??r,created:!1};if(await v(t,r)){if(!o)throw new Error(`branch "${r}" already exists with no worktree; refusing to clobber (pass allowExistingBranch:true to attach a worktree onto it)`);return await c(["worktree","add",i,r],t),{path:h(i),branch:r,created:!0}}return await c(["worktree","add",i,"-b",r,n],t),{path:h(i),branch:r,created:!0}}s(B,"ensureWorktree");async function S(e){let{repoRoot:t,worktreePath:r}=e;if(!d.existsSync(r))return{removed:!1,reason:"absent"};let n=!1;try{n=(await c(["status","--porcelain"],r)).stdout.trim().length>0}catch{n=!1}if(n)return{removed:!1,reason:"dirty"};try{return await c(["worktree","remove",r],t),{removed:!0}}catch(o){let i=o instanceof Error?o.message:String(o);if(/not a working tree|No such file or directory|not a valid path|is not a working tree/i.test(i))return{removed:!1,reason:"absent"};throw o}}s(S,"removeWorktree");export{c as a,B as b,S as c};
@@ -1,2 +1,2 @@
1
- import{c as E,o as m}from"./chunk-5DIOZDDZ.js";import{a as d}from"./chunk-H2ORWIEY.js";import{a as c}from"./chunk-ZLLER3HP.js";import*as p from"node:fs";import*as u from"node:path";import*as _ from"node:os";function T(){if(process.env.RULEMETRIC_API_KEY||process.env.RULEMETRIC_ACCESS_TOKEN)return;let s=u.join(_.homedir(),".config","rulemetric","env");C(s)||C(u.join(process.cwd(),".env.local"))}c(T,"ensureEnv");function C(s){try{let t=p.readFileSync(s,"utf-8");for(let n of t.split(`
1
+ import{c as E,o as m}from"./chunk-7DFNBRLY.js";import{a as d}from"./chunk-H2ORWIEY.js";import{a as c}from"./chunk-ZLLER3HP.js";import*as p from"node:fs";import*as u from"node:path";import*as _ from"node:os";function T(){if(process.env.RULEMETRIC_API_KEY||process.env.RULEMETRIC_ACCESS_TOKEN)return;let s=u.join(_.homedir(),".config","rulemetric","env");C(s)||C(u.join(process.cwd(),".env.local"))}c(T,"ensureEnv");function C(s){try{let t=p.readFileSync(s,"utf-8");for(let n of t.split(`
2
2
  `)){let e=n.trim();if(!e||e.startsWith("#"))continue;let o=e.indexOf("=");if(o<0)continue;let r=e.slice(0,o).trim(),i=e.slice(o+1).trim();process.env[r]||(process.env[r]=i)}return!!(process.env.RULEMETRIC_API_KEY||process.env.RULEMETRIC_ACCESS_TOKEN)}catch{return!1}}c(C,"loadEnvFile");T();async function I(s){let t={totalSessions:0,totalCalls:0,totalInputTokens:0,totalOutputTokens:0,totalCacheReadTokens:0,totalCacheWriteTokens:0,totalCostUSD:0,providers:{}},n=await m(s);t.providers={};for(let a of n)t.providers[a.provider]=(t.providers[a.provider]||0)+1;let e=new E,o=n.filter(a=>a.provider==="claude");for(let a of o)try{let h=p.readdirSync(a.path).filter(f=>f.endsWith(".jsonl"));t.totalSessions+=h.length;for(let f of h){let v=p.readFileSync(u.join(a.path,f),"utf-8"),R=e.parse(v);for(let l of R.events)l.tokenUsage&&(t.totalCalls++,t.totalInputTokens+=l.tokenUsage.input,t.totalOutputTokens+=l.tokenUsage.output,t.totalCacheReadTokens+=l.tokenUsage.cacheRead??0,t.totalCacheWriteTokens+=l.tokenUsage.cacheWrite??0)}}catch{}let r=15,i=75;return t.totalCostUSD=Math.round((t.totalInputTokens/1e6*r+t.totalOutputTokens/1e6*i+t.totalCacheReadTokens/1e6*(r*.1)+t.totalCacheWriteTokens/1e6*(r*1.25))*100)/100,t}c(I,"loadLocalStats");async function U(s){let t=process.env.RULEMETRIC_API_URL??d,n=process.env.RULEMETRIC_API_KEY,e=process.env.RULEMETRIC_ACCESS_TOKEN,o=n??e;if(!o)return null;let r=new URLSearchParams;s&&r.set("projectPath",s);try{let i=await fetch(`${t}/api/insights/compute?${r}`,{headers:{Authorization:`Bearer ${o}`},signal:AbortSignal.timeout(5e3)});return i.ok?await i.json():null}catch{return null}}c(U,"loadApiInsights");async function g(s){let t=process.env.RULEMETRIC_API_URL??d,n=process.env.RULEMETRIC_API_KEY??process.env.RULEMETRIC_ACCESS_TOKEN;if(!n)return null;let e=new URLSearchParams;s&&e.set("projectPath",s);try{let o=await fetch(`${t}/api/insights/linked-instructions?${e}`,{headers:{Authorization:`Bearer ${n}`},signal:AbortSignal.timeout(5e3)});return o.ok?await o.json():null}catch{return null}}c(g,"loadLinkedInstructions");export{I as a,U as b,g as c};
@@ -1,2 +1,2 @@
1
- import{c as f}from"./chunk-VX2GJCQ4.js";import{a as o}from"./chunk-ZLLER3HP.js";import{createHash as w}from"node:crypto";import{mkdir as x,open as P,readFile as S,readdir as M,rename as C,stat as b,writeFile as _}from"node:fs/promises";import{homedir as A}from"node:os";import{basename as z,dirname as F,join as l}from"node:path";var $=3e4,E=5,I=8*1024*1024;function g(n){return w("sha256").update(`${n.externalSessionId}:${Math.round(n.mtimeMs)}:${n.size}`).digest("hex")}o(g,"fingerprint");async function k(n){try{return{fingerprints:JSON.parse(await S(n,"utf8")).fingerprints??{}}}catch{return{fingerprints:{}}}}o(k,"readState");async function O(n,i){let r=`${n}.${process.pid}.tmp`;await x(F(n),{recursive:!0}),await _(r,JSON.stringify(i)),await C(r,n)}o(O,"persistState");var h=class{constructor(i){this.options=i}static{o(this,"TranscriptSync")}lastSeenSize=new Map;lastSyncAt=new Map;inFlight=!1;async scan(){if(this.inFlight)return{discovered:0,imported:0,skipped:0};this.inFlight=!0;try{let i=await k(this.options.statePath),r=(await Promise.all(this.options.providers.map(t=>t.discover()))).flat().sort((t,p)=>p.mtimeMs-t.mtimeMs),s=Date.now(),e=[],a=0;for(let t of r){let p=g(t),d=this.lastSeenSize.get(t.path);if(this.lastSeenSize.set(t.path,t.size),i.fingerprints[t.path]===p){a++;continue}let m=this.options.minStableAgeMs??3e3;if(m>0&&s-t.mtimeMs<m){a++;continue}let v=d!==void 0&&d===t.size,u=this.lastSyncAt.get(t.path),T=u===void 0||s-u>=(this.options.activeResyncMs??$);if(!v&&!T){a++;continue}if(e.push(t),e.length>=(this.options.maxImportsPerScan??E))break}let c=0;for(let t of e){let p=g(t);if(t.size>(this.options.maxContentBytes??I)){i.fingerprints[t.path]=p,a++,this.options.log?.(`Transcript sync skipped oversized file: ${t.path}`);continue}let d=await S(t.path,"utf8");await this.options.importTranscript({content:d,tool:t.tool}),i.fingerprints[t.path]=p,this.lastSyncAt.set(t.path,Date.now()),c++,this.options.log?.(`Transcript sync imported ${t.tool} ${z(t.path)} (${t.externalSessionId}).`)}return e.length>0&&await O(this.options.statePath,i),{discovered:r.length,imported:c,skipped:a}}finally{this.inFlight=!1}}};async function D(n){let i;try{i=await P(n,"r");let r=Buffer.alloc(64*1024),{bytesRead:s}=await i.read(r,0,r.length,0),e=r.subarray(0,s).toString("utf8").split(`
1
+ import{d as f}from"./chunk-QXPYGN7I.js";import{a as o}from"./chunk-ZLLER3HP.js";import{createHash as w}from"node:crypto";import{mkdir as x,open as P,readFile as S,readdir as M,rename as C,stat as b,writeFile as _}from"node:fs/promises";import{homedir as A}from"node:os";import{basename as z,dirname as F,join as l}from"node:path";var $=3e4,E=5,I=8*1024*1024;function g(n){return w("sha256").update(`${n.externalSessionId}:${Math.round(n.mtimeMs)}:${n.size}`).digest("hex")}o(g,"fingerprint");async function k(n){try{return{fingerprints:JSON.parse(await S(n,"utf8")).fingerprints??{}}}catch{return{fingerprints:{}}}}o(k,"readState");async function O(n,i){let r=`${n}.${process.pid}.tmp`;await x(F(n),{recursive:!0}),await _(r,JSON.stringify(i)),await C(r,n)}o(O,"persistState");var h=class{constructor(i){this.options=i}static{o(this,"TranscriptSync")}lastSeenSize=new Map;lastSyncAt=new Map;inFlight=!1;async scan(){if(this.inFlight)return{discovered:0,imported:0,skipped:0};this.inFlight=!0;try{let i=await k(this.options.statePath),r=(await Promise.all(this.options.providers.map(t=>t.discover()))).flat().sort((t,p)=>p.mtimeMs-t.mtimeMs),s=Date.now(),e=[],a=0;for(let t of r){let p=g(t),d=this.lastSeenSize.get(t.path);if(this.lastSeenSize.set(t.path,t.size),i.fingerprints[t.path]===p){a++;continue}let m=this.options.minStableAgeMs??3e3;if(m>0&&s-t.mtimeMs<m){a++;continue}let v=d!==void 0&&d===t.size,u=this.lastSyncAt.get(t.path),T=u===void 0||s-u>=(this.options.activeResyncMs??$);if(!v&&!T){a++;continue}if(e.push(t),e.length>=(this.options.maxImportsPerScan??E))break}let c=0;for(let t of e){let p=g(t);if(t.size>(this.options.maxContentBytes??I)){i.fingerprints[t.path]=p,a++,this.options.log?.(`Transcript sync skipped oversized file: ${t.path}`);continue}let d=await S(t.path,"utf8");await this.options.importTranscript({content:d,tool:t.tool}),i.fingerprints[t.path]=p,this.lastSyncAt.set(t.path,Date.now()),c++,this.options.log?.(`Transcript sync imported ${t.tool} ${z(t.path)} (${t.externalSessionId}).`)}return e.length>0&&await O(this.options.statePath,i),{discovered:r.length,imported:c,skipped:a}}finally{this.inFlight=!1}}};async function D(n){let i;try{i=await P(n,"r");let r=Buffer.alloc(64*1024),{bytesRead:s}=await i.read(r,0,r.length,0),e=r.subarray(0,s).toString("utf8").split(`
2
2
  `)[0];return e?JSON.parse(e):null}catch{return null}finally{await i?.close()}}o(D,"readFirstJsonLine");async function y(n,i,r){let s=await M(n,{withFileTypes:!0}).catch(()=>[]);for(let e of s){let a=l(n,e.name);if(e.isDirectory()){await y(a,i,r);continue}if(!e.isFile()||!e.name.startsWith("rollout-")||!e.name.endsWith(".jsonl"))continue;let[c,t]=await Promise.all([b(a).catch(()=>null),D(a)]);if(!c||c.mtimeMs<r||t?.type!=="session_meta")continue;let p=t.payload?.originator,d=t.payload?.id??t.payload?.session_id;!p?.toLowerCase().startsWith("codex")||!d||i.push({path:a,tool:"codex",externalSessionId:d,projectPath:t.payload?.cwd??null,mtimeMs:c.mtimeMs,size:c.size})}}o(y,"walkCodexSessions");function J(n=process.env.CODEX_HOME??l(A(),".codex"),i=14,r){return{name:"codex",async discover(){let s=typeof r=="function"?await r():r;if(s.mode==="off")return[];let e=[],a=Date.now()-Math.max(1,i)*24*60*60*1e3;return await y(l(n,"sessions"),e,a),s.mode==="all"?e:e.filter(c=>f(s,c.projectPath))}}}o(J,"createCodexTranscriptProvider");function U(n,i){let r=o(async()=>{try{let e=await n.scan();e.imported>0&&i.log?.(`Transcript sync imported/updated ${e.imported} session${e.imported===1?"":"s"}.`)}catch(e){i.log?.(`Transcript sync failed: ${e instanceof Error?e.message:String(e)}`)}},"run"),s=setInterval(()=>void r(),i.intervalMs??3e4);i.signal.addEventListener("abort",()=>clearInterval(s),{once:!0}),r()}o(U,"startTranscriptSync");export{h as a,J as b,U as c};
@@ -1 +1 @@
1
- import{c as C}from"./chunk-TIOKY2IA.js";import{a as H}from"./chunk-ZYVWALMS.js";import{a as A}from"./chunk-NKPLTT7J.js";import{a as E}from"./chunk-HUADECKZ.js";import{a as I}from"./chunk-7SI6KWSX.js";import{a as x}from"./chunk-H7J27U4P.js";import{b as S}from"./chunk-BUWWFHGO.js";import{a as M}from"./chunk-IQTSUAGM.js";import{a as L}from"./chunk-CRIFP3QP.js";import{a as y}from"./chunk-RSKQRVPJ.js";import{a as P}from"./chunk-SWSGNEVO.js";import{a as N}from"./chunk-BPQ66YTY.js";import{a as k}from"./chunk-UF6US7VU.js";import{b as _}from"./chunk-SNJ2NIIE.js";import{b as R}from"./chunk-IXLDCX7M.js";import{a as T}from"./chunk-JIJKIPE6.js";import{b as h}from"./chunk-5RBLIVBF.js";import{j as b}from"./chunk-ZYI66XKV.js";import{d as w}from"./chunk-NTKO4H2K.js";import{b as f,e as v,f as p}from"./chunk-H2ORWIEY.js";import{a as s}from"./chunk-ZLLER3HP.js";var W={process_eval:E,process_insights:I,process_launch:S,process_send_message:y,process_conversation:A,process_session_goal:H,distill_memories:R,memory_ab:M,process_announcement:T,process_run_cleanup:L,cron_suggest_instructions:_,cron_refresh_skills:k,cron_refresh_pricing:N,cron_eval_autorun:P,cron_instruction_evolution:b,process_judge_review:x},D=Object.keys(W),F=new Set(["process_announcement","process_run_cleanup","memory_ab"]);function J(e=process.env){return e.DATABASE_URL?D:D.filter(n=>!F.has(n))}s(J,"availableCapabilities");var U=3e4,K=3e4,G=3e4,V=250,B=5e3,q=`thin-agent-${process.pid}`,g=null;function Q(e,n,r,l){let c;try{let d=w();c={claude:d.claudeBin!=null,codex:d.codexBin!=null,codexModel:d.codexConfiguredModel}}catch{}let i=s(d=>{p("/api/workers/heartbeat",{workerType:"cli-worker",clientName:q,clientVersion:l,workerVersion:"0.1.0",currentJobId:null,inFlightCount:0,lastError:null,status:d,metadata:{capabilities:e,mode:"thin-agent",llmEngines:c}}).then(u=>{let t=u?.advisory;t&&t.message!==g?(g=t.message,a(r,{event:"worker_advisory",code:t.code,message:t.message})):t||(g=null)}).catch(u=>{a(r,{event:"presence_heartbeat_error",error:u instanceof Error?u.message:String(u)})})},"send");i("alive");let o=setInterval(()=>i("alive"),G);n.addEventListener("abort",()=>{clearInterval(o),i("shutting_down")},{once:!0})}s(Q,"startPresenceHeartbeat");function a(e,n){try{e(JSON.stringify({ts:new Date().toISOString(),...n}))}catch{e(`[agent-loop] log_error event=${n.event}`)}}s(a,"structuredLog");function O(e,n){return n.aborted?Promise.resolve(!1):e<=0?Promise.resolve(!0):new Promise(r=>{let l=setTimeout(()=>{n.removeEventListener("abort",c),r(!0)},e),c=s(()=>{clearTimeout(l),n.removeEventListener("abort",c),r(!1)},"onAbort");n.addEventListener("abort",c,{once:!0})})}s(O,"abortableSleep");async function X(e,n){let r=`capabilities=${encodeURIComponent(e.join(","))}&waitMs=${n}`,l=await v(`/api/work/next?${r}`);return l==null||typeof l=="string"?null:l}s(X,"pollForWork");function z(e,n){return{logger:{info:s(r=>n(r),"info"),warn:s(r=>n(r),"warn"),error:s(r=>n(r),"error")},job:{attempts:e}}}s(z,"makeHelpers");async function Y(e,n,r){let l=W[e.kind],c=Date.now();if(a(r,{event:"claim",jobId:e.id,kind:e.kind,attempts:e.attempts}),!l){let o=`unknown kind: ${e.kind}`;a(r,{event:"fail",jobId:e.id,kind:e.kind,terminal:!0,error:o}),await p(`/api/work/${e.id}/fail`,{leaseToken:e.leaseToken,error:o,terminal:!0}).catch(()=>{});return}let i=setInterval(()=>{a(r,{event:"heartbeat",jobId:e.id}),p(`/api/work/${e.id}/heartbeat`,{leaseToken:e.leaseToken}).catch(o=>{a(r,{event:"heartbeat_error",jobId:e.id,error:o instanceof Error?o.message:String(o)})})},n);try{let o=z(e.attempts,r),d=await l(e.payload,o)??{};clearInterval(i),a(r,{event:"complete",jobId:e.id,kind:e.kind,durationMs:Date.now()-c}),await p(`/api/work/${e.id}/complete`,{leaseToken:e.leaseToken,result:d})}catch(o){clearInterval(i);let d=h(o),u=o instanceof Error?o.message:String(o);a(r,{event:"fail",jobId:e.id,kind:e.kind,durationMs:Date.now()-c,terminal:d,error:u}),await p(`/api/work/${e.id}/fail`,{leaseToken:e.leaseToken,error:u,terminal:d}).catch(t=>{a(r,{event:"fail_post_error",jobId:e.id,error:t instanceof Error?t.message:String(t)})})}}s(Y,"runOne");async function we(e){let n=e.log??(()=>{}),r=e.pollWaitMs??U,l=e.heartbeatIntervalMs??K,c=e.capabilities??J(),i=V;a(n,{event:"agent_start",capabilities:c,pollWaitMs:r,heartbeatIntervalMs:l}),Q(c,e.signal,n,e.version),C({signal:e.signal,log:n}).catch(t=>{a(n,{event:"tt_heartbeat_fatal",error:t instanceof Error?t.message:String(t)})});let o=5*6e4,d=0,u=s(()=>{if(!e.readInstalledVersion||!e.version)return!1;let t=Date.now();if(t-d<o)return!1;d=t;let m=e.readInstalledVersion();return!!(m&&m!==e.version)},"versionDrifted");for(;!e.signal.aborted;){if(u()){a(n,{event:"agent_version_drift",bootVersion:e.version,installedVersion:e.readInstalledVersion?.()??null}),e.onVersionDrift?.();break}let t=null;try{t=await X(c,r)}catch(m){let $=m instanceof f?m.statusCode:void 0;if(a(n,{event:"poll_error",status:$,error:m instanceof Error?m.message:String(m)}),!await O(i,e.signal))break;i=Math.min(i*2,B);continue}if(!t){if(a(n,{event:"poll_204"}),!await O(i,e.signal))break;i=Math.min(i*2,B);continue}i=V,await Y(t,l,n)}a(n,{event:"agent_stop"})}s(we,"runAgentLoop");export{W as a,D as b,J as c,X as d,we as e};
1
+ import{c as C}from"./chunk-TIOKY2IA.js";import{a as y}from"./chunk-RSKQRVPJ.js";import{a as H}from"./chunk-ZYVWALMS.js";import{a as A}from"./chunk-NKPLTT7J.js";import{a as E}from"./chunk-HUADECKZ.js";import{a as I}from"./chunk-QV4A73AC.js";import{a as x}from"./chunk-H7J27U4P.js";import{b as S}from"./chunk-W2MOTOQE.js";import{a as M}from"./chunk-IQTSUAGM.js";import{a as L}from"./chunk-WFYQ6SPJ.js";import{a as P}from"./chunk-SWSGNEVO.js";import{a as N}from"./chunk-BPQ66YTY.js";import{a as k}from"./chunk-UF6US7VU.js";import{b as _}from"./chunk-SNJ2NIIE.js";import{b as R}from"./chunk-IXLDCX7M.js";import{a as T}from"./chunk-TYL5LNTJ.js";import{b as h}from"./chunk-5RBLIVBF.js";import{j as b}from"./chunk-ZYI66XKV.js";import{d as w}from"./chunk-NTKO4H2K.js";import{b as f,e as v,f as p}from"./chunk-H2ORWIEY.js";import{a as s}from"./chunk-ZLLER3HP.js";var W={process_eval:E,process_insights:I,process_launch:S,process_send_message:y,process_conversation:A,process_session_goal:H,distill_memories:R,memory_ab:M,process_announcement:T,process_run_cleanup:L,cron_suggest_instructions:_,cron_refresh_skills:k,cron_refresh_pricing:N,cron_eval_autorun:P,cron_instruction_evolution:b,process_judge_review:x},D=Object.keys(W),F=new Set(["process_announcement","process_run_cleanup","memory_ab"]);function J(e=process.env){return e.DATABASE_URL?D:D.filter(n=>!F.has(n))}s(J,"availableCapabilities");var U=3e4,K=3e4,G=3e4,V=250,B=5e3,q=`thin-agent-${process.pid}`,g=null;function Q(e,n,r,l){let c;try{let d=w();c={claude:d.claudeBin!=null,codex:d.codexBin!=null,codexModel:d.codexConfiguredModel}}catch{}let i=s(d=>{p("/api/workers/heartbeat",{workerType:"cli-worker",clientName:q,clientVersion:l,workerVersion:"0.1.0",currentJobId:null,inFlightCount:0,lastError:null,status:d,metadata:{capabilities:e,mode:"thin-agent",llmEngines:c}}).then(u=>{let t=u?.advisory;t&&t.message!==g?(g=t.message,a(r,{event:"worker_advisory",code:t.code,message:t.message})):t||(g=null)}).catch(u=>{a(r,{event:"presence_heartbeat_error",error:u instanceof Error?u.message:String(u)})})},"send");i("alive");let o=setInterval(()=>i("alive"),G);n.addEventListener("abort",()=>{clearInterval(o),i("shutting_down")},{once:!0})}s(Q,"startPresenceHeartbeat");function a(e,n){try{e(JSON.stringify({ts:new Date().toISOString(),...n}))}catch{e(`[agent-loop] log_error event=${n.event}`)}}s(a,"structuredLog");function O(e,n){return n.aborted?Promise.resolve(!1):e<=0?Promise.resolve(!0):new Promise(r=>{let l=setTimeout(()=>{n.removeEventListener("abort",c),r(!0)},e),c=s(()=>{clearTimeout(l),n.removeEventListener("abort",c),r(!1)},"onAbort");n.addEventListener("abort",c,{once:!0})})}s(O,"abortableSleep");async function X(e,n){let r=`capabilities=${encodeURIComponent(e.join(","))}&waitMs=${n}`,l=await v(`/api/work/next?${r}`);return l==null||typeof l=="string"?null:l}s(X,"pollForWork");function z(e,n){return{logger:{info:s(r=>n(r),"info"),warn:s(r=>n(r),"warn"),error:s(r=>n(r),"error")},job:{attempts:e}}}s(z,"makeHelpers");async function Y(e,n,r){let l=W[e.kind],c=Date.now();if(a(r,{event:"claim",jobId:e.id,kind:e.kind,attempts:e.attempts}),!l){let o=`unknown kind: ${e.kind}`;a(r,{event:"fail",jobId:e.id,kind:e.kind,terminal:!0,error:o}),await p(`/api/work/${e.id}/fail`,{leaseToken:e.leaseToken,error:o,terminal:!0}).catch(()=>{});return}let i=setInterval(()=>{a(r,{event:"heartbeat",jobId:e.id}),p(`/api/work/${e.id}/heartbeat`,{leaseToken:e.leaseToken}).catch(o=>{a(r,{event:"heartbeat_error",jobId:e.id,error:o instanceof Error?o.message:String(o)})})},n);try{let o=z(e.attempts,r),d=await l(e.payload,o)??{};clearInterval(i),a(r,{event:"complete",jobId:e.id,kind:e.kind,durationMs:Date.now()-c}),await p(`/api/work/${e.id}/complete`,{leaseToken:e.leaseToken,result:d})}catch(o){clearInterval(i);let d=h(o),u=o instanceof Error?o.message:String(o);a(r,{event:"fail",jobId:e.id,kind:e.kind,durationMs:Date.now()-c,terminal:d,error:u}),await p(`/api/work/${e.id}/fail`,{leaseToken:e.leaseToken,error:u,terminal:d}).catch(t=>{a(r,{event:"fail_post_error",jobId:e.id,error:t instanceof Error?t.message:String(t)})})}}s(Y,"runOne");async function we(e){let n=e.log??(()=>{}),r=e.pollWaitMs??U,l=e.heartbeatIntervalMs??K,c=e.capabilities??J(),i=V;a(n,{event:"agent_start",capabilities:c,pollWaitMs:r,heartbeatIntervalMs:l}),Q(c,e.signal,n,e.version),C({signal:e.signal,log:n}).catch(t=>{a(n,{event:"tt_heartbeat_fatal",error:t instanceof Error?t.message:String(t)})});let o=5*6e4,d=0,u=s(()=>{if(!e.readInstalledVersion||!e.version)return!1;let t=Date.now();if(t-d<o)return!1;d=t;let m=e.readInstalledVersion();return!!(m&&m!==e.version)},"versionDrifted");for(;!e.signal.aborted;){if(u()){a(n,{event:"agent_version_drift",bootVersion:e.version,installedVersion:e.readInstalledVersion?.()??null}),e.onVersionDrift?.();break}let t=null;try{t=await X(c,r)}catch(m){let $=m instanceof f?m.statusCode:void 0;if(a(n,{event:"poll_error",status:$,error:m instanceof Error?m.message:String(m)}),!await O(i,e.signal))break;i=Math.min(i*2,B);continue}if(!t){if(a(n,{event:"poll_204"}),!await O(i,e.signal))break;i=Math.min(i*2,B);continue}i=V,await Y(t,l,n)}a(n,{event:"agent_stop"})}s(we,"runAgentLoop");export{W as a,D as b,J as c,X as d,we as e};
@@ -1,4 +1,4 @@
1
- import{a as S,b as z,c as T}from"./chunk-QFVGUZDO.js";import{a as j}from"./chunk-5RBLIVBF.js";import{a as O}from"./chunk-GPTPK6QX.js";import{c as A,d as C,f as b}from"./chunk-B3BHB26P.js";import{e as _,f as I,h as u}from"./chunk-H2ORWIEY.js";import{a as $}from"./chunk-ZLLER3HP.js";async function D(f,m){let{mirrorId:o,projectPath:s,projectId:i,config:p}=f,e=$(n=>m.logger.info(n),"log");if(p?.sessionId)return M({mirrorId:o,sessionId:p.sessionId},e);e(`Processing insights job ${o}...`),await u(`/api/insights-jobs/${o}/progress`,{status:"running",progress:{step:"reading_data"}});try{let{repaired:n}=await I("/api/sessions/repair-analyzed-at",{});n>0&&e(` Repaired analyzed_at on ${n} orphan session(s).`)}catch(n){e(` Warning: analyzed_at repair failed: ${n instanceof Error?n.message:String(n)}`)}let a=await J(s,i);if(!a)throw new j("No session data found \u2014 ensure sessions are captured and enriched.");e(` Found ${a.stats.sessions} sessions, generating recommendations...`);let w=20,c=200;if(C()!=="none"){let n=0,t=0;try{for(;n<c;){let l=await _(`/api/sessions?hasAnalysis=false&limit=${w}&offset=${t}`);if(l.length===0)break;e(` Generating facets for ${l.length} un-analyzed sessions (drained ${n} so far)...`);for(let g of l){if(n>=c)break;try{let d=await _(`/api/sessions/${g.id}/events?limit=100`);if(d.length<2){n++,t++;continue}let P=d.filter(h=>h.eventType==="user_message"||h.eventType==="human").map(h=>h.content?.slice(0,200)??"").filter(Boolean).join(`
1
+ import{a as S,b as z,c as T}from"./chunk-QFVGUZDO.js";import{a as O}from"./chunk-GPTPK6QX.js";import{a as j}from"./chunk-5RBLIVBF.js";import{c as A,d as C,f as b}from"./chunk-B3BHB26P.js";import{e as _,f as I,h as u}from"./chunk-H2ORWIEY.js";import{a as $}from"./chunk-ZLLER3HP.js";async function D(f,m){let{mirrorId:o,projectPath:s,projectId:i,config:p}=f,e=$(n=>m.logger.info(n),"log");if(p?.sessionId)return M({mirrorId:o,sessionId:p.sessionId},e);e(`Processing insights job ${o}...`),await u(`/api/insights-jobs/${o}/progress`,{status:"running",progress:{step:"reading_data"}});try{let{repaired:n}=await I("/api/sessions/repair-analyzed-at",{});n>0&&e(` Repaired analyzed_at on ${n} orphan session(s).`)}catch(n){e(` Warning: analyzed_at repair failed: ${n instanceof Error?n.message:String(n)}`)}let a=await J(s,i);if(!a)throw new j("No session data found \u2014 ensure sessions are captured and enriched.");e(` Found ${a.stats.sessions} sessions, generating recommendations...`);let w=20,c=200;if(C()!=="none"){let n=0,t=0;try{for(;n<c;){let l=await _(`/api/sessions?hasAnalysis=false&limit=${w}&offset=${t}`);if(l.length===0)break;e(` Generating facets for ${l.length} un-analyzed sessions (drained ${n} so far)...`);for(let g of l){if(n>=c)break;try{let d=await _(`/api/sessions/${g.id}/events?limit=100`);if(d.length<2){n++,t++;continue}let P=d.filter(h=>h.eventType==="user_message"||h.eventType==="human").map(h=>h.content?.slice(0,200)??"").filter(Boolean).join(`
2
2
  ---
3
3
  `);if(!P){n++,t++;continue}let E=await b(T,P,4096);if(E){let h=d.filter(R=>R.eventType==="user_message"||R.eventType==="human").length;await u(`/api/sessions/${g.id}/enrich`,{analysis:{source:"generated_facets",...E},analyzedEventCount:d.length,analyzedTurnCount:h}),e(` Generated facets for session ${g.id} (${g.tool})`)}else t++;n++}catch(d){e(` Failed to generate facets for session ${g.id}: ${d instanceof Error?d.message:String(d)}`),n++,t++}}if(l.length<w)break}}catch(l){e(` Warning: facet generation failed after ${n} sessions: ${l instanceof Error?l.message:String(l)}`)}}let r={},y=S.length+1;for(let n=0;n<S.length;n++){let t=S[n];e(` [${n+1}/${y}] Generating ${t.name}...`);try{await u(`/api/insights-jobs/${o}/progress`,{status:"running",progress:{step:t.name,current:n+1,total:y,partial:{...r}}})}catch(g){e(` Warning: progress update failed for ${t.name}: ${g instanceof Error?g.message:String(g)}`)}e(` Running LLM prompt for ${t.name}...`);let l=await b(t.prompt,a.summary,t.maxTokens);l?(r[t.name]=l,e(` Got result for ${t.name}`)):e(` No result for ${t.name} (LLM returned null)`)}e(` [${y}/${y}] Generating at_a_glance...`),await u(`/api/insights-jobs/${o}/progress`,{status:"running",progress:{step:"at_a_glance",current:y,total:y,partial:{...r}}});let N=[a.summary,r.what_works?`
4
4
  ## What Works
@@ -0,0 +1 @@
1
+ import{a as r}from"./chunk-ZLLER3HP.js";import{readFile as b,stat as w}from"node:fs/promises";import{homedir as F}from"node:os";import{isAbsolute as y,join as f,resolve as v,sep as S}from"node:path";var u="capture.json",R={codex:{section:"codex",label:"Codex capture",envFlag:"RULEMETRIC_CODEX_CAPTURE",envRoots:"RULEMETRIC_CODEX_ROOTS"},hooks:{section:"hooks",label:"Hook capture",envFlag:"RULEMETRIC_HOOKS_CAPTURE",envRoots:"RULEMETRIC_HOOKS_ROOTS"}};function P(e,o){return e==="~"?o:e.startsWith("~/")?f(o,e.slice(2)):e}r(P,"expandTilde");function x(e,o){return e.map(t=>typeof t=="string"?t.trim():"").filter(Boolean).map(t=>P(t,o)).filter(t=>y(t)).map(t=>v(t))}r(x,"normaliseRoots");function h(e){return{mode:"off",roots:[],source:"config",error:e}}r(h,"failClosed");async function E(e,o){let t=o.env??process.env,s=o.home??F(),n=t[e.envFlag]?.trim().toLowerCase();if(n==="off"||n==="none"||n==="0")return{mode:"off",roots:[],source:"env"};if(n==="all"||n==="1")return{mode:"all",roots:[],source:"env"};let i=t[e.envRoots]?.trim();if(i){let m=x(i.split(","),s);return m.length>0?{mode:"allowlist",roots:m,source:"env"}:{mode:"off",roots:[],source:"env",error:`${e.envRoots} had no absolute paths`}}let l=f(o.configDir,u),c;try{c=await b(l,"utf8")}catch{return{mode:"all",roots:[],source:"default"}}let p;try{p=JSON.parse(c)}catch{return h(`${u} is present but is not valid JSON \u2014 ${e.label} is OFF until it parses.`)}let a=p?.[e.section];if(!a||typeof a!="object")return{mode:"all",roots:[],source:"default"};let d=typeof a.mode=="string"?a.mode.trim().toLowerCase():void 0;if(d==="off")return{mode:"off",roots:[],source:"config"};if(d==="all")return{mode:"all",roots:[],source:"config"};let g=Array.isArray(a.roots)?a.roots:[];if(d===void 0&&g.length===0)return{mode:"all",roots:[],source:"default"};let C=x(g,s);return C.length===0?h(`${u} selects an allowlist but lists no roots (absolute paths required) \u2014 ${e.label} is OFF.`):{mode:"allowlist",roots:C,source:"config"}}r(E,"loadSectionScope");async function $(e){return E(R.codex,e)}r($,"loadCodexCaptureScope");async function N(e){return E(R.hooks,e)}r(N,"loadHooksCaptureScope");function D(e,o){if(e.mode==="off")return!1;if(e.mode==="all")return!0;if(!o)return!1;let t=v(o);return e.roots.some(s=>t===s||t.startsWith(s.endsWith(S)?s:s+S))}r(D,"isPathInScope");function O(e,o){if(e.error)return`OFF \u2014 ${e.error}`;switch(e.mode){case"off":return`off (${e.source}) \u2014 ${o}`;case"allowlist":return`scoped to ${e.roots.length} path${e.roots.length===1?"":"s"} (${e.source})`;default:return"all projects (unscoped)"}}r(O,"describeCaptureScope");function I(e){return O(e,"no Codex transcripts are swept")}r(I,"describeCodexCaptureScope");function M(e){return O(e,"no hook-captured sessions are uploaded")}r(M,"describeHooksCaptureScope");function A(e){let o=null,t=null;return async()=>{let s=f(e.configDir,u),n;try{let c=await w(s);n=`${c.mtimeMs}:${c.size}`}catch{n="absent"}if(o&&t===n)return o;let i=await $(e),l=o===null||o.mode!==i.mode||o.error!==i.error||o.roots.join("\0")!==i.roots.join("\0");return o=i,t=n,l&&e.onChange?.(i),i}}r(A,"createCodexScopeWatcher");export{u as a,$ as b,N as c,D as d,O as e,I as f,M as g,A as h};
@@ -0,0 +1,2 @@
1
+ import{a as m}from"./chunk-QXPYGN7I.js";import{a as n}from"./chunk-ZLLER3HP.js";import{copyFileSync as y,mkdirSync as x,readFileSync as S,writeFileSync as w}from"node:fs";import{homedir as f}from"node:os";import{isAbsolute as h,join as l,resolve as b}from"node:path";function a(e){return l(e,m)}n(a,"captureConfigPath");function v(e){let r;try{r=S(a(e),"utf-8")}catch{return{}}try{let t=JSON.parse(r);if(!t||typeof t!="object"||Array.isArray(t))throw new Error("not a JSON object");return t}catch(t){throw new Error(`${a(e)} is not valid JSON (${t instanceof Error?t.message:String(t)}). Fix or delete it \u2014 refusing to overwrite what you wrote.`)}}n(v,"readCaptureConfig");function F(e,r){x(e,{recursive:!0});let t=a(e);return w(t,JSON.stringify(r,null,2)+`
2
+ `),t}n(F,"writeCaptureConfig");function C(e,r=f()){let t=e.trim(),s=t==="~"?r:t.startsWith("~/")?l(r,t.slice(2)):t;return b(s)}n(C,"normaliseRoot");function N(e,r=f()){let t=e.trim();if(!t)return!1;let s=t==="~"?r:t.startsWith("~/")?l(r,t.slice(2)):t;return h(s)}n(N,"isUsableRoot");function j(e,r,t=f(),s="codex"){let o={...e[s]??{}},u=Array.isArray(o.roots)?o.roots.map(i=>C(String(i),t)):[],g=!1;if(r.op==="mode")o.mode=r.mode,r.mode==="all"&&delete o.roots;else if(r.op==="clear")delete o.mode,delete o.roots;else{let i=r.roots.map(c=>C(c,t)),d=r.op==="add"?[...new Set([...u,...i])]:u.filter(c=>!i.includes(c));d.length===0&&r.op==="remove"?(delete o.roots,o.mode="off",g=!0):(o.roots=d.sort(),o.mode="allowlist")}let p={...e};return Object.keys(o).length===0?delete p[s]:p[s]=o,{config:p,emptiedToOff:g}}n(j,"applyScopeEdit");function J(e){let r=a(e),t=`${r}.broken`;try{y(r,t)}catch{}return t}n(J,"backupUnparseableConfig");export{a,v as b,F as c,C as d,N as e,j as f,J as g};
@@ -1,2 +1,2 @@
1
- import{a as R}from"./chunk-5RBLIVBF.js";import{b as B}from"./chunk-N7TGRFVZ.js";import{a as v,f as d,g as n,h as m,i as U}from"./chunk-JGLVVIEM.js";import{a as $}from"./chunk-ZLLER3HP.js";import{and as L,asc as j,eq as l,gt as q,isNotNull as F,sql as O}from"drizzle-orm";var _=100,C=10;async function G(I,s={}){let t=s.db??U(),D=s.sendEmail??B,p=s.log??(o=>process.stderr.write(`[process_announcement] ${o}
1
+ import{b as B}from"./chunk-N7TGRFVZ.js";import{a as R}from"./chunk-5RBLIVBF.js";import{a as v,f as d,g as n,h as m,i as U}from"./chunk-JGLVVIEM.js";import{a as $}from"./chunk-ZLLER3HP.js";import{and as L,asc as j,eq as l,gt as q,isNotNull as F,sql as O}from"drizzle-orm";var _=100,C=10;async function G(I,s={}){let t=s.db??U(),D=s.sendEmail??B,p=s.log??(o=>process.stderr.write(`[process_announcement] ${o}
2
2
  `)),b=s.webBaseUrl??process.env.RULEMETRIC_WEB_URL??process.env.WEB_URL??"https://rulemetric.com",{announcementId:r}=I,[i]=await t.select().from(d).where(l(d.id,r)).limit(1);if(!i)throw new R(`Announcement ${r} not found`);if(i.status!=="queued"&&i.status!=="sending")throw new R(`Announcement ${r} is in status='${i.status}'; expected 'queued' or 'sending'.`);await t.update(d).set({status:"sending",updatedAt:new Date}).where(l(d.id,r)),p(`Sending announcement ${r} (${i.subject??""})`);let w=0,f=0,h=0,y=0,k=null;try{for(;;){let c=await t.select({userId:m.userId,email:v.email,displayName:v.displayName,unsubscribeToken:m.unsubscribeToken}).from(m).innerJoin(v,l(v.id,m.userId)).where(L(l(m.productAnnouncements,!0),F(v.email),k?q(m.userId,k):void 0)).orderBy(j(m.userId)).limit(_);if(c.length===0)break;k=c[c.length-1].userId;for(let A=0;A<c.length;A+=C){let P=c.slice(A,A+C),S=await Promise.allSettled(P.map(g=>W({recipient:g,announcement:i,webBaseUrl:b,sendEmail:D,db:t})));for(let g=0;g<S.length;g++){let u=S[g];if(u.status==="fulfilled")u.value.ok==="sent"?w++:u.value.ok==="skipped"?h++:(f++,u.value.provider==="noop"&&y++,p(` recipient ${P[g].userId}: send failed \u2014 ${u.value.error}`));else{f++;let T=u.reason instanceof Error?u.reason.message:String(u.reason);p(` recipient ${P[g].userId}: send failed \u2014 ${T}`)}}}if(c.length<_)break}y>0&&p(`WARNING: ${y} recipient(s) hit the noop email provider and were recorded as FAILED \u2014 no email provider is configured on this worker (set RESEND_API_KEY in ~/.config/rulemetric/env and reinstall the service)`);let o=await t.select({status:n.status,count:O`count(*)::int`}).from(n).where(l(n.announcementId,r)).groupBy(n.status),e={};for(let c of o)e[c.status]=c.count;let a=e.sent??0,E=e.failed??0,N=a===0&&E>0?"failed":"sent",x=E>0?`${E} of ${a+E} recipient(s) failed; see announcement_deliveries`:null;return await t.update(d).set({status:N,recipientCount:a,...N==="sent"?{sentAt:new Date}:{},error:x,updatedAt:new Date}).where(l(d.id,r)),p(`Done: status=${N} sent=${a} failed=${E} (this attempt: sent=${w} failed=${f} skipped=${h})`),{sent:w,failed:f,skipped:h}}catch(o){let e=o instanceof Error?o.message:String(o);throw await t.update(d).set({status:"failed",error:e.slice(0,1e3),updatedAt:new Date}).where(l(d.id,r)).catch(()=>{}),o}}$(G,"processAnnouncement");function K(I){return I.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}$(K,"escapeHtml");async function W(I){let{recipient:s,announcement:t,webBaseUrl:D,sendEmail:p,db:b}=I;if(!s.email)return{ok:"skipped",reason:"no-email"};let r=await b.insert(n).values({announcementId:t.id,userId:s.userId,email:s.email,status:"pending"}).onConflictDoNothing({target:[n.announcementId,n.userId]}).returning({id:n.id});if(r.length===0)return{ok:"skipped",reason:"already-claimed"};let i=r[0].id,w=D.replace(/\/$/,""),f=encodeURIComponent(s.unsubscribeToken),h=`${w}/unsubscribe/${f}`,y=s.displayName?.trim().split(/\s+/)[0]||"there",k=t.htmlBody.replaceAll("{{unsubscribe_url}}",h).replaceAll("{{recipient_name}}",K(y)),o=t.textBody.replaceAll("{{unsubscribe_url}}",h).replaceAll("{{recipient_name}}",y);try{let e=await p({to:s.email,subject:t.subject,html:k,text:o,fromName:"RuleMetric",idempotencyKey:i,headers:{"List-Unsubscribe":`<${w}/api/unsubscribe/${f}>`,"List-Unsubscribe-Post":"List-Unsubscribe=One-Click"}});if(e.provider==="noop"){let a="no email provider configured (RESEND_API_KEY unset on the worker)";return await b.update(n).set({status:"failed",error:a}).where(l(n.id,i)),{ok:"failed",error:a,provider:e.provider}}return await b.update(n).set({status:"sent",providerId:e.id,sentAt:new Date}).where(l(n.id,i)),{ok:"sent",providerId:e.id,provider:e.provider}}catch(e){let a=e instanceof Error?e.message:String(e);return await b.update(n).set({status:"failed",error:a.slice(0,1e3)}).where(l(n.id,i)).catch(()=>{}),{ok:"failed",error:a}}}$(W,"sendOne");export{G as a};
@@ -1 +1 @@
1
- import{b as l}from"./chunk-MDPN46EY.js";import{a as p}from"./chunk-5RBLIVBF.js";import{h}from"./chunk-H2ORWIEY.js";import{a as c}from"./chunk-ZLLER3HP.js";async function g(t){if(!t.worktree?.create)return t;let{branch:e,baseRef:s}=t.worktree,n=await l({repoRoot:t.projectPath,branch:e,baseRef:s});return{...t,projectPath:n.path,gitBranch:n.branch}}c(g,"resolveWorktreeForLaunch");async function L(t,e){let{mirrorId:s,tool:n}=t,{config:r}=t,a=c(o=>e.logger.info(o),"log");if(e.job.attempts>1)throw new p(`process_launch is not safe to retry (attempt ${e.job.attempts}). Re-launch manually.`);r=await g(r),r.worktree?.create&&a(`Worktree resolved: ${r.projectPath} (branch ${r.gitBranch})`),a(`Launching ${n}...`);let{getLauncher:f}=await import("./dist-BC6GMBXV.js"),i=await f(n).launch(r);a(`Launch completed: sessionId=${i.sessionId}`);let u={...i,worktreePath:r.worktree?.create?r.projectPath:void 0,runId:r.runId};return await h(`/api/launch-jobs/${s}/state`,{result:u}).catch(o=>{a(`result persist failed: ${o instanceof Error?o.message:String(o)}`)}),u}c(L,"processLaunch");export{g as a,L as b};
1
+ import{b as l}from"./chunk-6QKI756T.js";import{a as p}from"./chunk-5RBLIVBF.js";import{h}from"./chunk-H2ORWIEY.js";import{a as c}from"./chunk-ZLLER3HP.js";async function g(t){if(!t.worktree?.create)return t;let{branch:e,baseRef:s}=t.worktree,n=await l({repoRoot:t.projectPath,branch:e,baseRef:s});return{...t,projectPath:n.path,gitBranch:n.branch}}c(g,"resolveWorktreeForLaunch");async function L(t,e){let{mirrorId:s,tool:n}=t,{config:r}=t,a=c(o=>e.logger.info(o),"log");if(e.job.attempts>1)throw new p(`process_launch is not safe to retry (attempt ${e.job.attempts}). Re-launch manually.`);r=await g(r),r.worktree?.create&&a(`Worktree resolved: ${r.projectPath} (branch ${r.gitBranch})`),a(`Launching ${n}...`);let{getLauncher:f}=await import("./dist-FAVALJ5C.js"),i=await f(n).launch(r);a(`Launch completed: sessionId=${i.sessionId}`);let u={...i,worktreePath:r.worktree?.create?r.projectPath:void 0,runId:r.runId};return await h(`/api/launch-jobs/${s}/state`,{result:u}).catch(o=>{a(`result persist failed: ${o instanceof Error?o.message:String(o)}`)}),u}c(L,"processLaunch");export{g as a,L as b};
@@ -1,2 +1,2 @@
1
- import{c as R}from"./chunk-MDPN46EY.js";import{a as P}from"./chunk-5RBLIVBF.js";import{b as s,c as r,i as j}from"./chunk-JGLVVIEM.js";import{a as g}from"./chunk-ZLLER3HP.js";import{and as y,eq as l,isNotNull as I}from"drizzle-orm";async function O($,p={}){let k=p.db??j(),b=p.removeWorktreeFn??R,n=p.log??(e=>process.stderr.write(`[process_run_cleanup] ${e}
1
+ import{c as R}from"./chunk-6QKI756T.js";import{a as P}from"./chunk-5RBLIVBF.js";import{b as s,c as r,i as j}from"./chunk-JGLVVIEM.js";import{a as g}from"./chunk-ZLLER3HP.js";import{and as y,eq as l,isNotNull as I}from"drizzle-orm";async function O($,p={}){let k=p.db??j(),b=p.removeWorktreeFn??R,n=p.log??(e=>process.stderr.write(`[process_run_cleanup] ${e}
2
2
  `)),{runId:t}=$,[i]=await k.select({id:s.id,userId:s.userId,projectPath:s.projectPath}).from(s).where(l(s.id,t)).limit(1);if(!i)throw new P(`Run ${t} not found`);if(!i.projectPath)throw new P(`Run ${t} has no projectPath; cannot resolve a repo root for worktree cleanup`);let c=i.projectPath,v=await k.select({id:r.id,projectPath:r.projectPath}).from(r).where(y(l(r.runId,t),l(r.userId,i.userId),I(r.endedAt))),a=[],u=0,d=0,h=0,m=0,w=new Set;for(let e of v)if(!(!e.projectPath||e.projectPath===c)&&!w.has(e.projectPath)){w.add(e.projectPath);try{let o=await b({repoRoot:c,worktreePath:e.projectPath});o.removed?(u++,a.push({sessionId:e.id,worktreePath:e.projectPath,status:"removed"}),n(`removed worktree ${e.projectPath} (session ${e.id})`)):o.reason==="dirty"?(d++,a.push({sessionId:e.id,worktreePath:e.projectPath,status:"skipped-dirty"}),n(`skipped dirty worktree ${e.projectPath} (session ${e.id}) \u2014 uncommitted changes`)):(h++,a.push({sessionId:e.id,worktreePath:e.projectPath,status:"absent"}),n(`worktree absent ${e.projectPath} (session ${e.id})`))}catch(o){let f=o instanceof Error?o.message:String(o);m++,a.push({sessionId:e.id,worktreePath:e.projectPath,status:"error",error:f.slice(0,1e3)}),n(`error removing worktree ${e.projectPath} (session ${e.id}): ${f}`)}}return n(`run ${t} cleanup: removed=${u} skippedDirty=${d} absent=${h} errored=${m}`),{runId:t,repoRoot:c,removed:u,skippedDirty:d,absent:h,errored:m,worktrees:a}}g(O,"processRunCleanup");export{O as a};
@@ -1,2 +1,2 @@
1
- import{a as l,b as w,c as C,d as b,e as v,f as a,g as x}from"../../chunk-RUZ36O55.js";import{b as m,d as u}from"../../chunk-VX2GJCQ4.js";import{a as g}from"../../chunk-PPKPCXJD.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-V44SRRYR.js";import"../../chunk-U6XEU573.js";import"../../chunk-VLOX6KOM.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-H2ORWIEY.js";import{l as h}from"../../chunk-O6C2UGBY.js";import{a as p}from"../../chunk-ZLLER3HP.js";import{existsSync as S}from"node:fs";import{Flags as s}from"@oclif/core";var c=class y extends g{static{p(this,"CaptureScope")}static description="Show or set which projects the worker sweeps for Codex transcripts";static examples=["<%= config.bin %> <%= command.id %>","<%= config.bin %> <%= command.id %> --add ~/work/client-a --add ~/work/client-b","<%= config.bin %> <%= command.id %> --remove ~/work/client-a","<%= config.bin %> <%= command.id %> --off","<%= config.bin %> <%= command.id %> --all"];static flags={add:s.string({description:"Capture Codex sessions under this path (repeatable). Implies an allowlist.",multiple:!0}),remove:s.string({description:"Stop capturing under this path (repeatable).",multiple:!0}),off:s.boolean({description:"Skip the Codex sweep entirely.",exclusive:["all"]}),all:s.boolean({description:"Capture every project (the default).",exclusive:["off"]}),clear:s.boolean({description:"Remove the codex scope, restoring the default."})};async run(){let{flags:e}=await this.parse(y),i=h(),r=l(i);if(!((e.add?.length??0)>0||(e.remove?.length??0)>0||e.off||e.all||e.clear)){await this.show(i,r);return}for(let t of[...e.add??[],...e.remove??[]])v(t)||this.error(`Not an absolute path: ${t}
2
- Use an absolute path or ~/\u2026 \u2014 relative paths cannot be matched against a session's cwd.`);for(let t of e.add??[]){let n=b(t);S(n)||this.warn(`${n} does not exist yet \u2014 added anyway, but nothing will match until it does.`)}let o;try{o=w(i)}catch(t){e.clear||this.error(t instanceof Error?t.message:String(t));let n=x(i);this.warn(`${l(i)} was not valid JSON \u2014 saved it to ${n} and starting fresh.`),o={}}let f=!1;if(e.clear&&({config:o}=a(o,{op:"clear"})),e.off&&({config:o}=a(o,{op:"mode",mode:"off"})),e.all&&({config:o}=a(o,{op:"mode",mode:"all"})),e.remove?.length){let t=a(o,{op:"remove",roots:e.remove});o=t.config,f=t.emptiedToOff}e.add?.length&&({config:o}=a(o,{op:"add",roots:e.add})),C(i,o),f&&(this.log("Removed the last root \u2014 Codex capture is now OFF rather than silently capturing everything."),this.log("Use --all to go back to capturing every project.")),await this.show(i,r),this.log(""),this.log("Takes effect on the next sweep (within ~30s). No restart needed.")}async show(e,i){let r=await m({configDir:e});if(this.log(`Codex capture: ${u(r)}`),r.roots.length)for(let d of r.roots)this.log(` \u2022 ${d}`);this.log(`Config: ${i}`),r.error&&(this.log(""),this.log("This scope is FAILING CLOSED \u2014 nothing is being captured from Codex."),this.log("Fix the file, or run `rulemetric capture scope --clear` to start over.")),r.source==="env"&&(this.log(""),this.log("Set by environment variable, which outranks the config file."),this.log("Unset RULEMETRIC_CODEX_CAPTURE / RULEMETRIC_CODEX_ROOTS for the file to apply."))}};export{c as default};
1
+ import{a as f,b as k,c as S,d as x,e as R,f as n,g as y}from"../../chunk-SHYP27B7.js";import{b as C,c as w,f as v,g as b}from"../../chunk-QXPYGN7I.js";import{a as u}from"../../chunk-PPKPCXJD.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-V44SRRYR.js";import"../../chunk-U6XEU573.js";import"../../chunk-VLOX6KOM.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-H2ORWIEY.js";import{l as m}from"../../chunk-O6C2UGBY.js";import{a as h}from"../../chunk-ZLLER3HP.js";import{existsSync as O}from"node:fs";import{Flags as c}from"@oclif/core";var g=class E extends u{static{h(this,"CaptureScope")}static description="Show or set which projects RuleMetric captures \u2014 the Codex sweep and hook-driven sessions each have their own scope";static examples=["<%= config.bin %> <%= command.id %>","<%= config.bin %> <%= command.id %> --add ~/work/client-a --add ~/work/client-b","<%= config.bin %> <%= command.id %> --tool hooks --add ~/work/client-a","<%= config.bin %> <%= command.id %> --tool hooks --off","<%= config.bin %> <%= command.id %> --remove ~/work/client-a","<%= config.bin %> <%= command.id %> --off","<%= config.bin %> <%= command.id %> --all"];static flags={tool:c.string({description:'Which capture path to edit: "codex" (the worker transcript sweep, the default) or "hooks" (Claude Code / Cursor / Copilot / Antigravity hook sessions).',options:["codex","hooks"],default:"codex"}),add:c.string({description:"Capture sessions under this path (repeatable). Implies an allowlist.",multiple:!0}),remove:c.string({description:"Stop capturing under this path (repeatable).",multiple:!0}),off:c.boolean({description:"Turn this capture path off entirely.",exclusive:["all"]}),all:c.boolean({description:"Capture every project (the default).",exclusive:["off"]}),clear:c.boolean({description:"Remove this scope, restoring the default."})};async run(){let{flags:o}=await this.parse(E),s=m(),d=f(s);if(!((o.add?.length??0)>0||(o.remove?.length??0)>0||o.off||o.all||o.clear)){await this.show(s,d);return}for(let t of[...o.add??[],...o.remove??[]])R(t)||this.error(`Not an absolute path: ${t}
2
+ Use an absolute path or ~/\u2026 \u2014 relative paths cannot be matched against a session's cwd.`);for(let t of o.add??[]){let a=x(t);O(a)||this.warn(`${a} does not exist yet \u2014 added anyway, but nothing will match until it does.`)}let e;try{e=k(s)}catch(t){o.clear||this.error(t instanceof Error?t.message:String(t));let a=y(s);this.warn(`${f(s)} was not valid JSON \u2014 saved it to ${a} and starting fresh.`),e={}}let i=o.tool??"codex",r=void 0,l=!1;if(o.clear&&({config:e}=n(e,{op:"clear"},r,i)),o.off&&({config:e}=n(e,{op:"mode",mode:"off"},r,i)),o.all&&({config:e}=n(e,{op:"mode",mode:"all"},r,i)),o.remove?.length){let t=n(e,{op:"remove",roots:o.remove},r,i);e=t.config,l=t.emptiedToOff}o.add?.length&&({config:e}=n(e,{op:"add",roots:o.add},r,i)),S(s,e),l&&(this.log(`Removed the last root \u2014 ${i==="hooks"?"hook":"Codex"} capture is now OFF rather than silently capturing everything.`),this.log("Use --all to go back to capturing every project.")),await this.show(s,d),this.log(""),this.log(i==="hooks"?"Takes effect on the next hook fire. No restart needed.":"Takes effect on the next sweep (within ~30s). No restart needed.")}async show(o,s){let d=await C({configDir:o}),p=await w({configDir:o}),e=h((i,r,l,t)=>{if(this.log(`${i}: ${l}`),r.roots.length)for(let a of r.roots)this.log(` \u2022 ${a}`);r.error&&(this.log(" This scope is FAILING CLOSED \u2014 nothing is being captured on this path."),this.log(` Fix the file, or run \`rulemetric capture scope ${i==="Hook capture"?"--tool hooks ":""}--clear\` to start over.`)),r.source==="env"&&this.log(` Set by environment variable, which outranks the config file (${t}).`)},"print");e("Codex capture",d,v(d),"RULEMETRIC_CODEX_CAPTURE / RULEMETRIC_CODEX_ROOTS"),e("Hook capture",p,b(p),"RULEMETRIC_HOOKS_CAPTURE / RULEMETRIC_HOOKS_ROOTS"),this.log(`Config: ${s}`)}};export{g as default};
@@ -1 +1 @@
1
- import{b as A,c as U}from"../chunk-V5U3E4BZ.js";import{a as L}from"../chunk-VLXCQ2DC.js";import"../chunk-I2DZGJRR.js";import{e as T,f as E,g as x}from"../chunk-QWCEZEDO.js";import"../chunk-KKDHD4XA.js";import"../chunk-SZ62CP55.js";import{d as F,e as G}from"../chunk-ZYI66XKV.js";import"../chunk-RMDLJN4L.js";import{i as M,j as N,k as D,m as Y,n as B}from"../chunk-BL4BN6RU.js";import"../chunk-2ZAKZEXW.js";import{d as X}from"../chunk-NTKO4H2K.js";import"../chunk-KQCAELPN.js";import"../chunk-L2CFSMBC.js";import"../chunk-Z72VHGV7.js";import"../chunk-4L2ZEIRE.js";import"../chunk-CDY7TQFZ.js";import"../chunk-XRTZU7IZ.js";import"../chunk-B3BHB26P.js";import"../chunk-N7ODX6PO.js";import"../chunk-PJ3WHQ67.js";import"../chunk-G5BXZT6F.js";import"../chunk-HMMO27U4.js";import{a as O,b as I,d as H}from"../chunk-VX2GJCQ4.js";import{a as _}from"../chunk-PPKPCXJD.js";import"../chunk-IZTIYR5Q.js";import"../chunk-V44SRRYR.js";import"../chunk-U6XEU573.js";import"../chunk-VLOX6KOM.js";import"../chunk-3AV3GTMP.js";import{a as C,e as P}from"../chunk-H2ORWIEY.js";import{a as R,g as v,l as k}from"../chunk-O6C2UGBY.js";import{a as $}from"../chunk-ZLLER3HP.js";import{spawnSync as J}from"node:child_process";import{existsSync as q,readFileSync as K}from"node:fs";import{join as j}from"node:path";var S=class h extends _{static{$(this,"Diagnostics")}static description='Diagnose capture / proxy / connectivity problems (e.g. a client-side "502 Bad Gateway")';static examples=["<%= config.bin %> diagnostics"];baseUrl(){return process.env.RULEMETRIC_API_URL??R().apiUrl??C}async checkDirect(){let o=process.env.HTTPS_PROXY,i=process.env.HTTP_PROXY;delete process.env.HTTPS_PROXY,delete process.env.HTTP_PROXY;let t=new AbortController,a=setTimeout(()=>t.abort(),8e3);try{return(await globalThis.fetch(`${this.baseUrl()}/health`,{signal:t.signal})).ok}catch{return!1}finally{clearTimeout(a),o!==void 0&&(process.env.HTTPS_PROXY=o),i!==void 0&&(process.env.HTTP_PROXY=i)}}configuredProxy(){if(process.env.HTTPS_PROXY)return process.env.HTTPS_PROXY;for(let o of["settings.local.json","settings.json"]){let i=j(process.cwd(),".claude",o);if(q(i))try{let t=JSON.parse(K(i,"utf8"));if(t.env?.HTTPS_PROXY)return t.env.HTTPS_PROXY}catch{}}return null}checkThroughProxy(o){let i=J("curl",["-sS","-x",o,"--max-time","8","-o","/dev/null","-w","%{http_code}",`${this.baseUrl()}/health`],{encoding:"utf8",stdio:["ignore","pipe","ignore"]});return i.error||typeof i.stdout!="string"?null:i.stdout.trim()==="200"}async run(){await this.parse(h);let o=process.version,i=this.configuredProxy(),t=i!=null,[a,m,c]=await Promise.all([this.checkDirect(),x(T),x(E)]),u=t&&i?this.checkThroughProxy(i):null,e=$((n,g,p)=>{let f=g===null?"\u2013":g?"[OK]":"[!!]";this.log(` ${f} ${n.padEnd(22)} ${p}`)},"line");this.log("RuleMetric diagnostics"),this.log(""),e("Node",!A(o),`${o}${A(o)?" (< 20.11 \u2014 breaks the bundled proxy)":""}`),e("API (direct)",a,`${this.baseUrl()}/health ${a?"reachable":"UNREACHABLE"}`),e("Authenticated",v(),v()?"yes":"no \u2014 run `rulemetric auth login`"),e("Proxy configured",t?!0:null,t?i:"no HTTPS_PROXY set"),t&&(e("Gateway :"+T,m,m?"listening":"NOT listening"),e("mitmproxy :"+E,c,c?"listening":"not listening (gateway should route direct)"),e("API (via proxy)",u,u===null?"inconclusive (curl unavailable)":u?"reachable":"FAILED \u2014 502/blocked through your proxy"));let s=X();e("claude CLI",s.claudeBin!=null,s.claudeBin??"not found \u2014 LLM features (grading, distill) will no-op"),e("codex CLI",s.codexBin!=null?!0:null,s.codexBin?`${s.codexBin}${s.codexConfiguredModel?` (model ${s.codexConfiguredModel})`:""}`:"not found \u2014 optional; enables the cross-vendor reviewer (evals validate-judge)");let r=null;if(v()&&a)try{r=await P("/api/workers/health")}catch{r=null}if(r){let n=r.worker;e("Worker",!!n.active,n.present?n.active?`online (last heartbeat ${n.ageSeconds??"?"}s ago${n.clientVersion?`, v${n.clientVersion}`:""})`:`NOT RUNNING \u2014 last heartbeat ${z(n.ageSeconds)} ago`:"never connected \u2014 no worker has ever reported in");let g=r.pending.reduce((p,f)=>p+f.count,0);if(g>0){let p=r.verdict.stuck.reduce((b,w)=>b+w.count,0),f=r.verdict.unclaimable.reduce((b,w)=>b+w.count,0);e("Job queue",p===0,`${g} pending`+(p>0?` \u2014 ${p} waiting on this worker`:"")+(f>0?` \u2014 ${f} need a worker with DATABASE_URL`:""))}else e("Job queue",!0,"empty")}else v()&&a&&e("Worker",null,"could not read /workers/health (older API?)");let l=L(process.cwd()),d=await I({configDir:k()}),W={claude_code:"session hooks (+ proxy for instruction linking)",codex:`worker transcript sync of ~/.codex/sessions \u2014 ${H(d)}`,cursor:"user hooks (~/.cursor/hooks.json)",copilot_agent:"workspace hooks",antigravity:"user hooks (~/.gemini/config/hooks.json)"};this.log(""),this.log(" Capture coverage (agents found on this machine):");for(let n of l)this.log(` \u2022 ${n.padEnd(15)} ${W[n]??"captured"}`);if(l.includes("codex"))if(d.error)this.log(` ! ${d.error}`);else if(d.mode==="allowlist")for(let n of d.roots)this.log(` \u21B3 ${n}`);else d.mode==="all"&&this.log(` \u21B3 scope it with ${j(k(),O)} ({"codex":{"roots":["/path/to/repo"]}}) or RULEMETRIC_CODEX_CAPTURE=off`);r&&!r.worker.active&&l.includes("codex")&&d.mode!=="off"&&this.log(" ! Codex capture runs INSIDE the worker \u2014 it is stopped while the worker is down."),v()&&a&&await this.reportEvolutionSpend();let y=U({nodeVersion:o,directApiOk:a,httpsProxySet:t,gatewayAlive:m,mitmproxyAlive:c,proxyPathOk:u});this.log("");let V=y.severity==="ok"?"[OK]":y.severity==="warn"?"[!!]":"[XX]";this.log(`${V} ${y.headline}`);for(let n of y.hints)this.log(` \u2022 ${n}`);if(r&&r.verdict.severity!=="ok"){let n=r.verdict.severity==="warn"?"[!!]":"[XX]";this.log(""),this.log(`${n} ${r.verdict.headline}`);for(let g of r.verdict.hints)this.log(` \u2022 ${g}`)}}async reportEvolutionSpend(){let o;try{o=await P("/api/eval-targets?type=instruction&limit=200")}catch{return}let i=o.filter(t=>{let a=t.metadata??{};return a.autoEvolveEnabled===!0||a.autoEvolveEnabled==="true"});if(i.length!==0){this.log(""),this.log(" Nightly instruction evolution (cron_instruction_evolution, 07:30 UTC):");for(let t of i){let a=t.metadata??{},m=N(a),c=M(a);if(m){this.log(` \u2022 ${t.name} \u2014 PAUSED (metadata.autoEvolvePaused). Opt-in preserved.`),this.log(" \u21B3 resume: set autoEvolvePaused=false");continue}let u=null;try{u=(await P(`/api/eval-targets/${t.id}/evals`)).filter(s=>!s.retiredAt).length}catch{}if(this.log(` \u2022 ${t.name}`),u!=null){let e=G(u,c.minPairs,F(c,u));if(!e.feasible)this.log(` \u21B3 cannot reach a verdict \u2014 ${e.reason}`);else{let s=D({liveCases:u,passes:e.passes});this.log(` \u21B3 each night: ${B(s)}`)}}this.log(` \u21B3 pairs budget ${c.minPairs}`+(c.configured?" (metadata.autoEvolvePairs)":" (default)")+` \xB7 writes ${a.autoEvolveApply===!0||a.autoEvolveApply==="true"?"ENABLED":"off (dry run)"}`),c.note&&this.log(` ! ${c.note}`);try{let e=await P(`/api/eval-targets/${t.id}/promotions?limit=1`),s=e.promotions[0];if(s){let l=s.gates?.cost,d=l?.modelCalls?`${l.modelCalls} model calls, ${l.usablePairs??"?"} usable pair(s)`+(l.mde!=null?`, resolved +/-${Y(l.mde)}`:"")+(l.wallMs?`, ${(l.wallMs/6e4).toFixed(0)} min`:""):"cost not recorded (decision predates cost tracking)";this.log(` \u21B3 last run ${new Date(s.createdAt).toISOString().slice(0,10)}: ${s.decision}${s.applied?" (APPLIED)":""} \u2014 ${d}`)}let r=e.counts??{};this.log(` \u21B3 lifetime: ${r.promote??0} promote / ${r.revert??0} revert / ${r.refuse??0} refuse`)}catch{}}this.log(" \u21B3 pause the spend: metadata.autoEvolvePaused=true (keeps the opt-in)")}}};function z(h){if(h===null)return"never";if(h<90)return`${Math.round(h)}s`;let o=Math.round(h/60);return o<90?`${o}m`:`${Math.round(o/60)}h`}$(z,"formatAge");export{S as default};
1
+ import{b as A,c as M}from"../chunk-V5U3E4BZ.js";import{a as D}from"../chunk-VLXCQ2DC.js";import"../chunk-I2DZGJRR.js";import{e as E,f as S,g as x}from"../chunk-QWCEZEDO.js";import"../chunk-KKDHD4XA.js";import"../chunk-SZ62CP55.js";import{d as W,e as V}from"../chunk-ZYI66XKV.js";import"../chunk-RMDLJN4L.js";import{i as Y,j as B,k as F,m as G,n as j}from"../chunk-BL4BN6RU.js";import"../chunk-2ZAKZEXW.js";import{d as N}from"../chunk-NTKO4H2K.js";import"../chunk-KQCAELPN.js";import"../chunk-L2CFSMBC.js";import"../chunk-Z72VHGV7.js";import"../chunk-4L2ZEIRE.js";import"../chunk-CDY7TQFZ.js";import"../chunk-XRTZU7IZ.js";import"../chunk-B3BHB26P.js";import"../chunk-N7ODX6PO.js";import"../chunk-PJ3WHQ67.js";import"../chunk-G5BXZT6F.js";import"../chunk-HMMO27U4.js";import{a as H,b as I,c as U,f as X,g as L}from"../chunk-QXPYGN7I.js";import{a as O}from"../chunk-PPKPCXJD.js";import"../chunk-IZTIYR5Q.js";import"../chunk-V44SRRYR.js";import"../chunk-U6XEU573.js";import"../chunk-VLOX6KOM.js";import"../chunk-3AV3GTMP.js";import{a as _,e as P}from"../chunk-H2ORWIEY.js";import{a as R,g as v,l as k}from"../chunk-O6C2UGBY.js";import{a as b}from"../chunk-ZLLER3HP.js";import{spawnSync as Q}from"node:child_process";import{existsSync as Z,readFileSync as ee}from"node:fs";import{join as J}from"node:path";var C=class h extends O{static{b(this,"Diagnostics")}static description='Diagnose capture / proxy / connectivity problems (e.g. a client-side "502 Bad Gateway")';static examples=["<%= config.bin %> diagnostics"];baseUrl(){return process.env.RULEMETRIC_API_URL??R().apiUrl??_}async checkDirect(){let o=process.env.HTTPS_PROXY,s=process.env.HTTP_PROXY;delete process.env.HTTPS_PROXY,delete process.env.HTTP_PROXY;let t=new AbortController,a=setTimeout(()=>t.abort(),8e3);try{return(await globalThis.fetch(`${this.baseUrl()}/health`,{signal:t.signal})).ok}catch{return!1}finally{clearTimeout(a),o!==void 0&&(process.env.HTTPS_PROXY=o),s!==void 0&&(process.env.HTTP_PROXY=s)}}configuredProxy(){if(process.env.HTTPS_PROXY)return process.env.HTTPS_PROXY;for(let o of["settings.local.json","settings.json"]){let s=J(process.cwd(),".claude",o);if(Z(s))try{let t=JSON.parse(ee(s,"utf8"));if(t.env?.HTTPS_PROXY)return t.env.HTTPS_PROXY}catch{}}return null}checkThroughProxy(o){let s=Q("curl",["-sS","-x",o,"--max-time","8","-o","/dev/null","-w","%{http_code}",`${this.baseUrl()}/health`],{encoding:"utf8",stdio:["ignore","pipe","ignore"]});return s.error||typeof s.stdout!="string"?null:s.stdout.trim()==="200"}async run(){await this.parse(h);let o=process.version,s=this.configuredProxy(),t=s!=null,[a,m,c]=await Promise.all([this.checkDirect(),x(E),x(S)]),u=t&&s?this.checkThroughProxy(s):null,e=b((n,p,g)=>{let f=p===null?"\u2013":p?"[OK]":"[!!]";this.log(` ${f} ${n.padEnd(22)} ${g}`)},"line");this.log("RuleMetric diagnostics"),this.log(""),e("Node",!A(o),`${o}${A(o)?" (< 20.11 \u2014 breaks the bundled proxy)":""}`),e("API (direct)",a,`${this.baseUrl()}/health ${a?"reachable":"UNREACHABLE"}`),e("Authenticated",v(),v()?"yes":"no \u2014 run `rulemetric auth login`"),e("Proxy configured",t?!0:null,t?s:"no HTTPS_PROXY set"),t&&(e("Gateway :"+E,m,m?"listening":"NOT listening"),e("mitmproxy :"+S,c,c?"listening":"not listening (gateway should route direct)"),e("API (via proxy)",u,u===null?"inconclusive (curl unavailable)":u?"reachable":"FAILED \u2014 502/blocked through your proxy"));let i=N();e("claude CLI",i.claudeBin!=null,i.claudeBin??"not found \u2014 LLM features (grading, distill) will no-op"),e("codex CLI",i.codexBin!=null?!0:null,i.codexBin?`${i.codexBin}${i.codexConfiguredModel?` (model ${i.codexConfiguredModel})`:""}`:"not found \u2014 optional; enables the cross-vendor reviewer (evals validate-judge)");let r=null;if(v()&&a)try{r=await P("/api/workers/health")}catch{r=null}if(r){let n=r.worker;e("Worker",!!n.active,n.present?n.active?`online (last heartbeat ${n.ageSeconds??"?"}s ago${n.clientVersion?`, v${n.clientVersion}`:""})`:`NOT RUNNING \u2014 last heartbeat ${te(n.ageSeconds)} ago`:"never connected \u2014 no worker has ever reported in");let p=r.pending.reduce((g,f)=>g+f.count,0);if(p>0){let g=r.verdict.stuck.reduce((w,T)=>w+T.count,0),f=r.verdict.unclaimable.reduce((w,T)=>w+T.count,0);e("Job queue",g===0,`${p} pending`+(g>0?` \u2014 ${g} waiting on this worker`:"")+(f>0?` \u2014 ${f} need a worker with DATABASE_URL`:""))}else e("Job queue",!0,"empty")}else v()&&a&&e("Worker",null,"could not read /workers/health (older API?)");let l=D(process.cwd()),d=await I({configDir:k()}),q=await U({configDir:k()}),y=` \u2014 ${L(q)}`,K={claude_code:`session hooks (+ proxy for instruction linking)${y}`,codex:`worker transcript sync of ~/.codex/sessions \u2014 ${X(d)}`,cursor:`user hooks (~/.cursor/hooks.json)${y}`,copilot_agent:`workspace hooks${y}`,antigravity:`user hooks (~/.gemini/config/hooks.json)${y}`};this.log(""),this.log(" Capture coverage (agents found on this machine):");for(let n of l)this.log(` \u2022 ${n.padEnd(15)} ${K[n]??"captured"}`);if(l.includes("codex"))if(d.error)this.log(` ! ${d.error}`);else if(d.mode==="allowlist")for(let n of d.roots)this.log(` \u21B3 ${n}`);else d.mode==="all"&&this.log(` \u21B3 scope it with ${J(k(),H)} ({"codex":{"roots":["/path/to/repo"]}}) or RULEMETRIC_CODEX_CAPTURE=off`);r&&!r.worker.active&&l.includes("codex")&&d.mode!=="off"&&this.log(" ! Codex capture runs INSIDE the worker \u2014 it is stopped while the worker is down."),v()&&a&&await this.reportEvolutionSpend();let $=M({nodeVersion:o,directApiOk:a,httpsProxySet:t,gatewayAlive:m,mitmproxyAlive:c,proxyPathOk:u});this.log("");let z=$.severity==="ok"?"[OK]":$.severity==="warn"?"[!!]":"[XX]";this.log(`${z} ${$.headline}`);for(let n of $.hints)this.log(` \u2022 ${n}`);if(r&&r.verdict.severity!=="ok"){let n=r.verdict.severity==="warn"?"[!!]":"[XX]";this.log(""),this.log(`${n} ${r.verdict.headline}`);for(let p of r.verdict.hints)this.log(` \u2022 ${p}`)}}async reportEvolutionSpend(){let o;try{o=await P("/api/eval-targets?type=instruction&limit=200")}catch{return}let s=o.filter(t=>{let a=t.metadata??{};return a.autoEvolveEnabled===!0||a.autoEvolveEnabled==="true"});if(s.length!==0){this.log(""),this.log(" Nightly instruction evolution (cron_instruction_evolution, 07:30 UTC):");for(let t of s){let a=t.metadata??{},m=B(a),c=Y(a);if(m){this.log(` \u2022 ${t.name} \u2014 PAUSED (metadata.autoEvolvePaused). Opt-in preserved.`),this.log(" \u21B3 resume: set autoEvolvePaused=false");continue}let u=null;try{u=(await P(`/api/eval-targets/${t.id}/evals`)).filter(i=>!i.retiredAt).length}catch{}if(this.log(` \u2022 ${t.name}`),u!=null){let e=V(u,c.minPairs,W(c,u));if(!e.feasible)this.log(` \u21B3 cannot reach a verdict \u2014 ${e.reason}`);else{let i=F({liveCases:u,passes:e.passes});this.log(` \u21B3 each night: ${j(i)}`)}}this.log(` \u21B3 pairs budget ${c.minPairs}`+(c.configured?" (metadata.autoEvolvePairs)":" (default)")+` \xB7 writes ${a.autoEvolveApply===!0||a.autoEvolveApply==="true"?"ENABLED":"off (dry run)"}`),c.note&&this.log(` ! ${c.note}`);try{let e=await P(`/api/eval-targets/${t.id}/promotions?limit=1`),i=e.promotions[0];if(i){let l=i.gates?.cost,d=l?.modelCalls?`${l.modelCalls} model calls, ${l.usablePairs??"?"} usable pair(s)`+(l.mde!=null?`, resolved +/-${G(l.mde)}`:"")+(l.wallMs?`, ${(l.wallMs/6e4).toFixed(0)} min`:""):"cost not recorded (decision predates cost tracking)";this.log(` \u21B3 last run ${new Date(i.createdAt).toISOString().slice(0,10)}: ${i.decision}${i.applied?" (APPLIED)":""} \u2014 ${d}`)}let r=e.counts??{};this.log(` \u21B3 lifetime: ${r.promote??0} promote / ${r.revert??0} revert / ${r.refuse??0} refuse`)}catch{}}this.log(" \u21B3 pause the spend: metadata.autoEvolvePaused=true (keeps the opt-in)")}}};function te(h){if(h===null)return"never";if(h<90)return`${Math.round(h)}s`;let o=Math.round(h/60);return o<90?`${o}m`:`${Math.round(o/60)}h`}b(te,"formatAge");export{C as default};
@@ -1,3 +1,3 @@
1
- import{a as C,b as L,c as D}from"../../chunk-3HSEVXMQ.js";import{e as I}from"../../chunk-IYDADY62.js";import"../../chunk-TIOKY2IA.js";import"../../chunk-ZYVWALMS.js";import"../../chunk-NKPLTT7J.js";import"../../chunk-HUADECKZ.js";import"../../chunk-7SI6KWSX.js";import"../../chunk-QFVGUZDO.js";import"../../chunk-H7J27U4P.js";import"../../chunk-BUWWFHGO.js";import"../../chunk-IQTSUAGM.js";import"../../chunk-CRIFP3QP.js";import"../../chunk-MDPN46EY.js";import"../../chunk-RSKQRVPJ.js";import"../../chunk-SWSGNEVO.js";import"../../chunk-BPQ66YTY.js";import"../../chunk-UF6US7VU.js";import"../../chunk-SNJ2NIIE.js";import"../../chunk-IXLDCX7M.js";import"../../chunk-JIJKIPE6.js";import"../../chunk-5RBLIVBF.js";import"../../chunk-GPTPK6QX.js";import"../../chunk-N7TGRFVZ.js";import{j as d}from"../../chunk-JGLVVIEM.js";import"../../chunk-Q4APAZUC.js";import"../../chunk-YQ56FQEO.js";import"../../chunk-GIRPEMTW.js";import"../../chunk-MODXEGCU.js";import"../../chunk-5DIOZDDZ.js";import"../../chunk-4VZLIGMS.js";import"../../chunk-CNOD6HWU.js";import"../../chunk-X64R6JCJ.js";import"../../chunk-6UEFCMR2.js";import"../../chunk-ZYI66XKV.js";import"../../chunk-RMDLJN4L.js";import"../../chunk-BL4BN6RU.js";import"../../chunk-2ZAKZEXW.js";import"../../chunk-NTKO4H2K.js";import"../../chunk-CJRYYV76.js";import"../../chunk-KQCAELPN.js";import"../../chunk-L2CFSMBC.js";import"../../chunk-Z72VHGV7.js";import"../../chunk-4L2ZEIRE.js";import"../../chunk-CDY7TQFZ.js";import"../../chunk-XRTZU7IZ.js";import"../../chunk-B3BHB26P.js";import"../../chunk-N7ODX6PO.js";import"../../chunk-PJ3WHQ67.js";import"../../chunk-G5BXZT6F.js";import"../../chunk-HMMO27U4.js";import{b as k,d as h,e as A}from"../../chunk-VX2GJCQ4.js";import{a as O}from"../../chunk-PPKPCXJD.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-V44SRRYR.js";import"../../chunk-U6XEU573.js";import"../../chunk-VLOX6KOM.js";import"../../chunk-3AV3GTMP.js";import{f as b}from"../../chunk-H2ORWIEY.js";import{e as P,l as f}from"../../chunk-O6C2UGBY.js";import{a as e}from"../../chunk-ZLLER3HP.js";import{trace as se,context as ie}from"@opentelemetry/api";import{NodeSDK as j}from"@opentelemetry/sdk-node";import{OTLPTraceExporter as q}from"@opentelemetry/exporter-trace-otlp-http";import{BatchSpanProcessor as F,ConsoleSpanExporter as U,SimpleSpanProcessor as X}from"@opentelemetry/sdk-trace-node";import{Resource as B}from"@opentelemetry/resources";import{ATTR_SERVICE_NAME as H,ATTR_SERVICE_VERSION as K}from"@opentelemetry/semantic-conventions";function $(t){if(!t)return{};let r={};for(let n of t.split(",")){let s=n.indexOf("=");if(s===-1)continue;let i=n.slice(0,s).trim(),a=n.slice(s+1).trim();i&&(r[i]=a)}return r}e($,"parseOtlpHeaders");var p=null;function y(){return process.env.TELEMETRY_ENABLED!=="false"}e(y,"isTelemetryEnabled");function S(t){if(!y()||p!==null)return"off";let r=new B({[H]:t.serviceName,[K]:t.serviceVersion??"0.1.0"}),n=process.env.OTEL_EXPORTER_OTLP_ENDPOINT,s,i;if(n){let a=$(process.env.OTEL_EXPORTER_OTLP_HEADERS),l=new q({url:`${n}/v1/traces`,headers:a});i=new F(l),s="otlp"}else if(process.env.OTEL_SPAN_EXPORT==="none")i=void 0,s="silent";else{let a=new U;i=new X(a),s="console"}return p=new j({resource:r,spanProcessors:i?[i]:[]}),p.start(),s}e(S,"initTelemetry");async function m(){p&&(await p.shutdown(),p=null)}e(m,"shutdownTelemetry");import{SpanKind as he,SpanStatusCode as ye}from"@opentelemetry/api";import{trace as ve,context as we}from"@opentelemetry/api";import*as u from"@sentry/node";var E=!1;function T(t){if(E)return!1;let r=process.env.SENTRY_DSN;return r?(u.init({dsn:r,serverName:t.serviceName,environment:process.env.NODE_ENV??"development",tracesSampleRate:0}),E=!0,!0):!1}e(T,"initSentry");async function g(t){E&&await u.flush(t)}e(g,"flushSentry");import{existsSync as J,mkdirSync as W,readFileSync as R,unlinkSync as V,writeFileSync as M}from"node:fs";import{dirname as z,join as v}from"node:path";import{execFileSync as Q}from"node:child_process";var c=v(f(),"evals-agent.lock");function Z(t){try{return process.kill(t,0),!0}catch(r){return r.code==="EPERM"}}e(Z,"pidAlive");function ee(t){if(!Z(t))return!1;try{let r=Q("ps",["-p",String(t),"-o","command="],{encoding:"utf-8",stdio:["ignore","pipe","ignore"]});return/run\.js\s+evals\s+agent|evals\s+agent/.test(r)}catch{return!0}}e(ee,"isLiveAgent");function te(){try{W(z(c),{recursive:!0})}catch{}for(let t=0;t<2;t++)try{return M(c,String(process.pid),{flag:"wx"}),{ok:!0}}catch(r){if(r.code!=="EEXIST")throw r;let n=0;try{n=Number(R(c,"utf-8").trim())}catch{}if(n&&n!==process.pid&&ee(n))return{ok:!1,holder:n};try{V(c)}catch{}}try{M(c,String(process.pid))}catch{}return{ok:!0}}e(te,"acquireAgentLock");function x(){try{J(c)&&Number(R(c,"utf-8").trim())===process.pid&&V(c)}catch{}}e(x,"releaseAgentLock");var w=class t extends O{static{e(this,"EvalAgentCommand")}static description="The worker daemon: long-polls /api/work/next, claims jobs, and runs them locally. Installed as a launchd service by `rulemetric service install`.";static examples=["<%= config.bin %> evals agent"];async run(){await this.parse(t),this.requireAuth();let r=te();if(!r.ok){this.log(`Another rulemetric evals agent is already running (pid ${r.holder}). Refusing to start a second instance.`);return}process.env.PG_APPLICATION_NAME||="rulemetric-agent",T({serviceName:"rulemetric-agent"})&&this.log("[sentry] error capture enabled");let s=S({serviceName:"rulemetric-agent"});s==="otlp"?this.log(`[otel] traces exporting to ${process.env.OTEL_EXPORTER_OTLP_ENDPOINT}`):s==="console"?this.log("[otel] cron spans printing to stdout (set OTEL_EXPORTER_OTLP_ENDPOINT to ship to a backend)"):this.log("[otel] disabled (TELEMETRY_ENABLED=false)"),!P()&&!process.env.RULEMETRIC_API_KEY&&this.error("No auth token found. Run `rulemetric auth login` first."),this.log("Starting thin agent (Phase 4b parallel-run)..."),this.log(`Long-polling /api/work/next. Press Ctrl+C to stop.
1
+ import{a as C,b as L,c as D}from"../../chunk-GWDZNGUP.js";import{e as I}from"../../chunk-PBPNIKQA.js";import"../../chunk-TIOKY2IA.js";import"../../chunk-RSKQRVPJ.js";import"../../chunk-ZYVWALMS.js";import"../../chunk-NKPLTT7J.js";import"../../chunk-HUADECKZ.js";import"../../chunk-QV4A73AC.js";import"../../chunk-QFVGUZDO.js";import"../../chunk-H7J27U4P.js";import"../../chunk-W2MOTOQE.js";import"../../chunk-IQTSUAGM.js";import"../../chunk-WFYQ6SPJ.js";import"../../chunk-6QKI756T.js";import"../../chunk-SWSGNEVO.js";import"../../chunk-BPQ66YTY.js";import"../../chunk-UF6US7VU.js";import"../../chunk-SNJ2NIIE.js";import"../../chunk-GPTPK6QX.js";import"../../chunk-IXLDCX7M.js";import"../../chunk-TYL5LNTJ.js";import"../../chunk-N7TGRFVZ.js";import"../../chunk-5RBLIVBF.js";import{j as d}from"../../chunk-JGLVVIEM.js";import"../../chunk-Q4APAZUC.js";import"../../chunk-YQ56FQEO.js";import"../../chunk-GIRPEMTW.js";import"../../chunk-MODXEGCU.js";import"../../chunk-7DFNBRLY.js";import"../../chunk-4VZLIGMS.js";import"../../chunk-CNOD6HWU.js";import"../../chunk-X64R6JCJ.js";import"../../chunk-6UEFCMR2.js";import"../../chunk-ZYI66XKV.js";import"../../chunk-RMDLJN4L.js";import"../../chunk-BL4BN6RU.js";import"../../chunk-2ZAKZEXW.js";import"../../chunk-NTKO4H2K.js";import"../../chunk-CJRYYV76.js";import"../../chunk-KQCAELPN.js";import"../../chunk-L2CFSMBC.js";import"../../chunk-Z72VHGV7.js";import"../../chunk-4L2ZEIRE.js";import"../../chunk-CDY7TQFZ.js";import"../../chunk-XRTZU7IZ.js";import"../../chunk-B3BHB26P.js";import"../../chunk-N7ODX6PO.js";import"../../chunk-PJ3WHQ67.js";import"../../chunk-G5BXZT6F.js";import"../../chunk-HMMO27U4.js";import{b as k,f as h,h as A}from"../../chunk-QXPYGN7I.js";import{a as O}from"../../chunk-PPKPCXJD.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-V44SRRYR.js";import"../../chunk-U6XEU573.js";import"../../chunk-VLOX6KOM.js";import"../../chunk-3AV3GTMP.js";import{f as b}from"../../chunk-H2ORWIEY.js";import{e as P,l as f}from"../../chunk-O6C2UGBY.js";import{a as e}from"../../chunk-ZLLER3HP.js";import{trace as se,context as ie}from"@opentelemetry/api";import{NodeSDK as j}from"@opentelemetry/sdk-node";import{OTLPTraceExporter as q}from"@opentelemetry/exporter-trace-otlp-http";import{BatchSpanProcessor as F,ConsoleSpanExporter as U,SimpleSpanProcessor as X}from"@opentelemetry/sdk-trace-node";import{Resource as B}from"@opentelemetry/resources";import{ATTR_SERVICE_NAME as H,ATTR_SERVICE_VERSION as K}from"@opentelemetry/semantic-conventions";function $(t){if(!t)return{};let r={};for(let n of t.split(",")){let s=n.indexOf("=");if(s===-1)continue;let i=n.slice(0,s).trim(),a=n.slice(s+1).trim();i&&(r[i]=a)}return r}e($,"parseOtlpHeaders");var p=null;function y(){return process.env.TELEMETRY_ENABLED!=="false"}e(y,"isTelemetryEnabled");function S(t){if(!y()||p!==null)return"off";let r=new B({[H]:t.serviceName,[K]:t.serviceVersion??"0.1.0"}),n=process.env.OTEL_EXPORTER_OTLP_ENDPOINT,s,i;if(n){let a=$(process.env.OTEL_EXPORTER_OTLP_HEADERS),l=new q({url:`${n}/v1/traces`,headers:a});i=new F(l),s="otlp"}else if(process.env.OTEL_SPAN_EXPORT==="none")i=void 0,s="silent";else{let a=new U;i=new X(a),s="console"}return p=new j({resource:r,spanProcessors:i?[i]:[]}),p.start(),s}e(S,"initTelemetry");async function m(){p&&(await p.shutdown(),p=null)}e(m,"shutdownTelemetry");import{SpanKind as he,SpanStatusCode as ye}from"@opentelemetry/api";import{trace as ve,context as we}from"@opentelemetry/api";import*as u from"@sentry/node";var E=!1;function T(t){if(E)return!1;let r=process.env.SENTRY_DSN;return r?(u.init({dsn:r,serverName:t.serviceName,environment:process.env.NODE_ENV??"development",tracesSampleRate:0}),E=!0,!0):!1}e(T,"initSentry");async function g(t){E&&await u.flush(t)}e(g,"flushSentry");import{existsSync as J,mkdirSync as W,readFileSync as R,unlinkSync as V,writeFileSync as M}from"node:fs";import{dirname as z,join as v}from"node:path";import{execFileSync as Q}from"node:child_process";var c=v(f(),"evals-agent.lock");function Z(t){try{return process.kill(t,0),!0}catch(r){return r.code==="EPERM"}}e(Z,"pidAlive");function ee(t){if(!Z(t))return!1;try{let r=Q("ps",["-p",String(t),"-o","command="],{encoding:"utf-8",stdio:["ignore","pipe","ignore"]});return/run\.js\s+evals\s+agent|evals\s+agent/.test(r)}catch{return!0}}e(ee,"isLiveAgent");function te(){try{W(z(c),{recursive:!0})}catch{}for(let t=0;t<2;t++)try{return M(c,String(process.pid),{flag:"wx"}),{ok:!0}}catch(r){if(r.code!=="EEXIST")throw r;let n=0;try{n=Number(R(c,"utf-8").trim())}catch{}if(n&&n!==process.pid&&ee(n))return{ok:!1,holder:n};try{V(c)}catch{}}try{M(c,String(process.pid))}catch{}return{ok:!0}}e(te,"acquireAgentLock");function x(){try{J(c)&&Number(R(c,"utf-8").trim())===process.pid&&V(c)}catch{}}e(x,"releaseAgentLock");var w=class t extends O{static{e(this,"EvalAgentCommand")}static description="The worker daemon: long-polls /api/work/next, claims jobs, and runs them locally. Installed as a launchd service by `rulemetric service install`.";static examples=["<%= config.bin %> evals agent"];async run(){await this.parse(t),this.requireAuth();let r=te();if(!r.ok){this.log(`Another rulemetric evals agent is already running (pid ${r.holder}). Refusing to start a second instance.`);return}process.env.PG_APPLICATION_NAME||="rulemetric-agent",T({serviceName:"rulemetric-agent"})&&this.log("[sentry] error capture enabled");let s=S({serviceName:"rulemetric-agent"});s==="otlp"?this.log(`[otel] traces exporting to ${process.env.OTEL_EXPORTER_OTLP_ENDPOINT}`):s==="console"?this.log("[otel] cron spans printing to stdout (set OTEL_EXPORTER_OTLP_ENDPOINT to ship to a backend)"):this.log("[otel] disabled (TELEMETRY_ENABLED=false)"),!P()&&!process.env.RULEMETRIC_API_KEY&&this.error("No auth token found. Run `rulemetric auth login` first."),this.log("Starting thin agent (Phase 4b parallel-run)..."),this.log(`Long-polling /api/work/next. Press Ctrl+C to stop.
2
2
  `);let a=new AbortController,l=await k({configDir:f()});if(this.log(`[transcript-sync] Codex capture: ${h(l)}`),l.error)this.log(`[transcript-sync] WARNING: ${l.error}`);else if(l.mode==="allowlist")for(let o of l.roots)this.log(`[transcript-sync] \u2022 ${o}`);let G=new C({providers:[L(void 0,void 0,A({configDir:f(),onChange:e(o=>this.log(`[transcript-sync] Codex capture changed: ${h(o)}`),"onChange")}))],statePath:v(f(),"transcript-sync-state.json"),importTranscript:e(o=>b("/api/sessions/import",o),"importTranscript"),log:e(o=>this.log(`[transcript-sync] ${o}`),"log")});D(G,{signal:a.signal,log:e(o=>this.log(`[transcript-sync] ${o}`),"log")});let N=e(async o=>{this.log(`
3
3
  [${o}] shutting down agent...`),a.abort(),await Promise.allSettled([g(2e3),m(),d()]),x(),process.exit(0)},"shutdown");process.on("SIGINT",()=>{N("SIGINT")}),process.on("SIGTERM",()=>{N("SIGTERM")});let _=!1;try{await I({signal:a.signal,log:e(o=>this.log(o),"log"),version:this.config.version,readInstalledVersion:e(()=>{try{return JSON.parse(R(v(this.config.root,"package.json"),"utf-8")).version??null}catch{return null}},"readInstalledVersion"),onVersionDrift:e(()=>{_=!0},"onVersionDrift")}),_&&(this.log("[upgrade] Installed CLI version changed \u2014 restarting worker onto the new code."),await Promise.allSettled([g(2e3),m(),d()]),x(),process.exit(1))}finally{x(),await d()}}};export{w as default};
@@ -1,3 +1,3 @@
1
- import{a as d}from"../../chunk-PPKPCXJD.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-V44SRRYR.js";import"../../chunk-U6XEU573.js";import"../../chunk-VLOX6KOM.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-H2ORWIEY.js";import"../../chunk-O6C2UGBY.js";import{a as c}from"../../chunk-ZLLER3HP.js";import{Args as m}from"@oclif/core";import{execFileSync as u}from"node:child_process";import{existsSync as f}from"node:fs";import{join as h,delimiter as g}from"node:path";var l=["session-start","session-end","user-prompt","post-tool-use","assistant-response"],a=class p extends d{static{c(this,"HooksRun")}static description="Execute a hook script (called by AI tool hooks, not for direct use)";static hidden=!0;static args={hook:m.string({description:"Hook name to run",required:!0,options:[...l]})};async run(){let{args:r}=await this.parse(p),t=r.hook,{scriptsDir:e}=await import("@rulemetric/hooks/scripts-dir"),o=h(e,`${t}.sh`);f(o)||this.error(`Hook script not found: ${o}`);try{let s=await this.readStdin(),i=`${process.env.PATH??""}${g}${e}`;if(u("bash",[o],{input:s,stdio:["pipe","inherit","inherit"],timeout:t==="session-end"?3e4:1e4,env:{...process.env,PATH:i}}),process.env.RULEMETRIC_HOOK_TOOL==="antigravity"&&t==="post-tool-use")try{let{tailAntigravityTranscript:n}=await import("../../lib/antigravity-transcript.js");await n(s)}catch(n){process.stderr.write(`[antigravity-tailer] ${n.message}
2
- `)}}catch(s){let i=s.status;process.env.RULEMETRIC_HOOK_DEBUG&&process.stderr.write(`[rulemetric hooks run ${t}] non-fatal exit ${i??"?"}: ${s.message??""}
3
- `)}}readStdin(){return new Promise(r=>{let t=[];process.stdin.on("data",e=>t.push(e)),process.stdin.on("end",()=>r(Buffer.concat(t).toString("utf-8"))),process.stdin.readableEnded&&r(Buffer.concat(t).toString("utf-8"))})}};export{a as default};
1
+ import{a as p}from"../../chunk-PPKPCXJD.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-V44SRRYR.js";import"../../chunk-U6XEU573.js";import"../../chunk-VLOX6KOM.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-H2ORWIEY.js";import"../../chunk-O6C2UGBY.js";import{a as c}from"../../chunk-ZLLER3HP.js";import{Args as m}from"@oclif/core";import{execFileSync as f}from"node:child_process";import{existsSync as g}from"node:fs";import{join as h,delimiter as l}from"node:path";var v=["session-start","session-end","user-prompt","post-tool-use","assistant-response"],a=class d extends p{static{c(this,"HooksRun")}static description="Execute a hook script (called by AI tool hooks, not for direct use)";static hidden=!0;static args={hook:m.string({description:"Hook name to run",required:!0,options:[...v]})};async run(){let{args:e}=await this.parse(d),t=e.hook,{scriptsDir:o}=await import("@rulemetric/hooks/scripts-dir"),i=h(o,`${t}.sh`);g(i)||this.error(`Hook script not found: ${i}`);try{let s=await this.readStdin();try{let{evaluateHookCaptureGate:r}=await import("../../lib/hooks-capture-gate.js"),{getDefaultConfigDir:u}=await import("../../lib/auth.js");if(!(await r({stdin:s,configDir:u()})).allowed)return}catch{}let n=`${process.env.PATH??""}${l}${o}`;if(f("bash",[i],{input:s,stdio:["pipe","inherit","inherit"],timeout:t==="session-end"?3e4:1e4,env:{...process.env,PATH:n}}),process.env.RULEMETRIC_HOOK_TOOL==="antigravity"&&t==="post-tool-use")try{let{tailAntigravityTranscript:r}=await import("../../lib/antigravity-transcript.js");await r(s)}catch(r){process.stderr.write(`[antigravity-tailer] ${r.message}
2
+ `)}}catch(s){let n=s.status;process.env.RULEMETRIC_HOOK_DEBUG&&process.stderr.write(`[rulemetric hooks run ${t}] non-fatal exit ${n??"?"}: ${s.message??""}
3
+ `)}}readStdin(){return new Promise(e=>{let t=[];process.stdin.on("data",o=>t.push(o)),process.stdin.on("end",()=>e(Buffer.concat(t).toString("utf-8"))),process.stdin.readableEnded&&e(Buffer.concat(t).toString("utf-8"))})}};export{a as default};
@@ -0,0 +1 @@
1
+ import{a as u}from"../../chunk-PPKPCXJD.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-V44SRRYR.js";import"../../chunk-U6XEU573.js";import"../../chunk-VLOX6KOM.js";import"../../chunk-3AV3GTMP.js";import{e as f,i as g}from"../../chunk-H2ORWIEY.js";import"../../chunk-O6C2UGBY.js";import{a as h}from"../../chunk-ZLLER3HP.js";import{Args as w,Flags as b}from"@oclif/core";var a=class m extends u{static{h(this,"SessionsDelete")}static description="Permanently delete captured sessions and everything stored with them (events, context snapshots, offloaded blobs)";static examples=["<%= config.bin %> sessions delete 4f9d\u2026","<%= config.bin %> sessions delete 4f9d\u2026 8a21\u2026","<%= config.bin %> sessions delete --project /work/client-a --yes"];static args={ids:w.string({description:"Session id(s) to delete",required:!1})};static strict=!1;static flags={project:b.string({description:"Delete every session captured under this project path (use with --yes)."}),yes:b.boolean({description:"Skip the confirmation prompt. Required for --project in non-interactive use.",default:!1})};async run(){let{argv:v,flags:o}=await this.parse(m);this.requireAuth();let n=v.map(t=>t.trim()).filter(Boolean);n.length===0&&!o.project&&this.error("Nothing to delete. Pass one or more session ids, or --project <path> for a bulk scrub."),n.length>0&&o.project&&this.error("Pass either session ids or --project, not both.");let s=n;if(o.project){s=[];let t=0,e=100;for(;;){let r=await f(`/api/sessions?projectPath=${encodeURIComponent(o.project)}&hideEmpty=false&limit=${e}&offset=${t}`);if(s.push(...r.map($=>$.id)),r.length<e)break;t+=e}if(s.length===0){this.log(`No sessions found under ${o.project}. Nothing to delete.`);return}this.log(`${s.length} session(s) captured under ${o.project}.`)}if(!o.yes){process.stdin.isTTY||this.error(`Refusing to delete ${s.length} session(s) without --yes in a non-interactive shell.`);let{createInterface:t}=await import("node:readline/promises"),e=t({input:process.stdin,output:process.stdout}),r=await e.question(`Permanently delete ${s.length} session(s) and all captured content? This cannot be undone. [y/N] `);if(e.close(),r.trim().toLowerCase()!=="y"){this.log("Aborted \u2014 nothing deleted.");return}}let d=0,c=0,p=0,l=0,i=0;for(let t of s)try{let e=await g(`/api/sessions/${t}`);d+=e.eventsDeleted??0,c+=e.snapshotsDeleted??0,p+=e.blobsDeleted??0,l+=e.blobsFailed??0,this.log(`deleted ${t} (${e.eventsDeleted??0} events, ${e.snapshotsDeleted??0} snapshots)`)}catch(e){i+=1,this.warn(`failed to delete ${t}: ${e.message}`)}this.log(""),this.log(`Deleted ${s.length-i}/${s.length} session(s): ${d} events, ${c} snapshots, ${p} storage blob(s) removed.`),l>0&&this.warn(`${l} storage blob(s) could not be removed (rows are gone; blobs are orphaned).`),i>0&&this.error(`${i} session(s) failed to delete \u2014 see warnings above.`)}};export{a as default};
@@ -1 +1 @@
1
- import{a as l}from"../../chunk-5DIOZDDZ.js";import{a}from"../../chunk-PPKPCXJD.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-V44SRRYR.js";import"../../chunk-U6XEU573.js";import"../../chunk-VLOX6KOM.js";import"../../chunk-3AV3GTMP.js";import{e as r}from"../../chunk-H2ORWIEY.js";import"../../chunk-O6C2UGBY.js";import{a as n}from"../../chunk-ZLLER3HP.js";import{Flags as c}from"@oclif/core";var o=class d extends a{static{n(this,"SessionsList")}static description="List captured sessions";static examples=["<%= config.bin %> sessions list","<%= config.bin %> sessions list --tool claude_code","<%= config.bin %> sessions list --tool codex"];static flags={tool:c.string({description:`Filter by tool (${l.join(", ")})`}),limit:c.integer({description:"Max results",default:20})};async run(){let{flags:e}=await this.parse(d);this.requireAuth();let s=new URLSearchParams;e.tool&&s.set("tool",e.tool),s.set("limit",String(e.limit));let i=await r(`/api/sessions?${s}`);if(i.length===0){this.log("No sessions found.");return}for(let t of i){let p=t.projectPath?.split("/").pop()??"\u2014",m=t.analysis?.adherenceScore!=null?`${t.analysis.adherenceScore}%`:"\u2014",u=new Date(t.startedAt).toLocaleDateString();this.log(`${t.id.slice(0,8)} ${t.tool.padEnd(15)} ${p.padEnd(20)} ${String(t.eventCount).padStart(5)} events ${m.padStart(4)} adherence ${u}`)}}};export{o as default};
1
+ import{a as l}from"../../chunk-7DFNBRLY.js";import{a}from"../../chunk-PPKPCXJD.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-V44SRRYR.js";import"../../chunk-U6XEU573.js";import"../../chunk-VLOX6KOM.js";import"../../chunk-3AV3GTMP.js";import{e as r}from"../../chunk-H2ORWIEY.js";import"../../chunk-O6C2UGBY.js";import{a as n}from"../../chunk-ZLLER3HP.js";import{Flags as c}from"@oclif/core";var o=class d extends a{static{n(this,"SessionsList")}static description="List captured sessions";static examples=["<%= config.bin %> sessions list","<%= config.bin %> sessions list --tool claude_code","<%= config.bin %> sessions list --tool codex"];static flags={tool:c.string({description:`Filter by tool (${l.join(", ")})`}),limit:c.integer({description:"Max results",default:20})};async run(){let{flags:e}=await this.parse(d);this.requireAuth();let s=new URLSearchParams;e.tool&&s.set("tool",e.tool),s.set("limit",String(e.limit));let i=await r(`/api/sessions?${s}`);if(i.length===0){this.log("No sessions found.");return}for(let t of i){let p=t.projectPath?.split("/").pop()??"\u2014",m=t.analysis?.adherenceScore!=null?`${t.analysis.adherenceScore}%`:"\u2014",u=new Date(t.startedAt).toLocaleDateString();this.log(`${t.id.slice(0,8)} ${t.tool.padEnd(15)} ${p.padEnd(20)} ${String(t.eventCount).padStart(5)} events ${m.padStart(4)} adherence ${u}`)}}};export{o as default};
@@ -1 +1 @@
1
- import{a as D}from"../chunk-4Z5ECCJE.js";import{a as F}from"../chunk-DVN7GFJG.js";import{a as M}from"../chunk-O2SDD2WW.js";import{a as E}from"../chunk-GBMF3TP6.js";import{a as O}from"../chunk-WSCK4WNK.js";import"../chunk-ARNZQBMX.js";import{a as B,b as S,c as R}from"../chunk-XA4KSQEC.js";import{a as $}from"../chunk-42XJZBQD.js";import"../chunk-RDET7CKR.js";import"../chunk-ZR3MUNLS.js";import"../chunk-X23L2MF6.js";import"../chunk-B22HYCBV.js";import"../chunk-ZXF5NE54.js";import{a as u,b as T,d as a,e as v}from"../chunk-NJ5UED3H.js";import"../chunk-5DIOZDDZ.js";import{a as X}from"../chunk-3AV3GTMP.js";import"../chunk-H2ORWIEY.js";import"../chunk-O6C2UGBY.js";import{a as m}from"../chunk-ZLLER3HP.js";import{useState as w,useEffect as nt,useCallback as G,useRef as st}from"react";import{render as U,Box as c,Text as o,useInput as at,useApp as lt}from"ink";import{Fragment as ht,jsx as t,jsxs as h}from"react/jsx-runtime";var dt=90;function J(){let s=process.stdout.columns||80,n=Math.min(160,s),i=n>=dt,d=i?Math.floor(n/2):n,b=Math.max(6,Math.min(10,d-34));return{dashWidth:n,wide:i,halfWidth:d,barWidth:b}}m(J,"getLayout");function z({active:s,providerName:n}){return h(c,{justifyContent:"space-between",paddingX:1,children:[t(c,{gap:1,children:u.map(i=>t(o,{bold:s===i,color:s===i?a:v,children:s===i?`[ ${T[i]} ]`:` ${T[i]} `},i))}),n&&t(o,{color:a,bold:!0,children:n})]})}m(z,"PeriodTabs");function H({width:s,insightsFocused:n=!1}){return t(c,{borderStyle:"round",borderColor:v,width:s,justifyContent:"center",paddingX:1,children:h(o,{children:[t(o,{color:a,bold:!0,children:"<"}),t(o,{color:a,children:">"}),t(o,{dimColor:!0,children:" switch "}),t(o,{color:a,bold:!0,children:"q"}),t(o,{dimColor:!0,children:" quit "}),t(o,{color:a,bold:!0,children:"s"}),h(o,{dimColor:!0,children:[" ",n?"back":"suggestions"," "]}),t(o,{color:a,bold:!0,children:"1"}),t(o,{dimColor:!0,children:"-"}),t(o,{color:a,bold:!0,children:"5"}),t(o,{dimColor:!0,children:" period "}),t(o,{color:a,bold:!0,children:"r"}),t(o,{dimColor:!0,children:" refresh "}),t(o,{color:a,bold:!0,children:"n"}),t(o,{dimColor:!0,children:" new session "}),t(o,{color:a,bold:!0,children:"l"}),t(o,{dimColor:!0,children:" launcher"})]})})}m(H,"StatusBar");function ct({wide:s,width:n,children:i}){return s?t(c,{width:n,children:i}):t(ht,{children:i})}m(ct,"Row");function ut({initialLocal:s,initialApi:n,initialInstructions:i,initialPeriod:d,initialLauncherFocused:b=!1}){let{exit:j}=lt(),[e,L]=w(d),[K,Q]=w(s),[W,V]=w(n),[Z,tt]=w(i),[ot,k]=w(!1),[p,I]=w(!1),[Y,_]=w(b),et=X()?.orgSlug??null,y=st(null),it=J(),g=G(async()=>{k(!0);let[r,x,P]=await Promise.all([B(),S(),R()]);Q(r),V(x),tt(P),k(!1)},[]);nt(()=>{let r=setInterval(g,3e4);return()=>clearInterval(r)},[g]);let f=G(r=>{r!==e&&(L(r),y.current&&clearTimeout(y.current),y.current=setTimeout(g,300))},[e,g]);at((r,x)=>{if(Y)return;if(r==="q"){if(p){I(!1);return}j();return}if(r==="s"){I(A=>!A);return}if(x.escape&&p){I(!1);return}if(r==="l"&&!p){_(!0);return}if(p)return;if(r==="r"){g();return}if(r==="n"){import("../dist-BC6GMBXV.js").then(({getLauncher:A})=>{A("claude_code").launch({projectPath:process.cwd(),mode:"interactive"})});return}let P=u.indexOf(e);x.leftArrow?f(u[(P-1+u.length)%u.length]):x.rightArrow||x.tab?f(u[(P+1)%u.length]):r==="1"?f("today"):r==="2"?f("week"):r==="3"?f("30days"):r==="4"?f("month"):r==="5"&&f("all")});let{dashWidth:l,wide:q,halfWidth:rt,barWidth:C}=it,N=q?rt:l;return ot?h(c,{flexDirection:"column",width:l,children:[t(z,{active:e}),t(c,{borderStyle:"round",borderColor:a,paddingX:1,width:l,children:h(o,{dimColor:!0,children:["Loading ",T[e],"..."]})}),t(H,{width:l})]}):Y?t(c,{flexDirection:"column",width:l,children:t($,{onClose:()=>_(!1),activeOrg:et,defaultProjectPath:process.cwd(),width:l})}):h(c,{flexDirection:"column",width:l,children:[t(z,{active:e}),t(D,{local:K,api:W,label:T[e],width:l}),h(ct,{wide:q,width:l,children:[t(O,{api:W,width:N,barWidth:C}),t(F,{api:W,width:N,barWidth:C})]}),t(E,{instructions:Z,width:l,barWidth:C}),t(M,{api:W,width:l,focused:p}),t(H,{width:l,insightsFocused:p})]})}m(ut,"InteractiveDashboard");async function yt(s="week",n={}){let[i,d,b]=await Promise.all([B(),S(),R()]);if(process.stdin.isTTY&&process.stdout.isTTY){let{waitUntilExit:e}=U(t(ut,{initialLocal:i,initialApi:d,initialInstructions:b,initialPeriod:s,initialLauncherFocused:n.openLauncher??!1}));await e()}else{let e=J(),{unmount:L}=U(h(c,{flexDirection:"column",width:e.dashWidth,children:[t(D,{local:i,api:d,label:T[s],width:e.dashWidth}),t(O,{api:d,width:e.dashWidth,barWidth:e.barWidth}),t(F,{api:d,width:e.dashWidth,barWidth:e.barWidth}),t(E,{instructions:b,width:e.dashWidth,barWidth:e.barWidth}),t(M,{api:d,width:e.dashWidth})]}),{patchConsole:!1});L()}}m(yt,"renderDashboard");export{yt as renderDashboard};
1
+ import{a as O}from"../chunk-WSCK4WNK.js";import{a as D}from"../chunk-4Z5ECCJE.js";import{a as F}from"../chunk-DVN7GFJG.js";import{a as M}from"../chunk-O2SDD2WW.js";import{a as E}from"../chunk-GBMF3TP6.js";import"../chunk-ARNZQBMX.js";import{a as B,b as S,c as R}from"../chunk-G6XGDHGC.js";import{a as $}from"../chunk-6Q4GWZQV.js";import"../chunk-B22HYCBV.js";import"../chunk-RDET7CKR.js";import"../chunk-ZR3MUNLS.js";import"../chunk-X23L2MF6.js";import"../chunk-ZXF5NE54.js";import{a as u,b as T,d as a,e as v}from"../chunk-NJ5UED3H.js";import"../chunk-7DFNBRLY.js";import{a as X}from"../chunk-3AV3GTMP.js";import"../chunk-H2ORWIEY.js";import"../chunk-O6C2UGBY.js";import{a as m}from"../chunk-ZLLER3HP.js";import{useState as w,useEffect as nt,useCallback as G,useRef as st}from"react";import{render as U,Box as c,Text as o,useInput as at,useApp as lt}from"ink";import{Fragment as ht,jsx as t,jsxs as h}from"react/jsx-runtime";var dt=90;function J(){let s=process.stdout.columns||80,n=Math.min(160,s),i=n>=dt,d=i?Math.floor(n/2):n,b=Math.max(6,Math.min(10,d-34));return{dashWidth:n,wide:i,halfWidth:d,barWidth:b}}m(J,"getLayout");function z({active:s,providerName:n}){return h(c,{justifyContent:"space-between",paddingX:1,children:[t(c,{gap:1,children:u.map(i=>t(o,{bold:s===i,color:s===i?a:v,children:s===i?`[ ${T[i]} ]`:` ${T[i]} `},i))}),n&&t(o,{color:a,bold:!0,children:n})]})}m(z,"PeriodTabs");function H({width:s,insightsFocused:n=!1}){return t(c,{borderStyle:"round",borderColor:v,width:s,justifyContent:"center",paddingX:1,children:h(o,{children:[t(o,{color:a,bold:!0,children:"<"}),t(o,{color:a,children:">"}),t(o,{dimColor:!0,children:" switch "}),t(o,{color:a,bold:!0,children:"q"}),t(o,{dimColor:!0,children:" quit "}),t(o,{color:a,bold:!0,children:"s"}),h(o,{dimColor:!0,children:[" ",n?"back":"suggestions"," "]}),t(o,{color:a,bold:!0,children:"1"}),t(o,{dimColor:!0,children:"-"}),t(o,{color:a,bold:!0,children:"5"}),t(o,{dimColor:!0,children:" period "}),t(o,{color:a,bold:!0,children:"r"}),t(o,{dimColor:!0,children:" refresh "}),t(o,{color:a,bold:!0,children:"n"}),t(o,{dimColor:!0,children:" new session "}),t(o,{color:a,bold:!0,children:"l"}),t(o,{dimColor:!0,children:" launcher"})]})})}m(H,"StatusBar");function ct({wide:s,width:n,children:i}){return s?t(c,{width:n,children:i}):t(ht,{children:i})}m(ct,"Row");function ut({initialLocal:s,initialApi:n,initialInstructions:i,initialPeriod:d,initialLauncherFocused:b=!1}){let{exit:j}=lt(),[e,L]=w(d),[K,Q]=w(s),[W,V]=w(n),[Z,tt]=w(i),[ot,k]=w(!1),[p,I]=w(!1),[Y,_]=w(b),et=X()?.orgSlug??null,y=st(null),it=J(),g=G(async()=>{k(!0);let[r,x,P]=await Promise.all([B(),S(),R()]);Q(r),V(x),tt(P),k(!1)},[]);nt(()=>{let r=setInterval(g,3e4);return()=>clearInterval(r)},[g]);let f=G(r=>{r!==e&&(L(r),y.current&&clearTimeout(y.current),y.current=setTimeout(g,300))},[e,g]);at((r,x)=>{if(Y)return;if(r==="q"){if(p){I(!1);return}j();return}if(r==="s"){I(A=>!A);return}if(x.escape&&p){I(!1);return}if(r==="l"&&!p){_(!0);return}if(p)return;if(r==="r"){g();return}if(r==="n"){import("../dist-FAVALJ5C.js").then(({getLauncher:A})=>{A("claude_code").launch({projectPath:process.cwd(),mode:"interactive"})});return}let P=u.indexOf(e);x.leftArrow?f(u[(P-1+u.length)%u.length]):x.rightArrow||x.tab?f(u[(P+1)%u.length]):r==="1"?f("today"):r==="2"?f("week"):r==="3"?f("30days"):r==="4"?f("month"):r==="5"&&f("all")});let{dashWidth:l,wide:q,halfWidth:rt,barWidth:C}=it,N=q?rt:l;return ot?h(c,{flexDirection:"column",width:l,children:[t(z,{active:e}),t(c,{borderStyle:"round",borderColor:a,paddingX:1,width:l,children:h(o,{dimColor:!0,children:["Loading ",T[e],"..."]})}),t(H,{width:l})]}):Y?t(c,{flexDirection:"column",width:l,children:t($,{onClose:()=>_(!1),activeOrg:et,defaultProjectPath:process.cwd(),width:l})}):h(c,{flexDirection:"column",width:l,children:[t(z,{active:e}),t(D,{local:K,api:W,label:T[e],width:l}),h(ct,{wide:q,width:l,children:[t(O,{api:W,width:N,barWidth:C}),t(F,{api:W,width:N,barWidth:C})]}),t(E,{instructions:Z,width:l,barWidth:C}),t(M,{api:W,width:l,focused:p}),t(H,{width:l,insightsFocused:p})]})}m(ut,"InteractiveDashboard");async function yt(s="week",n={}){let[i,d,b]=await Promise.all([B(),S(),R()]);if(process.stdin.isTTY&&process.stdout.isTTY){let{waitUntilExit:e}=U(t(ut,{initialLocal:i,initialApi:d,initialInstructions:b,initialPeriod:s,initialLauncherFocused:n.openLauncher??!1}));await e()}else{let e=J(),{unmount:L}=U(h(c,{flexDirection:"column",width:e.dashWidth,children:[t(D,{local:i,api:d,label:T[s],width:e.dashWidth}),t(O,{api:d,width:e.dashWidth,barWidth:e.barWidth}),t(F,{api:d,width:e.dashWidth,barWidth:e.barWidth}),t(E,{instructions:b,width:e.dashWidth,barWidth:e.barWidth}),t(M,{api:d,width:e.dashWidth})]}),{patchConsole:!1});L()}}m(yt,"renderDashboard");export{yt as renderDashboard};
@@ -1 +1 @@
1
- import{a,b,c}from"../chunk-XA4KSQEC.js";import"../chunk-5DIOZDDZ.js";import"../chunk-H2ORWIEY.js";import"../chunk-O6C2UGBY.js";import"../chunk-ZLLER3HP.js";export{b as loadApiInsights,c as loadLinkedInstructions,a as loadLocalStats};
1
+ import{a,b,c}from"../chunk-G6XGDHGC.js";import"../chunk-7DFNBRLY.js";import"../chunk-H2ORWIEY.js";import"../chunk-O6C2UGBY.js";import"../chunk-ZLLER3HP.js";export{b as loadApiInsights,c as loadLinkedInstructions,a as loadLocalStats};
@@ -1 +1 @@
1
- import{a}from"../../chunk-42XJZBQD.js";import"../../chunk-RDET7CKR.js";import"../../chunk-ZR3MUNLS.js";import"../../chunk-X23L2MF6.js";import"../../chunk-B22HYCBV.js";import"../../chunk-ZXF5NE54.js";import"../../chunk-NJ5UED3H.js";import"../../chunk-H2ORWIEY.js";import"../../chunk-O6C2UGBY.js";import"../../chunk-ZLLER3HP.js";export{a as LauncherOverlay};
1
+ import{a}from"../../chunk-6Q4GWZQV.js";import"../../chunk-B22HYCBV.js";import"../../chunk-RDET7CKR.js";import"../../chunk-ZR3MUNLS.js";import"../../chunk-X23L2MF6.js";import"../../chunk-ZXF5NE54.js";import"../../chunk-NJ5UED3H.js";import"../../chunk-H2ORWIEY.js";import"../../chunk-O6C2UGBY.js";import"../../chunk-ZLLER3HP.js";export{a as LauncherOverlay};
@@ -1 +1 @@
1
- import{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y}from"./chunk-5DIOZDDZ.js";import"./chunk-ZLLER3HP.js";export{c as ClaudeCodeAdapter,i as CodexAdapter,f as CopilotAgentAdapter,d as CursorAdapter,g as RuleMetricMcpAdapter,b as SESSION_EVENT_TYPES,a as SESSION_TOOLS,e as VSCodeCopilotAdapter,l as buildAnalysisPrompt,u as buildTmuxAttachCommand,t as buildTmuxHasSessionArgs,r as buildTmuxLaunchArgs,s as buildTmuxSendKeysArgs,k as detectTool,o as discoverAllSessions,h as freshCodexState,j as getAdapter,n as getAllProviders,w as getAvailableLaunchers,v as getLauncher,p as getProvider,m as parseAnalysisResponse,x as sanitizeBranch,q as sanitizeTmuxName,y as worktreePathFor};
1
+ import{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y}from"./chunk-7DFNBRLY.js";import"./chunk-ZLLER3HP.js";export{c as ClaudeCodeAdapter,i as CodexAdapter,f as CopilotAgentAdapter,d as CursorAdapter,g as RuleMetricMcpAdapter,b as SESSION_EVENT_TYPES,a as SESSION_TOOLS,e as VSCodeCopilotAdapter,l as buildAnalysisPrompt,u as buildTmuxAttachCommand,t as buildTmuxHasSessionArgs,r as buildTmuxLaunchArgs,s as buildTmuxSendKeysArgs,k as detectTool,o as discoverAllSessions,h as freshCodexState,j as getAdapter,n as getAllProviders,w as getAvailableLaunchers,v as getLauncher,p as getProvider,m as parseAnalysisResponse,x as sanitizeBranch,q as sanitizeTmuxName,y as worktreePathFor};
@@ -1 +1 @@
1
- import{a,b,c,d,e}from"../chunk-IYDADY62.js";import"../chunk-TIOKY2IA.js";import"../chunk-ZYVWALMS.js";import"../chunk-NKPLTT7J.js";import"../chunk-HUADECKZ.js";import"../chunk-7SI6KWSX.js";import"../chunk-QFVGUZDO.js";import"../chunk-H7J27U4P.js";import"../chunk-BUWWFHGO.js";import"../chunk-IQTSUAGM.js";import"../chunk-CRIFP3QP.js";import"../chunk-MDPN46EY.js";import"../chunk-RSKQRVPJ.js";import"../chunk-SWSGNEVO.js";import"../chunk-BPQ66YTY.js";import"../chunk-UF6US7VU.js";import"../chunk-SNJ2NIIE.js";import"../chunk-IXLDCX7M.js";import"../chunk-JIJKIPE6.js";import"../chunk-5RBLIVBF.js";import"../chunk-GPTPK6QX.js";import"../chunk-N7TGRFVZ.js";import"../chunk-JGLVVIEM.js";import"../chunk-Q4APAZUC.js";import"../chunk-YQ56FQEO.js";import"../chunk-GIRPEMTW.js";import"../chunk-MODXEGCU.js";import"../chunk-5DIOZDDZ.js";import"../chunk-4VZLIGMS.js";import"../chunk-CNOD6HWU.js";import"../chunk-X64R6JCJ.js";import"../chunk-6UEFCMR2.js";import"../chunk-ZYI66XKV.js";import"../chunk-RMDLJN4L.js";import"../chunk-BL4BN6RU.js";import"../chunk-2ZAKZEXW.js";import"../chunk-NTKO4H2K.js";import"../chunk-CJRYYV76.js";import"../chunk-KQCAELPN.js";import"../chunk-L2CFSMBC.js";import"../chunk-Z72VHGV7.js";import"../chunk-4L2ZEIRE.js";import"../chunk-CDY7TQFZ.js";import"../chunk-XRTZU7IZ.js";import"../chunk-B3BHB26P.js";import"../chunk-N7ODX6PO.js";import"../chunk-PJ3WHQ67.js";import"../chunk-G5BXZT6F.js";import"../chunk-HMMO27U4.js";import"../chunk-H2ORWIEY.js";import"../chunk-O6C2UGBY.js";import"../chunk-ZLLER3HP.js";export{b as CAPABILITIES,a as HANDLERS,c as availableCapabilities,d as pollForWork,e as runAgentLoop};
1
+ import{a,b,c,d,e}from"../chunk-PBPNIKQA.js";import"../chunk-TIOKY2IA.js";import"../chunk-RSKQRVPJ.js";import"../chunk-ZYVWALMS.js";import"../chunk-NKPLTT7J.js";import"../chunk-HUADECKZ.js";import"../chunk-QV4A73AC.js";import"../chunk-QFVGUZDO.js";import"../chunk-H7J27U4P.js";import"../chunk-W2MOTOQE.js";import"../chunk-IQTSUAGM.js";import"../chunk-WFYQ6SPJ.js";import"../chunk-6QKI756T.js";import"../chunk-SWSGNEVO.js";import"../chunk-BPQ66YTY.js";import"../chunk-UF6US7VU.js";import"../chunk-SNJ2NIIE.js";import"../chunk-GPTPK6QX.js";import"../chunk-IXLDCX7M.js";import"../chunk-TYL5LNTJ.js";import"../chunk-N7TGRFVZ.js";import"../chunk-5RBLIVBF.js";import"../chunk-JGLVVIEM.js";import"../chunk-Q4APAZUC.js";import"../chunk-YQ56FQEO.js";import"../chunk-GIRPEMTW.js";import"../chunk-MODXEGCU.js";import"../chunk-7DFNBRLY.js";import"../chunk-4VZLIGMS.js";import"../chunk-CNOD6HWU.js";import"../chunk-X64R6JCJ.js";import"../chunk-6UEFCMR2.js";import"../chunk-ZYI66XKV.js";import"../chunk-RMDLJN4L.js";import"../chunk-BL4BN6RU.js";import"../chunk-2ZAKZEXW.js";import"../chunk-NTKO4H2K.js";import"../chunk-CJRYYV76.js";import"../chunk-KQCAELPN.js";import"../chunk-L2CFSMBC.js";import"../chunk-Z72VHGV7.js";import"../chunk-4L2ZEIRE.js";import"../chunk-CDY7TQFZ.js";import"../chunk-XRTZU7IZ.js";import"../chunk-B3BHB26P.js";import"../chunk-N7ODX6PO.js";import"../chunk-PJ3WHQ67.js";import"../chunk-G5BXZT6F.js";import"../chunk-HMMO27U4.js";import"../chunk-H2ORWIEY.js";import"../chunk-O6C2UGBY.js";import"../chunk-ZLLER3HP.js";export{b as CAPABILITIES,a as HANDLERS,c as availableCapabilities,d as pollForWork,e as runAgentLoop};
@@ -1 +1 @@
1
- import{a,b,c,d,e,f,g}from"../chunk-RUZ36O55.js";import"../chunk-VX2GJCQ4.js";import"../chunk-ZLLER3HP.js";export{f as applyScopeEdit,g as backupUnparseableConfig,a as captureConfigPath,e as isUsableRoot,d as normaliseRoot,b as readCaptureConfig,c as writeCaptureConfig};
1
+ import{a,b,c,d,e,f,g}from"../chunk-SHYP27B7.js";import"../chunk-QXPYGN7I.js";import"../chunk-ZLLER3HP.js";export{f as applyScopeEdit,g as backupUnparseableConfig,a as captureConfigPath,e as isUsableRoot,d as normaliseRoot,b as readCaptureConfig,c as writeCaptureConfig};
@@ -1 +1 @@
1
- import{a,b,c,d,e}from"../chunk-VX2GJCQ4.js";import"../chunk-ZLLER3HP.js";export{a as CAPTURE_CONFIG_FILENAME,e as createCodexScopeWatcher,d as describeCodexCaptureScope,c as isPathInScope,b as loadCodexCaptureScope};
1
+ import{a,b,c,d,e,f,g,h}from"../chunk-QXPYGN7I.js";import"../chunk-ZLLER3HP.js";export{a as CAPTURE_CONFIG_FILENAME,h as createCodexScopeWatcher,e as describeCaptureScope,f as describeCodexCaptureScope,g as describeHooksCaptureScope,d as isPathInScope,b as loadCodexCaptureScope,c as loadHooksCaptureScope};
@@ -1 +1 @@
1
- import{a}from"../../chunk-JIJKIPE6.js";import"../../chunk-5RBLIVBF.js";import"../../chunk-N7TGRFVZ.js";import"../../chunk-JGLVVIEM.js";import"../../chunk-ZLLER3HP.js";export{a as processAnnouncement};
1
+ import{a}from"../../chunk-TYL5LNTJ.js";import"../../chunk-N7TGRFVZ.js";import"../../chunk-5RBLIVBF.js";import"../../chunk-JGLVVIEM.js";import"../../chunk-ZLLER3HP.js";export{a as processAnnouncement};
@@ -1 +1 @@
1
- import{a}from"../../chunk-7SI6KWSX.js";import"../../chunk-QFVGUZDO.js";import"../../chunk-5RBLIVBF.js";import"../../chunk-GPTPK6QX.js";import"../../chunk-B3BHB26P.js";import"../../chunk-N7ODX6PO.js";import"../../chunk-PJ3WHQ67.js";import"../../chunk-H2ORWIEY.js";import"../../chunk-O6C2UGBY.js";import"../../chunk-ZLLER3HP.js";export{a as processInsights};
1
+ import{a}from"../../chunk-QV4A73AC.js";import"../../chunk-QFVGUZDO.js";import"../../chunk-GPTPK6QX.js";import"../../chunk-5RBLIVBF.js";import"../../chunk-B3BHB26P.js";import"../../chunk-N7ODX6PO.js";import"../../chunk-PJ3WHQ67.js";import"../../chunk-H2ORWIEY.js";import"../../chunk-O6C2UGBY.js";import"../../chunk-ZLLER3HP.js";export{a as processInsights};
@@ -1 +1 @@
1
- import{a,b}from"../../chunk-BUWWFHGO.js";import"../../chunk-MDPN46EY.js";import"../../chunk-5RBLIVBF.js";import"../../chunk-5DIOZDDZ.js";import"../../chunk-N7ODX6PO.js";import"../../chunk-H2ORWIEY.js";import"../../chunk-O6C2UGBY.js";import"../../chunk-ZLLER3HP.js";export{b as processLaunch,a as resolveWorktreeForLaunch};
1
+ import{a,b}from"../../chunk-W2MOTOQE.js";import"../../chunk-6QKI756T.js";import"../../chunk-5RBLIVBF.js";import"../../chunk-7DFNBRLY.js";import"../../chunk-N7ODX6PO.js";import"../../chunk-H2ORWIEY.js";import"../../chunk-O6C2UGBY.js";import"../../chunk-ZLLER3HP.js";export{b as processLaunch,a as resolveWorktreeForLaunch};
@@ -1 +1 @@
1
- import{a}from"../../chunk-CRIFP3QP.js";import"../../chunk-MDPN46EY.js";import"../../chunk-5RBLIVBF.js";import"../../chunk-JGLVVIEM.js";import"../../chunk-5DIOZDDZ.js";import"../../chunk-N7ODX6PO.js";import"../../chunk-ZLLER3HP.js";export{a as processRunCleanup};
1
+ import{a}from"../../chunk-WFYQ6SPJ.js";import"../../chunk-6QKI756T.js";import"../../chunk-5RBLIVBF.js";import"../../chunk-JGLVVIEM.js";import"../../chunk-7DFNBRLY.js";import"../../chunk-N7ODX6PO.js";import"../../chunk-ZLLER3HP.js";export{a as processRunCleanup};
@@ -0,0 +1 @@
1
+ import{c as a,d as c}from"../chunk-QXPYGN7I.js";import{a as s}from"../chunk-ZLLER3HP.js";function d(n,r){let o=null;try{let e=JSON.parse(n);e&&typeof e=="object"&&!Array.isArray(e)&&(o=e)}catch{}if(o){let e=o.toolCall,i=[Array.isArray(o.workspacePaths)?o.workspacePaths[0]:void 0,Array.isArray(o.workspace_roots)?o.workspace_roots[0]:void 0,o.cwd,e?.args?.Cwd,e?.args?.cwd];for(let t of i)if(typeof t=="string"&&t.trim())return t.trim()}return r&&r.trim()?r:null}s(d,"extractHookCwd");async function u(n){let r=await a(n);if(r.mode==="all")return{allowed:!0,scope:r,cwd:null};if(r.mode==="off")return{allowed:!1,scope:r,cwd:null};let o=d(n.stdin,n.processCwd??process.cwd());return{allowed:c(r,o),scope:r,cwd:o}}s(u,"evaluateHookCaptureGate");export{u as evaluateHookCaptureGate,d as extractHookCwd};
@@ -1 +1 @@
1
- import{a,b,c}from"../chunk-3HSEVXMQ.js";import"../chunk-VX2GJCQ4.js";import"../chunk-ZLLER3HP.js";export{a as TranscriptSync,b as createCodexTranscriptProvider,c as startTranscriptSync};
1
+ import{a,b,c}from"../chunk-GWDZNGUP.js";import"../chunk-QXPYGN7I.js";import"../chunk-ZLLER3HP.js";export{a as TranscriptSync,b as createCodexTranscriptProvider,c as startTranscriptSync};
@@ -1 +1 @@
1
- import{a as b,b as c,c as d}from"../chunk-MDPN46EY.js";import{x as a}from"../chunk-5DIOZDDZ.js";import"../chunk-N7ODX6PO.js";import"../chunk-ZLLER3HP.js";export{c as ensureWorktree,d as removeWorktree,b as runGit,a as sanitizeBranch};
1
+ import{a as b,b as c,c as d}from"../chunk-6QKI756T.js";import{x as a}from"../chunk-7DFNBRLY.js";import"../chunk-N7ODX6PO.js";import"../chunk-ZLLER3HP.js";export{c as ensureWorktree,d as removeWorktree,b as runGit,a as sanitizeBranch};
@@ -762,10 +762,12 @@
762
762
  "capture:scope": {
763
763
  "aliases": [],
764
764
  "args": {},
765
- "description": "Show or set which projects the worker sweeps for Codex transcripts",
765
+ "description": "Show or set which projects RuleMetric captures the Codex sweep and hook-driven sessions each have their own scope",
766
766
  "examples": [
767
767
  "<%= config.bin %> <%= command.id %>",
768
768
  "<%= config.bin %> <%= command.id %> --add ~/work/client-a --add ~/work/client-b",
769
+ "<%= config.bin %> <%= command.id %> --tool hooks --add ~/work/client-a",
770
+ "<%= config.bin %> <%= command.id %> --tool hooks --off",
769
771
  "<%= config.bin %> <%= command.id %> --remove ~/work/client-a",
770
772
  "<%= config.bin %> <%= command.id %> --off",
771
773
  "<%= config.bin %> <%= command.id %> --all"
@@ -780,8 +782,20 @@
780
782
  "multiple": false,
781
783
  "type": "option"
782
784
  },
785
+ "tool": {
786
+ "description": "Which capture path to edit: \"codex\" (the worker transcript sweep, the default) or \"hooks\" (Claude Code / Cursor / Copilot / Antigravity hook sessions).",
787
+ "name": "tool",
788
+ "default": "codex",
789
+ "hasDynamicHelp": false,
790
+ "multiple": false,
791
+ "options": [
792
+ "codex",
793
+ "hooks"
794
+ ],
795
+ "type": "option"
796
+ },
783
797
  "add": {
784
- "description": "Capture Codex sessions under this path (repeatable). Implies an allowlist.",
798
+ "description": "Capture sessions under this path (repeatable). Implies an allowlist.",
785
799
  "name": "add",
786
800
  "hasDynamicHelp": false,
787
801
  "multiple": true,
@@ -795,7 +809,7 @@
795
809
  "type": "option"
796
810
  },
797
811
  "off": {
798
- "description": "Skip the Codex sweep entirely.",
812
+ "description": "Turn this capture path off entirely.",
799
813
  "exclusive": [
800
814
  "all"
801
815
  ],
@@ -813,7 +827,7 @@
813
827
  "type": "boolean"
814
828
  },
815
829
  "clear": {
816
- "description": "Remove the codex scope, restoring the default.",
830
+ "description": "Remove this scope, restoring the default.",
817
831
  "name": "clear",
818
832
  "allowNo": false,
819
833
  "type": "boolean"
@@ -3696,6 +3710,61 @@
3696
3710
  "analyze.js"
3697
3711
  ]
3698
3712
  },
3713
+ "sessions:delete": {
3714
+ "aliases": [],
3715
+ "args": {
3716
+ "ids": {
3717
+ "description": "Session id(s) to delete",
3718
+ "name": "ids",
3719
+ "required": false
3720
+ }
3721
+ },
3722
+ "description": "Permanently delete captured sessions and everything stored with them (events, context snapshots, offloaded blobs)",
3723
+ "examples": [
3724
+ "<%= config.bin %> sessions delete 4f9d…",
3725
+ "<%= config.bin %> sessions delete 4f9d… 8a21…",
3726
+ "<%= config.bin %> sessions delete --project /work/client-a --yes"
3727
+ ],
3728
+ "flags": {
3729
+ "api-url": {
3730
+ "description": "Override API base URL",
3731
+ "env": "RULEMETRIC_API_URL",
3732
+ "hidden": true,
3733
+ "name": "api-url",
3734
+ "hasDynamicHelp": false,
3735
+ "multiple": false,
3736
+ "type": "option"
3737
+ },
3738
+ "project": {
3739
+ "description": "Delete every session captured under this project path (use with --yes).",
3740
+ "name": "project",
3741
+ "hasDynamicHelp": false,
3742
+ "multiple": false,
3743
+ "type": "option"
3744
+ },
3745
+ "yes": {
3746
+ "description": "Skip the confirmation prompt. Required for --project in non-interactive use.",
3747
+ "name": "yes",
3748
+ "allowNo": false,
3749
+ "type": "boolean"
3750
+ }
3751
+ },
3752
+ "hasDynamicHelp": false,
3753
+ "hiddenAliases": [],
3754
+ "id": "sessions:delete",
3755
+ "pluginAlias": "@rulemetric/cli",
3756
+ "pluginName": "@rulemetric/cli",
3757
+ "pluginType": "core",
3758
+ "strict": false,
3759
+ "enableJsonFlag": false,
3760
+ "isESM": true,
3761
+ "relativePath": [
3762
+ "dist",
3763
+ "commands",
3764
+ "sessions",
3765
+ "delete.js"
3766
+ ]
3767
+ },
3699
3768
  "sessions:end": {
3700
3769
  "aliases": [],
3701
3770
  "args": {},
@@ -4438,5 +4507,5 @@
4438
4507
  ]
4439
4508
  }
4440
4509
  },
4441
- "version": "0.7.37"
4510
+ "version": "0.7.39"
4442
4511
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rulemetric/cli",
3
- "version": "0.7.37",
3
+ "version": "0.7.39",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -77,9 +77,9 @@
77
77
  "postgres": "^3.4.0",
78
78
  "react": "^19.0.0",
79
79
  "zod": "^3.24.0",
80
- "@rulemetric/hooks": "0.7.37",
81
- "@rulemetric/proxy": "0.7.37",
82
- "@rulemetric/skills-registry": "0.7.37"
80
+ "@rulemetric/hooks": "0.7.39",
81
+ "@rulemetric/proxy": "0.7.39",
82
+ "@rulemetric/skills-registry": "0.7.39"
83
83
  },
84
84
  "//deps": "Worker (`evals agent`) runtime deps: the @opentelemetry/* set, @sentry/node, and postgres are STATIC top-level imports loaded at worker startup (via bundled @rulemetric/{telemetry,db}) — they MUST be runtime deps or a clean `npm i -g` crashes with ModuleLoadError. `better-sqlite3` is optionalDependencies (below): it's a native module, lazy `require()`'d inside a try/catch (packages/session providers cursor/opencode) so a missing binary degrades gracefully — making it a hard dep would break `npm i -g` on platforms without prebuilt binaries. `resend` stays a devDep: lazy `await import('resend')` guarded by RESEND_API_KEY, which end-user workers never set (provider falls back to noop). Classification verified via import-graph scan of dist/commands/evals/agent.js + per-importer static/lazy check.",
85
85
  "optionalDependencies": {
@@ -97,14 +97,14 @@
97
97
  "tsx": "^4.19.0",
98
98
  "typescript": "^5.9.0",
99
99
  "vitest": "^3.2.0",
100
+ "@rulemetric/api": "0.0.1",
100
101
  "@rulemetric/core": "0.0.1",
101
102
  "@rulemetric/db": "0.0.1",
102
103
  "@rulemetric/effectiveness": "0.0.1",
103
104
  "@rulemetric/email": "0.0.1",
104
105
  "@rulemetric/session": "0.2.1",
105
106
  "@rulemetric/telemetry": "0.0.1",
106
- "@rulemetric/typescript-config": "0.0.0",
107
- "@rulemetric/api": "0.0.1"
107
+ "@rulemetric/typescript-config": "0.0.0"
108
108
  },
109
109
  "scripts": {
110
110
  "build": "node scripts/build.mjs",
@@ -1,2 +0,0 @@
1
- import{a as d}from"./chunk-VX2GJCQ4.js";import{a as n}from"./chunk-ZLLER3HP.js";import{copyFileSync as C,mkdirSync as y,readFileSync as x,writeFileSync as w}from"node:fs";import{homedir as p}from"node:os";import{isAbsolute as S,join as f,resolve as b}from"node:path";function i(e){return f(e,d)}n(i,"captureConfigPath");function E(e){let r;try{r=x(i(e),"utf-8")}catch{return{}}try{let t=JSON.parse(r);if(!t||typeof t!="object"||Array.isArray(t))throw new Error("not a JSON object");return t}catch(t){throw new Error(`${i(e)} is not valid JSON (${t instanceof Error?t.message:String(t)}). Fix or delete it \u2014 refusing to overwrite what you wrote.`)}}n(E,"readCaptureConfig");function v(e,r){y(e,{recursive:!0});let t=i(e);return w(t,JSON.stringify(r,null,2)+`
2
- `),t}n(v,"writeCaptureConfig");function m(e,r=p()){let t=e.trim(),o=t==="~"?r:t.startsWith("~/")?f(r,t.slice(2)):t;return b(o)}n(m,"normaliseRoot");function F(e,r=p()){let t=e.trim();if(!t)return!1;let o=t==="~"?r:t.startsWith("~/")?f(r,t.slice(2)):t;return S(o)}n(F,"isUsableRoot");function N(e,r,t=p()){let o={...e.codex??{}},l=Array.isArray(o.roots)?o.roots.map(s=>m(String(s),t)):[],u=!1;if(r.op==="mode")o.mode=r.mode,r.mode==="all"&&delete o.roots;else if(r.op==="clear")delete o.mode,delete o.roots;else{let s=r.roots.map(c=>m(c,t)),g=r.op==="add"?[...new Set([...l,...s])]:l.filter(c=>!s.includes(c));g.length===0&&r.op==="remove"?(delete o.roots,o.mode="off",u=!0):(o.roots=g.sort(),o.mode="allowlist")}let a={...e};return Object.keys(o).length===0?delete a.codex:a.codex=o,{config:a,emptiedToOff:u}}n(N,"applyScopeEdit");function j(e){let r=i(e),t=`${r}.broken`;try{C(r,t)}catch{}return t}n(j,"backupUnparseableConfig");export{i as a,E as b,v as c,m as d,F as e,N as f,j as g};
@@ -1 +0,0 @@
1
- import{a as s}from"./chunk-ZLLER3HP.js";import{readFile as v,stat as w}from"node:fs/promises";import{homedir as E}from"node:os";import{isAbsolute as O,join as d,resolve as S,sep as m}from"node:path";var l="capture.json";function R(e,o){return e==="~"?o:e.startsWith("~/")?d(o,e.slice(2)):e}s(R,"expandTilde");function x(e,o){return e.map(r=>typeof r=="string"?r.trim():"").filter(Boolean).map(r=>R(r,o)).filter(r=>O(r)).map(r=>S(r))}s(x,"normaliseRoots");function h(e){return{mode:"off",roots:[],source:"config",error:e}}s(h,"failClosed");async function y(e){let o=e.env??process.env,r=e.home??E(),t=o.RULEMETRIC_CODEX_CAPTURE?.trim().toLowerCase();if(t==="off"||t==="none"||t==="0")return{mode:"off",roots:[],source:"env"};if(t==="all"||t==="1")return{mode:"all",roots:[],source:"env"};let i=o.RULEMETRIC_CODEX_ROOTS?.trim();if(i){let g=x(i.split(","),r);return g.length>0?{mode:"allowlist",roots:g,source:"env"}:{mode:"off",roots:[],source:"env",error:"RULEMETRIC_CODEX_ROOTS had no absolute paths"}}let n=d(e.configDir,l),c;try{c=await v(n,"utf8")}catch{return{mode:"all",roots:[],source:"default"}}let u;try{u=JSON.parse(c)}catch{return h(`${l} is present but is not valid JSON \u2014 Codex capture is OFF until it parses.`)}let a=u?.codex;if(!a||typeof a!="object")return{mode:"all",roots:[],source:"default"};let f=typeof a.mode=="string"?a.mode.trim().toLowerCase():void 0;if(f==="off")return{mode:"off",roots:[],source:"config"};if(f==="all")return{mode:"all",roots:[],source:"config"};let p=Array.isArray(a.roots)?a.roots:[];if(f===void 0&&p.length===0)return{mode:"all",roots:[],source:"default"};let C=x(p,r);return C.length===0?h(`${l} selects an allowlist but lists no roots (absolute paths required) \u2014 Codex capture is OFF.`):{mode:"allowlist",roots:C,source:"config"}}s(y,"loadCodexCaptureScope");function $(e,o){if(e.mode==="off")return!1;if(e.mode==="all")return!0;if(!o)return!1;let r=S(o);return e.roots.some(t=>r===t||r.startsWith(t.endsWith(m)?t:t+m))}s($,"isPathInScope");function T(e){if(e.error)return`OFF \u2014 ${e.error}`;switch(e.mode){case"off":return`off (${e.source}) \u2014 no Codex transcripts are swept`;case"allowlist":return`scoped to ${e.roots.length} path${e.roots.length===1?"":"s"} (${e.source})`;default:return"all projects (unscoped)"}}s(T,"describeCodexCaptureScope");function _(e){let o=null,r=null;return async()=>{let t=d(e.configDir,l),i;try{let u=await w(t);i=`${u.mtimeMs}:${u.size}`}catch{i="absent"}if(o&&r===i)return o;let n=await y(e),c=o===null||o.mode!==n.mode||o.error!==n.error||o.roots.join("\0")!==n.roots.join("\0");return o=n,r=i,c&&e.onChange?.(n),n}}s(_,"createCodexScopeWatcher");export{l as a,y as b,$ as c,T as d,_ as e};
File without changes