loki-mode 7.15.0 → 7.16.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.
@@ -1,60 +1,60 @@
1
1
  // @bun
2
- var V5=Object.defineProperty;var q5=($)=>$;function J5($,K){this[$]=q5.bind(null,K)}var g=($,K)=>{for(var Q in K)V5($,Q,{get:K[Q],enumerable:!0,configurable:!0,set:J5.bind(K,Q)})};var F=($,K)=>()=>($&&(K=$($=0)),K);var X1=import.meta.require;var T$={};g(T$,{lokiDir:()=>L,homeLokiDir:()=>m1,findRepoRootForVersion:()=>v1,REPO_ROOT:()=>p});import{resolve as o,dirname as g1}from"path";import{fileURLToPath as W5}from"url";import{existsSync as w1}from"fs";import{homedir as G5}from"os";function B5(){let $=Y$;for(let K=0;K<6;K++){if(w1(o($,"VERSION"))&&w1(o($,"autonomy/run.sh")))return $;let Q=g1($);if(Q===$)break;$=Q}return o(Y$,"..","..","..")}function v1($){let K=$;for(let Q=0;Q<6;Q++){if(w1(o(K,"VERSION"))&&w1(o(K,"autonomy/run.sh")))return K;let X=g1(K);if(X===K)break;K=X}return o($,"..","..","..")}function L(){return process.env.LOKI_DIR??o(process.cwd(),".loki")}function m1(){return o(G5(),".loki")}var Y$,p;var v=F(()=>{Y$=g1(W5(import.meta.url));p=B5()});import{readFileSync as M5}from"fs";import{resolve as Y5,dirname as T5}from"path";import{fileURLToPath as O5}from"url";function I1(){if($1!==null)return $1;let $="7.15.0";if(typeof $==="string"&&$.length>0)return $1=$,$1;try{let K=T5(O5(import.meta.url)),Q=v1(K);$1=M5(Y5(Q,"VERSION"),"utf-8").trim()}catch{$1="unknown"}return $1}var $1=null;var f1=F(()=>{v()});var A$={};g(A$,{runOrThrow:()=>A5,run:()=>k,commandVersion:()=>w5,commandExists:()=>m,ShellError:()=>u1});async function k($,K={}){let Q=Bun.spawn({cmd:[...$],stdout:"pipe",stderr:"pipe",env:K.env?{...process.env,...K.env}:process.env,cwd:K.cwd}),X,Z;if(K.timeoutMs&&K.timeoutMs>0)X=setTimeout(()=>{try{Q.kill("SIGTERM")}catch{}Z=setTimeout(()=>{try{Q.kill("SIGKILL")}catch{}},2000)},K.timeoutMs);try{let[z,H,V]=await Promise.all([new Response(Q.stdout).text(),new Response(Q.stderr).text(),Q.exited]);return{stdout:z,stderr:H,exitCode:V}}finally{if(X)clearTimeout(X);if(Z)clearTimeout(Z)}}async function A5($,K={}){let Q=await k($,K);if(Q.exitCode!==0)throw new u1(`command failed (${Q.exitCode}): ${$.join(" ")}`,Q.exitCode,Q.stdout,Q.stderr);return Q}async function m($){let K=_5($),Q=await k(["sh","-c",`command -v ${K}`],{timeoutMs:5000});if(Q.exitCode===0)return Q.stdout.trim()||null;return null}function _5($){if(!/^[A-Za-z0-9._/-]+$/.test($))throw Error(`refused to shell-escape suspect token: ${$}`);return $}async function w5($,K="--version"){if(!await m($))return null;let X=await k([$,K],{timeoutMs:5000});if(X.exitCode!==0)return null;return((X.stdout||X.stderr).split(/\r?\n/)[0]?.trim()??"")||null}var u1;var n=F(()=>{u1=class u1 extends Error{message;exitCode;stdout;stderr;constructor($,K,Q,X){super($);this.message=$;this.exitCode=K;this.stdout=Q;this.stderr=X;this.name="ShellError"}}});function a($){return I5?"":$}var I5,O,D,I,uK,_,S,h,U;var l=F(()=>{I5=(process.env.NO_COLOR??"").length>0;O=a("\x1B[0;31m"),D=a("\x1B[0;32m"),I=a("\x1B[1;33m"),uK=a("\x1B[0;34m"),_=a("\x1B[0;36m"),S=a("\x1B[1m"),h=a("\x1B[2m"),U=a("\x1B[0m")});import{existsSync as N5}from"fs";async function Z1(){if(W1!==void 0)return W1;let $="/opt/homebrew/bin/python3.12";if(N5($))return W1=$,$;let K=await m("python3.12");if(K)return W1=K,K;let Q=await m("python3");return W1=Q,Q}async function K1($,K={}){let Q=await Z1();if(!Q)return{stdout:"",stderr:"python3 not found",exitCode:127};return k([Q,"-c",$],K)}var W1;var G1=F(()=>{n()});var E$={};g(E$,{runStatus:()=>d5});import{existsSync as b,readFileSync as H1,readdirSync as P$,statSync as L$}from"fs";import{resolve as N,basename as y5}from"path";import{homedir as g5}from"os";async function m5(){if(await m("jq"))return!0;return process.stdout.write(`${O}Error: jq is required but not installed.${U}
2
+ var I7=Object.defineProperty;var P7=($)=>$;function L7($,Q){this[$]=P7.bind(null,Q)}var g=($,Q)=>{for(var K in Q)I7($,K,{get:Q[K],enumerable:!0,configurable:!0,set:L7.bind(Q,K)})};var k=($,Q)=>()=>($&&(Q=$($=0)),Q);var z1=import.meta.require;var w$={};g(w$,{lokiDir:()=>L,homeLokiDir:()=>c1,findRepoRootForVersion:()=>u1,REPO_ROOT:()=>p});import{resolve as o,dirname as f1}from"path";import{fileURLToPath as k7}from"url";import{existsSync as P1}from"fs";import{homedir as j7}from"os";function F7(){let $=A$;for(let Q=0;Q<6;Q++){if(P1(o($,"VERSION"))&&P1(o($,"autonomy/run.sh")))return $;let K=f1($);if(K===$)break;$=K}return o(A$,"..","..","..")}function u1($){let Q=$;for(let K=0;K<6;K++){if(P1(o(Q,"VERSION"))&&P1(o(Q,"autonomy/run.sh")))return Q;let Z=f1(Q);if(Z===Q)break;Q=Z}return o($,"..","..","..")}function L(){return process.env.LOKI_DIR??o(process.cwd(),".loki")}function c1(){return o(j7(),".loki")}var A$,p;var m=k(()=>{A$=f1(k7(import.meta.url));p=F7()});import{readFileSync as R7}from"fs";import{resolve as E7,dirname as S7}from"path";import{fileURLToPath as x7}from"url";function L1(){if($1!==null)return $1;let $="7.16.0";if(typeof $==="string"&&$.length>0)return $1=$,$1;try{let Q=S7(x7(import.meta.url)),K=u1(Q);$1=R7(E7(K,"VERSION"),"utf-8").trim()}catch{$1="unknown"}return $1}var $1=null;var p1=k(()=>{m()});var P$={};g(P$,{runOrThrow:()=>N7,run:()=>F,commandVersion:()=>D7,commandExists:()=>v,ShellError:()=>l1});async function F($,Q={}){let K=Bun.spawn({cmd:[...$],stdout:"pipe",stderr:"pipe",env:Q.env?{...process.env,...Q.env}:process.env,cwd:Q.cwd}),Z,z;if(Q.timeoutMs&&Q.timeoutMs>0)Z=setTimeout(()=>{try{K.kill("SIGTERM")}catch{}z=setTimeout(()=>{try{K.kill("SIGKILL")}catch{}},2000)},Q.timeoutMs);try{let[U,X,W]=await Promise.all([new Response(K.stdout).text(),new Response(K.stderr).text(),K.exited]);return{stdout:U,stderr:X,exitCode:W}}finally{if(Z)clearTimeout(Z);if(z)clearTimeout(z)}}async function N7($,Q={}){let K=await F($,Q);if(K.exitCode!==0)throw new l1(`command failed (${K.exitCode}): ${$.join(" ")}`,K.exitCode,K.stdout,K.stderr);return K}async function v($){let Q=C7($),K=await F(["sh","-c",`command -v ${Q}`],{timeoutMs:5000});if(K.exitCode===0)return K.stdout.trim()||null;return null}function C7($){if(!/^[A-Za-z0-9._/-]+$/.test($))throw Error(`refused to shell-escape suspect token: ${$}`);return $}async function D7($,Q="--version"){if(!await v($))return null;let Z=await F([$,Q],{timeoutMs:5000});if(Z.exitCode!==0)return null;return((Z.stdout||Z.stderr).split(/\r?\n/)[0]?.trim()??"")||null}var l1;var n=k(()=>{l1=class l1 extends Error{message;exitCode;stdout;stderr;constructor($,Q,K,Z){super($);this.message=$;this.exitCode=Q;this.stdout=K;this.stderr=Z;this.name="ShellError"}}});function a($){return h7?"":$}var h7,O,C,I,I3,A,x,h,H;var l=k(()=>{h7=(process.env.NO_COLOR??"").length>0;O=a("\x1B[0;31m"),C=a("\x1B[0;32m"),I=a("\x1B[1;33m"),I3=a("\x1B[0;34m"),A=a("\x1B[0;36m"),x=a("\x1B[1m"),h=a("\x1B[2m"),H=a("\x1B[0m")});import{existsSync as l7}from"fs";async function X1(){if(G1!==void 0)return G1;let $="/opt/homebrew/bin/python3.12";if(l7($))return G1=$,$;let Q=await v("python3.12");if(Q)return G1=Q,Q;let K=await v("python3");return G1=K,K}async function Q1($,Q={}){let K=await X1();if(!K)return{stdout:"",stderr:"python3 not found",exitCode:127};return F([K,"-c",$],Q)}var G1;var B1=k(()=>{n()});var D$={};g(D$,{runStatus:()=>z8});import{existsSync as b,readFileSync as H1,readdirSync as R$,statSync as E$}from"fs";import{resolve as N,basename as s7}from"path";import{homedir as r7}from"os";async function i7(){if(await v("jq"))return!0;return process.stdout.write(`${O}Error: jq is required but not installed.${H}
3
3
  `),process.stdout.write(`Install with:
4
4
  `),process.stdout.write(` brew install jq (macOS)
5
5
  `),process.stdout.write(` apt install jq (Debian/Ubuntu)
6
6
  `),process.stdout.write(` yum install jq (RHEL/CentOS)
7
- `),!1}function j1($){if(!Number.isFinite($)||$<=0)return!1;try{return process.kill($,0),!0}catch{return!1}}function P1($){if(!b($))return null;try{let K=H1($,"utf-8").trim();if(!K)return null;let Q=Number.parseInt(K,10);return Number.isFinite(Q)?Q:null}catch{return null}}function f5($){let K=[],Q=P1(N($,"loki.pid"));if(Q!==null&&j1(Q))K.push(`global:${Q}`);let X=N($,"sessions");if(b(X)){let Z=[];try{Z=P$(X)}catch{Z=[]}for(let z of Z){let H=N(X,z);try{if(!L$(H).isDirectory())continue}catch{continue}let V=N(H,"loki.pid"),q=P1(V);if(q!==null&&j1(q))K.push(`${z}:${q}`)}}if(b($)){let Z=[];try{Z=P$($)}catch{Z=[]}for(let z of Z){if(!z.startsWith("run-")||!z.endsWith(".pid"))continue;let H=N($,z);try{if(!L$(H).isFile())continue}catch{continue}let V=y5(z,".pid").slice(4),q=P1(H);if(q!==null&&j1(q)){if(!K.some((W)=>W.startsWith(`${V}:`)))K.push(`${V}:${q}`)}}}return K}async function k$($,K){let Q=await k(["jq","-r",$,K]);if(Q.exitCode!==0)return null;return Q.stdout.trim()}function x$($,K){try{let Q=H1($,"utf-8"),Z=JSON.parse(Q)[K];if(typeof Z==="number"){if(K==="budget_used"){let z=Math.round(Z*100)/100;if(Number.isInteger(z))return String(z);return String(z)}return String(Z)}if(Z===void 0||Z===null)return"0";return String(Z)}catch{return"0"}}function F$($,K,Q){try{let X=H1($,"utf-8"),z=JSON.parse(X)[K];if(typeof z==="number"&&Number.isFinite(z))return z;return Q}catch{return Q}}async function u5(){let $=L();if(!await m5())return 1;if(!b($))return process.stdout.write(`${S}Loki Mode Status${U}
7
+ `),!1}function k1($){if(!Number.isFinite($)||$<=0)return!1;try{return process.kill($,0),!0}catch{return!1}}function j1($){if(!b($))return null;try{let Q=H1($,"utf-8").trim();if(!Q)return null;let K=Number.parseInt(Q,10);return Number.isFinite(K)?K:null}catch{return null}}function e7($){let Q=[],K=j1(N($,"loki.pid"));if(K!==null&&k1(K))Q.push(`global:${K}`);let Z=N($,"sessions");if(b(Z)){let z=[];try{z=R$(Z)}catch{z=[]}for(let U of z){let X=N(Z,U);try{if(!E$(X).isDirectory())continue}catch{continue}let W=N(X,"loki.pid"),J=j1(W);if(J!==null&&k1(J))Q.push(`${U}:${J}`)}}if(b($)){let z=[];try{z=R$($)}catch{z=[]}for(let U of z){if(!U.startsWith("run-")||!U.endsWith(".pid"))continue;let X=N($,U);try{if(!E$(X).isFile())continue}catch{continue}let W=s7(U,".pid").slice(4),J=j1(X);if(J!==null&&k1(J)){if(!Q.some((V)=>V.startsWith(`${W}:`)))Q.push(`${W}:${J}`)}}}return Q}async function S$($,Q){let K=await F(["jq","-r",$,Q]);if(K.exitCode!==0)return null;return K.stdout.trim()}function x$($,Q){try{let K=H1($,"utf-8"),z=JSON.parse(K)[Q];if(typeof z==="number"){if(Q==="budget_used"){let U=Math.round(z*100)/100;if(Number.isInteger(U))return String(U);return String(U)}return String(z)}if(z===void 0||z===null)return"0";return String(z)}catch{return"0"}}function N$($,Q,K){try{let Z=H1($,"utf-8"),U=JSON.parse(Z)[Q];if(typeof U==="number"&&Number.isFinite(U))return U;return K}catch{return K}}async function $8(){let $=L();if(!await i7())return 1;if(!b($))return process.stdout.write(`${x}Loki Mode Status${H}
8
8
  `),process.stdout.write(`
9
- `),process.stdout.write(`${I}No active session found.${U}
9
+ `),process.stdout.write(`${I}No active session found.${H}
10
10
  `),process.stdout.write(`Loki Mode has not been initialized in this directory.
11
11
  `),process.stdout.write(`
12
12
  `),process.stdout.write(`To start a session:
13
13
  `),process.stdout.write(` loki start <prd> - Start with a PRD file
14
14
  `),process.stdout.write(` loki start - Start without a PRD
15
15
  `),process.stdout.write(`
16
- `),process.stdout.write(`${h}Current directory: ${process.cwd()}${U}
17
- `),0;process.stdout.write(`${S}Loki Mode Status${U}
16
+ `),process.stdout.write(`${h}Current directory: ${process.cwd()}${H}
17
+ `),0;process.stdout.write(`${x}Loki Mode Status${H}
18
18
  `),process.stdout.write(`
19
- `);let K="",Q=N($,"state","provider");if(b(Q))try{K=H1(Q,"utf-8").trim()}catch{K=""}let X=K||process.env.LOKI_PROVIDER||"claude",Z="full features";switch(X){case"codex":case"aider":Z="degraded mode";break;case"cline":Z="near-full mode";break;default:Z="full features";break}process.stdout.write(`${_}Provider:${U} ${X} (${Z})
20
- `),process.stdout.write(`${h} Switch with: loki provider set <claude|codex|cline|aider>${U}
19
+ `);let Q="",K=N($,"state","provider");if(b(K))try{Q=H1(K,"utf-8").trim()}catch{Q=""}let Z=Q||process.env.LOKI_PROVIDER||"claude",z="full features";switch(Z){case"codex":case"aider":z="degraded mode";break;case"cline":z="near-full mode";break;default:z="full features";break}process.stdout.write(`${A}Provider:${H} ${Z} (${z})
20
+ `),process.stdout.write(`${h} Switch with: loki provider set <claude|codex|cline|aider>${H}
21
21
  `),process.stdout.write(`
22
- `);let z=f5($);if(z.length>0){process.stdout.write(`${D}Active Sessions: ${z.length}${U}
23
- `);for(let B of z){let T=B.indexOf(":"),Y=T>=0?B.slice(0,T):B,R=T>=0?B.slice(T+1):"";if(Y==="global")process.stdout.write(` ${_}[global]${U} PID ${R}
24
- `);else process.stdout.write(` ${_}[#${Y}]${U} PID ${R}
22
+ `);let U=e7($);if(U.length>0){process.stdout.write(`${C}Active Sessions: ${U.length}${H}
23
+ `);for(let B of U){let T=B.indexOf(":"),Y=T>=0?B.slice(0,T):B,E=T>=0?B.slice(T+1):"";if(Y==="global")process.stdout.write(` ${A}[global]${H} PID ${E}
24
+ `);else process.stdout.write(` ${A}[#${Y}]${H} PID ${E}
25
25
  `)}process.stdout.write(`
26
- `),process.stdout.write(`${h} Stop specific: loki stop <session-id>${U}
27
- `),process.stdout.write(`${h} Stop all: loki stop${U}
26
+ `),process.stdout.write(`${h} Stop specific: loki stop <session-id>${H}
27
+ `),process.stdout.write(`${h} Stop all: loki stop${H}
28
28
  `),process.stdout.write(`
29
- `)}if(b(N($,"PAUSE")))process.stdout.write(`${I}Status: PAUSED${U}
30
- `),process.stdout.write(`${h} Resume with: loki resume${U}
29
+ `)}if(b(N($,"PAUSE")))process.stdout.write(`${I}Status: PAUSED${H}
30
+ `),process.stdout.write(`${h} Resume with: loki resume${H}
31
31
  `),process.stdout.write(`
32
- `);else if(b(N($,"STOP")))process.stdout.write(`${O}Status: STOPPED${U}
33
- `),process.stdout.write(`${h} Clear with: loki resume${U}
32
+ `);else if(b(N($,"STOP")))process.stdout.write(`${O}Status: STOPPED${H}
33
+ `),process.stdout.write(`${h} Clear with: loki resume${H}
34
34
  `),process.stdout.write(`
35
- `);let H=N($,"STATUS.txt");if(b(H)){process.stdout.write(`${_}Session Info:${U}
36
- `);try{process.stdout.write(H1(H,"utf-8"))}catch{}process.stdout.write(`
37
- `)}let V=N($,"state","orchestrator.json");if(b(V)){process.stdout.write(`${_}Orchestrator State:${U}
38
- `);let B=await k$('.currentPhase // "unknown"',V);process.stdout.write(`${B??"unknown"}
39
- `)}let q=N($,"queue","pending.json");if(b(q)){let B=await k$('if type == "array" then length elif .tasks then .tasks | length else 0 end',q);process.stdout.write(`${_}Pending Tasks:${U} ${B??"0"}
40
- `)}let J=N($,"metrics","budget.json");if(b(J)){let B=x$(J,"budget_limit"),T=x$(J,"budget_used");if(B!=="0")process.stdout.write(`${_}Budget:${U} $${T} / $${B}
41
- `);else process.stdout.write(`${_}Cost:${U} $${T} (no limit)
42
- `)}let W=N($,"state","context-usage.json");if(b(W)){let B=F$(W,"window_size",200000),T=F$(W,"used_tokens",0),Y=0;if(B>0)Y=Math.floor(T*100/B);process.stdout.write(`${_}Context:${U} ${Y}% (${T} / ${B} tokens)
43
- `)}let G=[N($,"dashboard","dashboard.pid"),N(g5(),".loki","dashboard","dashboard.pid")].find((B)=>b(B))??"";if(G&&b(G)){let B=P1(G);if(B!==null&&j1(B)){let T=N(G,".."),Y=(w,P)=>{let f=N(T,w);try{return b(f)?H1(f,"utf-8").trim()||P:P}catch{return P}},R=Y("scheme","http"),E=Y("host","127.0.0.1"),C=Y("port",process.env.LOKI_DASHBOARD_PORT||"57374");if(E==="0.0.0.0")E="127.0.0.1";process.stdout.write(`${_}Dashboard:${U} ${R}://${E}:${C}/
44
- `)}}return await c5($),process.stdout.write(`
45
- `),process.stdout.write(`${h} Tip: loki context show - detailed token breakdown${U}
46
- `),process.stdout.write(`${h} Tip: loki code overview - codebase intelligence${U}
47
- `),0}async function c5($){let K=N($,"state"),Q=p5(K),X=N(K,"relevant-learnings.json"),Z=N($,"escalations"),z=Q.length>0,H=b(X),V=b(Z);if(!z&&!H&&!V)return;if(process.stdout.write(`
48
- ${_}Phase 1 artifacts:${U}
49
- `),z){let q=Q[Q.length-1],J=R$(q);if(J&&Array.isArray(J.findings)){let W={Critical:0,High:0,Medium:0,Low:0};for(let G of J.findings){let B=String(G.severity??"");if(B in W)W[B]=(W[B]??0)+1}let M=Object.entries(W).filter(([,G])=>G>0).map(([G,B])=>`${B} ${G.toLowerCase()}`).join(", ");process.stdout.write(` Findings (iter ${J.iteration??"?"}): ${M||"none"} -- ${J.findings.length} total
50
- `)}}if(H){let q=R$(X);if(q&&Array.isArray(q.learnings)&&q.learnings.length>0){let J=new Map;for(let M of q.learnings){let G=String(M.trigger??"unknown");J.set(G,(J.get(G)??0)+1)}let W=[...J.entries()].sort((M,G)=>G[1]-M[1]).slice(0,3).map(([M,G])=>`${G} ${M}`).join(", ");process.stdout.write(` Learnings: ${q.learnings.length} total (${W})
51
- `)}}if(V){let q=0,J="";try{let M=(await import("fs")).readdirSync(Z).filter((G)=>G.endsWith(".md"));if(q=M.length,M.length>0)M.sort(),J=M[M.length-1]??""}catch{}if(q>0)process.stdout.write(` Escalations: ${q} handoff doc${q===1?"":"s"} (latest: ${J})
52
- `)}}function p5($){if(!b($))return[];try{return X1("fs").readdirSync($).filter((X)=>/^findings-\d+\.json$/.test(X)).sort((X,Z)=>{let z=Number.parseInt(X.replace(/[^0-9]/g,""),10)||0,H=Number.parseInt(Z.replace(/[^0-9]/g,""),10)||0;return z-H}).map((X)=>N($,X))}catch{return[]}}function R$($){try{let K=X1("fs");return JSON.parse(K.readFileSync($,"utf-8"))}catch{return null}}async function l5(){let $=await Z1();if(!$)return process.stderr.write(`{"error": "Failed to generate JSON status. Ensure python3 is available."}
53
- `),1;let K=p,Q=L(),X=process.env.LOKI_DASHBOARD_PORT||"57374",Z=process.env.LOKI_PROVIDER||"claude",z=await k([$,"-c",v5,K,Q,X,Z],{timeoutMs:30000});if(z.exitCode!==0)return process.stderr.write(`{"error": "Failed to generate JSON status. Ensure python3 is available."}
54
- `),1;return process.stdout.write(z.stdout),0}async function d5($){let K=[...$];while(K.length>0){let Q=K[0];if(Q==="--json")return l5();if(Q==="--help"||Q==="-h")return process.stdout.write(`Usage: loki status [--json]
55
- `),0;return process.stdout.write(`${O}Unknown flag: ${Q}${U}
35
+ `);let X=N($,"STATUS.txt");if(b(X)){process.stdout.write(`${A}Session Info:${H}
36
+ `);try{process.stdout.write(H1(X,"utf-8"))}catch{}process.stdout.write(`
37
+ `)}let W=N($,"state","orchestrator.json");if(b(W)){process.stdout.write(`${A}Orchestrator State:${H}
38
+ `);let B=await S$('.currentPhase // "unknown"',W);process.stdout.write(`${B??"unknown"}
39
+ `)}let J=N($,"queue","pending.json");if(b(J)){let B=await S$('if type == "array" then length elif .tasks then .tasks | length else 0 end',J);process.stdout.write(`${A}Pending Tasks:${H} ${B??"0"}
40
+ `)}let q=N($,"metrics","budget.json");if(b(q)){let B=x$(q,"budget_limit"),T=x$(q,"budget_used");if(B!=="0")process.stdout.write(`${A}Budget:${H} $${T} / $${B}
41
+ `);else process.stdout.write(`${A}Cost:${H} $${T} (no limit)
42
+ `)}let V=N($,"state","context-usage.json");if(b(V)){let B=N$(V,"window_size",200000),T=N$(V,"used_tokens",0),Y=0;if(B>0)Y=Math.floor(T*100/B);process.stdout.write(`${A}Context:${H} ${Y}% (${T} / ${B} tokens)
43
+ `)}let G=[N($,"dashboard","dashboard.pid"),N(r7(),".loki","dashboard","dashboard.pid")].find((B)=>b(B))??"";if(G&&b(G)){let B=j1(G);if(B!==null&&k1(B)){let T=N(G,".."),Y=(w,j)=>{let f=N(T,w);try{return b(f)?H1(f,"utf-8").trim()||j:j}catch{return j}},E=Y("scheme","http"),S=Y("host","127.0.0.1"),D=Y("port",process.env.LOKI_DASHBOARD_PORT||"57374");if(S==="0.0.0.0")S="127.0.0.1";process.stdout.write(`${A}Dashboard:${H} ${E}://${S}:${D}/
44
+ `)}}return await Q8($),process.stdout.write(`
45
+ `),process.stdout.write(`${h} Tip: loki context show - detailed token breakdown${H}
46
+ `),process.stdout.write(`${h} Tip: loki code overview - codebase intelligence${H}
47
+ `),0}async function Q8($){let Q=N($,"state"),K=K8(Q),Z=N(Q,"relevant-learnings.json"),z=N($,"escalations"),U=K.length>0,X=b(Z),W=b(z);if(!U&&!X&&!W)return;if(process.stdout.write(`
48
+ ${A}Phase 1 artifacts:${H}
49
+ `),U){let J=K[K.length-1],q=C$(J);if(q&&Array.isArray(q.findings)){let V={Critical:0,High:0,Medium:0,Low:0};for(let G of q.findings){let B=String(G.severity??"");if(B in V)V[B]=(V[B]??0)+1}let M=Object.entries(V).filter(([,G])=>G>0).map(([G,B])=>`${B} ${G.toLowerCase()}`).join(", ");process.stdout.write(` Findings (iter ${q.iteration??"?"}): ${M||"none"} -- ${q.findings.length} total
50
+ `)}}if(X){let J=C$(Z);if(J&&Array.isArray(J.learnings)&&J.learnings.length>0){let q=new Map;for(let M of J.learnings){let G=String(M.trigger??"unknown");q.set(G,(q.get(G)??0)+1)}let V=[...q.entries()].sort((M,G)=>G[1]-M[1]).slice(0,3).map(([M,G])=>`${G} ${M}`).join(", ");process.stdout.write(` Learnings: ${J.learnings.length} total (${V})
51
+ `)}}if(W){let J=0,q="";try{let M=(await import("fs")).readdirSync(z).filter((G)=>G.endsWith(".md"));if(J=M.length,M.length>0)M.sort(),q=M[M.length-1]??""}catch{}if(J>0)process.stdout.write(` Escalations: ${J} handoff doc${J===1?"":"s"} (latest: ${q})
52
+ `)}}function K8($){if(!b($))return[];try{return z1("fs").readdirSync($).filter((Z)=>/^findings-\d+\.json$/.test(Z)).sort((Z,z)=>{let U=Number.parseInt(Z.replace(/[^0-9]/g,""),10)||0,X=Number.parseInt(z.replace(/[^0-9]/g,""),10)||0;return U-X}).map((Z)=>N($,Z))}catch{return[]}}function C$($){try{let Q=z1("fs");return JSON.parse(Q.readFileSync($,"utf-8"))}catch{return null}}async function Z8(){let $=await X1();if(!$)return process.stderr.write(`{"error": "Failed to generate JSON status. Ensure python3 is available."}
53
+ `),1;let Q=p,K=L(),Z=process.env.LOKI_DASHBOARD_PORT||"57374",z=process.env.LOKI_PROVIDER||"claude",U=await F([$,"-c",t7,Q,K,Z,z],{timeoutMs:30000});if(U.exitCode!==0)return process.stderr.write(`{"error": "Failed to generate JSON status. Ensure python3 is available."}
54
+ `),1;return process.stdout.write(U.stdout),0}async function z8($){let Q=[...$];while(Q.length>0){let K=Q[0];if(K==="--json")return Z8();if(K==="--help"||K==="-h")return process.stdout.write(`Usage: loki status [--json]
55
+ `),0;return process.stdout.write(`${O}Unknown flag: ${K}${H}
56
56
  `),process.stdout.write(`Usage: loki status [--json]
57
- `),1}return u5()}var v5=`
57
+ `),1}return $8()}var t7=`
58
58
  import json, os, sys, time
59
59
 
60
60
  skill_dir = sys.argv[1]
@@ -328,10 +328,10 @@ if os.path.isfile(gate_count_file):
328
328
  result['phase1'] = phase1
329
329
 
330
330
  print(json.dumps(result, indent=2))
331
- `;var S$=F(()=>{n();G1();l();v()});var h$={};g(h$,{runStats:()=>t5,computeStats:()=>C$});import{readdirSync as N$,readFileSync as o5,statSync as D$}from"fs";import{join as s}from"path";function U1($){try{if(!D$($).isFile())return null;return JSON.parse(o5($,"utf-8"))}catch{return null}}function d1($){try{return D$($).isDirectory()}catch{return!1}}function n5($){if(!d1($))return[];try{let K=N$($).filter((Q)=>Q.startsWith("iteration-")&&Q.endsWith(".json"));return K.sort(),K.map((Q)=>s($,Q))}catch{return[]}}function V1($){return Math.trunc($).toLocaleString("en-US")}function p1($){let K=Math.trunc($);if(K<60)return`${K}s`;let Q=Math.trunc(K/3600),X=Math.trunc(K%3600/60),Z=K%60;if(Q>0)return`${Q}h ${String(X).padStart(2,"0")}m`;return`${X}m ${String(Z).padStart(2,"0")}s`}function r($,K=0){let Q=Math.pow(10,K);return Math.round($*Q)/Q}function q1($,K){return $.toFixed(K)}function l1($,K){return $.length>=K?$:$+" ".repeat(K-$.length)}function a5($){let K="N/A",Q=0,X=U1(s($,"state","orchestrator.json"));if(X&&typeof X==="object"){if(typeof X.currentPhase==="string")K=X.currentPhase;if(typeof X.currentIteration==="number")Q=X.currentIteration}let Z=s($,"metrics","efficiency"),z=n5(Z),H=[];for(let j of z){let x=U1(j);if(x&&typeof x==="object")H.push(x)}if(H.length>0)Q=Math.max(Q,H.length);let V=H.reduce((j,x)=>j+(x.input_tokens??0),0),q=H.reduce((j,x)=>j+(x.output_tokens??0),0),J=V+q,W=H.reduce((j,x)=>j+(x.cost_usd??0),0),M=H.reduce((j,x)=>j+(x.duration_seconds??0),0),G=0,B=0,T=U1(s($,"metrics","budget.json"));if(T&&typeof T==="object"){if(typeof T.budget_limit==="number")G=T.budget_limit;if(typeof T.budget_used==="number")B=T.budget_used}let Y=0,R=0,E=U1(s($,"state","quality-gates.json"));if(E&&typeof E==="object"){if(Array.isArray(E)){for(let j of E)if(R+=1,j===!0)Y+=1;else if(j&&typeof j==="object"){let x=j;if(x.passed===!0||x.status==="passed")Y+=1}}else for(let j of Object.values(E))if(typeof j==="boolean"){if(R+=1,j)Y+=1}else if(j&&typeof j==="object"){R+=1;let x=j;if(x.passed===!0||x.status==="passed")Y+=1}}let C={},w=U1(s($,"quality","gate-failure-count.json"));if(w&&typeof w==="object"&&!Array.isArray(w)){let j={};for(let[x,c]of Object.entries(w))if(typeof c==="number")j[x]=c;C=j}let P=0,f=0,B$=0,y1=s($,"quality");if(d1(y1)){let j=[];try{j=N$(y1)}catch{j=[]}for(let x of j){if(!x.endsWith(".json")||x==="gate-failure-count.json")continue;let c=U1(s(y1,x));if(!c||typeof c!=="object")continue;if(!(("verdict"in c)||("approved"in c)||("reviewers"in c)))continue;P+=1;let M$=(c.verdict??"").toString().toLowerCase();if(c.approved===!0||["approved","approve","pass"].includes(M$))f+=1;else if(["revision","revise","changes_requested","reject"].includes(M$))B$+=1}}return{phase:K,iterationCount:Q,iterations:H,totalInput:V,totalOutput:q,totalTokens:J,totalCost:W,totalDuration:M,budgetLimit:G,budgetUsed:B,gatesPassed:Y,gatesTotal:R,gateFailures:C,reviewsTotal:P,reviewsApproved:f,reviewsRevision:B$}}function s5($,K){let Q=$.iterationCount,X={session:{iterations:Q,duration_seconds:$.totalDuration,phase:$.phase},tokens:{input:$.totalInput,output:$.totalOutput,total:$.totalTokens,cost_usd:r($.totalCost,2)},quality:{gates_passed:$.gatesPassed,gates_total:$.gatesTotal,reviews_total:$.reviewsTotal,reviews_approved:$.reviewsApproved,reviews_revision:$.reviewsRevision,gate_failures:$.gateFailures},efficiency:{avg_tokens_per_iteration:Q>0?r($.totalTokens/Q,0):0,avg_cost_per_iteration:Q>0?r($.totalCost/Q,2):0,avg_duration_per_iteration:Q>0?r($.totalDuration/Q,1):0},budget:{used:r($.budgetUsed,2),limit:$.budgetLimit,percent:$.budgetLimit>0?r($.budgetUsed/$.budgetLimit*100,1):0}};if(K)X.iterations=$.iterations.map((H,V)=>({number:V+1,input_tokens:H.input_tokens??0,output_tokens:H.output_tokens??0,cost_usd:r(H.cost_usd??0,2),duration_seconds:H.duration_seconds??0}));let Z=JSON.stringify(X,null,2);function z(H,V){if(!V)return;let q=new RegExp(`("${H}": )(-?\\d+)(,?)$`,"m");Z=Z.replace(q,(J,W,M,G)=>`${W}${M}.0${G}`)}if(z("avg_duration_per_iteration",Q>0&&Number.isInteger(X.efficiency.avg_duration_per_iteration)),z("percent",$.budgetLimit>0&&Number.isInteger(X.budget.percent)),z("cost_usd",Q>0&&Number.isInteger(X.tokens.cost_usd)),K)Z=Z.replace(/("cost_usd": )(-?\d+)(,?)$/gm,(H,V,q,J)=>`${V}${q}.0${J}`);return Z}function r5($,K){let Q=[];if(Q.push("Loki Mode Session Statistics"),Q.push("============================"),Q.push(""),Q.push("Session"),Q.push(` Iterations completed: ${$.iterationCount}`),Q.push(` Duration: ${p1($.totalDuration)}`),Q.push(` Current phase: ${$.phase}`),Q.push(""),Q.push("Token Usage"),$.iterations.length>0)Q.push(` Input tokens: ${V1($.totalInput)}`),Q.push(` Output tokens: ${V1($.totalOutput)}`),Q.push(` Total tokens: ${V1($.totalTokens)}`),Q.push(` Estimated cost: $${q1($.totalCost,2)}`);else Q.push(" N/A (no iteration metrics found)");if(Q.push(""),Q.push("Quality Gates"),$.gatesTotal>0){let X=Math.round($.gatesPassed/$.gatesTotal*100);Q.push(` Gates passed: ${$.gatesPassed}/${$.gatesTotal} (${X}%)`)}else Q.push(" Gates passed: N/A");if($.reviewsTotal>0){let X=[];if($.reviewsApproved>0)X.push(`${$.reviewsApproved} approved`);if($.reviewsRevision>0)X.push(`${$.reviewsRevision} revision requested`);let Z=X.length>0?X.join(", "):"N/A";Q.push(` Code reviews: ${$.reviewsTotal} (${Z})`)}if(Object.keys($.gateFailures).length>0){let X=Object.entries($.gateFailures).filter(([,Z])=>Z>0).map(([Z,z])=>`${Z} (${z})`);if(X.length>0)Q.push(` Gate failures: ${X.join(", ")}`)}if(Q.push(""),Q.push("Efficiency"),$.iterationCount>0&&$.iterations.length>0){let X=Math.round($.totalTokens/$.iterationCount),Z=$.totalCost/$.iterationCount,z=$.totalDuration/$.iterationCount;Q.push(` Avg tokens/iteration: ${V1(X)}`),Q.push(` Avg cost/iteration: $${q1(Z,2)}`),Q.push(` Avg duration/iteration: ${p1(z)}`)}else Q.push(" N/A (no iteration metrics found)");if(Q.push(""),Q.push("Budget"),$.budgetLimit>0){let X=r($.budgetUsed/$.budgetLimit*100,1),Z=Number.isInteger(X)?`${X}.0`:`${X}`;Q.push(` Used: $${q1($.budgetUsed,2)} / $${q1($.budgetLimit,2)} (${Z}%)`)}else if($.budgetUsed>0)Q.push(` Used: $${q1($.budgetUsed,2)} (no limit set)`);else Q.push(" N/A");if(K&&$.iterations.length>0)Q.push(""),Q.push("Per-Iteration Breakdown"),$.iterations.forEach((X,Z)=>{let z=Z+1,H=l1(V1(X.input_tokens??0),10),V=l1(V1(X.output_tokens??0),10),q=X.cost_usd??0,J=p1(X.duration_seconds??0),W=l1(`${z}`,3);Q.push(` #${W} input: ${H} output: ${V} cost: $${q1(q,2)} time: ${J}`)});return Q.join(`
332
- `)}function C$($){let K=!1,Q=!1;for(let H of $)if(H==="--json")K=!0;else if(H==="--efficiency")Q=!0;let X=L();if(!d1(X)){if(K)return{exitCode:0,stdout:'{"error": "No active session"}'};return{exitCode:0,stdout:`${I}No active session found.${U}
333
- Start a session with: loki start <prd>`}}let Z=a5(X);return{exitCode:0,stdout:K?s5(Z,Q):r5(Z,Q)}}async function t5($){let K=C$($);return console.log(K.stdout),K.exitCode}var b$=F(()=>{v();l()});var l$={};g(l$,{runDoctor:()=>W7,pythonImportOk:()=>a1,httpReachable:()=>o1,checkTool:()=>f$,checkSkills:()=>u$,checkDisk:()=>n1,buildDoctorJson:()=>p$,_setPythonImportOkForTest:()=>Z7});import{existsSync as i5,lstatSync as e5,readlinkSync as $7,statfsSync as K7}from"fs";import{homedir as g$}from"os";import{resolve as y$}from"path";function X7($){let K=$.match(Q7);return K?K[1]:null}async function v$($){try{let K=await k([$,"--version"],{timeoutMs:5000}),Q=(K.stdout||K.stderr||"").trim();return X7(Q)}catch{return null}}function m$($,K){let Q=$.split(".").map((Z)=>parseInt(Z,10)),X=K.split(".").map((Z)=>parseInt(Z,10));while(Q.length<2)Q.push(0);while(X.length<2)X.push(0);for(let Z=0;Z<2;Z++){let z=Q[Z]??0,H=X[Z]??0;if(Number.isNaN(z)||Number.isNaN(H))return 0;if(z!==H)return z-H}return 0}async function f$($,K,Q,X=null){let Z=await m(K),z=Z!==null,H=z?await v$(K):null,V="pass";if(!z)V=Q==="required"?"fail":"warn";else if(X&&H){if(m$(H,X)<0)V=Q==="required"?"fail":"warn"}return{name:$,command:K,found:z,version:H,required:Q,min_version:X,status:V,path:Z}}function n1(){let $=null;try{let Q=K7(g$()),X=Number(Q.bavail)*Number(Q.bsize);$=Math.round(X/1073741824*10)/10}catch{$=null}let K="pass";if($!==null){if($<1)K="fail";else if($<5)K="warn"}return{available_gb:$,status:K}}async function o1($,K=2000){try{return(await fetch($,{signal:AbortSignal.timeout(K)})).ok}catch{return!1}}async function a1($,K=!1){let Q=`import ${$}`,X=K?30000:5000;if(!K)return(await K1(Q,{timeoutMs:X})).exitCode===0;let Z=await Z1();if(!Z)return!1;return(await k([Z,"-c",Q],{timeoutMs:X})).exitCode===0}function Z7($){x1.fn=$??a1}function u$(){let $=g$();return z7.map(({name:K,dir:Q})=>{let X=y$($,Q),Z=X,z=y$(X,"SKILL.md");if(i5(z))return{name:K,path:Z,status:"pass",detail:""};try{if(e5(X).isSymbolicLink()){let V="unknown";try{V=$7(X)}catch{}return{name:K,path:Z,status:"fail",detail:`(broken symlink -> ${V})`}}}catch{}return{name:K,path:Z,status:"warn",detail:"(not found - run 'loki setup-skill')"}})}async function c$(){return Promise.all(H7.map(async($)=>{return{...await f$($.jsonName,$.cmd,$.required,$.min??null),displayName:$.displayName}}))}async function U7(){let K=await m("sentrux")!==null,Q=K?await v$("sentrux"):null;return{found:K,version:Q,status:K?"pass":"warn",required:"optional"}}async function V7(){let{openSync:$,statSync:K,readSync:Q,closeSync:X,existsSync:Z}=await import("fs"),{join:z}=await import("path"),H=65536,V=process.env.LOKI_DIR??".loki",q=z(V,"memory",".errors.log"),J=[],W=!1;try{if(Z(q)){W=!0;let M=K(q).size,G=Math.max(0,M-65536),B=M-G,T=Buffer.alloc(B),Y=$(q,"r");try{Q(Y,T,0,B,G)}finally{X(Y)}let E=T.toString("utf-8").split(`
334
- `);if(G>0&&E.length>0)E=E.slice(1);E=E.map((C)=>C.trim()).filter((C)=>C.length>0),J=E.slice(-5)}}catch{J=[]}return{errors_log_path:W?q:null,recent_errors:J,recent_error_count:J.length,status:J.length===0?"pass":"warn"}}async function p$(){let K=(await c$()).map(({displayName:q,...J})=>J),Q=n1(),X=await U7(),Z=await V7(),z=0,H=0,V=0;for(let q of K)if(q.status==="pass")z++;else if(q.status==="fail")H++;else V++;if(Q.status==="pass")z++;else if(Q.status==="fail")H++;else V++;return{loki_mode_version:I1(),checks:K,disk:Q,sentrux:X,memory:Z,summary:{passed:z,failed:H,warnings:V,ok:H===0}}}function A($){switch($){case"pass":return`${D}PASS${U}`;case"fail":return`${O}FAIL${U}`;case"warn":return`${I}WARN${U}`}}function L1($){let K=$.version?` (v${$.version})`:"",Q=$.displayName;if(!$.found){let X=$.required==="required"?"not found":$.required==="recommended"?"not found (recommended)":"not found (optional)";return` ${A($.status)} ${Q} - ${X}`}if($.min_version&&$.version&&m$($.version,$.min_version)<0){let X=$.required==="required"?"requires":"recommended";return` ${A($.status)} ${Q}${K} - ${X} >= ${$.min_version}`}return` ${A($.status)} ${Q}${K}`}function k1($,K){if(K==="pass")$.pass++;else if(K==="fail")$.fail++;else $.warn++}function q7(){process.stdout.write(`${S}loki doctor${U} - Check system prerequisites
331
+ `;var h$=k(()=>{n();B1();l();m()});var m$={};g(m$,{runStats:()=>q8,computeStats:()=>g$});import{readdirSync as b$,readFileSync as X8,statSync as y$}from"fs";import{join as s}from"path";function W1($){try{if(!y$($).isFile())return null;return JSON.parse(X8($,"utf-8"))}catch{return null}}function a1($){try{return y$($).isDirectory()}catch{return!1}}function U8($){if(!a1($))return[];try{let Q=b$($).filter((K)=>K.startsWith("iteration-")&&K.endsWith(".json"));return Q.sort(),Q.map((K)=>s($,K))}catch{return[]}}function J1($){return Math.trunc($).toLocaleString("en-US")}function o1($){let Q=Math.trunc($);if(Q<60)return`${Q}s`;let K=Math.trunc(Q/3600),Z=Math.trunc(Q%3600/60),z=Q%60;if(K>0)return`${K}h ${String(Z).padStart(2,"0")}m`;return`${Z}m ${String(z).padStart(2,"0")}s`}function r($,Q=0){let K=Math.pow(10,Q);return Math.round($*K)/K}function q1($,Q){return $.toFixed(Q)}function n1($,Q){return $.length>=Q?$:$+" ".repeat(Q-$.length)}function H8($){let Q="N/A",K=0,Z=W1(s($,"state","orchestrator.json"));if(Z&&typeof Z==="object"){if(typeof Z.currentPhase==="string")Q=Z.currentPhase;if(typeof Z.currentIteration==="number")K=Z.currentIteration}let z=s($,"metrics","efficiency"),U=U8(z),X=[];for(let P of U){let R=W1(P);if(R&&typeof R==="object")X.push(R)}if(X.length>0)K=Math.max(K,X.length);let W=X.reduce((P,R)=>P+(R.input_tokens??0),0),J=X.reduce((P,R)=>P+(R.output_tokens??0),0),q=W+J,V=X.reduce((P,R)=>P+(R.cost_usd??0),0),M=X.reduce((P,R)=>P+(R.duration_seconds??0),0),G=0,B=0,T=W1(s($,"metrics","budget.json"));if(T&&typeof T==="object"){if(typeof T.budget_limit==="number")G=T.budget_limit;if(typeof T.budget_used==="number")B=T.budget_used}let Y=0,E=0,S=W1(s($,"state","quality-gates.json"));if(S&&typeof S==="object"){if(Array.isArray(S)){for(let P of S)if(E+=1,P===!0)Y+=1;else if(P&&typeof P==="object"){let R=P;if(R.passed===!0||R.status==="passed")Y+=1}}else for(let P of Object.values(S))if(typeof P==="boolean"){if(E+=1,P)Y+=1}else if(P&&typeof P==="object"){E+=1;let R=P;if(R.passed===!0||R.status==="passed")Y+=1}}let D={},w=W1(s($,"quality","gate-failure-count.json"));if(w&&typeof w==="object"&&!Array.isArray(w)){let P={};for(let[R,c]of Object.entries(w))if(typeof c==="number")P[R]=c;D=P}let j=0,f=0,O$=0,v1=s($,"quality");if(a1(v1)){let P=[];try{P=b$(v1)}catch{P=[]}for(let R of P){if(!R.endsWith(".json")||R==="gate-failure-count.json")continue;let c=W1(s(v1,R));if(!c||typeof c!=="object")continue;if(!(("verdict"in c)||("approved"in c)||("reviewers"in c)))continue;j+=1;let _$=(c.verdict??"").toString().toLowerCase();if(c.approved===!0||["approved","approve","pass"].includes(_$))f+=1;else if(["revision","revise","changes_requested","reject"].includes(_$))O$+=1}}return{phase:Q,iterationCount:K,iterations:X,totalInput:W,totalOutput:J,totalTokens:q,totalCost:V,totalDuration:M,budgetLimit:G,budgetUsed:B,gatesPassed:Y,gatesTotal:E,gateFailures:D,reviewsTotal:j,reviewsApproved:f,reviewsRevision:O$}}function W8($,Q){let K=$.iterationCount,Z={session:{iterations:K,duration_seconds:$.totalDuration,phase:$.phase},tokens:{input:$.totalInput,output:$.totalOutput,total:$.totalTokens,cost_usd:r($.totalCost,2)},quality:{gates_passed:$.gatesPassed,gates_total:$.gatesTotal,reviews_total:$.reviewsTotal,reviews_approved:$.reviewsApproved,reviews_revision:$.reviewsRevision,gate_failures:$.gateFailures},efficiency:{avg_tokens_per_iteration:K>0?r($.totalTokens/K,0):0,avg_cost_per_iteration:K>0?r($.totalCost/K,2):0,avg_duration_per_iteration:K>0?r($.totalDuration/K,1):0},budget:{used:r($.budgetUsed,2),limit:$.budgetLimit,percent:$.budgetLimit>0?r($.budgetUsed/$.budgetLimit*100,1):0}};if(Q)Z.iterations=$.iterations.map((X,W)=>({number:W+1,input_tokens:X.input_tokens??0,output_tokens:X.output_tokens??0,cost_usd:r(X.cost_usd??0,2),duration_seconds:X.duration_seconds??0}));let z=JSON.stringify(Z,null,2);function U(X,W){if(!W)return;let J=new RegExp(`("${X}": )(-?\\d+)(,?)$`,"m");z=z.replace(J,(q,V,M,G)=>`${V}${M}.0${G}`)}if(U("avg_duration_per_iteration",K>0&&Number.isInteger(Z.efficiency.avg_duration_per_iteration)),U("percent",$.budgetLimit>0&&Number.isInteger(Z.budget.percent)),U("cost_usd",K>0&&Number.isInteger(Z.tokens.cost_usd)),Q)z=z.replace(/("cost_usd": )(-?\d+)(,?)$/gm,(X,W,J,q)=>`${W}${J}.0${q}`);return z}function J8($,Q){let K=[];if(K.push("Loki Mode Session Statistics"),K.push("============================"),K.push(""),K.push("Session"),K.push(` Iterations completed: ${$.iterationCount}`),K.push(` Duration: ${o1($.totalDuration)}`),K.push(` Current phase: ${$.phase}`),K.push(""),K.push("Token Usage"),$.iterations.length>0)K.push(` Input tokens: ${J1($.totalInput)}`),K.push(` Output tokens: ${J1($.totalOutput)}`),K.push(` Total tokens: ${J1($.totalTokens)}`),K.push(` Estimated cost: $${q1($.totalCost,2)}`);else K.push(" N/A (no iteration metrics found)");if(K.push(""),K.push("Quality Gates"),$.gatesTotal>0){let Z=Math.round($.gatesPassed/$.gatesTotal*100);K.push(` Gates passed: ${$.gatesPassed}/${$.gatesTotal} (${Z}%)`)}else K.push(" Gates passed: N/A");if($.reviewsTotal>0){let Z=[];if($.reviewsApproved>0)Z.push(`${$.reviewsApproved} approved`);if($.reviewsRevision>0)Z.push(`${$.reviewsRevision} revision requested`);let z=Z.length>0?Z.join(", "):"N/A";K.push(` Code reviews: ${$.reviewsTotal} (${z})`)}if(Object.keys($.gateFailures).length>0){let Z=Object.entries($.gateFailures).filter(([,z])=>z>0).map(([z,U])=>`${z} (${U})`);if(Z.length>0)K.push(` Gate failures: ${Z.join(", ")}`)}if(K.push(""),K.push("Efficiency"),$.iterationCount>0&&$.iterations.length>0){let Z=Math.round($.totalTokens/$.iterationCount),z=$.totalCost/$.iterationCount,U=$.totalDuration/$.iterationCount;K.push(` Avg tokens/iteration: ${J1(Z)}`),K.push(` Avg cost/iteration: $${q1(z,2)}`),K.push(` Avg duration/iteration: ${o1(U)}`)}else K.push(" N/A (no iteration metrics found)");if(K.push(""),K.push("Budget"),$.budgetLimit>0){let Z=r($.budgetUsed/$.budgetLimit*100,1),z=Number.isInteger(Z)?`${Z}.0`:`${Z}`;K.push(` Used: $${q1($.budgetUsed,2)} / $${q1($.budgetLimit,2)} (${z}%)`)}else if($.budgetUsed>0)K.push(` Used: $${q1($.budgetUsed,2)} (no limit set)`);else K.push(" N/A");if(Q&&$.iterations.length>0)K.push(""),K.push("Per-Iteration Breakdown"),$.iterations.forEach((Z,z)=>{let U=z+1,X=n1(J1(Z.input_tokens??0),10),W=n1(J1(Z.output_tokens??0),10),J=Z.cost_usd??0,q=o1(Z.duration_seconds??0),V=n1(`${U}`,3);K.push(` #${V} input: ${X} output: ${W} cost: $${q1(J,2)} time: ${q}`)});return K.join(`
332
+ `)}function g$($){let Q=!1,K=!1;for(let X of $)if(X==="--json")Q=!0;else if(X==="--efficiency")K=!0;let Z=L();if(!a1(Z)){if(Q)return{exitCode:0,stdout:'{"error": "No active session"}'};return{exitCode:0,stdout:`${I}No active session found.${H}
333
+ Start a session with: loki start <prd>`}}let z=H8(Z);return{exitCode:0,stdout:Q?W8(z,K):J8(z,K)}}async function q8($){let Q=g$($);return console.log(Q.stdout),Q.exitCode}var v$=k(()=>{m();l()});var a$={};g(a$,{runDoctor:()=>k8,pythonImportOk:()=>t1,httpReachable:()=>s1,checkTool:()=>l$,checkSkills:()=>d$,checkDisk:()=>r1,buildDoctorJson:()=>n$,_setPythonImportOkForTest:()=>O8});import{existsSync as V8,lstatSync as G8,readlinkSync as B8,statfsSync as M8}from"fs";import{homedir as u$}from"os";import{resolve as f$}from"path";function T8($){let Q=$.match(Y8);return Q?Q[1]:null}async function c$($){try{let Q=await F([$,"--version"],{timeoutMs:5000}),K=(Q.stdout||Q.stderr||"").trim();return T8(K)}catch{return null}}function p$($,Q){let K=$.split(".").map((z)=>parseInt(z,10)),Z=Q.split(".").map((z)=>parseInt(z,10));while(K.length<2)K.push(0);while(Z.length<2)Z.push(0);for(let z=0;z<2;z++){let U=K[z]??0,X=Z[z]??0;if(Number.isNaN(U)||Number.isNaN(X))return 0;if(U!==X)return U-X}return 0}async function l$($,Q,K,Z=null){let z=await v(Q),U=z!==null,X=U?await c$(Q):null,W="pass";if(!U)W=K==="required"?"fail":"warn";else if(Z&&X){if(p$(X,Z)<0)W=K==="required"?"fail":"warn"}return{name:$,command:Q,found:U,version:X,required:K,min_version:Z,status:W,path:z}}function r1(){let $=null;try{let K=M8(u$()),Z=Number(K.bavail)*Number(K.bsize);$=Math.round(Z/1073741824*10)/10}catch{$=null}let Q="pass";if($!==null){if($<1)Q="fail";else if($<5)Q="warn"}return{available_gb:$,status:Q}}async function s1($,Q=2000){try{return(await fetch($,{signal:AbortSignal.timeout(Q)})).ok}catch{return!1}}async function t1($,Q=!1){let K=`import ${$}`,Z=Q?30000:5000;if(!Q)return(await Q1(K,{timeoutMs:Z})).exitCode===0;let z=await X1();if(!z)return!1;return(await F([z,"-c",K],{timeoutMs:Z})).exitCode===0}function O8($){E1.fn=$??t1}function d$(){let $=u$();return _8.map(({name:Q,dir:K})=>{let Z=f$($,K),z=Z,U=f$(Z,"SKILL.md");if(V8(U))return{name:Q,path:z,status:"pass",detail:""};try{if(G8(Z).isSymbolicLink()){let W="unknown";try{W=B8(Z)}catch{}return{name:Q,path:z,status:"fail",detail:`(broken symlink -> ${W})`}}}catch{}return{name:Q,path:z,status:"warn",detail:"(not found - run 'loki setup-skill')"}})}async function o$(){return Promise.all(A8.map(async($)=>{return{...await l$($.jsonName,$.cmd,$.required,$.min??null),displayName:$.displayName}}))}async function w8(){let Q=await v("sentrux")!==null,K=Q?await c$("sentrux"):null;return{found:Q,version:K,status:Q?"pass":"warn",required:"optional"}}async function I8(){let{openSync:$,statSync:Q,readSync:K,closeSync:Z,existsSync:z}=await import("fs"),{join:U}=await import("path"),X=65536,W=process.env.LOKI_DIR??".loki",J=U(W,"memory",".errors.log"),q=[],V=!1;try{if(z(J)){V=!0;let M=Q(J).size,G=Math.max(0,M-65536),B=M-G,T=Buffer.alloc(B),Y=$(J,"r");try{K(Y,T,0,B,G)}finally{Z(Y)}let S=T.toString("utf-8").split(`
334
+ `);if(G>0&&S.length>0)S=S.slice(1);S=S.map((D)=>D.trim()).filter((D)=>D.length>0),q=S.slice(-5)}}catch{q=[]}return{errors_log_path:V?J:null,recent_errors:q,recent_error_count:q.length,status:q.length===0?"pass":"warn"}}async function n$(){let Q=(await o$()).map(({displayName:J,...q})=>q),K=r1(),Z=await w8(),z=await I8(),U=0,X=0,W=0;for(let J of Q)if(J.status==="pass")U++;else if(J.status==="fail")X++;else W++;if(K.status==="pass")U++;else if(K.status==="fail")X++;else W++;return{loki_mode_version:L1(),checks:Q,disk:K,sentrux:Z,memory:z,summary:{passed:U,failed:X,warnings:W,ok:X===0}}}function _($){switch($){case"pass":return`${C}PASS${H}`;case"fail":return`${O}FAIL${H}`;case"warn":return`${I}WARN${H}`}}function F1($){let Q=$.version?` (v${$.version})`:"",K=$.displayName;if(!$.found){let Z=$.required==="required"?"not found":$.required==="recommended"?"not found (recommended)":"not found (optional)";return` ${_($.status)} ${K} - ${Z}`}if($.min_version&&$.version&&p$($.version,$.min_version)<0){let Z=$.required==="required"?"requires":"recommended";return` ${_($.status)} ${K}${Q} - ${Z} >= ${$.min_version}`}return` ${_($.status)} ${K}${Q}`}function R1($,Q){if(Q==="pass")$.pass++;else if(Q==="fail")$.fail++;else $.warn++}function P8(){process.stdout.write(`${x}loki doctor${H} - Check system prerequisites
335
335
 
336
336
  `),process.stdout.write(`Usage: loki doctor [--json]
337
337
 
@@ -340,84 +340,84 @@ Start a session with: loki start <prd>`}}let Z=a5(X);return{exitCode:0,stdout:K?
340
340
 
341
341
  `),process.stdout.write(`Checks: node, python3, jq, git, curl, bash version,
342
342
  `),process.stdout.write(` claude/codex CLIs, and disk space.
343
- `)}async function J7(){process.stdout.write(`${S}Loki Mode Doctor${U}
343
+ `)}async function L8(){process.stdout.write(`${x}Loki Mode Doctor${H}
344
344
 
345
345
  `),process.stdout.write(`Checking system prerequisites...
346
346
 
347
- `);let $={pass:0,fail:0,warn:0},K=await c$(),Q=new Map(K.map((w)=>[w.command,w]));process.stdout.write(`${_}Required:${U}
348
- `);for(let w of["node","python3","jq","git","curl"]){let P=Q.get(w);process.stdout.write(L1(P)+`
349
- `),k1($,P.status)}process.stdout.write(`
350
- `),process.stdout.write(`${_}AI Providers:${U}
351
- `);let X=["claude","codex","cline","aider"],Z=!1;for(let w of X){let P=Q.get(w);if(process.stdout.write(L1(P)+`
352
- `),k1($,P.status),P.found)Z=!0}if(!Z)process.stdout.write(` ${A("fail")} No AI provider CLI installed -- at least one is required
353
- `),process.stdout.write(` ${I}Install: npm install -g @anthropic-ai/claude-code${U}
347
+ `);let $={pass:0,fail:0,warn:0},Q=await o$(),K=new Map(Q.map((w)=>[w.command,w]));process.stdout.write(`${A}Required:${H}
348
+ `);for(let w of["node","python3","jq","git","curl"]){let j=K.get(w);process.stdout.write(F1(j)+`
349
+ `),R1($,j.status)}process.stdout.write(`
350
+ `),process.stdout.write(`${A}AI Providers:${H}
351
+ `);let Z=["claude","codex","cline","aider"],z=!1;for(let w of Z){let j=K.get(w);if(process.stdout.write(F1(j)+`
352
+ `),R1($,j.status),j.found)z=!0}if(!z)process.stdout.write(` ${_("fail")} No AI provider CLI installed -- at least one is required
353
+ `),process.stdout.write(` ${I}Install: npm install -g @anthropic-ai/claude-code${H}
354
354
  `),$.fail++;process.stdout.write(`
355
- `),process.stdout.write(`${_}API Keys:${U}
356
- `);let z=Q.get("claude")?.found??!1,H=Q.get("codex")?.found??!1,V=process.env;if(V.ANTHROPIC_API_KEY)process.stdout.write(` ${A("pass")} ANTHROPIC_API_KEY is set
357
- `),$.pass++;else if(z)process.stdout.write(` ${h} -- ${U} ANTHROPIC_API_KEY not set (Claude CLI uses its own login)
358
- `);if(V.OPENAI_API_KEY)process.stdout.write(` ${A("pass")} OPENAI_API_KEY is set
359
- `),$.pass++;else if(H)process.stdout.write(` ${h} -- ${U} OPENAI_API_KEY not set (Codex CLI uses its own login)
360
- `);if(V.ANTHROPIC_BASE_URL){let w=V.ANTHROPIC_BASE_URL;if(process.stdout.write(` ${A("pass")} ANTHROPIC_BASE_URL: ${w}
361
- `),$.pass++,!V.LOKI_MODEL_OVERRIDE)process.stdout.write(` ${A("warn")} LOKI_MODEL_OVERRIDE not set -- opus/sonnet/haiku aliases may not resolve on alt-provider
362
- `),$.warn++;else process.stdout.write(` ${A("pass")} LOKI_MODEL_OVERRIDE: ${V.LOKI_MODEL_OVERRIDE}
355
+ `),process.stdout.write(`${A}API Keys:${H}
356
+ `);let U=K.get("claude")?.found??!1,X=K.get("codex")?.found??!1,W=process.env;if(W.ANTHROPIC_API_KEY)process.stdout.write(` ${_("pass")} ANTHROPIC_API_KEY is set
357
+ `),$.pass++;else if(U)process.stdout.write(` ${h} -- ${H} ANTHROPIC_API_KEY not set (Claude CLI uses its own login)
358
+ `);if(W.OPENAI_API_KEY)process.stdout.write(` ${_("pass")} OPENAI_API_KEY is set
359
+ `),$.pass++;else if(X)process.stdout.write(` ${h} -- ${H} OPENAI_API_KEY not set (Codex CLI uses its own login)
360
+ `);if(W.ANTHROPIC_BASE_URL){let w=W.ANTHROPIC_BASE_URL;if(process.stdout.write(` ${_("pass")} ANTHROPIC_BASE_URL: ${w}
361
+ `),$.pass++,!W.LOKI_MODEL_OVERRIDE)process.stdout.write(` ${_("warn")} LOKI_MODEL_OVERRIDE not set -- opus/sonnet/haiku aliases may not resolve on alt-provider
362
+ `),$.warn++;else process.stdout.write(` ${_("pass")} LOKI_MODEL_OVERRIDE: ${W.LOKI_MODEL_OVERRIDE}
363
363
  `),$.pass++}process.stdout.write(`
364
- `),process.stdout.write(`${_}Skills:${U}
365
- `);for(let w of u$())if(w.status==="pass")process.stdout.write(` ${A("pass")} ${w.name} ${h}${w.path}${U}
366
- `),$.pass++;else if(w.status==="fail")process.stdout.write(` ${A("fail")} ${w.name} ${h}${w.detail}${U}
367
- `),process.stdout.write(` ${I}Fix: loki setup-skill${U}
368
- `),$.fail++;else process.stdout.write(` ${A("warn")} ${w.name} ${h}${w.detail}${U}
364
+ `),process.stdout.write(`${A}Skills:${H}
365
+ `);for(let w of d$())if(w.status==="pass")process.stdout.write(` ${_("pass")} ${w.name} ${h}${w.path}${H}
366
+ `),$.pass++;else if(w.status==="fail")process.stdout.write(` ${_("fail")} ${w.name} ${h}${w.detail}${H}
367
+ `),process.stdout.write(` ${I}Fix: loki setup-skill${H}
368
+ `),$.fail++;else process.stdout.write(` ${_("warn")} ${w.name} ${h}${w.detail}${H}
369
369
  `),$.warn++;process.stdout.write(`
370
- `),process.stdout.write(`${_}Integrations:${U}
371
- `);let[q,J,W]=await Promise.all([x1.fn("mcp"),x1.fn("numpy",!0),x1.fn("sentence_transformers",!0)]);if(q)process.stdout.write(` ${A("pass")} MCP SDK (Python)
372
- `),$.pass++;else process.stdout.write(` ${A("warn")} MCP SDK - not installed (pip3 install mcp)
373
- `),$.warn++;if(J)process.stdout.write(` ${A("pass")} numpy (vector search)
374
- `),$.pass++;else process.stdout.write(` ${A("warn")} numpy - not installed (pip3 install numpy)
375
- `),$.warn++;if(W)process.stdout.write(` ${A("pass")} sentence-transformers (embeddings)
376
- `),$.pass++;else process.stdout.write(` ${A("warn")} sentence-transformers - not installed (loki memory vectors setup)
377
- `),$.warn++;if(await o1("http://localhost:8100/api/v2/heartbeat"))process.stdout.write(` ${A("pass")} ChromaDB server (port 8100)
378
- `),$.pass++;else process.stdout.write(` ${A("warn")} ChromaDB - not running (docker start loki-chroma)
379
- `),$.warn++;{let w=["pyright-langserver","pylsp","typescript-language-server","gopls","rust-analyzer","jdtls"],P=[];for(let f of w)if(await m(f))P.push(f);if(P.length>0)process.stdout.write(` ${A("pass")} LSP servers detected (${P.length}): ${P.join(", ")}
380
- `),$.pass++;else process.stdout.write(` ${A("warn")} LSP servers - none on PATH (install for symbol grounding: npm i -g pyright typescript-language-server; brew install gopls)
381
- `),$.warn++}let M=process.env.LOKI_MIROFISH_URL;if(M)if(await o1(`${M}/health`))process.stdout.write(` ${A("pass")} MiroFish server (${M})
382
- `),$.pass++;else process.stdout.write(` ${A("warn")} MiroFish - not running (loki start --mirofish-docker <image>)
383
- `),$.warn++;if(process.env.LOKI_OTEL_ENDPOINT)process.stdout.write(` ${A("pass")} OTEL endpoint: ${process.env.LOKI_OTEL_ENDPOINT}
384
- `),$.pass++;else process.stdout.write(` ${A("warn")} OTEL - not configured (set LOKI_OTEL_ENDPOINT)
385
- `),$.warn++;if(await m("sentrux")){let w="unknown";try{let f=(await k(["sentrux","--version"],{timeoutMs:2000})).stdout.split(/\s+/).filter(Boolean).pop();if(f)w=f.replace(/^v/,"")}catch{}process.stdout.write(` ${A("pass")} sentrux ${w} (architectural drift gate: loki sentrux help)
386
- `),$.pass++}else process.stdout.write(` ${A("warn")} sentrux - not installed (optional, brew install sentrux/tap/sentrux)
370
+ `),process.stdout.write(`${A}Integrations:${H}
371
+ `);let[J,q,V]=await Promise.all([E1.fn("mcp"),E1.fn("numpy",!0),E1.fn("sentence_transformers",!0)]);if(J)process.stdout.write(` ${_("pass")} MCP SDK (Python)
372
+ `),$.pass++;else process.stdout.write(` ${_("warn")} MCP SDK - not installed (pip3 install mcp)
373
+ `),$.warn++;if(q)process.stdout.write(` ${_("pass")} numpy (vector search)
374
+ `),$.pass++;else process.stdout.write(` ${_("warn")} numpy - not installed (pip3 install numpy)
375
+ `),$.warn++;if(V)process.stdout.write(` ${_("pass")} sentence-transformers (embeddings)
376
+ `),$.pass++;else process.stdout.write(` ${_("warn")} sentence-transformers - not installed (loki memory vectors setup)
377
+ `),$.warn++;if(await s1("http://localhost:8100/api/v2/heartbeat"))process.stdout.write(` ${_("pass")} ChromaDB server (port 8100)
378
+ `),$.pass++;else process.stdout.write(` ${_("warn")} ChromaDB - not running (docker start loki-chroma)
379
+ `),$.warn++;{let w=["pyright-langserver","pylsp","typescript-language-server","gopls","rust-analyzer","jdtls"],j=[];for(let f of w)if(await v(f))j.push(f);if(j.length>0)process.stdout.write(` ${_("pass")} LSP servers detected (${j.length}): ${j.join(", ")}
380
+ `),$.pass++;else process.stdout.write(` ${_("warn")} LSP servers - none on PATH (install for symbol grounding: npm i -g pyright typescript-language-server; brew install gopls)
381
+ `),$.warn++}let M=process.env.LOKI_MIROFISH_URL;if(M)if(await s1(`${M}/health`))process.stdout.write(` ${_("pass")} MiroFish server (${M})
382
+ `),$.pass++;else process.stdout.write(` ${_("warn")} MiroFish - not running (loki start --mirofish-docker <image>)
383
+ `),$.warn++;if(process.env.LOKI_OTEL_ENDPOINT)process.stdout.write(` ${_("pass")} OTEL endpoint: ${process.env.LOKI_OTEL_ENDPOINT}
384
+ `),$.pass++;else process.stdout.write(` ${_("warn")} OTEL - not configured (set LOKI_OTEL_ENDPOINT)
385
+ `),$.warn++;if(await v("sentrux")){let w="unknown";try{let f=(await F(["sentrux","--version"],{timeoutMs:2000})).stdout.split(/\s+/).filter(Boolean).pop();if(f)w=f.replace(/^v/,"")}catch{}process.stdout.write(` ${_("pass")} sentrux ${w} (architectural drift gate: loki sentrux help)
386
+ `),$.pass++}else process.stdout.write(` ${_("warn")} sentrux - not installed (optional, brew install sentrux/tap/sentrux)
387
387
  `),$.warn++;process.stdout.write(`
388
- `),process.stdout.write(`${_}System:${U}
389
- `);let G=Q.get("bash");process.stdout.write(L1(G)+`
390
- `),k1($,G.status);let B=Q.get("bun");if(B)process.stdout.write(L1(B)+`
391
- `),k1($,B.status);let T=n1(),Y=T.available_gb===null?null:Math.floor(T.available_gb);if(Y===null)process.stdout.write(` ${A("warn")} Disk space: unable to determine
392
- `),$.warn++;else if(T.status==="fail")process.stdout.write(` ${A("fail")} Disk space: ${Y}GB available (need >= 1GB)
393
- `),$.fail++;else if(T.status==="warn")process.stdout.write(` ${A("warn")} Disk space: ${Y}GB available (low)
394
- `),$.warn++;else process.stdout.write(` ${A("pass")} Disk space: ${Y}GB available
388
+ `),process.stdout.write(`${A}System:${H}
389
+ `);let G=K.get("bash");process.stdout.write(F1(G)+`
390
+ `),R1($,G.status);let B=K.get("bun");if(B)process.stdout.write(F1(B)+`
391
+ `),R1($,B.status);let T=r1(),Y=T.available_gb===null?null:Math.floor(T.available_gb);if(Y===null)process.stdout.write(` ${_("warn")} Disk space: unable to determine
392
+ `),$.warn++;else if(T.status==="fail")process.stdout.write(` ${_("fail")} Disk space: ${Y}GB available (need >= 1GB)
393
+ `),$.fail++;else if(T.status==="warn")process.stdout.write(` ${_("warn")} Disk space: ${Y}GB available (low)
394
+ `),$.warn++;else process.stdout.write(` ${_("pass")} Disk space: ${Y}GB available
395
395
  `),$.pass++;process.stdout.write(`
396
- `),process.stdout.write(`${_}Runtime route:${U}
397
- `);let R=process.versions.bun!==void 0,E=process.argv[0]??"(unknown)";if(process.stdout.write(` ${A("pass")} Active runtime: ${R?"Bun":"Node"} (${E})
398
- `),process.env.LOKI_LEGACY_BASH==="1"||process.env.LOKI_LEGACY_BASH==="true")process.stdout.write(` ${A("warn")} LOKI_LEGACY_BASH set: shim routes every command to autonomy/loki (bash)
399
- `);if(process.env.LOKI_TS_ENTRY)process.stdout.write(` ${A("pass")} LOKI_TS_ENTRY override: ${process.env.LOKI_TS_ENTRY}
400
- `);if(process.env.BUN_FROM_SOURCE==="1"||process.env.BUN_FROM_SOURCE==="true")process.stdout.write(` ${A("pass")} BUN_FROM_SOURCE set: shim prefers loki-ts/src/ over dist/
401
- `);let C=await Z1();if(C!==null){let P=(await k([C,"-c","import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}')"],{timeoutMs:5000})).stdout.trim();if(P.startsWith("3.12"))process.stdout.write(` ${A("pass")} Python 3.12 (chromadb / sentence-transformers): ${P} at ${C}
402
- `);else if(P)process.stdout.write(` ${A("warn")} Python 3.12 NOT found -- using ${P} at ${C}; chromadb / sentence-transformers may fail. Install python3.12 (brew install python@3.12 / apt install python3.12).
403
- `);else process.stdout.write(` ${A("warn")} Python 3 found at ${C} but version probe failed; chromadb may not work.
404
- `)}else process.stdout.write(` ${A("warn")} Python 3 not on PATH -- memory + MCP integrations disabled.
396
+ `),process.stdout.write(`${A}Runtime route:${H}
397
+ `);let E=process.versions.bun!==void 0,S=process.argv[0]??"(unknown)";if(process.stdout.write(` ${_("pass")} Active runtime: ${E?"Bun":"Node"} (${S})
398
+ `),process.env.LOKI_LEGACY_BASH==="1"||process.env.LOKI_LEGACY_BASH==="true")process.stdout.write(` ${_("warn")} LOKI_LEGACY_BASH set: shim routes every command to autonomy/loki (bash)
399
+ `);if(process.env.LOKI_TS_ENTRY)process.stdout.write(` ${_("pass")} LOKI_TS_ENTRY override: ${process.env.LOKI_TS_ENTRY}
400
+ `);if(process.env.BUN_FROM_SOURCE==="1"||process.env.BUN_FROM_SOURCE==="true")process.stdout.write(` ${_("pass")} BUN_FROM_SOURCE set: shim prefers loki-ts/src/ over dist/
401
+ `);let D=await X1();if(D!==null){let j=(await F([D,"-c","import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}')"],{timeoutMs:5000})).stdout.trim();if(j.startsWith("3.12"))process.stdout.write(` ${_("pass")} Python 3.12 (chromadb / sentence-transformers): ${j} at ${D}
402
+ `);else if(j)process.stdout.write(` ${_("warn")} Python 3.12 NOT found -- using ${j} at ${D}; chromadb / sentence-transformers may fail. Install python3.12 (brew install python@3.12 / apt install python3.12).
403
+ `);else process.stdout.write(` ${_("warn")} Python 3 found at ${D} but version probe failed; chromadb may not work.
404
+ `)}else process.stdout.write(` ${_("warn")} Python 3 not on PATH -- memory + MCP integrations disabled.
405
405
  `);if(process.stdout.write(`
406
- `),process.stdout.write(`${S}Summary:${U} ${D}${$.pass} passed${U}, ${O}${$.fail} failed${U}, ${I}${$.warn} warnings${U}
406
+ `),process.stdout.write(`${x}Summary:${H} ${C}${$.pass} passed${H}, ${O}${$.fail} failed${H}, ${I}${$.warn} warnings${H}
407
407
 
408
- `),$.fail>0)return process.stdout.write(`${O}Some required prerequisites are missing.${U}
408
+ `),$.fail>0)return process.stdout.write(`${O}Some required prerequisites are missing.${H}
409
409
  `),process.stdout.write(`Install missing dependencies and run 'loki doctor' again.
410
- `),1;if($.warn>0)return process.stdout.write(`${I}All required checks passed with some warnings.${U}
411
- `),0;return process.stdout.write(`${D}All checks passed. System is ready for Loki Mode.${U}
412
- `),0}async function W7($){let K=!1;for(let Q of $)if(Q==="--json")K=!0;else if(Q==="--help"||Q==="-h")return q7(),0;else return process.stderr.write(`${O}Unknown option: ${Q}${U}
410
+ `),1;if($.warn>0)return process.stdout.write(`${I}All required checks passed with some warnings.${H}
411
+ `),0;return process.stdout.write(`${C}All checks passed. System is ready for Loki Mode.${H}
412
+ `),0}async function k8($){let Q=!1;for(let K of $)if(K==="--json")Q=!0;else if(K==="--help"||K==="-h")return P8(),0;else return process.stderr.write(`${O}Unknown option: ${K}${H}
413
413
  `),process.stderr.write(`Usage: loki doctor [--json]
414
- `),1;if(K){let Q=await p$();return process.stdout.write(JSON.stringify(Q,null,2)+`
415
- `),0}return J7()}var Q7,x1,z7,H7;var d$=F(()=>{n();G1();l();f1();Q7=/(\d+\.\d+(?:\.\d+)*)/;x1={fn:a1};z7=[{name:"Claude Code",dir:".claude/skills/loki-mode"},{name:"Codex CLI",dir:".codex/skills/loki-mode"},{name:"Cline CLI",dir:".cline/skills/loki-mode"},{name:"Aider CLI",dir:".aider/skills/loki-mode"}];H7=[{displayName:"Node.js (>= 18)",jsonName:"Node.js",cmd:"node",required:"required",min:"18.0"},{displayName:"Python 3 (>= 3.8)",jsonName:"Python 3",cmd:"python3",required:"required",min:"3.8"},{displayName:"jq",jsonName:"jq",cmd:"jq",required:"required"},{displayName:"git",jsonName:"git",cmd:"git",required:"required"},{displayName:"curl",jsonName:"curl",cmd:"curl",required:"required"},{displayName:"bash (>= 4.0)",jsonName:"bash",cmd:"bash",required:"recommended",min:"4.0"},{displayName:"Bun (>= 1.3)",jsonName:"Bun",cmd:"bun",required:"recommended",min:"1.3"},{displayName:"Claude CLI",jsonName:"Claude CLI",cmd:"claude",required:"optional"},{displayName:"Codex CLI",jsonName:"Codex CLI",cmd:"codex",required:"optional"},{displayName:"Cline CLI",jsonName:"Cline CLI",cmd:"cline",required:"optional"},{displayName:"Aider CLI",jsonName:"Aider CLI",cmd:"aider",required:"optional"}]});import{existsSync as a$,mkdirSync as L6,readdirSync as G7,readFileSync as s$,renameSync as k6,writeFileSync as x6}from"fs";import{dirname as B7,join as M7,resolve as Y7}from"path";import{fileURLToPath as T7}from"url";function O7(){try{let $=B7(T7(import.meta.url)),K=Y7($,"..","..","data","model-pricing.json");if(!a$(K))return M1;let X=JSON.parse(s$(K,"utf8")).pricing;if(!X||typeof X!=="object")return M1;let Z={};for(let[z,H]of Object.entries(X))if(H!==null&&typeof H==="object"&&typeof H.input==="number"&&typeof H.output==="number")Z[z]={input:H.input,output:H.output};for(let z of Object.keys(M1))if(!(z in Z))return M1;return Z}catch{return M1}}function A7($){return Math.round(($+Number.EPSILON)*1e4)/1e4}function _7($){let K=($??n$).toLowerCase();return o$[K]??o$[n$]}function r$($){let K=0;for(let Q of $){if(typeof Q.cost_usd==="number"&&Number.isFinite(Q.cost_usd)){K+=Q.cost_usd;continue}let X=_7(Q.model),Z=typeof Q.input_tokens==="number"?Q.input_tokens:0,z=typeof Q.output_tokens==="number"?Q.output_tokens:0;K+=Z/1e6*X.input+z/1e6*X.output}return A7(K)}function t$($){if(!a$($))return[];let K=[],Q;try{Q=G7($)}catch{return[]}for(let X of Q){if(!X.endsWith(".json"))continue;let Z=M7($,X);try{let z=s$(Z,"utf8"),H=JSON.parse(z);if(H&&typeof H==="object")K.push(H)}catch{}}return K}var M1,o$,n$="sonnet";var i$=F(()=>{v();M1={opus:{input:5,output:25},sonnet:{input:3,output:15},haiku:{input:1,output:5},"gpt-5.3-codex":{input:1.5,output:12}};o$=Object.freeze(O7())});import{existsSync as F1,readdirSync as w7,readFileSync as I7,statSync as j7}from"fs";import{join as R1}from"path";function P7($){let K=[],Q=R1($,"votes");if(!F1(Q))return K;let X;try{X=w7(Q)}catch{return K}for(let Z of X){if(!Z.startsWith("round-")||!Z.endsWith(".json"))continue;try{let z=R1(Q,Z);if(!j7(z).isFile())continue;let H=JSON.parse(I7(z,"utf8"));K.push({iteration:typeof H.iteration==="number"?H.iteration:void 0,verdict:typeof H.verdict==="string"?H.verdict:void 0,complete_votes:typeof H.complete_votes==="number"?H.complete_votes:void 0,total_members:typeof H.total_members==="number"?H.total_members:void 0,threshold:typeof H.threshold==="number"?H.threshold:void 0})}catch{}}return K}function L7(){return{iteration_count:0,total_cost_usd:0,avg_cost_per_iteration:null,total_input_tokens:0,total_output_tokens:0,total_duration_ms:0,avg_duration_ms_per_iteration:null,model_breakdown:{},phase_breakdown:{},status_breakdown:{}}}function k7(){return{council_rounds:0,unanimous_rate:null,approval_rate:null,iteration_success_rate:null}}function x7($){let K=L7();if($.length===0)return K;K.iteration_count=$.length,K.total_cost_usd=Math.round(r$($)*1e4)/1e4;for(let Q of $){if(typeof Q.input_tokens==="number")K.total_input_tokens+=Q.input_tokens;if(typeof Q.output_tokens==="number")K.total_output_tokens+=Q.output_tokens;let X=Q;if(typeof X.duration_ms==="number")K.total_duration_ms+=X.duration_ms;if(typeof Q.model==="string")K.model_breakdown[Q.model]=(K.model_breakdown[Q.model]??0)+1;if(typeof X.phase==="string")K.phase_breakdown[X.phase]=(K.phase_breakdown[X.phase]??0)+1;if(typeof X.status==="string")K.status_breakdown[X.status]=(K.status_breakdown[X.status]??0)+1}return K.avg_cost_per_iteration=Math.round(K.total_cost_usd/K.iteration_count*1e4)/1e4,K.avg_duration_ms_per_iteration=Math.round(K.total_duration_ms/K.iteration_count),K}function F7($,K,Q){let X=k7();if(X.council_rounds=$.length,$.length>0){let Z=0,z=0;for(let H of $){if(typeof H.complete_votes==="number"&&typeof H.total_members==="number"&&H.total_members>0&&H.complete_votes===H.total_members)Z+=1;if(H.verdict==="COMPLETE")z+=1}X.unanimous_rate=Math.round(Z/$.length*1e4)/1e4,X.approval_rate=Math.round(z/$.length*1e4)/1e4}if(Q>0)X.iteration_success_rate=Math.round(K/Q*1e4)/1e4;return X}function e$($){let K=[],Q=R1($,"metrics","efficiency"),X=R1($,"council"),Z=F1(Q)?t$(Q):[];if(!F1(Q))K.push("no .loki/metrics/efficiency/ dir (efficiency KPIs zeroed)");else if(Z.length===0)K.push(".loki/metrics/efficiency/ exists but no iteration files found");let z=P7(X);if(!F1(X))K.push("no .loki/council/ dir (accuracy KPIs zeroed)");else if(z.length===0)K.push(".loki/council/ exists but no round-N.json files found");let H=x7(Z),V=H.status_breakdown.success??0,q=F7(z,V,H.iteration_count);return{schema_version:1,generated_at:new Date().toISOString(),loki_dir:$,efficiency:H,accuracy:q,notes:K}}function $0($){return JSON.stringify($,null,2)}function K0($){let K=[];K.push(`Loki Mode KPIs (snapshot at ${$.generated_at})`),K.push(`Source: ${$.loki_dir}`),K.push(""),K.push("Efficiency"),K.push(` Iterations: ${$.efficiency.iteration_count}`),K.push(` Total cost USD: ${$.efficiency.total_cost_usd}`),K.push(` Avg cost per iter: ${$.efficiency.avg_cost_per_iteration??"n/a"}`),K.push(` Total input tokens: ${$.efficiency.total_input_tokens}`),K.push(` Total output tokens: ${$.efficiency.total_output_tokens}`),K.push(` Total duration (ms): ${$.efficiency.total_duration_ms}`),K.push(` Avg duration / iter: ${$.efficiency.avg_duration_ms_per_iteration??"n/a"}`);let Q=Object.entries($.efficiency.model_breakdown).sort((z,H)=>z[0].localeCompare(H[0]));if(Q.length>0)K.push(` Model breakdown: ${Q.map(([z,H])=>`${z}=${H}`).join(", ")}`);let X=Object.entries($.efficiency.phase_breakdown).sort((z,H)=>z[0].localeCompare(H[0]));if(X.length>0)K.push(` Phase breakdown: ${X.map(([z,H])=>`${z}=${H}`).join(", ")}`);let Z=Object.entries($.efficiency.status_breakdown).sort((z,H)=>z[0].localeCompare(H[0]));if(Z.length>0)K.push(` Status breakdown: ${Z.map(([z,H])=>`${z}=${H}`).join(", ")}`);if(K.push(""),K.push("Accuracy"),K.push(` Council rounds: ${$.accuracy.council_rounds}`),K.push(` Unanimous rate: ${$.accuracy.unanimous_rate??"n/a"}`),K.push(` Approval rate: ${$.accuracy.approval_rate??"n/a"}`),K.push(` Iter success rate: ${$.accuracy.iteration_success_rate??"n/a"}`),$.notes.length>0){K.push(""),K.push("Notes");for(let z of $.notes)K.push(` - ${z}`)}return K.join(`
416
- `)}var Q0=F(()=>{i$()});var X0={};g(X0,{runKpis:()=>E7});function E7($){let K=!1;for(let X of $){if(X==="--help"||X==="-h"||X==="help")return process.stdout.write(R7),0;if(X==="--json"){K=!0;continue}return process.stderr.write(`loki kpis: unknown arg: ${X}
414
+ `),1;if(Q){let K=await n$();return process.stdout.write(JSON.stringify(K,null,2)+`
415
+ `),0}return L8()}var Y8,E1,_8,A8;var s$=k(()=>{n();B1();l();p1();Y8=/(\d+\.\d+(?:\.\d+)*)/;E1={fn:t1};_8=[{name:"Claude Code",dir:".claude/skills/loki-mode"},{name:"Codex CLI",dir:".codex/skills/loki-mode"},{name:"Cline CLI",dir:".cline/skills/loki-mode"},{name:"Aider CLI",dir:".aider/skills/loki-mode"}];A8=[{displayName:"Node.js (>= 18)",jsonName:"Node.js",cmd:"node",required:"required",min:"18.0"},{displayName:"Python 3 (>= 3.8)",jsonName:"Python 3",cmd:"python3",required:"required",min:"3.8"},{displayName:"jq",jsonName:"jq",cmd:"jq",required:"required"},{displayName:"git",jsonName:"git",cmd:"git",required:"required"},{displayName:"curl",jsonName:"curl",cmd:"curl",required:"required"},{displayName:"bash (>= 4.0)",jsonName:"bash",cmd:"bash",required:"recommended",min:"4.0"},{displayName:"Bun (>= 1.3)",jsonName:"Bun",cmd:"bun",required:"recommended",min:"1.3"},{displayName:"Claude CLI",jsonName:"Claude CLI",cmd:"claude",required:"optional"},{displayName:"Codex CLI",jsonName:"Codex CLI",cmd:"codex",required:"optional"},{displayName:"Cline CLI",jsonName:"Cline CLI",cmd:"cline",required:"optional"},{displayName:"Aider CLI",jsonName:"Aider CLI",cmd:"aider",required:"optional"}]});import{existsSync as i$,mkdirSync as zK,readdirSync as j8,readFileSync as e$,renameSync as XK,writeFileSync as UK}from"fs";import{dirname as F8,join as R8,resolve as E8}from"path";import{fileURLToPath as S8}from"url";function x8(){try{let $=F8(S8(import.meta.url)),Q=E8($,"..","..","data","model-pricing.json");if(!i$(Q))return Y1;let Z=JSON.parse(e$(Q,"utf8")).pricing;if(!Z||typeof Z!=="object")return Y1;let z={};for(let[U,X]of Object.entries(Z))if(X!==null&&typeof X==="object"&&typeof X.input==="number"&&typeof X.output==="number")z[U]={input:X.input,output:X.output};for(let U of Object.keys(Y1))if(!(U in z))return Y1;return z}catch{return Y1}}function N8($){return Math.round(($+Number.EPSILON)*1e4)/1e4}function C8($){let Q=($??t$).toLowerCase();return r$[Q]??r$[t$]}function $0($){let Q=0;for(let K of $){if(typeof K.cost_usd==="number"&&Number.isFinite(K.cost_usd)){Q+=K.cost_usd;continue}let Z=C8(K.model),z=typeof K.input_tokens==="number"?K.input_tokens:0,U=typeof K.output_tokens==="number"?K.output_tokens:0;Q+=z/1e6*Z.input+U/1e6*Z.output}return N8(Q)}function Q0($){if(!i$($))return[];let Q=[],K;try{K=j8($)}catch{return[]}for(let Z of K){if(!Z.endsWith(".json"))continue;let z=R8($,Z);try{let U=e$(z,"utf8"),X=JSON.parse(U);if(X&&typeof X==="object")Q.push(X)}catch{}}return Q}var Y1,r$,t$="sonnet";var K0=k(()=>{m();Y1={opus:{input:5,output:25},sonnet:{input:3,output:15},haiku:{input:1,output:5},"gpt-5.3-codex":{input:1.5,output:12}};r$=Object.freeze(x8())});import{existsSync as S1,readdirSync as D8,readFileSync as h8,statSync as b8}from"fs";import{join as x1}from"path";function y8($){let Q=[],K=x1($,"votes");if(!S1(K))return Q;let Z;try{Z=D8(K)}catch{return Q}for(let z of Z){if(!z.startsWith("round-")||!z.endsWith(".json"))continue;try{let U=x1(K,z);if(!b8(U).isFile())continue;let X=JSON.parse(h8(U,"utf8"));Q.push({iteration:typeof X.iteration==="number"?X.iteration:void 0,verdict:typeof X.verdict==="string"?X.verdict:void 0,complete_votes:typeof X.complete_votes==="number"?X.complete_votes:void 0,total_members:typeof X.total_members==="number"?X.total_members:void 0,threshold:typeof X.threshold==="number"?X.threshold:void 0})}catch{}}return Q}function g8(){return{iteration_count:0,total_cost_usd:0,avg_cost_per_iteration:null,total_input_tokens:0,total_output_tokens:0,total_duration_ms:0,avg_duration_ms_per_iteration:null,model_breakdown:{},phase_breakdown:{},status_breakdown:{}}}function m8(){return{council_rounds:0,unanimous_rate:null,approval_rate:null,iteration_success_rate:null}}function v8($){let Q=g8();if($.length===0)return Q;Q.iteration_count=$.length,Q.total_cost_usd=Math.round($0($)*1e4)/1e4;for(let K of $){if(typeof K.input_tokens==="number")Q.total_input_tokens+=K.input_tokens;if(typeof K.output_tokens==="number")Q.total_output_tokens+=K.output_tokens;let Z=K;if(typeof Z.duration_ms==="number")Q.total_duration_ms+=Z.duration_ms;if(typeof K.model==="string")Q.model_breakdown[K.model]=(Q.model_breakdown[K.model]??0)+1;if(typeof Z.phase==="string")Q.phase_breakdown[Z.phase]=(Q.phase_breakdown[Z.phase]??0)+1;if(typeof Z.status==="string")Q.status_breakdown[Z.status]=(Q.status_breakdown[Z.status]??0)+1}return Q.avg_cost_per_iteration=Math.round(Q.total_cost_usd/Q.iteration_count*1e4)/1e4,Q.avg_duration_ms_per_iteration=Math.round(Q.total_duration_ms/Q.iteration_count),Q}function f8($,Q,K){let Z=m8();if(Z.council_rounds=$.length,$.length>0){let z=0,U=0;for(let X of $){if(typeof X.complete_votes==="number"&&typeof X.total_members==="number"&&X.total_members>0&&X.complete_votes===X.total_members)z+=1;if(X.verdict==="COMPLETE")U+=1}Z.unanimous_rate=Math.round(z/$.length*1e4)/1e4,Z.approval_rate=Math.round(U/$.length*1e4)/1e4}if(K>0)Z.iteration_success_rate=Math.round(Q/K*1e4)/1e4;return Z}function Z0($){let Q=[],K=x1($,"metrics","efficiency"),Z=x1($,"council"),z=S1(K)?Q0(K):[];if(!S1(K))Q.push("no .loki/metrics/efficiency/ dir (efficiency KPIs zeroed)");else if(z.length===0)Q.push(".loki/metrics/efficiency/ exists but no iteration files found");let U=y8(Z);if(!S1(Z))Q.push("no .loki/council/ dir (accuracy KPIs zeroed)");else if(U.length===0)Q.push(".loki/council/ exists but no round-N.json files found");let X=v8(z),W=X.status_breakdown.success??0,J=f8(U,W,X.iteration_count);return{schema_version:1,generated_at:new Date().toISOString(),loki_dir:$,efficiency:X,accuracy:J,notes:Q}}function z0($){return JSON.stringify($,null,2)}function X0($){let Q=[];Q.push(`Loki Mode KPIs (snapshot at ${$.generated_at})`),Q.push(`Source: ${$.loki_dir}`),Q.push(""),Q.push("Efficiency"),Q.push(` Iterations: ${$.efficiency.iteration_count}`),Q.push(` Total cost USD: ${$.efficiency.total_cost_usd}`),Q.push(` Avg cost per iter: ${$.efficiency.avg_cost_per_iteration??"n/a"}`),Q.push(` Total input tokens: ${$.efficiency.total_input_tokens}`),Q.push(` Total output tokens: ${$.efficiency.total_output_tokens}`),Q.push(` Total duration (ms): ${$.efficiency.total_duration_ms}`),Q.push(` Avg duration / iter: ${$.efficiency.avg_duration_ms_per_iteration??"n/a"}`);let K=Object.entries($.efficiency.model_breakdown).sort((U,X)=>U[0].localeCompare(X[0]));if(K.length>0)Q.push(` Model breakdown: ${K.map(([U,X])=>`${U}=${X}`).join(", ")}`);let Z=Object.entries($.efficiency.phase_breakdown).sort((U,X)=>U[0].localeCompare(X[0]));if(Z.length>0)Q.push(` Phase breakdown: ${Z.map(([U,X])=>`${U}=${X}`).join(", ")}`);let z=Object.entries($.efficiency.status_breakdown).sort((U,X)=>U[0].localeCompare(X[0]));if(z.length>0)Q.push(` Status breakdown: ${z.map(([U,X])=>`${U}=${X}`).join(", ")}`);if(Q.push(""),Q.push("Accuracy"),Q.push(` Council rounds: ${$.accuracy.council_rounds}`),Q.push(` Unanimous rate: ${$.accuracy.unanimous_rate??"n/a"}`),Q.push(` Approval rate: ${$.accuracy.approval_rate??"n/a"}`),Q.push(` Iter success rate: ${$.accuracy.iteration_success_rate??"n/a"}`),$.notes.length>0){Q.push(""),Q.push("Notes");for(let U of $.notes)Q.push(` - ${U}`)}return Q.push(""),Q.push("See also: loki trust (trust trajectory across runs)"),Q.join(`
416
+ `)}var U0=k(()=>{K0()});var H0={};g(H0,{runKpis:()=>c8});function c8($){let Q=!1;for(let Z of $){if(Z==="--help"||Z==="-h"||Z==="help")return process.stdout.write(u8),0;if(Z==="--json"){Q=!0;continue}return process.stderr.write(`loki kpis: unknown arg: ${Z}
417
417
  Run 'loki kpis --help' for usage.
418
- `),1}let Q=e$(L());return process.stdout.write(K?$0(Q)+`
419
- `:K0(Q)+`
420
- `),0}var R7=`loki kpis -- accuracy + efficiency KPI snapshot (v7.5.28 MVP)
418
+ `),1}let K=Z0(L());return process.stdout.write(Q?z0(K)+`
419
+ `:X0(K)+`
420
+ `),0}var u8=`loki kpis -- accuracy + efficiency KPI snapshot (v7.5.28 MVP)
421
421
 
422
422
  Usage:
423
423
  loki kpis Pretty-print KPI snapshot
@@ -437,30 +437,52 @@ iteration success rate.
437
437
  This is the Phase K MVP -- read-only derivation. Per-iteration
438
438
  emission, dashboard panel, and the loki-bench harness are deferred
439
439
  follow-ups (see project_v7_5_18_arc_status.md).
440
- `;var Z0=F(()=>{Q0();v()});import{closeSync as s1,fstatSync as S7,lstatSync as N7,mkdirSync as z0,openSync as H0,readSync as D7,renameSync as C7,rmSync as U0,statSync as h7,unlinkSync as V0,writeFileSync as b7,writeSync as y7}from"fs";import{dirname as q0}from"path";function Y1($,K){z0(q0($),{recursive:!0});let Q=`${$}.tmp.${process.pid}.${++g7}`;b7(Q,`${JSON.stringify(K,null,2)}
441
- `),C7(Q,$)}async function J0($,K){let Q=E1.get($)??Promise.resolve(),X=()=>{},Z=new Promise((H)=>{X=H}),z=Q.catch(()=>{}).then(()=>Z);E1.set($,z);try{return await Q.catch(()=>{}),await K()}finally{if(X(),E1.get($)===z)E1.delete($)}}function v7($){return`${$}.lock`}function m7($){if(!Number.isFinite($)||$<=0)return!1;try{return process.kill($,0),!0}catch(K){return K?.code==="EPERM"}}function f7($){let K=null;try{return z0(q0($),{recursive:!0}),K=H0($,"wx"),y7(K,`${process.pid}
442
- `),K}catch(Q){if(K!==null){try{s1(K)}catch{}try{V0($)}catch{}}if(Q?.code==="EEXIST")return null;throw Q}}function u7($,K){let Q;try{Q=N7($)}catch{return!0}if(Q.isSymbolicLink())try{return V0($),!0}catch{return!1}let X;try{X=H0($,"r")}catch{return!0}try{let Z=S7(X);if(Date.now()-Z.mtimeMs<K)return!1;let H=NaN;try{let V=Buffer.alloc(64),q=D7(X,V,0,64,0);H=Number.parseInt(V.subarray(0,q).toString("utf-8").trim(),10)}catch{}if(Number.isFinite(H)&&m7(H))return!1;try{if(h7($).mtimeMs>Z.mtimeMs)return!1}catch{return!0}try{U0($,{force:!0})}catch{}return!0}finally{try{s1(X)}catch{}}}function r1($,K,Q={}){let X=Q.timeoutMs??1e4,Z=Q.pollMs??25,z=Q.staleMs??30000,H=v7($),V=Date.now()+X,q=null,J=0,W=new Int32Array(new SharedArrayBuffer(4));while(q===null){if(q=f7(H),q!==null)break;if(Date.now()>V)throw Error(`withFileLockSync: timed out after ${X}ms acquiring ${H}`);if(u7(H,z))continue;let M=Math.min(Z*2**Math.min(J,4),200);J+=1,Atomics.wait(W,0,0,M)}try{return K()}finally{try{s1(q)}catch{}try{U0(H,{force:!0})}catch{}}}var g7=0,E1;var S1=F(()=>{E1=new Map});import{existsSync as Q1,mkdirSync as J1,copyFileSync as M0,readFileSync as e1,readdirSync as c7,statSync as p7,writeFileSync as l7,renameSync as Y0,appendFileSync as T0,rmSync as d7}from"fs";import{join as y,dirname as N1}from"path";function n7($){let K=G0.then($,$);return G0=K.catch((Q)=>{console.warn("[checkpoint] serialized op rejected:",Q);return}),K}function d($){return y($,"state","checkpoints")}function O0($){return y(d($),"index.jsonl")}async function a7($){let K=await k(["git","rev-parse","HEAD"],{cwd:$,timeoutMs:5000});if(K.exitCode!==0)return"no-git";return K.stdout.trim()||"no-git"}async function s7($){let K=await k(["git","branch","--show-current"],{cwd:$,timeoutMs:5000});if(K.exitCode!==0)return"unknown";return K.stdout.trim()||"unknown"}async function r7($){let K=await k(["git","diff","--quiet"],{cwd:$,timeoutMs:5000}),Q=await k(["git","diff","--cached","--quiet"],{cwd:$,timeoutMs:5000}),X=K.exitCode===1,Z=Q.exitCode===1;return X||Z}function t7($){let K=y($,"state","orchestrator.json");if(!Q1(K))return"unknown";try{let X=JSON.parse(e1(K,"utf-8")).currentPhase;return typeof X==="string"&&X.length>0?X:"unknown"}catch{return"unknown"}}function e7($,K){for(let Q of i7){let X=y($,Q);if(!Q1(X))continue;let Z=y(K,Q);J1(N1(Z),{recursive:!0});try{M0(X,Z)}catch{}}}function _0($,K){J1(N1($),{recursive:!0});let Q=`${$}.tmp.${process.pid}.${++A0}`;l7(Q,K),Y0(Q,$)}function $8($){return JSON.stringify($,null,2)}function w0($){return`{${[`"id": ${JSON.stringify($.id)}`,`"ts": ${JSON.stringify($.ts)}`,`"iter": ${JSON.stringify($.iter)}`,`"task": ${JSON.stringify($.task)}`,`"sha": ${JSON.stringify($.sha)}`].join(", ")}}`}async function K8($){return n7(()=>Q8($))}async function Q8($){let K=$.lokiDirOverride??L(),Q=process.cwd(),X=d(K);if(J1(X,{recursive:!0}),!$.forceCreate){if(!await r7(Q))return{created:!1,reason:"no uncommitted changes"}}let Z=await a7(Q),z=await s7(Q),H=$.iteration??Number.parseInt(process.env.ITERATION_COUNT??"0",10),V=$.epochOverride??Math.floor(Date.now()/1000),q=`cp-${H}-${V}`,J=y(X,q);J1(J,{recursive:!0}),e7(K,J);let W=new Date().toISOString().replace(/\.\d{3}Z$/,"Z"),M=($.taskDescription??"task completed").slice(0,o7),G=$.provider??process.env.PROVIDER_NAME??"claude",B={id:q,timestamp:W,iteration:H,task_id:$.taskId??"unknown",task_description:M,git_sha:Z,git_branch:z,provider:G,phase:t7(K)};_0(y(J,"metadata.json"),$8(B));let T={id:B.id,ts:B.timestamp,iter:B.iteration,task:B.task_description,sha:B.git_sha},Y=O0(K);return r1(Y,()=>{T0(Y,`${w0(T)}
443
- `)}),X8(K),{created:!0,id:q,metadata:B,dir:J}}function $$($){let K=d($);if(!Q1(K))return[];return c7(K).filter((Q)=>Q.startsWith("cp-")).filter((Q)=>{try{return p7(y(K,Q)).isDirectory()}catch{return!1}})}function K$($){return[...$].sort((K,Q)=>{let X=B0(K),Z=B0(Q);return X-Z})}function B0($){let K=$.split("-");if(K.length<3)return 0;let Q=K[K.length-1],X=Number.parseInt(Q??"0",10);return Number.isFinite(X)?X:0}function X8($){let K=$$($);if(K.length<=W0)return;let Q=K$(K),X=Q.slice(0,Q.length-W0);for(let Z of X)try{d7(y(d($),Z),{recursive:!0,force:!0})}catch{}Z8($)}function Z8($){let K=K$($$($)),Q=[];for(let z of K){let H=y(d($),z,"metadata.json"),V=y(d($),z);if(!Q1(H)){t1($,V,"missing_field","metadata.json");continue}try{let q=JSON.parse(e1(H,"utf-8")),J=j0(q,H);if(!J.ok){t1($,V,J.reason,J.field);continue}let W=J.value;Q.push(w0({id:W.id,ts:W.timestamp,iter:W.iteration,task:W.task_description??"",sha:W.git_sha}))}catch{t1($,V,"invalid_type","metadata.json")}}let X=O0($),Z=Q.length>0?`${Q.join(`
440
+ `;var W0=k(()=>{U0();m()});import{existsSync as p8,mkdirSync as l8,readdirSync as d8,readFileSync as o8,statSync as n8,writeFileSync as a8}from"fs";import{join as T1}from"path";function i1($){return $&&typeof $==="object"?$:{}}function K1($){return Math.round($*1e4)/1e4}function e8($){let Q=String($??"").trim().toUpperCase();if(!Q)return null;for(let K of q0)if(Q.startsWith(K))return!0;return!1}function $6($){let Q=e8($.final_verdict);if(Q!==null)return Q?1:0;let K=$.reviewers;if(Array.isArray(K)&&K.length>0){let Z=0,z=0;for(let U of K){if(!U||typeof U!=="object")continue;z+=1;let X=String(U.vote??"").trim().toUpperCase();if(q0.some((W)=>X.startsWith(W)))Z+=1}if(z>0)return Z===z?1:0}return null}function Q6($){let Q=Number($.total),K=Number($.passed);if(!Number.isFinite(Q)||!Number.isFinite(K))return null;if(Q<=0)return null;return Math.max(0,Math.min(1,K/Q))}function K6($){let Q;if($&&typeof $==="object")Q=$.count;else Q=$;let K=Number(Q);if(!Number.isFinite(K)||K<0)return null;return K}function Z6($){let Q=i1($.council);for(let K of[Q.interventions,$.interventions]){let Z=Number(K);if(Number.isFinite(Z)&&Z>=0)return Z}return null}function z6($){let Q=T1($,"proofs"),K=[];if(!p8(Q))return K;let Z;try{Z=d8(Q).sort()}catch{return K}for(let z of Z){let U=T1(Q,z);try{if(!n8(U).isDirectory())continue}catch{continue}let X=null;try{X=JSON.parse(o8(T1(U,"proof.json"),"utf8"))}catch{continue}if(!X||typeof X!=="object")continue;K.push({run_id:String(X.run_id??z),generated_at:typeof X.generated_at==="string"?X.generated_at:null,council_pass_rate:$6(i1(X.council)),gate_pass_rate:Q6(i1(X.quality_gates)),iterations:K6(X.iterations),interventions:Z6(X)})}return K.sort((z,U)=>{let X=z.generated_at===null?1:0,W=U.generated_at===null?1:0;if(X!==W)return X-W;return(z.generated_at??"").localeCompare(U.generated_at??"")}),K}function J0($){return $.reduce((Q,K)=>Q+K,0)/$.length}function X6($,Q){let K=r8[$],Z=t8[$],z=i8[$],U=Q.filter((Y)=>Y!==null),X=U.length;if(X===0)return{axis:$,label:z,available:!1,higher_is_better:K,note:"no runs recorded this metric"};if(X<2)return{axis:$,label:z,available:!0,higher_is_better:K,data_points:X,latest:K1(U[X-1]),direction:"flat",improving:null,delta:0,earlier_mean:K1(U[0]),later_mean:K1(U[X-1]),insufficient:!0,note:"not enough history yet (need 2+ runs with this metric)"};let W=Math.floor(X/2),J=U.slice(0,W),q=U.slice(X-W),V=J0(J),M=J0(q),G=M-V,B;if(Math.abs(G)<=Z)B="flat";else if(G>0)B="up";else B="down";let T;if(B==="flat")T=null;else T=B==="up"===K;return{axis:$,label:z,available:!0,higher_is_better:K,data_points:X,latest:K1(U[X-1]),direction:B,improving:T,delta:K1(G),earlier_mean:K1(V),later_mean:K1(M),insufficient:!1}}function V0($){let Q=z6($),K=Q.map((J)=>({run_id:J.run_id,generated_at:J.generated_at,council_pass_rate:J.council_pass_rate,gate_pass_rate:J.gate_pass_rate,iterations:J.iterations,interventions:J.interventions})),Z={};for(let J of N1)Z[J]=X6(J,Q.map((q)=>q[J]));let z=Q.length<2,U=N1.filter((J)=>Z[J].available&&Z[J].improving===!0),X=N1.filter((J)=>Z[J].available&&Z[J].improving===!1),W=[];if(z)W.push(`not enough history yet: ${Q.length} run(s) recorded, need 2+ to show a trend`);if(!Z.interventions.available)W.push("intervention trend unavailable: no per-run intervention count in proof.json yet (axis lights up automatically once recorded)");return{schema_version:s8,generated_at:new Date().toISOString(),loki_dir:$,runs_count:Q.length,insufficient:z,axes:Z,improving_count:U.length,regressing_count:X.length,improving_axes:U,regressing_axes:X,series:K,notes:W}}function G0($){return JSON.stringify($,null,2)}function B0($,Q){let K=T1($,"metrics"),Z=T1(K,"trust-trajectory.json");try{return l8(K,{recursive:!0}),a8(Z,JSON.stringify(Q,null,2)),Z}catch{return null}}function U6($){if($==="up")return"up";if($==="down")return"down";return"flat"}function H6($){let Q=$.label??$.axis;if(!$.available)return` ${(Q+":").padEnd(26)} no data`;let K;if($.insufficient)K="(need 2+ runs)";else if($.improving===!0)K="improving";else if($.improving===!1)K="regressing";else K="stable";let Z=$.higher_is_better?"higher better":"lower better",z=$.latest??"n/a";return` ${(Q+":").padEnd(26)} ${U6($.direction).padEnd(5)} latest=${String(z).padEnd(7)} ${K.padEnd(11)} [${Z}]`}function M0($){let Q=[];if(Q.push(`Loki Mode Trust Trajectory (snapshot at ${$.generated_at})`),Q.push(`Source: ${$.loki_dir}`),Q.push(`Runs analyzed: ${$.runs_count}`),Q.push(""),$.insufficient){if(Q.push("Not enough history yet."),Q.push("Trust trajectory needs 2+ recorded runs to show a direction."),Q.push("Each `loki start` run writes a proof-of-run; come back after the next run."),$.notes.length>0){Q.push(""),Q.push("Notes");for(let z of $.notes)Q.push(` - ${z}`)}return Q.join(`
441
+ `)}Q.push("Is the agent earning autonomy on this repo?");for(let z of N1)if($.axes[z])Q.push(H6($.axes[z]));Q.push("");let{improving_count:K,regressing_count:Z}=$;if(K&&!Z)Q.push(`Overall: trending more trustworthy (${K} axis improving).`);else if(Z&&!K)Q.push(`Overall: trust regressing (${Z} axis regressing). Review recent runs.`);else if(K||Z)Q.push(`Overall: mixed (${K} improving / ${Z} regressing).`);else Q.push("Overall: stable.");if($.notes.length>0){Q.push(""),Q.push("Notes");for(let z of $.notes)Q.push(` - ${z}`)}return Q.join(`
442
+ `)}var s8=1,N1,r8,t8,i8,q0;var Y0=k(()=>{N1=["council_pass_rate","gate_pass_rate","iterations","interventions"],r8={council_pass_rate:!0,gate_pass_rate:!0,iterations:!1,interventions:!1},t8={council_pass_rate:0.01,gate_pass_rate:0.01,iterations:0.25,interventions:0.25},i8={council_pass_rate:"Council pass rate",gate_pass_rate:"Gate pass rate",iterations:"Iterations to completion",interventions:"Human interventions"},q0=["APPROVE","APPROVED","COMPLETE","PASS","PASSED"]});var T0={};g(T0,{runTrust:()=>J6});function J6($){let Q=!1;for(let z of $){if(z==="--help"||z==="-h"||z==="help")return process.stdout.write(W6),0;if(z==="--json"){Q=!0;continue}return process.stderr.write(`loki trust: unknown arg: ${z}
443
+ Run 'loki trust --help' for usage.
444
+ `),1}let K=L(),Z=V0(K);return B0(K,Z),process.stdout.write(Q?G0(Z)+`
445
+ `:M0(Z)+`
446
+ `),0}var W6=`loki trust -- visible trust trajectory (R4)
447
+
448
+ Usage:
449
+ loki trust Pretty-print the per-project trust trajectory
450
+ loki trust --json Emit the trajectory as JSON
451
+ loki trust --help Show this help
452
+
453
+ Shows whether the agent is earning autonomy on THIS repo over time:
454
+ - Council pass rate (higher is better)
455
+ - Gate pass rate (higher is better)
456
+ - Iterations to completion (lower is better)
457
+ - Human interventions (lower is better, when recorded)
458
+
459
+ Derived read-only from proof-of-run history in .loki/proofs/. With fewer
460
+ than 2 recorded runs it reports "not enough history yet" rather than a
461
+ fabricated trend. Complements 'loki kpis' (single-run snapshot).
462
+ `;var O0=k(()=>{Y0();m()});import{closeSync as e1,fstatSync as q6,lstatSync as V6,mkdirSync as _0,openSync as A0,readSync as G6,renameSync as B6,rmSync as w0,statSync as M6,unlinkSync as I0,writeFileSync as Y6,writeSync as T6}from"fs";import{dirname as P0}from"path";function O1($,Q){_0(P0($),{recursive:!0});let K=`${$}.tmp.${process.pid}.${++O6}`;Y6(K,`${JSON.stringify(Q,null,2)}
463
+ `),B6(K,$)}async function L0($,Q){let K=C1.get($)??Promise.resolve(),Z=()=>{},z=new Promise((X)=>{Z=X}),U=K.catch(()=>{}).then(()=>z);C1.set($,U);try{return await K.catch(()=>{}),await Q()}finally{if(Z(),C1.get($)===U)C1.delete($)}}function _6($){return`${$}.lock`}function A6($){if(!Number.isFinite($)||$<=0)return!1;try{return process.kill($,0),!0}catch(Q){return Q?.code==="EPERM"}}function w6($){let Q=null;try{return _0(P0($),{recursive:!0}),Q=A0($,"wx"),T6(Q,`${process.pid}
464
+ `),Q}catch(K){if(Q!==null){try{e1(Q)}catch{}try{I0($)}catch{}}if(K?.code==="EEXIST")return null;throw K}}function I6($,Q){let K;try{K=V6($)}catch{return!0}if(K.isSymbolicLink())try{return I0($),!0}catch{return!1}let Z;try{Z=A0($,"r")}catch{return!0}try{let z=q6(Z);if(Date.now()-z.mtimeMs<Q)return!1;let X=NaN;try{let W=Buffer.alloc(64),J=G6(Z,W,0,64,0);X=Number.parseInt(W.subarray(0,J).toString("utf-8").trim(),10)}catch{}if(Number.isFinite(X)&&A6(X))return!1;try{if(M6($).mtimeMs>z.mtimeMs)return!1}catch{return!0}try{w0($,{force:!0})}catch{}return!0}finally{try{e1(Z)}catch{}}}function $$($,Q,K={}){let Z=K.timeoutMs??1e4,z=K.pollMs??25,U=K.staleMs??30000,X=_6($),W=Date.now()+Z,J=null,q=0,V=new Int32Array(new SharedArrayBuffer(4));while(J===null){if(J=w6(X),J!==null)break;if(Date.now()>W)throw Error(`withFileLockSync: timed out after ${Z}ms acquiring ${X}`);if(I6(X,U))continue;let M=Math.min(z*2**Math.min(q,4),200);q+=1,Atomics.wait(V,0,0,M)}try{return Q()}finally{try{e1(J)}catch{}try{w0(X,{force:!0})}catch{}}}var O6=0,C1;var D1=k(()=>{C1=new Map});import{existsSync as Z1,mkdirSync as V1,copyFileSync as R0,readFileSync as Z$,readdirSync as P6,statSync as L6,writeFileSync as k6,renameSync as E0,appendFileSync as S0,rmSync as j6}from"fs";import{join as y,dirname as h1}from"path";function R6($){let Q=j0.then($,$);return j0=Q.catch((K)=>{console.warn("[checkpoint] serialized op rejected:",K);return}),Q}function d($){return y($,"state","checkpoints")}function x0($){return y(d($),"index.jsonl")}async function E6($){let Q=await F(["git","rev-parse","HEAD"],{cwd:$,timeoutMs:5000});if(Q.exitCode!==0)return"no-git";return Q.stdout.trim()||"no-git"}async function S6($){let Q=await F(["git","branch","--show-current"],{cwd:$,timeoutMs:5000});if(Q.exitCode!==0)return"unknown";return Q.stdout.trim()||"unknown"}async function x6($){let Q=await F(["git","diff","--quiet"],{cwd:$,timeoutMs:5000}),K=await F(["git","diff","--cached","--quiet"],{cwd:$,timeoutMs:5000}),Z=Q.exitCode===1,z=K.exitCode===1;return Z||z}function N6($){let Q=y($,"state","orchestrator.json");if(!Z1(Q))return"unknown";try{let Z=JSON.parse(Z$(Q,"utf-8")).currentPhase;return typeof Z==="string"&&Z.length>0?Z:"unknown"}catch{return"unknown"}}function D6($,Q){for(let K of C6){let Z=y($,K);if(!Z1(Z))continue;let z=y(Q,K);V1(h1(z),{recursive:!0});try{R0(Z,z)}catch{}}}function C0($,Q){V1(h1($),{recursive:!0});let K=`${$}.tmp.${process.pid}.${++N0}`;k6(K,Q),E0(K,$)}function h6($){return JSON.stringify($,null,2)}function D0($){return`{${[`"id": ${JSON.stringify($.id)}`,`"ts": ${JSON.stringify($.ts)}`,`"iter": ${JSON.stringify($.iter)}`,`"task": ${JSON.stringify($.task)}`,`"sha": ${JSON.stringify($.sha)}`].join(", ")}}`}async function b6($){return R6(()=>y6($))}async function y6($){let Q=$.lokiDirOverride??L(),K=process.cwd(),Z=d(Q);if(V1(Z,{recursive:!0}),!$.forceCreate){if(!await x6(K))return{created:!1,reason:"no uncommitted changes"}}let z=await E6(K),U=await S6(K),X=$.iteration??Number.parseInt(process.env.ITERATION_COUNT??"0",10),W=$.epochOverride??Math.floor(Date.now()/1000),J=`cp-${X}-${W}`,q=y(Z,J);V1(q,{recursive:!0}),D6(Q,q);let V=new Date().toISOString().replace(/\.\d{3}Z$/,"Z"),M=($.taskDescription??"task completed").slice(0,F6),G=$.provider??process.env.PROVIDER_NAME??"claude",B={id:J,timestamp:V,iteration:X,task_id:$.taskId??"unknown",task_description:M,git_sha:z,git_branch:U,provider:G,phase:N6(Q)};C0(y(q,"metadata.json"),h6(B));let T={id:B.id,ts:B.timestamp,iter:B.iteration,task:B.task_description,sha:B.git_sha},Y=x0(Q);return $$(Y,()=>{S0(Y,`${D0(T)}
465
+ `)}),g6(Q),{created:!0,id:J,metadata:B,dir:q}}function z$($){let Q=d($);if(!Z1(Q))return[];return P6(Q).filter((K)=>K.startsWith("cp-")).filter((K)=>{try{return L6(y(Q,K)).isDirectory()}catch{return!1}})}function X$($){return[...$].sort((Q,K)=>{let Z=F0(Q),z=F0(K);return Z-z})}function F0($){let Q=$.split("-");if(Q.length<3)return 0;let K=Q[Q.length-1],Z=Number.parseInt(K??"0",10);return Number.isFinite(Z)?Z:0}function g6($){let Q=z$($);if(Q.length<=k0)return;let K=X$(Q),Z=K.slice(0,K.length-k0);for(let z of Z)try{j6(y(d($),z),{recursive:!0,force:!0})}catch{}m6($)}function m6($){let Q=X$(z$($)),K=[];for(let U of Q){let X=y(d($),U,"metadata.json"),W=y(d($),U);if(!Z1(X)){Q$($,W,"missing_field","metadata.json");continue}try{let J=JSON.parse(Z$(X,"utf-8")),q=b0(J,X);if(!q.ok){Q$($,W,q.reason,q.field);continue}let V=q.value;K.push(D0({id:V.id,ts:V.timestamp,iter:V.iteration,task:V.task_description??"",sha:V.git_sha}))}catch{Q$($,W,"invalid_type","metadata.json")}}let Z=x0($),z=K.length>0?`${K.join(`
444
466
  `)}
445
- `:"";_0(X,Z)}function t1($,K,Q,X){let Z=y($,"events.jsonl"),z={timestamp:new Date().toISOString(),type:"checkpoint.metadata.dropped",checkpoint_dir:K,reason:Q,field:X};try{J1(N1(Z),{recursive:!0}),r1(Z,()=>{T0(Z,`${JSON.stringify(z)}
446
- `)})}catch{}}function Q$($){let K=$??L(),Q=K$($$(K)),X=[];for(let Z of Q){let z=I0(K,Z);if(z)X.push(z)}return X}function I0($,K){let Q=y(d($),K,"metadata.json");if(!Q1(Q))return null;try{let X=JSON.parse(e1(Q,"utf-8"));return z8(X,Q)}catch{return null}}function z8($,K){let Q=j0($,K);return Q.ok?Q.value:null}function j0($,K){if($===null||typeof $!=="object")return console.warn(`[checkpoint] invalid metadata at ${K}: not an object`),{ok:!1,reason:"invalid_type",field:"<root>"};let Q=$,X=["id","timestamp","task_id","task_description","git_sha","git_branch","provider","phase"];for(let Z of X){if(!(Z in Q))return console.warn(`[checkpoint] invalid metadata at ${K}: field "${Z}" missing`),{ok:!1,reason:"missing_field",field:Z};if(typeof Q[Z]!=="string")return console.warn(`[checkpoint] invalid metadata at ${K}: field "${Z}" not a string`),{ok:!1,reason:"invalid_type",field:Z}}if(!Object.prototype.hasOwnProperty.call(Q,"iteration"))return console.warn(`[checkpoint] invalid metadata at ${K}: field "iteration" missing`),{ok:!1,reason:"missing_field",field:"iteration"};if(typeof Q.iteration!=="number"||!Number.isFinite(Q.iteration))return console.warn(`[checkpoint] invalid metadata at ${K}: field "iteration" not a finite number`),{ok:!1,reason:"invalid_type",field:"iteration"};for(let Z of U8){let z=Q[Z];if(H8.test(z))return console.warn(`[checkpoint] invalid metadata at ${K}: field "${Z}" contains control characters`),{ok:!1,reason:"control_chars",field:Z}}return{ok:!0,value:{id:Q.id,timestamp:Q.timestamp,iteration:Q.iteration,task_id:Q.task_id,task_description:Q.task_description,git_sha:Q.git_sha,git_branch:Q.git_branch,provider:Q.provider,phase:Q.phase}}}function X$($,K){if(!V8.test($))throw new P0($);let Q=K??L(),X=y(d(Q),$);if(!Q1(X))throw new i1($);let Z=I0(Q,$);if(!Z)throw new i1($);return Z}function L0($,K){let Q=X$($,K),X=K??L(),Z=y(d(X),$),z=[];for(let H of q8){let V=y(Z,H);if(!Q1(V))continue;z.push({from:V,to:y(X,H)})}return{id:$,metadata:Q,restore:z}}function J8($){let K=[],Q=0;for(let X of $.restore)try{J1(N1(X.to),{recursive:!0});let Z=`${X.to}.tmp.${process.pid}.${++A0}`;M0(X.from,Z),Y0(Z,X.to),Q+=1}catch(Z){K.push(`${X.from} -> ${X.to}: ${Z.message}`)}return{restored:Q,errors:K}}async function k0($,K,Q=!1){let X=null;try{let z=await K8({taskDescription:`pre-rollback snapshot (before restoring ${$.id})`,taskId:"rollback",forceCreate:!0,lokiDirOverride:K});if(z.created)X=z.id}catch(z){let H=z instanceof Error?z.message:String(z);if(!Q)throw Error("pre-rollback snapshot failed ("+H+"); aborting rollback to preserve current state. Re-run with force to roll back anyway without a safety snapshot.");console.warn("[checkpoint] pre-rollback snapshot failed; proceeding due to force:",H)}let Z=J8($);return{preRollbackSnapshotId:X,restored:Z.restored,errors:Z.errors}}var W0=50,o7=200,G0,i7,A0=0,H8,U8,V8,i1,P0,q8;var x0=F(()=>{v();n();S1();G0=Promise.resolve();i7=["state/orchestrator.json","autonomy-state.json","queue/pending.json","queue/completed.json","queue/in-progress.json","queue/current-task.json","CONTINUITY.md"];H8=/[\x00-\x08\x0a-\x1f\x7f-\x9f]/,U8=["id","task_id","git_sha","git_branch","provider","phase"];V8=/^[a-zA-Z0-9_-]+$/;i1=class i1 extends Error{id;constructor($){super(`Checkpoint not found: ${$}`);this.id=$;this.name="CheckpointNotFoundError"}};P0=class P0 extends Error{id;constructor($){super(`Invalid checkpoint ID: must be alphanumeric, hyphens, underscores only (got: ${$})`);this.id=$;this.name="InvalidCheckpointIdError"}};q8=["state/orchestrator.json","queue/pending.json","queue/completed.json","queue/in-progress.json","queue/current-task.json","CONTINUITY.md"]});var E0={};g(E0,{runRollback:()=>W8});async function W8($){let K=$[0],Q=$.slice(1);if(K===void 0||K==="help"||K==="--help"||K==="-h")return process.stdout.write(F0),K===void 0?1:0;switch(K){case"list":{let X=[...Q$()].reverse();if(X.length===0)return process.stdout.write(`${I}No checkpoints found.${U}
447
- `),0;process.stdout.write(`${S}Checkpoints${U} (${X.length}, newest first):
448
- `);for(let Z of X)process.stdout.write(` ${_}${Z.id}${U} iter=${Z.iteration} ${Z.git_branch||"(no branch)"}@${(Z.git_sha||"").slice(0,7)} ${Z.timestamp}
449
- `);return 0}case"show":{let X=Q[0];if(!X)return process.stderr.write(`${O}Missing checkpoint id.${U} Use \`loki rollback list\`.
450
- `),2;try{let Z=X$(X);return process.stdout.write(`${JSON.stringify(Z,null,2)}
451
- `),0}catch(Z){return process.stderr.write(`${O}Failed to read checkpoint:${U} ${Z.message}
452
- `),1}}case"to":{let X=Q[0];if(!X)return process.stderr.write(`${O}Missing checkpoint id.${U} Use \`loki rollback list\`.
453
- `),2;return await R0(X,Q.includes("--force"))}case"latest":{let X=Q$(),Z=X[X.length-1];if(!Z)return process.stderr.write(`${O}No checkpoints found to roll back to.${U}
454
- `),1;return process.stdout.write(`Rolling back to latest checkpoint: ${_}${Z.id}${U}
455
- `),await R0(Z.id,Q.includes("--force"))}default:return process.stderr.write(`Unknown subcommand: ${K}
456
- `),process.stderr.write(F0),2}}async function R0($,K=!1){let Q;try{Q=L0($)}catch(Z){return process.stderr.write(`${O}Cannot plan rollback:${U} ${Z.message}
457
- `),1}if(Q.restore.length===0)return process.stdout.write(`${I}Checkpoint ${$} has no restorable state files; nothing to do.${U}
458
- `),0;let X;try{X=await k0(Q,void 0,K)}catch(Z){return process.stderr.write(`${O}Rollback aborted:${U} ${Z.message}
459
- `),1}if(X.errors.length>0){for(let Z of X.errors)process.stderr.write(`${O}restore error:${U} ${Z}
460
- `);return process.stderr.write(`${O}Partial rollback: ${X.restored}/${Q.restore.length} files restored.${U}
461
- `),1}if(process.stdout.write(`${D}Rolled back ${X.restored}/${Q.restore.length} state files from ${$}.${U}
462
- `),X.preRollbackSnapshotId)process.stdout.write(`Saved your prior state as ${_}${X.preRollbackSnapshotId}${U}; undo this rollback with \`loki rollback to ${X.preRollbackSnapshotId}\`.
463
- `);return process.stdout.write("Run `loki start` to resume from the restored state.\n"),0}var F0=`Usage: loki rollback <subcommand>
467
+ `:"";C0(Z,z)}function Q$($,Q,K,Z){let z=y($,"events.jsonl"),U={timestamp:new Date().toISOString(),type:"checkpoint.metadata.dropped",checkpoint_dir:Q,reason:K,field:Z};try{V1(h1(z),{recursive:!0}),$$(z,()=>{S0(z,`${JSON.stringify(U)}
468
+ `)})}catch{}}function U$($){let Q=$??L(),K=X$(z$(Q)),Z=[];for(let z of K){let U=h0(Q,z);if(U)Z.push(U)}return Z}function h0($,Q){let K=y(d($),Q,"metadata.json");if(!Z1(K))return null;try{let Z=JSON.parse(Z$(K,"utf-8"));return v6(Z,K)}catch{return null}}function v6($,Q){let K=b0($,Q);return K.ok?K.value:null}function b0($,Q){if($===null||typeof $!=="object")return console.warn(`[checkpoint] invalid metadata at ${Q}: not an object`),{ok:!1,reason:"invalid_type",field:"<root>"};let K=$,Z=["id","timestamp","task_id","task_description","git_sha","git_branch","provider","phase"];for(let z of Z){if(!(z in K))return console.warn(`[checkpoint] invalid metadata at ${Q}: field "${z}" missing`),{ok:!1,reason:"missing_field",field:z};if(typeof K[z]!=="string")return console.warn(`[checkpoint] invalid metadata at ${Q}: field "${z}" not a string`),{ok:!1,reason:"invalid_type",field:z}}if(!Object.prototype.hasOwnProperty.call(K,"iteration"))return console.warn(`[checkpoint] invalid metadata at ${Q}: field "iteration" missing`),{ok:!1,reason:"missing_field",field:"iteration"};if(typeof K.iteration!=="number"||!Number.isFinite(K.iteration))return console.warn(`[checkpoint] invalid metadata at ${Q}: field "iteration" not a finite number`),{ok:!1,reason:"invalid_type",field:"iteration"};for(let z of u6){let U=K[z];if(f6.test(U))return console.warn(`[checkpoint] invalid metadata at ${Q}: field "${z}" contains control characters`),{ok:!1,reason:"control_chars",field:z}}return{ok:!0,value:{id:K.id,timestamp:K.timestamp,iteration:K.iteration,task_id:K.task_id,task_description:K.task_description,git_sha:K.git_sha,git_branch:K.git_branch,provider:K.provider,phase:K.phase}}}function H$($,Q){if(!c6.test($))throw new y0($);let K=Q??L(),Z=y(d(K),$);if(!Z1(Z))throw new K$($);let z=h0(K,$);if(!z)throw new K$($);return z}function g0($,Q){let K=H$($,Q),Z=Q??L(),z=y(d(Z),$),U=[];for(let X of p6){let W=y(z,X);if(!Z1(W))continue;U.push({from:W,to:y(Z,X)})}return{id:$,metadata:K,restore:U}}function l6($){let Q=[],K=0;for(let Z of $.restore)try{V1(h1(Z.to),{recursive:!0});let z=`${Z.to}.tmp.${process.pid}.${++N0}`;R0(Z.from,z),E0(z,Z.to),K+=1}catch(z){Q.push(`${Z.from} -> ${Z.to}: ${z.message}`)}return{restored:K,errors:Q}}async function m0($,Q,K=!1){let Z=null;try{let U=await b6({taskDescription:`pre-rollback snapshot (before restoring ${$.id})`,taskId:"rollback",forceCreate:!0,lokiDirOverride:Q});if(U.created)Z=U.id}catch(U){let X=U instanceof Error?U.message:String(U);if(!K)throw Error("pre-rollback snapshot failed ("+X+"); aborting rollback to preserve current state. Re-run with force to roll back anyway without a safety snapshot.");console.warn("[checkpoint] pre-rollback snapshot failed; proceeding due to force:",X)}let z=l6($);return{preRollbackSnapshotId:Z,restored:z.restored,errors:z.errors}}var k0=50,F6=200,j0,C6,N0=0,f6,u6,c6,K$,y0,p6;var v0=k(()=>{m();n();D1();j0=Promise.resolve();C6=["state/orchestrator.json","autonomy-state.json","queue/pending.json","queue/completed.json","queue/in-progress.json","queue/current-task.json","CONTINUITY.md"];f6=/[\x00-\x08\x0a-\x1f\x7f-\x9f]/,u6=["id","task_id","git_sha","git_branch","provider","phase"];c6=/^[a-zA-Z0-9_-]+$/;K$=class K$ extends Error{id;constructor($){super(`Checkpoint not found: ${$}`);this.id=$;this.name="CheckpointNotFoundError"}};y0=class y0 extends Error{id;constructor($){super(`Invalid checkpoint ID: must be alphanumeric, hyphens, underscores only (got: ${$})`);this.id=$;this.name="InvalidCheckpointIdError"}};p6=["state/orchestrator.json","queue/pending.json","queue/completed.json","queue/in-progress.json","queue/current-task.json","CONTINUITY.md"]});var c0={};g(c0,{runRollback:()=>d6});async function d6($){let Q=$[0],K=$.slice(1);if(Q===void 0||Q==="help"||Q==="--help"||Q==="-h")return process.stdout.write(f0),Q===void 0?1:0;switch(Q){case"list":{let Z=[...U$()].reverse();if(Z.length===0)return process.stdout.write(`${I}No checkpoints found.${H}
469
+ `),0;process.stdout.write(`${x}Checkpoints${H} (${Z.length}, newest first):
470
+ `);for(let z of Z)process.stdout.write(` ${A}${z.id}${H} iter=${z.iteration} ${z.git_branch||"(no branch)"}@${(z.git_sha||"").slice(0,7)} ${z.timestamp}
471
+ `);return 0}case"show":{let Z=K[0];if(!Z)return process.stderr.write(`${O}Missing checkpoint id.${H} Use \`loki rollback list\`.
472
+ `),2;try{let z=H$(Z);return process.stdout.write(`${JSON.stringify(z,null,2)}
473
+ `),0}catch(z){return process.stderr.write(`${O}Failed to read checkpoint:${H} ${z.message}
474
+ `),1}}case"to":{let Z=K[0];if(!Z)return process.stderr.write(`${O}Missing checkpoint id.${H} Use \`loki rollback list\`.
475
+ `),2;return await u0(Z,K.includes("--force"))}case"latest":{let Z=U$(),z=Z[Z.length-1];if(!z)return process.stderr.write(`${O}No checkpoints found to roll back to.${H}
476
+ `),1;return process.stdout.write(`Rolling back to latest checkpoint: ${A}${z.id}${H}
477
+ `),await u0(z.id,K.includes("--force"))}default:return process.stderr.write(`Unknown subcommand: ${Q}
478
+ `),process.stderr.write(f0),2}}async function u0($,Q=!1){let K;try{K=g0($)}catch(z){return process.stderr.write(`${O}Cannot plan rollback:${H} ${z.message}
479
+ `),1}if(K.restore.length===0)return process.stdout.write(`${I}Checkpoint ${$} has no restorable state files; nothing to do.${H}
480
+ `),0;let Z;try{Z=await m0(K,void 0,Q)}catch(z){return process.stderr.write(`${O}Rollback aborted:${H} ${z.message}
481
+ `),1}if(Z.errors.length>0){for(let z of Z.errors)process.stderr.write(`${O}restore error:${H} ${z}
482
+ `);return process.stderr.write(`${O}Partial rollback: ${Z.restored}/${K.restore.length} files restored.${H}
483
+ `),1}if(process.stdout.write(`${C}Rolled back ${Z.restored}/${K.restore.length} state files from ${$}.${H}
484
+ `),Z.preRollbackSnapshotId)process.stdout.write(`Saved your prior state as ${A}${Z.preRollbackSnapshotId}${H}; undo this rollback with \`loki rollback to ${Z.preRollbackSnapshotId}\`.
485
+ `);return process.stdout.write("Run `loki start` to resume from the restored state.\n"),0}var f0=`Usage: loki rollback <subcommand>
464
486
 
465
487
  Subcommands:
466
488
  list List checkpoints (newest first)
@@ -481,72 +503,72 @@ to the checkpoint's snapshot (if one was anchored at checkpoint time):
481
503
  git stash apply refs/loki/cp/<id>
482
504
 
483
505
  Re-run \`loki start\` to resume from the restored state.
484
- `;var S0=F(()=>{x0();l()});function G8(){return process.env.LOKI_TIER||"oss"}function N0($){let K=G8();if(K==="oss")return{allowed:!0,notes:[]};if(!process.env.LOKI_LICENSE_KEY)return{allowed:!1,notes:[`${I}LOKI_TIER='${K}' requested but no LOKI_LICENSE_KEY set.${U}`,`Hosted/enterprise license verification is not available yet (capability: ${$}).`,"OSS users: leave LOKI_TIER unset (or 'oss') -- everything stays free."]};return{allowed:!0,notes:[`${I}LOKI_LICENSE_KEY set but the verification backend is not available yet (R9 seam).${U}`]}}var D0=F(()=>{l()});var h0={};g(h0,{runProof:()=>F8});import{existsSync as T1,readdirSync as B8,readFileSync as C0,mkdtempSync as M8,copyFileSync as Y8,rmSync as T8}from"fs";import{join as i}from"path";import{tmpdir as O8}from"os";import{createInterface as A8}from"readline";import{readFile as _8}from"fs/promises";function e($){return $&&typeof $==="object"?$:{}}function u($){return $===void 0||$===null?"-":String($)}function O1(){return i(L(),"proofs")}function Z$($){let K=i(O1(),$,"proof.json");if(!T1(K))return null;try{return JSON.parse(C0(K,"utf8"))}catch{return{}}}function t($,K){return $.length>=K?$:$+" ".repeat(K-$.length)}function I8(){let $=O1();if(!T1($))return process.stdout.write(`${I}No proofs found.${U} Run 'loki start' to generate one.
485
- `),0;let K=[];try{K=B8($,{withFileTypes:!0}).filter((X)=>X.isDirectory()).map((X)=>X.name).sort()}catch{K=[]}let Q=[];for(let X of K){let Z=i($,X,"proof.json");if(!T1(Z))continue;let z={};try{z=JSON.parse(C0(Z,"utf8"))}catch{z={}}let H=u(z.run_id),V=u(z.generated_at),q=u(e(z.council).final_verdict),J=u(e(z.cost).usd),W=u(e(z.files_changed).count);Q.push(`${t(H,26)} ${t(V,20)} ${t(q,10)} ${t(J,9)} ${W}`)}if(Q.length===0)return process.stdout.write(`${I}No proofs found.${U} Run 'loki start' to generate one.
506
+ `;var p0=k(()=>{v0();l()});function o6(){return process.env.LOKI_TIER||"oss"}function l0($){let Q=o6();if(Q==="oss")return{allowed:!0,notes:[]};if(!process.env.LOKI_LICENSE_KEY)return{allowed:!1,notes:[`${I}LOKI_TIER='${Q}' requested but no LOKI_LICENSE_KEY set.${H}`,`Hosted/enterprise license verification is not available yet (capability: ${$}).`,"OSS users: leave LOKI_TIER unset (or 'oss') -- everything stays free."]};return{allowed:!0,notes:[`${I}LOKI_LICENSE_KEY set but the verification backend is not available yet (R9 seam).${H}`]}}var d0=k(()=>{l()});var n0={};g(n0,{runProof:()=>HQ});import{existsSync as _1,readdirSync as n6,readFileSync as o0,mkdtempSync as a6,copyFileSync as s6,rmSync as r6}from"fs";import{join as i}from"path";import{tmpdir as t6}from"os";import{createInterface as i6}from"readline";import{readFile as e6}from"fs/promises";function e($){return $&&typeof $==="object"?$:{}}function u($){return $===void 0||$===null?"-":String($)}function A1(){return i(L(),"proofs")}function W$($){let Q=i(A1(),$,"proof.json");if(!_1(Q))return null;try{return JSON.parse(o0(Q,"utf8"))}catch{return{}}}function t($,Q){return $.length>=Q?$:$+" ".repeat(Q-$.length)}function QQ(){let $=A1();if(!_1($))return process.stdout.write(`${I}No proofs found.${H} Run 'loki start' to generate one.
507
+ `),0;let Q=[];try{Q=n6($,{withFileTypes:!0}).filter((Z)=>Z.isDirectory()).map((Z)=>Z.name).sort()}catch{Q=[]}let K=[];for(let Z of Q){let z=i($,Z,"proof.json");if(!_1(z))continue;let U={};try{U=JSON.parse(o0(z,"utf8"))}catch{U={}}let X=u(U.run_id),W=u(U.generated_at),J=u(e(U.council).final_verdict),q=u(e(U.cost).usd),V=u(e(U.files_changed).count);K.push(`${t(X,26)} ${t(W,20)} ${t(J,10)} ${t(q,9)} ${V}`)}if(K.length===0)return process.stdout.write(`${I}No proofs found.${H} Run 'loki start' to generate one.
486
508
  `),0;process.stdout.write(`${t("RUN_ID",26)} ${t("GENERATED_AT",20)} ${t("VERDICT",10)} ${t("COST_USD",9)} FILES
487
- `);for(let X of Q)process.stdout.write(`${X}
488
- `);return 0}function j8($){if(!$)return process.stderr.write(`${O}Missing proof id.${U} Use 'loki proof list'.
489
- `),2;let K=Z$($);if(K===null)return process.stderr.write(`${O}Proof not found: ${$}${U}
509
+ `);for(let Z of K)process.stdout.write(`${Z}
510
+ `);return 0}function KQ($){if(!$)return process.stderr.write(`${O}Missing proof id.${H} Use 'loki proof list'.
511
+ `),2;let Q=W$($);if(Q===null)return process.stderr.write(`${O}Proof not found: ${$}${H}
490
512
  `),process.stderr.write(`Use 'loki proof list' to see available proofs.
491
- `),1;return process.stdout.write(`${JSON.stringify(K,null,2)}
492
- `),0}async function P8($){if(!$)return process.stderr.write(`${O}Missing proof id.${U} Use 'loki proof list'.
493
- `),2;let K=i(O1(),$,"index.html");if(!T1(K))return process.stderr.write(`${O}Proof page not found: ${$}/index.html${U}
513
+ `),1;return process.stdout.write(`${JSON.stringify(Q,null,2)}
514
+ `),0}async function ZQ($){if(!$)return process.stderr.write(`${O}Missing proof id.${H} Use 'loki proof list'.
515
+ `),2;let Q=i(A1(),$,"index.html");if(!_1(Q))return process.stderr.write(`${O}Proof page not found: ${$}/index.html${H}
494
516
  `),process.stderr.write(`Use 'loki proof list' to see available proofs.
495
- `),1;process.stdout.write(`${D}Opening proof: ${K}${U}
496
- `);for(let Q of["open","xdg-open","start"])try{if((await k([Q,K],{timeoutMs:5000})).exitCode===0)return 0}catch{}return process.stdout.write(`
517
+ `),1;process.stdout.write(`${C}Opening proof: ${Q}${H}
518
+ `);for(let K of["open","xdg-open","start"])try{if((await F([K,Q],{timeoutMs:5000})).exitCode===0)return 0}catch{}return process.stdout.write(`
497
519
  Could not detect browser opener.
498
- `),process.stdout.write(`Please open in browser: ${K}
499
- `),0}function L8($){return new Promise((K)=>{let Q=A8({input:process.stdin,output:process.stdout});Q.question($,(X)=>{Q.close();let Z=X.trim().toLowerCase();K(Z==="y"||Z==="yes")})})}async function k8($,K,Q){let X=N0("hosted_publish");for(let G of X.notes)process.stderr.write(`${G}
500
- `);let Z=process.env.LOKI_HOSTED_ENDPOINT||"";if(!Z)return process.stderr.write(`${I}Hosted publishing backend not available.${U}
520
+ `),process.stdout.write(`Please open in browser: ${Q}
521
+ `),0}function zQ($){return new Promise((Q)=>{let K=i6({input:process.stdin,output:process.stdout});K.question($,(Z)=>{K.close();let z=Z.trim().toLowerCase();Q(z==="y"||z==="yes")})})}async function XQ($,Q,K){let Z=l0("hosted_publish");for(let G of Z.notes)process.stderr.write(`${G}
522
+ `);let z=process.env.LOKI_HOSTED_ENDPOINT||"";if(!z)return process.stderr.write(`${I}Hosted publishing backend not available.${H}
501
523
  `),process.stderr.write(`There is no official Loki hosted service yet (R9 ships the seam, not a live backend).
502
524
  `),process.stderr.write(`To publish to your own hosted endpoint, set LOKI_HOSTED_ENDPOINT to its URL.
503
525
  `),process.stderr.write(`Or publish to a GitHub Gist instead: loki proof share ${$}
504
- `),1;let z=Z$($);if(z){if(e(z.redaction).applied!==!0)return process.stderr.write(`${O}Refusing to publish: proof redaction was not confirmed applied.${U}
526
+ `),1;let U=W$($);if(U){if(e(U.redaction).applied!==!0)return process.stderr.write(`${O}Refusing to publish: proof redaction was not confirmed applied.${H}
505
527
  `),process.stderr.write(`Regenerate the proof (LOKI_PROOF=1) so the redactor runs, then retry.
506
- `),1}process.stdout.write(`${S}Publishing proof '${$}' to hosted endpoint${U}
507
- `),process.stdout.write(` endpoint: ${Z}
508
- `),process.stdout.write(` payload: ${K} (already redacted by the generator)
528
+ `),1}process.stdout.write(`${x}Publishing proof '${$}' to hosted endpoint${H}
529
+ `),process.stdout.write(` endpoint: ${z}
530
+ `),process.stdout.write(` payload: ${Q} (already redacted by the generator)
509
531
 
510
- `);let H;try{H=await _8(K)}catch{return process.stderr.write(`${O}Could not read proof page: ${K}${U}
511
- `),1}let V={"Content-Type":"text/html","X-Loki-Proof-Id":$},q=process.env.LOKI_LICENSE_KEY||"";if(q)V.Authorization=`Bearer ${q}`;let J;try{J=await fetch(Z,{method:"POST",headers:V,body:new Uint8Array(H)})}catch(G){return process.stderr.write(`${O}Failed to reach hosted endpoint: ${String(G.message||G)}${U}
532
+ `);let X;try{X=await e6(Q)}catch{return process.stderr.write(`${O}Could not read proof page: ${Q}${H}
533
+ `),1}let W={"Content-Type":"text/html","X-Loki-Proof-Id":$},J=process.env.LOKI_LICENSE_KEY||"";if(J)W.Authorization=`Bearer ${J}`;let q;try{q=await fetch(z,{method:"POST",headers:W,body:new Uint8Array(X)})}catch(G){return process.stderr.write(`${O}Failed to reach hosted endpoint: ${String(G.message||G)}${H}
512
534
  `),process.stderr.write(`Check LOKI_HOSTED_ENDPOINT or publish to a gist: loki proof share ${$}
513
- `),1}let W=await J.text();if(!J.ok){if(process.stderr.write(`${O}Hosted endpoint returned HTTP ${J.status}.${U}
514
- `),W)process.stderr.write(`Response:
515
- `),process.stderr.write(`${W.slice(0,500)}
535
+ `),1}let V=await q.text();if(!q.ok){if(process.stderr.write(`${O}Hosted endpoint returned HTTP ${q.status}.${H}
536
+ `),V)process.stderr.write(`Response:
537
+ `),process.stderr.write(`${V.slice(0,500)}
516
538
  `);return process.stderr.write(`Nothing was published. Or publish to a gist: loki proof share ${$}
517
- `),1}let M="";try{let G=JSON.parse(W);if(G&&typeof G==="object"){let B=G.url??G.public_url;if(typeof B==="string")M=B}}catch{}if(M)process.stdout.write(`${D}Published: ${M}${U}
518
- `);else process.stdout.write(`${D}Published to ${Z} (HTTP ${J.status}).${U}
539
+ `),1}let M="";try{let G=JSON.parse(V);if(G&&typeof G==="object"){let B=G.url??G.public_url;if(typeof B==="string")M=B}}catch{}if(M)process.stdout.write(`${C}Published: ${M}${H}
540
+ `);else process.stdout.write(`${C}Published to ${z} (HTTP ${q.status}).${H}
519
541
  `),process.stdout.write(`The endpoint did not return a 'url' field; check your endpoint's response.
520
- `);return 0}async function x8($){let K="",Q=!1,X="--public",Z=!1;for(let Y of $)if(Y==="--yes"||Y==="-y")Q=!0;else if(Y==="--private")X="";else if(Y==="--public")X="--public";else if(Y==="--hosted")Z=!0;else if(Y.startsWith("-"))return process.stderr.write(`${O}Unknown option: ${Y}${U}
521
- `),1;else K=Y;if(!K)return process.stderr.write(`${O}Missing proof id.${U} Use 'loki proof list'.
522
- `),2;let z=i(O1(),K,"index.html");if(!T1(z))return process.stderr.write(`${O}Proof page not found: ${K}/index.html${U}
542
+ `);return 0}async function UQ($){let Q="",K=!1,Z="--public",z=!1;for(let Y of $)if(Y==="--yes"||Y==="-y")K=!0;else if(Y==="--private")Z="";else if(Y==="--public")Z="--public";else if(Y==="--hosted")z=!0;else if(Y.startsWith("-"))return process.stderr.write(`${O}Unknown option: ${Y}${H}
543
+ `),1;else Q=Y;if(!Q)return process.stderr.write(`${O}Missing proof id.${H} Use 'loki proof list'.
544
+ `),2;let U=i(A1(),Q,"index.html");if(!_1(U))return process.stderr.write(`${O}Proof page not found: ${Q}/index.html${H}
523
545
  `),process.stderr.write(`Use 'loki proof list' to see available proofs.
524
- `),1;if(Z)return k8(K,z,i(O1(),K,"proof.json"));if((await k(["gh","--version"],{timeoutMs:5000})).exitCode!==0)return process.stderr.write(`${O}gh CLI not found${U}
546
+ `),1;if(z)return XQ(Q,U,i(A1(),Q,"proof.json"));if((await F(["gh","--version"],{timeoutMs:5000})).exitCode!==0)return process.stderr.write(`${O}gh CLI not found${H}
525
547
  `),process.stderr.write(`Install the GitHub CLI to publish a proof:
526
548
  `),process.stderr.write(` brew install gh # macOS
527
549
  `),process.stderr.write(` sudo apt install gh # Ubuntu/Debian
528
550
  `),process.stderr.write(` https://cli.github.com # Other platforms
529
- `),1;if((await k(["gh","auth","status"],{timeoutMs:1e4})).exitCode!==0)return process.stderr.write(`${O}GitHub CLI not authenticated${U}
551
+ `),1;if((await F(["gh","auth","status"],{timeoutMs:1e4})).exitCode!==0)return process.stderr.write(`${O}GitHub CLI not authenticated${H}
530
552
  `),process.stderr.write(`Run 'gh auth login' to authenticate, then try again.
531
- `),1;let q=X===""?"secret":"public";process.stdout.write(`${S}Publishing proof '${K}' as a ${q} GitHub Gist${U}
553
+ `),1;let J=Z===""?"secret":"public";process.stdout.write(`${x}Publishing proof '${Q}' as a ${J} GitHub Gist${H}
532
554
 
533
555
  `),process.stdout.write(`What will be shared:
534
- `),process.stdout.write(` - ${z}
535
- `);let J=Z$(K);if(J){let Y=u(e(J.cost).usd),R=u(e(J.files_changed).count),E=u(e(J.council).final_verdict),C=e(J.redaction);process.stdout.write(` - cost.usd: ${Y}
536
- `),process.stdout.write(` - files_changed: ${R}
537
- `),process.stdout.write(` - council verdict: ${E}
538
- `),process.stdout.write(` - redaction: applied=${u(C.applied)} rules_version=${u(C.rules_version)} redactions_count=${u(C.redactions_count)}
556
+ `),process.stdout.write(` - ${U}
557
+ `);let q=W$(Q);if(q){let Y=u(e(q.cost).usd),E=u(e(q.files_changed).count),S=u(e(q.council).final_verdict),D=e(q.redaction);process.stdout.write(` - cost.usd: ${Y}
558
+ `),process.stdout.write(` - files_changed: ${E}
559
+ `),process.stdout.write(` - council verdict: ${S}
560
+ `),process.stdout.write(` - redaction: applied=${u(D.applied)} rules_version=${u(D.rules_version)} redactions_count=${u(D.redactions_count)}
539
561
  `)}if(process.stdout.write(`
540
- ${I}Secrets, API keys, tokens, env values, and absolute paths have already been stripped by the generator.${U}
562
+ ${I}Secrets, API keys, tokens, env values, and absolute paths have already been stripped by the generator.${H}
541
563
 
542
- `),!Q){if(!await L8(`Publish this proof to a ${q} gist? [y/N] `))return process.stdout.write(`Aborted. Nothing was published.
543
- `),0}let W=M8(i(O8(),"loki-proof-")),M=i(W,"index.html");Y8(z,M),process.stdout.write(`Uploading proof page...
544
- `);let G=`Loki Mode proof-of-run ${K}`,B=["gh","gist","create",M,"--desc",G];if(X!=="")B.push(X);let T=await k(B,{timeoutMs:60000});try{T8(W,{recursive:!0,force:!0})}catch{}if(T.exitCode!==0)return process.stderr.write(`${O}Failed to create gist${U}
564
+ `),!K){if(!await zQ(`Publish this proof to a ${J} gist? [y/N] `))return process.stdout.write(`Aborted. Nothing was published.
565
+ `),0}let V=a6(i(t6(),"loki-proof-")),M=i(V,"index.html");s6(U,M),process.stdout.write(`Uploading proof page...
566
+ `);let G=`Loki Mode proof-of-run ${Q}`,B=["gh","gist","create",M,"--desc",G];if(Z!=="")B.push(Z);let T=await F(B,{timeoutMs:60000});try{r6(V,{recursive:!0,force:!0})}catch{}if(T.exitCode!==0)return process.stderr.write(`${O}Failed to create gist${H}
545
567
  `),process.stderr.write(`${T.stdout}${T.stderr}
546
- `),1;return process.stdout.write(`${D}Shared: ${T.stdout.trim()}${U}
547
- `),0}async function F8($){let K=$[0],Q=$.slice(1);if(K===void 0||K==="help"||K==="--help"||K==="-h")return process.stdout.write(w8),K===void 0?1:0;switch(K){case"list":return I8();case"show":return j8(Q[0]);case"open":return P8(Q[0]);case"share":return x8(Q);default:return process.stderr.write(`${O}Unknown subcommand: ${K}${U}
568
+ `),1;return process.stdout.write(`${C}Shared: ${T.stdout.trim()}${H}
569
+ `),0}async function HQ($){let Q=$[0],K=$.slice(1);if(Q===void 0||Q==="help"||Q==="--help"||Q==="-h")return process.stdout.write($Q),Q===void 0?1:0;switch(Q){case"list":return QQ();case"show":return KQ(K[0]);case"open":return ZQ(K[0]);case"share":return UQ(K);default:return process.stderr.write(`${O}Unknown subcommand: ${Q}${H}
548
570
  `),process.stderr.write(`Run 'loki proof --help' for usage.
549
- `),1}}var w8;var b0=F(()=>{v();n();l();D0();w8=`${S}loki proof${U} - inspect and share proof-of-run artifacts
571
+ `),1}}var $Q;var a0=k(()=>{m();n();l();d0();$Q=`${x}loki proof${H} - inspect and share proof-of-run artifacts
550
572
 
551
573
  Usage: loki proof <subcommand> [args]
552
574
 
@@ -562,15 +584,15 @@ Options for 'share':
562
584
  --hosted Publish to LOKI_HOSTED_ENDPOINT (open-core seam; no official backend yet)
563
585
 
564
586
  Proofs are generated automatically at run completion (LOKI_PROOF=0 to opt out).
565
- `});var m0={};g(m0,{runWiki:()=>D8});import{existsSync as z$,readFileSync as y0}from"fs";import{join as H$,resolve as R8}from"path";function S8(){return H$(process.cwd(),".loki","wiki")}function N8($){let K="";for(let Z of $){if(Z==="--help"||Z==="-h")return process.stdout.write(`Usage: loki wiki show [section]
587
+ `});var i0={};g(i0,{runWiki:()=>GQ});import{existsSync as J$,readFileSync as s0}from"fs";import{join as q$,resolve as WQ}from"path";function qQ(){return q$(process.cwd(),".loki","wiki")}function VQ($){let Q="";for(let z of $){if(z==="--help"||z==="-h")return process.stdout.write(`Usage: loki wiki show [section]
566
588
  Sections: architecture, modules, data-flow
567
- `),0;if(Z.startsWith("-"))return process.stderr.write(`${O}Unknown option: ${Z}${U}
568
- `),1;K=Z}let Q=S8();if(!z$(Q))return process.stderr.write(`${I}No wiki found. Run 'loki wiki generate' first.${U}
569
- `),1;if(K){if(!E8.has(K))return process.stderr.write(`${O}No such section: ${K} (try: architecture, modules, data-flow)${U}
570
- `),1;let Z=H$(Q,`${K}.md`);if(!z$(Z))return process.stderr.write(`${O}Section not generated: ${K}${U}
571
- `),1;return process.stdout.write(y0(Z,"utf8")),0}let X=H$(Q,"index.md");if(!z$(X))return process.stderr.write(`${O}Wiki index not found. Run 'loki wiki generate'.${U}
572
- `),1;return process.stdout.write(y0(X,"utf8")),0}async function v0($,K){let Q=R8(p,"autonomy","loki"),X=3600000,Z=Bun.spawn({cmd:[Q,"wiki",$,...K],stdin:"inherit",stdout:"inherit",stderr:"inherit",env:{...process.env,LOKI_LEGACY_BASH:"1"}}),z=setTimeout(()=>{try{Z.kill("SIGKILL")}catch{}},3600000);try{return await Z.exited}finally{clearTimeout(z)}}async function D8($){let K=$[0],Q=$.slice(1);switch(K){case void 0:case"help":case"--help":case"-h":return process.stdout.write(g0),0;case"show":return N8(Q);case"generate":return v0("generate",Q);case"ask":return v0("ask",Q);default:return process.stderr.write(`${O}Unknown wiki command: ${K}${U}
573
- `),process.stdout.write(g0),1}}var g0,E8;var f0=F(()=>{v();l();g0=`${S}loki wiki${U} - Auto-generated, cited codebase wiki + Q&A
589
+ `),0;if(z.startsWith("-"))return process.stderr.write(`${O}Unknown option: ${z}${H}
590
+ `),1;Q=z}let K=qQ();if(!J$(K))return process.stderr.write(`${I}No wiki found. Run 'loki wiki generate' first.${H}
591
+ `),1;if(Q){if(!JQ.has(Q))return process.stderr.write(`${O}No such section: ${Q} (try: architecture, modules, data-flow)${H}
592
+ `),1;let z=q$(K,`${Q}.md`);if(!J$(z))return process.stderr.write(`${O}Section not generated: ${Q}${H}
593
+ `),1;return process.stdout.write(s0(z,"utf8")),0}let Z=q$(K,"index.md");if(!J$(Z))return process.stderr.write(`${O}Wiki index not found. Run 'loki wiki generate'.${H}
594
+ `),1;return process.stdout.write(s0(Z,"utf8")),0}async function t0($,Q){let K=WQ(p,"autonomy","loki"),Z=3600000,z=Bun.spawn({cmd:[K,"wiki",$,...Q],stdin:"inherit",stdout:"inherit",stderr:"inherit",env:{...process.env,LOKI_LEGACY_BASH:"1"}}),U=setTimeout(()=>{try{z.kill("SIGKILL")}catch{}},3600000);try{return await z.exited}finally{clearTimeout(U)}}async function GQ($){let Q=$[0],K=$.slice(1);switch(Q){case void 0:case"help":case"--help":case"-h":return process.stdout.write(r0),0;case"show":return VQ(K);case"generate":return t0("generate",K);case"ask":return t0("ask",K);default:return process.stderr.write(`${O}Unknown wiki command: ${Q}${H}
595
+ `),process.stdout.write(r0),1}}var r0,JQ;var e0=k(()=>{m();l();r0=`${x}loki wiki${H} - Auto-generated, cited codebase wiki + Q&A
574
596
 
575
597
  Usage: loki wiki <command> [options]
576
598
 
@@ -586,8 +608,8 @@ Examples:
586
608
  loki wiki generate
587
609
  loki wiki show architecture
588
610
  loki wiki ask "how does the cli dispatch commands"
589
- `,E8=new Set(["architecture","modules","data-flow"])});var V$={};g(V$,{renderFindingsForPrompt:()=>g8,loadPreviousFindings:()=>U$,findLatestReviewDir:()=>d0,_parseReviewerOutputForTests:()=>v8});import{existsSync as c0,readFileSync as u0,readdirSync as p0,statSync as C8}from"fs";import{join as D1}from"path";function y8($){let K=$.toLowerCase();if(K==="critical")return"Critical";if(K==="high")return"High";if(K==="medium")return"Medium";return"Low"}function l0($,K,Q,X){let Z=[],z=$.split(/\r?\n/);for(let H of z){let V=H.trim();if(V.length===0)continue;let q=V.replace(/^[-*]\s*/,""),J=h8.exec(q);if(!J||!J[1]||!J[2])continue;let W=y8(J[1]),M=J[2].trim(),G=b8.exec(M),B=G&&G[1]?G[1]:null,T=G&&G[2]?Number.parseInt(G[2],10):null;Z.push({reviewId:Q,iteration:X,reviewer:K,severity:W,description:M,file:B,line:Number.isFinite(T)?T:null,raw:V})}return Z}function d0($,K){let Q=D1($,"quality","reviews");if(!c0(Q))return null;let X;try{X=p0(Q)}catch{return null}let Z=K===void 0?X.filter((V)=>V.startsWith("review-")):X.filter((V)=>V.endsWith(`-${K}`)&&V.startsWith("review-"));if(Z.length===0)return null;Z.sort();let z=Z[Z.length-1];if(!z)return null;let H=D1(Q,z);try{if(!C8(H).isDirectory())return null}catch{return null}return H}function U$($,K){let Q=d0($,K);if(Q===null)return{reviewDir:null,reviewId:null,iteration:null,findings:[]};let X=null,Z=null,z=D1(Q,"aggregate.json");if(c0(z))try{let J=u0(z,"utf-8"),W=JSON.parse(J);if(typeof W.review_id==="string")X=W.review_id;if(typeof W.iteration==="number")Z=W.iteration}catch{}let H;try{H=p0(Q)}catch{return{reviewDir:Q,reviewId:X,iteration:Z,findings:[]}}let V=new Set(["diff.txt","files.txt","anti-sycophancy.txt"]),q=[];for(let J of H){if(!J.endsWith(".txt"))continue;if(V.has(J))continue;if(J.endsWith("-prompt.txt"))continue;let W=J.replace(/\.txt$/,""),M;try{M=u0(D1(Q,J),"utf-8")}catch{continue}q.push(...l0(M,W,X??"",Z??-1))}return{reviewDir:Q,reviewId:X,iteration:Z,findings:q}}function g8($){if($.length===0)return"";let K=["Critical","High","Medium","Low"],Q=new Map;for(let Z of K)Q.set(Z,[]);for(let Z of $){let z=Q.get(Z.severity);if(z)z.push(Z)}let X=[];X.push("PREVIOUS REVIEWER FINDINGS (must address each, or supply counter-evidence in .loki/state/counter-evidence-<iter>.json):");for(let Z of K){let z=Q.get(Z)??[];if(z.length===0)continue;X.push(` [${Z}] (${z.length}):`);for(let H of z){let V=H.file?` (${H.file}${H.line!==null?":"+H.line:""})`:"";X.push(` - ${H.description}${V} -- via ${H.reviewer}`)}}return X.join(`
590
- `)}function v8($,K,Q="review-test",X=0){return l0($,K,Q,X)}var h8,b8;var C1=F(()=>{h8=/\[(Critical|High|Medium|Low)\]\s*(.+)/i,b8=/([\w.\-/]+\.[a-zA-Z]+):(\d+)/});import{existsSync as m8}from"fs";import{join as f8}from"path";async function o0($,K){let Q=f8($,"memory");if(!m8(Q))return{stored:!1,reason:"memory dir not initialized"};let X=Math.max(0,Math.floor(K.durationSeconds??0)),Z={_LOKI_PROJECT_DIR:p,_LOKI_TARGET_DIR:process.cwd(),_LOKI_TASK_ID:K.taskId,_LOKI_OUTCOME:K.outcome,_LOKI_PHASE:K.phase,_LOKI_GOAL:K.goal,_LOKI_DURATION:String(X),_LOKI_LOKI_DIR:$},H=await K1(`
611
+ `,JQ=new Set(["architecture","modules","data-flow"])});var G$={};g(G$,{renderFindingsForPrompt:()=>OQ,loadPreviousFindings:()=>V$,findLatestReviewDir:()=>z7,_parseReviewerOutputForTests:()=>_Q});import{existsSync as Q7,readFileSync as $7,readdirSync as K7,statSync as BQ}from"fs";import{join as b1}from"path";function TQ($){let Q=$.toLowerCase();if(Q==="critical")return"Critical";if(Q==="high")return"High";if(Q==="medium")return"Medium";return"Low"}function Z7($,Q,K,Z){let z=[],U=$.split(/\r?\n/);for(let X of U){let W=X.trim();if(W.length===0)continue;let J=W.replace(/^[-*]\s*/,""),q=MQ.exec(J);if(!q||!q[1]||!q[2])continue;let V=TQ(q[1]),M=q[2].trim(),G=YQ.exec(M),B=G&&G[1]?G[1]:null,T=G&&G[2]?Number.parseInt(G[2],10):null;z.push({reviewId:K,iteration:Z,reviewer:Q,severity:V,description:M,file:B,line:Number.isFinite(T)?T:null,raw:W})}return z}function z7($,Q){let K=b1($,"quality","reviews");if(!Q7(K))return null;let Z;try{Z=K7(K)}catch{return null}let z=Q===void 0?Z.filter((W)=>W.startsWith("review-")):Z.filter((W)=>W.endsWith(`-${Q}`)&&W.startsWith("review-"));if(z.length===0)return null;z.sort();let U=z[z.length-1];if(!U)return null;let X=b1(K,U);try{if(!BQ(X).isDirectory())return null}catch{return null}return X}function V$($,Q){let K=z7($,Q);if(K===null)return{reviewDir:null,reviewId:null,iteration:null,findings:[]};let Z=null,z=null,U=b1(K,"aggregate.json");if(Q7(U))try{let q=$7(U,"utf-8"),V=JSON.parse(q);if(typeof V.review_id==="string")Z=V.review_id;if(typeof V.iteration==="number")z=V.iteration}catch{}let X;try{X=K7(K)}catch{return{reviewDir:K,reviewId:Z,iteration:z,findings:[]}}let W=new Set(["diff.txt","files.txt","anti-sycophancy.txt"]),J=[];for(let q of X){if(!q.endsWith(".txt"))continue;if(W.has(q))continue;if(q.endsWith("-prompt.txt"))continue;let V=q.replace(/\.txt$/,""),M;try{M=$7(b1(K,q),"utf-8")}catch{continue}J.push(...Z7(M,V,Z??"",z??-1))}return{reviewDir:K,reviewId:Z,iteration:z,findings:J}}function OQ($){if($.length===0)return"";let Q=["Critical","High","Medium","Low"],K=new Map;for(let z of Q)K.set(z,[]);for(let z of $){let U=K.get(z.severity);if(U)U.push(z)}let Z=[];Z.push("PREVIOUS REVIEWER FINDINGS (must address each, or supply counter-evidence in .loki/state/counter-evidence-<iter>.json):");for(let z of Q){let U=K.get(z)??[];if(U.length===0)continue;Z.push(` [${z}] (${U.length}):`);for(let X of U){let W=X.file?` (${X.file}${X.line!==null?":"+X.line:""})`:"";Z.push(` - ${X.description}${W} -- via ${X.reviewer}`)}}return Z.join(`
612
+ `)}function _Q($,Q,K="review-test",Z=0){return Z7($,Q,K,Z)}var MQ,YQ;var y1=k(()=>{MQ=/\[(Critical|High|Medium|Low)\]\s*(.+)/i,YQ=/([\w.\-/]+\.[a-zA-Z]+):(\d+)/});import{existsSync as AQ}from"fs";import{join as wQ}from"path";async function X7($,Q){let K=wQ($,"memory");if(!AQ(K))return{stored:!1,reason:"memory dir not initialized"};let Z=Math.max(0,Math.floor(Q.durationSeconds??0)),z={_LOKI_PROJECT_DIR:p,_LOKI_TARGET_DIR:process.cwd(),_LOKI_TASK_ID:Q.taskId,_LOKI_OUTCOME:Q.outcome,_LOKI_PHASE:Q.phase,_LOKI_GOAL:Q.goal,_LOKI_DURATION:String(Z),_LOKI_LOKI_DIR:$},X=await Q1(`
591
613
  import os, sys
592
614
  project = os.environ.get('_LOKI_PROJECT_DIR', '')
593
615
  loki = os.environ.get('_LOKI_LOKI_DIR', '.loki')
@@ -614,23 +636,23 @@ try:
614
636
  print('OK')
615
637
  except Exception as e:
616
638
  print('ERR:' + str(e))
617
- `,{env:Z,timeoutMs:15000});if(H.exitCode===127)return{stored:!1,reason:"python3 not found"};let V=H.stdout.trim();if(V==="OK")return{stored:!0,reason:"stored"};if(V.startsWith("ERR:"))return{stored:!1,reason:V.replace(/^ERR:/,"")};return{stored:!1,reason:H.stderr.trim()||"unknown"}}var n0=F(()=>{G1();v()});var t0={};g(t0,{loadLearnings:()=>q$,appendLearning:()=>A1,appendFromGateFailure:()=>a8});import{existsSync as u8,readFileSync as c8}from"fs";import{join as a0}from"path";import{createHash as p8}from"crypto";function s0($){return a0($,l8)}function d8($){if($===null||typeof $!=="object")return!1;let K=$;return typeof K.id==="string"&&typeof K.timestamp==="string"&&typeof K.iteration==="number"&&typeof K.trigger==="string"&&typeof K.rootCause==="string"&&typeof K.fix==="string"&&typeof K.preventInFuture==="string"&&typeof K.evidence==="object"&&K.evidence!==null}function r0($){if(!u8($))return{version:1,learnings:[]};try{let K=c8($,"utf-8"),Q=JSON.parse(K);if(Q.version===1&&Array.isArray(Q.learnings))return{version:1,learnings:Q.learnings.filter(d8)}}catch{}return{version:1,learnings:[]}}function o8($,K){return p8("sha256").update(`${$}\x00${K}`).digest("hex").slice(0,16)}async function A1($,K,Q={}){let X=o8(K.trigger,K.rootCause),Z=new Date().toISOString(),z={id:X,timestamp:Z,...K},H=s0($);if(await J0(H,()=>{let q=r0(H),J=q.learnings.findIndex((W)=>W.id===X);if(J>=0){let W=q.learnings[J];q.learnings[J]={...W,timestamp:Z,iteration:z.iteration}}else q.learnings.push(z);Y1(H,q)}),Q.episodeBridge!==null&&(Q.episodeBridge!==void 0||process.env.LOKI_AUTO_LEARNINGS_EPISODE==="1")){let q=Q.episodeBridge??o0,J=Q.bridgeFailureLog??n8;try{let W=await q($,{taskId:`learning-${X}`,outcome:"failure",phase:"VERIFY",goal:`${K.trigger}: ${K.rootCause}`});if(W&&!W.stored){if(!new Set(["memory dir not initialized","stub"]).has(W.reason))J(`episode_bridge skipped: ${W.reason}`)}}catch(W){J(`episode_bridge threw: ${W.message}`)}}return z}function n8($){process.stderr.write(`[learnings_writer] ${$}
618
- `)}async function a8($,K,Q,X={}){let Z=`[${Q.severity}] ${Q.description}`;return A1($,{iteration:K,trigger:"gate_failure",rootCause:Z,fix:"pending: dev agent must address in next iteration or supply counter-evidence",preventInFuture:"if this finding recurs, lower its severity threshold or add a regression test",evidence:{reviewId:Q.reviewId,file:Q.file??void 0,line:Q.line??void 0,severity:Q.severity,reviewer:Q.reviewer}},X)}function q$($){return r0(s0($))}var l8;var h1=F(()=>{S1();n0();l8=a0("state","relevant-learnings.json")});var e0={};g(e0,{runOverrideCouncil:()=>$K,recordOverrideOutcome:()=>KK,loadCounterEvidence:()=>e8,canonicalFindingId:()=>J$,DEFAULT_OVERRIDE_JUDGES:()=>i0});import{existsSync as s8,readFileSync as r8}from"fs";import{join as t8}from"path";function e8($,K){let Q=t8($,"state",`counter-evidence-${K}.json`);if(!s8(Q))return null;try{let X=r8(Q,"utf-8"),Z=JSON.parse(X);if(typeof Z.iteration!=="number")return null;let z=Array.isArray(Z.evidence)?Z.evidence:[],H=[];for(let V of z){if(typeof V!=="object"||V===null)continue;let q=V;if(typeof q.findingId!=="string")continue;if(typeof q.claim!=="string")continue;let J=q.proofType;if(typeof J!=="string"||!i8.has(J))continue;let W=J,M=Array.isArray(q.artifacts)?q.artifacts:[];H.push({findingId:q.findingId,claim:q.claim,proofType:W,artifacts:M.filter((G)=>typeof G==="string")})}return{iteration:Z.iteration,evidence:H}}catch{return null}}async function $K($,K,Q,X={}){let Z=X.judges??i0,z=new Set,H=new Set,V={},q=new Map;for(let J of K.evidence)q.set(J.findingId,J);for(let J of $){let W=J$(J),M=q.get(W);if(!M){H.add(W);continue}let G=await Promise.all(Z.map((T)=>Q({finding:J,evidence:M,judge:T})));if(V[W]=G,G.filter((T)=>T.verdict==="APPROVE_OVERRIDE").length>=2)z.add(W);else H.add(W)}return{approvedFindingIds:z,rejectedFindingIds:H,votes:V}}function J$($){let K=$.raw.slice(0,80).replace(/\s+/g," ").trim();return`${$.reviewer}::${K}`}async function KK($,K,Q,X,Z={}){let z={episodeBridge:Z.episodeBridge===void 0?null:Z.episodeBridge};for(let H of X){let V=J$(H);if(Q.approvedFindingIds.has(V))await A1($,{iteration:K,trigger:"override_approved",rootCause:`[${H.severity}] ${H.description}`,fix:"override council approved counter-evidence; finding lifted",preventInFuture:"if this reviewer/file pair recurs, narrow the reviewer's selector OR add a baseline doc",evidence:{findingId:V,reviewId:H.reviewId,file:H.file??void 0,line:H.line??void 0,severity:H.severity,reviewer:H.reviewer}},z);else if(Q.rejectedFindingIds.has(V))await A1($,{iteration:K,trigger:"override_rejected",rootCause:`[${H.severity}] ${H.description}`,fix:"override council rejected -- dev agent must fix the finding",preventInFuture:"address this finding in the next iteration",evidence:{findingId:V,reviewId:H.reviewId,file:H.file??void 0,line:H.line??void 0,severity:H.severity,reviewer:H.reviewer}},z)}}var i8,i0;var $5=F(()=>{h1();i8=new Set(["file-exists","test-passes","grep-miss","reviewer-misread","duplicate-code-path","out-of-scope"]);i0=["judge-primary","judge-secondary","judge-tertiary"]});var X5={};g(X5,{writeEscalationHandoff:()=>BK,renderHandoff:()=>K5,readLatestHandoff:()=>MK});import{existsSync as QK,mkdirSync as XK,readdirSync as ZK,readFileSync as zK,renameSync as HK,writeFileSync as UK}from"fs";import{dirname as VK,join as b1}from"path";function qK(){return new Date().toISOString()}function JK($){let K=$.file?` (${$.file}${$.line!==null?":"+$.line:""})`:"";return` - [${$.severity}] ${$.description}${K} -- ${$.reviewer}`}function WK($){let K=$.evidence,Q=K.file?` ${K.file}${K.line!==void 0?":"+K.line:""}`:"";return` - **${$.trigger}** (iter ${$.iteration})${Q}: ${$.rootCause}`}function K5($,K,Q){let X=[];if(X.push(`# Loki escalation handoff -- ${qK()}`),X.push(""),X.push(`Gate **${$.gateName}** has failed ${$.consecutiveFailures} consecutive times at iteration ${$.iteration}.`),X.push(""),X.push(`Reason: ${$.detail}`),X.push(""),K.length>0){X.push(`## Outstanding findings (${K.length})`),X.push("");for(let Z of K)X.push(JK(Z));X.push("")}else X.push("## Outstanding findings"),X.push(""),X.push("(no per-finding records captured -- gate failed without populating reviewer outputs)"),X.push("");if(Q.length>0){X.push(`## Recent learnings (${Math.min(Q.length,10)})`),X.push("");for(let Z of Q.slice(-10))X.push(WK(Z));X.push("")}return X.push("## What the human must decide"),X.push(""),X.push("- Approve override? Write `.loki/state/counter-evidence-<iter>.json` with one entry per finding to dispute, then `rm .loki/PAUSE` to resume."),X.push("- Disable a gate? Set `LOKI_GATE_<NAME>=false` in env (see skills/quality-gates.md)."),X.push("- Tweak escalation? Set `LOKI_GATE_PAUSE_LIMIT` or `LOKI_GATE_ESCALATE_LIMIT`."),X.push("- Roll back? Switch to `LOKI_LEGACY_BASH=1` and re-run; the bash route does not consult this handoff doc."),X.push(""),X.push("To resume: address the findings (or supply counter-evidence) and `rm .loki/PAUSE`."),X.join(`
619
- `)}function GK($,K){XK(VK($),{recursive:!0});let Q=`${$}.tmp.${process.pid}.${++Q5}`;UK(Q,K),HK(Q,$)}function BK($,K,Q={}){let X=Q.findings??U$($,K.iteration).findings,Z=Q.learnings??q$($).learnings,z=K5(K,X,Z),H=(Q.now?.()??new Date).toISOString().replace(/[-:.]/g,""),V=b1($,"escalations"),q=++Q5,J=b1(V,`handoff-${H}-${process.pid}-${q}-${K.gateName}.md`);return GK(J,z),{path:J,bytes:z.length}}function MK($){let K=b1($,"escalations");if(!QK(K))return null;let Q;try{Q=ZK(K).filter((z)=>z.endsWith(".md"))}catch{return null}if(Q.length===0)return null;Q.sort();let X=Q[Q.length-1];if(!X)return null;let Z=b1(K,X);try{return{path:Z,body:zK(Z,"utf-8")}}catch{return null}}var Q5=0;var Z5=F(()=>{C1();h1()});var z5={};g(z5,{runInternalPhase1Hooks:()=>wK,_resolveForTests:()=>_K,_internalPhase1HooksHelp:()=>LK});import{existsSync as YK,mkdirSync as TK,readdirSync as OK,statSync as AK}from"fs";import{join as _1,resolve as _K}from"path";async function wK($){let[K,...Q]=$;switch(K){case void 0:case"help":case"--help":case"-h":return process.stdout.write(W$),K===void 0?1:0;case"reflect":return IK(Q);case"override":return jK(Q);case"handoff":return PK(Q);default:return process.stderr.write(`Unknown subcommand: ${K}
620
- `),process.stderr.write(W$),2}}async function IK($){let K=G$($[0]);if(K===null)return process.stderr.write(`reflect: missing or invalid <iter>
621
- `),2;let Q=L();try{let Z=(await Promise.resolve().then(() => (C1(),V$))).loadPreviousFindings(Q,K);if(Z.findings.length===0)return process.stdout.write(`reflect: no findings for iter ${K} (nothing to do)
622
- `),0;let z=_1(Q,"state");TK(z,{recursive:!0}),Y1(_1(z,`findings-${K}.json`),{review_id:Z.reviewId,iteration:K,findings:Z.findings});let H=await Promise.resolve().then(() => (h1(),t0)),V=0;if(process.env.LOKI_AUTO_LEARNINGS!=="0"){for(let q of Z.findings)if(q.severity==="Critical"||q.severity==="High")await H.appendFromGateFailure(Q,K,q,{episodeBridge:null}),V+=1}return process.stdout.write(`reflect: persisted ${Z.findings.length} findings + ${V} learnings (iter ${K})
623
- `),0}catch(X){return process.stderr.write(`reflect: ${X.message}
624
- `),1}}async function jK($){let K=G$($[0]);if(K===null)return process.stderr.write(`override: missing or invalid <iter>
625
- `),2;let Q=L();try{let X=await Promise.resolve().then(() => ($5(),e0)),Z=X.loadCounterEvidence(Q,K);if(Z===null||Z.evidence.length===0)return process.stdout.write(`override: no counter-evidence for iter ${K} (skip)
626
- `),0;let H=(await Promise.resolve().then(() => (C1(),V$))).loadPreviousFindings(Q,K),V=H.findings.filter((Y)=>Y.severity==="Critical"||Y.severity==="High");if(V.length===0)return process.stdout.write(`override: no blocking findings for iter ${K} (skip)
627
- `),0;let q=new Set(["duplicate-code-path","file-exists","test-passes","grep-miss","out-of-scope"]),J=async(Y)=>{let R=q.has(Y.evidence.proofType);return{judge:Y.judge,verdict:R?"APPROVE_OVERRIDE":"REJECT_OVERRIDE",reasoning:R?`[stub] proofType=${Y.evidence.proofType} trusted`:`[stub] proofType=${Y.evidence.proofType} requires manual review`}},W=await X.runOverrideCouncil(V,Z,J);await X.recordOverrideOutcome(Q,K,W,V);let M=_1(Q,"quality","reviews");if(YK(M))try{let Y=OK(M).filter((E)=>E.startsWith("review-")).sort(),R=Y[Y.length-1];if(R&&AK(_1(M,R)).isDirectory())Y1(_1(M,R,`override-${K}.json`),{review_id:H.reviewId,iteration:K,approved_finding_ids:Array.from(W.approvedFindingIds),rejected_finding_ids:Array.from(W.rejectedFindingIds),votes:W.votes})}catch{}let G=W.approvedFindingIds.size,B=W.rejectedFindingIds.size;if(B===0&&G>0)process.stdout.write(`override: LIFTED -- ${G} approved, ${B} rejected
639
+ `,{env:z,timeoutMs:15000});if(X.exitCode===127)return{stored:!1,reason:"python3 not found"};let W=X.stdout.trim();if(W==="OK")return{stored:!0,reason:"stored"};if(W.startsWith("ERR:"))return{stored:!1,reason:W.replace(/^ERR:/,"")};return{stored:!1,reason:X.stderr.trim()||"unknown"}}var U7=k(()=>{B1();m()});var q7={};g(q7,{loadLearnings:()=>B$,appendLearning:()=>w1,appendFromGateFailure:()=>EQ});import{existsSync as IQ,readFileSync as PQ}from"fs";import{join as H7}from"path";import{createHash as LQ}from"crypto";function W7($){return H7($,kQ)}function jQ($){if($===null||typeof $!=="object")return!1;let Q=$;return typeof Q.id==="string"&&typeof Q.timestamp==="string"&&typeof Q.iteration==="number"&&typeof Q.trigger==="string"&&typeof Q.rootCause==="string"&&typeof Q.fix==="string"&&typeof Q.preventInFuture==="string"&&typeof Q.evidence==="object"&&Q.evidence!==null}function J7($){if(!IQ($))return{version:1,learnings:[]};try{let Q=PQ($,"utf-8"),K=JSON.parse(Q);if(K.version===1&&Array.isArray(K.learnings))return{version:1,learnings:K.learnings.filter(jQ)}}catch{}return{version:1,learnings:[]}}function FQ($,Q){return LQ("sha256").update(`${$}\x00${Q}`).digest("hex").slice(0,16)}async function w1($,Q,K={}){let Z=FQ(Q.trigger,Q.rootCause),z=new Date().toISOString(),U={id:Z,timestamp:z,...Q},X=W7($);if(await L0(X,()=>{let J=J7(X),q=J.learnings.findIndex((V)=>V.id===Z);if(q>=0){let V=J.learnings[q];J.learnings[q]={...V,timestamp:z,iteration:U.iteration}}else J.learnings.push(U);O1(X,J)}),K.episodeBridge!==null&&(K.episodeBridge!==void 0||process.env.LOKI_AUTO_LEARNINGS_EPISODE==="1")){let J=K.episodeBridge??X7,q=K.bridgeFailureLog??RQ;try{let V=await J($,{taskId:`learning-${Z}`,outcome:"failure",phase:"VERIFY",goal:`${Q.trigger}: ${Q.rootCause}`});if(V&&!V.stored){if(!new Set(["memory dir not initialized","stub"]).has(V.reason))q(`episode_bridge skipped: ${V.reason}`)}}catch(V){q(`episode_bridge threw: ${V.message}`)}}return U}function RQ($){process.stderr.write(`[learnings_writer] ${$}
640
+ `)}async function EQ($,Q,K,Z={}){let z=`[${K.severity}] ${K.description}`;return w1($,{iteration:Q,trigger:"gate_failure",rootCause:z,fix:"pending: dev agent must address in next iteration or supply counter-evidence",preventInFuture:"if this finding recurs, lower its severity threshold or add a regression test",evidence:{reviewId:K.reviewId,file:K.file??void 0,line:K.line??void 0,severity:K.severity,reviewer:K.reviewer}},Z)}function B$($){return J7(W7($))}var kQ;var g1=k(()=>{D1();U7();kQ=H7("state","relevant-learnings.json")});var G7={};g(G7,{runOverrideCouncil:()=>hQ,recordOverrideOutcome:()=>bQ,loadCounterEvidence:()=>DQ,canonicalFindingId:()=>M$,DEFAULT_OVERRIDE_JUDGES:()=>V7});import{existsSync as SQ,readFileSync as xQ}from"fs";import{join as NQ}from"path";function DQ($,Q){let K=NQ($,"state",`counter-evidence-${Q}.json`);if(!SQ(K))return null;try{let Z=xQ(K,"utf-8"),z=JSON.parse(Z);if(typeof z.iteration!=="number")return null;let U=Array.isArray(z.evidence)?z.evidence:[],X=[];for(let W of U){if(typeof W!=="object"||W===null)continue;let J=W;if(typeof J.findingId!=="string")continue;if(typeof J.claim!=="string")continue;let q=J.proofType;if(typeof q!=="string"||!CQ.has(q))continue;let V=q,M=Array.isArray(J.artifacts)?J.artifacts:[];X.push({findingId:J.findingId,claim:J.claim,proofType:V,artifacts:M.filter((G)=>typeof G==="string")})}return{iteration:z.iteration,evidence:X}}catch{return null}}async function hQ($,Q,K,Z={}){let z=Z.judges??V7,U=new Set,X=new Set,W={},J=new Map;for(let q of Q.evidence)J.set(q.findingId,q);for(let q of $){let V=M$(q),M=J.get(V);if(!M){X.add(V);continue}let G=await Promise.all(z.map((T)=>K({finding:q,evidence:M,judge:T})));if(W[V]=G,G.filter((T)=>T.verdict==="APPROVE_OVERRIDE").length>=2)U.add(V);else X.add(V)}return{approvedFindingIds:U,rejectedFindingIds:X,votes:W}}function M$($){let Q=$.raw.slice(0,80).replace(/\s+/g," ").trim();return`${$.reviewer}::${Q}`}async function bQ($,Q,K,Z,z={}){let U={episodeBridge:z.episodeBridge===void 0?null:z.episodeBridge};for(let X of Z){let W=M$(X);if(K.approvedFindingIds.has(W))await w1($,{iteration:Q,trigger:"override_approved",rootCause:`[${X.severity}] ${X.description}`,fix:"override council approved counter-evidence; finding lifted",preventInFuture:"if this reviewer/file pair recurs, narrow the reviewer's selector OR add a baseline doc",evidence:{findingId:W,reviewId:X.reviewId,file:X.file??void 0,line:X.line??void 0,severity:X.severity,reviewer:X.reviewer}},U);else if(K.rejectedFindingIds.has(W))await w1($,{iteration:Q,trigger:"override_rejected",rootCause:`[${X.severity}] ${X.description}`,fix:"override council rejected -- dev agent must fix the finding",preventInFuture:"address this finding in the next iteration",evidence:{findingId:W,reviewId:X.reviewId,file:X.file??void 0,line:X.line??void 0,severity:X.severity,reviewer:X.reviewer}},U)}}var CQ,V7;var B7=k(()=>{g1();CQ=new Set(["file-exists","test-passes","grep-miss","reviewer-misread","duplicate-code-path","out-of-scope"]);V7=["judge-primary","judge-secondary","judge-tertiary"]});var T7={};g(T7,{writeEscalationHandoff:()=>nQ,renderHandoff:()=>M7,readLatestHandoff:()=>aQ});import{existsSync as yQ,mkdirSync as gQ,readdirSync as mQ,readFileSync as vQ,renameSync as fQ,writeFileSync as uQ}from"fs";import{dirname as cQ,join as m1}from"path";function pQ(){return new Date().toISOString()}function lQ($){let Q=$.file?` (${$.file}${$.line!==null?":"+$.line:""})`:"";return` - [${$.severity}] ${$.description}${Q} -- ${$.reviewer}`}function dQ($){let Q=$.evidence,K=Q.file?` ${Q.file}${Q.line!==void 0?":"+Q.line:""}`:"";return` - **${$.trigger}** (iter ${$.iteration})${K}: ${$.rootCause}`}function M7($,Q,K){let Z=[];if(Z.push(`# Loki escalation handoff -- ${pQ()}`),Z.push(""),Z.push(`Gate **${$.gateName}** has failed ${$.consecutiveFailures} consecutive times at iteration ${$.iteration}.`),Z.push(""),Z.push(`Reason: ${$.detail}`),Z.push(""),Q.length>0){Z.push(`## Outstanding findings (${Q.length})`),Z.push("");for(let z of Q)Z.push(lQ(z));Z.push("")}else Z.push("## Outstanding findings"),Z.push(""),Z.push("(no per-finding records captured -- gate failed without populating reviewer outputs)"),Z.push("");if(K.length>0){Z.push(`## Recent learnings (${Math.min(K.length,10)})`),Z.push("");for(let z of K.slice(-10))Z.push(dQ(z));Z.push("")}return Z.push("## What the human must decide"),Z.push(""),Z.push("- Approve override? Write `.loki/state/counter-evidence-<iter>.json` with one entry per finding to dispute, then `rm .loki/PAUSE` to resume."),Z.push("- Disable a gate? Set `LOKI_GATE_<NAME>=false` in env (see skills/quality-gates.md)."),Z.push("- Tweak escalation? Set `LOKI_GATE_PAUSE_LIMIT` or `LOKI_GATE_ESCALATE_LIMIT`."),Z.push("- Roll back? Switch to `LOKI_LEGACY_BASH=1` and re-run; the bash route does not consult this handoff doc."),Z.push(""),Z.push("To resume: address the findings (or supply counter-evidence) and `rm .loki/PAUSE`."),Z.join(`
641
+ `)}function oQ($,Q){gQ(cQ($),{recursive:!0});let K=`${$}.tmp.${process.pid}.${++Y7}`;uQ(K,Q),fQ(K,$)}function nQ($,Q,K={}){let Z=K.findings??V$($,Q.iteration).findings,z=K.learnings??B$($).learnings,U=M7(Q,Z,z),X=(K.now?.()??new Date).toISOString().replace(/[-:.]/g,""),W=m1($,"escalations"),J=++Y7,q=m1(W,`handoff-${X}-${process.pid}-${J}-${Q.gateName}.md`);return oQ(q,U),{path:q,bytes:U.length}}function aQ($){let Q=m1($,"escalations");if(!yQ(Q))return null;let K;try{K=mQ(Q).filter((U)=>U.endsWith(".md"))}catch{return null}if(K.length===0)return null;K.sort();let Z=K[K.length-1];if(!Z)return null;let z=m1(Q,Z);try{return{path:z,body:vQ(z,"utf-8")}}catch{return null}}var Y7=0;var O7=k(()=>{y1();g1()});var _7={};g(_7,{runInternalPhase1Hooks:()=>$3,_resolveForTests:()=>eQ,_internalPhase1HooksHelp:()=>z3});import{existsSync as sQ,mkdirSync as rQ,readdirSync as tQ,statSync as iQ}from"fs";import{join as I1,resolve as eQ}from"path";async function $3($){let[Q,...K]=$;switch(Q){case void 0:case"help":case"--help":case"-h":return process.stdout.write(Y$),Q===void 0?1:0;case"reflect":return Q3(K);case"override":return K3(K);case"handoff":return Z3(K);default:return process.stderr.write(`Unknown subcommand: ${Q}
642
+ `),process.stderr.write(Y$),2}}async function Q3($){let Q=T$($[0]);if(Q===null)return process.stderr.write(`reflect: missing or invalid <iter>
643
+ `),2;let K=L();try{let z=(await Promise.resolve().then(() => (y1(),G$))).loadPreviousFindings(K,Q);if(z.findings.length===0)return process.stdout.write(`reflect: no findings for iter ${Q} (nothing to do)
644
+ `),0;let U=I1(K,"state");rQ(U,{recursive:!0}),O1(I1(U,`findings-${Q}.json`),{review_id:z.reviewId,iteration:Q,findings:z.findings});let X=await Promise.resolve().then(() => (g1(),q7)),W=0;if(process.env.LOKI_AUTO_LEARNINGS!=="0"){for(let J of z.findings)if(J.severity==="Critical"||J.severity==="High")await X.appendFromGateFailure(K,Q,J,{episodeBridge:null}),W+=1}return process.stdout.write(`reflect: persisted ${z.findings.length} findings + ${W} learnings (iter ${Q})
645
+ `),0}catch(Z){return process.stderr.write(`reflect: ${Z.message}
646
+ `),1}}async function K3($){let Q=T$($[0]);if(Q===null)return process.stderr.write(`override: missing or invalid <iter>
647
+ `),2;let K=L();try{let Z=await Promise.resolve().then(() => (B7(),G7)),z=Z.loadCounterEvidence(K,Q);if(z===null||z.evidence.length===0)return process.stdout.write(`override: no counter-evidence for iter ${Q} (skip)
648
+ `),0;let X=(await Promise.resolve().then(() => (y1(),G$))).loadPreviousFindings(K,Q),W=X.findings.filter((Y)=>Y.severity==="Critical"||Y.severity==="High");if(W.length===0)return process.stdout.write(`override: no blocking findings for iter ${Q} (skip)
649
+ `),0;let J=new Set(["duplicate-code-path","file-exists","test-passes","grep-miss","out-of-scope"]),q=async(Y)=>{let E=J.has(Y.evidence.proofType);return{judge:Y.judge,verdict:E?"APPROVE_OVERRIDE":"REJECT_OVERRIDE",reasoning:E?`[stub] proofType=${Y.evidence.proofType} trusted`:`[stub] proofType=${Y.evidence.proofType} requires manual review`}},V=await Z.runOverrideCouncil(W,z,q);await Z.recordOverrideOutcome(K,Q,V,W);let M=I1(K,"quality","reviews");if(sQ(M))try{let Y=tQ(M).filter((S)=>S.startsWith("review-")).sort(),E=Y[Y.length-1];if(E&&iQ(I1(M,E)).isDirectory())O1(I1(M,E,`override-${Q}.json`),{review_id:X.reviewId,iteration:Q,approved_finding_ids:Array.from(V.approvedFindingIds),rejected_finding_ids:Array.from(V.rejectedFindingIds),votes:V.votes})}catch{}let G=V.approvedFindingIds.size,B=V.rejectedFindingIds.size;if(B===0&&G>0)process.stdout.write(`override: LIFTED -- ${G} approved, ${B} rejected
628
650
  `);else process.stdout.write(`override: BLOCKED -- ${G} approved, ${B} rejected
629
- `);return 0}catch(X){return process.stderr.write(`override: ${X.message}
630
- `),1}}async function PK($){let K=$[0],Q=Number.parseInt($[1]??"0",10),X=G$($[2]);if(!K||!Number.isFinite(Q)||X===null)return process.stderr.write(`handoff: usage: handoff <gate> <consecutive-failures> <iter>
631
- `),2;let Z=L();try{let H=(await Promise.resolve().then(() => (Z5(),X5))).writeEscalationHandoff(Z,{gateName:K,iteration:X,consecutiveFailures:Q,detail:`${K} hit PAUSE_LIMIT (${Q} consecutive failures)`});return process.stdout.write(`handoff: wrote ${H.path} (${H.bytes}B)
632
- `),0}catch(z){return process.stderr.write(`handoff: ${z.message}
633
- `),1}}function G$($){if($===void 0)return null;let K=Number.parseInt($,10);return Number.isFinite(K)&&K>=0?K:null}var W$=`loki internal phase1-hooks <subcommand>
651
+ `);return 0}catch(Z){return process.stderr.write(`override: ${Z.message}
652
+ `),1}}async function Z3($){let Q=$[0],K=Number.parseInt($[1]??"0",10),Z=T$($[2]);if(!Q||!Number.isFinite(K)||Z===null)return process.stderr.write(`handoff: usage: handoff <gate> <consecutive-failures> <iter>
653
+ `),2;let z=L();try{let X=(await Promise.resolve().then(() => (O7(),T7))).writeEscalationHandoff(z,{gateName:Q,iteration:Z,consecutiveFailures:K,detail:`${Q} hit PAUSE_LIMIT (${K} consecutive failures)`});return process.stdout.write(`handoff: wrote ${X.path} (${X.bytes}B)
654
+ `),0}catch(U){return process.stderr.write(`handoff: ${U.message}
655
+ `),1}}function T$($){if($===void 0)return null;let Q=Number.parseInt($,10);return Number.isFinite(Q)&&Q>=0?Q:null}var Y$=`loki internal phase1-hooks <subcommand>
634
656
 
635
657
  Subcommands:
636
658
  reflect <iter> Persist structured findings + auto-learnings.
@@ -639,24 +661,24 @@ Subcommands:
639
661
 
640
662
  This command is invoked by autonomy/run.sh between iterations. Users
641
663
  should not run it directly -- run \`loki start\` instead.
642
- `,LK;var H5=F(()=>{v();S1();LK=W$});f1();function O$(){return process.stdout.write(`Loki Mode v${I1()}
643
- `),0}n();l();v();import{readFileSync as j5,existsSync as P5}from"fs";import{resolve as L5}from"path";var k5=["claude","codex","cline","aider"];function _$(){let $=L5(L(),"state","provider");if(!P5($))return"";try{return j5($,"utf-8").trim()}catch{return""}}function x5($,K){return $||K||process.env.LOKI_PROVIDER||"claude"}function F5($){let K=_$(),Q=x5($,K);switch(process.stdout.write(`${S}Current Provider${U}
664
+ `,z3;var A7=k(()=>{m();D1();z3=Y$});p1();function I$(){return process.stdout.write(`Loki Mode v${L1()}
665
+ `),0}n();l();m();import{readFileSync as b7,existsSync as y7}from"fs";import{resolve as g7}from"path";var m7=["claude","codex","cline","aider"];function L$(){let $=g7(L(),"state","provider");if(!y7($))return"";try{return b7($,"utf-8").trim()}catch{return""}}function v7($,Q){return $||Q||process.env.LOKI_PROVIDER||"claude"}function f7($){let Q=L$(),K=v7($,Q);switch(process.stdout.write(`${x}Current Provider${H}
644
666
  `),process.stdout.write(`
645
- `),process.stdout.write(`${_}Provider:${U} ${Q}
646
- `),Q){case"claude":process.stdout.write(`${D}Status:${U} Full features (subagents, parallel, MCP)
647
- `);break;case"cline":process.stdout.write(`${D}Status:${U} Near-full mode (subagents, MCP, 12+ providers)
648
- `);break;case"codex":case"aider":process.stdout.write(`${I}Status:${U} Degraded mode (sequential only)
649
- `);break;default:break}if(K)process.stdout.write(`${h}(saved in .loki/state/provider)${U}
650
- `);else process.stdout.write(`${h}(default - not explicitly set)${U}
667
+ `),process.stdout.write(`${A}Provider:${H} ${K}
668
+ `),K){case"claude":process.stdout.write(`${C}Status:${H} Full features (subagents, parallel, MCP)
669
+ `);break;case"cline":process.stdout.write(`${C}Status:${H} Near-full mode (subagents, MCP, 12+ providers)
670
+ `);break;case"codex":case"aider":process.stdout.write(`${I}Status:${H} Degraded mode (sequential only)
671
+ `);break;default:break}if(Q)process.stdout.write(`${h}(saved in .loki/state/provider)${H}
672
+ `);else process.stdout.write(`${h}(default - not explicitly set)${H}
651
673
  `);return process.stdout.write(`
652
- `),process.stdout.write(`Switch provider: ${_}loki provider set <name>${U}
653
- `),process.stdout.write(`Available: ${_}loki provider list${U}
654
- `),0}async function R5(){let K=_$()||process.env.LOKI_PROVIDER||"claude";process.stdout.write(`${S}Available Providers${U}
674
+ `),process.stdout.write(`Switch provider: ${A}loki provider set <name>${H}
675
+ `),process.stdout.write(`Available: ${A}loki provider list${H}
676
+ `),0}async function u7(){let Q=L$()||process.env.LOKI_PROVIDER||"claude";process.stdout.write(`${x}Available Providers${H}
655
677
  `),process.stdout.write(`
656
- `);let Q=await Promise.all(k5.map(async(z)=>[z,await m(z)!==null])),X=new Map;for(let[z,H]of Q)X.set(z,H?`${D}installed${U}`:`${O}not installed${U}`);let Z=[["claude","claude - Claude Code (Anthropic) "],["codex","codex - Codex CLI (OpenAI) "],["cline","cline - Cline (multi-provider) "],["aider","aider - Aider (terminal pair prog) "]];for(let[z,H]of Z){let V=K===z?` ${_}(current)${U}`:"";process.stdout.write(` ${H} ${X.get(z)}${V}
678
+ `);let K=await Promise.all(m7.map(async(U)=>[U,await v(U)!==null])),Z=new Map;for(let[U,X]of K)Z.set(U,X?`${C}installed${H}`:`${O}not installed${H}`);let z=[["claude","claude - Claude Code (Anthropic) "],["codex","codex - Codex CLI (OpenAI) "],["cline","cline - Cline (multi-provider) "],["aider","aider - Aider (terminal pair prog) "]];for(let[U,X]of z){let W=Q===U?` ${A}(current)${H}`:"";process.stdout.write(` ${X} ${Z.get(U)}${W}
657
679
  `)}return process.stdout.write(`
658
- `),process.stdout.write(`Set provider: ${_}loki provider set <name>${U}
659
- `),0}function E5(){return process.stdout.write(`${S}Loki Mode Provider Management${U}
680
+ `),process.stdout.write(`Set provider: ${A}loki provider set <name>${H}
681
+ `),0}function c7(){return process.stdout.write(`${x}Loki Mode Provider Management${H}
660
682
  `),process.stdout.write(`
661
683
  `),process.stdout.write(`Usage: loki provider <command>
662
684
  `),process.stdout.write(`
@@ -674,17 +696,17 @@ should not run it directly -- run \`loki start\` instead.
674
696
  `),process.stdout.write(` loki provider list
675
697
  `),process.stdout.write(` loki provider info codex
676
698
  `),process.stdout.write(` loki provider models
677
- `),0}async function w$($){let K=$[0]??"show",Q=$.slice(1);switch(K){case"show":case"current":return F5(Q[0]);case"list":return R5();case"set":case"info":case"models":return S5(["provider",K,...Q]);default:return E5()}}async function S5($){let{run:K}=await Promise.resolve().then(() => (n(),A$)),{resolve:Q}=await import("path"),{REPO_ROOT:X}=await Promise.resolve().then(() => (v(),T$)),Z=Q(X,"autonomy","loki"),z=await K([Z,...$],{env:{LOKI_LEGACY_BASH:"1"},timeoutMs:3600000});return process.stdout.write(z.stdout),process.stderr.write(z.stderr),z.exitCode}l();v();G1();import{existsSync as I$,readFileSync as D5}from"fs";import{resolve as z1}from"path";import{mkdir as C5}from"fs/promises";var B1=z1(m1(),"learnings");function c1($){if(!I$($))return 0;try{let K=D5($,"utf-8"),Q=0;for(let X of K.split(`
678
- `))if(X.includes('"description"'))Q++;return Q}catch{return 0}}async function h5(){await C5(B1,{recursive:!0});let $=c1(z1(B1,"patterns.jsonl")),K=c1(z1(B1,"mistakes.jsonl")),Q=c1(z1(B1,"successes.jsonl"));return process.stdout.write(`${S}Cross-Project Learnings${U}
699
+ `),0}async function k$($){let Q=$[0]??"show",K=$.slice(1);switch(Q){case"show":case"current":return f7(K[0]);case"list":return u7();case"set":case"info":case"models":return p7(["provider",Q,...K]);default:return c7()}}async function p7($){let{run:Q}=await Promise.resolve().then(() => (n(),P$)),{resolve:K}=await import("path"),{REPO_ROOT:Z}=await Promise.resolve().then(() => (m(),w$)),z=K(Z,"autonomy","loki"),U=await Q([z,...$],{env:{LOKI_LEGACY_BASH:"1"},timeoutMs:3600000});return process.stdout.write(U.stdout),process.stderr.write(U.stderr),U.exitCode}l();m();B1();import{existsSync as j$,readFileSync as d7}from"fs";import{resolve as U1}from"path";import{mkdir as o7}from"fs/promises";var M1=U1(c1(),"learnings");function d1($){if(!j$($))return 0;try{let Q=d7($,"utf-8"),K=0;for(let Z of Q.split(`
700
+ `))if(Z.includes('"description"'))K++;return K}catch{return 0}}async function n7(){await o7(M1,{recursive:!0});let $=d1(U1(M1,"patterns.jsonl")),Q=d1(U1(M1,"mistakes.jsonl")),K=d1(U1(M1,"successes.jsonl"));return process.stdout.write(`${x}Cross-Project Learnings${H}
679
701
  `),process.stdout.write(`
680
- `),process.stdout.write(` Patterns: ${D}${$}${U}
681
- `),process.stdout.write(` Mistakes: ${I}${K}${U}
682
- `),process.stdout.write(` Successes: ${_}${Q}${U}
702
+ `),process.stdout.write(` Patterns: ${C}${$}${H}
703
+ `),process.stdout.write(` Mistakes: ${I}${Q}${H}
704
+ `),process.stdout.write(` Successes: ${A}${K}${H}
683
705
  `),process.stdout.write(`
684
- `),process.stdout.write(`Location: ${B1}
706
+ `),process.stdout.write(`Location: ${M1}
685
707
  `),process.stdout.write(`
686
708
  `),process.stdout.write(`Use 'loki memory show <type>' to view entries
687
- `),0}async function b5($){if($){let X=`
709
+ `),0}async function a7($){if($){let Z=`
688
710
  try:
689
711
  from memory.layers import IndexLayer
690
712
  layer = IndexLayer('.loki/memory')
@@ -694,9 +716,9 @@ except ImportError:
694
716
  print('Error: memory.layers module not found')
695
717
  except Exception as e:
696
718
  print(f'Error: {e}')
697
- `.trim(),Z=await K1(X,{cwd:p});return process.stdout.write(Z.stdout),0}let K=z1(L(),"memory","index.json");if(!I$(K))return process.stdout.write(`No index found
698
- `),0;let Q=await K1(`import json, sys; sys.stdout.write(json.dumps(json.load(open(${JSON.stringify(K)})), indent=4) + "\\n")`);if(Q.exitCode!==0)return process.stdout.write(`No index found
699
- `),0;return process.stdout.write(Q.stdout),0}async function j$($){switch($[0]??"list"){case"list":case"ls":return h5();case"index":return b5($[1]==="rebuild");default:{let Q=z1(p,"autonomy","loki"),X=3600000,Z=Bun.spawn({cmd:[Q,"memory",...$],stdin:"inherit",stdout:"inherit",stderr:"inherit",env:{...process.env,LOKI_LEGACY_BASH:"1"}}),z=setTimeout(()=>{try{Z.kill("SIGKILL")}catch{}},3600000);try{return await Z.exited}finally{clearTimeout(z)}}}}var U5=`Loki Mode (TypeScript port, Phase 2 of bash->Bun migration)
719
+ `.trim(),z=await Q1(Z,{cwd:p});return process.stdout.write(z.stdout),0}let Q=U1(L(),"memory","index.json");if(!j$(Q))return process.stdout.write(`No index found
720
+ `),0;let K=await Q1(`import json, sys; sys.stdout.write(json.dumps(json.load(open(${JSON.stringify(Q)})), indent=4) + "\\n")`);if(K.exitCode!==0)return process.stdout.write(`No index found
721
+ `),0;return process.stdout.write(K.stdout),0}async function F$($){switch($[0]??"list"){case"list":case"ls":return n7();case"index":return a7($[1]==="rebuild");default:{let K=U1(p,"autonomy","loki"),Z=3600000,z=Bun.spawn({cmd:[K,"memory",...$],stdin:"inherit",stdout:"inherit",stderr:"inherit",env:{...process.env,LOKI_LEGACY_BASH:"1"}}),U=setTimeout(()=>{try{z.kill("SIGKILL")}catch{}},3600000);try{return await z.exited}finally{clearTimeout(U)}}}}var w7=`Loki Mode (TypeScript port, Phase 2 of bash->Bun migration)
700
722
 
701
723
  Usage: loki <command> [args...]
702
724
 
@@ -718,12 +740,12 @@ Phase 2 ported (Bun-native, fast):
718
740
 
719
741
  All other commands fall through to the bash CLI (autonomy/loki).
720
742
  Set LOKI_LEGACY_BASH=1 to force the bash CLI for every command.
721
- `;function kK(){let $=process.env.LOKI_LEGACY_BASH;if($===void 0)return;let K=$.trim().toLowerCase();if(K!=="1"&&K!=="true"&&K!=="yes"&&K!=="on")return;if(process.env.LOKI_SUPPRESS_BUN_DIRECT_WARN==="1")return;process.stderr.write(`warning: LOKI_LEGACY_BASH is set, but you are running the Bun runtime directly (src/cli.ts). The env var only takes effect via the bin/loki shim, which dispatches between Bun and bash. Behavior is unchanged; this message is informational.
722
- `)}async function xK($){kK();let K=$[0],Q=$.slice(1);switch(K){case void 0:case"help":case"--help":case"-h":return process.stdout.write(U5),0;case"version":case"--version":case"-v":return O$();case"provider":return w$(Q);case"memory":return j$(Q);case"status":{let{runStatus:X}=await Promise.resolve().then(() => (S$(),E$));return X(Q)}case"stats":{let{runStats:X}=await Promise.resolve().then(() => (b$(),h$));return X(Q)}case"doctor":{let{runDoctor:X}=await Promise.resolve().then(() => (d$(),l$));return X(Q)}case"kpis":{let{runKpis:X}=await Promise.resolve().then(() => (Z0(),X0));return X(Q)}case"rollback":{let{runRollback:X}=await Promise.resolve().then(() => (S0(),E0));return X(Q)}case"proof":{let{runProof:X}=await Promise.resolve().then(() => (b0(),h0));return X(Q)}case"wiki":{let{runWiki:X}=await Promise.resolve().then(() => (f0(),m0));return X(Q)}case"internal":{let X=Q[0];if(!X||X==="--help"||X==="-h"||X==="help"){let z=["loki internal -- runtime hooks driven by autonomy/run.sh","","Subcommands:"," phase1-hooks Persist structured findings, run override council,"," append learnings, and write the escalation handoff"," doc once per iteration. Driven by run.sh; not"," intended for direct invocation.","","Phase 1 (RARV-C closure) env vars:"," LOKI_INJECT_FINDINGS=1 Persist structured reviewer findings to"," .loki/state/findings-<iter>.json so the"," next iteration can address them."," LOKI_OVERRIDE_COUNCIL=1 Allow a 3-LLM override panel to lift a"," BLOCK when counter-evidence is presented."," See LOKI_OVERRIDE_JUDGES (csv),"," LOKI_OVERRIDE_PANEL_SIZE,"," LOKI_OVERRIDE_REAL_JUDGE."," LOKI_AUTO_LEARNINGS=1 Append failure rootcauses to"," .loki/state/relevant-learnings.json via"," the episodic memory bridge."," LOKI_HANDOFF_MD=1 Write a structured human handoff doc to"," .loki/escalations/<ts>.md before PAUSE.","","All four are default-on as of v7.5.3. Set to 0 to disable.","Reference: CHANGELOG.md (search 'Phase 1') and skills/healing.md.","","These commands are wired into the autonomous loop and may change","without notice. Do not script against them.",""].join(`
723
- `);return process.stdout.write(`${z}
724
- `),0}if(X==="phase1-hooks"){let{runInternalPhase1Hooks:z}=await Promise.resolve().then(() => (H5(),z5));return z(Q.slice(1))}return process.stderr.write(`Unknown internal subcommand: ${X}
743
+ `;function X3(){let $=process.env.LOKI_LEGACY_BASH;if($===void 0)return;let Q=$.trim().toLowerCase();if(Q!=="1"&&Q!=="true"&&Q!=="yes"&&Q!=="on")return;if(process.env.LOKI_SUPPRESS_BUN_DIRECT_WARN==="1")return;process.stderr.write(`warning: LOKI_LEGACY_BASH is set, but you are running the Bun runtime directly (src/cli.ts). The env var only takes effect via the bin/loki shim, which dispatches between Bun and bash. Behavior is unchanged; this message is informational.
744
+ `)}async function U3($){X3();let Q=$[0],K=$.slice(1);switch(Q){case void 0:case"help":case"--help":case"-h":return process.stdout.write(w7),0;case"version":case"--version":case"-v":return I$();case"provider":return k$(K);case"memory":return F$(K);case"status":{let{runStatus:Z}=await Promise.resolve().then(() => (h$(),D$));return Z(K)}case"stats":{let{runStats:Z}=await Promise.resolve().then(() => (v$(),m$));return Z(K)}case"doctor":{let{runDoctor:Z}=await Promise.resolve().then(() => (s$(),a$));return Z(K)}case"kpis":{let{runKpis:Z}=await Promise.resolve().then(() => (W0(),H0));return Z(K)}case"trust":{let{runTrust:Z}=await Promise.resolve().then(() => (O0(),T0));return Z(K)}case"rollback":{let{runRollback:Z}=await Promise.resolve().then(() => (p0(),c0));return Z(K)}case"proof":{let{runProof:Z}=await Promise.resolve().then(() => (a0(),n0));return Z(K)}case"wiki":{let{runWiki:Z}=await Promise.resolve().then(() => (e0(),i0));return Z(K)}case"internal":{let Z=K[0];if(!Z||Z==="--help"||Z==="-h"||Z==="help"){let U=["loki internal -- runtime hooks driven by autonomy/run.sh","","Subcommands:"," phase1-hooks Persist structured findings, run override council,"," append learnings, and write the escalation handoff"," doc once per iteration. Driven by run.sh; not"," intended for direct invocation.","","Phase 1 (RARV-C closure) env vars:"," LOKI_INJECT_FINDINGS=1 Persist structured reviewer findings to"," .loki/state/findings-<iter>.json so the"," next iteration can address them."," LOKI_OVERRIDE_COUNCIL=1 Allow a 3-LLM override panel to lift a"," BLOCK when counter-evidence is presented."," See LOKI_OVERRIDE_JUDGES (csv),"," LOKI_OVERRIDE_PANEL_SIZE,"," LOKI_OVERRIDE_REAL_JUDGE."," LOKI_AUTO_LEARNINGS=1 Append failure rootcauses to"," .loki/state/relevant-learnings.json via"," the episodic memory bridge."," LOKI_HANDOFF_MD=1 Write a structured human handoff doc to"," .loki/escalations/<ts>.md before PAUSE.","","All four are default-on as of v7.5.3. Set to 0 to disable.","Reference: CHANGELOG.md (search 'Phase 1') and skills/healing.md.","","These commands are wired into the autonomous loop and may change","without notice. Do not script against them.",""].join(`
745
+ `);return process.stdout.write(`${U}
746
+ `),0}if(Z==="phase1-hooks"){let{runInternalPhase1Hooks:U}=await Promise.resolve().then(() => (A7(),_7));return U(K.slice(1))}return process.stderr.write(`Unknown internal subcommand: ${Z}
725
747
  `),process.stderr.write(`Run 'loki internal --help' for the supported list.
726
- `),2}default:return process.stderr.write(`Unknown command: ${K}
727
- `),process.stderr.write(U5),2}}process.on("SIGINT",()=>process.exit(130));process.on("SIGTERM",()=>process.exit(143));var FK=await xK(Bun.argv.slice(2));process.exit(FK);
748
+ `),2}default:return process.stderr.write(`Unknown command: ${Q}
749
+ `),process.stderr.write(w7),2}}process.on("SIGINT",()=>process.exit(130));process.on("SIGTERM",()=>process.exit(143));var H3=await U3(Bun.argv.slice(2));process.exit(H3);
728
750
 
729
- //# debugId=2D27899C6324387764756E2164756E21
751
+ //# debugId=36813D9891E226F164756E2164756E21