@rulemetric/cli 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/base-command.js +1 -1
- package/dist/{chunk-R6JXE273.js → chunk-3A7RPMNN.js} +1 -1
- package/dist/{chunk-X3VL5H24.js → chunk-3IH22LYI.js} +1 -1
- package/dist/{chunk-CNOD6HWU.js → chunk-3VYV6ZYB.js} +1 -1
- package/dist/{chunk-3DGL2ZY3.js → chunk-4STKWINN.js} +1 -1
- package/dist/{chunk-CBUTNIJA.js → chunk-4T2FJLDA.js} +1 -1
- package/dist/{chunk-3AZV7ZPJ.js → chunk-553EGRRW.js} +1 -1
- package/dist/{chunk-EQHKCGSX.js → chunk-6SUN4NOY.js} +1 -1
- package/dist/{chunk-HYDGERWD.js → chunk-7BYMIHIB.js} +1 -1
- package/dist/{chunk-LLIHRQPH.js → chunk-7L4P7FCK.js} +1 -1
- package/dist/{chunk-7FZB65VH.js → chunk-7LXG3DDL.js} +1 -1
- package/dist/{chunk-KWNIKGAE.js → chunk-BN54LTXD.js} +1 -1
- package/dist/{chunk-X3RTCN6S.js → chunk-DAD4YBYC.js} +1 -1
- package/dist/{chunk-MO57LGGK.js → chunk-EOJ3LAP6.js} +1 -1
- package/dist/{chunk-QTZPLAYC.js → chunk-ERNDMEYG.js} +1 -1
- package/dist/{chunk-YFQ4FOAS.js → chunk-F5WE6JXK.js} +1 -1
- package/dist/{chunk-5EDINFHF.js → chunk-FH55JFUY.js} +1 -1
- package/dist/chunk-FK73GD2X.js +2 -0
- package/dist/{chunk-CDDICCY2.js → chunk-FORJT5H6.js} +1 -1
- package/dist/{chunk-RZTVYUX4.js → chunk-H6MN2AAF.js} +1 -1
- package/dist/{chunk-IVDTORX5.js → chunk-HKC224ZO.js} +1 -1
- package/dist/{chunk-2B7Y6JNB.js → chunk-MIOMKROL.js} +1 -1
- package/dist/{chunk-B3BHB26P.js → chunk-MODFTCZY.js} +1 -1
- package/dist/{chunk-PKLXZYBY.js → chunk-N7ML6X6Y.js} +1 -1
- package/dist/{chunk-SYTQDPPN.js → chunk-NDZVH5QW.js} +1 -1
- package/dist/{chunk-FWTYR36W.js → chunk-NTJKAIHS.js} +1 -1
- package/dist/{chunk-QAV4HW7D.js → chunk-OFC7HIBX.js} +1 -1
- package/dist/{chunk-K4B24SMJ.js → chunk-OFSUKSZ2.js} +1 -1
- package/dist/{chunk-UUZB4IKU.js → chunk-OI7MOALX.js} +1 -1
- package/dist/{chunk-NTKO4H2K.js → chunk-OPUI7CM2.js} +1 -1
- package/dist/chunk-PZNWH4VQ.js +7 -0
- package/dist/{chunk-6M74HH6Y.js → chunk-RSMLOYVJ.js} +1 -1
- package/dist/chunk-S7YDBO42.js +1 -0
- package/dist/{chunk-KHWG7ZG4.js → chunk-SE5SRPIB.js} +1 -1
- package/dist/{chunk-JPUH3V67.js → chunk-TCR7TSAJ.js} +1 -1
- package/dist/{chunk-DZ3FBQYD.js → chunk-UC377K7P.js} +1 -1
- package/dist/{chunk-GF76D2DU.js → chunk-UY5QYCTK.js} +1 -1
- package/dist/{chunk-XRTZU7IZ.js → chunk-V5MJ4ICC.js} +1 -1
- package/dist/chunk-VKVWEG5J.js +11 -0
- package/dist/chunk-VXM4PEED.js +46 -0
- package/dist/{chunk-C2275MFP.js → chunk-W2SG3KND.js} +1 -1
- package/dist/{chunk-E2NVNLFD.js → chunk-W65UX4FC.js} +1 -1
- package/dist/{chunk-SANYAPBK.js → chunk-WEBB76XA.js} +1 -1
- package/dist/{chunk-VA5DPQB4.js → chunk-WVJEBQYU.js} +1 -1
- package/dist/{chunk-S62MK372.js → chunk-X4N4MT2I.js} +1 -1
- package/dist/{chunk-BPP7AEFW.js → chunk-XILSJP4P.js} +1 -1
- package/dist/{chunk-VFYT3SC5.js → chunk-YVM2CHNV.js} +1 -1
- package/dist/{chunk-PQN2GAG4.js → chunk-YY53MMH7.js} +1 -1
- package/dist/{chunk-WKDXH7NO.js → chunk-ZJOYLBRU.js} +1 -1
- package/dist/commands/antigravity/backfill.js +1 -1
- package/dist/commands/auth/create-key.js +1 -1
- package/dist/commands/auth/login.js +1 -1
- package/dist/commands/auth/logout.js +1 -1
- package/dist/commands/auth/revoke-key.js +1 -1
- package/dist/commands/auth/signup.js +1 -1
- package/dist/commands/auth/status.js +1 -1
- package/dist/commands/capture/scope.js +1 -1
- package/dist/commands/catalog/index.js +1 -1
- package/dist/commands/catalog/recommend.js +1 -1
- package/dist/commands/convert.js +1 -1
- package/dist/commands/converters.js +1 -1
- package/dist/commands/crons/list.js +1 -1
- package/dist/commands/crons/run.js +1 -1
- package/dist/commands/dashboard.js +1 -1
- package/dist/commands/diagnostics.js +1 -1
- package/dist/commands/eval-targets/create.js +1 -1
- package/dist/commands/eval-targets/list.js +1 -1
- package/dist/commands/evals/agent.js +1 -1
- package/dist/commands/evals/auto-run.js +1 -1
- package/dist/commands/evals/benchmark.js +1 -1
- package/dist/commands/evals/compare.js +1 -1
- package/dist/commands/evals/create.js +1 -1
- package/dist/commands/evals/optimize-description.js +1 -1
- package/dist/commands/evals/optimize.js +1 -1
- package/dist/commands/evals/refine-cases.js +1 -1
- package/dist/commands/evals/run.js +1 -1
- package/dist/commands/evals/validate-judge.js +1 -1
- package/dist/commands/experiments/list.js +1 -1
- package/dist/commands/gateway/ensure.js +1 -1
- package/dist/commands/hooks/install.js +1 -1
- package/dist/commands/hooks/run.js +1 -1
- package/dist/commands/hooks/uninstall.js +1 -1
- package/dist/commands/import.js +1 -1
- package/dist/commands/instructions/create.js +1 -1
- package/dist/commands/instructions/dedupe.js +1 -0
- package/dist/commands/instructions/delete.js +1 -1
- package/dist/commands/instructions/fork.js +1 -1
- package/dist/commands/instructions/get.js +1 -1
- package/dist/commands/instructions/list.js +1 -1
- package/dist/commands/instructions/promote.js +1 -1
- package/dist/commands/instructions/pull.js +1 -1
- package/dist/commands/instructions/restore.js +1 -1
- package/dist/commands/instructions/retract.js +1 -1
- package/dist/commands/instructions/upstream.js +1 -1
- package/dist/commands/instructions/versions.js +1 -1
- package/dist/commands/launcher.js +1 -1
- package/dist/commands/local/down.js +1 -1
- package/dist/commands/local/up.js +1 -1
- package/dist/commands/org/current.js +1 -1
- package/dist/commands/org/list.js +1 -1
- package/dist/commands/org/switch.js +1 -1
- package/dist/commands/packs/add-instruction.js +1 -1
- package/dist/commands/packs/apply.js +1 -1
- package/dist/commands/packs/create.js +1 -1
- package/dist/commands/packs/fork.js +1 -1
- package/dist/commands/packs/get.js +1 -1
- package/dist/commands/packs/list.js +1 -1
- package/dist/commands/packs/remove-instruction.js +1 -1
- package/dist/commands/proxy/env.js +1 -1
- package/dist/commands/proxy/logs.js +1 -1
- package/dist/commands/proxy/restart.js +1 -1
- package/dist/commands/proxy/setup.js +1 -1
- package/dist/commands/proxy/start.js +1 -1
- package/dist/commands/proxy/status.js +1 -1
- package/dist/commands/proxy/stop.js +1 -1
- package/dist/commands/research/backfill.js +1 -1
- package/dist/commands/research/tail-transcript.js +1 -1
- package/dist/commands/service/install.js +1 -1
- package/dist/commands/service/status.js +1 -1
- package/dist/commands/service/uninstall.js +1 -1
- package/dist/commands/sessions/analyze.js +1 -1
- package/dist/commands/sessions/delete.js +1 -1
- package/dist/commands/sessions/end.js +1 -1
- package/dist/commands/sessions/import.js +1 -1
- package/dist/commands/sessions/list.js +1 -1
- package/dist/commands/sessions/start.js +1 -1
- package/dist/commands/setup.js +1 -1
- package/dist/commands/skills/export-approved.js +1 -1
- package/dist/commands/skills/install.js +1 -1
- package/dist/commands/skills/list.js +1 -1
- package/dist/commands/skills/publish.js +1 -1
- package/dist/commands/skills/search.js +1 -1
- package/dist/commands/skills/update.js +1 -1
- package/dist/commands/suggestions/accept.js +1 -1
- package/dist/commands/suggestions/auto.js +1 -1
- package/dist/commands/suggestions/dismiss.js +1 -1
- package/dist/commands/suggestions/list.js +1 -1
- package/dist/commands/suggestions/refresh.js +1 -1
- package/dist/commands/suggestions/undo.js +1 -1
- package/dist/dashboard/Dashboard.js +1 -1
- package/dist/dashboard/data.js +1 -1
- package/dist/dashboard/launcher/LauncherOverlay.js +1 -1
- package/dist/dashboard/launcher/api.js +1 -1
- package/dist/dashboard/launcher/useLaunchJobs.js +1 -1
- package/dist/lib/active-org-refresh.js +1 -1
- package/dist/lib/agent-loop.js +1 -1
- package/dist/lib/antigravity-transcript.js +1 -1
- package/dist/lib/api-client.js +1 -1
- package/dist/lib/auth.js +1 -1
- package/dist/lib/claude-md-blocks.js +1 -0
- package/dist/lib/codex-exec.js +1 -1
- package/dist/lib/ensure-api-key.js +1 -1
- package/dist/lib/ensure-fresh-token.js +1 -1
- package/dist/lib/eval-benchmark.js +1 -1
- package/dist/lib/eval-candidate-run.js +1 -1
- package/dist/lib/eval-case-generator.js +1 -1
- package/dist/lib/eval-conversation-handler.js +1 -1
- package/dist/lib/eval-grader.js +1 -1
- package/dist/lib/eval-resume.js +1 -1
- package/dist/lib/eval-run-batch.js +1 -1
- package/dist/lib/evolution-enrolment.js +1 -1
- package/dist/lib/handlers/cron-auto-accept-suggestions.js +1 -1
- package/dist/lib/handlers/cron-eval-autorun.js +1 -1
- package/dist/lib/handlers/cron-instruction-evolution.js +1 -1
- package/dist/lib/handlers/cron-instruction-training.js +1 -1
- package/dist/lib/handlers/cron-refresh-pricing.js +1 -1
- package/dist/lib/handlers/cron-suggest-instructions.js +1 -1
- package/dist/lib/handlers/distill-memories.js +1 -1
- package/dist/lib/handlers/process-changelog.js +1 -1
- package/dist/lib/handlers/process-conversation.js +1 -1
- package/dist/lib/handlers/process-eval.js +1 -1
- package/dist/lib/handlers/process-insights.js +1 -1
- package/dist/lib/handlers/process-judge-review.js +1 -1
- package/dist/lib/handlers/process-launch.js +1 -1
- package/dist/lib/handlers/process-memory-ab.js +1 -1
- package/dist/lib/handlers/process-run-cleanup.js +1 -1
- package/dist/lib/handlers/process-session-goal.js +1 -1
- package/dist/lib/instruction-proposer.js +1 -1
- package/dist/lib/judge-review-runner.js +1 -1
- package/dist/lib/llm-client.js +1 -1
- package/dist/lib/manual-tasks.js +1 -1
- package/dist/lib/research-client.js +1 -1
- package/dist/lib/retraction.js +1 -1
- package/dist/lib/reviewer-detect.js +1 -1
- package/dist/lib/setup-steps.js +1 -1
- package/dist/lib/suggestion-accept.js +1 -1
- package/dist/lib/telemetry.js +1 -1
- package/dist/lib/terminal-target-heartbeat.js +1 -1
- package/oclif.manifest.json +442 -386
- package/package.json +6 -6
- package/dist/chunk-3PUOJ6F2.js +0 -45
- package/dist/chunk-JZ5Z2BRO.js +0 -7
- package/dist/chunk-MMPZIZYZ.js +0 -10
- package/dist/chunk-QWPWY3SW.js +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as c,c as d}from"./chunk-IZTIYR5Q.js";import{d as u}from"./chunk-
|
|
1
|
+
import{a as c,c as d}from"./chunk-IZTIYR5Q.js";import{d as u}from"./chunk-OI7MOALX.js";import{a}from"./chunk-6SUN4NOY.js";import{a as n}from"./chunk-WVJEBQYU.js";import{b as i}from"./chunk-OFC7HIBX.js";import{g as r}from"./chunk-PZNWH4VQ.js";import{a as s}from"./chunk-ZLLER3HP.js";import{Command as f,Flags as h}from"@oclif/core";function p(t){return t instanceof i?t.statusCode>=500||t.statusCode===408||t.statusCode===0:/fetch failed|ECONNREFUSED|ECONNRESET|ETIMEDOUT|EAI_AGAIN|bad gateway|timed out/i.test(t.message??"")}s(p,"isAvailabilityError");var m=class extends f{static{s(this,"BaseCommand")}static baseFlags={"api-url":h.string({description:"Override API base URL",env:"RULEMETRIC_API_URL",hidden:!0})};async init(){await super.init();let{flags:e}=await this.parse(this.constructor);e["api-url"]&&(process.env.RULEMETRIC_API_URL=e["api-url"]);let o=d(this.config.version);o&&!this.argv.includes("--quiet")&&!process.env.RULEMETRIC_QUIET&&process.stderr.write(`
|
|
2
2
|
${o}
|
|
3
3
|
|
|
4
4
|
`),c();try{await a()}catch{}}requireAuth(){r()||this.error("Not logged in. Run `rulemetric auth login` to authenticate."),n()}async catch(e){throw p(e)&&await u({command:this.id,statusCode:e instanceof i?e.statusCode:void 0,message:e.message,cliVersion:this.config.version}),e instanceof i&&(e.statusCode===401&&this.error("Session expired. Run `rulemetric auth login` to re-authenticate."),this.error(e.message)),(e.message?.includes("fetch failed")||e.message?.includes("ECONNREFUSED"))&&this.error("Could not connect to the API server. Is it running?"),e}};export{m as a};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as S,b as _}from"./chunk-CDY7TQFZ.js";import{c as w}from"./chunk-
|
|
1
|
+
import{a as S,b as _}from"./chunk-CDY7TQFZ.js";import{c as w}from"./chunk-V5MJ4ICC.js";import{d as A}from"./chunk-TZA4HAVF.js";import{a as u}from"./chunk-ZLLER3HP.js";var E=`You are a rigorous eval grader. Your job is to evaluate whether an AI assistant's output meets a set of expectations.
|
|
2
2
|
|
|
3
3
|
You will receive:
|
|
4
4
|
1. The original prompt that was given to the AI
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as M,b as j,c as N,d as v}from"./chunk-4PWGV2OW.js";import{a as S}from"./chunk-5RBLIVBF.js";import{c as O,d as z,f as b}from"./chunk-
|
|
1
|
+
import{a as M,b as j,c as N,d as v}from"./chunk-4PWGV2OW.js";import{a as S}from"./chunk-5RBLIVBF.js";import{c as O,d as z,f as b}from"./chunk-MODFTCZY.js";import{e as _,f as A,h as p}from"./chunk-OFC7HIBX.js";import{a as E}from"./chunk-VXM4PEED.js";import{a as h}from"./chunk-ZLLER3HP.js";async function Z(g,c){let{mirrorId:o,projectPath:e,projectId:a,config:d}=g,s=h(t=>c.logger.info(t),"log");if(d?.sessionId)return L({mirrorId:o,sessionId:d.sessionId},s);s(`Processing insights job ${o}...`),await p(`/api/insights-jobs/${o}/progress`,{status:"running",progress:{step:"reading_data"}});try{let{repaired:t}=await A("/api/sessions/repair-analyzed-at",{});t>0&&s(` Repaired analyzed_at on ${t} orphan session(s).`)}catch(t){s(` Warning: analyzed_at repair failed: ${t instanceof Error?t.message:String(t)}`)}let r=await H(e,a);if(!r)throw new S("No session data found \u2014 ensure sessions are captured and enriched.");s(` Found ${r.stats.sessions} sessions, generating recommendations...`);let f=20,n=200;if(z()!=="none"){let t=0,i=0;try{for(;t<n;){let m=await _(`/api/sessions?hasAnalysis=false&limit=${f}&offset=${i}`);if(m.length===0)break;s(` Generating facets for ${m.length} un-analyzed sessions (drained ${t} so far)...`);for(let y of m){if(t>=n)break;try{let u=await _(`/api/sessions/${y.id}/events?limit=100`);if(u.length<2){t++,i++;continue}let I=u.filter(w=>w.eventType==="user_message"||w.eventType==="human").map(w=>w.content?.slice(0,200)??"").filter(Boolean).join(`
|
|
2
2
|
---
|
|
3
3
|
`);if(!I){t++,i++;continue}let P=await b(v,I,4096);if(P){let w=u.filter(C=>C.eventType==="user_message"||C.eventType==="human").length;await p(`/api/sessions/${y.id}/enrich`,{analysis:{source:"generated_facets",...P},analyzedEventCount:u.length,analyzedTurnCount:w}),s(` Generated facets for session ${y.id} (${y.tool})`)}else i++;t++}catch(u){s(` Failed to generate facets for session ${y.id}: ${u instanceof Error?u.message:String(u)}`),t++,i++}}if(m.length<f)break}}catch(m){s(` Warning: facet generation failed after ${t} sessions: ${m instanceof Error?m.message:String(m)}`)}}let k=await F(e,s);k&&s(` Generator memory: ${k.split(`
|
|
4
4
|
`).length} lines of prior-advice context`);let l={},$=j.length+1;for(let t=0;t<j.length;t++){let i=j[t];s(` [${t+1}/${$}] Generating ${i.name}...`);try{await p(`/api/insights-jobs/${o}/progress`,{status:"running",progress:{step:i.name,current:t+1,total:$,partial:{...l}}})}catch(u){s(` Warning: progress update failed for ${i.name}: ${u instanceof Error?u.message:String(u)}`)}s(` Running LLM prompt for ${i.name}...`);let m=i.usesGeneratorMemory&&k?`${r.summary}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c as J}from"./chunk-
|
|
1
|
+
import{c as J}from"./chunk-7L4P7FCK.js";import{a as M}from"./chunk-UC377K7P.js";import{a as B}from"./chunk-W2SG3KND.js";import{b as L}from"./chunk-WEBB76XA.js";import{a as D}from"./chunk-4T2FJLDA.js";import{a as V}from"./chunk-DAD4YBYC.js";import{a as P}from"./chunk-RSKQRVPJ.js";import{a as x}from"./chunk-X4N4MT2I.js";import{a as F}from"./chunk-OFSUKSZ2.js";import{a as O}from"./chunk-RSMLOYVJ.js";import{a as A}from"./chunk-UF6US7VU.js";import{e as S}from"./chunk-4STKWINN.js";import{b as C}from"./chunk-ERNDMEYG.js";import{a as N}from"./chunk-ZJOYLBRU.js";import{a as T}from"./chunk-BN54LTXD.js";import{b as R}from"./chunk-5RBLIVBF.js";import{a as $}from"./chunk-S7YDBO42.js";import{a as W}from"./chunk-3IH22LYI.js";import{l as H}from"./chunk-HKC224ZO.js";import{d as y}from"./chunk-OPUI7CM2.js";import{b as E,e as I,f}from"./chunk-OFC7HIBX.js";import{a as o}from"./chunk-ZLLER3HP.js";var X={process_eval:T,process_insights:M,process_launch:L,process_send_message:P,process_conversation:N,process_session_goal:x,distill_memories:C,memory_ab:D,process_run_cleanup:V,cron_suggest_instructions:S,cron_refresh_skills:A,cron_refresh_pricing:O,cron_eval_autorun:W,cron_auto_accept_suggestions:$,cron_instruction_training:F,cron_instruction_evolution:H,process_judge_review:B},K=Object.keys(X),z=new Set([]);function Z(e=process.env){return e.DATABASE_URL?K:K.filter(n=>!z.has(n))}o(Z,"availableCapabilities");var j=3e4,ee=3e4,ne=3e4,U=250,G=5e3,re=`thin-agent-${process.pid}`,h=null;function te(e,n,r,l){let a;try{let u=y();a={claude:u.claudeBin!=null,codex:u.codexBin!=null,codexModel:u.codexConfiguredModel}}catch{}let m=o(u=>{f("/api/workers/heartbeat",{workerType:"cli-worker",clientName:re,clientVersion:l,workerVersion:"0.1.0",currentJobId:null,inFlightCount:0,lastError:null,status:u,metadata:{capabilities:e,mode:"thin-agent",llmEngines:a}}).then(c=>{let i=c?.advisory;i&&i.message!==h?(h=i.message,s(r,{event:"worker_advisory",code:i.code,message:i.message})):i||(h=null)}).catch(c=>{s(r,{event:"presence_heartbeat_error",error:c instanceof Error?c.message:String(c)})})},"send");m("alive");let t=setInterval(()=>m("alive"),ne);n.addEventListener("abort",()=>{clearInterval(t),m("shutting_down")},{once:!0})}o(te,"startPresenceHeartbeat");function s(e,n){try{e(JSON.stringify({ts:new Date().toISOString(),...n}))}catch{e(`[agent-loop] log_error event=${n.event}`)}}o(s,"structuredLog");function q(e,n){return n.aborted?Promise.resolve(!1):e<=0?Promise.resolve(!0):new Promise(r=>{let l=setTimeout(()=>{n.removeEventListener("abort",a),r(!0)},e),a=o(()=>{clearTimeout(l),n.removeEventListener("abort",a),r(!1)},"onAbort");n.addEventListener("abort",a,{once:!0})})}o(q,"abortableSleep");async function oe(e,n){let r=`capabilities=${encodeURIComponent(e.join(","))}&waitMs=${n}`,l=await I(`/api/work/next?${r}`);return l==null||typeof l=="string"?null:l}o(oe,"pollForWork");function se(e,n){return{logger:{info:o(r=>n(r),"info"),warn:o(r=>n(r),"warn"),error:o(r=>n(r),"error")},job:{attempts:e}}}o(se,"makeHelpers");async function ae(e,n,r){let l=X[e.kind],a=Date.now();if(s(r,{event:"claim",jobId:e.id,kind:e.kind,attempts:e.attempts}),!l){let t=`unknown kind: ${e.kind}`;s(r,{event:"fail",jobId:e.id,kind:e.kind,terminal:!0,error:t}),await f(`/api/work/${e.id}/fail`,{leaseToken:e.leaseToken,error:t,terminal:!0}).catch(()=>{});return}let m=setInterval(()=>{s(r,{event:"heartbeat",jobId:e.id}),f(`/api/work/${e.id}/heartbeat`,{leaseToken:e.leaseToken}).catch(t=>{s(r,{event:"heartbeat_error",jobId:e.id,error:t instanceof Error?t.message:String(t)})})},n);try{let t=se(e.attempts,r),u=await l(e.payload,t)??{};clearInterval(m),s(r,{event:"complete",jobId:e.id,kind:e.kind,durationMs:Date.now()-a}),await f(`/api/work/${e.id}/complete`,{leaseToken:e.leaseToken,result:u})}catch(t){clearInterval(m);let u=R(t),c=t instanceof Error?t.message:String(t);s(r,{event:"fail",jobId:e.id,kind:e.kind,durationMs:Date.now()-a,terminal:u,error:c}),await f(`/api/work/${e.id}/fail`,{leaseToken:e.leaseToken,error:c,terminal:u}).catch(i=>{s(r,{event:"fail_post_error",jobId:e.id,error:i instanceof Error?i.message:String(i)})})}}o(ae,"runOne");var Q=new Set(["process_eval","process_conversation","process_insights","process_session_goal","distill_memories","memory_ab","cron_suggest_instructions","cron_eval_autorun","cron_instruction_evolution","process_judge_review"]);async function Te(e){let n=e.log??(()=>{}),r=e.pollWaitMs??j,l=e.heartbeatIntervalMs??ee,a=e.capabilities??Z();s(n,{event:"agent_start",capabilities:a,pollWaitMs:r,heartbeatIntervalMs:l}),te(a,e.signal,n,e.version),J({signal:e.signal,log:n}).catch(d=>{s(n,{event:"tt_heartbeat_fatal",error:d instanceof Error?d.message:String(d)})});let m=5*6e4,t=0,u=o(()=>{if(!e.readInstalledVersion||!e.version)return!1;let d=Date.now();if(d-t<m)return!1;t=d;let _=e.readInstalledVersion();return!!(_&&_!==e.version)},"versionDrifted"),c=new AbortController,i=c.signal;e.signal.aborted?c.abort():e.signal.addEventListener("abort",()=>c.abort(),{once:!0});let v=o(async(d,_)=>{let g=U;for(;!i.aborted;){if(u()){s(n,{event:"agent_version_drift",bootVersion:e.version,installedVersion:e.readInstalledVersion?.()??null}),c.abort(),e.onVersionDrift?.();break}let b=null;try{b=await oe([..._],r)}catch(p){let Y=p instanceof E?p.statusCode:void 0;if(s(n,{event:"poll_error",lane:d,status:Y,error:p instanceof Error?p.message:String(p)}),!await q(g,i))break;g=Math.min(g*2,G);continue}if(!b){if(s(n,{event:"poll_204",lane:d}),!await q(g,i))break;g=Math.min(g*2,G);continue}g=U,await ae(b,l,n)}},"runLane"),k=a.filter(d=>Q.has(d)),w=a.filter(d=>!Q.has(d));k.length>0&&w.length>0?(s(n,{event:"agent_lanes",heavy:k.length,fast:w.length}),await Promise.all([v("heavy",k),v("fast",w)])):await v("single",a),s(n,{event:"agent_stop"})}o(Te,"runAgentLoop");export{X as a,K as b,Z as c,oe as d,Te as e};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{a as w}from"./chunk-
|
|
1
|
+
import{a as w}from"./chunk-MODFTCZY.js";import{a as r}from"./chunk-ZLLER3HP.js";import{spawn as k}from"node:child_process";import{mkdtempSync as v,readFileSync as M,rmSync as S}from"node:fs";import{tmpdir as $}from"node:os";import{join as P}from"node:path";var D=r(o=>`codex:${o}`,"codexModelId");function R(o,i){return["exec","--sandbox","read-only","--skip-git-repo-check","--ephemeral","--model",o,"--output-last-message",i,"-"]}r(R,"buildCodexArgs");async function j(o){let{prompt:i,systemPrompt:l,model:c,timeout:u=12e4,workDir:b=process.cwd()}=o,T=l?`${l}
|
|
2
2
|
|
|
3
3
|
${i}`:i,m=w("codex");if(!m)return{output:"",exitCode:null,durationMs:0,error:"Codex CLI not found on PATH, well-known install dirs, or the node bin dir \u2014 is it installed?"};let p=v(P($(),"rulemetric-codex-")),a=P(p,"last-message.txt"),h=Date.now();return new Promise(E=>{let s={...process.env};delete s.HTTPS_PROXY;let y=["/opt/homebrew/bin","/usr/local/bin"],x=(s.PATH??"").split(":").filter(Boolean),f=y.filter(e=>!x.includes(e));f.length&&(s.PATH=[...x,...f].join(":"));let t=k(m,R(c,a),{cwd:b,env:s,stdio:["pipe","pipe","pipe"]}),g="";t.stdout.on("data",()=>{}),t.stderr.on("data",e=>{g+=e.toString()});let n=r(e=>{S(p,{recursive:!0,force:!0}),E({...e,durationMs:Date.now()-h})},"finish"),C=setTimeout(()=>{t.kill("SIGTERM"),n({output:"",exitCode:null,error:`codex exec timed out after ${u}ms`})},u);t.on("error",e=>{clearTimeout(C),n({output:"",exitCode:null,error:`failed to spawn codex: ${e.message} (is the Codex CLI installed?)`})}),t.on("close",e=>{clearTimeout(C);let d="";try{d=M(a,"utf8").trim()}catch{}if(e!==0||d===""){n({output:d,exitCode:e,error:`codex exec failed (exit ${e}): ${g.trim().slice(-500)||"no last message produced"}`});return}n({output:d,exitCode:e,model:D(c)})}),t.stdin.write(T),t.stdin.end()})}r(j,"executeCodexEval");export{D as a,R as b,j as c};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import{a as f,b as g,e as A}from"./chunk-FK73GD2X.js";import{e as l,f as d,i as I}from"./chunk-OFC7HIBX.js";import{l as y}from"./chunk-VXM4PEED.js";import{a as c}from"./chunk-ZLLER3HP.js";import*as a from"node:fs";import*as p from"node:path";function S(t,e,n){let i=p.join(t,"CLAUDE.md"),o=f(e),s=g(e),r=a.existsSync(i)?a.readFileSync(i,"utf8"):"";if(r.includes(o))return!1;let m=`${r.length>0&&!r.endsWith(`
|
|
2
|
+
`)?`
|
|
3
|
+
|
|
4
|
+
`:r.length>0?`
|
|
5
|
+
`:""}
|
|
6
|
+
${o}
|
|
7
|
+
${n}
|
|
8
|
+
${s}
|
|
9
|
+
`;return a.writeFileSync(i,r+m,"utf8"),!0}c(S,"appendToCLAUDEmd");function b(t,e){let n=p.join(t,"CLAUDE.md");if(!a.existsSync(n))return!1;let i=f(e),o=g(e),s=a.readFileSync(n,"utf8"),r=s.indexOf(i);if(r===-1)return!1;let u=s.indexOf(o,r);if(u===-1)return!1;let m=s.slice(0,r),$=s.slice(u+o.length),v=(m.replace(/\n+$/,"")+`
|
|
10
|
+
`+$.replace(/^\n+/,"")).replace(/^\n+/,"");return a.writeFileSync(n,v,"utf8"),!0}c(b,"removeFromCLAUDEmd");function w(t,e=90){return t.length<=e?t:`${t.slice(0,e-1)}\u2026`}c(w,"truncate");function x(t){return l(`/api/instruction-suggestions/${encodeURIComponent(t)}`)}c(x,"fetchSuggestion");async function h(t,e,n,i){await d(`/api/instruction-suggestions/${encodeURIComponent(t)}/events`,{eventType:"accepted",projectPath:e,instructionId:n,actor:i})}c(h,"logAccepted");async function k(t,e,n,i){await d(`/api/instruction-suggestions/${encodeURIComponent(t)}/events`,{eventType:"redundant",projectPath:e,instructionId:n,actor:i})}c(k,"logRedundant");async function R(t){let e=t.suggestion??await x(t.suggestionId);if(e.kind==="remove")return D(t,e);if(e.kind==="trim")return C(t,e);let n=e.instructionId;e.instructionScope==="public"&&(n=(await d(`/api/instructions/${encodeURIComponent(e.instructionId)}/promote-from-public`,{targetScope:"personal"})).instructionId);let i=await l(`/api/instructions/${encodeURIComponent(n)}`);if(!t.force){let s=y(i.content,A(t.dir));if(s.redundant)return await k(t.suggestionId,t.projectPath,n,t.actor),{action:"redundant",instructionId:n,name:i.name,fileModified:!1,redundancy:s,messages:[`Skipped: ${i.name} already applies here in different words \u2014 adding it would spend context to say the same thing twice.`,...s.matches.map(r=>` "${w(r.directive)}"
|
|
11
|
+
already covered by ${r.matchedSource??r.matchedId} (${(r.similarity*100).toFixed(0)}% match): "${w(r.matchedDirective)}"`),"Add it anyway with `--force` if the overlap is not real."]}}let o=S(t.dir,n,i.content);return await h(t.suggestionId,t.projectPath,n,t.actor),{action:o?"added":"already-present",instructionId:n,name:i.name,fileModified:o,messages:o?[`Accepted: added ${i.name} to CLAUDE.md. It will be active starting in your next session.`]:[`Already present: ${i.name} is already in CLAUDE.md (block id: ${n}).`]}}c(R,"acceptSuggestion");async function C(t,e){let n=e.estimatedTokens?` It currently costs roughly ${e.estimatedTokens} tokens per session (estimated).`:"";return await h(t.suggestionId,t.projectPath,e.instructionId,t.actor),{action:"acknowledged",instructionId:e.instructionId,name:e.name,fileModified:!1,messages:[`Noted: ${e.name} is measured neutral, not harmful.${n}`,"Nothing was changed \u2014 trimming is a judgement call about which parts carry the value,","and the measurement only found the absence of a detectable effect, not which half to cut.",` View it: rulemetric instructions get ${e.instructionId}`," Then edit CLAUDE.md (or the instruction) and let the next measurement cycle re-check it.","This suggestion will stop re-surfacing."]}}c(C,"acknowledgeTrim");async function D(t,e){let n=b(t.dir,e.instructionId);await I(`/api/instructions/${encodeURIComponent(e.instructionId)}`);let i=e.estimatedTokens?` Frees roughly ${e.estimatedTokens} tokens of context per session (estimated).`:"",o=n?[`Retired: removed ${e.name} from CLAUDE.md and archived it.${i}`]:[`Archived ${e.name}.${i}`,"CLAUDE.md was not modified \u2014 no rulemetric-managed block for this instruction was found in this directory. If you added it by hand, remove it yourself."];return o.push("Undo with: rulemetric instructions restore "+e.instructionId),await h(t.suggestionId,t.projectPath,e.instructionId,t.actor),{action:n?"retired":"archived-only",instructionId:e.instructionId,name:e.name,fileModified:n,messages:o}}c(D,"acceptRemoval");export{S as a,b,x as c,R as d};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import{a as o}from"./chunk-ZLLER3HP.js";function j(e){if(!e||typeof e!="object")return e;let s=e,n=s.project_areas;if(n!==void 0&&!Array.isArray(n)){let t=n&&typeof n=="object"?n.areas:void 0;s.project_areas=Array.isArray(t)?t:void 0}return e}o(j,"normalizeRecommendations");import{z as p}from"zod";var T=["org","team","project","personal"],b=p.object({name:p.string().min(1),description:p.string().min(1),type:p.literal("instruction").default("instruction"),scope:p.enum(T),version:p.string().min(1),tags:p.array(p.string()).optional(),compatibility:p.array(p.string()).optional(),slots:p.record(p.string(),p.string()).optional(),metadata:p.record(p.string(),p.unknown()).optional()});import{z as f}from"zod";var M=f.object({name:f.string().min(1),description:f.string().min(1),type:f.literal("prompt"),version:f.string().min(1),tags:f.array(f.string()).optional(),variables:f.array(f.string()).optional(),metadata:f.record(f.string(),f.unknown()).optional()});function g(e,s){let n=s.map(t=>`- ID: ${t.id}
|
|
2
|
+
Name: ${t.name}
|
|
3
|
+
Description: ${t.description}
|
|
4
|
+
Tags: ${t.tags.join(", ")}
|
|
5
|
+
Preview: ${t.contentPreview}`).join(`
|
|
6
|
+
|
|
7
|
+
`);return`You are an expert at matching AI coding instructions to software projects.
|
|
8
|
+
|
|
9
|
+
## Project
|
|
10
|
+
- Name: ${e.name}
|
|
11
|
+
- Description: ${e.description??"No description"}
|
|
12
|
+
- Languages: ${e.languages.join(", ")||"Unknown"}
|
|
13
|
+
- Topics: ${e.topics.join(", ")||"None"}
|
|
14
|
+
- Dependencies: ${e.dependencies.join(", ")||"None"}
|
|
15
|
+
|
|
16
|
+
## Available Instructions
|
|
17
|
+
|
|
18
|
+
${n}
|
|
19
|
+
|
|
20
|
+
## Task
|
|
21
|
+
|
|
22
|
+
Analyze the project and recommend which instructions would be most useful. Consider:
|
|
23
|
+
1. Language and framework alignment
|
|
24
|
+
2. Project purpose and what standards/practices would help
|
|
25
|
+
3. Security, testing, and quality needs based on the project type
|
|
26
|
+
|
|
27
|
+
Return your response as JSON in this exact format:
|
|
28
|
+
{
|
|
29
|
+
"recommendations": [
|
|
30
|
+
{ "instructionId": "<id>", "score": <0.0-1.0>, "reason": "<one sentence explanation>" }
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
Only include instructions with a relevance score >= 0.5. Order by score descending. Return valid JSON only, no markdown fences.`}o(g,"buildRecommendationPrompt");var S=32e3,N={name:"x".repeat(64),description:"x".repeat(256),languages:["TypeScript","Python","Go"],topics:["x".repeat(32)],dependencies:["x".repeat(32)]};function k(e,s={}){if(e.length===0)return[];let n=s.charBudget??S,t=g(N,[]).length,r=[],i=[],d=0;for(let a of e){let l=D(a);i.length>0&&t+d+l>n&&(r.push(i),i=[],d=0),i.push(a),d+=l}return i.length>0&&r.push(i),r}o(k,"batchCandidatesForPrompt");function D(e){return`- ID: ${e.id}
|
|
35
|
+
Name: ${e.name}
|
|
36
|
+
Description: ${e.description}
|
|
37
|
+
Tags: ${e.tags.join(", ")}
|
|
38
|
+
Preview: ${e.contentPreview}`.length+2}o(D,"renderedSize");var I=["Added","Changed","Fixed","Removed","Deprecated","Security"],F=/^##\s+\[([^\]]+)\](?:\s*[-–]\s*(\d{4}-\d{2}-\d{2}))?\s*$/,$=/^###\s+(.+?)\s*$/,G=/^[-*]\s+(.*\S)\s*$/,U=/^ {2,}(\S.*)$/;function H(e){let s=e.split(/\r?\n/),n=[],t=null,r=null,i=null;for(let d of s){let a=d.match(F);if(a){t&&n.push(t);let u=a[1].trim();t={version:u,date:a[2]??null,unreleased:u.toLowerCase()==="unreleased",sections:{}},r=null,i=null;continue}if(!t)continue;let l=d.match($);if(l){let u=l[1].trim();I.includes(u)?(r=u,t.sections[r]||(t.sections[r]=[]),i=t.sections[r]):(r=null,i=null);continue}if(!r||!i)continue;let m=d.match(G);if(m){i.push(m[1]);continue}let h=d.match(U);if(h&&i.length>0){i[i.length-1]+=" "+h[1].trim();continue}}return t&&n.push(t),{entries:n}}o(H,"parseChangelog");function z(e){return e.entries.filter(s=>s.unreleased?!1:Object.values(s.sections).some(n=>n&&n.length>0))}o(z,"announceableEntries");function y(e){let s=/^(#{1,6})\s+/.exec(e);return s?s[1].length:0}o(y,"headingLevel");function P(e){return e.replace(/^#{1,6}\s+/,"").replace(/[`*_~]/g,"").trim().toLowerCase()}o(P,"normaliseHeading");function B(e,s){let n=P(s);if(n.length===0)return{content:e,removed:!1,removedText:null,reason:"not-found"};let t=e.split(`
|
|
39
|
+
`),r=[];for(let u=0;u<t.length;u+=1)y(t[u])>0&&P(t[u])===n&&r.push(u);if(r.length===0)return{content:e,removed:!1,removedText:null,reason:"not-found"};if(r.length>1)return{content:e,removed:!1,removedText:null,reason:"ambiguous"};let i=r[0],d=y(t[i]),a=t.length;for(let u=i+1;u<t.length;u+=1){let v=y(t[u]);if(v>0&&v<=d){a=u;break}}let l=t.slice(i,a).join(`
|
|
40
|
+
`),m=[...t.slice(0,i),...t.slice(a)];return m.join("").trim().length===0?{content:e,removed:!1,removedText:null,reason:"would-empty-file"}:{content:m.join(`
|
|
41
|
+
`).replace(/\n{3,}/g,`
|
|
42
|
+
|
|
43
|
+
`),removed:!0,removedText:l}}o(B,"removeMarkdownSection");function K(e,s){let n=s.trim();if(n.length===0)return{content:e,removed:!1,removedText:null,reason:"not-found"};let t=e.indexOf(n);if(t===-1)return{content:e,removed:!1,removedText:null,reason:"not-found"};if(e.indexOf(n,t+1)!==-1)return{content:e,removed:!1,removedText:null,reason:"ambiguous"};let r=(e.slice(0,t)+e.slice(t+n.length)).replace(/\n{3,}/g,`
|
|
44
|
+
|
|
45
|
+
`);return r.trim().length===0?{content:e,removed:!1,removedText:null,reason:"would-empty-file"}:{content:r,removed:!0,removedText:n}}o(K,"removeExactBlock");var L=["HTTPS_PROXY","HTTP_PROXY","NODE_EXTRA_CA_CERTS"];function W(e,s){if(!e||typeof e!="object")return{value:e,removed:!1,removedDescriptions:[],reason:"not-found"};let n=structuredClone(e);if(!n.hooks)return{value:n,removed:!1,removedDescriptions:[],reason:"not-found"};let t=[];for(let[r,i]of Object.entries(n.hooks)){if(!Array.isArray(i))continue;let d=i.filter(a=>{let l=(a.hooks??[]).some(m=>typeof m.command=="string"&&m.command.includes(s));return l&&t.push(`${r}: ${a.matcher??"*"} \u2192 ${(a.hooks??[]).map(m=>m.command).join(", ")}`),!l});d.length===0?delete n.hooks[r]:n.hooks[r]=d}return Object.keys(n.hooks).length===0&&delete n.hooks,{value:n,removed:t.length>0,removedDescriptions:t,...t.length===0?{reason:"not-found"}:{}}}o(W,"removeHookByCommand");function q(e,s){if(!e||typeof e!="object")return{value:e,removed:!1,removedDescriptions:[],reason:"not-found"};let n=structuredClone(e);return!n.mcpServers||!(s in n.mcpServers)?{value:n,removed:!1,removedDescriptions:[],reason:"not-found"}:(delete n.mcpServers[s],Object.keys(n.mcpServers).length===0&&delete n.mcpServers,{value:n,removed:!0,removedDescriptions:[`mcpServers.${s}`]})}o(q,"removeMcpServer");function w(e){if(!e||typeof e!="object")return[];let s=e.env;return s?L.filter(n=>n in s):[]}o(w,"protectedEnvKeysPresent");function V(e,s){let n=w(e),t=new Set(w(s));return n.filter(r=>!t.has(r))}o(V,"lostProtectedEnvKeys");function Y(e,s){let n=`HTTP ${e}`;if(!s||typeof s!="object")return{message:n};let t=s,r=typeof t.error=="string"&&t.error?t.error:t.error?JSON.stringify(t.error):n,i=typeof t.code=="string"&&t.code?t.code:void 0;return i?{message:r,code:i}:{message:r}}o(Y,"parseApiError");var J=/[\p{L}\p{N}]+/gu;function x(e){let s=new Set;for(let n of e.toLowerCase().matchAll(J)){let t=` ${n[0]} `;for(let r=0;r+3<=t.length;r+=1)s.add(t.slice(r,r+3))}return s}o(x,"trigrams");function _(e,s){let n=x(e),t=x(s);if(n.size===0||t.size===0)return 0;let r=0,[i,d]=n.size<=t.size?[n,t]:[t,n];for(let l of i)d.has(l)&&(r+=1);let a=n.size+t.size-r;return a===0?0:r/a}o(_,"trigramSimilarity");var R=.3,Q=15;function C(e){let n=e.replace(/<!--[\s\S]*?-->/g," ").replace(/```[\s\S]*?```/g," "),t=[];for(let r of n.split(`
|
|
46
|
+
`)){let i=r.trim();if(i.length===0||i.startsWith("#"))continue;let d=i.replace(/^(?:[-*+]|\d+[.)])\s+/,"").trim();if(d.length!==0)for(let a of d.split(/(?<=[.!?])\s+(?=[A-Z(`"'*])/)){let l=a.trim();l.length>=Q&&t.push(l)}}return t}o(C,"splitDirectives");function O(e,s,n=R){let t=C(e);if(t.length===0)return{redundant:!1,coverage:0,matches:[],novel:[]};let r=s.flatMap(a=>C(a.content).map(l=>({text:l,id:a.id,source:a.source}))),i=[],d=[];for(let a of t){let l=null;for(let m of r){let h=_(a,m.text);h<n||(l===null||h>l.similarity)&&(l={directive:a,matchedDirective:m.text,matchedId:m.id,matchedSource:m.source,similarity:h})}l?i.push(l):d.push(a)}return{redundant:d.length===0,coverage:i.length/t.length,matches:i,novel:d}}o(O,"assessRedundancy");function X(e,s=R){let n=[];for(let t=0;t<e.length;t+=1){let r=O(e[t].content,e.slice(0,t),s);r.matches.length>0&&n.push({instruction:e[t],verdict:r})}return n}o(X,"findInternalRedundancy");import $e from"gray-matter";import{z as A}from"zod";var ze=A.object({type:A.enum(["instruction","prompt"])});export{j as a,g as b,k as c,H as d,z as e,B as f,K as g,W as h,q as i,V as j,Y as k,O as l,X as m};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c as d,d as t}from"./chunk-
|
|
1
|
+
import{c as d,d as t}from"./chunk-NDZVH5QW.js";import{a as r}from"./chunk-ZLLER3HP.js";async function g(o,i){let{evalTargetId:s}=o;try{let e=await t({targetId:s,engineFlag:"auto",skipReviewed:!0,log:r(a=>i.logger.info(`[judge-review] ${a}`),"log"),warn:r(a=>i.logger.warn(`[judge-review] ${a}`),"warn")});return{evalTargetId:s,reviewerModel:e.reviewerModel,comparedPairs:e.report.pairs,disagreements:e.report.disagreements.length,persisted:e.persisted,alreadyReviewed:e.alreadyReviewed,deferredPartialRuns:e.deferredPartialRuns}}catch(e){if(e instanceof d)return i.logger.info(`[judge-review] skipped (${e.reason}): ${e.message}`),{evalTargetId:s,skipped:e.reason};throw e}}r(g,"processJudgeReview");export{g as a};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as C}from"./chunk-AFYZYXQ3.js";import{b as $}from"./chunk-
|
|
1
|
+
import{a as C}from"./chunk-AFYZYXQ3.js";import{b as $}from"./chunk-3VYV6ZYB.js";import{a as y}from"./chunk-TCR7TSAJ.js";import{d as f}from"./chunk-TZA4HAVF.js";import{e as h,f as w}from"./chunk-OFC7HIBX.js";import{a as v}from"./chunk-ZLLER3HP.js";async function N(n,i,p){let{conversationId:a,messageId:g,messageContent:r}=n,o=await h(`/api/eval-targets/${i}`),c=await h(`/api/eval-targets/${i}/evals`),e=await h(`/api/eval-conversations/${a}/messages`),t=e.findIndex(l=>l.id===g);if(t>=0&&e.slice(t+1).some(u=>u.role==="assistant"&&(u.type==="results"||u.type==="proposal"||u.type==="generated"||u.type==="text"))){p(`Message ${g} already processed \u2014 skipping (idempotency guard)`);return}let s=v(async(l,u,m)=>{await w(`/api/eval-conversations/${a}/messages/assistant`,{content:l,type:u,data:m})},"postMessage"),d=await _(o,c,e,r,p);p(`Action: ${d.action}`);try{switch(d.action){case"run_evals":await x(o,c,a,s,p);break;case"generate_cases":await k(o,i,a,s,p);break;case"analyze_results":case"propose_changes":await E(o,c,e,r,a,s,p);break;case"respond":await s(d.response,"text");break}}catch(l){let u=l instanceof Error?l.message:String(l);throw await s(`Something went wrong: ${u}`,"text").catch(()=>{}),l}}v(N,"processConversationJob");async function _(n,i,p,a,g){let r=p.slice(-10).map(e=>`${e.role}: ${e.content.slice(0,200)}`).join(`
|
|
2
2
|
`),o=`You are an eval assistant. Decide what action to take based on the user's message.
|
|
3
3
|
|
|
4
4
|
## Current State
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{b as l}from"./chunk-6QKI756T.js";import{a as p}from"./chunk-5RBLIVBF.js";import{h}from"./chunk-
|
|
1
|
+
import{b as l}from"./chunk-6QKI756T.js";import{a as p}from"./chunk-5RBLIVBF.js";import{h}from"./chunk-OFC7HIBX.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 +1 @@
|
|
|
1
|
-
import{a as s,b as n,c as a,d as g}from"./chunk-3AV3GTMP.js";import{e as o}from"./chunk-
|
|
1
|
+
import{a as s,b as n,c as a,d as g}from"./chunk-3AV3GTMP.js";import{e as o}from"./chunk-OFC7HIBX.js";import{a as e}from"./chunk-ZLLER3HP.js";var i=!1;async function c(){if(process.env.RULEMETRIC_ORG_ID)return;let r=s();if(!(r&&!g(r)))try{let t=await o("/api/profile");if(!t.activeOrgId){a();return}if(r&&t.activeOrgId===r.orgId){n({orgId:r.orgId,orgSlug:r.orgSlug,syncedAt:Date.now()});return}let d=(await o("/api/orgs")).find(l=>l.id===t.activeOrgId);n({orgId:t.activeOrgId,orgSlug:d?.slug,syncedAt:Date.now()})}catch{}}e(c,"syncActiveOrgFromServer");async function p(){i||(i=!0,await c())}e(p,"maybeRefreshActiveOrg");async function v(){i=!0,await c()}e(v,"bootstrapActiveOrg");function O(){i=!1}e(O,"_resetRefreshAttempt");export{p as a,v as b,O as c};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{f}from"./chunk-
|
|
1
|
+
import{f}from"./chunk-MODFTCZY.js";import{b as S,e as a,h as y}from"./chunk-OFC7HIBX.js";import{a as p}from"./chunk-ZLLER3HP.js";var _=1800*1e3,G=300*1e3,T=10,h=`Given these messages from an AI coding session, write a 1-2 sentence summary of what the user is trying to accomplish. Focus on the goal, not the steps. No preamble.
|
|
2
2
|
|
|
3
3
|
Return strict JSON in the form: {"goalSummary": "..."}`;async function k(n,e={}){let d=e.llm??f,o=e.now??Date.now,w=e.getSession??(async s=>{try{return await a(`/api/sessions/${s}`)}catch(t){if(t instanceof S&&t.statusCode===404)return null;throw t}}),m=e.getEvents??((s,t)=>a(`/api/sessions/${s}/events?limit=${t.limit}&sort=${t.sort}`)),v=e.saveGoal??(async(s,t)=>{await y(`/api/sessions/${s}/enrich`,{analysis:t})}),i=await w(n.sessionId);if(!i)return{skipped:"not_found"};let[P]=await m(n.sessionId,{limit:1,sort:"desc"}),A=new Date(P?.timestamp??i.startedAt).getTime();if(o()-A>_)return{skipped:"stale"};let l=i.analysis??{},c=l.goalSummaryAt?new Date(l.goalSummaryAt).getTime():0;if(c&&o()-c<G)return{skipped:"recent"};let g=(await m(n.sessionId,{limit:T*2,sort:"asc"})).filter(s=>s.content&&(s.eventType==="user_message"||s.eventType==="assistant_response")).map(s=>`${s.eventType==="user_message"?"USER":"ASSISTANT"}: ${s.content}`).join(`
|
|
4
4
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c as u}from"./chunk-
|
|
1
|
+
import{c as u}from"./chunk-OI7MOALX.js";import{b as c,e as y,f as m}from"./chunk-OFC7HIBX.js";import{a as n,b as t,i as s,k as p}from"./chunk-PZNWH4VQ.js";import{a}from"./chunk-ZLLER3HP.js";import{hostname as l}from"node:os";async function R(f,r,h){t();let o=process.env.RULEMETRIC_API_KEY,d=n().apiKey;if(o||d)try{await y("/api/profile");return}catch(e){if(!(e instanceof c)||e.statusCode!==401)return;if(o){r('Your exported RULEMETRIC_API_KEY was rejected (revoked?). Unset it or replace it with a fresh key (`rulemetric auth create-key --name "my-laptop"`).');return}p(),t(),r("Stored API key was rejected (revoked?) \u2014 replacing it with a fresh one.")}let i=`${l()} (auto)`;try{let e=await m("/api/auth/api-keys",{name:i});s(e.key,process.env.RULEMETRIC_API_URL),t(),f(`Created API key "${i}" for hooks + proxy auth (saved to your config).`),u("key_created",{},h)}catch(e){let k=e instanceof Error?e.message:String(e);r(`Could not auto-create an API key (${k}). Hooks/proxy will work via your session token for ABOUT AN HOUR \u2014 the token expires, and capture then stops until a key exists. Run \`rulemetric auth create-key --name "my-laptop"\` (or \`rulemetric auth login\` again) to fix this permanently.`)}}a(R,"ensureDeviceApiKey");export{R as a};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as h,b as D}from"./chunk-FP6QAPNK.js";import{d as _,e as C}from"./chunk-
|
|
1
|
+
import{a as h,b as D}from"./chunk-FP6QAPNK.js";import{d as _,e as C}from"./chunk-VXM4PEED.js";import{a as o}from"./chunk-ZLLER3HP.js";import*as m from"node:fs/promises";import*as x from"node:path";import{eq as z}from"drizzle-orm";import{randomBytes as H}from"node:crypto";var A="#0d9488",g="#1a1a1a",y="#666666",M="#f5f5f7",k="#ffffff",I="#e5e5e9",O=["Added","Changed","Fixed","Removed","Deprecated","Security"];function U(e){let t=["January","February","March","April","May","June","July","August","September","October","November","December"],[n,r,a]=e.split("-").map(p=>parseInt(p,10));return!n||!r||!a||r<1||r>12?e:`${t[r-1]} ${a}, ${n}`}o(U,"formatIsoDate");function l(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}o(l,"escapeHtml");function P(e){let t=[];for(let n of O){let r=e[n];r&&r.length>0&&t.push({name:n,items:r})}return t}o(P,"orderedSections");function v(e){let{version:t,date:n,sections:r,unsubscribeUrl:a,productUrl:p,recipientName:u}=e,c=U(n),s=`What's new in RuleMetric \u2014 ${c}`,b=u?`Hi ${u},`:"Hi there,",i=P(r),d=new Date().getUTCFullYear(),E=i.map(({name:$,items:R})=>{let w=R.map(S=>` <li style="margin:0 0 6px 0;font-size:15px;line-height:1.5;color:${g};">${l(S)}</li>`).join(`
|
|
2
2
|
`);return` <h3 style="margin:24px 0 8px 0;font-size:16px;line-height:1.3;font-weight:600;color:${g};">${$}</h3>
|
|
3
3
|
<ul style="margin:0 0 8px 0;padding-left:20px;">
|
|
4
4
|
${w}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a}from"./chunk-
|
|
1
|
+
import{a}from"./chunk-OFC7HIBX.js";import{a as e}from"./chunk-ZLLER3HP.js";function i(){return process.env.RULEMETRIC_API_URL??a}e(i,"apiUrl");function u(){let n=process.env.RULEMETRIC_API_KEY??process.env.RULEMETRIC_ACCESS_TOKEN;if(!n)throw new Error("not signed in \u2014 run `rulemetric auth login`");return n}e(u,"authToken");async function t(n,o){let r=await fetch(`${i()}${n}`,{...o,headers:{Authorization:`Bearer ${u()}`,"Content-Type":"application/json",...o?.headers??{}},signal:AbortSignal.timeout(1e4)});if(!r.ok)throw new Error(`${r.status} ${r.statusText}`);return await r.json()}e(t,"request");function c({limit:n}){return t(`/api/launch-jobs?limit=${n}`)}e(c,"fetchLaunchJobs");function h(n){return t("/api/launch-jobs",{method:"POST",body:JSON.stringify(n)})}e(h,"createLaunchJob");function l(n){return t(`/api/launch-jobs/${n}/cancel`,{method:"POST"})}e(l,"cancelLaunchJob");function p(){return t("/api/launchers")}e(p,"listLaunchers");export{c as a,h as b,l as c,p as d};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as i}from"./chunk-
|
|
1
|
+
import{a as i}from"./chunk-W65UX4FC.js";import{h as s}from"./chunk-OFC7HIBX.js";import{a as n}from"./chunk-ZLLER3HP.js";async function l(a,c){let{mirrorId:g,evalTargetId:p,config:r}=a,e=n(o=>c.logger.info(o),"log");await i(r,p,e);let t={type:"conversation",conversationId:r.conversationId};return await s(`/api/eval-jobs/${g}/state`,{result:t}).catch(o=>{e(`result persist failed: ${o instanceof Error?o.message:String(o)}`)}),t}n(l,"processConversation");export{l as a};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{a as v,b as u,e as y,g as d}from"../../chunk-
|
|
1
|
+
import{a as v,b as u,e as y,g as d}from"../../chunk-F5WE6JXK.js";import{a as h}from"../../chunk-SE5SRPIB.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-OI7MOALX.js";import"../../chunk-6SUN4NOY.js";import"../../chunk-WVJEBQYU.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-OFC7HIBX.js";import"../../chunk-VXM4PEED.js";import"../../chunk-PZNWH4VQ.js";import{a as p}from"../../chunk-ZLLER3HP.js";import{Args as k,Flags as o}from"@oclif/core";import{existsSync as T}from"node:fs";import{homedir as P}from"node:os";import{join as I}from"node:path";var A=I(P(),".gemini","antigravity-ide","brain"),g=class x extends h{static{p(this,"AntigravityBackfill")}static description="Backfill historical events from an Antigravity conversation transcript into a RuleMetric session. Useful for seeding a conversation that existed before hooks were installed \u2014 the live hook intentionally only captures forward.";static examples=["<%= config.bin %> antigravity backfill 26fd215d-f43b-4ea5-b177-dc2c0e696f97 --session 158db9aa-68ee-43fc-961b-f3a180578694","<%= config.bin %> antigravity backfill 26fd215d-f43b-4ea5-b177-dc2c0e696f97 --dry-run"];static args={conversationId:k.string({description:"Antigravity conversationId (UUID) \u2014 the directory name under ~/.gemini/antigravity-ide/brain/",required:!0})};static flags={session:o.string({char:"s",description:"RuleMetric session UUID to POST events into. If omitted, resolved from the hook tmp file ($TMPDIR/rulemetric/<conversationId>) \u2014 fails if neither is present."}),transcript:o.string({description:"Path to the transcript.jsonl file. Defaults to ~/.gemini/antigravity-ide/brain/<conversationId>/.system_generated/logs/transcript.jsonl"}),"after-step":o.integer({description:"Only emit records with step_index > this value. Default: read from existing state file, else -1 (everything)."}),limit:o.integer({description:"Cap on the number of records to process this run."}),"dry-run":o.boolean({default:!1,description:"Classify records without POSTing. Reports counts only."}),"save-state":o.boolean({default:!0,allowNo:!0,description:"After backfill, persist the highest step_index so the live hook resumes from there."})};async run(){let{args:b,flags:e}=await this.parse(x),t=b.conversationId;d.loadEnvFile(),process.env.RULEMETRIC_API_URL||this.error("RULEMETRIC_API_URL is not set. Configure it via env or ~/.config/rulemetric/env.");let l=e.transcript??I(A,t,".system_generated","logs","transcript.jsonl");T(l)||this.error(`Transcript not found: ${l}`);let m=e.session??d.resolveRwSessionId(t);m||this.error(`No RuleMetric session resolved. Pass --session <uuid>, or run the Antigravity hook at least once so $TMPDIR/rulemetric/${t} is populated.`);let n=e["after-step"];n===void 0&&(n=d.load(t)?.lastStepIdx??-1);let i=v(l,n);e.limit!==void 0&&i.length>e.limit&&(i=i.slice(0,e.limit));let R=u(l);if(this.log(`Conversation ${t}: transcript max step = ${R}, after-step = ${n}, records to process = ${i.length}`),i.length===0){this.log("Nothing to backfill.");return}if(e["dry-run"]){let r=0,a=0,c={};for(let S of i){let f=(await import("../../lib/antigravity-transcript.js")).classifyRecord(S,0);f?(r++,c[f.eventType]=(c[f.eventType]??0)+1):a++}this.log(`Dry run: would emit ${r}, skip ${a}. By eventType: ${JSON.stringify(c)}`);return}let w=Date.now(),s=await y(i,m,t,n,{onProgress:p(({attempted:r,total:a})=>{(r%100===0||r===a)&&process.stderr.write(` \u2026${r}/${a}
|
|
2
2
|
`)},"onProgress")}),$=((Date.now()-w)/1e3).toFixed(1);this.log(`Backfill complete in ${$}s. attempted=${s.attempted} emitted=${s.emitted} skipped=${s.skipped} failed=${s.failed} highestStepIdx=${s.highestStepIdx}`),e["save-state"]?(d.save(t,{lastStepIdx:s.highestStepIdx}),this.log(`State saved \u2192 live hook will resume from step_index > ${s.highestStepIdx}.`)):this.log("State NOT saved (--no-save-state). Live hook will re-emit any new records from after-step.")}};export{g as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as n}from"../../chunk-
|
|
1
|
+
import{a as n}from"../../chunk-SE5SRPIB.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-OI7MOALX.js";import"../../chunk-6SUN4NOY.js";import"../../chunk-WVJEBQYU.js";import"../../chunk-3AV3GTMP.js";import{f as r}from"../../chunk-OFC7HIBX.js";import"../../chunk-VXM4PEED.js";import{i as o,l as s}from"../../chunk-PZNWH4VQ.js";import{a}from"../../chunk-ZLLER3HP.js";import*as c from"node:path";import{Flags as l}from"@oclif/core";var t=class g extends n{static{a(this,"AuthCreateKey")}static description="Create a long-lived API key for CLI and proxy authentication";static examples=['<%= config.bin %> auth create-key --name "laptop"','<%= config.bin %> auth create-key --name "ci token" --no-save'];static flags={name:l.string({char:"n",description:"Name for this key",required:!0}),save:l.boolean({char:"s",description:"Save key to ~/.config/rulemetric/env for hooks/proxy",default:!0,allowNo:!0})};async run(){let{flags:i}=await this.parse(g),e=await r("/api/auth/api-keys",{name:i.name});this.log(""),this.log("API key created successfully:"),this.log(""),this.log(` Name: ${e.name}`),this.log(` Key: ${e.key}`),this.log(` Prefix: ${e.keyPrefix}`),this.log(""),this.warn("Save this key now \u2014 it will not be shown again."),i.save&&(o(e.key,process.env.RULEMETRIC_API_URL),this.log(""),this.log(`Key saved to ${c.join(s(),"env")} (RULEMETRIC_API_KEY)`),this.log("Hooks and proxy will use this key automatically."))}};export{t as default};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as f}from"../../chunk-
|
|
1
|
+
import{a as f}from"../../chunk-XILSJP4P.js";import{a as w}from"../../chunk-SE5SRPIB.js";import"../../chunk-IZTIYR5Q.js";import{c}from"../../chunk-OI7MOALX.js";import"../../chunk-6SUN4NOY.js";import{b as n}from"../../chunk-WVJEBQYU.js";import"../../chunk-3AV3GTMP.js";import{b as r,d as a}from"../../chunk-OFC7HIBX.js";import"../../chunk-VXM4PEED.js";import{b as m,d,h as u,i as g}from"../../chunk-PZNWH4VQ.js";import{a as l}from"../../chunk-ZLLER3HP.js";import{Flags as p}from"@oclif/core";var h=class y extends w{static{l(this,"AuthLogin")}static description="Log in to RuleMetric";static examples=["<%= config.bin %> auth login","<%= config.bin %> auth login -e user@example.com"];static flags={email:p.string({char:"e",description:"Email address"}),password:p.string({char:"p",description:"Password (for non-interactive use)"}),"api-key":p.string({description:"Authenticate with an API key from https://rulemetric.com/connect (required for Google/GitHub sign-ins, which have no password)",exclusive:["password"]})};async run(){let{flags:s}=await this.parse(y);if(s["api-key"]){await this.loginWithApiKey(s["api-key"]);return}let e=s.email,t=s.password;if(!e||!t){process.stdin.isTTY||this.error("Missing credentials in a non-interactive shell. Pass --email/-e and --password/-p, or set RULEMETRIC_API_KEY (create a key at https://rulemetric.com/connect).");let{input:o,password:k}=await import("@inquirer/prompts");this.log("Signed up with Google or GitHub? You have no password \u2014 press Ctrl-C and run:"),this.log(" rulemetric auth login --api-key <key> (create one at https://rulemetric.com/connect)"),this.log(""),e||(e=await o({message:"Email:"})),t||(t=await k({message:"Password:"}))}let i;try{i=await a("/auth/login",{method:"POST",body:{email:e,password:t},timeoutMs:2e4})}catch(o){throw o instanceof r&&o.statusCode===401&&this.error(`Invalid email or password.
|
|
2
2
|
|
|
3
3
|
If you signed up with Google or GitHub, you have no password \u2014 that is why this cannot work. Create an API key at https://rulemetric.com/connect, then run:
|
|
4
4
|
rulemetric auth login --api-key <key>`),o}let v=i.expiresAt??new Date(Date.now()+3600*1e3).toISOString();d({accessToken:i.accessToken,refreshToken:i.refreshToken,expiresAt:v,email:i.email}),u(i.accessToken,process.env.RULEMETRIC_API_URL),await n(),await f(this.log.bind(this),this.warn.bind(this),this.config.version),c("auth_login",{},this.config.version),this.log(`Logged in as ${i.email}`)}async loginWithApiKey(s){let e=s.trim();e||this.error("Empty --api-key. Create one at https://rulemetric.com/connect"),process.env.RULEMETRIC_API_KEY=e;try{await a("/api/setup/status",{timeoutMs:2e4})}catch(t){throw delete process.env.RULEMETRIC_API_KEY,t instanceof r&&(t.statusCode===401||t.statusCode===403)&&this.error("That API key was rejected. Check you copied it whole (it is shown only once at creation) or mint a new one at https://rulemetric.com/connect"),t}g(e,process.env.RULEMETRIC_API_URL),m(),await n(),c("auth_login",{method:"api_key"},this.config.version),this.log(`Authenticated with API key ${e.slice(0,11)}...`),this.log("Verify any time with: rulemetric auth status")}};export{h as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as s}from"../../chunk-
|
|
1
|
+
import{a as s}from"../../chunk-SE5SRPIB.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-OI7MOALX.js";import"../../chunk-6SUN4NOY.js";import"../../chunk-WVJEBQYU.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-OFC7HIBX.js";import"../../chunk-VXM4PEED.js";import{f as i,j as r}from"../../chunk-PZNWH4VQ.js";import{a as o}from"../../chunk-ZLLER3HP.js";var e=class t extends s{static{o(this,"AuthLogout")}static description="Log out of RuleMetric";static examples=["<%= config.bin %> auth logout"];async run(){await this.parse(t),i(),r(),this.log("Logged out successfully.")}};export{e as default};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as k}from"../../chunk-
|
|
1
|
+
import{a as k}from"../../chunk-SE5SRPIB.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-OI7MOALX.js";import"../../chunk-6SUN4NOY.js";import"../../chunk-WVJEBQYU.js";import"../../chunk-3AV3GTMP.js";import{e as n,i as c}from"../../chunk-OFC7HIBX.js";import"../../chunk-VXM4PEED.js";import"../../chunk-PZNWH4VQ.js";import{a as s}from"../../chunk-ZLLER3HP.js";import{Args as y}from"@oclif/core";var a=class m extends k{static{s(this,"AuthRevokeKey")}static description="Revoke an API key (run with no argument to list active keys)";static examples=["<%= config.bin %> auth revoke-key","<%= config.bin %> auth revoke-key rm_abc12345",'<%= config.bin %> auth revoke-key "my-laptop (auto)"'];static args={id:y.string({description:"API key ID, prefix (rm_xxxxxxxx), or name"})};async run(){let{args:o}=await this.parse(m),r=(await n("/api/auth/api-keys")).filter(e=>!e.revokedAt);if(!o.id){if(r.length===0){this.log("No active API keys.");return}this.log(`Active API keys \u2014 pass an id, prefix, or name to revoke one:
|
|
2
2
|
`);for(let e of r)this.log(` ${e.id} ${e.keyPrefix}... ${e.name}`);return}let i=o.id,t=r.filter(e=>e.id===i||e.name===i||i.startsWith("rm_")&&i.startsWith(e.keyPrefix));t.length===0&&this.error(`No active API key matches "${i}". Run \`rulemetric auth revoke-key\` with no argument to list keys.`),t.length>1&&this.error(`"${i}" matches ${t.length} keys \u2014 use the exact key ID:
|
|
3
3
|
`+t.map(e=>` ${e.id} ${e.keyPrefix}... ${e.name}`).join(`
|
|
4
4
|
`)),await c(`/api/auth/api-keys/${t[0].id}`),this.log(`API key ${t[0].keyPrefix}... ("${t[0].name}") revoked.`)}};export{a as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as g}from"../../chunk-
|
|
1
|
+
import{a as g}from"../../chunk-XILSJP4P.js";import{a as h}from"../../chunk-SE5SRPIB.js";import"../../chunk-IZTIYR5Q.js";import{c as d}from"../../chunk-OI7MOALX.js";import"../../chunk-6SUN4NOY.js";import{b as l}from"../../chunk-WVJEBQYU.js";import"../../chunk-3AV3GTMP.js";import{b as m,d as p}from"../../chunk-OFC7HIBX.js";import"../../chunk-VXM4PEED.js";import{d as n,h as c}from"../../chunk-PZNWH4VQ.js";import{a as o}from"../../chunk-ZLLER3HP.js";import{Flags as u}from"@oclif/core";var t=class f extends h{static{o(this,"AuthSignup")}static description="Create a RuleMetric account from the CLI";static examples=["<%= config.bin %> auth signup","<%= config.bin %> auth signup -e user@example.com"];static flags={email:u.string({char:"e",description:"Email address"}),password:u.string({char:"p",description:"Password (min 8 chars; for non-interactive use)"})};async run(){let{flags:a}=await this.parse(f),i=a.email,r=a.password;if(!i||!r){process.stdin.isTTY||this.error("Missing credentials in a non-interactive shell. Pass --email/-e and --password/-p.");let{input:s,password:v}=await import("@inquirer/prompts");i||(i=await s({message:"Email:"})),r||(r=await v({message:"Password (min 8 chars):"}))}let e;try{e=await p("/auth/signup",{method:"POST",body:{email:i,password:r},timeoutMs:2e4})}catch(s){throw s instanceof m&&s.statusCode===409&&this.error(`An account with ${i} already exists. Run: rulemetric auth login -e ${i}`),s}if(e.confirmationRequired||!e.accessToken||!e.refreshToken){this.log(`Account created for ${e.email}.`),this.log("Check your email and click the confirmation link, then run:"),this.log(` rulemetric auth login -e ${e.email}`);return}let w=e.expiresAt??new Date(Date.now()+3600*1e3).toISOString();n({accessToken:e.accessToken,refreshToken:e.refreshToken,expiresAt:w,email:e.email}),c(e.accessToken,process.env.RULEMETRIC_API_URL),await l(),await g(this.log.bind(this),this.warn.bind(this),this.config.version),d("auth_signup",{},this.config.version),this.log(`Signed up and logged in as ${e.email}`)}};export{t as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as c}from"../../chunk-W2MV25SB.js";import{a as g}from"../../chunk-
|
|
1
|
+
import{a as c}from"../../chunk-W2MV25SB.js";import{a as g}from"../../chunk-SE5SRPIB.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-OI7MOALX.js";import"../../chunk-6SUN4NOY.js";import"../../chunk-WVJEBQYU.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-OFC7HIBX.js";import"../../chunk-VXM4PEED.js";import{a,e as l,l as t}from"../../chunk-PZNWH4VQ.js";import{a as r}from"../../chunk-ZLLER3HP.js";import*as u from"node:path";var o=class h extends g{static{r(this,"AuthStatus")}static description="Show current authentication status";static examples=["<%= config.bin %> auth status"];async run(){await this.parse(h);let e=l(),i=process.env.RULEMETRIC_API_KEY,s=a().apiKey;if(i||s){let m=i||s,p=i?"RULEMETRIC_API_KEY env var":u.join(t(),"env");this.log(`Authenticated via API key ${m.slice(0,11)}... (${p})`),e&&this.log(`Logged in as: ${e.email}`),this.log(`Config: ${t()}`);return}if(!e){this.log("Not logged in. Run `rulemetric auth login` to authenticate.");return}let n=new Date(e.expiresAt).getTime();if(Number.isNaN(n)||Date.now()>=n){this.log("Session expired. Run `rulemetric auth login` to re-authenticate.");return}this.log(`Logged in as: ${e.email}`),this.log(`Session expires: ${c(e.expiresAt)}`),this.log(`Config: ${t()}`)}};export{o as default};
|
|
@@ -1,2 +1,2 @@
|
|
|
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-
|
|
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-SE5SRPIB.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-OI7MOALX.js";import"../../chunk-6SUN4NOY.js";import"../../chunk-WVJEBQYU.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-OFC7HIBX.js";import"../../chunk-VXM4PEED.js";import{l as m}from"../../chunk-PZNWH4VQ.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
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,2 +1,2 @@
|
|
|
1
|
-
import{a as g,b as d,c as p}from"../../chunk-W2MV25SB.js";import{a as c}from"../../chunk-
|
|
1
|
+
import{a as g,b as d,c as p}from"../../chunk-W2MV25SB.js";import{a as c}from"../../chunk-SE5SRPIB.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-OI7MOALX.js";import"../../chunk-6SUN4NOY.js";import"../../chunk-WVJEBQYU.js";import"../../chunk-3AV3GTMP.js";import{e as n}from"../../chunk-OFC7HIBX.js";import"../../chunk-VXM4PEED.js";import"../../chunk-PZNWH4VQ.js";import{a}from"../../chunk-ZLLER3HP.js";import{Flags as i}from"@oclif/core";var o=class m extends c{static{a(this,"Catalog")}static description="Browse the org instruction catalog";static flags={badge:i.string({description:"Filter by badge",options:["recommended","required"]}),scope:i.string({description:"Filter by scope",options:["org","team"]}),search:i.string({description:"Search by name or description"})};async run(){let{flags:e}=await this.parse(m);this.requireAuth();let s=new URLSearchParams;e.badge&&s.set("badge",e.badge),e.scope&&s.set("scope",e.scope),e.search&&s.set("search",e.search);let r=await n(`/api/catalog?${s.toString()}`);if(r.length===0){this.log("No instructions found in catalog.");return}for(let t of r){let l=t.badge?` [${t.badge}]`:"",f=t.tags?.length?` (${t.tags.join(", ")})`:"";this.log(` ${d(t.name,40)} \u2014 ${p(t.scope)}${l} v${t.version}${f} ${g(t.updatedAt)}`)}this.log(`
|
|
2
2
|
${r.length} instruction(s) found.`)}};export{o as default};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{a as i}from"../../chunk-
|
|
1
|
+
import{a as i}from"../../chunk-SE5SRPIB.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-OI7MOALX.js";import"../../chunk-6SUN4NOY.js";import"../../chunk-WVJEBQYU.js";import"../../chunk-3AV3GTMP.js";import{f as n}from"../../chunk-OFC7HIBX.js";import"../../chunk-VXM4PEED.js";import"../../chunk-PZNWH4VQ.js";import{a as t}from"../../chunk-ZLLER3HP.js";import{Args as c}from"@oclif/core";var o=class s extends i{static{t(this,"CatalogRecommend")}static description="Get AI-powered instruction recommendations for a project";static args={projectId:c.string({description:"ID of the project",required:!0})};async run(){let{args:a}=await this.parse(s);this.requireAuth(),this.log(`Analyzing project and generating recommendations...
|
|
2
2
|
`);let r=await n(`/api/projects/${a.projectId}/recommendations`,{});if(r.error&&this.warn(`Note: ${r.error}`),r.recommendations.length===0){this.log("No recommendations found.");return}for(let e of r.recommendations)this.log(` ${(e.score*100).toFixed(0)}% \u2014 ${e.instructionId}`),this.log(` ${e.reason}
|
|
3
3
|
`)}};export{o as default};
|
package/dist/commands/convert.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as l}from"../chunk-WLVQJH4E.js";import{a as u}from"../chunk-
|
|
1
|
+
import{a as l}from"../chunk-WLVQJH4E.js";import{a as u}from"../chunk-SE5SRPIB.js";import"../chunk-IZTIYR5Q.js";import"../chunk-OI7MOALX.js";import"../chunk-6SUN4NOY.js";import"../chunk-WVJEBQYU.js";import"../chunk-3AV3GTMP.js";import{a as n,f as c}from"../chunk-OFC7HIBX.js";import"../chunk-VXM4PEED.js";import"../chunk-PZNWH4VQ.js";import{a}from"../chunk-ZLLER3HP.js";import*as d from"node:fs";import{Args as p,Flags as i}from"@oclif/core";var e=class f extends u{static{a(this,"Convert")}static description="Convert an instruction to a target format";static examples=["<%= config.bin %> convert <id> --format claude-md","<%= config.bin %> convert <id> -f cursorrules --score","<%= config.bin %> convert <id> -f copilot -o .github/copilot-instructions.md"];static args={id:p.string({description:"Instruction ID",required:!0})};static flags={format:i.string({char:"f",description:"Target format (e.g., claude-md, cursorrules)",required:!0}),score:i.boolean({description:"Include quality score",default:!1}),output:i.string({char:"o",description:"Write output to file"})};async run(){let{args:s,flags:t}=await this.parse(f);this.requireAuth(),l(s.id,"instruction ID");let o=new URL(`${process.env.RULEMETRIC_API_URL??n}/api/instructions/${encodeURIComponent(s.id)}/convert`);o.searchParams.set("format",t.format),o.searchParams.set("score",String(t.score));let r=await c(`${o.pathname}${o.search}`,{});t.output?(d.writeFileSync(t.output,r.output,"utf-8"),this.log(`Written to ${t.output}`)):this.log(r.output),t.score&&r.score&&(this.log(""),this.log(`Quality Score: ${r.score.overall}/100`)),r.warnings.length>0&&this.warn(`Warnings: ${r.warnings.join(", ")}`)}};export{e as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as s}from"../chunk-
|
|
1
|
+
import{a as s}from"../chunk-SE5SRPIB.js";import"../chunk-IZTIYR5Q.js";import"../chunk-OI7MOALX.js";import"../chunk-6SUN4NOY.js";import"../chunk-WVJEBQYU.js";import"../chunk-3AV3GTMP.js";import{e as a}from"../chunk-OFC7HIBX.js";import"../chunk-VXM4PEED.js";import"../chunk-PZNWH4VQ.js";import{a as o}from"../chunk-ZLLER3HP.js";import{Flags as m}from"@oclif/core";import{printTable as c}from"@oclif/table";var e=class n extends s{static{o(this,"Converters")}static description="List all supported conversion formats";static examples=["<%= config.bin %> converters","<%= config.bin %> converters --tier 1"];static enableJsonFlag=!0;static flags={tier:m.string({char:"t",description:"Filter by tier",options:["1","2","3"]})};async run(){let{flags:i}=await this.parse(n);this.requireAuth();let r=await a("/api/converters");if(i.tier){let t=Number.parseInt(i.tier,10);r=r.filter(p=>p.tier===t)}return c({data:r.map(t=>({ID:t.id,Name:t.name,Tier:String(t.tier),"Output Path":t.outputPath})),columns:["ID","Name","Tier","Output Path"]}),r}};export{e as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as o}from"../../chunk-GY5IJ4RS.js";import{a as n}from"../../chunk-
|
|
1
|
+
import{a as o}from"../../chunk-GY5IJ4RS.js";import{a as n}from"../../chunk-SE5SRPIB.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-OI7MOALX.js";import"../../chunk-6SUN4NOY.js";import"../../chunk-WVJEBQYU.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-OFC7HIBX.js";import"../../chunk-VXM4PEED.js";import"../../chunk-PZNWH4VQ.js";import{a as i}from"../../chunk-ZLLER3HP.js";import{printTable as t}from"@oclif/table";var a=class s extends n{static{i(this,"CronsList")}static description="List manually-runnable maintenance tasks";static examples=["<%= config.bin %> crons list"];async run(){await this.parse(s),t({data:o.map(e=>({Name:e.name,"Scheduled by":e.scheduledBy,Description:e.description})),columns:["Name","Scheduled by","Description"]}),this.log(""),this.log("Scheduled crons run in Supabase pg_cron \u2014 audit them with:"),this.log(` psql "$DATABASE_URL" -c 'select jobname, schedule, active from cron.job;'`),this.log("Run any task above on demand with: rulemetric crons run <name>")}};export{a as default};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{a as u}from"../../chunk-GY5IJ4RS.js";import{a as c}from"../../chunk-
|
|
1
|
+
import{a as u}from"../../chunk-GY5IJ4RS.js";import{a as c}from"../../chunk-SE5SRPIB.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-OI7MOALX.js";import"../../chunk-6SUN4NOY.js";import"../../chunk-WVJEBQYU.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-OFC7HIBX.js";import"../../chunk-VXM4PEED.js";import"../../chunk-PZNWH4VQ.js";import{a as l}from"../../chunk-ZLLER3HP.js";import{Args as g,Flags as f}from"@oclif/core";var i=class m extends c{static{l(this,"CronsRun")}static description="Run a maintenance task synchronously, right now";static examples=["<%= config.bin %> crons run cron_check_changelog","<%= config.bin %> crons run cron_suggest_instructions --quiet"];static args={name:g.string({description:"Task name (run `rulemetric crons list` to see all)",required:!0})};static flags={quiet:f.boolean({char:"q",description:"Suppress per-line log output; print summary only"})};async run(){let{args:s,flags:d}=await this.parse(m);this.requireAuth();let n=u.find(e=>e.name===s.name);n||this.error(`Unknown task: ${s.name}
|
|
2
2
|
Run \`rulemetric crons list\` to see available tasks.`);let o;try{({runManualTask:o}=await import("../../lib/manual-tasks.js"))}catch(e){let r=e?.code;throw(r==="ERR_MODULE_NOT_FOUND"||r==="MODULE_NOT_FOUND")&&this.error("`crons run` needs the worker runtime, which isn't available in this install.\nThese maintenance tasks connect to the database directly \u2014 run them from a full RuleMetric checkout with DATABASE_URL and the worker dependencies installed."),e}this.log(`\u25B6 Running ${n.name} \u2026`);let h=Date.now(),t=await o(s.name);if(!d.quiet)for(let e of t.logs){let r=e.level==="error"||e.level==="warn"?`[${e.level}]`:"";this.log(` ${r} ${e.message}`)}let a=((t.durationMs??Date.now()-h)/1e3).toFixed(1);t.ok?this.log(`\u2713 ${n.name} completed in ${a}s (${t.logs.length} log line${t.logs.length===1?"":"s"})`):this.error(`\u2717 ${n.name} failed after ${a}s: ${t.error}`)}};export{i as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as o}from"../chunk-
|
|
1
|
+
import{a as o}from"../chunk-SE5SRPIB.js";import"../chunk-IZTIYR5Q.js";import"../chunk-OI7MOALX.js";import"../chunk-6SUN4NOY.js";import"../chunk-WVJEBQYU.js";import"../chunk-3AV3GTMP.js";import"../chunk-OFC7HIBX.js";import"../chunk-VXM4PEED.js";import"../chunk-PZNWH4VQ.js";import{a as i}from"../chunk-ZLLER3HP.js";import{Flags as r}from"@oclif/core";var a=class s extends o{static{i(this,"Dashboard")}static description="Interactive TUI dashboard showing session analytics, outcomes, friction, and insights";static examples=["<%= config.bin %> dashboard","<%= config.bin %> dashboard --period 30days","<%= config.bin %> dashboard --launcher"];static flags={period:r.string({char:"p",default:"week",options:["today","week","30days","month","all"],description:"Initial time period"}),launcher:r.boolean({char:"l",default:!1,description:"Open the launcher overlay immediately"})};async run(){let{flags:e}=await this.parse(s),{renderDashboard:t}=await import("../dashboard/Dashboard.js");await t(e.period,{openLauncher:e.launcher})}};export{a as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{b as
|
|
1
|
+
import{b as R,c as B}from"../chunk-V5U3E4BZ.js";import{a as Y}from"../chunk-3QXRLIGC.js";import"../chunk-HFGO5762.js";import{e as S,f as A,g as C}from"../chunk-QWCEZEDO.js";import"../chunk-KKDHD4XA.js";import"../chunk-SZ62CP55.js";import{d as J,e as q}from"../chunk-HKC224ZO.js";import"../chunk-H6MN2AAF.js";import"../chunk-G7V4ZZZ3.js";import"../chunk-NTJKAIHS.js";import{i as j,j as F,k as G,m as W,n as V}from"../chunk-BL4BN6RU.js";import"../chunk-7LXG3DDL.js";import{d as D}from"../chunk-OPUI7CM2.js";import"../chunk-EOJ3LAP6.js";import"../chunk-L2CFSMBC.js";import"../chunk-Z72VHGV7.js";import"../chunk-KGURGIZ2.js";import"../chunk-TCR7TSAJ.js";import"../chunk-CDY7TQFZ.js";import"../chunk-V5MJ4ICC.js";import"../chunk-MODFTCZY.js";import"../chunk-PJ3WHQ67.js";import"../chunk-N7ODX6PO.js";import"../chunk-G5BXZT6F.js";import"../chunk-TZA4HAVF.js";import{a as I,b as M,c as N,f as U,g as X}from"../chunk-QXPYGN7I.js";import{a as H}from"../chunk-SE5SRPIB.js";import"../chunk-IZTIYR5Q.js";import"../chunk-OI7MOALX.js";import"../chunk-6SUN4NOY.js";import"../chunk-WVJEBQYU.js";import"../chunk-3AV3GTMP.js";import{a as L,e as P}from"../chunk-OFC7HIBX.js";import"../chunk-VXM4PEED.js";import{a as O,g as f,l as E}from"../chunk-PZNWH4VQ.js";import{a as T}from"../chunk-ZLLER3HP.js";import{spawnSync as ee}from"node:child_process";import{existsSync as te,readFileSync as oe}from"node:fs";import{join as K}from"node:path";var _=class h extends H{static{T(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??O().apiUrl??L}async checkDirect(){let n=process.env.HTTPS_PROXY,i=process.env.HTTP_PROXY;delete process.env.HTTPS_PROXY,delete process.env.HTTP_PROXY;let o=new AbortController,a=setTimeout(()=>o.abort(),8e3);try{return(await globalThis.fetch(`${this.baseUrl()}/health`,{signal:o.signal})).ok}catch{return!1}finally{clearTimeout(a),n!==void 0&&(process.env.HTTPS_PROXY=n),i!==void 0&&(process.env.HTTP_PROXY=i)}}configuredProxy(){if(process.env.HTTPS_PROXY)return process.env.HTTPS_PROXY;for(let n of["settings.local.json","settings.json"]){let i=K(process.cwd(),".claude",n);if(te(i))try{let o=JSON.parse(oe(i,"utf8"));if(o.env?.HTTPS_PROXY)return o.env.HTTPS_PROXY}catch{}}return null}checkThroughProxy(n){let i=ee("curl",["-sS","-x",n,"--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 n=process.version,i=this.configuredProxy(),o=i!=null,[a,m,u]=await Promise.all([this.checkDirect(),C(S),C(A)]),d=o&&i?this.checkThroughProxy(i):null,e=T((r,p,b)=>{let c=p===null?"\u2013":p?"[OK]":"[!!]";this.log(` ${c} ${r.padEnd(22)} ${b}`)},"line");this.log("RuleMetric diagnostics"),this.log(""),e("Node",!R(n),`${n}${R(n)?" (< 20.11 \u2014 breaks the bundled proxy)":""}`),e("API (direct)",a,`${this.baseUrl()}/health ${a?"reachable":"UNREACHABLE"}`),e("Authenticated",f(),f()?"yes":"no \u2014 run `rulemetric auth login`"),e("Proxy configured",o?!0:null,o?i:"no HTTPS_PROXY set"),o&&(e("Gateway :"+S,m,m?"listening":"NOT listening"),e("mitmproxy :"+A,u,u?"listening":"not listening (gateway should route direct)"),e("API (via proxy)",d,d===null?"inconclusive (curl unavailable)":d?"reachable":"FAILED \u2014 502/blocked through your proxy"));let s=D();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 t=null;if(f()&&a)try{t=await P("/api/workers/health")}catch{t=null}if(t){let r=t.worker;e("Worker",!!r.active,r.present?r.active?`online (last heartbeat ${r.ageSeconds??"?"}s ago${r.clientVersion?`, v${r.clientVersion}`:""})`:`NOT RUNNING \u2014 last heartbeat ${ne(r.ageSeconds)} ago`:"never connected \u2014 no worker has ever reported in");let p=t.worker.engines;if(p!=null){let c=[p.claude&&"claude",p.codex&&"codex"].filter(Boolean);e("LLM engine",c.length>0,c.length>0?`${c.join(" + ")} available to the worker`:"NONE \u2014 the worker found no `claude` and no `codex`. LLM jobs will complete with empty output rather than failing.")}let b=t.pending.reduce((c,w)=>c+w.count,0);if(b>0){let c=t.verdict.stuck.reduce((v,y)=>v+y.count,0),w=t.verdict.unclaimable.reduce((v,y)=>v+y.count,0),x=(t.verdict.engineBlocked??[]).reduce((v,y)=>v+y.count,0);e("Job queue",c===0&&x===0,`${b} pending`+(c>0?` \u2014 ${c} waiting on this worker`:"")+(x>0?` \u2014 ${x} need a local LLM engine`:"")+(w>0?` \u2014 ${w} need a worker with DATABASE_URL`:""))}else e("Job queue",!0,"empty")}else f()&&a&&e("Worker",null,"could not read /workers/health (older API?)");let l=Y(process.cwd()),g=await M({configDir:E()}),z=await N({configDir:E()}),$=` \u2014 ${X(z)}`,Q={claude_code:`session hooks (+ proxy for instruction linking)${$}`,codex:`worker transcript sync of ~/.codex/sessions \u2014 ${U(g)}`,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 r of l)this.log(` \u2022 ${r.padEnd(15)} ${Q[r]??"captured"}`);if(l.includes("codex"))if(g.error)this.log(` ! ${g.error}`);else if(g.mode==="allowlist")for(let r of g.roots)this.log(` \u21B3 ${r}`);else g.mode==="all"&&this.log(` \u21B3 scope it with ${K(E(),I)} ({"codex":{"roots":["/path/to/repo"]}}) or RULEMETRIC_CODEX_CAPTURE=off`);t&&!t.worker.active&&l.includes("codex")&&g.mode!=="off"&&this.log(" ! Codex capture runs INSIDE the worker \u2014 it is stopped while the worker is down."),f()&&a&&await this.reportEvolutionSpend();let k=B({nodeVersion:n,directApiOk:a,httpsProxySet:o,gatewayAlive:m,mitmproxyAlive:u,proxyPathOk:d});this.log("");let Z=k.severity==="ok"?"[OK]":k.severity==="warn"?"[!!]":"[XX]";this.log(`${Z} ${k.headline}`);for(let r of k.hints)this.log(` \u2022 ${r}`);if(t&&t.verdict.severity!=="ok"){let r=t.verdict.severity==="warn"?"[!!]":"[XX]";this.log(""),this.log(`${r} ${t.verdict.headline}`);for(let p of t.verdict.hints)this.log(` \u2022 ${p}`)}}async reportEvolutionSpend(){let n;try{n=await P("/api/eval-targets?type=instruction&limit=200")}catch{return}let i=n.filter(o=>{let a=o.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 o of i){let a=o.metadata??{},m=F(a),u=j(a);if(m){this.log(` \u2022 ${o.name} \u2014 PAUSED (metadata.autoEvolvePaused). Opt-in preserved.`),this.log(" \u21B3 resume: set autoEvolvePaused=false");continue}let d=null;try{d=(await P(`/api/eval-targets/${o.id}/evals`)).filter(s=>!s.retiredAt).length}catch{}if(this.log(` \u2022 ${o.name}`),d!=null){let e=q(d,u.minPairs,J(u,d));if(!e.feasible)this.log(` \u21B3 cannot reach a verdict \u2014 ${e.reason}`);else{let s=G({liveCases:d,passes:e.passes});this.log(` \u21B3 each night: ${V(s)}`)}}this.log(` \u21B3 pairs budget ${u.minPairs}`+(u.configured?" (metadata.autoEvolvePairs)":" (default)")+` \xB7 writes ${a.autoEvolveApply===!0||a.autoEvolveApply==="true"?"ENABLED":"off (dry run)"}`),u.note&&this.log(` ! ${u.note}`);try{let e=await P(`/api/eval-targets/${o.id}/promotions?limit=1`),s=e.promotions[0];if(s){let l=s.gates?.cost,g=l?.modelCalls?`${l.modelCalls} model calls, ${l.usablePairs??"?"} usable pair(s)`+(l.mde!=null?`, resolved +/-${W(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 ${g}`)}let t=e.counts??{};this.log(` \u21B3 lifetime: ${t.promote??0} promote / ${t.revert??0} revert / ${t.refuse??0} refuse`)}catch{}}this.log(" \u21B3 pause the spend: metadata.autoEvolvePaused=true (keeps the opt-in)")}}};function ne(h){if(h===null)return"never";if(h<90)return`${Math.round(h)}s`;let n=Math.round(h/60);return n<90?`${n}m`:`${Math.round(n/60)}h`}T(ne,"formatAge");export{_ as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a}from"../../chunk-
|
|
1
|
+
import{a}from"../../chunk-SE5SRPIB.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-OI7MOALX.js";import"../../chunk-6SUN4NOY.js";import"../../chunk-WVJEBQYU.js";import"../../chunk-3AV3GTMP.js";import{f as s}from"../../chunk-OFC7HIBX.js";import"../../chunk-VXM4PEED.js";import"../../chunk-PZNWH4VQ.js";import{a as o}from"../../chunk-ZLLER3HP.js";import{Flags as e}from"@oclif/core";import{readFileSync as p}from"node:fs";var n=class c extends a{static{o(this,"EvalTargetCreate")}static description="Create an eval target (instruction, skill, prompt, or plan to test)";static examples=["<%= config.bin %> eval-targets create --name my-rules --type instruction --file ./CLAUDE.md",'<%= config.bin %> eval-targets create --name my-prompt --type prompt --content "Always use TypeScript"'];static flags={name:e.string({char:"n",description:"Name for the eval target",required:!0}),type:e.string({char:"t",description:"Target type",options:["instruction","skill","prompt","plan"],required:!0}),file:e.string({char:"f",description:"Path to content file"}),content:e.string({char:"c",description:"Content string (alternative to --file)"}),description:e.string({char:"d",description:"Description of the target",default:""})};async run(){let{flags:t}=await this.parse(c);this.requireAuth();let i;t.file?i=p(t.file,"utf-8"):t.content?i=t.content:this.error("Provide either --file or --content");let r=await s("/api/eval-targets",{name:t.name,type:t.type,content:i,description:t.description});this.log(`Created eval target: ${r.name} (${r.id}) v${r.version}`)}};export{n as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as p,b as e}from"../../chunk-W2MV25SB.js";import{a as o}from"../../chunk-
|
|
1
|
+
import{a as p,b as e}from"../../chunk-W2MV25SB.js";import{a as o}from"../../chunk-SE5SRPIB.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-OI7MOALX.js";import"../../chunk-6SUN4NOY.js";import"../../chunk-WVJEBQYU.js";import"../../chunk-3AV3GTMP.js";import{e as n}from"../../chunk-OFC7HIBX.js";import"../../chunk-VXM4PEED.js";import"../../chunk-PZNWH4VQ.js";import{a as s}from"../../chunk-ZLLER3HP.js";import{Flags as m}from"@oclif/core";import{printTable as d}from"@oclif/table";var r=class l extends o{static{s(this,"EvalTargetList")}static description="List eval targets";static examples=["<%= config.bin %> eval-targets list","<%= config.bin %> eval-targets list --type instruction"];static flags={type:m.string({char:"t",description:"Filter by type",options:["instruction","skill","prompt","plan"]})};async run(){let{flags:i}=await this.parse(l);this.requireAuth();let c=i.type?`?type=${i.type}`:"",a=await n(`/api/eval-targets${c}`);if(a.length===0){this.log("No eval targets found. Create one with `rulemetric eval-targets create`.");return}d({data:a.map(t=>({Name:e(t.name,30),Type:t.type,Version:`v${t.version}`,Description:e(t.description,40),Updated:p(t.updatedAt)})),columns:["Name","Type","Version","Description","Updated"]})}};export{r as default};
|