@rulemetric/cli 0.7.42 → 0.7.43

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.
@@ -0,0 +1 @@
1
+ import{b as A,c as L}from"./chunk-5R5RGKOW.js";import{b as G}from"./chunk-GIRPEMTW.js";import{a as _}from"./chunk-MODXEGCU.js";import{d as N,f as F}from"./chunk-B3BHB26P.js";import{e as f,f as $}from"./chunk-KLEF5D3A.js";import{a as d}from"./chunk-ZLLER3HP.js";import{readFileSync as D,realpathSync as U}from"node:fs";import P from"node:path";import O from"node:os";function X(s){let o=P.resolve(s);if(o===P.resolve(O.homedir()))return!1;let a=P.parse(o).root;if(o===a)return!1;try{let n=U(O.tmpdir());if(U(o)===n)return!1}catch{}return!0}d(X,"isScorableProjectPath");var V=5,z=Number(process.env.RULEMETRIC_MAX_SUGGESTION_PROJECTS??10),K=48,W=.5,T=400,Y=3,q=.6,Q=1;function Z(s){let o=s.bloated??[],a=new Set([...s.harmful.map(n=>n.id),...s.candidates.map(n=>n.id)]);return o.filter(n=>!a.has(n.id)).slice(0,Q).map(n=>({instructionId:n.id,estimatedTokens:n.estimatedTokens,topProjectId:n.topProjectId??null,score:.55,reason:`Costs ~${n.estimatedTokens} tokens every session and measures neutral across ${n.exposures} exposed session(s) \u2014 enough data to detect an effect, and none found. Consider shortening "${n.name}" rather than removing it.`+(n.containsSafetyLanguage?" CAUTION: it contains guardrail language (destructive-command or credential rules) \u2014 preserve those lines when shortening.":"")}))}d(Z,"buildTrimProposals");function tt(s){let o=[];for(let n of s.harmful){let c=n.verdict.delta;o.push({instructionId:n.id,score:Math.min(.95,.75+Math.abs(c)),topProjectId:n.topProjectId??null,reason:`Measured harmful: sessions using "${n.name}" scored ${(c*100).toFixed(1)}pp worse across ${n.exposures} exposed session(s). Observational \u2014 review before archiving.`})}let a=new Set(s.harmful.map(n=>n.id));for(let n of s.candidates)a.has(n.id)||o.push({instructionId:n.id,score:q,topProjectId:n.topProjectId??null,reason:`Unused: "${n.name}" is ${n.reason} (${n.totalExposures} lifetime exposure(s)) but still costs context budget every session.`});return o.slice(0,Y)}d(tt,"buildRemovalProposals");async function et(){let s=P.join(O.homedir(),".config","rulemetric","skills-registry.json");try{let o=D(s,"utf-8"),a=JSON.parse(o);return Date.now()-new Date(a.generatedAt).getTime()>K*60*60*1e3}catch{return!0}}d(et,"checkSkillsRegistryStale");var dt=d(async(s,o)=>{let a=N(),n=a!=="none";n?o.logger.info(`Scoring backend: ${a}`):o.logger.warn("No LLM backend available (claude CLI missing and ANTHROPIC_API_KEY unset); skipping relevance scoring. Removal/trim proposals still run \u2014 they need no LLM.");let c;try{c=(await f("/api/sessions/project-paths?limit="+z)).projectPaths}catch(t){o.logger.warn(`Failed to fetch project paths: ${t instanceof Error?t.message:String(t)}`);return}if(c.length===0){o.logger.info("No recent project paths; nothing to score");return}let R=new Map;try{let t=await f("/api/projects?limit=200");for(let e of t.projects??[])e.primaryCheckoutPath&&R.set(_(e.primaryCheckoutPath),e.id)}catch(t){o.logger.warn(`Failed to fetch projects for id resolution: ${t instanceof Error?t.message:String(t)}`)}let w=new Map;try{let t=await f(`/api/catalog?limit=200&contentPreview=${T}`);for(let e of t)w.set(e.id,{id:e.id,name:e.name,description:e.description??"",tags:e.tags??[],contentPreview:(e.contentPreview??"").slice(0,T)})}catch(t){o.logger.warn(`Failed to fetch catalog: ${t instanceof Error?t.message:String(t)}`)}try{let t=await f("/api/instructions?limit=100");for(let e of t.instructions??[])w.has(e.id)||w.set(e.id,{id:e.id,name:e.name,description:e.description??"",tags:e.tags??[],contentPreview:(e.content??"").slice(0,T)})}catch(t){o.logger.warn(`Failed to fetch personal instructions: ${t instanceof Error?t.message:String(t)}`)}let h=[],g=[];try{let t=await f("/api/insights/groom-candidates");if(!t.captureHealthy)o.logger.info(`Grooming paused: ${t.reason??"capture unhealthy"}`);else{h=tt(t),g=Z(t);let e=t.safetyGuarded+t.harmfulSafetyGuarded;o.logger.info(`Removal proposals: ${h.length} (${t.harmful.length} measured-harmful, ${t.candidates.length} never-used, ${e} withheld by the safety allowlist); trim proposals: ${g.length} (${(t.bloated??[]).length} measured-neutral and expensive, ${t.trimSafetyFlagged??0} flagged as containing guardrail language)`)}}catch(t){o.logger.warn(`Failed to fetch groom candidates: ${t instanceof Error?t.message:String(t)}`)}let y=[...w.values()];if(y.length===0&&h.length===0&&g.length===0){o.logger.info("No candidate instructions and nothing to retire; nothing to score");return}o.logger.info(`Scoring ${y.length} candidates across ${c.length} project(s)`);let x=0,l=null,S=new Set;for(let t of c)try{let e=_(t);if(!X(e)){o.logger.info(`Skipping ${e}: not a project directory (home/root)`);continue}let u=G(e),b=n&&u.length>0;u.length===0&&o.logger.info(`${e}: insufficient language signals; removal/trim only`);let H={name:P.basename(e),description:null,languages:u,topics:[],dependencies:[]},k=b?L(y):[];b&&o.logger.info(`Scoring ${y.length} candidates for ${e} in ${k.length} batch(es)`);let v=[],j=0;for(let r of k)try{let i=await F(A(H,r),"",4096);if(!i){j++;continue}let C=i.recommendations??[];for(let m of C)typeof m.instructionId=="string"&&typeof m.score=="number"&&typeof m.reason=="string"&&v.push({instructionId:m.instructionId,score:m.score,reason:m.reason})}catch(i){j++,o.logger.warn(`Batch failed for ${e}: ${i instanceof Error?i.message:String(i)}`)}j>0&&o.logger.warn(`${j}/${k.length} batch(es) failed for ${e} (backend ${a}); suggestions are partial`),b&&v.length===0&&o.logger.warn(`No usable LLM output for ${e} (backend ${a})`);let J=v.filter(r=>r.score>=W).sort((r,i)=>i.score-r.score).slice(0,V),E=R.get(e),B=l===null||l===e;l===null&&(l=e);let M=d(r=>r.topProjectId?r.topProjectId===E:B,"placeHere"),p=[...J.map(r=>({instructionId:r.instructionId,score:r.score,reason:r.reason,kind:"add"})),...h.filter(M).map(({topProjectId:r,...i})=>({...i,kind:"remove"})),...g.filter(M).map(({estimatedTokens:r,topProjectId:i,...C})=>({...C,kind:"trim"}))];if(p.length===0){o.logger.info(`Nothing to suggest for ${e}`);continue}await $("/api/instruction-suggestions/batch-upsert",{projectPath:e,...E?{projectId:E}:{},suggestions:p}),o.logger.info(`${e}: ${p.filter(r=>r.kind==="add").length} add + ${p.filter(r=>r.kind==="remove").length} remove + ${p.filter(r=>r.kind==="trim").length} trim`);for(let r of p)r.kind!=="add"&&S.add(r.instructionId);x++}catch(e){o.logger.warn(`Failed to score ${t}: ${e instanceof Error?e.message:String(e)}`)}let I=[...h.filter(t=>!S.has(t.instructionId)),...g.filter(t=>!S.has(t.instructionId)).map(({estimatedTokens:t,...e})=>e)];if(I.length>0&&l)try{let t=new Set(g.map(e=>e.instructionId));await $("/api/instruction-suggestions/batch-upsert",{projectPath:l,...R.get(l)?{projectId:R.get(l)}:{},suggestions:I.map(({topProjectId:e,...u})=>({...u,kind:t.has(u.instructionId)?"trim":"remove"}))}),o.logger.info(`Orphan sweep: ${I.length} proposal(s) whose project was not scored this run placed on ${l}`)}catch(t){o.logger.warn(`Orphan sweep failed: ${t instanceof Error?t.message:String(t)}`)}if(await et())try{await $("/api/instruction-suggestions/mark-stale",{}),o.logger.warn("Skills registry is stale (>48h); marked all suggestions stale")}catch{}o.logger.info(`Done: scored ${x}/${c.length} projects`)},"cronSuggestInstructions");export{X as a,Z as b,tt as c,dt as d};
@@ -1 +1 @@
1
- import{c as C}from"./chunk-5XUN743A.js";import{b as S}from"./chunk-BLCMXTIK.js";import{a as M}from"./chunk-KZZ2MUQQ.js";import{a as L}from"./chunk-DGH4FBMM.js";import{a as y}from"./chunk-RSKQRVPJ.js";import{a as H}from"./chunk-HXZM2UHO.js";import{d as _}from"./chunk-PRKJFYVF.js";import{b as R}from"./chunk-YW3JQKGY.js";import{a as T}from"./chunk-RWF75MTD.js";import{a as A}from"./chunk-O2BKBW7Z.js";import{a as E}from"./chunk-KGQ5W54Y.js";import{a as I}from"./chunk-O7PSLZO6.js";import{b as h}from"./chunk-5RBLIVBF.js";import{a as x}from"./chunk-MOAJLSYV.js";import{a as P}from"./chunk-EN43UYBN.js";import{a as N}from"./chunk-FAXV5AAG.js";import{a as k}from"./chunk-UF6US7VU.js";import{j as b}from"./chunk-2RCWYVEU.js";import{d as w}from"./chunk-NTKO4H2K.js";import{b as f,e as v,f as p}from"./chunk-KLEF5D3A.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-5XUN743A.js";import{b as S}from"./chunk-BLCMXTIK.js";import{a as M}from"./chunk-KZZ2MUQQ.js";import{a as L}from"./chunk-DGH4FBMM.js";import{a as y}from"./chunk-RSKQRVPJ.js";import{a as H}from"./chunk-HXZM2UHO.js";import{d as _}from"./chunk-V2IEFHT7.js";import{b as R}from"./chunk-YW3JQKGY.js";import{a as T}from"./chunk-RWF75MTD.js";import{a as A}from"./chunk-O2BKBW7Z.js";import{a as E}from"./chunk-KGQ5W54Y.js";import{a as I}from"./chunk-O7PSLZO6.js";import{b as h}from"./chunk-5RBLIVBF.js";import{a as x}from"./chunk-MOAJLSYV.js";import{a as P}from"./chunk-EN43UYBN.js";import{a as N}from"./chunk-FAXV5AAG.js";import{a as k}from"./chunk-UF6US7VU.js";import{j as b}from"./chunk-2RCWYVEU.js";import{d as w}from"./chunk-NTKO4H2K.js";import{b as f,e as v,f as p}from"./chunk-KLEF5D3A.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,3 +1,3 @@
1
- import{a as C,b as L,c as D}from"../../chunk-GWDZNGUP.js";import{e as I}from"../../chunk-O56AZKJL.js";import"../../chunk-5XUN743A.js";import"../../chunk-BLCMXTIK.js";import"../../chunk-KZZ2MUQQ.js";import"../../chunk-DGH4FBMM.js";import"../../chunk-6QKI756T.js";import"../../chunk-RSKQRVPJ.js";import"../../chunk-HXZM2UHO.js";import"../../chunk-PRKJFYVF.js";import"../../chunk-YW3JQKGY.js";import"../../chunk-RWF75MTD.js";import"../../chunk-N7TGRFVZ.js";import{j as d}from"../../chunk-7G6T5C7J.js";import"../../chunk-O2BKBW7Z.js";import"../../chunk-KGQ5W54Y.js";import"../../chunk-O7PSLZO6.js";import"../../chunk-QFVGUZDO.js";import"../../chunk-5R5RGKOW.js";import"../../chunk-5RBLIVBF.js";import"../../chunk-MOAJLSYV.js";import"../../chunk-EN43UYBN.js";import"../../chunk-FAXV5AAG.js";import"../../chunk-UF6US7VU.js";import"../../chunk-YQ56FQEO.js";import"../../chunk-5KD2N2MH.js";import"../../chunk-GIRPEMTW.js";import"../../chunk-MODXEGCU.js";import"../../chunk-7DFNBRLY.js";import"../../chunk-4VZLIGMS.js";import"../../chunk-CNOD6HWU.js";import"../../chunk-AI6FMGKM.js";import"../../chunk-6UEFCMR2.js";import"../../chunk-2RCWYVEU.js";import"../../chunk-RMDLJN4L.js";import"../../chunk-BL4BN6RU.js";import"../../chunk-DBELYMDA.js";import"../../chunk-NTKO4H2K.js";import"../../chunk-CJRYYV76.js";import"../../chunk-ATL4WZBF.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-2DXBC2JQ.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-NIRD7ETU.js";import"../../chunk-6VKQT2J3.js";import"../../chunk-QY3UKLDE.js";import"../../chunk-3AV3GTMP.js";import{f as b}from"../../chunk-KLEF5D3A.js";import{e as P,l as f}from"../../chunk-JZ5Z2BRO.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-W74LSQ6Y.js";import"../../chunk-5XUN743A.js";import"../../chunk-BLCMXTIK.js";import"../../chunk-KZZ2MUQQ.js";import"../../chunk-DGH4FBMM.js";import"../../chunk-6QKI756T.js";import"../../chunk-RSKQRVPJ.js";import"../../chunk-HXZM2UHO.js";import"../../chunk-V2IEFHT7.js";import"../../chunk-YW3JQKGY.js";import"../../chunk-RWF75MTD.js";import"../../chunk-N7TGRFVZ.js";import{j as d}from"../../chunk-7G6T5C7J.js";import"../../chunk-O2BKBW7Z.js";import"../../chunk-KGQ5W54Y.js";import"../../chunk-O7PSLZO6.js";import"../../chunk-QFVGUZDO.js";import"../../chunk-5R5RGKOW.js";import"../../chunk-5RBLIVBF.js";import"../../chunk-MOAJLSYV.js";import"../../chunk-EN43UYBN.js";import"../../chunk-FAXV5AAG.js";import"../../chunk-UF6US7VU.js";import"../../chunk-YQ56FQEO.js";import"../../chunk-5KD2N2MH.js";import"../../chunk-GIRPEMTW.js";import"../../chunk-MODXEGCU.js";import"../../chunk-7DFNBRLY.js";import"../../chunk-4VZLIGMS.js";import"../../chunk-CNOD6HWU.js";import"../../chunk-AI6FMGKM.js";import"../../chunk-6UEFCMR2.js";import"../../chunk-2RCWYVEU.js";import"../../chunk-RMDLJN4L.js";import"../../chunk-BL4BN6RU.js";import"../../chunk-DBELYMDA.js";import"../../chunk-NTKO4H2K.js";import"../../chunk-CJRYYV76.js";import"../../chunk-ATL4WZBF.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-2DXBC2JQ.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-NIRD7ETU.js";import"../../chunk-6VKQT2J3.js";import"../../chunk-QY3UKLDE.js";import"../../chunk-3AV3GTMP.js";import{f as b}from"../../chunk-KLEF5D3A.js";import{e as P,l as f}from"../../chunk-JZ5Z2BRO.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 +1 @@
1
- import{a,b,c,d,e}from"../chunk-O56AZKJL.js";import"../chunk-5XUN743A.js";import"../chunk-BLCMXTIK.js";import"../chunk-KZZ2MUQQ.js";import"../chunk-DGH4FBMM.js";import"../chunk-6QKI756T.js";import"../chunk-RSKQRVPJ.js";import"../chunk-HXZM2UHO.js";import"../chunk-PRKJFYVF.js";import"../chunk-YW3JQKGY.js";import"../chunk-RWF75MTD.js";import"../chunk-N7TGRFVZ.js";import"../chunk-7G6T5C7J.js";import"../chunk-O2BKBW7Z.js";import"../chunk-KGQ5W54Y.js";import"../chunk-O7PSLZO6.js";import"../chunk-QFVGUZDO.js";import"../chunk-5R5RGKOW.js";import"../chunk-5RBLIVBF.js";import"../chunk-MOAJLSYV.js";import"../chunk-EN43UYBN.js";import"../chunk-FAXV5AAG.js";import"../chunk-UF6US7VU.js";import"../chunk-YQ56FQEO.js";import"../chunk-5KD2N2MH.js";import"../chunk-GIRPEMTW.js";import"../chunk-MODXEGCU.js";import"../chunk-7DFNBRLY.js";import"../chunk-4VZLIGMS.js";import"../chunk-CNOD6HWU.js";import"../chunk-AI6FMGKM.js";import"../chunk-6UEFCMR2.js";import"../chunk-2RCWYVEU.js";import"../chunk-RMDLJN4L.js";import"../chunk-BL4BN6RU.js";import"../chunk-DBELYMDA.js";import"../chunk-NTKO4H2K.js";import"../chunk-CJRYYV76.js";import"../chunk-ATL4WZBF.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-KLEF5D3A.js";import"../chunk-JZ5Z2BRO.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-W74LSQ6Y.js";import"../chunk-5XUN743A.js";import"../chunk-BLCMXTIK.js";import"../chunk-KZZ2MUQQ.js";import"../chunk-DGH4FBMM.js";import"../chunk-6QKI756T.js";import"../chunk-RSKQRVPJ.js";import"../chunk-HXZM2UHO.js";import"../chunk-V2IEFHT7.js";import"../chunk-YW3JQKGY.js";import"../chunk-RWF75MTD.js";import"../chunk-N7TGRFVZ.js";import"../chunk-7G6T5C7J.js";import"../chunk-O2BKBW7Z.js";import"../chunk-KGQ5W54Y.js";import"../chunk-O7PSLZO6.js";import"../chunk-QFVGUZDO.js";import"../chunk-5R5RGKOW.js";import"../chunk-5RBLIVBF.js";import"../chunk-MOAJLSYV.js";import"../chunk-EN43UYBN.js";import"../chunk-FAXV5AAG.js";import"../chunk-UF6US7VU.js";import"../chunk-YQ56FQEO.js";import"../chunk-5KD2N2MH.js";import"../chunk-GIRPEMTW.js";import"../chunk-MODXEGCU.js";import"../chunk-7DFNBRLY.js";import"../chunk-4VZLIGMS.js";import"../chunk-CNOD6HWU.js";import"../chunk-AI6FMGKM.js";import"../chunk-6UEFCMR2.js";import"../chunk-2RCWYVEU.js";import"../chunk-RMDLJN4L.js";import"../chunk-BL4BN6RU.js";import"../chunk-DBELYMDA.js";import"../chunk-NTKO4H2K.js";import"../chunk-CJRYYV76.js";import"../chunk-ATL4WZBF.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-KLEF5D3A.js";import"../chunk-JZ5Z2BRO.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}from"../../chunk-PRKJFYVF.js";import"../../chunk-5R5RGKOW.js";import"../../chunk-GIRPEMTW.js";import"../../chunk-MODXEGCU.js";import"../../chunk-B3BHB26P.js";import"../../chunk-N7ODX6PO.js";import"../../chunk-PJ3WHQ67.js";import"../../chunk-KLEF5D3A.js";import"../../chunk-JZ5Z2BRO.js";import"../../chunk-ZLLER3HP.js";export{c as buildRemovalProposals,b as buildTrimProposals,d as cronSuggestInstructions,a as isScorableProjectPath};
1
+ import{a,b,c,d}from"../../chunk-V2IEFHT7.js";import"../../chunk-5R5RGKOW.js";import"../../chunk-GIRPEMTW.js";import"../../chunk-MODXEGCU.js";import"../../chunk-B3BHB26P.js";import"../../chunk-N7ODX6PO.js";import"../../chunk-PJ3WHQ67.js";import"../../chunk-KLEF5D3A.js";import"../../chunk-JZ5Z2BRO.js";import"../../chunk-ZLLER3HP.js";export{c as buildRemovalProposals,b as buildTrimProposals,d as cronSuggestInstructions,a as isScorableProjectPath};
@@ -1 +1 @@
1
- import{a as l}from"../chunk-3BZPEN5H.js";import{d as g}from"../chunk-PRKJFYVF.js";import"../chunk-N7TGRFVZ.js";import"../chunk-7G6T5C7J.js";import"../chunk-5R5RGKOW.js";import{a as u}from"../chunk-UF6US7VU.js";import"../chunk-GIRPEMTW.js";import"../chunk-MODXEGCU.js";import"../chunk-B3BHB26P.js";import"../chunk-N7ODX6PO.js";import"../chunk-PJ3WHQ67.js";import{a as i}from"../chunk-GY5IJ4RS.js";import"../chunk-KLEF5D3A.js";import"../chunk-JZ5Z2BRO.js";import{a as o}from"../chunk-ZLLER3HP.js";var c={cron_check_changelog:o(async(r,e)=>{let s=await l({logger:{info:o(t=>e.logger.info(t),"info"),warn:o(t=>e.logger.warn(t),"warn")}});e.logger.info(`[cron_check_changelog] result: created=${s.createdCount} skipped=${s.skippedCount}`)},"cron_check_changelog"),cron_suggest_instructions:o((r,e)=>g(r,e),"cron_suggest_instructions"),cron_refresh_skills:o((r,e)=>u(r,e),"cron_refresh_skills")},p=i.map(r=>{let e=c[r.name];if(!e)throw new Error(`manual-tasks: no handler registered for "${r.name}"`);return{...r,handler:e}});async function m(r){let e=p.find(n=>n.name===r);if(!e)return{name:r,durationMs:0,ok:!1,error:`Unknown task: ${r}`,logs:[]};let s=[],t={logger:{info:o(n=>s.push({level:"info",message:n}),"info"),warn:o(n=>s.push({level:"warn",message:n}),"warn"),error:o(n=>s.push({level:"error",message:n}),"error")},job:{attempts:0}},a=Date.now();try{return await e.handler({},t),{name:r,durationMs:Date.now()-a,ok:!0,logs:s}}catch(n){return{name:r,durationMs:Date.now()-a,ok:!1,error:n instanceof Error?n.message:String(n),logs:s}}}o(m,"runManualTask");export{p as MANUAL_TASKS,m as runManualTask};
1
+ import{a as l}from"../chunk-3BZPEN5H.js";import{d as g}from"../chunk-V2IEFHT7.js";import"../chunk-N7TGRFVZ.js";import"../chunk-7G6T5C7J.js";import"../chunk-5R5RGKOW.js";import{a as u}from"../chunk-UF6US7VU.js";import"../chunk-GIRPEMTW.js";import"../chunk-MODXEGCU.js";import"../chunk-B3BHB26P.js";import"../chunk-N7ODX6PO.js";import"../chunk-PJ3WHQ67.js";import{a as i}from"../chunk-GY5IJ4RS.js";import"../chunk-KLEF5D3A.js";import"../chunk-JZ5Z2BRO.js";import{a as o}from"../chunk-ZLLER3HP.js";var c={cron_check_changelog:o(async(r,e)=>{let s=await l({logger:{info:o(t=>e.logger.info(t),"info"),warn:o(t=>e.logger.warn(t),"warn")}});e.logger.info(`[cron_check_changelog] result: created=${s.createdCount} skipped=${s.skippedCount}`)},"cron_check_changelog"),cron_suggest_instructions:o((r,e)=>g(r,e),"cron_suggest_instructions"),cron_refresh_skills:o((r,e)=>u(r,e),"cron_refresh_skills")},p=i.map(r=>{let e=c[r.name];if(!e)throw new Error(`manual-tasks: no handler registered for "${r.name}"`);return{...r,handler:e}});async function m(r){let e=p.find(n=>n.name===r);if(!e)return{name:r,durationMs:0,ok:!1,error:`Unknown task: ${r}`,logs:[]};let s=[],t={logger:{info:o(n=>s.push({level:"info",message:n}),"info"),warn:o(n=>s.push({level:"warn",message:n}),"warn"),error:o(n=>s.push({level:"error",message:n}),"error")},job:{attempts:0}},a=Date.now();try{return await e.handler({},t),{name:r,durationMs:Date.now()-a,ok:!0,logs:s}}catch(n){return{name:r,durationMs:Date.now()-a,ok:!1,error:n instanceof Error?n.message:String(n),logs:s}}}o(m,"runManualTask");export{p as MANUAL_TASKS,m as runManualTask};
@@ -4657,5 +4657,5 @@
4657
4657
  ]
4658
4658
  }
4659
4659
  },
4660
- "version": "0.7.42"
4660
+ "version": "0.7.43"
4661
4661
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rulemetric/cli",
3
- "version": "0.7.42",
3
+ "version": "0.7.43",
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.42",
81
- "@rulemetric/proxy": "0.7.42",
82
- "@rulemetric/skills-registry": "0.7.42"
80
+ "@rulemetric/hooks": "0.7.43",
81
+ "@rulemetric/proxy": "0.7.43",
82
+ "@rulemetric/skills-registry": "0.7.43"
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": {
@@ -102,9 +102,9 @@
102
102
  "@rulemetric/db": "0.0.1",
103
103
  "@rulemetric/effectiveness": "0.0.1",
104
104
  "@rulemetric/email": "0.0.1",
105
- "@rulemetric/typescript-config": "0.0.0",
105
+ "@rulemetric/session": "0.2.1",
106
106
  "@rulemetric/telemetry": "0.0.1",
107
- "@rulemetric/session": "0.2.1"
107
+ "@rulemetric/typescript-config": "0.0.0"
108
108
  },
109
109
  "scripts": {
110
110
  "build": "node scripts/build.mjs",
@@ -1 +0,0 @@
1
- import{b as x,c as M}from"./chunk-5R5RGKOW.js";import{b as L}from"./chunk-GIRPEMTW.js";import{a as E}from"./chunk-MODXEGCU.js";import{d as A,f as N}from"./chunk-B3BHB26P.js";import{e as m,f as j}from"./chunk-KLEF5D3A.js";import{a as d}from"./chunk-ZLLER3HP.js";import{readFileSync as J,realpathSync as F}from"node:fs";import P from"node:path";import _ from"node:os";function B(s){let o=P.resolve(s);if(o===P.resolve(_.homedir()))return!1;let a=P.parse(o).root;if(o===a)return!1;try{let n=F(_.tmpdir());if(F(o)===n)return!1}catch{}return!0}d(B,"isScorableProjectPath");var D=5,X=Number(process.env.RULEMETRIC_MAX_SUGGESTION_PROJECTS??10),V=48,z=.5,C=400,K=3,W=.6,Y=1;function q(s){let o=s.bloated??[],a=new Set([...s.harmful.map(n=>n.id),...s.candidates.map(n=>n.id)]);return o.filter(n=>!a.has(n.id)).slice(0,Y).map(n=>({instructionId:n.id,estimatedTokens:n.estimatedTokens,topProjectId:n.topProjectId??null,score:.55,reason:`Costs ~${n.estimatedTokens} tokens every session and measures neutral across ${n.exposures} exposed session(s) \u2014 enough data to detect an effect, and none found. Consider shortening "${n.name}" rather than removing it.`+(n.containsSafetyLanguage?" CAUTION: it contains guardrail language (destructive-command or credential rules) \u2014 preserve those lines when shortening.":"")}))}d(q,"buildTrimProposals");function Q(s){let o=[];for(let n of s.harmful){let l=n.verdict.delta;o.push({instructionId:n.id,score:Math.min(.95,.75+Math.abs(l)),topProjectId:n.topProjectId??null,reason:`Measured harmful: sessions using "${n.name}" scored ${(l*100).toFixed(1)}pp worse across ${n.exposures} exposed session(s). Observational \u2014 review before archiving.`})}let a=new Set(s.harmful.map(n=>n.id));for(let n of s.candidates)a.has(n.id)||o.push({instructionId:n.id,score:W,topProjectId:n.topProjectId??null,reason:`Unused: "${n.name}" is ${n.reason} (${n.totalExposures} lifetime exposure(s)) but still costs context budget every session.`});return o.slice(0,K)}d(Q,"buildRemovalProposals");async function Z(){let s=P.join(_.homedir(),".config","rulemetric","skills-registry.json");try{let o=J(s,"utf-8"),a=JSON.parse(o);return Date.now()-new Date(a.generatedAt).getTime()>V*60*60*1e3}catch{return!0}}d(Z,"checkSkillsRegistryStale");var ct=d(async(s,o)=>{let a=A();if(a==="none"){o.logger.warn("No LLM backend available (claude CLI missing and ANTHROPIC_API_KEY unset); skipping suggestion compute");return}o.logger.info(`Scoring backend: ${a}`);let n;try{n=(await m("/api/sessions/project-paths?limit="+X)).projectPaths}catch(t){o.logger.warn(`Failed to fetch project paths: ${t instanceof Error?t.message:String(t)}`);return}if(n.length===0){o.logger.info("No recent project paths; nothing to score");return}let l=new Map;try{let t=await m("/api/projects?limit=200");for(let e of t.projects??[])e.primaryCheckoutPath&&l.set(E(e.primaryCheckoutPath),e.id)}catch(t){o.logger.warn(`Failed to fetch projects for id resolution: ${t instanceof Error?t.message:String(t)}`)}let w=new Map;try{let t=await m(`/api/catalog?limit=200&contentPreview=${C}`);for(let e of t)w.set(e.id,{id:e.id,name:e.name,description:e.description??"",tags:e.tags??[],contentPreview:(e.contentPreview??"").slice(0,C)})}catch(t){o.logger.warn(`Failed to fetch catalog: ${t instanceof Error?t.message:String(t)}`)}try{let t=await m("/api/instructions?limit=100");for(let e of t.instructions??[])w.has(e.id)||w.set(e.id,{id:e.id,name:e.name,description:e.description??"",tags:e.tags??[],contentPreview:(e.content??"").slice(0,C)})}catch(t){o.logger.warn(`Failed to fetch personal instructions: ${t instanceof Error?t.message:String(t)}`)}let f=[],g=[];try{let t=await m("/api/insights/groom-candidates");if(!t.captureHealthy)o.logger.info(`Grooming paused: ${t.reason??"capture unhealthy"}`);else{f=Q(t),g=q(t);let e=t.safetyGuarded+t.harmfulSafetyGuarded;o.logger.info(`Removal proposals: ${f.length} (${t.harmful.length} measured-harmful, ${t.candidates.length} never-used, ${e} withheld by the safety allowlist); trim proposals: ${g.length} (${(t.bloated??[]).length} measured-neutral and expensive, ${t.trimSafetyFlagged??0} flagged as containing guardrail language)`)}}catch(t){o.logger.warn(`Failed to fetch groom candidates: ${t instanceof Error?t.message:String(t)}`)}let R=[...w.values()];if(R.length===0&&f.length===0&&g.length===0){o.logger.info("No candidate instructions and nothing to retire; nothing to score");return}o.logger.info(`Scoring ${R.length} candidates across ${n.length} project(s)`);let T=0,c=null,$=new Set;for(let t of n)try{let e=E(t);if(!B(e)){o.logger.info(`Skipping ${e}: not a project directory (home/root)`);continue}let h=L(e);if(h.length===0){o.logger.info(`Skipping ${e}: insufficient language signals`);continue}let G={name:P.basename(e),description:null,languages:h,topics:[],dependencies:[]},I=M(R);o.logger.info(`Scoring ${R.length} candidates for ${e} in ${I.length} batch(es)`);let b=[],y=0;for(let r of I)try{let i=await N(x(G,r),"",4096);if(!i){y++;continue}let v=i.recommendations??[];for(let p of v)typeof p.instructionId=="string"&&typeof p.score=="number"&&typeof p.reason=="string"&&b.push({instructionId:p.instructionId,score:p.score,reason:p.reason})}catch(i){y++,o.logger.warn(`Batch failed for ${e}: ${i instanceof Error?i.message:String(i)}`)}y>0&&o.logger.warn(`${y}/${I.length} batch(es) failed for ${e} (backend ${a}); suggestions are partial`),b.length===0&&o.logger.warn(`No usable LLM output for ${e} (backend ${a})`);let U=b.filter(r=>r.score>=z).sort((r,i)=>i.score-r.score).slice(0,D),k=l.get(e),H=c===null||c===e;c===null&&(c=e);let O=d(r=>r.topProjectId?r.topProjectId===k:H,"placeHere"),u=[...U.map(r=>({instructionId:r.instructionId,score:r.score,reason:r.reason,kind:"add"})),...f.filter(O).map(({topProjectId:r,...i})=>({...i,kind:"remove"})),...g.filter(O).map(({estimatedTokens:r,topProjectId:i,...v})=>({...v,kind:"trim"}))];if(u.length===0){o.logger.info(`Nothing to suggest for ${e}`);continue}await j("/api/instruction-suggestions/batch-upsert",{projectPath:e,...k?{projectId:k}:{},suggestions:u}),o.logger.info(`${e}: ${u.filter(r=>r.kind==="add").length} add + ${u.filter(r=>r.kind==="remove").length} remove + ${u.filter(r=>r.kind==="trim").length} trim`);for(let r of u)r.kind!=="add"&&$.add(r.instructionId);T++}catch(e){o.logger.warn(`Failed to score ${t}: ${e instanceof Error?e.message:String(e)}`)}let S=[...f.filter(t=>!$.has(t.instructionId)),...g.filter(t=>!$.has(t.instructionId)).map(({estimatedTokens:t,...e})=>e)];if(S.length>0&&c)try{let t=new Set(g.map(e=>e.instructionId));await j("/api/instruction-suggestions/batch-upsert",{projectPath:c,...l.get(c)?{projectId:l.get(c)}:{},suggestions:S.map(({topProjectId:e,...h})=>({...h,kind:t.has(h.instructionId)?"trim":"remove"}))}),o.logger.info(`Orphan sweep: ${S.length} proposal(s) whose project was not scored this run placed on ${c}`)}catch(t){o.logger.warn(`Orphan sweep failed: ${t instanceof Error?t.message:String(t)}`)}if(await Z())try{await j("/api/instruction-suggestions/mark-stale",{}),o.logger.warn("Skills registry is stale (>48h); marked all suggestions stale")}catch{}o.logger.info(`Done: scored ${T}/${n.length} projects`)},"cronSuggestInstructions");export{B as a,q as b,Q as c,ct as d};