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