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