loki-mode 7.13.0 → 7.14.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,12 +1,12 @@
1
1
  // @bun
2
- var g0=Object.defineProperty;var m0=($)=>$;function v0($,K){this[$]=m0.bind(null,K)}var y=($,K)=>{for(var Q in K)g0($,Q,{get:K[Q],enumerable:!0,configurable:!0,set:v0.bind(K,Q)})};var R=($,K)=>()=>($&&(K=$($=0)),K);var K1=import.meta.require;var H$={};y(H$,{lokiDir:()=>x,homeLokiDir:()=>g1,findRepoRootForVersion:()=>y1,REPO_ROOT:()=>c});import{resolve as l,dirname as b1}from"path";import{fileURLToPath as f0}from"url";import{existsSync as O1}from"fs";import{homedir as u0}from"os";function c0(){let $=U$;for(let K=0;K<6;K++){if(O1(l($,"VERSION"))&&O1(l($,"autonomy/run.sh")))return $;let Q=b1($);if(Q===$)break;$=Q}return l(U$,"..","..","..")}function y1($){let K=$;for(let Q=0;Q<6;Q++){if(O1(l(K,"VERSION"))&&O1(l(K,"autonomy/run.sh")))return K;let X=b1(K);if(X===K)break;K=X}return l($,"..","..","..")}function x(){return process.env.LOKI_DIR??l(process.cwd(),".loki")}function g1(){return l(u0(),".loki")}var U$,c;var g=R(()=>{U$=b1(f0(import.meta.url));c=c0()});import{readFileSync as p0}from"fs";import{resolve as l0,dirname as d0}from"path";import{fileURLToPath as o0}from"url";function T1(){if(s!==null)return s;let $="7.13.0";if(typeof $==="string"&&$.length>0)return s=$,s;try{let K=d0(o0(import.meta.url)),Q=y1(K);s=p0(l0(Q,"VERSION"),"utf-8").trim()}catch{s="unknown"}return s}var s=null;var m1=R(()=>{g()});var V$={};y(V$,{runOrThrow:()=>n0,run:()=>S,commandVersion:()=>r0,commandExists:()=>m,ShellError:()=>v1});async function S($,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,U,W]=await Promise.all([new Response(Q.stdout).text(),new Response(Q.stderr).text(),Q.exited]);return{stdout:z,stderr:U,exitCode:W}}finally{if(X)clearTimeout(X);if(Z)clearTimeout(Z)}}async function n0($,K={}){let Q=await S($,K);if(Q.exitCode!==0)throw new v1(`command failed (${Q.exitCode}): ${$.join(" ")}`,Q.exitCode,Q.stdout,Q.stderr);return Q}async function m($){let K=a0($),Q=await S(["sh","-c",`command -v ${K}`],{timeoutMs:5000});if(Q.exitCode===0)return Q.stdout.trim()||null;return null}function a0($){if(!/^[A-Za-z0-9._/-]+$/.test($))throw Error(`refused to shell-escape suspect token: ${$}`);return $}async function r0($,K="--version"){if(!await m($))return null;let X=await S([$,K],{timeoutMs:5000});if(X.exitCode!==0)return null;return((X.stdout||X.stderr).split(/\r?\n/)[0]?.trim()??"")||null}var v1;var d=R(()=>{v1=class v1 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 o($){return s0?"":$}var s0,T,D,L,e7,_,N,C,H;var p=R(()=>{s0=(process.env.NO_COLOR??"").length>0;T=o("\x1B[0;31m"),D=o("\x1B[0;32m"),L=o("\x1B[1;33m"),e7=o("\x1B[0;34m"),_=o("\x1B[0;36m"),N=o("\x1B[1m"),C=o("\x1B[2m"),H=o("\x1B[0m")});import{existsSync as UK}from"fs";async function Q1(){if(W1!==void 0)return W1;let $="/opt/homebrew/bin/python3.12";if(UK($))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 t($,K={}){let Q=await Q1();if(!Q)return{stdout:"",stderr:"python3 not found",exitCode:127};return S([Q,"-c",$],K)}var W1;var V1=R(()=>{d()});var w$={};y(w$,{runStatus:()=>wK});import{existsSync as h,readFileSync as Z1,readdirSync as M$,statSync as Y$}from"fs";import{resolve as F,basename as JK}from"path";import{homedir as GK}from"os";async function MK(){if(await m("jq"))return!0;return process.stdout.write(`${T}Error: jq is required but not installed.${H}
2
+ var UK=Object.defineProperty;var HK=($)=>$;function WK($,K){this[$]=HK.bind(null,K)}var g=($,K)=>{for(var Q in K)UK($,Q,{get:K[Q],enumerable:!0,configurable:!0,set:WK.bind(K,Q)})};var E=($,K)=>()=>($&&(K=$($=0)),K);var X1=import.meta.require;var Y$={};g(Y$,{lokiDir:()=>L,homeLokiDir:()=>v1,findRepoRootForVersion:()=>m1,REPO_ROOT:()=>p});import{resolve as o,dirname as g1}from"path";import{fileURLToPath as VK}from"url";import{existsSync as _1}from"fs";import{homedir as qK}from"os";function JK(){let $=M$;for(let K=0;K<6;K++){if(_1(o($,"VERSION"))&&_1(o($,"autonomy/run.sh")))return $;let Q=g1($);if(Q===$)break;$=Q}return o(M$,"..","..","..")}function m1($){let K=$;for(let Q=0;Q<6;Q++){if(_1(o(K,"VERSION"))&&_1(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 v1(){return o(qK(),".loki")}var M$,p;var m=E(()=>{M$=g1(VK(import.meta.url));p=JK()});import{readFileSync as GK}from"fs";import{resolve as BK,dirname as MK}from"path";import{fileURLToPath as YK}from"url";function w1(){if(i!==null)return i;let $="7.14.0";if(typeof $==="string"&&$.length>0)return i=$,i;try{let K=MK(YK(import.meta.url)),Q=m1(K);i=GK(BK(Q,"VERSION"),"utf-8").trim()}catch{i="unknown"}return i}var i=null;var f1=E(()=>{m()});var T$={};g(T$,{runOrThrow:()=>OK,run:()=>k,commandVersion:()=>AK,commandExists:()=>v,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,U,W]=await Promise.all([new Response(Q.stdout).text(),new Response(Q.stderr).text(),Q.exited]);return{stdout:z,stderr:U,exitCode:W}}finally{if(X)clearTimeout(X);if(Z)clearTimeout(Z)}}async function OK($,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 v($){let K=TK($),Q=await k(["sh","-c",`command -v ${K}`],{timeoutMs:5000});if(Q.exitCode===0)return Q.stdout.trim()||null;return null}function TK($){if(!/^[A-Za-z0-9._/-]+$/.test($))throw Error(`refused to shell-escape suspect token: ${$}`);return $}async function AK($,K="--version"){if(!await v($))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=E(()=>{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 _K?"":$}var _K,A,D,x,y8,_,N,C,H;var l=E(()=>{_K=(process.env.NO_COLOR??"").length>0;A=a("\x1B[0;31m"),D=a("\x1B[0;32m"),x=a("\x1B[1;33m"),y8=a("\x1B[0;34m"),_=a("\x1B[0;36m"),N=a("\x1B[1m"),C=a("\x1B[2m"),H=a("\x1B[0m")});import{existsSync as EK}from"fs";async function Z1(){if(J1!==void 0)return J1;let $="/opt/homebrew/bin/python3.12";if(EK($))return J1=$,$;let K=await v("python3.12");if(K)return J1=K,K;let Q=await v("python3");return J1=Q,Q}async function e($,K={}){let Q=await Z1();if(!Q)return{stdout:"",stderr:"python3 not found",exitCode:127};return k([Q,"-c",$],K)}var J1;var G1=E(()=>{n()});var F$={};g(F$,{runStatus:()=>pK});import{existsSync as h,readFileSync as U1,readdirSync as j$,statSync as P$}from"fs";import{resolve as S,basename as DK}from"path";import{homedir as bK}from"os";async function gK(){if(await v("jq"))return!0;return process.stdout.write(`${A}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 A1($){if(!Number.isFinite($)||$<=0)return!1;try{return process.kill($,0),!0}catch{return!1}}function _1($){if(!h($))return null;try{let K=Z1($,"utf-8").trim();if(!K)return null;let Q=Number.parseInt(K,10);return Number.isFinite(Q)?Q:null}catch{return null}}function YK($){let K=[],Q=_1(F($,"loki.pid"));if(Q!==null&&A1(Q))K.push(`global:${Q}`);let X=F($,"sessions");if(h(X)){let Z=[];try{Z=M$(X)}catch{Z=[]}for(let z of Z){let U=F(X,z);try{if(!Y$(U).isDirectory())continue}catch{continue}let W=F(U,"loki.pid"),V=_1(W);if(V!==null&&A1(V))K.push(`${z}:${V}`)}}if(h($)){let Z=[];try{Z=M$($)}catch{Z=[]}for(let z of Z){if(!z.startsWith("run-")||!z.endsWith(".pid"))continue;let U=F($,z);try{if(!Y$(U).isFile())continue}catch{continue}let W=JK(z,".pid").slice(4),V=_1(U);if(V!==null&&A1(V)){if(!K.some((J)=>J.startsWith(`${W}:`)))K.push(`${W}:${V}`)}}}return K}async function O$($,K){let Q=await S(["jq","-r",$,K]);if(Q.exitCode!==0)return null;return Q.stdout.trim()}function T$($,K){try{let Q=Z1($,"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 A$($,K,Q){try{let X=Z1($,"utf-8"),z=JSON.parse(X)[K];if(typeof z==="number"&&Number.isFinite(z))return z;return Q}catch{return Q}}async function OK(){let $=x();if(!await MK())return 1;if(!h($))return process.stdout.write(`${N}Loki Mode Status${H}
7
+ `),!1}function I1($){if(!Number.isFinite($)||$<=0)return!1;try{return process.kill($,0),!0}catch{return!1}}function j1($){if(!h($))return null;try{let K=U1($,"utf-8").trim();if(!K)return null;let Q=Number.parseInt(K,10);return Number.isFinite(Q)?Q:null}catch{return null}}function mK($){let K=[],Q=j1(S($,"loki.pid"));if(Q!==null&&I1(Q))K.push(`global:${Q}`);let X=S($,"sessions");if(h(X)){let Z=[];try{Z=j$(X)}catch{Z=[]}for(let z of Z){let U=S(X,z);try{if(!P$(U).isDirectory())continue}catch{continue}let W=S(U,"loki.pid"),V=j1(W);if(V!==null&&I1(V))K.push(`${z}:${V}`)}}if(h($)){let Z=[];try{Z=j$($)}catch{Z=[]}for(let z of Z){if(!z.startsWith("run-")||!z.endsWith(".pid"))continue;let U=S($,z);try{if(!P$(U).isFile())continue}catch{continue}let W=DK(z,".pid").slice(4),V=j1(U);if(V!==null&&I1(V)){if(!K.some((J)=>J.startsWith(`${W}:`)))K.push(`${W}:${V}`)}}}return K}async function L$($,K){let Q=await k(["jq","-r",$,K]);if(Q.exitCode!==0)return null;return Q.stdout.trim()}function k$($,K){try{let Q=U1($,"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 x$($,K,Q){try{let X=U1($,"utf-8"),z=JSON.parse(X)[K];if(typeof z==="number"&&Number.isFinite(z))return z;return Q}catch{return Q}}async function vK(){let $=L();if(!await gK())return 1;if(!h($))return process.stdout.write(`${N}Loki Mode Status${H}
8
8
  `),process.stdout.write(`
9
- `),process.stdout.write(`${L}No active session found.${H}
9
+ `),process.stdout.write(`${x}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:
@@ -16,45 +16,45 @@ var g0=Object.defineProperty;var m0=($)=>$;function v0($,K){this[$]=m0.bind(null
16
16
  `),process.stdout.write(`${C}Current directory: ${process.cwd()}${H}
17
17
  `),0;process.stdout.write(`${N}Loki Mode Status${H}
18
18
  `),process.stdout.write(`
19
- `);let K="",Q=F($,"state","provider");if(h(Q))try{K=Z1(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:${H} ${X} (${Z})
19
+ `);let K="",Q=S($,"state","provider");if(h(Q))try{K=U1(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:${H} ${X} (${Z})
20
20
  `),process.stdout.write(`${C} Switch with: loki provider set <claude|codex|cline|aider>${H}
21
21
  `),process.stdout.write(`
22
- `);let z=YK($);if(z.length>0){process.stdout.write(`${D}Active Sessions: ${z.length}${H}
23
- `);for(let B of z){let M=B.indexOf(":"),A=M>=0?B.slice(0,M):B,E=M>=0?B.slice(M+1):"";if(A==="global")process.stdout.write(` ${_}[global]${H} PID ${E}
24
- `);else process.stdout.write(` ${_}[#${A}]${H} PID ${E}
22
+ `);let z=mK($);if(z.length>0){process.stdout.write(`${D}Active Sessions: ${z.length}${H}
23
+ `);for(let G of z){let M=G.indexOf(":"),T=M>=0?G.slice(0,M):G,F=M>=0?G.slice(M+1):"";if(T==="global")process.stdout.write(` ${_}[global]${H} PID ${F}
24
+ `);else process.stdout.write(` ${_}[#${T}]${H} PID ${F}
25
25
  `)}process.stdout.write(`
26
26
  `),process.stdout.write(`${C} Stop specific: loki stop <session-id>${H}
27
27
  `),process.stdout.write(`${C} Stop all: loki stop${H}
28
28
  `),process.stdout.write(`
29
- `)}if(h(F($,"PAUSE")))process.stdout.write(`${L}Status: PAUSED${H}
29
+ `)}if(h(S($,"PAUSE")))process.stdout.write(`${x}Status: PAUSED${H}
30
30
  `),process.stdout.write(`${C} Resume with: loki resume${H}
31
31
  `),process.stdout.write(`
32
- `);else if(h(F($,"STOP")))process.stdout.write(`${T}Status: STOPPED${H}
32
+ `);else if(h(S($,"STOP")))process.stdout.write(`${A}Status: STOPPED${H}
33
33
  `),process.stdout.write(`${C} Clear with: loki resume${H}
34
34
  `),process.stdout.write(`
35
- `);let U=F($,"STATUS.txt");if(h(U)){process.stdout.write(`${_}Session Info:${H}
36
- `);try{process.stdout.write(Z1(U,"utf-8"))}catch{}process.stdout.write(`
37
- `)}let W=F($,"state","orchestrator.json");if(h(W)){process.stdout.write(`${_}Orchestrator State:${H}
38
- `);let B=await O$('.currentPhase // "unknown"',W);process.stdout.write(`${B??"unknown"}
39
- `)}let V=F($,"queue","pending.json");if(h(V)){let B=await O$('if type == "array" then length elif .tasks then .tasks | length else 0 end',V);process.stdout.write(`${_}Pending Tasks:${H} ${B??"0"}
40
- `)}let q=F($,"metrics","budget.json");if(h(q)){let B=T$(q,"budget_limit"),M=T$(q,"budget_used");if(B!=="0")process.stdout.write(`${_}Budget:${H} $${M} / $${B}
35
+ `);let U=S($,"STATUS.txt");if(h(U)){process.stdout.write(`${_}Session Info:${H}
36
+ `);try{process.stdout.write(U1(U,"utf-8"))}catch{}process.stdout.write(`
37
+ `)}let W=S($,"state","orchestrator.json");if(h(W)){process.stdout.write(`${_}Orchestrator State:${H}
38
+ `);let G=await L$('.currentPhase // "unknown"',W);process.stdout.write(`${G??"unknown"}
39
+ `)}let V=S($,"queue","pending.json");if(h(V)){let G=await L$('if type == "array" then length elif .tasks then .tasks | length else 0 end',V);process.stdout.write(`${_}Pending Tasks:${H} ${G??"0"}
40
+ `)}let q=S($,"metrics","budget.json");if(h(q)){let G=k$(q,"budget_limit"),M=k$(q,"budget_used");if(G!=="0")process.stdout.write(`${_}Budget:${H} $${M} / $${G}
41
41
  `);else process.stdout.write(`${_}Cost:${H} $${M} (no limit)
42
- `)}let J=F($,"state","context-usage.json");if(h(J)){let B=A$(J,"window_size",200000),M=A$(J,"used_tokens",0),A=0;if(B>0)A=Math.floor(M*100/B);process.stdout.write(`${_}Context:${H} ${A}% (${M} / ${B} tokens)
43
- `)}let G=[F($,"dashboard","dashboard.pid"),F(GK(),".loki","dashboard","dashboard.pid")].find((B)=>h(B))??"";if(G&&h(G)){let B=_1(G);if(B!==null&&A1(B)){let M=F(G,".."),A=(w,P)=>{let v=F(M,w);try{return h(v)?Z1(v,"utf-8").trim()||P:P}catch{return P}},E=A("scheme","http"),j=A("host","127.0.0.1"),b=A("port",process.env.LOKI_DASHBOARD_PORT||"57374");if(j==="0.0.0.0")j="127.0.0.1";process.stdout.write(`${_}Dashboard:${H} ${E}://${j}:${b}/
44
- `)}}return await TK($),process.stdout.write(`
42
+ `)}let J=S($,"state","context-usage.json");if(h(J)){let G=x$(J,"window_size",200000),M=x$(J,"used_tokens",0),T=0;if(G>0)T=Math.floor(M*100/G);process.stdout.write(`${_}Context:${H} ${T}% (${M} / ${G} tokens)
43
+ `)}let B=[S($,"dashboard","dashboard.pid"),S(bK(),".loki","dashboard","dashboard.pid")].find((G)=>h(G))??"";if(B&&h(B)){let G=j1(B);if(G!==null&&I1(G)){let M=S(B,".."),T=(w,P)=>{let f=S(M,w);try{return h(f)?U1(f,"utf-8").trim()||P:P}catch{return P}},F=T("scheme","http"),j=T("host","127.0.0.1"),y=T("port",process.env.LOKI_DASHBOARD_PORT||"57374");if(j==="0.0.0.0")j="127.0.0.1";process.stdout.write(`${_}Dashboard:${H} ${F}://${j}:${y}/
44
+ `)}}return await fK($),process.stdout.write(`
45
45
  `),process.stdout.write(`${C} Tip: loki context show - detailed token breakdown${H}
46
46
  `),process.stdout.write(`${C} Tip: loki code overview - codebase intelligence${H}
47
- `),0}async function TK($){let K=F($,"state"),Q=AK(K),X=F(K,"relevant-learnings.json"),Z=F($,"escalations"),z=Q.length>0,U=h(X),W=h(Z);if(!z&&!U&&!W)return;if(process.stdout.write(`
47
+ `),0}async function fK($){let K=S($,"state"),Q=uK(K),X=S(K,"relevant-learnings.json"),Z=S($,"escalations"),z=Q.length>0,U=h(X),W=h(Z);if(!z&&!U&&!W)return;if(process.stdout.write(`
48
48
  ${_}Phase 1 artifacts:${H}
49
- `),z){let V=Q[Q.length-1],q=_$(V);if(q&&Array.isArray(q.findings)){let J={Critical:0,High:0,Medium:0,Low:0};for(let G of q.findings){let B=String(G.severity??"");if(B in J)J[B]=(J[B]??0)+1}let Y=Object.entries(J).filter(([,G])=>G>0).map(([G,B])=>`${B} ${G.toLowerCase()}`).join(", ");process.stdout.write(` Findings (iter ${q.iteration??"?"}): ${Y||"none"} -- ${q.findings.length} total
50
- `)}}if(U){let V=_$(X);if(V&&Array.isArray(V.learnings)&&V.learnings.length>0){let q=new Map;for(let Y of V.learnings){let G=String(Y.trigger??"unknown");q.set(G,(q.get(G)??0)+1)}let J=[...q.entries()].sort((Y,G)=>G[1]-Y[1]).slice(0,3).map(([Y,G])=>`${G} ${Y}`).join(", ");process.stdout.write(` Learnings: ${V.learnings.length} total (${J})
51
- `)}}if(W){let V=0,q="";try{let Y=(await import("fs")).readdirSync(Z).filter((G)=>G.endsWith(".md"));if(V=Y.length,Y.length>0)Y.sort(),q=Y[Y.length-1]??""}catch{}if(V>0)process.stdout.write(` Escalations: ${V} handoff doc${V===1?"":"s"} (latest: ${q})
52
- `)}}function AK($){if(!h($))return[];try{return K1("fs").readdirSync($).filter((X)=>/^findings-\d+\.json$/.test(X)).sort((X,Z)=>{let z=Number.parseInt(X.replace(/[^0-9]/g,""),10)||0,U=Number.parseInt(Z.replace(/[^0-9]/g,""),10)||0;return z-U}).map((X)=>F($,X))}catch{return[]}}function _$($){try{let K=K1("fs");return JSON.parse(K.readFileSync($,"utf-8"))}catch{return null}}async function _K(){let $=await Q1();if(!$)return process.stderr.write(`{"error": "Failed to generate JSON status. Ensure python3 is available."}
53
- `),1;let K=c,Q=x(),X=process.env.LOKI_DASHBOARD_PORT||"57374",Z=process.env.LOKI_PROVIDER||"claude",z=await S([$,"-c",BK,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 wK($){let K=[...$];while(K.length>0){let Q=K[0];if(Q==="--json")return _K();if(Q==="--help"||Q==="-h")return process.stdout.write(`Usage: loki status [--json]
55
- `),0;return process.stdout.write(`${T}Unknown flag: ${Q}${H}
49
+ `),z){let V=Q[Q.length-1],q=R$(V);if(q&&Array.isArray(q.findings)){let J={Critical:0,High:0,Medium:0,Low:0};for(let B of q.findings){let G=String(B.severity??"");if(G in J)J[G]=(J[G]??0)+1}let Y=Object.entries(J).filter(([,B])=>B>0).map(([B,G])=>`${G} ${B.toLowerCase()}`).join(", ");process.stdout.write(` Findings (iter ${q.iteration??"?"}): ${Y||"none"} -- ${q.findings.length} total
50
+ `)}}if(U){let V=R$(X);if(V&&Array.isArray(V.learnings)&&V.learnings.length>0){let q=new Map;for(let Y of V.learnings){let B=String(Y.trigger??"unknown");q.set(B,(q.get(B)??0)+1)}let J=[...q.entries()].sort((Y,B)=>B[1]-Y[1]).slice(0,3).map(([Y,B])=>`${B} ${Y}`).join(", ");process.stdout.write(` Learnings: ${V.learnings.length} total (${J})
51
+ `)}}if(W){let V=0,q="";try{let Y=(await import("fs")).readdirSync(Z).filter((B)=>B.endsWith(".md"));if(V=Y.length,Y.length>0)Y.sort(),q=Y[Y.length-1]??""}catch{}if(V>0)process.stdout.write(` Escalations: ${V} handoff doc${V===1?"":"s"} (latest: ${q})
52
+ `)}}function uK($){if(!h($))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,U=Number.parseInt(Z.replace(/[^0-9]/g,""),10)||0;return z-U}).map((X)=>S($,X))}catch{return[]}}function R$($){try{let K=X1("fs");return JSON.parse(K.readFileSync($,"utf-8"))}catch{return null}}async function cK(){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",yK,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 pK($){let K=[...$];while(K.length>0){let Q=K[0];if(Q==="--json")return cK();if(Q==="--help"||Q==="-h")return process.stdout.write(`Usage: loki status [--json]
55
+ `),0;return process.stdout.write(`${A}Unknown flag: ${Q}${H}
56
56
  `),process.stdout.write(`Usage: loki status [--json]
57
- `),1}return OK()}var BK=`
57
+ `),1}return vK()}var yK=`
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 I$=R(()=>{d();V1();p();g()});var k$={};y(k$,{runStats:()=>xK,computeStats:()=>L$});import{readdirSync as j$,readFileSync as IK,statSync as P$}from"fs";import{join as n}from"path";function z1($){try{if(!P$($).isFile())return null;return JSON.parse(IK($,"utf-8"))}catch{return null}}function p1($){try{return P$($).isDirectory()}catch{return!1}}function jK($){if(!p1($))return[];try{let K=j$($).filter((Q)=>Q.startsWith("iteration-")&&Q.endsWith(".json"));return K.sort(),K.map((Q)=>n($,Q))}catch{return[]}}function U1($){return Math.trunc($).toLocaleString("en-US")}function u1($){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 a($,K=0){let Q=Math.pow(10,K);return Math.round($*Q)/Q}function H1($,K){return $.toFixed(K)}function c1($,K){return $.length>=K?$:$+" ".repeat(K-$.length)}function PK($){let K="N/A",Q=0,X=z1(n($,"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=n($,"metrics","efficiency"),z=jK(Z),U=[];for(let I of z){let k=z1(I);if(k&&typeof k==="object")U.push(k)}if(U.length>0)Q=Math.max(Q,U.length);let W=U.reduce((I,k)=>I+(k.input_tokens??0),0),V=U.reduce((I,k)=>I+(k.output_tokens??0),0),q=W+V,J=U.reduce((I,k)=>I+(k.cost_usd??0),0),Y=U.reduce((I,k)=>I+(k.duration_seconds??0),0),G=0,B=0,M=z1(n($,"metrics","budget.json"));if(M&&typeof M==="object"){if(typeof M.budget_limit==="number")G=M.budget_limit;if(typeof M.budget_used==="number")B=M.budget_used}let A=0,E=0,j=z1(n($,"state","quality-gates.json"));if(j&&typeof j==="object"){if(Array.isArray(j)){for(let I of j)if(E+=1,I===!0)A+=1;else if(I&&typeof I==="object"){let k=I;if(k.passed===!0||k.status==="passed")A+=1}}else for(let I of Object.values(j))if(typeof I==="boolean"){if(E+=1,I)A+=1}else if(I&&typeof I==="object"){E+=1;let k=I;if(k.passed===!0||k.status==="passed")A+=1}}let b={},w=z1(n($,"quality","gate-failure-count.json"));if(w&&typeof w==="object"&&!Array.isArray(w)){let I={};for(let[k,u]of Object.entries(w))if(typeof u==="number")I[k]=u;b=I}let P=0,v=0,Z$=0,D1=n($,"quality");if(p1(D1)){let I=[];try{I=j$(D1)}catch{I=[]}for(let k of I){if(!k.endsWith(".json")||k==="gate-failure-count.json")continue;let u=z1(n(D1,k));if(!u||typeof u!=="object")continue;if(!(("verdict"in u)||("approved"in u)||("reviewers"in u)))continue;P+=1;let z$=(u.verdict??"").toString().toLowerCase();if(u.approved===!0||["approved","approve","pass"].includes(z$))v+=1;else if(["revision","revise","changes_requested","reject"].includes(z$))Z$+=1}}return{phase:K,iterationCount:Q,iterations:U,totalInput:W,totalOutput:V,totalTokens:q,totalCost:J,totalDuration:Y,budgetLimit:G,budgetUsed:B,gatesPassed:A,gatesTotal:E,gateFailures:b,reviewsTotal:P,reviewsApproved:v,reviewsRevision:Z$}}function LK($,K){let Q=$.iterationCount,X={session:{iterations:Q,duration_seconds:$.totalDuration,phase:$.phase},tokens:{input:$.totalInput,output:$.totalOutput,total:$.totalTokens,cost_usd:a($.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?a($.totalTokens/Q,0):0,avg_cost_per_iteration:Q>0?a($.totalCost/Q,2):0,avg_duration_per_iteration:Q>0?a($.totalDuration/Q,1):0},budget:{used:a($.budgetUsed,2),limit:$.budgetLimit,percent:$.budgetLimit>0?a($.budgetUsed/$.budgetLimit*100,1):0}};if(K)X.iterations=$.iterations.map((U,W)=>({number:W+1,input_tokens:U.input_tokens??0,output_tokens:U.output_tokens??0,cost_usd:a(U.cost_usd??0,2),duration_seconds:U.duration_seconds??0}));let Z=JSON.stringify(X,null,2);function z(U,W){if(!W)return;let V=new RegExp(`("${U}": )(-?\\d+)(,?)$`,"m");Z=Z.replace(V,(q,J,Y,G)=>`${J}${Y}.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,(U,W,V,q)=>`${W}${V}.0${q}`);return Z}function kK($,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: ${u1($.totalDuration)}`),Q.push(` Current phase: ${$.phase}`),Q.push(""),Q.push("Token Usage"),$.iterations.length>0)Q.push(` Input tokens: ${U1($.totalInput)}`),Q.push(` Output tokens: ${U1($.totalOutput)}`),Q.push(` Total tokens: ${U1($.totalTokens)}`),Q.push(` Estimated cost: $${H1($.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: ${U1(X)}`),Q.push(` Avg cost/iteration: $${H1(Z,2)}`),Q.push(` Avg duration/iteration: ${u1(z)}`)}else Q.push(" N/A (no iteration metrics found)");if(Q.push(""),Q.push("Budget"),$.budgetLimit>0){let X=a($.budgetUsed/$.budgetLimit*100,1),Z=Number.isInteger(X)?`${X}.0`:`${X}`;Q.push(` Used: $${H1($.budgetUsed,2)} / $${H1($.budgetLimit,2)} (${Z}%)`)}else if($.budgetUsed>0)Q.push(` Used: $${H1($.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,U=c1(U1(X.input_tokens??0),10),W=c1(U1(X.output_tokens??0),10),V=X.cost_usd??0,q=u1(X.duration_seconds??0),J=c1(`${z}`,3);Q.push(` #${J} input: ${U} output: ${W} cost: $${H1(V,2)} time: ${q}`)});return Q.join(`
332
- `)}function L$($){let K=!1,Q=!1;for(let U of $)if(U==="--json")K=!0;else if(U==="--efficiency")Q=!0;let X=x();if(!p1(X)){if(K)return{exitCode:0,stdout:'{"error": "No active session"}'};return{exitCode:0,stdout:`${L}No active session found.${H}
333
- Start a session with: loki start <prd>`}}let Z=PK(X);return{exitCode:0,stdout:K?LK(Z,Q):kK(Z,Q)}}async function xK($){let K=L$($);return console.log(K.stdout),K.exitCode}var x$=R(()=>{g();p()});var b$={};y(b$,{runDoctor:()=>fK,pythonImportOk:()=>o1,httpReachable:()=>l1,checkTool:()=>N$,checkSkills:()=>C$,checkDisk:()=>d1,buildDoctorJson:()=>D$,_setPythonImportOkForTest:()=>hK});import{existsSync as RK,lstatSync as EK,readlinkSync as FK,statfsSync as SK}from"fs";import{homedir as E$}from"os";import{resolve as R$}from"path";function CK($){let K=$.match(NK);return K?K[1]:null}async function F$($){try{let K=await S([$,"--version"],{timeoutMs:5000}),Q=(K.stdout||K.stderr||"").trim();return CK(Q)}catch{return null}}function S$($,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,U=X[Z]??0;if(Number.isNaN(z)||Number.isNaN(U))return 0;if(z!==U)return z-U}return 0}async function N$($,K,Q,X=null){let Z=await m(K),z=Z!==null,U=z?await F$(K):null,W="pass";if(!z)W=Q==="required"?"fail":"warn";else if(X&&U){if(S$(U,X)<0)W=Q==="required"?"fail":"warn"}return{name:$,command:K,found:z,version:U,required:Q,min_version:X,status:W,path:Z}}function d1(){let $=null;try{let Q=SK(E$()),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 l1($,K=2000){try{return(await fetch($,{signal:AbortSignal.timeout(K)})).ok}catch{return!1}}async function o1($,K=!1){let Q=`import ${$}`,X=K?30000:5000;if(!K)return(await t(Q,{timeoutMs:X})).exitCode===0;let Z=await Q1();if(!Z)return!1;return(await S([Z,"-c",Q],{timeoutMs:X})).exitCode===0}function hK($){j1.fn=$??o1}function C$(){let $=E$();return DK.map(({name:K,dir:Q})=>{let X=R$($,Q),Z=X,z=R$(X,"SKILL.md");if(RK(z))return{name:K,path:Z,status:"pass",detail:""};try{if(EK(X).isSymbolicLink()){let W="unknown";try{W=FK(X)}catch{}return{name:K,path:Z,status:"fail",detail:`(broken symlink -> ${W})`}}}catch{}return{name:K,path:Z,status:"warn",detail:"(not found - run 'loki setup-skill')"}})}async function h$(){return Promise.all(bK.map(async($)=>{return{...await N$($.jsonName,$.cmd,$.required,$.min??null),displayName:$.displayName}}))}async function yK(){let K=await m("sentrux")!==null,Q=K?await F$("sentrux"):null;return{found:K,version:Q,status:K?"pass":"warn",required:"optional"}}async function gK(){let{openSync:$,statSync:K,readSync:Q,closeSync:X,existsSync:Z}=await import("fs"),{join:z}=await import("path"),U=65536,W=process.env.LOKI_DIR??".loki",V=z(W,"memory",".errors.log"),q=[],J=!1;try{if(Z(V)){J=!0;let Y=K(V).size,G=Math.max(0,Y-65536),B=Y-G,M=Buffer.alloc(B),A=$(V,"r");try{Q(A,M,0,B,G)}finally{X(A)}let j=M.toString("utf-8").split(`
334
- `);if(G>0&&j.length>0)j=j.slice(1);j=j.map((b)=>b.trim()).filter((b)=>b.length>0),q=j.slice(-5)}}catch{q=[]}return{errors_log_path:J?V:null,recent_errors:q,recent_error_count:q.length,status:q.length===0?"pass":"warn"}}async function D$(){let K=(await h$()).map(({displayName:V,...q})=>q),Q=d1(),X=await yK(),Z=await gK(),z=0,U=0,W=0;for(let V of K)if(V.status==="pass")z++;else if(V.status==="fail")U++;else W++;if(Q.status==="pass")z++;else if(Q.status==="fail")U++;else W++;return{loki_mode_version:T1(),checks:K,disk:Q,sentrux:X,memory:Z,summary:{passed:z,failed:U,warnings:W,ok:U===0}}}function O($){switch($){case"pass":return`${D}PASS${H}`;case"fail":return`${T}FAIL${H}`;case"warn":return`${L}WARN${H}`}}function w1($){let K=$.version?` (v${$.version})`:"",Q=$.displayName;if(!$.found){let X=$.required==="required"?"not found":$.required==="recommended"?"not found (recommended)":"not found (optional)";return` ${O($.status)} ${Q} - ${X}`}if($.min_version&&$.version&&S$($.version,$.min_version)<0){let X=$.required==="required"?"requires":"recommended";return` ${O($.status)} ${Q}${K} - ${X} >= ${$.min_version}`}return` ${O($.status)} ${Q}${K}`}function I1($,K){if(K==="pass")$.pass++;else if(K==="fail")$.fail++;else $.warn++}function mK(){process.stdout.write(`${N}loki doctor${H} - Check system prerequisites
331
+ `;var E$=E(()=>{n();G1();l();m()});var h$={};g(h$,{runStats:()=>sK,computeStats:()=>C$});import{readdirSync as S$,readFileSync as lK,statSync as N$}from"fs";import{join as s}from"path";function H1($){try{if(!N$($).isFile())return null;return JSON.parse(lK($,"utf-8"))}catch{return null}}function d1($){try{return N$($).isDirectory()}catch{return!1}}function dK($){if(!d1($))return[];try{let K=S$($).filter((Q)=>Q.startsWith("iteration-")&&Q.endsWith(".json"));return K.sort(),K.map((Q)=>s($,Q))}catch{return[]}}function W1($){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 V1($,K){return $.toFixed(K)}function l1($,K){return $.length>=K?$:$+" ".repeat(K-$.length)}function oK($){let K="N/A",Q=0,X=H1(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=dK(Z),U=[];for(let I of z){let R=H1(I);if(R&&typeof R==="object")U.push(R)}if(U.length>0)Q=Math.max(Q,U.length);let W=U.reduce((I,R)=>I+(R.input_tokens??0),0),V=U.reduce((I,R)=>I+(R.output_tokens??0),0),q=W+V,J=U.reduce((I,R)=>I+(R.cost_usd??0),0),Y=U.reduce((I,R)=>I+(R.duration_seconds??0),0),B=0,G=0,M=H1(s($,"metrics","budget.json"));if(M&&typeof M==="object"){if(typeof M.budget_limit==="number")B=M.budget_limit;if(typeof M.budget_used==="number")G=M.budget_used}let T=0,F=0,j=H1(s($,"state","quality-gates.json"));if(j&&typeof j==="object"){if(Array.isArray(j)){for(let I of j)if(F+=1,I===!0)T+=1;else if(I&&typeof I==="object"){let R=I;if(R.passed===!0||R.status==="passed")T+=1}}else for(let I of Object.values(j))if(typeof I==="boolean"){if(F+=1,I)T+=1}else if(I&&typeof I==="object"){F+=1;let R=I;if(R.passed===!0||R.status==="passed")T+=1}}let y={},w=H1(s($,"quality","gate-failure-count.json"));if(w&&typeof w==="object"&&!Array.isArray(w)){let I={};for(let[R,c]of Object.entries(w))if(typeof c==="number")I[R]=c;y=I}let P=0,f=0,G$=0,y1=s($,"quality");if(d1(y1)){let I=[];try{I=S$(y1)}catch{I=[]}for(let R of I){if(!R.endsWith(".json")||R==="gate-failure-count.json")continue;let c=H1(s(y1,R));if(!c||typeof c!=="object")continue;if(!(("verdict"in c)||("approved"in c)||("reviewers"in c)))continue;P+=1;let B$=(c.verdict??"").toString().toLowerCase();if(c.approved===!0||["approved","approve","pass"].includes(B$))f+=1;else if(["revision","revise","changes_requested","reject"].includes(B$))G$+=1}}return{phase:K,iterationCount:Q,iterations:U,totalInput:W,totalOutput:V,totalTokens:q,totalCost:J,totalDuration:Y,budgetLimit:B,budgetUsed:G,gatesPassed:T,gatesTotal:F,gateFailures:y,reviewsTotal:P,reviewsApproved:f,reviewsRevision:G$}}function nK($,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((U,W)=>({number:W+1,input_tokens:U.input_tokens??0,output_tokens:U.output_tokens??0,cost_usd:r(U.cost_usd??0,2),duration_seconds:U.duration_seconds??0}));let Z=JSON.stringify(X,null,2);function z(U,W){if(!W)return;let V=new RegExp(`("${U}": )(-?\\d+)(,?)$`,"m");Z=Z.replace(V,(q,J,Y,B)=>`${J}${Y}.0${B}`)}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,(U,W,V,q)=>`${W}${V}.0${q}`);return Z}function aK($,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: ${W1($.totalInput)}`),Q.push(` Output tokens: ${W1($.totalOutput)}`),Q.push(` Total tokens: ${W1($.totalTokens)}`),Q.push(` Estimated cost: $${V1($.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: ${W1(X)}`),Q.push(` Avg cost/iteration: $${V1(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: $${V1($.budgetUsed,2)} / $${V1($.budgetLimit,2)} (${Z}%)`)}else if($.budgetUsed>0)Q.push(` Used: $${V1($.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,U=l1(W1(X.input_tokens??0),10),W=l1(W1(X.output_tokens??0),10),V=X.cost_usd??0,q=p1(X.duration_seconds??0),J=l1(`${z}`,3);Q.push(` #${J} input: ${U} output: ${W} cost: $${V1(V,2)} time: ${q}`)});return Q.join(`
332
+ `)}function C$($){let K=!1,Q=!1;for(let U of $)if(U==="--json")K=!0;else if(U==="--efficiency")Q=!0;let X=L();if(!d1(X)){if(K)return{exitCode:0,stdout:'{"error": "No active session"}'};return{exitCode:0,stdout:`${x}No active session found.${H}
333
+ Start a session with: loki start <prd>`}}let Z=oK(X);return{exitCode:0,stdout:K?nK(Z,Q):aK(Z,Q)}}async function sK($){let K=C$($);return console.log(K.stdout),K.exitCode}var D$=E(()=>{m();l()});var p$={};g(p$,{runDoctor:()=>V5,pythonImportOk:()=>a1,httpReachable:()=>o1,checkTool:()=>v$,checkSkills:()=>f$,checkDisk:()=>n1,buildDoctorJson:()=>c$,_setPythonImportOkForTest:()=>Q5});import{existsSync as rK,lstatSync as tK,readlinkSync as iK,statfsSync as eK}from"fs";import{homedir as y$}from"os";import{resolve as b$}from"path";function K5($){let K=$.match($5);return K?K[1]:null}async function g$($){try{let K=await k([$,"--version"],{timeoutMs:5000}),Q=(K.stdout||K.stderr||"").trim();return K5(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,U=X[Z]??0;if(Number.isNaN(z)||Number.isNaN(U))return 0;if(z!==U)return z-U}return 0}async function v$($,K,Q,X=null){let Z=await v(K),z=Z!==null,U=z?await g$(K):null,W="pass";if(!z)W=Q==="required"?"fail":"warn";else if(X&&U){if(m$(U,X)<0)W=Q==="required"?"fail":"warn"}return{name:$,command:K,found:z,version:U,required:Q,min_version:X,status:W,path:Z}}function n1(){let $=null;try{let Q=eK(y$()),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 e(Q,{timeoutMs:X})).exitCode===0;let Z=await Z1();if(!Z)return!1;return(await k([Z,"-c",Q],{timeoutMs:X})).exitCode===0}function Q5($){k1.fn=$??a1}function f$(){let $=y$();return X5.map(({name:K,dir:Q})=>{let X=b$($,Q),Z=X,z=b$(X,"SKILL.md");if(rK(z))return{name:K,path:Z,status:"pass",detail:""};try{if(tK(X).isSymbolicLink()){let W="unknown";try{W=iK(X)}catch{}return{name:K,path:Z,status:"fail",detail:`(broken symlink -> ${W})`}}}catch{}return{name:K,path:Z,status:"warn",detail:"(not found - run 'loki setup-skill')"}})}async function u$(){return Promise.all(Z5.map(async($)=>{return{...await v$($.jsonName,$.cmd,$.required,$.min??null),displayName:$.displayName}}))}async function z5(){let K=await v("sentrux")!==null,Q=K?await g$("sentrux"):null;return{found:K,version:Q,status:K?"pass":"warn",required:"optional"}}async function U5(){let{openSync:$,statSync:K,readSync:Q,closeSync:X,existsSync:Z}=await import("fs"),{join:z}=await import("path"),U=65536,W=process.env.LOKI_DIR??".loki",V=z(W,"memory",".errors.log"),q=[],J=!1;try{if(Z(V)){J=!0;let Y=K(V).size,B=Math.max(0,Y-65536),G=Y-B,M=Buffer.alloc(G),T=$(V,"r");try{Q(T,M,0,G,B)}finally{X(T)}let j=M.toString("utf-8").split(`
334
+ `);if(B>0&&j.length>0)j=j.slice(1);j=j.map((y)=>y.trim()).filter((y)=>y.length>0),q=j.slice(-5)}}catch{q=[]}return{errors_log_path:J?V:null,recent_errors:q,recent_error_count:q.length,status:q.length===0?"pass":"warn"}}async function c$(){let K=(await u$()).map(({displayName:V,...q})=>q),Q=n1(),X=await z5(),Z=await U5(),z=0,U=0,W=0;for(let V of K)if(V.status==="pass")z++;else if(V.status==="fail")U++;else W++;if(Q.status==="pass")z++;else if(Q.status==="fail")U++;else W++;return{loki_mode_version:w1(),checks:K,disk:Q,sentrux:X,memory:Z,summary:{passed:z,failed:U,warnings:W,ok:U===0}}}function O($){switch($){case"pass":return`${D}PASS${H}`;case"fail":return`${A}FAIL${H}`;case"warn":return`${x}WARN${H}`}}function P1($){let K=$.version?` (v${$.version})`:"",Q=$.displayName;if(!$.found){let X=$.required==="required"?"not found":$.required==="recommended"?"not found (recommended)":"not found (optional)";return` ${O($.status)} ${Q} - ${X}`}if($.min_version&&$.version&&m$($.version,$.min_version)<0){let X=$.required==="required"?"requires":"recommended";return` ${O($.status)} ${Q}${K} - ${X} >= ${$.min_version}`}return` ${O($.status)} ${Q}${K}`}function L1($,K){if(K==="pass")$.pass++;else if(K==="fail")$.fail++;else $.warn++}function H5(){process.stdout.write(`${N}loki doctor${H} - Check system prerequisites
335
335
 
336
336
  `),process.stdout.write(`Usage: loki doctor [--json]
337
337
 
@@ -340,17 +340,17 @@ Start a session with: loki start <prd>`}}let Z=PK(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 vK(){process.stdout.write(`${N}Loki Mode Doctor${H}
343
+ `)}async function W5(){process.stdout.write(`${N}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 h$(),Q=new Map(K.map((w)=>[w.command,w]));process.stdout.write(`${_}Required:${H}
348
- `);for(let w of["node","python3","jq","git","curl"]){let P=Q.get(w);process.stdout.write(w1(P)+`
349
- `),I1($,P.status)}process.stdout.write(`
347
+ `);let $={pass:0,fail:0,warn:0},K=await u$(),Q=new Map(K.map((w)=>[w.command,w]));process.stdout.write(`${_}Required:${H}
348
+ `);for(let w of["node","python3","jq","git","curl"]){let P=Q.get(w);process.stdout.write(P1(P)+`
349
+ `),L1($,P.status)}process.stdout.write(`
350
350
  `),process.stdout.write(`${_}AI Providers:${H}
351
- `);let X=["claude","codex","cline","aider"],Z=!1;for(let w of X){let P=Q.get(w);if(process.stdout.write(w1(P)+`
352
- `),I1($,P.status),P.found)Z=!0}if(!Z)process.stdout.write(` ${O("fail")} No AI provider CLI installed -- at least one is required
353
- `),process.stdout.write(` ${L}Install: npm install -g @anthropic-ai/claude-code${H}
351
+ `);let X=["claude","codex","cline","aider"],Z=!1;for(let w of X){let P=Q.get(w);if(process.stdout.write(P1(P)+`
352
+ `),L1($,P.status),P.found)Z=!0}if(!Z)process.stdout.write(` ${O("fail")} No AI provider CLI installed -- at least one is required
353
+ `),process.stdout.write(` ${x}Install: npm install -g @anthropic-ai/claude-code${H}
354
354
  `),$.fail++;process.stdout.write(`
355
355
  `),process.stdout.write(`${_}API Keys:${H}
356
356
  `);let z=Q.get("claude")?.found??!1,U=Q.get("codex")?.found??!1,W=process.env;if(W.ANTHROPIC_API_KEY)process.stdout.write(` ${O("pass")} ANTHROPIC_API_KEY is set
@@ -362,62 +362,62 @@ Start a session with: loki start <prd>`}}let Z=PK(X);return{exitCode:0,stdout:K?
362
362
  `),$.warn++;else process.stdout.write(` ${O("pass")} LOKI_MODEL_OVERRIDE: ${W.LOKI_MODEL_OVERRIDE}
363
363
  `),$.pass++}process.stdout.write(`
364
364
  `),process.stdout.write(`${_}Skills:${H}
365
- `);for(let w of C$())if(w.status==="pass")process.stdout.write(` ${O("pass")} ${w.name} ${C}${w.path}${H}
365
+ `);for(let w of f$())if(w.status==="pass")process.stdout.write(` ${O("pass")} ${w.name} ${C}${w.path}${H}
366
366
  `),$.pass++;else if(w.status==="fail")process.stdout.write(` ${O("fail")} ${w.name} ${C}${w.detail}${H}
367
- `),process.stdout.write(` ${L}Fix: loki setup-skill${H}
367
+ `),process.stdout.write(` ${x}Fix: loki setup-skill${H}
368
368
  `),$.fail++;else process.stdout.write(` ${O("warn")} ${w.name} ${C}${w.detail}${H}
369
369
  `),$.warn++;process.stdout.write(`
370
370
  `),process.stdout.write(`${_}Integrations:${H}
371
- `);let[V,q,J]=await Promise.all([j1.fn("mcp"),j1.fn("numpy",!0),j1.fn("sentence_transformers",!0)]);if(V)process.stdout.write(` ${O("pass")} MCP SDK (Python)
371
+ `);let[V,q,J]=await Promise.all([k1.fn("mcp"),k1.fn("numpy",!0),k1.fn("sentence_transformers",!0)]);if(V)process.stdout.write(` ${O("pass")} MCP SDK (Python)
372
372
  `),$.pass++;else process.stdout.write(` ${O("warn")} MCP SDK - not installed (pip3 install mcp)
373
373
  `),$.warn++;if(q)process.stdout.write(` ${O("pass")} numpy (vector search)
374
374
  `),$.pass++;else process.stdout.write(` ${O("warn")} numpy - not installed (pip3 install numpy)
375
375
  `),$.warn++;if(J)process.stdout.write(` ${O("pass")} sentence-transformers (embeddings)
376
376
  `),$.pass++;else process.stdout.write(` ${O("warn")} sentence-transformers - not installed (loki memory vectors setup)
377
- `),$.warn++;if(await l1("http://localhost:8100/api/v2/heartbeat"))process.stdout.write(` ${O("pass")} ChromaDB server (port 8100)
377
+ `),$.warn++;if(await o1("http://localhost:8100/api/v2/heartbeat"))process.stdout.write(` ${O("pass")} ChromaDB server (port 8100)
378
378
  `),$.pass++;else process.stdout.write(` ${O("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 v of w)if(await m(v))P.push(v);if(P.length>0)process.stdout.write(` ${O("pass")} LSP servers detected (${P.length}): ${P.join(", ")}
379
+ `),$.warn++;{let w=["pyright-langserver","pylsp","typescript-language-server","gopls","rust-analyzer","jdtls"],P=[];for(let f of w)if(await v(f))P.push(f);if(P.length>0)process.stdout.write(` ${O("pass")} LSP servers detected (${P.length}): ${P.join(", ")}
380
380
  `),$.pass++;else process.stdout.write(` ${O("warn")} LSP servers - none on PATH (install for symbol grounding: npm i -g pyright typescript-language-server; brew install gopls)
381
- `),$.warn++}let Y=process.env.LOKI_MIROFISH_URL;if(Y)if(await l1(`${Y}/health`))process.stdout.write(` ${O("pass")} MiroFish server (${Y})
381
+ `),$.warn++}let Y=process.env.LOKI_MIROFISH_URL;if(Y)if(await o1(`${Y}/health`))process.stdout.write(` ${O("pass")} MiroFish server (${Y})
382
382
  `),$.pass++;else process.stdout.write(` ${O("warn")} MiroFish - not running (loki start --mirofish-docker <image>)
383
383
  `),$.warn++;if(process.env.LOKI_OTEL_ENDPOINT)process.stdout.write(` ${O("pass")} OTEL endpoint: ${process.env.LOKI_OTEL_ENDPOINT}
384
384
  `),$.pass++;else process.stdout.write(` ${O("warn")} OTEL - not configured (set LOKI_OTEL_ENDPOINT)
385
- `),$.warn++;if(await m("sentrux")){let w="unknown";try{let v=(await S(["sentrux","--version"],{timeoutMs:2000})).stdout.split(/\s+/).filter(Boolean).pop();if(v)w=v.replace(/^v/,"")}catch{}process.stdout.write(` ${O("pass")} sentrux ${w} (architectural drift gate: loki sentrux help)
385
+ `),$.warn++;if(await v("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(` ${O("pass")} sentrux ${w} (architectural drift gate: loki sentrux help)
386
386
  `),$.pass++}else process.stdout.write(` ${O("warn")} sentrux - not installed (optional, brew install sentrux/tap/sentrux)
387
387
  `),$.warn++;process.stdout.write(`
388
388
  `),process.stdout.write(`${_}System:${H}
389
- `);let G=Q.get("bash");process.stdout.write(w1(G)+`
390
- `),I1($,G.status);let B=Q.get("bun");if(B)process.stdout.write(w1(B)+`
391
- `),I1($,B.status);let M=d1(),A=M.available_gb===null?null:Math.floor(M.available_gb);if(A===null)process.stdout.write(` ${O("warn")} Disk space: unable to determine
392
- `),$.warn++;else if(M.status==="fail")process.stdout.write(` ${O("fail")} Disk space: ${A}GB available (need >= 1GB)
393
- `),$.fail++;else if(M.status==="warn")process.stdout.write(` ${O("warn")} Disk space: ${A}GB available (low)
394
- `),$.warn++;else process.stdout.write(` ${O("pass")} Disk space: ${A}GB available
389
+ `);let B=Q.get("bash");process.stdout.write(P1(B)+`
390
+ `),L1($,B.status);let G=Q.get("bun");if(G)process.stdout.write(P1(G)+`
391
+ `),L1($,G.status);let M=n1(),T=M.available_gb===null?null:Math.floor(M.available_gb);if(T===null)process.stdout.write(` ${O("warn")} Disk space: unable to determine
392
+ `),$.warn++;else if(M.status==="fail")process.stdout.write(` ${O("fail")} Disk space: ${T}GB available (need >= 1GB)
393
+ `),$.fail++;else if(M.status==="warn")process.stdout.write(` ${O("warn")} Disk space: ${T}GB available (low)
394
+ `),$.warn++;else process.stdout.write(` ${O("pass")} Disk space: ${T}GB available
395
395
  `),$.pass++;process.stdout.write(`
396
396
  `),process.stdout.write(`${_}Runtime route:${H}
397
- `);let E=process.versions.bun!==void 0,j=process.argv[0]??"(unknown)";if(process.stdout.write(` ${O("pass")} Active runtime: ${E?"Bun":"Node"} (${j})
397
+ `);let F=process.versions.bun!==void 0,j=process.argv[0]??"(unknown)";if(process.stdout.write(` ${O("pass")} Active runtime: ${F?"Bun":"Node"} (${j})
398
398
  `),process.env.LOKI_LEGACY_BASH==="1"||process.env.LOKI_LEGACY_BASH==="true")process.stdout.write(` ${O("warn")} LOKI_LEGACY_BASH set: shim routes every command to autonomy/loki (bash)
399
399
  `);if(process.env.LOKI_TS_ENTRY)process.stdout.write(` ${O("pass")} LOKI_TS_ENTRY override: ${process.env.LOKI_TS_ENTRY}
400
400
  `);if(process.env.BUN_FROM_SOURCE==="1"||process.env.BUN_FROM_SOURCE==="true")process.stdout.write(` ${O("pass")} BUN_FROM_SOURCE set: shim prefers loki-ts/src/ over dist/
401
- `);let b=await Q1();if(b!==null){let P=(await S([b,"-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(` ${O("pass")} Python 3.12 (chromadb / sentence-transformers): ${P} at ${b}
402
- `);else if(P)process.stdout.write(` ${O("warn")} Python 3.12 NOT found -- using ${P} at ${b}; chromadb / sentence-transformers may fail. Install python3.12 (brew install python@3.12 / apt install python3.12).
403
- `);else process.stdout.write(` ${O("warn")} Python 3 found at ${b} but version probe failed; chromadb may not work.
401
+ `);let y=await Z1();if(y!==null){let P=(await k([y,"-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(` ${O("pass")} Python 3.12 (chromadb / sentence-transformers): ${P} at ${y}
402
+ `);else if(P)process.stdout.write(` ${O("warn")} Python 3.12 NOT found -- using ${P} at ${y}; chromadb / sentence-transformers may fail. Install python3.12 (brew install python@3.12 / apt install python3.12).
403
+ `);else process.stdout.write(` ${O("warn")} Python 3 found at ${y} but version probe failed; chromadb may not work.
404
404
  `)}else process.stdout.write(` ${O("warn")} Python 3 not on PATH -- memory + MCP integrations disabled.
405
405
  `);if(process.stdout.write(`
406
- `),process.stdout.write(`${N}Summary:${H} ${D}${$.pass} passed${H}, ${T}${$.fail} failed${H}, ${L}${$.warn} warnings${H}
406
+ `),process.stdout.write(`${N}Summary:${H} ${D}${$.pass} passed${H}, ${A}${$.fail} failed${H}, ${x}${$.warn} warnings${H}
407
407
 
408
- `),$.fail>0)return process.stdout.write(`${T}Some required prerequisites are missing.${H}
408
+ `),$.fail>0)return process.stdout.write(`${A}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(`${L}All required checks passed with some warnings.${H}
410
+ `),1;if($.warn>0)return process.stdout.write(`${x}All required checks passed with some warnings.${H}
411
411
  `),0;return process.stdout.write(`${D}All checks passed. System is ready for Loki Mode.${H}
412
- `),0}async function fK($){let K=!1;for(let Q of $)if(Q==="--json")K=!0;else if(Q==="--help"||Q==="-h")return mK(),0;else return process.stderr.write(`${T}Unknown option: ${Q}${H}
412
+ `),0}async function V5($){let K=!1;for(let Q of $)if(Q==="--json")K=!0;else if(Q==="--help"||Q==="-h")return H5(),0;else return process.stderr.write(`${A}Unknown option: ${Q}${H}
413
413
  `),process.stderr.write(`Usage: loki doctor [--json]
414
- `),1;if(K){let Q=await D$();return process.stdout.write(JSON.stringify(Q,null,2)+`
415
- `),0}return vK()}var NK,j1,DK,bK;var y$=R(()=>{d();V1();p();m1();NK=/(\d+\.\d+(?:\.\d+)*)/;j1={fn:o1};DK=[{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"}];bK=[{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 v$,mkdirSync as y8,readdirSync as uK,readFileSync as f$,renameSync as g8,writeFileSync as m8}from"fs";import{dirname as cK,join as pK,resolve as lK}from"path";import{fileURLToPath as dK}from"url";function oK(){try{let $=cK(dK(import.meta.url)),K=lK($,"..","..","data","model-pricing.json");if(!v$(K))return J1;let X=JSON.parse(f$(K,"utf8")).pricing;if(!X||typeof X!=="object")return J1;let Z={};for(let[z,U]of Object.entries(X))if(U!==null&&typeof U==="object"&&typeof U.input==="number"&&typeof U.output==="number")Z[z]={input:U.input,output:U.output};for(let z of Object.keys(J1))if(!(z in Z))return J1;return Z}catch{return J1}}function nK($){return Math.round(($+Number.EPSILON)*1e4)/1e4}function aK($){let K=($??m$).toLowerCase();return g$[K]??g$[m$]}function u$($){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=aK(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 nK(K)}function c$($){if(!v$($))return[];let K=[],Q;try{Q=uK($)}catch{return[]}for(let X of Q){if(!X.endsWith(".json"))continue;let Z=pK($,X);try{let z=f$(Z,"utf8"),U=JSON.parse(z);if(U&&typeof U==="object")K.push(U)}catch{}}return K}var J1,g$,m$="sonnet";var p$=R(()=>{g();J1={opus:{input:5,output:25},sonnet:{input:3,output:15},haiku:{input:1,output:5},"gpt-5.3-codex":{input:1.5,output:12}};g$=Object.freeze(oK())});import{existsSync as P1,readdirSync as rK,readFileSync as sK,statSync as tK}from"fs";import{join as L1}from"path";function iK($){let K=[],Q=L1($,"votes");if(!P1(Q))return K;let X;try{X=rK(Q)}catch{return K}for(let Z of X){if(!Z.startsWith("round-")||!Z.endsWith(".json"))continue;try{let z=L1(Q,Z);if(!tK(z).isFile())continue;let U=JSON.parse(sK(z,"utf8"));K.push({iteration:typeof U.iteration==="number"?U.iteration:void 0,verdict:typeof U.verdict==="string"?U.verdict:void 0,complete_votes:typeof U.complete_votes==="number"?U.complete_votes:void 0,total_members:typeof U.total_members==="number"?U.total_members:void 0,threshold:typeof U.threshold==="number"?U.threshold:void 0})}catch{}}return K}function eK(){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 $5(){return{council_rounds:0,unanimous_rate:null,approval_rate:null,iteration_success_rate:null}}function K5($){let K=eK();if($.length===0)return K;K.iteration_count=$.length,K.total_cost_usd=Math.round(u$($)*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 Q5($,K,Q){let X=$5();if(X.council_rounds=$.length,$.length>0){let Z=0,z=0;for(let U of $){if(typeof U.complete_votes==="number"&&typeof U.total_members==="number"&&U.total_members>0&&U.complete_votes===U.total_members)Z+=1;if(U.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 l$($){let K=[],Q=L1($,"metrics","efficiency"),X=L1($,"council"),Z=P1(Q)?c$(Q):[];if(!P1(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=iK(X);if(!P1(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 U=K5(Z),W=U.status_breakdown.success??0,V=Q5(z,W,U.iteration_count);return{schema_version:1,generated_at:new Date().toISOString(),loki_dir:$,efficiency:U,accuracy:V,notes:K}}function d$($){return JSON.stringify($,null,2)}function o$($){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,U)=>z[0].localeCompare(U[0]));if(Q.length>0)K.push(` Model breakdown: ${Q.map(([z,U])=>`${z}=${U}`).join(", ")}`);let X=Object.entries($.efficiency.phase_breakdown).sort((z,U)=>z[0].localeCompare(U[0]));if(X.length>0)K.push(` Phase breakdown: ${X.map(([z,U])=>`${z}=${U}`).join(", ")}`);let Z=Object.entries($.efficiency.status_breakdown).sort((z,U)=>z[0].localeCompare(U[0]));if(Z.length>0)K.push(` Status breakdown: ${Z.map(([z,U])=>`${z}=${U}`).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 n$=R(()=>{p$()});var a$={};y(a$,{runKpis:()=>Z5});function Z5($){let K=!1;for(let X of $){if(X==="--help"||X==="-h"||X==="help")return process.stdout.write(X5),0;if(X==="--json"){K=!0;continue}return process.stderr.write(`loki kpis: unknown arg: ${X}
414
+ `),1;if(K){let Q=await c$();return process.stdout.write(JSON.stringify(Q,null,2)+`
415
+ `),0}return W5()}var $5,k1,X5,Z5;var l$=E(()=>{n();G1();l();f1();$5=/(\d+\.\d+(?:\.\d+)*)/;k1={fn:a1};X5=[{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"}];Z5=[{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 n$,mkdirSync as _6,readdirSync as q5,readFileSync as a$,renameSync as w6,writeFileSync as I6}from"fs";import{dirname as J5,join as G5,resolve as B5}from"path";import{fileURLToPath as M5}from"url";function Y5(){try{let $=J5(M5(import.meta.url)),K=B5($,"..","..","data","model-pricing.json");if(!n$(K))return M1;let X=JSON.parse(a$(K,"utf8")).pricing;if(!X||typeof X!=="object")return M1;let Z={};for(let[z,U]of Object.entries(X))if(U!==null&&typeof U==="object"&&typeof U.input==="number"&&typeof U.output==="number")Z[z]={input:U.input,output:U.output};for(let z of Object.keys(M1))if(!(z in Z))return M1;return Z}catch{return M1}}function O5($){return Math.round(($+Number.EPSILON)*1e4)/1e4}function T5($){let K=($??o$).toLowerCase();return d$[K]??d$[o$]}function s$($){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=T5(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 O5(K)}function r$($){if(!n$($))return[];let K=[],Q;try{Q=q5($)}catch{return[]}for(let X of Q){if(!X.endsWith(".json"))continue;let Z=G5($,X);try{let z=a$(Z,"utf8"),U=JSON.parse(z);if(U&&typeof U==="object")K.push(U)}catch{}}return K}var M1,d$,o$="sonnet";var t$=E(()=>{m();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}};d$=Object.freeze(Y5())});import{existsSync as x1,readdirSync as A5,readFileSync as _5,statSync as w5}from"fs";import{join as R1}from"path";function I5($){let K=[],Q=R1($,"votes");if(!x1(Q))return K;let X;try{X=A5(Q)}catch{return K}for(let Z of X){if(!Z.startsWith("round-")||!Z.endsWith(".json"))continue;try{let z=R1(Q,Z);if(!w5(z).isFile())continue;let U=JSON.parse(_5(z,"utf8"));K.push({iteration:typeof U.iteration==="number"?U.iteration:void 0,verdict:typeof U.verdict==="string"?U.verdict:void 0,complete_votes:typeof U.complete_votes==="number"?U.complete_votes:void 0,total_members:typeof U.total_members==="number"?U.total_members:void 0,threshold:typeof U.threshold==="number"?U.threshold:void 0})}catch{}}return K}function j5(){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 P5(){return{council_rounds:0,unanimous_rate:null,approval_rate:null,iteration_success_rate:null}}function L5($){let K=j5();if($.length===0)return K;K.iteration_count=$.length,K.total_cost_usd=Math.round(s$($)*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 k5($,K,Q){let X=P5();if(X.council_rounds=$.length,$.length>0){let Z=0,z=0;for(let U of $){if(typeof U.complete_votes==="number"&&typeof U.total_members==="number"&&U.total_members>0&&U.complete_votes===U.total_members)Z+=1;if(U.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 i$($){let K=[],Q=R1($,"metrics","efficiency"),X=R1($,"council"),Z=x1(Q)?r$(Q):[];if(!x1(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=I5(X);if(!x1(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 U=L5(Z),W=U.status_breakdown.success??0,V=k5(z,W,U.iteration_count);return{schema_version:1,generated_at:new Date().toISOString(),loki_dir:$,efficiency:U,accuracy:V,notes:K}}function e$($){return JSON.stringify($,null,2)}function $0($){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,U)=>z[0].localeCompare(U[0]));if(Q.length>0)K.push(` Model breakdown: ${Q.map(([z,U])=>`${z}=${U}`).join(", ")}`);let X=Object.entries($.efficiency.phase_breakdown).sort((z,U)=>z[0].localeCompare(U[0]));if(X.length>0)K.push(` Phase breakdown: ${X.map(([z,U])=>`${z}=${U}`).join(", ")}`);let Z=Object.entries($.efficiency.status_breakdown).sort((z,U)=>z[0].localeCompare(U[0]));if(Z.length>0)K.push(` Status breakdown: ${Z.map(([z,U])=>`${z}=${U}`).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 K0=E(()=>{t$()});var Q0={};g(Q0,{runKpis:()=>R5});function R5($){let K=!1;for(let X of $){if(X==="--help"||X==="-h"||X==="help")return process.stdout.write(x5),0;if(X==="--json"){K=!0;continue}return process.stderr.write(`loki kpis: unknown arg: ${X}
417
417
  Run 'loki kpis --help' for usage.
418
- `),1}let Q=l$(x());return process.stdout.write(K?d$(Q)+`
419
- `:o$(Q)+`
420
- `),0}var X5=`loki kpis -- accuracy + efficiency KPI snapshot (v7.5.28 MVP)
418
+ `),1}let Q=i$(L());return process.stdout.write(K?e$(Q)+`
419
+ `:$0(Q)+`
420
+ `),0}var x5=`loki kpis -- accuracy + efficiency KPI snapshot (v7.5.28 MVP)
421
421
 
422
422
  Usage:
423
423
  loki kpis Pretty-print KPI snapshot
@@ -437,83 +437,96 @@ 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 r$=R(()=>{n$();g()});import{closeSync as s8,fstatSync as t8,lstatSync as i8,mkdirSync as z5,openSync as e8,readSync as $6,renameSync as U5,rmSync as K6,statSync as Q6,unlinkSync as X6,writeFileSync as H5,writeSync as Z6}from"fs";import{dirname as W5}from"path";function G1($,K){z5(W5($),{recursive:!0});let Q=`${$}.tmp.${process.pid}.${++V5}`;H5(Q,`${JSON.stringify(K,null,2)}
441
- `),U5(Q,$)}async function s$($,K){let Q=k1.get($)??Promise.resolve(),X=()=>{},Z=new Promise((U)=>{X=U}),z=Q.catch(()=>{}).then(()=>Z);k1.set($,z);try{return await Q.catch(()=>{}),await K()}finally{if(X(),k1.get($)===z)k1.delete($)}}var V5=0,k1;var x1=R(()=>{k1=new Map});import{existsSync as R1,mkdirSync as q5,copyFileSync as J5,readFileSync as G5,readdirSync as B5,statSync as M5,writeFileSync as V6,renameSync as Y5,appendFileSync as q6,rmSync as J6}from"fs";import{join as i,dirname as O5}from"path";function E1($){return i($,"state","checkpoints")}function A5($){let K=E1($);if(!R1(K))return[];return B5(K).filter((Q)=>Q.startsWith("cp-")).filter((Q)=>{try{return M5(i(K,Q)).isDirectory()}catch{return!1}})}function _5($){return[...$].sort((K,Q)=>{let X=t$(K),Z=t$(Q);return X-Z})}function t$($){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 a1($){let K=$??x(),Q=_5(A5(K)),X=[];for(let Z of Q){let z=i$(K,Z);if(z)X.push(z)}return X}function i$($,K){let Q=i(E1($),K,"metadata.json");if(!R1(Q))return null;try{let X=JSON.parse(G5(Q,"utf-8"));return w5(X,Q)}catch{return null}}function w5($,K){let Q=P5($,K);return Q.ok?Q.value:null}function P5($,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 j5){let z=Q[Z];if(I5.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 r1($,K){if(!L5.test($))throw new e$($);let Q=K??x(),X=i(E1(Q),$);if(!R1(X))throw new n1($);let Z=i$(Q,$);if(!Z)throw new n1($);return Z}function $0($,K){let Q=r1($,K),X=K??x(),Z=i(E1(X),$),z=[];for(let U of k5){let W=i(Z,U);if(!R1(W))continue;z.push({from:W,to:i(X,U)})}return{id:$,metadata:Q,restore:z}}function K0($){let K=[],Q=0;for(let X of $.restore)try{q5(O5(X.to),{recursive:!0});let Z=`${X.to}.tmp.${process.pid}.${++T5}`;J5(X.from,Z),Y5(Z,X.to),Q+=1}catch(Z){K.push(`${X.from} -> ${X.to}: ${Z.message}`)}return{restored:Q,errors:K}}var O6,T5=0,I5,j5,L5,n1,e$,k5;var Q0=R(()=>{g();d();x1();O6=Promise.resolve();I5=/[\x00-\x08\x0a-\x1f\x7f-\x9f]/,j5=["id","task_id","git_sha","git_branch","provider","phase"];L5=/^[a-zA-Z0-9_-]+$/;n1=class n1 extends Error{id;constructor($){super(`Checkpoint not found: ${$}`);this.id=$;this.name="CheckpointNotFoundError"}};e$=class e$ extends Error{id;constructor($){super(`Invalid checkpoint ID: must be alphanumeric, hyphens, underscores only (got: ${$})`);this.id=$;this.name="InvalidCheckpointIdError"}};k5=["state/orchestrator.json","queue/pending.json","queue/completed.json","queue/in-progress.json","queue/current-task.json"]});var z0={};y(z0,{runRollback:()=>x5});async function x5($){let K=$[0],Q=$.slice(1);if(K===void 0||K==="help"||K==="--help"||K==="-h")return process.stdout.write(X0),K===void 0?1:0;switch(K){case"list":{let X=[...a1()].reverse();if(X.length===0)return process.stdout.write(`${L}No checkpoints found.${H}
440
+ `;var X0=E(()=>{K0();m()});import{closeSync as s1,fstatSync as F5,lstatSync as E5,mkdirSync as Z0,openSync as z0,readSync as S5,renameSync as N5,rmSync as U0,statSync as C5,unlinkSync as H0,writeFileSync as h5,writeSync as D5}from"fs";import{dirname as W0}from"path";function Y1($,K){Z0(W0($),{recursive:!0});let Q=`${$}.tmp.${process.pid}.${++b5}`;h5(Q,`${JSON.stringify(K,null,2)}
441
+ `),N5(Q,$)}async function V0($,K){let Q=F1.get($)??Promise.resolve(),X=()=>{},Z=new Promise((U)=>{X=U}),z=Q.catch(()=>{}).then(()=>Z);F1.set($,z);try{return await Q.catch(()=>{}),await K()}finally{if(X(),F1.get($)===z)F1.delete($)}}function y5($){return`${$}.lock`}function g5($){if(!Number.isFinite($)||$<=0)return!1;try{return process.kill($,0),!0}catch(K){return K?.code==="EPERM"}}function m5($){let K=null;try{return Z0(W0($),{recursive:!0}),K=z0($,"wx"),D5(K,`${process.pid}
442
+ `),K}catch(Q){if(K!==null){try{s1(K)}catch{}try{H0($)}catch{}}if(Q?.code==="EEXIST")return null;throw Q}}function v5($,K){let Q;try{Q=E5($)}catch{return!0}if(Q.isSymbolicLink())try{return H0($),!0}catch{return!1}let X;try{X=z0($,"r")}catch{return!0}try{let Z=F5(X);if(Date.now()-Z.mtimeMs<K)return!1;let U=NaN;try{let W=Buffer.alloc(64),V=S5(X,W,0,64,0);U=Number.parseInt(W.subarray(0,V).toString("utf-8").trim(),10)}catch{}if(Number.isFinite(U)&&g5(U))return!1;try{if(C5($).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,U=y5($),W=Date.now()+X,V=null,q=0,J=new Int32Array(new SharedArrayBuffer(4));while(V===null){if(V=m5(U),V!==null)break;if(Date.now()>W)throw Error(`withFileLockSync: timed out after ${X}ms acquiring ${U}`);if(v5(U,z))continue;let Y=Math.min(Z*2**Math.min(q,4),200);q+=1,Atomics.wait(J,0,0,Y)}try{return K()}finally{try{s1(V)}catch{}try{U0(U,{force:!0})}catch{}}}var b5=0,F1;var E1=E(()=>{F1=new Map});import{existsSync as $1,mkdirSync as q1,copyFileSync as B0,readFileSync as e1,readdirSync as f5,statSync as u5,writeFileSync as c5,renameSync as M0,appendFileSync as Y0,rmSync as p5}from"fs";import{join as b,dirname as S1}from"path";function d5($){let K=J0.then($,$);return J0=K.catch((Q)=>{console.warn("[checkpoint] serialized op rejected:",Q);return}),K}function d($){return b($,"state","checkpoints")}function O0($){return b(d($),"index.jsonl")}async function o5($){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 n5($){let K=await k(["git","branch","--show-current"],{cwd:$,timeoutMs:5000});if(K.exitCode!==0)return"unknown";return K.stdout.trim()||"unknown"}async function a5($){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 s5($){let K=b($,"state","orchestrator.json");if(!$1(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 t5($,K){for(let Q of r5){let X=b($,Q);if(!$1(X))continue;let Z=b(K,Q);q1(S1(Z),{recursive:!0});try{B0(X,Z)}catch{}}}function A0($,K){q1(S1($),{recursive:!0});let Q=`${$}.tmp.${process.pid}.${++T0}`;c5(Q,K),M0(Q,$)}function i5($){return JSON.stringify($,null,2)}function _0($){return`{${[`"id": ${JSON.stringify($.id)}`,`"ts": ${JSON.stringify($.ts)}`,`"iter": ${JSON.stringify($.iter)}`,`"task": ${JSON.stringify($.task)}`,`"sha": ${JSON.stringify($.sha)}`].join(", ")}}`}async function e5($){return d5(()=>$7($))}async function $7($){let K=$.lokiDirOverride??L(),Q=process.cwd(),X=d(K);if(q1(X,{recursive:!0}),!$.forceCreate){if(!await a5(Q))return{created:!1,reason:"no uncommitted changes"}}let Z=await o5(Q),z=await n5(Q),U=$.iteration??Number.parseInt(process.env.ITERATION_COUNT??"0",10),W=$.epochOverride??Math.floor(Date.now()/1000),V=`cp-${U}-${W}`,q=b(X,V);q1(q,{recursive:!0}),t5(K,q);let J=new Date().toISOString().replace(/\.\d{3}Z$/,"Z"),Y=($.taskDescription??"task completed").slice(0,l5),B=$.provider??process.env.PROVIDER_NAME??"claude",G={id:V,timestamp:J,iteration:U,task_id:$.taskId??"unknown",task_description:Y,git_sha:Z,git_branch:z,provider:B,phase:s5(K)};A0(b(q,"metadata.json"),i5(G));let M={id:G.id,ts:G.timestamp,iter:G.iteration,task:G.task_description,sha:G.git_sha},T=O0(K);return r1(T,()=>{Y0(T,`${_0(M)}
443
+ `)}),K7(K),{created:!0,id:V,metadata:G,dir:q}}function $$($){let K=d($);if(!$1(K))return[];return f5(K).filter((Q)=>Q.startsWith("cp-")).filter((Q)=>{try{return u5(b(K,Q)).isDirectory()}catch{return!1}})}function K$($){return[...$].sort((K,Q)=>{let X=G0(K),Z=G0(Q);return X-Z})}function G0($){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 K7($){let K=$$($);if(K.length<=q0)return;let Q=K$(K),X=Q.slice(0,Q.length-q0);for(let Z of X)try{p5(b(d($),Z),{recursive:!0,force:!0})}catch{}Q7($)}function Q7($){let K=K$($$($)),Q=[];for(let z of K){let U=b(d($),z,"metadata.json"),W=b(d($),z);if(!$1(U)){t1($,W,"missing_field","metadata.json");continue}try{let V=JSON.parse(e1(U,"utf-8")),q=I0(V,U);if(!q.ok){t1($,W,q.reason,q.field);continue}let J=q.value;Q.push(_0({id:J.id,ts:J.timestamp,iter:J.iteration,task:J.task_description??"",sha:J.git_sha}))}catch{t1($,W,"invalid_type","metadata.json")}}let X=O0($),Z=Q.length>0?`${Q.join(`
444
+ `)}
445
+ `:"";A0(X,Z)}function t1($,K,Q,X){let Z=b($,"events.jsonl"),z={timestamp:new Date().toISOString(),type:"checkpoint.metadata.dropped",checkpoint_dir:K,reason:Q,field:X};try{q1(S1(Z),{recursive:!0}),r1(Z,()=>{Y0(Z,`${JSON.stringify(z)}
446
+ `)})}catch{}}function Q$($){let K=$??L(),Q=K$($$(K)),X=[];for(let Z of Q){let z=w0(K,Z);if(z)X.push(z)}return X}function w0($,K){let Q=b(d($),K,"metadata.json");if(!$1(Q))return null;try{let X=JSON.parse(e1(Q,"utf-8"));return X7(X,Q)}catch{return null}}function X7($,K){let Q=I0($,K);return Q.ok?Q.value:null}function I0($,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 z7){let z=Q[Z];if(Z7.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(!U7.test($))throw new j0($);let Q=K??L(),X=b(d(Q),$);if(!$1(X))throw new i1($);let Z=w0(Q,$);if(!Z)throw new i1($);return Z}function P0($,K){let Q=X$($,K),X=K??L(),Z=b(d(X),$),z=[];for(let U of H7){let W=b(Z,U);if(!$1(W))continue;z.push({from:W,to:b(X,U)})}return{id:$,metadata:Q,restore:z}}function W7($){let K=[],Q=0;for(let X of $.restore)try{q1(S1(X.to),{recursive:!0});let Z=`${X.to}.tmp.${process.pid}.${++T0}`;B0(X.from,Z),M0(Z,X.to),Q+=1}catch(Z){K.push(`${X.from} -> ${X.to}: ${Z.message}`)}return{restored:Q,errors:K}}async function L0($,K,Q=!1){let X=null;try{let z=await e5({taskDescription:`pre-rollback snapshot (before restoring ${$.id})`,taskId:"rollback",forceCreate:!0,lokiDirOverride:K});if(z.created)X=z.id}catch(z){let U=z instanceof Error?z.message:String(z);if(!Q)throw Error("pre-rollback snapshot failed ("+U+"); 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:",U)}let Z=W7($);return{preRollbackSnapshotId:X,restored:Z.restored,errors:Z.errors}}var q0=50,l5=200,J0,r5,T0=0,Z7,z7,U7,i1,j0,H7;var k0=E(()=>{m();n();E1();J0=Promise.resolve();r5=["state/orchestrator.json","autonomy-state.json","queue/pending.json","queue/completed.json","queue/in-progress.json","queue/current-task.json","CONTINUITY.md"];Z7=/[\x00-\x08\x0a-\x1f\x7f-\x9f]/,z7=["id","task_id","git_sha","git_branch","provider","phase"];U7=/^[a-zA-Z0-9_-]+$/;i1=class i1 extends Error{id;constructor($){super(`Checkpoint not found: ${$}`);this.id=$;this.name="CheckpointNotFoundError"}};j0=class j0 extends Error{id;constructor($){super(`Invalid checkpoint ID: must be alphanumeric, hyphens, underscores only (got: ${$})`);this.id=$;this.name="InvalidCheckpointIdError"}};H7=["state/orchestrator.json","queue/pending.json","queue/completed.json","queue/in-progress.json","queue/current-task.json","CONTINUITY.md"]});var F0={};g(F0,{runRollback:()=>V7});async function V7($){let K=$[0],Q=$.slice(1);if(K===void 0||K==="help"||K==="--help"||K==="-h")return process.stdout.write(x0),K===void 0?1:0;switch(K){case"list":{let X=[...Q$()].reverse();if(X.length===0)return process.stdout.write(`${x}No checkpoints found.${H}
442
447
  `),0;process.stdout.write(`${N}Checkpoints${H} (${X.length}, newest first):
443
448
  `);for(let Z of X)process.stdout.write(` ${_}${Z.id}${H} iter=${Z.iteration} ${Z.git_branch||"(no branch)"}@${(Z.git_sha||"").slice(0,7)} ${Z.timestamp}
444
- `);return 0}case"show":{let X=Q[0];if(!X)return process.stderr.write(`${T}Missing checkpoint id.${H} Use \`loki rollback list\`.
445
- `),2;try{let Z=r1(X);return process.stdout.write(`${JSON.stringify(Z,null,2)}
446
- `),0}catch(Z){return process.stderr.write(`${T}Failed to read checkpoint:${H} ${Z.message}
447
- `),1}}case"to":{let X=Q[0];if(!X)return process.stderr.write(`${T}Missing checkpoint id.${H} Use \`loki rollback list\`.
448
- `),2;return Z0(X)}case"latest":{let X=a1(),Z=X[X.length-1];if(!Z)return process.stderr.write(`${T}No checkpoints found to roll back to.${H}
449
+ `);return 0}case"show":{let X=Q[0];if(!X)return process.stderr.write(`${A}Missing checkpoint id.${H} 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(`${A}Failed to read checkpoint:${H} ${Z.message}
452
+ `),1}}case"to":{let X=Q[0];if(!X)return process.stderr.write(`${A}Missing checkpoint id.${H} 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(`${A}No checkpoints found to roll back to.${H}
449
454
  `),1;return process.stdout.write(`Rolling back to latest checkpoint: ${_}${Z.id}${H}
450
- `),Z0(Z.id)}default:return process.stderr.write(`Unknown subcommand: ${K}
451
- `),process.stderr.write(X0),2}}function Z0($){let K;try{K=$0($)}catch(X){return process.stderr.write(`${T}Cannot plan rollback:${H} ${X.message}
452
- `),1}if(K.restore.length===0)return process.stdout.write(`${L}Checkpoint ${$} has no restorable state files; nothing to do.${H}
453
- `),0;let Q=K0(K);if(Q.errors.length>0){for(let X of Q.errors)process.stderr.write(`${T}restore error:${H} ${X}
454
- `);return process.stderr.write(`${T}Partial rollback: ${Q.restored}/${K.restore.length} files restored.${H}
455
- `),1}return process.stdout.write(`${D}Rolled back ${Q.restored}/${K.restore.length} state files from ${$}.${H}
456
- `),process.stdout.write("Run `loki start` to resume from the restored state.\n"),0}var X0=`Usage: loki rollback <subcommand>
455
+ `),await R0(Z.id,Q.includes("--force"))}default:return process.stderr.write(`Unknown subcommand: ${K}
456
+ `),process.stderr.write(x0),2}}async function R0($,K=!1){let Q;try{Q=P0($)}catch(Z){return process.stderr.write(`${A}Cannot plan rollback:${H} ${Z.message}
457
+ `),1}if(Q.restore.length===0)return process.stdout.write(`${x}Checkpoint ${$} has no restorable state files; nothing to do.${H}
458
+ `),0;let X;try{X=await L0(Q,void 0,K)}catch(Z){return process.stderr.write(`${A}Rollback aborted:${H} ${Z.message}
459
+ `),1}if(X.errors.length>0){for(let Z of X.errors)process.stderr.write(`${A}restore error:${H} ${Z}
460
+ `);return process.stderr.write(`${A}Partial rollback: ${X.restored}/${Q.restore.length} files restored.${H}
461
+ `),1}if(process.stdout.write(`${D}Rolled back ${X.restored}/${Q.restore.length} state files from ${$}.${H}
462
+ `),X.preRollbackSnapshotId)process.stdout.write(`Saved your prior state as ${_}${X.preRollbackSnapshotId}${H}; 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 x0=`Usage: loki rollback <subcommand>
457
464
 
458
465
  Subcommands:
459
466
  list List checkpoints (newest first)
460
467
  show <id> Print metadata for one checkpoint
461
- to <id> Restore .loki/ state files to that checkpoint
468
+ to <id> Restore .loki/ state + context to that checkpoint
462
469
  latest Restore to the most recent checkpoint
463
470
 
464
- Restored files (matches autonomy/run.sh:7028 byte-for-byte):
471
+ Restored automatically (safe, non-code):
465
472
  .loki/state/orchestrator.json
466
473
  .loki/queue/{pending,completed,in-progress,current-task}.json
474
+ .loki/CONTINUITY.md (iteration / conversation handoff context)
467
475
 
468
- Note: only state files are restored. Source code, git history, and the
469
- session's autonomy-state.json are unchanged. Re-run \`loki start\` to
470
- resume from the restored state.
471
- `;var U0=R(()=>{Q0();p()});var V0={};y(V0,{runProof:()=>v5});import{existsSync as B1,readdirSync as R5,readFileSync as H0,mkdtempSync as E5,copyFileSync as F5,rmSync as S5}from"fs";import{join as $1}from"path";import{tmpdir as N5}from"os";import{createInterface as C5}from"readline";function e($){return $&&typeof $==="object"?$:{}}function f($){return $===void 0||$===null?"-":String($)}function F1(){return $1(x(),"proofs")}function W0($){let K=$1(F1(),$,"proof.json");if(!B1(K))return null;try{return JSON.parse(H0(K,"utf8"))}catch{return{}}}function r($,K){return $.length>=K?$:$+" ".repeat(K-$.length)}function D5(){let $=F1();if(!B1($))return process.stdout.write(`${L}No proofs found.${H} Run 'loki start' to generate one.
472
- `),0;let K=[];try{K=R5($,{withFileTypes:!0}).filter((X)=>X.isDirectory()).map((X)=>X.name).sort()}catch{K=[]}let Q=[];for(let X of K){let Z=$1($,X,"proof.json");if(!B1(Z))continue;let z={};try{z=JSON.parse(H0(Z,"utf8"))}catch{z={}}let U=f(z.run_id),W=f(z.generated_at),V=f(e(z.council).final_verdict),q=f(e(z.cost).usd),J=f(e(z.files_changed).count);Q.push(`${r(U,26)} ${r(W,20)} ${r(V,10)} ${r(q,9)} ${J}`)}if(Q.length===0)return process.stdout.write(`${L}No proofs found.${H} Run 'loki start' to generate one.
473
- `),0;process.stdout.write(`${r("RUN_ID",26)} ${r("GENERATED_AT",20)} ${r("VERDICT",10)} ${r("COST_USD",9)} FILES
476
+ Re-undoable: every rollback first captures a forced pre-rollback snapshot of
477
+ your current state, so you can always undo the undo (the snapshot id is printed).
478
+
479
+ Source code is NOT touched by this command. To also restore the working tree
480
+ to the checkpoint's snapshot (if one was anchored at checkpoint time):
481
+ git stash apply refs/loki/cp/<id>
482
+
483
+ Re-run \`loki start\` to resume from the restored state.
484
+ `;var E0=E(()=>{k0();l()});var C0={};g(C0,{runProof:()=>j7});import{existsSync as O1,readdirSync as q7,readFileSync as S0,mkdtempSync as J7,copyFileSync as G7,rmSync as B7}from"fs";import{join as Q1}from"path";import{tmpdir as M7}from"os";import{createInterface as Y7}from"readline";function K1($){return $&&typeof $==="object"?$:{}}function u($){return $===void 0||$===null?"-":String($)}function N1(){return Q1(L(),"proofs")}function N0($){let K=Q1(N1(),$,"proof.json");if(!O1(K))return null;try{return JSON.parse(S0(K,"utf8"))}catch{return{}}}function t($,K){return $.length>=K?$:$+" ".repeat(K-$.length)}function T7(){let $=N1();if(!O1($))return process.stdout.write(`${x}No proofs found.${H} Run 'loki start' to generate one.
485
+ `),0;let K=[];try{K=q7($,{withFileTypes:!0}).filter((X)=>X.isDirectory()).map((X)=>X.name).sort()}catch{K=[]}let Q=[];for(let X of K){let Z=Q1($,X,"proof.json");if(!O1(Z))continue;let z={};try{z=JSON.parse(S0(Z,"utf8"))}catch{z={}}let U=u(z.run_id),W=u(z.generated_at),V=u(K1(z.council).final_verdict),q=u(K1(z.cost).usd),J=u(K1(z.files_changed).count);Q.push(`${t(U,26)} ${t(W,20)} ${t(V,10)} ${t(q,9)} ${J}`)}if(Q.length===0)return process.stdout.write(`${x}No proofs found.${H} Run 'loki start' to generate one.
486
+ `),0;process.stdout.write(`${t("RUN_ID",26)} ${t("GENERATED_AT",20)} ${t("VERDICT",10)} ${t("COST_USD",9)} FILES
474
487
  `);for(let X of Q)process.stdout.write(`${X}
475
- `);return 0}function b5($){if(!$)return process.stderr.write(`${T}Missing proof id.${H} Use 'loki proof list'.
476
- `),2;let K=W0($);if(K===null)return process.stderr.write(`${T}Proof not found: ${$}${H}
488
+ `);return 0}function A7($){if(!$)return process.stderr.write(`${A}Missing proof id.${H} Use 'loki proof list'.
489
+ `),2;let K=N0($);if(K===null)return process.stderr.write(`${A}Proof not found: ${$}${H}
477
490
  `),process.stderr.write(`Use 'loki proof list' to see available proofs.
478
491
  `),1;return process.stdout.write(`${JSON.stringify(K,null,2)}
479
- `),0}async function y5($){if(!$)return process.stderr.write(`${T}Missing proof id.${H} Use 'loki proof list'.
480
- `),2;let K=$1(F1(),$,"index.html");if(!B1(K))return process.stderr.write(`${T}Proof page not found: ${$}/index.html${H}
492
+ `),0}async function _7($){if(!$)return process.stderr.write(`${A}Missing proof id.${H} Use 'loki proof list'.
493
+ `),2;let K=Q1(N1(),$,"index.html");if(!O1(K))return process.stderr.write(`${A}Proof page not found: ${$}/index.html${H}
481
494
  `),process.stderr.write(`Use 'loki proof list' to see available proofs.
482
495
  `),1;process.stdout.write(`${D}Opening proof: ${K}${H}
483
- `);for(let Q of["open","xdg-open","start"])try{if((await S([Q,K],{timeoutMs:5000})).exitCode===0)return 0}catch{}return process.stdout.write(`
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(`
484
497
  Could not detect browser opener.
485
498
  `),process.stdout.write(`Please open in browser: ${K}
486
- `),0}function g5($){return new Promise((K)=>{let Q=C5({input:process.stdin,output:process.stdout});Q.question($,(X)=>{Q.close();let Z=X.trim().toLowerCase();K(Z==="y"||Z==="yes")})})}async function m5($){let K="",Q=!1,X="--public";for(let M of $)if(M==="--yes"||M==="-y")Q=!0;else if(M==="--private")X="";else if(M==="--public")X="--public";else if(M==="--hosted")return process.stderr.write(`${T}Hosted publishing is not available yet (coming in R9).${H}
487
- `),1;else if(M.startsWith("-"))return process.stderr.write(`${T}Unknown option: ${M}${H}
488
- `),1;else K=M;if(!K)return process.stderr.write(`${T}Missing proof id.${H} Use 'loki proof list'.
489
- `),2;let Z=$1(F1(),K,"index.html");if(!B1(Z))return process.stderr.write(`${T}Proof page not found: ${K}/index.html${H}
499
+ `),0}function w7($){return new Promise((K)=>{let Q=Y7({input:process.stdin,output:process.stdout});Q.question($,(X)=>{Q.close();let Z=X.trim().toLowerCase();K(Z==="y"||Z==="yes")})})}async function I7($){let K="",Q=!1,X="--public";for(let M of $)if(M==="--yes"||M==="-y")Q=!0;else if(M==="--private")X="";else if(M==="--public")X="--public";else if(M==="--hosted")return process.stderr.write(`${A}Hosted publishing is not available yet (coming in R9).${H}
500
+ `),1;else if(M.startsWith("-"))return process.stderr.write(`${A}Unknown option: ${M}${H}
501
+ `),1;else K=M;if(!K)return process.stderr.write(`${A}Missing proof id.${H} Use 'loki proof list'.
502
+ `),2;let Z=Q1(N1(),K,"index.html");if(!O1(Z))return process.stderr.write(`${A}Proof page not found: ${K}/index.html${H}
490
503
  `),process.stderr.write(`Use 'loki proof list' to see available proofs.
491
- `),1;if((await S(["gh","--version"],{timeoutMs:5000})).exitCode!==0)return process.stderr.write(`${T}gh CLI not found${H}
504
+ `),1;if((await k(["gh","--version"],{timeoutMs:5000})).exitCode!==0)return process.stderr.write(`${A}gh CLI not found${H}
492
505
  `),process.stderr.write(`Install the GitHub CLI to publish a proof:
493
506
  `),process.stderr.write(` brew install gh # macOS
494
507
  `),process.stderr.write(` sudo apt install gh # Ubuntu/Debian
495
508
  `),process.stderr.write(` https://cli.github.com # Other platforms
496
- `),1;if((await S(["gh","auth","status"],{timeoutMs:1e4})).exitCode!==0)return process.stderr.write(`${T}GitHub CLI not authenticated${H}
509
+ `),1;if((await k(["gh","auth","status"],{timeoutMs:1e4})).exitCode!==0)return process.stderr.write(`${A}GitHub CLI not authenticated${H}
497
510
  `),process.stderr.write(`Run 'gh auth login' to authenticate, then try again.
498
511
  `),1;let W=X===""?"secret":"public";process.stdout.write(`${N}Publishing proof '${K}' as a ${W} GitHub Gist${H}
499
512
 
500
513
  `),process.stdout.write(`What will be shared:
501
514
  `),process.stdout.write(` - ${Z}
502
- `);let V=W0(K);if(V){let M=f(e(V.cost).usd),A=f(e(V.files_changed).count),E=f(e(V.council).final_verdict),j=e(V.redaction);process.stdout.write(` - cost.usd: ${M}
503
- `),process.stdout.write(` - files_changed: ${A}
504
- `),process.stdout.write(` - council verdict: ${E}
505
- `),process.stdout.write(` - redaction: applied=${f(j.applied)} rules_version=${f(j.rules_version)} redactions_count=${f(j.redactions_count)}
515
+ `);let V=N0(K);if(V){let M=u(K1(V.cost).usd),T=u(K1(V.files_changed).count),F=u(K1(V.council).final_verdict),j=K1(V.redaction);process.stdout.write(` - cost.usd: ${M}
516
+ `),process.stdout.write(` - files_changed: ${T}
517
+ `),process.stdout.write(` - council verdict: ${F}
518
+ `),process.stdout.write(` - redaction: applied=${u(j.applied)} rules_version=${u(j.rules_version)} redactions_count=${u(j.redactions_count)}
506
519
  `)}if(process.stdout.write(`
507
- ${L}Secrets, API keys, tokens, env values, and absolute paths have already been stripped by the generator.${H}
508
-
509
- `),!Q){if(!await g5(`Publish this proof to a ${W} gist? [y/N] `))return process.stdout.write(`Aborted. Nothing was published.
510
- `),0}let q=E5($1(N5(),"loki-proof-")),J=$1(q,"index.html");F5(Z,J),process.stdout.write(`Uploading proof page...
511
- `);let Y=`Loki Mode proof-of-run ${K}`,G=["gh","gist","create",J,"--desc",Y];if(X!=="")G.push(X);let B=await S(G,{timeoutMs:60000});try{S5(q,{recursive:!0,force:!0})}catch{}if(B.exitCode!==0)return process.stderr.write(`${T}Failed to create gist${H}
512
- `),process.stderr.write(`${B.stdout}${B.stderr}
513
- `),1;return process.stdout.write(`${D}Shared: ${B.stdout.trim()}${H}
514
- `),0}async function v5($){let K=$[0],Q=$.slice(1);if(K===void 0||K==="help"||K==="--help"||K==="-h")return process.stdout.write(h5),K===void 0?1:0;switch(K){case"list":return D5();case"show":return b5(Q[0]);case"open":return y5(Q[0]);case"share":return m5(Q);default:return process.stderr.write(`${T}Unknown subcommand: ${K}${H}
520
+ ${x}Secrets, API keys, tokens, env values, and absolute paths have already been stripped by the generator.${H}
521
+
522
+ `),!Q){if(!await w7(`Publish this proof to a ${W} gist? [y/N] `))return process.stdout.write(`Aborted. Nothing was published.
523
+ `),0}let q=J7(Q1(M7(),"loki-proof-")),J=Q1(q,"index.html");G7(Z,J),process.stdout.write(`Uploading proof page...
524
+ `);let Y=`Loki Mode proof-of-run ${K}`,B=["gh","gist","create",J,"--desc",Y];if(X!=="")B.push(X);let G=await k(B,{timeoutMs:60000});try{B7(q,{recursive:!0,force:!0})}catch{}if(G.exitCode!==0)return process.stderr.write(`${A}Failed to create gist${H}
525
+ `),process.stderr.write(`${G.stdout}${G.stderr}
526
+ `),1;return process.stdout.write(`${D}Shared: ${G.stdout.trim()}${H}
527
+ `),0}async function j7($){let K=$[0],Q=$.slice(1);if(K===void 0||K==="help"||K==="--help"||K==="-h")return process.stdout.write(O7),K===void 0?1:0;switch(K){case"list":return T7();case"show":return A7(Q[0]);case"open":return _7(Q[0]);case"share":return I7(Q);default:return process.stderr.write(`${A}Unknown subcommand: ${K}${H}
515
528
  `),process.stderr.write(`Run 'loki proof --help' for usage.
516
- `),1}}var h5;var q0=R(()=>{g();d();p();h5=`${N}loki proof${H} - inspect and share proof-of-run artifacts
529
+ `),1}}var O7;var h0=E(()=>{m();n();l();O7=`${N}loki proof${H} - inspect and share proof-of-run artifacts
517
530
 
518
531
  Usage: loki proof <subcommand> [args]
519
532
 
@@ -529,15 +542,15 @@ Options for 'share':
529
542
  --hosted Reserved for hosted publishing (coming in R9)
530
543
 
531
544
  Proofs are generated automatically at run completion (LOKI_PROOF=0 to opt out).
532
- `});var M0={};y(M0,{runWiki:()=>l5});import{existsSync as s1,readFileSync as J0}from"fs";import{join as t1,resolve as f5}from"path";function c5(){return t1(process.cwd(),".loki","wiki")}function p5($){let K="";for(let Z of $){if(Z==="--help"||Z==="-h")return process.stdout.write(`Usage: loki wiki show [section]
545
+ `});var g0={};g(g0,{runWiki:()=>R7});import{existsSync as Z$,readFileSync as D0}from"fs";import{join as z$,resolve as P7}from"path";function k7(){return z$(process.cwd(),".loki","wiki")}function x7($){let K="";for(let Z of $){if(Z==="--help"||Z==="-h")return process.stdout.write(`Usage: loki wiki show [section]
533
546
  Sections: architecture, modules, data-flow
534
- `),0;if(Z.startsWith("-"))return process.stderr.write(`${T}Unknown option: ${Z}${H}
535
- `),1;K=Z}let Q=c5();if(!s1(Q))return process.stderr.write(`${L}No wiki found. Run 'loki wiki generate' first.${H}
536
- `),1;if(K){if(!u5.has(K))return process.stderr.write(`${T}No such section: ${K} (try: architecture, modules, data-flow)${H}
537
- `),1;let Z=t1(Q,`${K}.md`);if(!s1(Z))return process.stderr.write(`${T}Section not generated: ${K}${H}
538
- `),1;return process.stdout.write(J0(Z,"utf8")),0}let X=t1(Q,"index.md");if(!s1(X))return process.stderr.write(`${T}Wiki index not found. Run 'loki wiki generate'.${H}
539
- `),1;return process.stdout.write(J0(X,"utf8")),0}async function B0($,K){let Q=f5(c,"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 l5($){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 p5(Q);case"generate":return B0("generate",Q);case"ask":return B0("ask",Q);default:return process.stderr.write(`${T}Unknown wiki command: ${K}${H}
540
- `),process.stdout.write(G0),1}}var G0,u5;var Y0=R(()=>{g();p();G0=`${N}loki wiki${H} - Auto-generated, cited codebase wiki + Q&A
547
+ `),0;if(Z.startsWith("-"))return process.stderr.write(`${A}Unknown option: ${Z}${H}
548
+ `),1;K=Z}let Q=k7();if(!Z$(Q))return process.stderr.write(`${x}No wiki found. Run 'loki wiki generate' first.${H}
549
+ `),1;if(K){if(!L7.has(K))return process.stderr.write(`${A}No such section: ${K} (try: architecture, modules, data-flow)${H}
550
+ `),1;let Z=z$(Q,`${K}.md`);if(!Z$(Z))return process.stderr.write(`${A}Section not generated: ${K}${H}
551
+ `),1;return process.stdout.write(D0(Z,"utf8")),0}let X=z$(Q,"index.md");if(!Z$(X))return process.stderr.write(`${A}Wiki index not found. Run 'loki wiki generate'.${H}
552
+ `),1;return process.stdout.write(D0(X,"utf8")),0}async function y0($,K){let Q=P7(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 R7($){let K=$[0],Q=$.slice(1);switch(K){case void 0:case"help":case"--help":case"-h":return process.stdout.write(b0),0;case"show":return x7(Q);case"generate":return y0("generate",Q);case"ask":return y0("ask",Q);default:return process.stderr.write(`${A}Unknown wiki command: ${K}${H}
553
+ `),process.stdout.write(b0),1}}var b0,L7;var m0=E(()=>{m();l();b0=`${N}loki wiki${H} - Auto-generated, cited codebase wiki + Q&A
541
554
 
542
555
  Usage: loki wiki <command> [options]
543
556
 
@@ -553,8 +566,8 @@ Examples:
553
566
  loki wiki generate
554
567
  loki wiki show architecture
555
568
  loki wiki ask "how does the cli dispatch commands"
556
- `,u5=new Set(["architecture","modules","data-flow"])});var e1={};y(e1,{renderFindingsForPrompt:()=>r5,loadPreviousFindings:()=>i1,findLatestReviewDir:()=>w0,_parseReviewerOutputForTests:()=>s5});import{existsSync as T0,readFileSync as O0,readdirSync as A0,statSync as d5}from"fs";import{join as S1}from"path";function a5($){let K=$.toLowerCase();if(K==="critical")return"Critical";if(K==="high")return"High";if(K==="medium")return"Medium";return"Low"}function _0($,K,Q,X){let Z=[],z=$.split(/\r?\n/);for(let U of z){let W=U.trim();if(W.length===0)continue;let V=W.replace(/^[-*]\s*/,""),q=o5.exec(V);if(!q||!q[1]||!q[2])continue;let J=a5(q[1]),Y=q[2].trim(),G=n5.exec(Y),B=G&&G[1]?G[1]:null,M=G&&G[2]?Number.parseInt(G[2],10):null;Z.push({reviewId:Q,iteration:X,reviewer:K,severity:J,description:Y,file:B,line:Number.isFinite(M)?M:null,raw:W})}return Z}function w0($,K){let Q=S1($,"quality","reviews");if(!T0(Q))return null;let X;try{X=A0(Q)}catch{return null}let Z=K===void 0?X.filter((W)=>W.startsWith("review-")):X.filter((W)=>W.endsWith(`-${K}`)&&W.startsWith("review-"));if(Z.length===0)return null;Z.sort();let z=Z[Z.length-1];if(!z)return null;let U=S1(Q,z);try{if(!d5(U).isDirectory())return null}catch{return null}return U}function i1($,K){let Q=w0($,K);if(Q===null)return{reviewDir:null,reviewId:null,iteration:null,findings:[]};let X=null,Z=null,z=S1(Q,"aggregate.json");if(T0(z))try{let q=O0(z,"utf-8"),J=JSON.parse(q);if(typeof J.review_id==="string")X=J.review_id;if(typeof J.iteration==="number")Z=J.iteration}catch{}let U;try{U=A0(Q)}catch{return{reviewDir:Q,reviewId:X,iteration:Z,findings:[]}}let W=new Set(["diff.txt","files.txt","anti-sycophancy.txt"]),V=[];for(let q of U){if(!q.endsWith(".txt"))continue;if(W.has(q))continue;if(q.endsWith("-prompt.txt"))continue;let J=q.replace(/\.txt$/,""),Y;try{Y=O0(S1(Q,q),"utf-8")}catch{continue}V.push(..._0(Y,J,X??"",Z??-1))}return{reviewDir:Q,reviewId:X,iteration:Z,findings:V}}function r5($){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 U of z){let W=U.file?` (${U.file}${U.line!==null?":"+U.line:""})`:"";X.push(` - ${U.description}${W} -- via ${U.reviewer}`)}}return X.join(`
557
- `)}function s5($,K,Q="review-test",X=0){return _0($,K,Q,X)}var o5,n5;var N1=R(()=>{o5=/\[(Critical|High|Medium|Low)\]\s*(.+)/i,n5=/([\w.\-/]+\.[a-zA-Z]+):(\d+)/});import{existsSync as t5}from"fs";import{join as i5}from"path";async function I0($,K){let Q=i5($,"memory");if(!t5(Q))return{stored:!1,reason:"memory dir not initialized"};let X=Math.max(0,Math.floor(K.durationSeconds??0)),Z={_LOKI_PROJECT_DIR:c,_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:$},U=await t(`
569
+ `,L7=new Set(["architecture","modules","data-flow"])});var H$={};g(H$,{renderFindingsForPrompt:()=>C7,loadPreviousFindings:()=>U$,findLatestReviewDir:()=>p0,_parseReviewerOutputForTests:()=>h7});import{existsSync as f0,readFileSync as v0,readdirSync as u0,statSync as F7}from"fs";import{join as C1}from"path";function N7($){let K=$.toLowerCase();if(K==="critical")return"Critical";if(K==="high")return"High";if(K==="medium")return"Medium";return"Low"}function c0($,K,Q,X){let Z=[],z=$.split(/\r?\n/);for(let U of z){let W=U.trim();if(W.length===0)continue;let V=W.replace(/^[-*]\s*/,""),q=E7.exec(V);if(!q||!q[1]||!q[2])continue;let J=N7(q[1]),Y=q[2].trim(),B=S7.exec(Y),G=B&&B[1]?B[1]:null,M=B&&B[2]?Number.parseInt(B[2],10):null;Z.push({reviewId:Q,iteration:X,reviewer:K,severity:J,description:Y,file:G,line:Number.isFinite(M)?M:null,raw:W})}return Z}function p0($,K){let Q=C1($,"quality","reviews");if(!f0(Q))return null;let X;try{X=u0(Q)}catch{return null}let Z=K===void 0?X.filter((W)=>W.startsWith("review-")):X.filter((W)=>W.endsWith(`-${K}`)&&W.startsWith("review-"));if(Z.length===0)return null;Z.sort();let z=Z[Z.length-1];if(!z)return null;let U=C1(Q,z);try{if(!F7(U).isDirectory())return null}catch{return null}return U}function U$($,K){let Q=p0($,K);if(Q===null)return{reviewDir:null,reviewId:null,iteration:null,findings:[]};let X=null,Z=null,z=C1(Q,"aggregate.json");if(f0(z))try{let q=v0(z,"utf-8"),J=JSON.parse(q);if(typeof J.review_id==="string")X=J.review_id;if(typeof J.iteration==="number")Z=J.iteration}catch{}let U;try{U=u0(Q)}catch{return{reviewDir:Q,reviewId:X,iteration:Z,findings:[]}}let W=new Set(["diff.txt","files.txt","anti-sycophancy.txt"]),V=[];for(let q of U){if(!q.endsWith(".txt"))continue;if(W.has(q))continue;if(q.endsWith("-prompt.txt"))continue;let J=q.replace(/\.txt$/,""),Y;try{Y=v0(C1(Q,q),"utf-8")}catch{continue}V.push(...c0(Y,J,X??"",Z??-1))}return{reviewDir:Q,reviewId:X,iteration:Z,findings:V}}function C7($){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 U of z){let W=U.file?` (${U.file}${U.line!==null?":"+U.line:""})`:"";X.push(` - ${U.description}${W} -- via ${U.reviewer}`)}}return X.join(`
570
+ `)}function h7($,K,Q="review-test",X=0){return c0($,K,Q,X)}var E7,S7;var h1=E(()=>{E7=/\[(Critical|High|Medium|Low)\]\s*(.+)/i,S7=/([\w.\-/]+\.[a-zA-Z]+):(\d+)/});import{existsSync as D7}from"fs";import{join as b7}from"path";async function l0($,K){let Q=b7($,"memory");if(!D7(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:$},U=await e(`
558
571
  import os, sys
559
572
  project = os.environ.get('_LOKI_PROJECT_DIR', '')
560
573
  loki = os.environ.get('_LOKI_LOKI_DIR', '.loki')
@@ -581,23 +594,23 @@ try:
581
594
  print('OK')
582
595
  except Exception as e:
583
596
  print('ERR:' + str(e))
584
- `,{env:Z,timeoutMs:15000});if(U.exitCode===127)return{stored:!1,reason:"python3 not found"};let W=U.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:U.stderr.trim()||"unknown"}}var j0=R(()=>{V1();g()});var x0={};y(x0,{loadLearnings:()=>$$,appendLearning:()=>M1,appendFromGateFailure:()=>U7});import{existsSync as e5,readFileSync as $7}from"fs";import{join as P0}from"path";import{createHash as K7}from"crypto";function L0($){return P0($,Q7)}function X7($){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 k0($){if(!e5($))return{version:1,learnings:[]};try{let K=$7($,"utf-8"),Q=JSON.parse(K);if(Q.version===1&&Array.isArray(Q.learnings))return{version:1,learnings:Q.learnings.filter(X7)}}catch{}return{version:1,learnings:[]}}function Z7($,K){return K7("sha256").update(`${$}\x00${K}`).digest("hex").slice(0,16)}async function M1($,K,Q={}){let X=Z7(K.trigger,K.rootCause),Z=new Date().toISOString(),z={id:X,timestamp:Z,...K},U=L0($);if(await s$(U,()=>{let V=k0(U),q=V.learnings.findIndex((J)=>J.id===X);if(q>=0){let J=V.learnings[q];V.learnings[q]={...J,timestamp:Z,iteration:z.iteration}}else V.learnings.push(z);G1(U,V)}),Q.episodeBridge!==null&&(Q.episodeBridge!==void 0||process.env.LOKI_AUTO_LEARNINGS_EPISODE==="1")){let V=Q.episodeBridge??I0,q=Q.bridgeFailureLog??z7;try{let J=await V($,{taskId:`learning-${X}`,outcome:"failure",phase:"VERIFY",goal:`${K.trigger}: ${K.rootCause}`});if(J&&!J.stored){if(!new Set(["memory dir not initialized","stub"]).has(J.reason))q(`episode_bridge skipped: ${J.reason}`)}}catch(J){q(`episode_bridge threw: ${J.message}`)}}return z}function z7($){process.stderr.write(`[learnings_writer] ${$}
585
- `)}async function U7($,K,Q,X={}){let Z=`[${Q.severity}] ${Q.description}`;return M1($,{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 $$($){return k0(L0($))}var Q7;var C1=R(()=>{x1();j0();Q7=P0("state","relevant-learnings.json")});var E0={};y(E0,{runOverrideCouncil:()=>G7,recordOverrideOutcome:()=>B7,loadCounterEvidence:()=>J7,canonicalFindingId:()=>K$,DEFAULT_OVERRIDE_JUDGES:()=>R0});import{existsSync as H7,readFileSync as W7}from"fs";import{join as V7}from"path";function J7($,K){let Q=V7($,"state",`counter-evidence-${K}.json`);if(!H7(Q))return null;try{let X=W7(Q,"utf-8"),Z=JSON.parse(X);if(typeof Z.iteration!=="number")return null;let z=Array.isArray(Z.evidence)?Z.evidence:[],U=[];for(let W of z){if(typeof W!=="object"||W===null)continue;let V=W;if(typeof V.findingId!=="string")continue;if(typeof V.claim!=="string")continue;let q=V.proofType;if(typeof q!=="string"||!q7.has(q))continue;let J=q,Y=Array.isArray(V.artifacts)?V.artifacts:[];U.push({findingId:V.findingId,claim:V.claim,proofType:J,artifacts:Y.filter((G)=>typeof G==="string")})}return{iteration:Z.iteration,evidence:U}}catch{return null}}async function G7($,K,Q,X={}){let Z=X.judges??R0,z=new Set,U=new Set,W={},V=new Map;for(let q of K.evidence)V.set(q.findingId,q);for(let q of $){let J=K$(q),Y=V.get(J);if(!Y){U.add(J);continue}let G=await Promise.all(Z.map((M)=>Q({finding:q,evidence:Y,judge:M})));if(W[J]=G,G.filter((M)=>M.verdict==="APPROVE_OVERRIDE").length>=2)z.add(J);else U.add(J)}return{approvedFindingIds:z,rejectedFindingIds:U,votes:W}}function K$($){let K=$.raw.slice(0,80).replace(/\s+/g," ").trim();return`${$.reviewer}::${K}`}async function B7($,K,Q,X,Z={}){let z={episodeBridge:Z.episodeBridge===void 0?null:Z.episodeBridge};for(let U of X){let W=K$(U);if(Q.approvedFindingIds.has(W))await M1($,{iteration:K,trigger:"override_approved",rootCause:`[${U.severity}] ${U.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:U.reviewId,file:U.file??void 0,line:U.line??void 0,severity:U.severity,reviewer:U.reviewer}},z);else if(Q.rejectedFindingIds.has(W))await M1($,{iteration:K,trigger:"override_rejected",rootCause:`[${U.severity}] ${U.description}`,fix:"override council rejected -- dev agent must fix the finding",preventInFuture:"address this finding in the next iteration",evidence:{findingId:W,reviewId:U.reviewId,file:U.file??void 0,line:U.line??void 0,severity:U.severity,reviewer:U.reviewer}},z)}}var q7,R0;var F0=R(()=>{C1();q7=new Set(["file-exists","test-passes","grep-miss","reviewer-misread","duplicate-code-path","out-of-scope"]);R0=["judge-primary","judge-secondary","judge-tertiary"]});var C0={};y(C0,{writeEscalationHandoff:()=>k7,renderHandoff:()=>S0,readLatestHandoff:()=>x7});import{existsSync as M7,mkdirSync as Y7,readdirSync as O7,readFileSync as T7,renameSync as A7,writeFileSync as _7}from"fs";import{dirname as w7,join as h1}from"path";function I7(){return new Date().toISOString()}function j7($){let K=$.file?` (${$.file}${$.line!==null?":"+$.line:""})`:"";return` - [${$.severity}] ${$.description}${K} -- ${$.reviewer}`}function P7($){let K=$.evidence,Q=K.file?` ${K.file}${K.line!==void 0?":"+K.line:""}`:"";return` - **${$.trigger}** (iter ${$.iteration})${Q}: ${$.rootCause}`}function S0($,K,Q){let X=[];if(X.push(`# Loki escalation handoff -- ${I7()}`),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(j7(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(P7(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(`
586
- `)}function L7($,K){Y7(w7($),{recursive:!0});let Q=`${$}.tmp.${process.pid}.${++N0}`;_7(Q,K),A7(Q,$)}function k7($,K,Q={}){let X=Q.findings??i1($,K.iteration).findings,Z=Q.learnings??$$($).learnings,z=S0(K,X,Z),U=(Q.now?.()??new Date).toISOString().replace(/[-:.]/g,""),W=h1($,"escalations"),V=++N0,q=h1(W,`handoff-${U}-${process.pid}-${V}-${K.gateName}.md`);return L7(q,z),{path:q,bytes:z.length}}function x7($){let K=h1($,"escalations");if(!M7(K))return null;let Q;try{Q=O7(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=h1(K,X);try{return{path:Z,body:T7(Z,"utf-8")}}catch{return null}}var N0=0;var h0=R(()=>{N1();C1()});var D0={};y(D0,{runInternalPhase1Hooks:()=>C7,_resolveForTests:()=>N7,_internalPhase1HooksHelp:()=>y7});import{existsSync as R7,mkdirSync as E7,readdirSync as F7,statSync as S7}from"fs";import{join as Y1,resolve as N7}from"path";async function C7($){let[K,...Q]=$;switch(K){case void 0:case"help":case"--help":case"-h":return process.stdout.write(Q$),K===void 0?1:0;case"reflect":return h7(Q);case"override":return D7(Q);case"handoff":return b7(Q);default:return process.stderr.write(`Unknown subcommand: ${K}
587
- `),process.stderr.write(Q$),2}}async function h7($){let K=X$($[0]);if(K===null)return process.stderr.write(`reflect: missing or invalid <iter>
588
- `),2;let Q=x();try{let Z=(await Promise.resolve().then(() => (N1(),e1))).loadPreviousFindings(Q,K);if(Z.findings.length===0)return process.stdout.write(`reflect: no findings for iter ${K} (nothing to do)
589
- `),0;let z=Y1(Q,"state");E7(z,{recursive:!0}),G1(Y1(z,`findings-${K}.json`),{review_id:Z.reviewId,iteration:K,findings:Z.findings});let U=await Promise.resolve().then(() => (C1(),x0)),W=0;if(process.env.LOKI_AUTO_LEARNINGS!=="0"){for(let V of Z.findings)if(V.severity==="Critical"||V.severity==="High")await U.appendFromGateFailure(Q,K,V,{episodeBridge:null}),W+=1}return process.stdout.write(`reflect: persisted ${Z.findings.length} findings + ${W} learnings (iter ${K})
597
+ `,{env:Z,timeoutMs:15000});if(U.exitCode===127)return{stored:!1,reason:"python3 not found"};let W=U.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:U.stderr.trim()||"unknown"}}var d0=E(()=>{G1();m()});var s0={};g(s0,{loadLearnings:()=>W$,appendLearning:()=>T1,appendFromGateFailure:()=>p7});import{existsSync as y7,readFileSync as g7}from"fs";import{join as o0}from"path";import{createHash as m7}from"crypto";function n0($){return o0($,v7)}function f7($){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 a0($){if(!y7($))return{version:1,learnings:[]};try{let K=g7($,"utf-8"),Q=JSON.parse(K);if(Q.version===1&&Array.isArray(Q.learnings))return{version:1,learnings:Q.learnings.filter(f7)}}catch{}return{version:1,learnings:[]}}function u7($,K){return m7("sha256").update(`${$}\x00${K}`).digest("hex").slice(0,16)}async function T1($,K,Q={}){let X=u7(K.trigger,K.rootCause),Z=new Date().toISOString(),z={id:X,timestamp:Z,...K},U=n0($);if(await V0(U,()=>{let V=a0(U),q=V.learnings.findIndex((J)=>J.id===X);if(q>=0){let J=V.learnings[q];V.learnings[q]={...J,timestamp:Z,iteration:z.iteration}}else V.learnings.push(z);Y1(U,V)}),Q.episodeBridge!==null&&(Q.episodeBridge!==void 0||process.env.LOKI_AUTO_LEARNINGS_EPISODE==="1")){let V=Q.episodeBridge??l0,q=Q.bridgeFailureLog??c7;try{let J=await V($,{taskId:`learning-${X}`,outcome:"failure",phase:"VERIFY",goal:`${K.trigger}: ${K.rootCause}`});if(J&&!J.stored){if(!new Set(["memory dir not initialized","stub"]).has(J.reason))q(`episode_bridge skipped: ${J.reason}`)}}catch(J){q(`episode_bridge threw: ${J.message}`)}}return z}function c7($){process.stderr.write(`[learnings_writer] ${$}
598
+ `)}async function p7($,K,Q,X={}){let Z=`[${Q.severity}] ${Q.description}`;return T1($,{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 W$($){return a0(n0($))}var v7;var D1=E(()=>{E1();d0();v7=o0("state","relevant-learnings.json")});var t0={};g(t0,{runOverrideCouncil:()=>s7,recordOverrideOutcome:()=>r7,loadCounterEvidence:()=>a7,canonicalFindingId:()=>V$,DEFAULT_OVERRIDE_JUDGES:()=>r0});import{existsSync as l7,readFileSync as d7}from"fs";import{join as o7}from"path";function a7($,K){let Q=o7($,"state",`counter-evidence-${K}.json`);if(!l7(Q))return null;try{let X=d7(Q,"utf-8"),Z=JSON.parse(X);if(typeof Z.iteration!=="number")return null;let z=Array.isArray(Z.evidence)?Z.evidence:[],U=[];for(let W of z){if(typeof W!=="object"||W===null)continue;let V=W;if(typeof V.findingId!=="string")continue;if(typeof V.claim!=="string")continue;let q=V.proofType;if(typeof q!=="string"||!n7.has(q))continue;let J=q,Y=Array.isArray(V.artifacts)?V.artifacts:[];U.push({findingId:V.findingId,claim:V.claim,proofType:J,artifacts:Y.filter((B)=>typeof B==="string")})}return{iteration:Z.iteration,evidence:U}}catch{return null}}async function s7($,K,Q,X={}){let Z=X.judges??r0,z=new Set,U=new Set,W={},V=new Map;for(let q of K.evidence)V.set(q.findingId,q);for(let q of $){let J=V$(q),Y=V.get(J);if(!Y){U.add(J);continue}let B=await Promise.all(Z.map((M)=>Q({finding:q,evidence:Y,judge:M})));if(W[J]=B,B.filter((M)=>M.verdict==="APPROVE_OVERRIDE").length>=2)z.add(J);else U.add(J)}return{approvedFindingIds:z,rejectedFindingIds:U,votes:W}}function V$($){let K=$.raw.slice(0,80).replace(/\s+/g," ").trim();return`${$.reviewer}::${K}`}async function r7($,K,Q,X,Z={}){let z={episodeBridge:Z.episodeBridge===void 0?null:Z.episodeBridge};for(let U of X){let W=V$(U);if(Q.approvedFindingIds.has(W))await T1($,{iteration:K,trigger:"override_approved",rootCause:`[${U.severity}] ${U.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:U.reviewId,file:U.file??void 0,line:U.line??void 0,severity:U.severity,reviewer:U.reviewer}},z);else if(Q.rejectedFindingIds.has(W))await T1($,{iteration:K,trigger:"override_rejected",rootCause:`[${U.severity}] ${U.description}`,fix:"override council rejected -- dev agent must fix the finding",preventInFuture:"address this finding in the next iteration",evidence:{findingId:W,reviewId:U.reviewId,file:U.file??void 0,line:U.line??void 0,severity:U.severity,reviewer:U.reviewer}},z)}}var n7,r0;var i0=E(()=>{D1();n7=new Set(["file-exists","test-passes","grep-miss","reviewer-misread","duplicate-code-path","out-of-scope"]);r0=["judge-primary","judge-secondary","judge-tertiary"]});var KK={};g(KK,{writeEscalationHandoff:()=>W8,renderHandoff:()=>e0,readLatestHandoff:()=>V8});import{existsSync as t7,mkdirSync as i7,readdirSync as e7,readFileSync as $8,renameSync as K8,writeFileSync as Q8}from"fs";import{dirname as X8,join as b1}from"path";function Z8(){return new Date().toISOString()}function z8($){let K=$.file?` (${$.file}${$.line!==null?":"+$.line:""})`:"";return` - [${$.severity}] ${$.description}${K} -- ${$.reviewer}`}function U8($){let K=$.evidence,Q=K.file?` ${K.file}${K.line!==void 0?":"+K.line:""}`:"";return` - **${$.trigger}** (iter ${$.iteration})${Q}: ${$.rootCause}`}function e0($,K,Q){let X=[];if(X.push(`# Loki escalation handoff -- ${Z8()}`),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(z8(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(U8(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(`
599
+ `)}function H8($,K){i7(X8($),{recursive:!0});let Q=`${$}.tmp.${process.pid}.${++$K}`;Q8(Q,K),K8(Q,$)}function W8($,K,Q={}){let X=Q.findings??U$($,K.iteration).findings,Z=Q.learnings??W$($).learnings,z=e0(K,X,Z),U=(Q.now?.()??new Date).toISOString().replace(/[-:.]/g,""),W=b1($,"escalations"),V=++$K,q=b1(W,`handoff-${U}-${process.pid}-${V}-${K.gateName}.md`);return H8(q,z),{path:q,bytes:z.length}}function V8($){let K=b1($,"escalations");if(!t7(K))return null;let Q;try{Q=e7(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:$8(Z,"utf-8")}}catch{return null}}var $K=0;var QK=E(()=>{h1();D1()});var XK={};g(XK,{runInternalPhase1Hooks:()=>Y8,_resolveForTests:()=>M8,_internalPhase1HooksHelp:()=>_8});import{existsSync as q8,mkdirSync as J8,readdirSync as G8,statSync as B8}from"fs";import{join as A1,resolve as M8}from"path";async function Y8($){let[K,...Q]=$;switch(K){case void 0:case"help":case"--help":case"-h":return process.stdout.write(q$),K===void 0?1:0;case"reflect":return O8(Q);case"override":return T8(Q);case"handoff":return A8(Q);default:return process.stderr.write(`Unknown subcommand: ${K}
600
+ `),process.stderr.write(q$),2}}async function O8($){let K=J$($[0]);if(K===null)return process.stderr.write(`reflect: missing or invalid <iter>
601
+ `),2;let Q=L();try{let Z=(await Promise.resolve().then(() => (h1(),H$))).loadPreviousFindings(Q,K);if(Z.findings.length===0)return process.stdout.write(`reflect: no findings for iter ${K} (nothing to do)
602
+ `),0;let z=A1(Q,"state");J8(z,{recursive:!0}),Y1(A1(z,`findings-${K}.json`),{review_id:Z.reviewId,iteration:K,findings:Z.findings});let U=await Promise.resolve().then(() => (D1(),s0)),W=0;if(process.env.LOKI_AUTO_LEARNINGS!=="0"){for(let V of Z.findings)if(V.severity==="Critical"||V.severity==="High")await U.appendFromGateFailure(Q,K,V,{episodeBridge:null}),W+=1}return process.stdout.write(`reflect: persisted ${Z.findings.length} findings + ${W} learnings (iter ${K})
590
603
  `),0}catch(X){return process.stderr.write(`reflect: ${X.message}
591
- `),1}}async function D7($){let K=X$($[0]);if(K===null)return process.stderr.write(`override: missing or invalid <iter>
592
- `),2;let Q=x();try{let X=await Promise.resolve().then(() => (F0(),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)
593
- `),0;let U=(await Promise.resolve().then(() => (N1(),e1))).loadPreviousFindings(Q,K),W=U.findings.filter((A)=>A.severity==="Critical"||A.severity==="High");if(W.length===0)return process.stdout.write(`override: no blocking findings for iter ${K} (skip)
594
- `),0;let V=new Set(["duplicate-code-path","file-exists","test-passes","grep-miss","out-of-scope"]),q=async(A)=>{let E=V.has(A.evidence.proofType);return{judge:A.judge,verdict:E?"APPROVE_OVERRIDE":"REJECT_OVERRIDE",reasoning:E?`[stub] proofType=${A.evidence.proofType} trusted`:`[stub] proofType=${A.evidence.proofType} requires manual review`}},J=await X.runOverrideCouncil(W,Z,q);await X.recordOverrideOutcome(Q,K,J,W);let Y=Y1(Q,"quality","reviews");if(R7(Y))try{let A=F7(Y).filter((j)=>j.startsWith("review-")).sort(),E=A[A.length-1];if(E&&S7(Y1(Y,E)).isDirectory())G1(Y1(Y,E,`override-${K}.json`),{review_id:U.reviewId,iteration:K,approved_finding_ids:Array.from(J.approvedFindingIds),rejected_finding_ids:Array.from(J.rejectedFindingIds),votes:J.votes})}catch{}let G=J.approvedFindingIds.size,B=J.rejectedFindingIds.size;if(B===0&&G>0)process.stdout.write(`override: LIFTED -- ${G} approved, ${B} rejected
595
- `);else process.stdout.write(`override: BLOCKED -- ${G} approved, ${B} rejected
604
+ `),1}}async function T8($){let K=J$($[0]);if(K===null)return process.stderr.write(`override: missing or invalid <iter>
605
+ `),2;let Q=L();try{let X=await Promise.resolve().then(() => (i0(),t0)),Z=X.loadCounterEvidence(Q,K);if(Z===null||Z.evidence.length===0)return process.stdout.write(`override: no counter-evidence for iter ${K} (skip)
606
+ `),0;let U=(await Promise.resolve().then(() => (h1(),H$))).loadPreviousFindings(Q,K),W=U.findings.filter((T)=>T.severity==="Critical"||T.severity==="High");if(W.length===0)return process.stdout.write(`override: no blocking findings for iter ${K} (skip)
607
+ `),0;let V=new Set(["duplicate-code-path","file-exists","test-passes","grep-miss","out-of-scope"]),q=async(T)=>{let F=V.has(T.evidence.proofType);return{judge:T.judge,verdict:F?"APPROVE_OVERRIDE":"REJECT_OVERRIDE",reasoning:F?`[stub] proofType=${T.evidence.proofType} trusted`:`[stub] proofType=${T.evidence.proofType} requires manual review`}},J=await X.runOverrideCouncil(W,Z,q);await X.recordOverrideOutcome(Q,K,J,W);let Y=A1(Q,"quality","reviews");if(q8(Y))try{let T=G8(Y).filter((j)=>j.startsWith("review-")).sort(),F=T[T.length-1];if(F&&B8(A1(Y,F)).isDirectory())Y1(A1(Y,F,`override-${K}.json`),{review_id:U.reviewId,iteration:K,approved_finding_ids:Array.from(J.approvedFindingIds),rejected_finding_ids:Array.from(J.rejectedFindingIds),votes:J.votes})}catch{}let B=J.approvedFindingIds.size,G=J.rejectedFindingIds.size;if(G===0&&B>0)process.stdout.write(`override: LIFTED -- ${B} approved, ${G} rejected
608
+ `);else process.stdout.write(`override: BLOCKED -- ${B} approved, ${G} rejected
596
609
  `);return 0}catch(X){return process.stderr.write(`override: ${X.message}
597
- `),1}}async function b7($){let K=$[0],Q=Number.parseInt($[1]??"0",10),X=X$($[2]);if(!K||!Number.isFinite(Q)||X===null)return process.stderr.write(`handoff: usage: handoff <gate> <consecutive-failures> <iter>
598
- `),2;let Z=x();try{let U=(await Promise.resolve().then(() => (h0(),C0))).writeEscalationHandoff(Z,{gateName:K,iteration:X,consecutiveFailures:Q,detail:`${K} hit PAUSE_LIMIT (${Q} consecutive failures)`});return process.stdout.write(`handoff: wrote ${U.path} (${U.bytes}B)
610
+ `),1}}async function A8($){let K=$[0],Q=Number.parseInt($[1]??"0",10),X=J$($[2]);if(!K||!Number.isFinite(Q)||X===null)return process.stderr.write(`handoff: usage: handoff <gate> <consecutive-failures> <iter>
611
+ `),2;let Z=L();try{let U=(await Promise.resolve().then(() => (QK(),KK))).writeEscalationHandoff(Z,{gateName:K,iteration:X,consecutiveFailures:Q,detail:`${K} hit PAUSE_LIMIT (${Q} consecutive failures)`});return process.stdout.write(`handoff: wrote ${U.path} (${U.bytes}B)
599
612
  `),0}catch(z){return process.stderr.write(`handoff: ${z.message}
600
- `),1}}function X$($){if($===void 0)return null;let K=Number.parseInt($,10);return Number.isFinite(K)&&K>=0?K:null}var Q$=`loki internal phase1-hooks <subcommand>
613
+ `),1}}function J$($){if($===void 0)return null;let K=Number.parseInt($,10);return Number.isFinite(K)&&K>=0?K:null}var q$=`loki internal phase1-hooks <subcommand>
601
614
 
602
615
  Subcommands:
603
616
  reflect <iter> Persist structured findings + auto-learnings.
@@ -606,24 +619,24 @@ Subcommands:
606
619
 
607
620
  This command is invoked by autonomy/run.sh between iterations. Users
608
621
  should not run it directly -- run \`loki start\` instead.
609
- `,y7;var b0=R(()=>{g();x1();y7=Q$});m1();function W$(){return process.stdout.write(`Loki Mode v${T1()}
610
- `),0}d();p();g();import{readFileSync as t0,existsSync as i0}from"fs";import{resolve as e0}from"path";var $K=["claude","codex","cline","aider"];function q$(){let $=e0(x(),"state","provider");if(!i0($))return"";try{return t0($,"utf-8").trim()}catch{return""}}function KK($,K){return $||K||process.env.LOKI_PROVIDER||"claude"}function QK($){let K=q$(),Q=KK($,K);switch(process.stdout.write(`${N}Current Provider${H}
622
+ `,_8;var ZK=E(()=>{m();E1();_8=q$});f1();function O$(){return process.stdout.write(`Loki Mode v${w1()}
623
+ `),0}n();l();m();import{readFileSync as wK,existsSync as IK}from"fs";import{resolve as jK}from"path";var PK=["claude","codex","cline","aider"];function A$(){let $=jK(L(),"state","provider");if(!IK($))return"";try{return wK($,"utf-8").trim()}catch{return""}}function LK($,K){return $||K||process.env.LOKI_PROVIDER||"claude"}function kK($){let K=A$(),Q=LK($,K);switch(process.stdout.write(`${N}Current Provider${H}
611
624
  `),process.stdout.write(`
612
625
  `),process.stdout.write(`${_}Provider:${H} ${Q}
613
626
  `),Q){case"claude":process.stdout.write(`${D}Status:${H} Full features (subagents, parallel, MCP)
614
627
  `);break;case"cline":process.stdout.write(`${D}Status:${H} Near-full mode (subagents, MCP, 12+ providers)
615
- `);break;case"codex":case"aider":process.stdout.write(`${L}Status:${H} Degraded mode (sequential only)
628
+ `);break;case"codex":case"aider":process.stdout.write(`${x}Status:${H} Degraded mode (sequential only)
616
629
  `);break;default:break}if(K)process.stdout.write(`${C}(saved in .loki/state/provider)${H}
617
630
  `);else process.stdout.write(`${C}(default - not explicitly set)${H}
618
631
  `);return process.stdout.write(`
619
632
  `),process.stdout.write(`Switch provider: ${_}loki provider set <name>${H}
620
633
  `),process.stdout.write(`Available: ${_}loki provider list${H}
621
- `),0}async function XK(){let K=q$()||process.env.LOKI_PROVIDER||"claude";process.stdout.write(`${N}Available Providers${H}
634
+ `),0}async function xK(){let K=A$()||process.env.LOKI_PROVIDER||"claude";process.stdout.write(`${N}Available Providers${H}
622
635
  `),process.stdout.write(`
623
- `);let Q=await Promise.all($K.map(async(z)=>[z,await m(z)!==null])),X=new Map;for(let[z,U]of Q)X.set(z,U?`${D}installed${H}`:`${T}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[z,U]of Z){let W=K===z?` ${_}(current)${H}`:"";process.stdout.write(` ${U} ${X.get(z)}${W}
636
+ `);let Q=await Promise.all(PK.map(async(z)=>[z,await v(z)!==null])),X=new Map;for(let[z,U]of Q)X.set(z,U?`${D}installed${H}`:`${A}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[z,U]of Z){let W=K===z?` ${_}(current)${H}`:"";process.stdout.write(` ${U} ${X.get(z)}${W}
624
637
  `)}return process.stdout.write(`
625
638
  `),process.stdout.write(`Set provider: ${_}loki provider set <name>${H}
626
- `),0}function ZK(){return process.stdout.write(`${N}Loki Mode Provider Management${H}
639
+ `),0}function RK(){return process.stdout.write(`${N}Loki Mode Provider Management${H}
627
640
  `),process.stdout.write(`
628
641
  `),process.stdout.write(`Usage: loki provider <command>
629
642
  `),process.stdout.write(`
@@ -641,17 +654,17 @@ should not run it directly -- run \`loki start\` instead.
641
654
  `),process.stdout.write(` loki provider list
642
655
  `),process.stdout.write(` loki provider info codex
643
656
  `),process.stdout.write(` loki provider models
644
- `),0}async function J$($){let K=$[0]??"show",Q=$.slice(1);switch(K){case"show":case"current":return QK(Q[0]);case"list":return XK();case"set":case"info":case"models":return zK(["provider",K,...Q]);default:return ZK()}}async function zK($){let{run:K}=await Promise.resolve().then(() => (d(),V$)),{resolve:Q}=await import("path"),{REPO_ROOT:X}=await Promise.resolve().then(() => (g(),H$)),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}p();g();V1();import{existsSync as G$,readFileSync as HK}from"fs";import{resolve as X1}from"path";import{mkdir as WK}from"fs/promises";var q1=X1(g1(),"learnings");function f1($){if(!G$($))return 0;try{let K=HK($,"utf-8"),Q=0;for(let X of K.split(`
645
- `))if(X.includes('"description"'))Q++;return Q}catch{return 0}}async function VK(){await WK(q1,{recursive:!0});let $=f1(X1(q1,"patterns.jsonl")),K=f1(X1(q1,"mistakes.jsonl")),Q=f1(X1(q1,"successes.jsonl"));return process.stdout.write(`${N}Cross-Project Learnings${H}
657
+ `),0}async function _$($){let K=$[0]??"show",Q=$.slice(1);switch(K){case"show":case"current":return kK(Q[0]);case"list":return xK();case"set":case"info":case"models":return FK(["provider",K,...Q]);default:return RK()}}async function FK($){let{run:K}=await Promise.resolve().then(() => (n(),T$)),{resolve:Q}=await import("path"),{REPO_ROOT:X}=await Promise.resolve().then(() => (m(),Y$)),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();m();G1();import{existsSync as w$,readFileSync as SK}from"fs";import{resolve as z1}from"path";import{mkdir as NK}from"fs/promises";var B1=z1(v1(),"learnings");function c1($){if(!w$($))return 0;try{let K=SK($,"utf-8"),Q=0;for(let X of K.split(`
658
+ `))if(X.includes('"description"'))Q++;return Q}catch{return 0}}async function CK(){await NK(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(`${N}Cross-Project Learnings${H}
646
659
  `),process.stdout.write(`
647
660
  `),process.stdout.write(` Patterns: ${D}${$}${H}
648
- `),process.stdout.write(` Mistakes: ${L}${K}${H}
661
+ `),process.stdout.write(` Mistakes: ${x}${K}${H}
649
662
  `),process.stdout.write(` Successes: ${_}${Q}${H}
650
663
  `),process.stdout.write(`
651
- `),process.stdout.write(`Location: ${q1}
664
+ `),process.stdout.write(`Location: ${B1}
652
665
  `),process.stdout.write(`
653
666
  `),process.stdout.write(`Use 'loki memory show <type>' to view entries
654
- `),0}async function qK($){if($){let X=`
667
+ `),0}async function hK($){if($){let X=`
655
668
  try:
656
669
  from memory.layers import IndexLayer
657
670
  layer = IndexLayer('.loki/memory')
@@ -661,9 +674,9 @@ except ImportError:
661
674
  print('Error: memory.layers module not found')
662
675
  except Exception as e:
663
676
  print(f'Error: {e}')
664
- `.trim(),Z=await t(X,{cwd:c});return process.stdout.write(Z.stdout),0}let K=X1(x(),"memory","index.json");if(!G$(K))return process.stdout.write(`No index found
665
- `),0;let Q=await t(`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
666
- `),0;return process.stdout.write(Q.stdout),0}async function B$($){switch($[0]??"list"){case"list":case"ls":return VK();case"index":return qK($[1]==="rebuild");default:{let Q=X1(c,"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 y0=`Loki Mode (TypeScript port, Phase 2 of bash->Bun migration)
677
+ `.trim(),Z=await e(X,{cwd:p});return process.stdout.write(Z.stdout),0}let K=z1(L(),"memory","index.json");if(!w$(K))return process.stdout.write(`No index found
678
+ `),0;let Q=await e(`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
679
+ `),0;return process.stdout.write(Q.stdout),0}async function I$($){switch($[0]??"list"){case"list":case"ls":return CK();case"index":return hK($[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 zK=`Loki Mode (TypeScript port, Phase 2 of bash->Bun migration)
667
680
 
668
681
  Usage: loki <command> [args...]
669
682
 
@@ -685,12 +698,12 @@ Phase 2 ported (Bun-native, fast):
685
698
 
686
699
  All other commands fall through to the bash CLI (autonomy/loki).
687
700
  Set LOKI_LEGACY_BASH=1 to force the bash CLI for every command.
688
- `;function g7(){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.
689
- `)}async function m7($){g7();let K=$[0],Q=$.slice(1);switch(K){case void 0:case"help":case"--help":case"-h":return process.stdout.write(y0),0;case"version":case"--version":case"-v":return W$();case"provider":return J$(Q);case"memory":return B$(Q);case"status":{let{runStatus:X}=await Promise.resolve().then(() => (I$(),w$));return X(Q)}case"stats":{let{runStats:X}=await Promise.resolve().then(() => (x$(),k$));return X(Q)}case"doctor":{let{runDoctor:X}=await Promise.resolve().then(() => (y$(),b$));return X(Q)}case"kpis":{let{runKpis:X}=await Promise.resolve().then(() => (r$(),a$));return X(Q)}case"rollback":{let{runRollback:X}=await Promise.resolve().then(() => (U0(),z0));return X(Q)}case"proof":{let{runProof:X}=await Promise.resolve().then(() => (q0(),V0));return X(Q)}case"wiki":{let{runWiki:X}=await Promise.resolve().then(() => (Y0(),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(`
701
+ `;function w8(){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.
702
+ `)}async function I8($){w8();let K=$[0],Q=$.slice(1);switch(K){case void 0:case"help":case"--help":case"-h":return process.stdout.write(zK),0;case"version":case"--version":case"-v":return O$();case"provider":return _$(Q);case"memory":return I$(Q);case"status":{let{runStatus:X}=await Promise.resolve().then(() => (E$(),F$));return X(Q)}case"stats":{let{runStats:X}=await Promise.resolve().then(() => (D$(),h$));return X(Q)}case"doctor":{let{runDoctor:X}=await Promise.resolve().then(() => (l$(),p$));return X(Q)}case"kpis":{let{runKpis:X}=await Promise.resolve().then(() => (X0(),Q0));return X(Q)}case"rollback":{let{runRollback:X}=await Promise.resolve().then(() => (E0(),F0));return X(Q)}case"proof":{let{runProof:X}=await Promise.resolve().then(() => (h0(),C0));return X(Q)}case"wiki":{let{runWiki:X}=await Promise.resolve().then(() => (m0(),g0));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(`
690
703
  `);return process.stdout.write(`${z}
691
- `),0}if(X==="phase1-hooks"){let{runInternalPhase1Hooks:z}=await Promise.resolve().then(() => (b0(),D0));return z(Q.slice(1))}return process.stderr.write(`Unknown internal subcommand: ${X}
704
+ `),0}if(X==="phase1-hooks"){let{runInternalPhase1Hooks:z}=await Promise.resolve().then(() => (ZK(),XK));return z(Q.slice(1))}return process.stderr.write(`Unknown internal subcommand: ${X}
692
705
  `),process.stderr.write(`Run 'loki internal --help' for the supported list.
693
706
  `),2}default:return process.stderr.write(`Unknown command: ${K}
694
- `),process.stderr.write(y0),2}}process.on("SIGINT",()=>process.exit(130));process.on("SIGTERM",()=>process.exit(143));var v7=await m7(Bun.argv.slice(2));process.exit(v7);
707
+ `),process.stderr.write(zK),2}}process.on("SIGINT",()=>process.exit(130));process.on("SIGTERM",()=>process.exit(143));var j8=await I8(Bun.argv.slice(2));process.exit(j8);
695
708
 
696
- //# debugId=8FA32380351CFCC964756E2164756E21
709
+ //# debugId=933701CC08C65BD764756E2164756E21