loki-mode 7.19.3 → 7.19.4

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