loki-mode 7.8.3 → 7.9.1

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