@xerg/cli 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +133 -11
  2. package/package.json +6 -11
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{Command as we}from"commander";import vt from"picocolors";import{readFileSync as Bt}from"fs";import{createHash as Ot}from"crypto";function y(t){return Ot("sha1").update(t).digest("hex")}function Y(t){if(!t)return null;let e=t.trim().match(/^(\d+)([mhdw])$/i);if(!e)throw new Error(`Invalid --since value "${t}". Use values like 30m, 24h, 7d, 2w.`);let o=Number(e[1]),n=e[2].toLowerCase(),s={m:60*1e3,h:3600*1e3,d:1440*60*1e3,w:10080*60*1e3};return Date.now()-o*s[n]}function R(){return new Date().toISOString()}function D(t){if(typeof t=="string"){let e=new Date(t);if(!Number.isNaN(e.getTime()))return e.toISOString()}if(typeof t=="number"){let e=new Date(t);if(!Number.isNaN(e.getTime()))return e.toISOString()}return R()}import{mkdirSync as xt}from"fs";import{dirname as Ft}from"path";import Dt from"better-sqlite3";import{drizzle as Pt}from"drizzle-orm/better-sqlite3";import{integer as U,real as T,sqliteTable as I,text as p}from"drizzle-orm/sqlite-core";var q=I("source_files",{id:p("id").primaryKey(),path:p("path").notNull(),kind:p("kind").notNull(),fileHash:p("file_hash").notNull(),mtimeMs:U("mtime_ms").notNull(),sizeBytes:U("size_bytes").notNull(),importedAt:p("imported_at").notNull()}),Q=I("runs",{id:p("id").primaryKey(),sourcePath:p("source_path").notNull(),sourceKind:p("source_kind").notNull(),timestamp:p("timestamp").notNull(),workflow:p("workflow").notNull(),environment:p("environment").notNull(),tagsJson:p("tags_json").notNull(),totalCostUsd:T("total_cost_usd").notNull(),totalTokens:U("total_tokens").notNull(),observedCostUsd:T("observed_cost_usd").notNull(),estimatedCostUsd:T("estimated_cost_usd").notNull()}),V=I("calls",{id:p("id").primaryKey(),runId:p("run_id").notNull(),timestamp:p("timestamp").notNull(),provider:p("provider").notNull(),model:p("model").notNull(),inputTokens:U("input_tokens").notNull(),outputTokens:U("output_tokens").notNull(),costUsd:T("cost_usd").notNull(),costSource:p("cost_source").notNull(),latencyMs:U("latency_ms"),toolCalls:U("tool_calls").notNull(),retries:U("retries").notNull(),attempt:U("attempt"),iteration:U("iteration"),status:p("status"),taskClass:p("task_class"),cacheHit:U("cache_hit",{mode:"boolean"}).notNull(),cacheCostUsd:T("cache_cost_usd"),metadataJson:p("metadata_json").notNull()}),Z=I("findings",{id:p("id").primaryKey(),auditId:p("audit_id").notNull(),classification:p("classification").notNull(),confidence:p("confidence").notNull(),kind:p("kind").notNull(),title:p("title").notNull(),summary:p("summary").notNull(),scope:p("scope").notNull(),scopeId:p("scope_id").notNull(),costImpactUsd:T("cost_impact_usd").notNull(),detailsJson:p("details_json").notNull()}),tt=I("pricing_catalog",{id:p("id").primaryKey(),provider:p("provider").notNull(),model:p("model").notNull(),effectiveDate:p("effective_date").notNull(),inputPer1m:T("input_per_1m").notNull(),outputPer1m:T("output_per_1m").notNull(),cachedInputPer1m:T("cached_input_per_1m")}),_=I("audit_snapshots",{id:p("id").primaryKey(),createdAt:p("created_at").notNull(),summaryJson:p("summary_json").notNull()}),et=`
2
+ import{readFileSync as ct}from"fs";import{styleText as ut}from"util";import{readFileSync as Ae}from"fs";import{createHash as Oe}from"crypto";function U(e){return Oe("sha1").update(e).digest("hex")}function H(e){if(!e)return null;let t=e.trim().match(/^(\d+)([mhdw])$/i);if(!t)throw new Error(`Invalid --since value "${e}". Use values like 30m, 24h, 7d, 2w.`);let n=Number(t[1]),o=t[2].toLowerCase(),r={m:60*1e3,h:3600*1e3,d:1440*60*1e3,w:10080*60*1e3};return Date.now()-n*r[o]}function R(){return new Date().toISOString()}function v(e){if(typeof e=="string"){let t=new Date(e);if(!Number.isNaN(t.getTime()))return t.toISOString()}if(typeof e=="number"){let t=new Date(e);if(!Number.isNaN(t.getTime()))return t.toISOString()}return R()}import{mkdirSync as $e}from"fs";import{dirname as Le}from"path";import _e from"better-sqlite3";var Y=`
3
3
  CREATE TABLE IF NOT EXISTS source_files (
4
4
  id TEXT PRIMARY KEY,
5
5
  path TEXT NOT NULL,
@@ -75,13 +75,135 @@ CREATE TABLE IF NOT EXISTS audit_snapshots (
75
75
  created_at TEXT NOT NULL,
76
76
  summary_json TEXT NOT NULL
77
77
  );
78
- `;function O(t){xt(Ft(t),{recursive:!0});let e=new Dt(t);return e.exec(et),{sqlite:e,db:Pt(e)}}function ot(t,e){let{db:o,sqlite:n}=O(e),s=R(),a=t.pricingCatalog.map(r=>({...r,cachedInputPer1m:r.cachedInputPer1m??null})),i=t.summary.sourceFiles.map(r=>({id:y(`${r.path}:${r.mtimeMs}:${r.sizeBytes}`),path:r.path,kind:r.kind,fileHash:y(Bt(r.path,"utf8")),mtimeMs:Math.trunc(r.mtimeMs),sizeBytes:r.sizeBytes,importedAt:s})),c=t.runs.map(r=>({id:r.id,sourcePath:r.sourcePath,sourceKind:r.sourceKind,timestamp:r.timestamp,workflow:r.workflow,environment:r.environment,tagsJson:JSON.stringify(r.tags),totalCostUsd:r.totalCostUsd,totalTokens:r.totalTokens,observedCostUsd:r.observedCostUsd,estimatedCostUsd:r.estimatedCostUsd})),l=t.runs.flatMap(r=>r.calls.map(u=>({id:u.id,runId:u.runId,timestamp:u.timestamp,provider:u.provider,model:u.model,inputTokens:u.inputTokens,outputTokens:u.outputTokens,costUsd:u.costUsd,costSource:u.costSource,latencyMs:u.latencyMs,toolCalls:u.toolCalls,retries:u.retries,attempt:u.attempt,iteration:u.iteration,status:u.status,taskClass:u.taskClass,cacheHit:u.cacheHit,cacheCostUsd:u.cacheCostUsd,metadataJson:JSON.stringify(u.metadata)}))),d=t.summary.findings.map(r=>({id:r.id,auditId:t.summary.auditId,classification:r.classification,confidence:r.confidence,kind:r.kind,title:r.title,summary:r.summary,scope:r.scope,scopeId:r.scopeId,costImpactUsd:r.costImpactUsd,detailsJson:JSON.stringify(r.details)}));a.length>0&&o.insert(tt).values(a).onConflictDoNothing().run(),i.length>0&&o.insert(q).values(i).onConflictDoNothing().run(),c.length>0&&o.insert(Q).values(c).onConflictDoNothing().run(),l.length>0&&o.insert(V).values(l).onConflictDoNothing().run(),d.length>0&&o.insert(Z).values(d).onConflictDoNothing().run(),o.insert(_).values({id:t.summary.auditId,createdAt:t.summary.generatedAt,summaryJson:JSON.stringify(t.summary)}).onConflictDoNothing().run(),n.close()}import{desc as Gt}from"drizzle-orm";var Mt={"retry-waste":"Retry waste","context-outlier":"Context bloat","loop-waste":"Loop waste","candidate-downgrade":"Downgrade candidates","idle-spend":"Idle waste"};function h(t){return Number(t.toFixed(6))}function Wt(t){if(!t)return"all";let e=t.trim().toLowerCase().match(/^(\d+)([mhdw])$/);return e?`${Number(e[1])}${e[2]}`:t.trim().toLowerCase()}function it(t){return t.replace(/\\/g,"/")}function Xt(t){let e=it(t),o="/sessions/",n=e.lastIndexOf(o);return n>=0?e.slice(0,n+o.length-1):e.slice(0,e.lastIndexOf("/"))||e}function Kt(t){let e=it(t);return e.slice(0,e.lastIndexOf("/"))||e}function jt(t){return Mt[t]??t}function zt(t){return t.kind==="sessions"?Xt(t.path):Kt(t.path)}function B(t){let e=Array.from(new Set(t.sources.map(n=>n.kind))).sort(),o=Array.from(new Set(t.sources.map(n=>`${n.kind}:${zt(n)}`))).sort();return y(JSON.stringify({kinds:e,roots:o,since:Wt(t.since)}))}function E(t,e){let o=new Map;for(let n of t){if(n.classification!==e)continue;let s=o.get(n.kind)??{kind:n.kind,label:jt(n.kind),classification:e,spendUsd:0,findingCount:0};s.spendUsd=h(s.spendUsd+n.costImpactUsd),s.findingCount+=1,o.set(n.kind,s)}return Array.from(o.values()).sort((n,s)=>s.spendUsd-n.spendUsd)}function nt(t){return new Map(t.map(e=>[e.key,e.spendUsd]))}function st(t,e){let o=nt(t),n=nt(e);return Array.from(new Set([...o.keys(),...n.keys()])).map(a=>{let i=n.get(a)??0,c=o.get(a)??0;return{key:a,baselineSpendUsd:h(i),currentSpendUsd:h(c),deltaSpendUsd:h(c-i)}}).filter(a=>a.deltaSpendUsd!==0).sort((a,i)=>Math.abs(i.deltaSpendUsd)-Math.abs(a.deltaSpendUsd)).slice(0,3)}function rt(t){return`${t.kind}:${t.scope}:${t.scopeId}`}function P(t){return t.sort((e,o)=>Math.abs(o.deltaCostImpactUsd)-Math.abs(e.deltaCostImpactUsd))}function Jt(t,e){let o=t.filter(d=>d.classification==="waste"&&d.confidence==="high"),n=e.filter(d=>d.classification==="waste"&&d.confidence==="high"),s=new Map(o.map(d=>[rt(d),d])),a=new Map(n.map(d=>[rt(d),d])),i=[],c=[],l=[];for(let[d,r]of s.entries()){let u=a.get(d);if(!u){i.push({kind:r.kind,title:r.title,scope:r.scope,scopeId:r.scopeId,currentCostImpactUsd:r.costImpactUsd,deltaCostImpactUsd:h(r.costImpactUsd)});continue}let m=h(r.costImpactUsd-u.costImpactUsd);m>0&&l.push({kind:r.kind,title:r.title,scope:r.scope,scopeId:r.scopeId,baselineCostImpactUsd:u.costImpactUsd,currentCostImpactUsd:r.costImpactUsd,deltaCostImpactUsd:m})}for(let[d,r]of a.entries())s.has(d)||c.push({kind:r.kind,title:r.title,scope:r.scope,scopeId:r.scopeId,baselineCostImpactUsd:r.costImpactUsd,deltaCostImpactUsd:h(-r.costImpactUsd)});return{newHighConfidenceWaste:P(i),resolvedHighConfidenceWaste:P(c),worsenedHighConfidenceWaste:P(l)}}function at(t){return{...t,comparisonKey:t.comparisonKey??B({sources:t.sourceFiles,since:t.since}),comparison:t.comparison??null,wasteByKind:t.wasteByKind?.length>0?t.wasteByKind:E(t.findings,"waste"),opportunityByKind:t.opportunityByKind?.length>0?t.opportunityByKind:E(t.findings,"opportunity"),notes:t.notes??[]}}function dt(t,e){let o=st(t.spendByWorkflow,e.spendByWorkflow),n=st(t.spendByModel,e.spendByModel);return{baselineAuditId:e.auditId,baselineGeneratedAt:e.generatedAt,baselineRunCount:e.runCount,baselineCallCount:e.callCount,baselineTotalSpendUsd:e.totalSpendUsd,baselineObservedSpendUsd:e.observedSpendUsd,baselineEstimatedSpendUsd:e.estimatedSpendUsd,baselineWasteSpendUsd:e.wasteSpendUsd,baselineOpportunitySpendUsd:e.opportunitySpendUsd,baselineStructuralWasteRate:e.structuralWasteRate,deltaTotalSpendUsd:h(t.totalSpendUsd-e.totalSpendUsd),deltaObservedSpendUsd:h(t.observedSpendUsd-e.observedSpendUsd),deltaEstimatedSpendUsd:h(t.estimatedSpendUsd-e.estimatedSpendUsd),deltaWasteSpendUsd:h(t.wasteSpendUsd-e.wasteSpendUsd),deltaOpportunitySpendUsd:h(t.opportunitySpendUsd-e.opportunitySpendUsd),deltaStructuralWasteRate:h(t.structuralWasteRate-e.structuralWasteRate),deltaRunCount:t.runCount-e.runCount,deltaCallCount:t.callCount-e.callCount,workflowDeltas:o,modelDeltas:n,findingChanges:Jt(t.findings,e.findings)}}function Ht(t){try{return at(JSON.parse(t))}catch{return null}}function Yt(t){let{db:e,sqlite:o}=O(t);try{return e.select({summaryJson:_.summaryJson}).from(_).orderBy(Gt(_.createdAt)).all().map(s=>Ht(s.summaryJson)).filter(s=>s!==null)}finally{o.close()}}function ct(t){return Yt(t.dbPath).find(e=>t.currentAuditId&&e.auditId===t.currentAuditId?!1:e.comparisonKey===t.comparisonKey)}import{statSync as Zt}from"fs";import K from"fast-glob";import{mkdirSync as M}from"fs";import{homedir as qt}from"os";import{join as lt}from"path";import Qt from"env-paths";function Vt(){let t=Qt("xerg",{suffix:""});return M(t.data,{recursive:!0}),M(t.config,{recursive:!0}),M(t.cache,{recursive:!0}),t}function ut(){return lt(Vt().data,"xerg.db")}function W(){return lt(qt(),".openclaw","agents","*","sessions","*.jsonl")}function X(){return"/tmp/openclaw/openclaw-*.log"}function x(t,e){try{let o=Zt(t);return o.isFile()?{kind:e,path:t,sizeBytes:o.size,mtimeMs:o.mtimeMs}:null}catch{return null}}async function j(t){let e=[];if(t.logFile){let a=x(t.logFile,"gateway");a&&e.push(a)}if(t.sessionsDir){let a=await K("**/*.jsonl",{absolute:!0,cwd:t.sessionsDir,onlyFiles:!0});for(let i of a){let c=x(i,"sessions");c&&e.push(c)}}if(e.length>0)return e.sort((a,i)=>i.mtimeMs-a.mtimeMs);let[o,n]=await Promise.all([K(X(),{absolute:!0,onlyFiles:!0}),K(W(),{absolute:!0,onlyFiles:!0})]);return[...o.map(a=>x(a,"gateway")).filter(Boolean),...n.map(a=>x(a,"sessions")).filter(Boolean)].sort((a,i)=>i.mtimeMs-a.mtimeMs)}async function pt(t){let e=await j(t),o=[];return e.length===0&&(o.push("No OpenClaw gateway logs or session files were detected."),o.push("Use --log-file or --sessions-dir if your OpenClaw data lives outside the defaults.")),e.some(n=>n.kind==="gateway")&&o.push("Gateway logs detected. These are preferred when cost metadata is present."),e.some(n=>n.kind==="sessions")&&o.push("Session transcript fallback detected. Xerg will extract usage metadata only."),{canAudit:e.length>0,sources:e,defaults:{gatewayPattern:X(),sessionsPattern:W()},notes:o}}function v(t){return{...t,id:y(`${t.kind}:${t.scope}:${t.scopeId}:${t.title}:${t.costImpactUsd}:${t.summary}`)}}function b(t){return Number(t.toFixed(6))}function mt(t){let e=[],n=t.flatMap(i=>i.calls.map(c=>({run:i,call:c}))).filter(({call:i})=>{let c=(i.status??"").toLowerCase();return c.includes("error")||c.includes("fail")}),s=n.reduce((i,c)=>i+c.call.costUsd,0);s>0&&e.push(v({classification:"waste",confidence:"high",kind:"retry-waste",title:"Retry waste is consuming measurable spend",summary:`${n.length} failed call${n.length===1?"":"s"} were followed by additional work, making their spend pure retry overhead.`,scope:"global",scopeId:"all",costImpactUsd:b(s),details:{failedCallCount:n.length}}));for(let i of t){let c=Math.max(...i.calls.map(l=>l.iteration??0));if(c>=7){let d=i.calls.filter(r=>(r.iteration??0)>5).reduce((r,u)=>r+u.costUsd,0);e.push(v({classification:"waste",confidence:"high",kind:"loop-waste",title:`Workflow "${i.workflow}" ran beyond efficient loop bounds`,summary:`This run reached ${c} iterations. Xerg treats the spend after iteration 5 as likely loop waste.`,scope:"run",scopeId:i.id,costImpactUsd:b(d),details:{workflow:i.workflow,maxIteration:c}}))}}let a=new Map;for(let i of t){let c=a.get(i.workflow)??[];c.push(i),a.set(i.workflow,c)}for(let[i,c]of a.entries()){if(c.length>=3){let r=c.map(w=>w.calls.reduce((S,C)=>S+C.inputTokens,0)),u=r.reduce((w,S)=>w+S,0)/r.length,m=c.filter(w=>{let S=w.calls.reduce((C,At)=>C+At.inputTokens,0);return S>u*1.75&&S>1500});if(m.length>0){let w=m.reduce((S,C)=>S+C.totalCostUsd,0);e.push(v({classification:"opportunity",confidence:"medium",kind:"context-outlier",title:`Context usage in "${i}" is well above its baseline`,summary:`Xerg found ${m.length} run${m.length===1?"":"s"} in this workflow with input token volume far above the workflow average.`,scope:"workflow",scopeId:i,costImpactUsd:b(w),details:{workflow:i,averageInputTokens:b(u),outlierRunCount:m.length}}))}}let l=c.filter(r=>/(heartbeat|cron|monitor|poll)/i.test(r.workflow));if(l.length>0){let r=l.reduce((u,m)=>u+m.totalCostUsd,0);e.push(v({classification:"opportunity",confidence:"medium",kind:"idle-spend",title:`Idle or monitoring spend detected in "${i}"`,summary:"This workflow name looks like a recurring heartbeat or monitoring loop. Review whether the cadence and model tier are justified.",scope:"workflow",scopeId:i,costImpactUsd:b(r),details:{workflow:i}}))}let d=c.flatMap(r=>r.calls).filter(r=>/(opus|gpt-4o|sonnet)/i.test(r.model)&&/(heartbeat|cron|monitor|summary|tag|triage)/i.test(r.taskClass??i));if(d.length>0){let r=d.reduce((u,m)=>u+m.costUsd,0);e.push(v({classification:"opportunity",confidence:"low",kind:"candidate-downgrade",title:`Candidate model downgrade opportunity in "${i}"`,summary:"An expensive model is being used on a workflow that looks operationally simple. Treat this as an A/B test candidate, not proven waste.",scope:"workflow",scopeId:i,costImpactUsd:b(r*.3),details:{workflow:i,expensiveCallCount:d.length,inspectedSpendUsd:b(r)}}))}}return e.sort((i,c)=>c.costImpactUsd-i.costImpactUsd)}import{readFileSync as ee}from"fs";import{basename as oe}from"path";var z=[{id:"anthropic-claude-haiku-4-5-2026-03-01",provider:"anthropic",model:"claude-haiku-4-5",effectiveDate:"2026-03-01",inputPer1m:.8,outputPer1m:4},{id:"anthropic-claude-sonnet-4-5-2026-03-01",provider:"anthropic",model:"claude-sonnet-4-5",effectiveDate:"2026-03-01",inputPer1m:3,outputPer1m:15},{id:"anthropic-claude-opus-4-2026-03-01",provider:"anthropic",model:"claude-opus-4",effectiveDate:"2026-03-01",inputPer1m:15,outputPer1m:75},{id:"openai-gpt-4o-2026-03-01",provider:"openai",model:"gpt-4o",effectiveDate:"2026-03-01",inputPer1m:2.5,outputPer1m:10},{id:"openai-gpt-4.1-mini-2026-03-01",provider:"openai",model:"gpt-4.1-mini",effectiveDate:"2026-03-01",inputPer1m:.4,outputPer1m:1.6},{id:"google-gemini-2.0-flash-2026-03-01",provider:"google",model:"gemini-2.0-flash",effectiveDate:"2026-03-01",inputPer1m:.35,outputPer1m:1.4},{id:"meta-llama-3.3-70b-2026-03-01",provider:"meta",model:"llama-3.3-70b-instruct",effectiveDate:"2026-03-01",inputPer1m:.9,outputPer1m:.9}];function te(t,e){let o=t.trim().toLowerCase(),n=e.trim().toLowerCase();return z.find(s=>s.provider.toLowerCase()===o&&s.model.toLowerCase()===n)}function ft(t,e,o,n){let s=te(t,e);if(!s)return null;let a=Math.max(o,0)/1e6*s.inputPer1m,i=Math.max(n,0)/1e6*s.outputPer1m;return Number((a+i).toFixed(8))}function g(t,e){if(!t||typeof t!="object")return null;let o=t;for(let n of e){let s=o;for(let a of n){if(!s||typeof s!="object"||!(a in s)){s=void 0;break}s=s[a]}if(s!==void 0)return s}return null}function k(t){if(typeof t=="number"&&Number.isFinite(t))return t;if(typeof t=="string"&&t.trim()!==""){let e=Number(t);return Number.isFinite(e)?e:null}return null}function N(t){return typeof t=="string"&&t.trim()!==""?t.trim():null}function gt(t){return typeof t=="boolean"?t:typeof t=="string"?["true","1","yes"].includes(t.trim().toLowerCase()):typeof t=="number"?t>0:!1}function wt(t,e){let o={};for(let n of e){let s=t[n];(typeof s=="string"||typeof s=="number"||typeof s=="boolean")&&(o[n]=s)}return o}function ne(t){let o=ee(t,"utf8").split(/\r?\n/).map(s=>s.trim()).filter(Boolean),n=[];for(let s of o)try{let a=JSON.parse(s);n.push(a)}catch{}return n}function se(t){return N(g(t,[["provider"],["message","provider"],["usage","provider"]]))??"unknown"}function re(t){return N(g(t,[["model"],["message","model"],["usage","model"]]))??"unknown-model"}function ht(t,e){return N(g(t,[["workflow"],["session","workflow"],["metadata","workflow"],["agent","name"],["agentId"],["sessionId"]]))??oe(e,".jsonl")}function ie(t){return N(g(t,[["environment"],["env"],["metadata","environment"]]))??"local"}function ae(t,e,o,n){return N(g(t,[["run_id"],["runId"],["trace_id"],["traceId"],["sessionId"],["thread_id"]]))??`${n}:${e}:${o}`}function de(t,e){return N(g(t,[["task_class"],["taskClass"],["metadata","taskClass"]]))??e.toLowerCase()}function F(t){let e=k(g(t,[["input_tokens"],["inputTokens"],["usage","input_tokens"],["usage","inputTokens"],["message","usage","input_tokens"],["message","usage","inputTokens"],["usage","prompt_tokens"],["message","usage","prompt_tokens"]]))??0,o=k(g(t,[["output_tokens"],["outputTokens"],["usage","output_tokens"],["usage","outputTokens"],["message","usage","output_tokens"],["message","usage","outputTokens"],["usage","completion_tokens"],["message","usage","completion_tokens"]]))??0,n=k(g(t,[["cost_usd"],["costUsd"],["usage","cost_usd"],["usage","costUsd"],["usage","cost","total"],["message","usage","cost","total"],["message","usage","cost_usd"],["pricing","total_usd"]]))??null;return{inputTokens:e,outputTokens:o,observedCost:n}}function ce(t,e,o,n){let s=se(e),a=re(e),i=ht(e,t.path),{inputTokens:c,outputTokens:l,observedCost:d}=F(e),r=ft(s,a,c,l),u=D(g(e,[["timestamp"],["createdAt"],["created_at"]])),m=k(g(e,[["attempt"],["usage","attempt"],["metadata","attempt"]]))??null,w=k(g(e,[["iteration"],["loop_iteration"],["metadata","iteration"]]))??null,S=k(g(e,[["retries"],["retry_count"],["metadata","retries"]]))??0,C=d??r??0;return{id:y(`${o}:${t.path}:${n}:${a}:${u}:${C}`),runId:o,timestamp:u,provider:s,model:a,inputTokens:c,outputTokens:l,costUsd:C,costSource:d!==null?"observed":"estimated",latencyMs:k(g(e,[["latency_ms"],["latencyMs"],["usage","latency_ms"]]))??null,toolCalls:k(g(e,[["tool_calls"],["toolCalls"],["usage","tool_calls"]]))??0,retries:S,attempt:m,iteration:w,status:N(g(e,[["status"],["level"],["result"],["error","type"]]))??null,taskClass:de(e,i),cacheHit:gt(g(e,[["cache_hit"],["cacheHit"],["usage","cache_hit"]])),cacheCostUsd:k(g(e,[["cache_cost_usd"],["cacheCostUsd"],["usage","cache_cost_usd"]]))??null,metadata:wt(e,["event","type","sessionId","agentId"])}}function le(t){return F(t).inputTokens>0||F(t).outputTokens>0||F(t).observedCost!==null}function yt(t,e){let o=Y(e),n=new Map;for(let s of t)ne(s.path).forEach((i,c)=>{if(!le(i))return;let l=ht(i,s.path),d=D(g(i,[["timestamp"],["createdAt"],["created_at"]]));if(o&&new Date(d).getTime()<o)return;let r=ae(i,l,c,s.path),u=y(`${s.path}:${r}`),m=ce(s,i,u,c),w=n.get(u);if(!w){n.set(u,{id:u,sourceKind:s.kind,sourcePath:s.path,timestamp:d,workflow:l,environment:ie(i),tags:{sourceKind:s.kind},calls:[m],totalCostUsd:m.costUsd,totalTokens:m.inputTokens+m.outputTokens,observedCostUsd:m.costSource==="observed"?m.costUsd:0,estimatedCostUsd:m.costSource==="estimated"?m.costUsd:0});return}w.calls.push(m),w.totalCostUsd=Number((w.totalCostUsd+m.costUsd).toFixed(8)),w.totalTokens+=m.inputTokens+m.outputTokens,w.observedCostUsd+=m.costSource==="observed"?m.costUsd:0,w.estimatedCostUsd+=m.costSource==="estimated"?m.costUsd:0});return Array.from(n.values()).sort((s,a)=>new Date(s.timestamp).getTime()-new Date(a.timestamp).getTime())}function Ut(t){let e=new Map;for(let o of t){let n=e.get(o.key)??{spendUsd:0,observedSpendUsd:0,callCount:0};n.spendUsd+=o.spendUsd,n.observedSpendUsd+=o.observedSpendUsd,n.callCount+=1,e.set(o.key,n)}return Array.from(e.entries()).map(([o,n])=>{let s=n.spendUsd===0?0:n.observedSpendUsd/n.spendUsd;return{key:o,spendUsd:Number(n.spendUsd.toFixed(6)),callCount:n.callCount,observedShare:Number(s.toFixed(4))}}).sort((o,n)=>n.spendUsd-o.spendUsd)}function St(t){let e=t.runs.reduce((l,d)=>l+d.calls.length,0),o=t.runs.reduce((l,d)=>l+d.totalCostUsd,0),n=t.runs.reduce((l,d)=>l+d.observedCostUsd,0),s=t.runs.reduce((l,d)=>l+d.estimatedCostUsd,0),a=t.findings.filter(l=>l.classification==="waste").reduce((l,d)=>l+d.costImpactUsd,0),i=t.findings.filter(l=>l.classification==="opportunity").reduce((l,d)=>l+d.costImpactUsd,0),c=R();return{auditId:y(`${c}:${t.runs.length}:${t.sources.map(l=>l.path).join("|")}`),generatedAt:c,comparisonKey:B({sources:t.sources,since:t.since}),comparison:null,since:t.since,runCount:t.runs.length,callCount:e,totalSpendUsd:Number(o.toFixed(6)),observedSpendUsd:Number(n.toFixed(6)),estimatedSpendUsd:Number(s.toFixed(6)),wasteSpendUsd:Number(a.toFixed(6)),opportunitySpendUsd:Number(i.toFixed(6)),structuralWasteRate:Number((o===0?0:a/o).toFixed(4)),wasteByKind:E(t.findings,"waste"),opportunityByKind:E(t.findings,"opportunity"),spendByWorkflow:Ut(t.runs.map(l=>({key:l.workflow,spendUsd:l.totalCostUsd,observedSpendUsd:l.observedCostUsd}))),spendByModel:Ut(t.runs.flatMap(l=>l.calls.map(d=>({key:`${d.provider}/${d.model}`,spendUsd:d.costUsd,observedSpendUsd:d.costSource==="observed"?d.costUsd:0})))),findings:t.findings,notes:["Cost per outcome is intentionally unavailable in v0. Xerg is measuring waste intelligence only.","Opportunity findings are directional recommendations, not proven waste."],sourceFiles:t.sources,dbPath:t.dbPath}}async function kt(t){return pt(t)}async function Tt(t){if(t.compare&&t.noDb)throw new Error("The --compare flag needs local snapshot history. Remove --no-db or provide --db <path>.");let e=await j(t);if(e.length===0)throw new Error("No OpenClaw sources were detected. Run `xerg doctor` or provide --log-file / --sessions-dir.");let o=yt(e,t.since),n=mt(o),s=t.noDb?void 0:t.dbPath??ut(),a=St({runs:o,findings:n,sources:e,since:t.since,dbPath:s});if(t.compare&&s){let i=ct({dbPath:s,comparisonKey:a.comparisonKey,currentAuditId:a.auditId});i?a.comparison=dt(a,i):a.notes=[...a.notes,"No prior comparable audit was found. Run the same audit again after a fix to unlock before/after deltas."]}return s&&ot({summary:a,runs:o,pricingCatalog:z},s),a}function f(t){return new Intl.NumberFormat("en-US",{style:"currency",currency:"USD",minimumFractionDigits:t>=1?2:4,maximumFractionDigits:4}).format(t)}function $(t){return`${(t*100).toFixed(0)}%`}function bt(t){let e=t*100;return`${e>0?"+":""}${e.toFixed(0)} pts`}function L(t){return`${t>0?"+":""}${f(t)}`}function H(t,e=5){return t.slice(0,e).map(o=>`- ${o.key}: ${f(o.spendUsd)} (${$(o.observedShare)} observed)`)}function Ct(t,e,o){return t.length===0?[`- ${e}`]:t.map(n=>{let s=`${n.findingCount} finding${n.findingCount===1?"":"s"}`,a=o?` ${o}`:"";return`- ${n.label}: ${f(n.spendUsd)} across ${s}${a}`})}function $t(t){return["## Waste taxonomy","Structural waste",...Ct(t.wasteByKind,"No confirmed waste buckets detected."),"Savings opportunities",...Ct(t.opportunityByKind,"No opportunity buckets detected.","(directional)")]}function ue(t,e){return t.findings.filter(o=>o.classification===e).sort((o,n)=>n.costImpactUsd-o.costImpactUsd)[0]}function pe(t){return t.findings.filter(e=>e.classification==="opportunity").sort((e,o)=>{let n=e.kind==="candidate-downgrade"?1:0,s=o.kind==="candidate-downgrade"?1:0;return n!==s?s-n:o.costImpactUsd-e.costImpactUsd})[0]??null}function Nt(t,e){return t.length===0?[`- ${e}`]:t.slice(0,5).map(o=>`- ${o.title}: ${f(o.costImpactUsd)} (${o.confidence})`)}function J(t){return`${t.key} (${L(t.deltaSpendUsd)})`}function me(t){return t.filter(e=>e.deltaSpendUsd<0).sort((e,o)=>e.deltaSpendUsd-o.deltaSpendUsd)[0]}function fe(t){return t.filter(e=>e.deltaSpendUsd>0).sort((e,o)=>o.deltaSpendUsd-e.deltaSpendUsd)[0]}function G(t,e){return e==="resolved"?`- Resolved: ${t.title} (${f(t.baselineCostImpactUsd??0)})`:e==="worsened"?`- Worsened: ${t.title} (${L(t.deltaCostImpactUsd)})`:`- New: ${t.title} (${f(t.currentCostImpactUsd??0)})`}function ge(t){if(!t.comparison)return[];let e=t.comparison,o=me(e.workflowDeltas),n=fe(e.workflowDeltas),s=n?.key??t.spendByWorkflow[0]?.key??null,a=[...e.findingChanges.newHighConfidenceWaste.map(i=>G(i,"new")),...e.findingChanges.resolvedHighConfidenceWaste.map(i=>G(i,"resolved")),...e.findingChanges.worsenedHighConfidenceWaste.map(i=>G(i,"worsened"))].slice(0,5);return["## Before / after",`Compared against ${e.baselineGeneratedAt}`,`- Total spend: ${f(e.baselineTotalSpendUsd)} -> ${f(t.totalSpendUsd)} (${L(e.deltaTotalSpendUsd)})`,`- Structural waste: ${f(e.baselineWasteSpendUsd)} -> ${f(t.wasteSpendUsd)} (${L(e.deltaWasteSpendUsd)})`,`- Waste rate: ${$(e.baselineStructuralWasteRate)} -> ${$(t.structuralWasteRate)} (${bt(e.deltaStructuralWasteRate)})`,`- Runs analyzed: ${e.baselineRunCount} -> ${t.runCount} (${e.deltaRunCount>0?"+":""}${e.deltaRunCount})`,`- Model calls: ${e.baselineCallCount} -> ${t.callCount} (${e.deltaCallCount>0?"+":""}${e.deltaCallCount})`,o?`- Biggest improvement: ${J(o)}`:"- Biggest improvement: none detected",n?`- Biggest regression: ${J(n)}`:"- Biggest regression: none detected",s?`- First workflow to inspect now: ${s}`:"- First workflow to inspect now: no workflow delta available",...e.modelDeltas.length>0?[`- Model swing to inspect: ${J(e.modelDeltas[0])}`]:["- Model swing to inspect: none"],...a.length>0?a:["- High-confidence waste changes: none"]]}function It(t){return["# Xerg doctor","",t.canAudit?"OpenClaw sources detected.":"No OpenClaw sources detected.","","## Defaults",`- gateway logs: ${t.defaults.gatewayPattern}`,`- session files: ${t.defaults.sessionsPattern}`,"","## Sources",...t.sources.length>0?t.sources.map(o=>`- [${o.kind}] ${o.path}`):["- none"],"","## Notes",...t.notes.map(o=>`- ${o}`)].join(`
79
- `)}function _t(t){let e=t.findings.filter(a=>a.classification==="waste"),o=t.findings.filter(a=>a.classification==="opportunity"),n=pe(t),s=ue(t,"waste");return["# Xerg audit","",`Total spend: ${f(t.totalSpendUsd)}`,`Observed spend: ${f(t.observedSpendUsd)}`,`Estimated spend: ${f(t.estimatedSpendUsd)}`,`Runs analyzed: ${t.runCount}`,`Model calls: ${t.callCount}`,`Structural waste identified: ${f(t.wasteSpendUsd)} (${$(t.structuralWasteRate)})`,`Potential impact surfaced: ${f(t.opportunitySpendUsd)}`,"",...$t(t),"","## Top workflows",...H(t.spendByWorkflow),"","## Top models",...H(t.spendByModel),"","## High-confidence waste",...Nt(e,"none detected"),"","## Opportunities",...Nt(o,"none detected"),"","## First savings test",...n?[`- Start with ${n.title}: ${f(n.costImpactUsd)} of potential impact`,`- Why this test first: ${n.summary}`]:["- No savings test surfaced yet"],...s?[`- Confirmed leak to close first: ${s.title}`]:["- Confirmed leak to close first: none"],...t.spendByWorkflow[0]?[`- Workflow to inspect first: ${t.spendByWorkflow[0].key}`]:["- Workflow to inspect first: none"],"",...ge(t),...t.comparison?[""]:[],"## Notes",...t.notes.map(a=>`- ${a}`)].join(`
80
- `)}function Lt(t){let e=["# Xerg Audit Report","",`- Generated: ${t.generatedAt}`,`- Total spend: ${f(t.totalSpendUsd)}`,`- Observed spend: ${f(t.observedSpendUsd)}`,`- Estimated spend: ${f(t.estimatedSpendUsd)}`,`- Structural waste identified: ${f(t.wasteSpendUsd)} (${$(t.structuralWasteRate)})`,`- Potential impact surfaced: ${f(t.opportunitySpendUsd)}`,`- Runs analyzed: ${t.runCount}`,`- Model calls: ${t.callCount}`,"",...$t(t),"","## Top workflows",...H(t.spendByWorkflow),"","## Findings",...t.findings.slice(0,10).map(o=>`- **${o.title}** (${o.classification}, ${o.confidence}) \u2014 ${o.summary} Estimated impact: ${f(o.costImpactUsd)}.`)];if(t.comparison){let o=t.comparison;e.push("","## Before / after",`- Compared against: ${o.baselineGeneratedAt}`,`- Total spend: ${f(o.baselineTotalSpendUsd)} -> ${f(t.totalSpendUsd)} (${L(o.deltaTotalSpendUsd)})`,`- Structural waste: ${f(o.baselineWasteSpendUsd)} -> ${f(t.wasteSpendUsd)} (${L(o.deltaWasteSpendUsd)})`,`- Waste rate: ${$(o.baselineStructuralWasteRate)} -> ${$(t.structuralWasteRate)} (${bt(o.deltaStructuralWasteRate)})`)}return e.join(`
81
- `)}async function Rt(t){let e=await Tt({logFile:t.logFile,sessionsDir:t.sessionsDir,since:t.since,compare:t.compare,dbPath:t.db,noDb:t.noDb});if(t.json){process.stdout.write(`${JSON.stringify(e,null,2)}
82
- `);return}if(t.markdown){process.stdout.write(`${Lt(e)}
83
- `);return}process.stdout.write(`${_t(e)}
84
- `)}async function Et(t){let e=await kt({logFile:t.logFile,sessionsDir:t.sessionsDir});process.stdout.write(`${It(e)}
85
- `)}var A=new we;A.name("xerg").description("Waste intelligence for OpenClaw workflows.").version("0.1.0");A.command("audit").description("Analyze OpenClaw logs and produce a waste intelligence report.").option("--log-file <path>","explicit OpenClaw gateway log file to analyze").option("--sessions-dir <path>","explicit OpenClaw sessions directory to analyze").option("--since <duration>","look back window such as 24h, 7d, or 30m").option("--compare","compare this audit to the newest compatible prior local snapshot").option("--json","render the report as JSON").option("--markdown","render the report as Markdown").option("--db <path>","custom SQLite database path").option("--no-db","skip local persistence").action(async t=>{if(t.json&&t.markdown)throw new Error("Use either --json or --markdown, not both.");await Rt(t)});A.command("doctor").description("Inspect your machine for OpenClaw sources and audit readiness.").option("--log-file <path>","explicit OpenClaw gateway log file to inspect").option("--sessions-dir <path>","explicit OpenClaw sessions directory to inspect").action(async t=>{await Et(t)});A.configureOutput({outputError:(t,e)=>{e(`${vt.red(t)}
86
- `)}});A.parseAsync(process.argv).catch(t=>{let e=t instanceof Error?t.message:"Unknown error";process.stderr.write(`${vt.red(`xerg failed: ${e}`)}
87
- `),process.exitCode=1});
78
+ `;function _(e){$e(Le(e),{recursive:!0});let t=new _e(e);return t.exec(Y),{sqlite:t}}function V(e,t){let{sqlite:n}=_(t),o=R(),r=e.pricingCatalog.map(s=>({...s,cachedInputPer1m:s.cachedInputPer1m??null})),a=e.summary.sourceFiles.map(s=>({id:U(`${s.path}:${s.mtimeMs}:${s.sizeBytes}`),path:s.path,kind:s.kind,fileHash:U(Ae(s.path,"utf8")),mtimeMs:Math.trunc(s.mtimeMs),sizeBytes:s.sizeBytes,importedAt:o})),i=e.runs.map(s=>({id:s.id,sourcePath:s.sourcePath,sourceKind:s.sourceKind,timestamp:s.timestamp,workflow:s.workflow,environment:s.environment,tagsJson:JSON.stringify(s.tags),totalCostUsd:s.totalCostUsd,totalTokens:s.totalTokens,observedCostUsd:s.observedCostUsd,estimatedCostUsd:s.estimatedCostUsd})),c=e.runs.flatMap(s=>s.calls.map(p=>({id:p.id,runId:p.runId,timestamp:p.timestamp,provider:p.provider,model:p.model,inputTokens:p.inputTokens,outputTokens:p.outputTokens,costUsd:p.costUsd,costSource:p.costSource,latencyMs:p.latencyMs,toolCalls:p.toolCalls,retries:p.retries,attempt:p.attempt,iteration:p.iteration,status:p.status,taskClass:p.taskClass,cacheHit:p.cacheHit,cacheCostUsd:p.cacheCostUsd,metadataJson:JSON.stringify(p.metadata)}))),u=e.summary.findings.map(s=>({id:s.id,auditId:e.summary.auditId,classification:s.classification,confidence:s.confidence,kind:s.kind,title:s.title,summary:s.summary,scope:s.scope,scopeId:s.scopeId,costImpactUsd:s.costImpactUsd,detailsJson:JSON.stringify(s.details)})),d=n.transaction(()=>{O(n,`
79
+ INSERT OR IGNORE INTO pricing_catalog (
80
+ id,
81
+ provider,
82
+ model,
83
+ effective_date,
84
+ input_per_1m,
85
+ output_per_1m,
86
+ cached_input_per_1m
87
+ ) VALUES (?, ?, ?, ?, ?, ?, ?)
88
+ `,r.map(s=>[s.id,s.provider,s.model,s.effectiveDate,s.inputPer1m,s.outputPer1m,s.cachedInputPer1m])),O(n,`
89
+ INSERT OR IGNORE INTO source_files (
90
+ id,
91
+ path,
92
+ kind,
93
+ file_hash,
94
+ mtime_ms,
95
+ size_bytes,
96
+ imported_at
97
+ ) VALUES (?, ?, ?, ?, ?, ?, ?)
98
+ `,a.map(s=>[s.id,s.path,s.kind,s.fileHash,s.mtimeMs,s.sizeBytes,s.importedAt])),O(n,`
99
+ INSERT OR IGNORE INTO runs (
100
+ id,
101
+ source_path,
102
+ source_kind,
103
+ timestamp,
104
+ workflow,
105
+ environment,
106
+ tags_json,
107
+ total_cost_usd,
108
+ total_tokens,
109
+ observed_cost_usd,
110
+ estimated_cost_usd
111
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
112
+ `,i.map(s=>[s.id,s.sourcePath,s.sourceKind,s.timestamp,s.workflow,s.environment,s.tagsJson,s.totalCostUsd,s.totalTokens,s.observedCostUsd,s.estimatedCostUsd])),O(n,`
113
+ INSERT OR IGNORE INTO calls (
114
+ id,
115
+ run_id,
116
+ timestamp,
117
+ provider,
118
+ model,
119
+ input_tokens,
120
+ output_tokens,
121
+ cost_usd,
122
+ cost_source,
123
+ latency_ms,
124
+ tool_calls,
125
+ retries,
126
+ attempt,
127
+ iteration,
128
+ status,
129
+ task_class,
130
+ cache_hit,
131
+ cache_cost_usd,
132
+ metadata_json
133
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
134
+ `,c.map(s=>[s.id,s.runId,s.timestamp,s.provider,s.model,s.inputTokens,s.outputTokens,s.costUsd,s.costSource,s.latencyMs??null,s.toolCalls,s.retries,s.attempt??null,s.iteration??null,s.status??null,s.taskClass??null,s.cacheHit?1:0,s.cacheCostUsd??null,s.metadataJson])),O(n,`
135
+ INSERT OR IGNORE INTO findings (
136
+ id,
137
+ audit_id,
138
+ classification,
139
+ confidence,
140
+ kind,
141
+ title,
142
+ summary,
143
+ scope,
144
+ scope_id,
145
+ cost_impact_usd,
146
+ details_json
147
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
148
+ `,u.map(s=>[s.id,s.auditId,s.classification,s.confidence,s.kind,s.title,s.summary,s.scope,s.scopeId,s.costImpactUsd,s.detailsJson])),n.prepare(`
149
+ INSERT OR IGNORE INTO audit_snapshots (
150
+ id,
151
+ created_at,
152
+ summary_json
153
+ ) VALUES (?, ?, ?)
154
+ `).run(e.summary.auditId,e.summary.generatedAt,JSON.stringify(e.summary))});try{d()}finally{n.close()}}function O(e,t,n){if(n.length===0)return;let o=e.prepare(t);for(let r of n)o.run(...r)}var xe={"retry-waste":"Retry waste","context-outlier":"Context bloat","loop-waste":"Loop waste","candidate-downgrade":"Downgrade candidates","idle-spend":"Idle waste"};function w(e){return Number(e.toFixed(6))}function ve(e){if(!e)return"all";let t=e.trim().toLowerCase().match(/^(\d+)([mhdw])$/);return t?`${Number(t[1])}${t[2]}`:e.trim().toLowerCase()}function ee(e){return e.replace(/\\/g,"/")}function De(e){let t=ee(e),n="/sessions/",o=t.lastIndexOf(n);return o>=0?t.slice(0,o+n.length-1):t.slice(0,t.lastIndexOf("/"))||t}function Fe(e){let t=ee(e);return t.slice(0,t.lastIndexOf("/"))||t}function Pe(e){return xe[e]??e}function Me(e){return e.kind==="sessions"?De(e.path):Fe(e.path)}function F(e){let t=Array.from(new Set(e.sources.map(o=>o.kind))).sort(),n=Array.from(new Set(e.sources.map(o=>`${o.kind}:${Me(o)}`))).sort();return U(JSON.stringify({kinds:t,roots:n,since:ve(e.since)}))}function $(e,t){let n=new Map;for(let o of e){if(o.classification!==t)continue;let r=n.get(o.kind)??{kind:o.kind,label:Pe(o.kind),classification:t,spendUsd:0,findingCount:0};r.spendUsd=w(r.spendUsd+o.costImpactUsd),r.findingCount+=1,n.set(o.kind,r)}return Array.from(n.values()).sort((o,r)=>r.spendUsd-o.spendUsd)}function q(e){return new Map(e.map(t=>[t.key,t.spendUsd]))}function Q(e,t){let n=q(e),o=q(t);return Array.from(new Set([...n.keys(),...o.keys()])).map(a=>{let i=o.get(a)??0,c=n.get(a)??0;return{key:a,baselineSpendUsd:w(i),currentSpendUsd:w(c),deltaSpendUsd:w(c-i)}}).filter(a=>a.deltaSpendUsd!==0).sort((a,i)=>Math.abs(i.deltaSpendUsd)-Math.abs(a.deltaSpendUsd)).slice(0,3)}function Z(e){return`${e.kind}:${e.scope}:${e.scopeId}`}function D(e){return e.sort((t,n)=>Math.abs(n.deltaCostImpactUsd)-Math.abs(t.deltaCostImpactUsd))}function Be(e,t){let n=e.filter(d=>d.classification==="waste"&&d.confidence==="high"),o=t.filter(d=>d.classification==="waste"&&d.confidence==="high"),r=new Map(n.map(d=>[Z(d),d])),a=new Map(o.map(d=>[Z(d),d])),i=[],c=[],u=[];for(let[d,s]of r.entries()){let p=a.get(d);if(!p){i.push({kind:s.kind,title:s.title,scope:s.scope,scopeId:s.scopeId,currentCostImpactUsd:s.costImpactUsd,deltaCostImpactUsd:w(s.costImpactUsd)});continue}let l=w(s.costImpactUsd-p.costImpactUsd);l>0&&u.push({kind:s.kind,title:s.title,scope:s.scope,scopeId:s.scopeId,baselineCostImpactUsd:p.costImpactUsd,currentCostImpactUsd:s.costImpactUsd,deltaCostImpactUsd:l})}for(let[d,s]of a.entries())r.has(d)||c.push({kind:s.kind,title:s.title,scope:s.scope,scopeId:s.scopeId,baselineCostImpactUsd:s.costImpactUsd,deltaCostImpactUsd:w(-s.costImpactUsd)});return{newHighConfidenceWaste:D(i),resolvedHighConfidenceWaste:D(c),worsenedHighConfidenceWaste:D(u)}}function te(e){return{...e,comparisonKey:e.comparisonKey??F({sources:e.sourceFiles,since:e.since}),comparison:e.comparison??null,wasteByKind:e.wasteByKind?.length>0?e.wasteByKind:$(e.findings,"waste"),opportunityByKind:e.opportunityByKind?.length>0?e.opportunityByKind:$(e.findings,"opportunity"),notes:e.notes??[]}}function ne(e,t){let n=Q(e.spendByWorkflow,t.spendByWorkflow),o=Q(e.spendByModel,t.spendByModel);return{baselineAuditId:t.auditId,baselineGeneratedAt:t.generatedAt,baselineRunCount:t.runCount,baselineCallCount:t.callCount,baselineTotalSpendUsd:t.totalSpendUsd,baselineObservedSpendUsd:t.observedSpendUsd,baselineEstimatedSpendUsd:t.estimatedSpendUsd,baselineWasteSpendUsd:t.wasteSpendUsd,baselineOpportunitySpendUsd:t.opportunitySpendUsd,baselineStructuralWasteRate:t.structuralWasteRate,deltaTotalSpendUsd:w(e.totalSpendUsd-t.totalSpendUsd),deltaObservedSpendUsd:w(e.observedSpendUsd-t.observedSpendUsd),deltaEstimatedSpendUsd:w(e.estimatedSpendUsd-t.estimatedSpendUsd),deltaWasteSpendUsd:w(e.wasteSpendUsd-t.wasteSpendUsd),deltaOpportunitySpendUsd:w(e.opportunitySpendUsd-t.opportunitySpendUsd),deltaStructuralWasteRate:w(e.structuralWasteRate-t.structuralWasteRate),deltaRunCount:e.runCount-t.runCount,deltaCallCount:e.callCount-t.callCount,workflowDeltas:n,modelDeltas:o,findingChanges:Be(e.findings,t.findings)}}function We(e){try{return te(JSON.parse(e))}catch{return null}}function Xe(e){let{sqlite:t}=_(e);try{return t.prepare(`
155
+ SELECT summary_json AS summaryJson
156
+ FROM audit_snapshots
157
+ ORDER BY created_at DESC
158
+ `).all().map(o=>We(o.summaryJson)).filter(o=>o!==null)}finally{t.close()}}function se(e){return Xe(e.dbPath).find(t=>e.currentAuditId&&t.auditId===e.currentAuditId?!1:t.comparisonKey===e.comparisonKey)}import{statSync as Ge}from"fs";import{glob as Je}from"fs/promises";import{resolve as Ke}from"path";import{mkdirSync as P}from"fs";import{homedir as re}from"os";import{join as h}from"path";import{platform as oe}from"process";function je(){let e=re(),t=oe==="darwin"?{data:h(e,"Library","Application Support","xerg"),config:h(e,"Library","Preferences","xerg"),cache:h(e,"Library","Caches","xerg")}:oe==="win32"?{data:h(process.env.LOCALAPPDATA??h(e,"AppData","Local"),"xerg","Data"),config:h(process.env.APPDATA??h(e,"AppData","Roaming"),"xerg","Config"),cache:h(process.env.LOCALAPPDATA??h(e,"AppData","Local"),"xerg","Cache")}:{data:h(process.env.XDG_DATA_HOME??h(e,".local","share"),"xerg"),config:h(process.env.XDG_CONFIG_HOME??h(e,".config"),"xerg"),cache:h(process.env.XDG_CACHE_HOME??h(e,".cache"),"xerg")};return P(t.data,{recursive:!0}),P(t.config,{recursive:!0}),P(t.cache,{recursive:!0}),t}function ie(){return h(je().data,"xerg.db")}function M(){return h(re(),".openclaw","agents","*","sessions","*.jsonl")}function B(){return"/tmp/openclaw/openclaw-*.log"}function A(e,t){try{let n=Ge(e);return n.isFile()?{kind:t,path:e,sizeBytes:n.size,mtimeMs:n.mtimeMs}:null}catch{return null}}async function X(e){let t=[];if(e.logFile){let a=A(e.logFile,"gateway");a&&t.push(a)}if(e.sessionsDir){let a=await W("**/*.jsonl",{cwd:e.sessionsDir,resolveWith:e.sessionsDir});for(let i of a){let c=A(i,"sessions");c&&t.push(c)}}if(t.length>0)return t.sort((a,i)=>i.mtimeMs-a.mtimeMs);let[n,o]=await Promise.all([W(B()),W(M())]);return[...n.map(a=>A(a,"gateway")).filter(Boolean),...o.map(a=>A(a,"sessions")).filter(Boolean)].sort((a,i)=>i.mtimeMs-a.mtimeMs)}async function W(e,t){let n=[];for await(let o of Je(e,{cwd:t?.cwd}))n.push(t?.resolveWith?Ke(t.resolveWith,o):o);return n}async function ae(e){let t=await X(e),n=[];return t.length===0&&(n.push("No OpenClaw gateway logs or session files were detected."),n.push("Use --log-file or --sessions-dir if your OpenClaw data lives outside the defaults.")),t.some(o=>o.kind==="gateway")&&n.push("Gateway logs detected. These are preferred when cost metadata is present."),t.some(o=>o.kind==="sessions")&&n.push("Session transcript fallback detected. Xerg will extract usage metadata only."),{canAudit:t.length>0,sources:t,defaults:{gatewayPattern:B(),sessionsPattern:M()},notes:n}}function L(e){return{...e,id:U(`${e.kind}:${e.scope}:${e.scopeId}:${e.title}:${e.costImpactUsd}:${e.summary}`)}}function b(e){return Number(e.toFixed(6))}function de(e){let t=[],o=e.flatMap(i=>i.calls.map(c=>({run:i,call:c}))).filter(({call:i})=>{let c=(i.status??"").toLowerCase();return c.includes("error")||c.includes("fail")}),r=o.reduce((i,c)=>i+c.call.costUsd,0);r>0&&t.push(L({classification:"waste",confidence:"high",kind:"retry-waste",title:"Retry waste is consuming measurable spend",summary:`${o.length} failed call${o.length===1?"":"s"} were followed by additional work, making their spend pure retry overhead.`,scope:"global",scopeId:"all",costImpactUsd:b(r),details:{failedCallCount:o.length}}));for(let i of e){let c=Math.max(...i.calls.map(u=>u.iteration??0));if(c>=7){let d=i.calls.filter(s=>(s.iteration??0)>5).reduce((s,p)=>s+p.costUsd,0);t.push(L({classification:"waste",confidence:"high",kind:"loop-waste",title:`Workflow "${i.workflow}" ran beyond efficient loop bounds`,summary:`This run reached ${c} iterations. Xerg treats the spend after iteration 5 as likely loop waste.`,scope:"run",scopeId:i.id,costImpactUsd:b(d),details:{workflow:i.workflow,maxIteration:c}}))}}let a=new Map;for(let i of e){let c=a.get(i.workflow)??[];c.push(i),a.set(i.workflow,c)}for(let[i,c]of a.entries()){if(c.length>=3){let s=c.map(g=>g.calls.reduce((k,y)=>k+y.inputTokens,0)),p=s.reduce((g,k)=>g+k,0)/s.length,l=c.filter(g=>{let k=g.calls.reduce((y,Re)=>y+Re.inputTokens,0);return k>p*1.75&&k>1500});if(l.length>0){let g=l.reduce((k,y)=>k+y.totalCostUsd,0);t.push(L({classification:"opportunity",confidence:"medium",kind:"context-outlier",title:`Context usage in "${i}" is well above its baseline`,summary:`Xerg found ${l.length} run${l.length===1?"":"s"} in this workflow with input token volume far above the workflow average.`,scope:"workflow",scopeId:i,costImpactUsd:b(g),details:{workflow:i,averageInputTokens:b(p),outlierRunCount:l.length}}))}}let u=c.filter(s=>/(heartbeat|cron|monitor|poll)/i.test(s.workflow));if(u.length>0){let s=u.reduce((p,l)=>p+l.totalCostUsd,0);t.push(L({classification:"opportunity",confidence:"medium",kind:"idle-spend",title:`Idle or monitoring spend detected in "${i}"`,summary:"This workflow name looks like a recurring heartbeat or monitoring loop. Review whether the cadence and model tier are justified.",scope:"workflow",scopeId:i,costImpactUsd:b(s),details:{workflow:i}}))}let d=c.flatMap(s=>s.calls).filter(s=>/(opus|gpt-4o|sonnet)/i.test(s.model)&&/(heartbeat|cron|monitor|summary|tag|triage)/i.test(s.taskClass??i));if(d.length>0){let s=d.reduce((p,l)=>p+l.costUsd,0);t.push(L({classification:"opportunity",confidence:"low",kind:"candidate-downgrade",title:`Candidate model downgrade opportunity in "${i}"`,summary:"An expensive model is being used on a workflow that looks operationally simple. Treat this as an A/B test candidate, not proven waste.",scope:"workflow",scopeId:i,costImpactUsd:b(s*.3),details:{workflow:i,expensiveCallCount:d.length,inspectedSpendUsd:b(s)}}))}}return t.sort((i,c)=>c.costImpactUsd-i.costImpactUsd)}import{readFileSync as He}from"fs";import{basename as Ye}from"path";var j=[{id:"anthropic-claude-haiku-4-5-2026-03-01",provider:"anthropic",model:"claude-haiku-4-5",effectiveDate:"2026-03-01",inputPer1m:.8,outputPer1m:4},{id:"anthropic-claude-sonnet-4-5-2026-03-01",provider:"anthropic",model:"claude-sonnet-4-5",effectiveDate:"2026-03-01",inputPer1m:3,outputPer1m:15},{id:"anthropic-claude-opus-4-2026-03-01",provider:"anthropic",model:"claude-opus-4",effectiveDate:"2026-03-01",inputPer1m:15,outputPer1m:75},{id:"openai-gpt-4o-2026-03-01",provider:"openai",model:"gpt-4o",effectiveDate:"2026-03-01",inputPer1m:2.5,outputPer1m:10},{id:"openai-gpt-4.1-mini-2026-03-01",provider:"openai",model:"gpt-4.1-mini",effectiveDate:"2026-03-01",inputPer1m:.4,outputPer1m:1.6},{id:"google-gemini-2.0-flash-2026-03-01",provider:"google",model:"gemini-2.0-flash",effectiveDate:"2026-03-01",inputPer1m:.35,outputPer1m:1.4},{id:"meta-llama-3.3-70b-2026-03-01",provider:"meta",model:"llama-3.3-70b-instruct",effectiveDate:"2026-03-01",inputPer1m:.9,outputPer1m:.9}];function ze(e,t){let n=e.trim().toLowerCase(),o=t.trim().toLowerCase();return j.find(r=>r.provider.toLowerCase()===n&&r.model.toLowerCase()===o)}function ce(e,t,n,o){let r=ze(e,t);if(!r)return null;let a=Math.max(n,0)/1e6*r.inputPer1m,i=Math.max(o,0)/1e6*r.outputPer1m;return Number((a+i).toFixed(8))}function f(e,t){if(!e||typeof e!="object")return null;let n=e;for(let o of t){let r=n;for(let a of o){if(!r||typeof r!="object"||!(a in r)){r=void 0;break}r=r[a]}if(r!==void 0)return r}return null}function S(e){if(typeof e=="number"&&Number.isFinite(e))return e;if(typeof e=="string"&&e.trim()!==""){let t=Number(e);return Number.isFinite(t)?t:null}return null}function C(e){return typeof e=="string"&&e.trim()!==""?e.trim():null}function ue(e){return typeof e=="boolean"?e:typeof e=="string"?["true","1","yes"].includes(e.trim().toLowerCase()):typeof e=="number"?e>0:!1}function pe(e,t){let n={};for(let o of t){let r=e[o];(typeof r=="string"||typeof r=="number"||typeof r=="boolean")&&(n[o]=r)}return n}function Ve(e){let n=He(e,"utf8").split(/\r?\n/).map(r=>r.trim()).filter(Boolean),o=[];for(let r of n)try{let a=JSON.parse(r);o.push(a)}catch{}return o}function qe(e){return C(f(e,[["provider"],["message","provider"],["usage","provider"]]))??"unknown"}function Qe(e){return C(f(e,[["model"],["message","model"],["usage","model"]]))??"unknown-model"}function le(e,t){return C(f(e,[["workflow"],["session","workflow"],["metadata","workflow"],["agent","name"],["agentId"],["sessionId"]]))??Ye(t,".jsonl")}function Ze(e){return C(f(e,[["environment"],["env"],["metadata","environment"]]))??"local"}function et(e,t,n,o){return C(f(e,[["run_id"],["runId"],["trace_id"],["traceId"],["sessionId"],["thread_id"]]))??`${o}:${t}:${n}`}function tt(e,t){return C(f(e,[["task_class"],["taskClass"],["metadata","taskClass"]]))??t.toLowerCase()}function x(e){let t=S(f(e,[["input_tokens"],["inputTokens"],["usage","input_tokens"],["usage","inputTokens"],["message","usage","input_tokens"],["message","usage","inputTokens"],["usage","prompt_tokens"],["message","usage","prompt_tokens"]]))??0,n=S(f(e,[["output_tokens"],["outputTokens"],["usage","output_tokens"],["usage","outputTokens"],["message","usage","output_tokens"],["message","usage","outputTokens"],["usage","completion_tokens"],["message","usage","completion_tokens"]]))??0,o=S(f(e,[["cost_usd"],["costUsd"],["usage","cost_usd"],["usage","costUsd"],["usage","cost","total"],["message","usage","cost","total"],["message","usage","cost_usd"],["pricing","total_usd"]]))??null;return{inputTokens:t,outputTokens:n,observedCost:o}}function nt(e,t,n,o){let r=qe(t),a=Qe(t),i=le(t,e.path),{inputTokens:c,outputTokens:u,observedCost:d}=x(t),s=ce(r,a,c,u),p=v(f(t,[["timestamp"],["createdAt"],["created_at"]])),l=S(f(t,[["attempt"],["usage","attempt"],["metadata","attempt"]]))??null,g=S(f(t,[["iteration"],["loop_iteration"],["metadata","iteration"]]))??null,k=S(f(t,[["retries"],["retry_count"],["metadata","retries"]]))??0,y=d??s??0;return{id:U(`${n}:${e.path}:${o}:${a}:${p}:${y}`),runId:n,timestamp:p,provider:r,model:a,inputTokens:c,outputTokens:u,costUsd:y,costSource:d!==null?"observed":"estimated",latencyMs:S(f(t,[["latency_ms"],["latencyMs"],["usage","latency_ms"]]))??null,toolCalls:S(f(t,[["tool_calls"],["toolCalls"],["usage","tool_calls"]]))??0,retries:k,attempt:l,iteration:g,status:C(f(t,[["status"],["level"],["result"],["error","type"]]))??null,taskClass:tt(t,i),cacheHit:ue(f(t,[["cache_hit"],["cacheHit"],["usage","cache_hit"]])),cacheCostUsd:S(f(t,[["cache_cost_usd"],["cacheCostUsd"],["usage","cache_cost_usd"]]))??null,metadata:pe(t,["event","type","sessionId","agentId"])}}function st(e){return x(e).inputTokens>0||x(e).outputTokens>0||x(e).observedCost!==null}function me(e,t){let n=H(t),o=new Map;for(let r of e)Ve(r.path).forEach((i,c)=>{if(!st(i))return;let u=le(i,r.path),d=v(f(i,[["timestamp"],["createdAt"],["created_at"]]));if(n&&new Date(d).getTime()<n)return;let s=et(i,u,c,r.path),p=U(`${r.path}:${s}`),l=nt(r,i,p,c),g=o.get(p);if(!g){o.set(p,{id:p,sourceKind:r.kind,sourcePath:r.path,timestamp:d,workflow:u,environment:Ze(i),tags:{sourceKind:r.kind},calls:[l],totalCostUsd:l.costUsd,totalTokens:l.inputTokens+l.outputTokens,observedCostUsd:l.costSource==="observed"?l.costUsd:0,estimatedCostUsd:l.costSource==="estimated"?l.costUsd:0});return}g.calls.push(l),g.totalCostUsd=Number((g.totalCostUsd+l.costUsd).toFixed(8)),g.totalTokens+=l.inputTokens+l.outputTokens,g.observedCostUsd+=l.costSource==="observed"?l.costUsd:0,g.estimatedCostUsd+=l.costSource==="estimated"?l.costUsd:0});return Array.from(o.values()).sort((r,a)=>new Date(r.timestamp).getTime()-new Date(a.timestamp).getTime())}function fe(e){let t=new Map;for(let n of e){let o=t.get(n.key)??{spendUsd:0,observedSpendUsd:0,callCount:0};o.spendUsd+=n.spendUsd,o.observedSpendUsd+=n.observedSpendUsd,o.callCount+=1,t.set(n.key,o)}return Array.from(t.entries()).map(([n,o])=>{let r=o.spendUsd===0?0:o.observedSpendUsd/o.spendUsd;return{key:n,spendUsd:Number(o.spendUsd.toFixed(6)),callCount:o.callCount,observedShare:Number(r.toFixed(4))}}).sort((n,o)=>o.spendUsd-n.spendUsd)}function ge(e){let t=e.runs.reduce((u,d)=>u+d.calls.length,0),n=e.runs.reduce((u,d)=>u+d.totalCostUsd,0),o=e.runs.reduce((u,d)=>u+d.observedCostUsd,0),r=e.runs.reduce((u,d)=>u+d.estimatedCostUsd,0),a=e.findings.filter(u=>u.classification==="waste").reduce((u,d)=>u+d.costImpactUsd,0),i=e.findings.filter(u=>u.classification==="opportunity").reduce((u,d)=>u+d.costImpactUsd,0),c=R();return{auditId:U(`${c}:${e.runs.length}:${e.sources.map(u=>u.path).join("|")}`),generatedAt:c,comparisonKey:F({sources:e.sources,since:e.since}),comparison:null,since:e.since,runCount:e.runs.length,callCount:t,totalSpendUsd:Number(n.toFixed(6)),observedSpendUsd:Number(o.toFixed(6)),estimatedSpendUsd:Number(r.toFixed(6)),wasteSpendUsd:Number(a.toFixed(6)),opportunitySpendUsd:Number(i.toFixed(6)),structuralWasteRate:Number((n===0?0:a/n).toFixed(4)),wasteByKind:$(e.findings,"waste"),opportunityByKind:$(e.findings,"opportunity"),spendByWorkflow:fe(e.runs.map(u=>({key:u.workflow,spendUsd:u.totalCostUsd,observedSpendUsd:u.observedCostUsd}))),spendByModel:fe(e.runs.flatMap(u=>u.calls.map(d=>({key:`${d.provider}/${d.model}`,spendUsd:d.costUsd,observedSpendUsd:d.costSource==="observed"?d.costUsd:0})))),findings:e.findings,notes:["Cost per outcome is intentionally unavailable in v0. Xerg is measuring waste intelligence only.","Opportunity findings are directional recommendations, not proven waste."],sourceFiles:e.sources,dbPath:e.dbPath}}async function he(e){return ae(e)}async function we(e){if(e.compare&&e.noDb)throw new Error("The --compare flag needs local snapshot history. Remove --no-db or provide --db <path>.");let t=await X(e);if(t.length===0)throw new Error("No OpenClaw sources were detected. Run `xerg doctor` or provide --log-file / --sessions-dir.");let n=me(t,e.since),o=de(n),r=e.noDb?void 0:e.dbPath??ie(),a=ge({runs:n,findings:o,sources:t,since:e.since,dbPath:r});if(e.compare&&r){let i=se({dbPath:r,comparisonKey:a.comparisonKey,currentAuditId:a.auditId});i?a.comparison=ne(a,i):a.notes=[...a.notes,"No prior comparable audit was found. Run the same audit again after a fix to unlock before/after deltas."]}return r&&V({summary:a,runs:n,pricingCatalog:j},r),a}function m(e){return new Intl.NumberFormat("en-US",{style:"currency",currency:"USD",minimumFractionDigits:e>=1?2:4,maximumFractionDigits:4}).format(e)}function N(e){return`${(e*100).toFixed(0)}%`}function Se(e){let t=e*100;return`${t>0?"+":""}${t.toFixed(0)} pts`}function I(e){return`${e>0?"+":""}${m(e)}`}function K(e,t=5){return e.slice(0,t).map(n=>`- ${n.key}: ${m(n.spendUsd)} (${N(n.observedShare)} observed)`)}function Ue(e,t,n){return e.length===0?[`- ${t}`]:e.map(o=>{let r=`${o.findingCount} finding${o.findingCount===1?"":"s"}`,a=n?` ${n}`:"";return`- ${o.label}: ${m(o.spendUsd)} across ${r}${a}`})}function Te(e){return["## Waste taxonomy","Structural waste",...Ue(e.wasteByKind,"No confirmed waste buckets detected."),"Savings opportunities",...Ue(e.opportunityByKind,"No opportunity buckets detected.","(directional)")]}function ot(e,t){return e.findings.filter(n=>n.classification===t).sort((n,o)=>o.costImpactUsd-n.costImpactUsd)[0]}function rt(e){return e.findings.filter(t=>t.classification==="opportunity").sort((t,n)=>{let o=t.kind==="candidate-downgrade"?1:0,r=n.kind==="candidate-downgrade"?1:0;return o!==r?r-o:n.costImpactUsd-t.costImpactUsd})[0]??null}function ke(e,t){return e.length===0?[`- ${t}`]:e.slice(0,5).map(n=>`- ${n.title}: ${m(n.costImpactUsd)} (${n.confidence})`)}function G(e){return`${e.key} (${I(e.deltaSpendUsd)})`}function it(e){return e.filter(t=>t.deltaSpendUsd<0).sort((t,n)=>t.deltaSpendUsd-n.deltaSpendUsd)[0]}function at(e){return e.filter(t=>t.deltaSpendUsd>0).sort((t,n)=>n.deltaSpendUsd-t.deltaSpendUsd)[0]}function J(e,t){return t==="resolved"?`- Resolved: ${e.title} (${m(e.baselineCostImpactUsd??0)})`:t==="worsened"?`- Worsened: ${e.title} (${I(e.deltaCostImpactUsd)})`:`- New: ${e.title} (${m(e.currentCostImpactUsd??0)})`}function dt(e){if(!e.comparison)return[];let t=e.comparison,n=it(t.workflowDeltas),o=at(t.workflowDeltas),r=o?.key??e.spendByWorkflow[0]?.key??null,a=[...t.findingChanges.newHighConfidenceWaste.map(i=>J(i,"new")),...t.findingChanges.resolvedHighConfidenceWaste.map(i=>J(i,"resolved")),...t.findingChanges.worsenedHighConfidenceWaste.map(i=>J(i,"worsened"))].slice(0,5);return["## Before / after",`Compared against ${t.baselineGeneratedAt}`,`- Total spend: ${m(t.baselineTotalSpendUsd)} -> ${m(e.totalSpendUsd)} (${I(t.deltaTotalSpendUsd)})`,`- Structural waste: ${m(t.baselineWasteSpendUsd)} -> ${m(e.wasteSpendUsd)} (${I(t.deltaWasteSpendUsd)})`,`- Waste rate: ${N(t.baselineStructuralWasteRate)} -> ${N(e.structuralWasteRate)} (${Se(t.deltaStructuralWasteRate)})`,`- Runs analyzed: ${t.baselineRunCount} -> ${e.runCount} (${t.deltaRunCount>0?"+":""}${t.deltaRunCount})`,`- Model calls: ${t.baselineCallCount} -> ${e.callCount} (${t.deltaCallCount>0?"+":""}${t.deltaCallCount})`,n?`- Biggest improvement: ${G(n)}`:"- Biggest improvement: none detected",o?`- Biggest regression: ${G(o)}`:"- Biggest regression: none detected",r?`- First workflow to inspect now: ${r}`:"- First workflow to inspect now: no workflow delta available",...t.modelDeltas.length>0?[`- Model swing to inspect: ${G(t.modelDeltas[0])}`]:["- Model swing to inspect: none"],...a.length>0?a:["- High-confidence waste changes: none"]]}function ye(e){return["# Xerg doctor","",e.canAudit?"OpenClaw sources detected.":"No OpenClaw sources detected.","","## Defaults",`- gateway logs: ${e.defaults.gatewayPattern}`,`- session files: ${e.defaults.sessionsPattern}`,"","## Sources",...e.sources.length>0?e.sources.map(n=>`- [${n.kind}] ${n.path}`):["- none"],"","## Notes",...e.notes.map(n=>`- ${n}`)].join(`
159
+ `)}function Ce(e){let t=e.findings.filter(a=>a.classification==="waste"),n=e.findings.filter(a=>a.classification==="opportunity"),o=rt(e),r=ot(e,"waste");return["# Xerg audit","",`Total spend: ${m(e.totalSpendUsd)}`,`Observed spend: ${m(e.observedSpendUsd)}`,`Estimated spend: ${m(e.estimatedSpendUsd)}`,`Runs analyzed: ${e.runCount}`,`Model calls: ${e.callCount}`,`Structural waste identified: ${m(e.wasteSpendUsd)} (${N(e.structuralWasteRate)})`,`Potential impact surfaced: ${m(e.opportunitySpendUsd)}`,"",...Te(e),"","## Top workflows",...K(e.spendByWorkflow),"","## Top models",...K(e.spendByModel),"","## High-confidence waste",...ke(t,"none detected"),"","## Opportunities",...ke(n,"none detected"),"","## First savings test",...o?[`- Start with ${o.title}: ${m(o.costImpactUsd)} of potential impact`,`- Why this test first: ${o.summary}`]:["- No savings test surfaced yet"],...r?[`- Confirmed leak to close first: ${r.title}`]:["- Confirmed leak to close first: none"],...e.spendByWorkflow[0]?[`- Workflow to inspect first: ${e.spendByWorkflow[0].key}`]:["- Workflow to inspect first: none"],"",...dt(e),...e.comparison?[""]:[],"## Notes",...e.notes.map(a=>`- ${a}`)].join(`
160
+ `)}function be(e){let t=["# Xerg Audit Report","",`- Generated: ${e.generatedAt}`,`- Total spend: ${m(e.totalSpendUsd)}`,`- Observed spend: ${m(e.observedSpendUsd)}`,`- Estimated spend: ${m(e.estimatedSpendUsd)}`,`- Structural waste identified: ${m(e.wasteSpendUsd)} (${N(e.structuralWasteRate)})`,`- Potential impact surfaced: ${m(e.opportunitySpendUsd)}`,`- Runs analyzed: ${e.runCount}`,`- Model calls: ${e.callCount}`,"",...Te(e),"","## Top workflows",...K(e.spendByWorkflow),"","## Findings",...e.findings.slice(0,10).map(n=>`- **${n.title}** (${n.classification}, ${n.confidence}) \u2014 ${n.summary} Estimated impact: ${m(n.costImpactUsd)}.`)];if(e.comparison){let n=e.comparison;t.push("","## Before / after",`- Compared against: ${n.baselineGeneratedAt}`,`- Total spend: ${m(n.baselineTotalSpendUsd)} -> ${m(e.totalSpendUsd)} (${I(n.deltaTotalSpendUsd)})`,`- Structural waste: ${m(n.baselineWasteSpendUsd)} -> ${m(e.wasteSpendUsd)} (${I(n.deltaWasteSpendUsd)})`,`- Waste rate: ${N(n.baselineStructuralWasteRate)} -> ${N(e.structuralWasteRate)} (${Se(n.deltaStructuralWasteRate)})`)}return t.join(`
161
+ `)}async function Ne(e){let t=await we({logFile:e.logFile,sessionsDir:e.sessionsDir,since:e.since,compare:e.compare,dbPath:e.db,noDb:e.noDb});if(e.json){process.stdout.write(`${JSON.stringify(t,null,2)}
162
+ `);return}if(e.markdown){process.stdout.write(`${be(t)}
163
+ `);return}process.stdout.write(`${Ce(t)}
164
+ `)}async function Ie(e){let t=await he({logFile:e.logFile,sessionsDir:e.sessionsDir});process.stdout.write(`${ye(t)}
165
+ `)}var Ee=Ut(),z=process.argv.slice(2),T=z[0];(!T||T==="--help"||T==="-h"||T==="help")&&(process.stdout.write(ft()),process.exit(0));(T==="--version"||T==="-v"||T==="version")&&(process.stdout.write(`${Ee}
166
+ `),process.exit(0));pt().catch(e=>{let t=e instanceof Error?e.message:"Unknown error";process.stderr.write(`${wt(`xerg failed: ${t}`)}
167
+ `),process.exitCode=1});async function pt(){if(T==="audit"){let e=lt(z.slice(1));if(e.json&&e.markdown)throw new Error("Use either --json or --markdown, not both.");await Ne(e);return}if(T==="doctor"){let e=mt(z.slice(1));await Ie(e);return}throw new Error(`Unknown command "${T}". Run \`xerg --help\` to see available commands.`)}function lt(e){let t={};for(let n=0;n<e.length;n+=1){let o=e[n];switch(o){case"--help":case"-h":process.stdout.write(gt()),process.exit(0);break;case"--log-file":t.logFile=E(o,e[n+1]),n+=1;break;case"--sessions-dir":t.sessionsDir=E(o,e[n+1]),n+=1;break;case"--since":t.since=E(o,e[n+1]),n+=1;break;case"--db":t.db=E(o,e[n+1]),n+=1;break;case"--compare":t.compare=!0;break;case"--json":t.json=!0;break;case"--markdown":t.markdown=!0;break;case"--no-db":t.noDb=!0;break;default:throw new Error(`Unknown audit option "${o}". Run \`xerg audit --help\` for usage.`)}}return t}function mt(e){let t={};for(let n=0;n<e.length;n+=1){let o=e[n];switch(o){case"--help":case"-h":process.stdout.write(ht()),process.exit(0);break;case"--log-file":t.logFile=E(o,e[n+1]),n+=1;break;case"--sessions-dir":t.sessionsDir=E(o,e[n+1]),n+=1;break;default:throw new Error(`Unknown doctor option "${o}". Run \`xerg doctor --help\` for usage.`)}}return t}function E(e,t){if(!t||t.startsWith("-"))throw new Error(`The ${e} flag needs a value.`);return t}function ft(){return`xerg ${Ee}
168
+
169
+ Waste intelligence for OpenClaw workflows.
170
+
171
+ Usage:
172
+ xerg <command> [options]
173
+
174
+ Commands:
175
+ audit Analyze OpenClaw logs and produce a waste intelligence report.
176
+ doctor Inspect your machine for OpenClaw sources and audit readiness.
177
+
178
+ Global options:
179
+ -h, --help Show help
180
+ -v, --version Show version
181
+ `}function gt(){return`xerg audit
182
+
183
+ Analyze OpenClaw logs and produce a waste intelligence report.
184
+
185
+ Usage:
186
+ xerg audit [options]
187
+
188
+ Options:
189
+ --log-file <path> Explicit OpenClaw gateway log file to analyze
190
+ --sessions-dir <path> Explicit OpenClaw sessions directory to analyze
191
+ --since <duration> Look back window such as 24h, 7d, or 30m
192
+ --compare Compare this audit to the newest compatible prior local snapshot
193
+ --json Render the report as JSON
194
+ --markdown Render the report as Markdown
195
+ --db <path> Custom SQLite database path
196
+ --no-db Skip local persistence
197
+ -h, --help Show help
198
+ `}function ht(){return`xerg doctor
199
+
200
+ Inspect your machine for OpenClaw sources and audit readiness.
201
+
202
+ Usage:
203
+ xerg doctor [options]
204
+
205
+ Options:
206
+ --log-file <path> Explicit OpenClaw gateway log file to inspect
207
+ --sessions-dir <path> Explicit OpenClaw sessions directory to inspect
208
+ -h, --help Show help
209
+ `}function wt(e){return process.stderr.isTTY?ut("red",e):e}function Ut(){let e=new URL("../package.json",import.meta.url);return JSON.parse(ct(e,"utf8")).version??"0.0.0"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xerg/cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "CLI waste intelligence for OpenClaw workflows.",
5
5
  "keywords": ["ai", "agents", "finops", "llm", "openclaw", "cost", "cli"],
6
6
  "homepage": "https://xerg.ai",
@@ -19,6 +19,9 @@
19
19
  "bin": {
20
20
  "xerg": "dist/index.js"
21
21
  },
22
+ "publishConfig": {
23
+ "access": "public"
24
+ },
22
25
  "files": ["dist", "README.md", "LICENSE"],
23
26
  "main": "./dist/index.js",
24
27
  "exports": {
@@ -35,17 +38,9 @@
35
38
  "typecheck": "tsc --noEmit -p tsconfig.json"
36
39
  },
37
40
  "dependencies": {
38
- "better-sqlite3": "^11.10.0",
39
- "commander": "^14.0.0",
40
- "drizzle-orm": "^0.44.2",
41
- "env-paths": "^3.0.0",
42
- "fast-glob": "^3.3.3",
43
- "picocolors": "^1.1.1",
44
- "zod": "^3.24.2"
41
+ "better-sqlite3": "^11.10.0"
45
42
  },
46
43
  "devDependencies": {
47
- "@xergai/core": "workspace:*",
48
- "tsup": "^8.4.0",
49
- "tsx": "^4.20.3"
44
+ "@xergai/core": "workspace:*"
50
45
  }
51
46
  }