loki-mode 7.124.0 → 7.126.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.
@@ -0,0 +1,70 @@
1
+ # Loki Cockpit (rec #6) - build spec
2
+
3
+ Status: IN BUILD (v7.126.0 target). Design approved via mockup
4
+ (scratchpad/loki-cockpit.html). Grounded in real engine state + Autonomi identity.
5
+
6
+ ## Product model (locked with founder)
7
+
8
+ Three surfaces, each for a different moment; the cockpit ADDS a choice, removes nothing:
9
+ - `loki start` - launch. Now DETACHES to background by default on an interactive
10
+ TTY, after a rich handoff (spec/path/tier/budget/logs/dashboard URL + actions:
11
+ view/watch/dashboard/detach/stop). Auto-picks "Both" after an 8s timeout.
12
+ CI / --bg / --yes / non-interactive skip the handoff -> exactly today's behavior.
13
+ - `loki cockpit` - NEW opt-in observability surface. Renders the approved cockpit
14
+ UI live from `.loki/` state, multi-repo. Two render paths:
15
+ 1. In-terminal 4K image (Kitty / iTerm2 / WezTerm / Ghostty graphics protocol)
16
+ - pixel-exact, the approved HTML/SVG rasterized in-pane.
17
+ 2. Browser-dashboard fallback (default everywhere else) - opens the existing
18
+ web dashboard (redesigned to the same identity).
19
+ (`loki watch` is UNCHANGED - it remains the PRD-file auto-rerun watcher.)
20
+ - `loki dashboard` - the web view (redesigned to the cockpit identity).
21
+ - `loki stop` - already exists; surfaced as an action in the handoff + cockpit.
22
+
23
+ ## Identity (from ~/git/autonomi-website, verified)
24
+
25
+ - Logo: purple squircle #553DE9 + white "A" (two strokes + Q-bezier apex) + teal
26
+ dot #1FC5A8. Always visible top-left.
27
+ - Accent #553de9 (light) / #8b7bf5 (dark). Teal #1FC5A8 secondary.
28
+ - Fonts: Fraunces (display), Inter (body), JetBrains Mono (mono). Ink #201515.
29
+ - Light-grey ground DEFAULT (#f1f2f6); dark mode optional.
30
+ - Semantic: verified #1f8a52, warning #9a6a12, failed #b23a3a.
31
+
32
+ ## Data sources (real, no new state invented)
33
+
34
+ - Multi-repo run list: `dashboard/registry.py` -> `get_fleet_runs()` /
35
+ `list_projects()` reading `~/.loki/dashboard/projects.json`.
36
+ - Per-run live state: `<target>/.loki/autonomy-state.json` (iteration, phase,
37
+ status), `.loki/council/*.json` (votes, gate/evidence blocks),
38
+ `.loki/verify/evidence.json` (verdict + gates + freshness), `.loki/events.json`.
39
+ - Budget: `.loki/metrics/` + state cost fields.
40
+
41
+ ## Render pipeline (dependency-free - the "no one has done this" bar)
42
+
43
+ No chafa / no headless Chrome hard dependency. Pipeline:
44
+ 1. Build an SVG of the cockpit from live state (exact fonts embedded, exact colors).
45
+ 2. Rasterize SVG -> PNG via a bundled pure path (resvg-js if present, else a
46
+ node canvas fallback; capability-detected).
47
+ 3. Encode PNG -> terminal via a SELF-CONTAINED encoder (Kitty graphics protocol
48
+ or iTerm2 inline-image escape, pure base64 - no external binary).
49
+ 4. Capability detection: $TERM / $TERM_PROGRAM / KITTY_WINDOW_ID / terminal
50
+ query; on unsupported terminals fall back to opening the browser dashboard.
51
+ Honest: never claim an image render happened when it fell back.
52
+
53
+ ## Stories
54
+
55
+ - S1 (start handoff + detach-default): cmd_start. Rich handoff card, 8s auto-Both,
56
+ actions, remember-per-project. Non-interactive/CI/--bg/--yes bypass. Tests.
57
+ - S2 (loki cockpit command + multi-repo model): cmd_cockpit, reads registry +
58
+ per-run state, run switcher, --once/--follow, browser fallback. Tests.
59
+ - S3 (render pipeline): SVG-from-state builder + SVG->PNG + terminal-image
60
+ encoder + capability detection + fallback. Tests (encoder byte-shape, detection).
61
+ - S4 (dashboard identity redesign): apply logo/purple/fonts/multi-repo switcher to
62
+ dashboard-ui; rebuild dist. Lightweight gate.
63
+ - S5 (docs + wiki + release): help text, README, wiki, CHANGELOG, 14 version files.
64
+
65
+ ## Constraints
66
+
67
+ - CLI-invariant: no existing command changes behavior (watch stays PRD-watcher;
68
+ start's non-interactive path byte-identical).
69
+ - Never fake-green: image path honest about fallback; every claim tested.
70
+ - Both routes where relevant; bash-route for start/cockpit/stop.
@@ -0,0 +1,53 @@
1
+ # loki start opening experience - UX / engagement / stickiness mandate
2
+
3
+ Founder mandate (2026-07-09): the moment `loki start` opens must deliver the best
4
+ UX, engagement, and stickiness in the CLI space - "nothing anyone ever attempted
5
+ with cli and terminal." This shapes S1 (start handoff) and a dedicated polish pass.
6
+
7
+ ## Principles
8
+
9
+ 1. Time-to-first-wow < 1 second. The instant the user hits enter, they see a
10
+ crafted, branded, alive moment - not a wall of logs. The Autonomi mark renders
11
+ immediately; the build identity (spec, tier, what it is about to do) reads at a
12
+ glance.
13
+ 2. Alive, not static. A subtle, tasteful motion on open (the RARV loop igniting,
14
+ a one-line "here is the plan" reveal). No gratuitous animation; one orchestrated
15
+ moment that lands.
16
+ 3. Confidence + control in the same breath. The user immediately understands: it
17
+ is running, it is safe, and here is exactly how to watch / steer / stop. The
18
+ handoff card IS the hook - it makes staying to watch feel rewarding.
19
+ 4. Stickiness = the cockpit pull. "Both" (dashboard + cockpit) is the default and
20
+ the card sells it: "watch it build, live." First run teaches `loki cockpit`;
21
+ the remembered choice makes the second run instant.
22
+ 5. Progress you feel. Show the first real signal fast (tier detected, first
23
+ iteration reasoning) so the user gets a dopamine hit of momentum, not a spinner.
24
+ 6. Honest always. Never fake progress or a wow that is not backed by real state.
25
+
26
+ ## Concrete asks (for the polish pass after slices merge)
27
+
28
+ - A crafted open banner: Autonomi logo + "Loki" wordmark (Fraunces feel in ASCII/
29
+ unicode), a one-line value framing of THIS run, then the handoff card.
30
+ - The countdown to auto-Both should feel inviting ("opening your cockpit in 8s -
31
+ press a key to choose"), not like a timeout to dread.
32
+ - The reattach hints after detach should be delightful + copy-pasteable
33
+ (`loki cockpit` front and center).
34
+ - Optional: a tiny "what Loki will do" 3-line plan preview (from detected tier +
35
+ spec) so the user sees intent before backgrounding.
36
+ - Measure: time-to-first-frame, and whether users pick Both (engagement proxy).
37
+
38
+ This is a follow-up polish story (S6) layered on S1 once the core lands. Do not
39
+ fake it; every wow is backed by a real field.
40
+
41
+ ## HARD CONSTRAINTS (founder, 2026-07-09)
42
+
43
+ - STARE-WORTHY: the open must be a VISUAL moment people stop and admire - the
44
+ quality of a crafted product launch screen, in the terminal. Type, spacing,
45
+ the Autonomi mark, colors (truecolor), and one alive beat. Not a log dump.
46
+ - ZERO NEW TOOLING / ZERO FRICTION: the user installs NOTHING extra and learns NO
47
+ new tool. No chafa, no headless Chrome as a requirement, no new binary, no
48
+ config step. It must work out of the box on `loki start`. The dependency-free
49
+ pure-bash render path (truecolor ANSI + optional in-terminal image where the
50
+ terminal already supports it, silent graceful fallback otherwise) is mandatory;
51
+ anything that would make a user run an install command is disqualified.
52
+ - IT JUST HAPPENS: the amazing open is the DEFAULT of `loki start`, not an opt-in
53
+ flag the user must discover. No extra ceremony.
@@ -2,7 +2,7 @@
2
2
 
3
3
  The flagship product of [Autonomi](https://www.autonomi.dev/). Loki Mode is a spec-driven autonomous builder with a built-in trust layer that takes any spec to a deployed product and verifies completion with evidence (quality gates plus a completion council), not just a "done" claim. Complete installation instructions for all platforms and use cases.
4
4
 
5
- **Version:** v7.124.0
5
+ **Version:** v7.126.0
6
6
 
7
7
  ---
8
8
 
@@ -396,7 +396,7 @@ provider works inside the container. Provide auth with your Anthropic API key:
396
396
  # Run Loki Mode in Docker (Claude provider, API-key auth)
397
397
  docker run --rm -e ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" \
398
398
  -v $(pwd):/workspace -w /workspace \
399
- asklokesh/loki-mode:7.124.0 start ./my-spec.md
399
+ asklokesh/loki-mode:7.126.0 start ./my-spec.md
400
400
  ```
401
401
 
402
402
  ##### docker compose + .env (no host install)
@@ -0,0 +1,16 @@
1
+ // @bun
2
+ var _=import.meta.require;function Z(D){return String(D??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function h(D,L,Q){let N=Q/512;return`<g transform="translate(${D},${L}) scale(${N})">
3
+ <rect x="0" y="0" width="512" height="512" rx="118" fill="#553de9"/>
4
+ <path d="M152 405 L242 120" stroke="#FFFEFB" stroke-width="28" stroke-linecap="round" fill="none"/>
5
+ <path d="M360 405 L270 120" stroke="#FFFEFB" stroke-width="28" stroke-linecap="round" fill="none"/>
6
+ <path d="M242 120 Q256 86 270 120" stroke="#FFFEFB" stroke-width="28" stroke-linecap="round" fill="none"/>
7
+ <circle cx="256" cy="295" r="20" fill="#1FC5A8"/>
8
+ </g>`}function b(D){switch(D){case"verified":return"#1f8a52";case"failed":return"#b23a3a";case"working":case"pending":return"#9a6a12";default:return"#6b6675"}}function u(D){switch(D){case"pass":return"#1f8a52";case"fail":return"#b23a3a";case"pending":return"#9a6a12";default:return"#6b6675"}}function p(D){switch(D){case"approve":return"#1f8a52";case"reject":return"#b23a3a";case"concern":return"#9a6a12";default:return"#6b6675"}}function F(D,L,Q,N,U="#201515"){return`<text x="${D}" y="${L}" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="12" fill="#6b6675" letter-spacing="0.5">${Z(Q.toUpperCase())}</text>
9
+ <text x="${D}" y="${L+24}" font-family="'JetBrains Mono','SF Mono',ui-monospace,monospace" font-size="20" font-weight="600" fill="${U}">${Z(N)}</text>`}function S(D){let U=D.budgetLimitUsd&&D.budgetLimitUsd>0?`$${D.budgetUsd.toFixed(2)} / $${D.budgetLimitUsd.toFixed(2)}`:`$${D.budgetUsd.toFixed(2)}`,J="";J+=h(32,32,44),J+=`<text x="92" y="54" font-family="'Fraunces','Georgia',serif" font-size="24" font-weight="600" fill="#201515">Autonomi</text>`,J+=`<text x="92" y="74" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="13" fill="#6b6675">Loki Cockpit</text>`;let X=D.freshness?`updated ${D.freshness}`:"live";J+=`<text x="868" y="54" text-anchor="end" font-family="'JetBrains Mono','SF Mono',ui-monospace,monospace" font-size="12" fill="#6b6675">${Z(X)}</text>`,J+=`<text x="868" y="74" text-anchor="end" font-family="'JetBrains Mono','SF Mono',ui-monospace,monospace" font-size="13" fill="${b(D.verdict)}" font-weight="600">${Z(D.verdict.toUpperCase())}</text>`;let $=96,M=168;J+=`<rect x="32" y="${$}" width="836" height="${M}" rx="16" fill="#ffffff" stroke="#e2e0e8"/>`,J+=`<text x="56" y="${$+34}" font-family="'Fraunces','Georgia',serif" font-size="20" font-weight="600" fill="#201515">${Z(D.run)}</text>`,J+=`<text x="56" y="${$+54}" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="13" fill="#6b6675">phase ${Z(D.phase)}</text>`;let K=$+96,T=(V)=>56+V*168;J+=F(T(0),K,"iteration",String(D.iteration)),J+=F(T(1),K,"tier",D.tier),J+=F(T(2),K,"provider",D.provider),J+=F(T(3),K,"budget",U),J+=F(T(4),K,"phase",D.phase,"#553de9");let C=$+M+40;J+=`<text x="32" y="${C}" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="13" font-weight="600" fill="#6b6675" letter-spacing="0.5">QUALITY GATES</text>`;let W=32,P=C+16,m=D.gates.length?D.gates:[{name:"no gates yet",status:"pending"}];for(let V of m){let j=Z(V.name),E=Math.max(74,14+j.length*7),A=u(V.status);if(J+=`<rect x="${W}" y="${P}" width="${E}" height="30" rx="8" fill="#ffffff" stroke="${A}"/>`,J+=`<circle cx="${W+14}" cy="${P+15}" r="4" fill="${A}"/>`,J+=`<text x="${W+24}" y="${P+19}" font-family="'JetBrains Mono','SF Mono',ui-monospace,monospace" font-size="12" fill="#201515">${j}</text>`,W+=E+10,W>778)break}let z=P+62;J+=`<text x="32" y="${z}" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="13" font-weight="600" fill="#6b6675" letter-spacing="0.5">COUNCIL</text>`;let q=32,I=z+16,x=D.council.length?D.council:[{reviewer:"pending",vote:"pending"}];for(let V of x){let j=`${Z(V.reviewer)}: ${Z(V.vote)}`,E=Math.max(90,14+j.length*7),A=p(V.vote);if(J+=`<rect x="${q}" y="${I}" width="${E}" height="30" rx="8" fill="${A}" fill-opacity="0.12" stroke="${A}"/>`,J+=`<text x="${q+12}" y="${I+19}" font-family="'JetBrains Mono','SF Mono',ui-monospace,monospace" font-size="12" fill="#201515">${j}</text>`,q+=E+10,q>768)break}let B=I+62;J+=`<text x="32" y="${B}" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="13" font-weight="600" fill="#6b6675" letter-spacing="0.5">FLEET (${D.fleet.length})</text>`;let G=B+20,O=D.fleet.slice(0,4);for(let V of O){let j=V.running?"#1f8a52":"#6b6675";J+=`<circle cx="38" cy="${G-4}" r="5" fill="${j}"/>`,J+=`<text x="52" y="${G}" font-family="'JetBrains Mono','SF Mono',ui-monospace,monospace" font-size="13" fill="#201515">${Z(V.name)}</text>`;let E=`iter ${V.iteration??0} ${Z(V.phase||V.status||"")}`;J+=`<text x="868" y="${G}" text-anchor="end" font-family="'JetBrains Mono','SF Mono',ui-monospace,monospace" font-size="12" fill="#6b6675">${E}</text>`,G+=26}if(D.fleet.length>O.length)J+=`<text x="52" y="${G}" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="12" fill="#6b6675">+ ${D.fleet.length-O.length} more</text>`;return`<svg xmlns="http://www.w3.org/2000/svg" width="900" height="560" viewBox="0 0 900 560">
10
+ <rect x="0" y="0" width="900" height="560" fill="#f1f2f6"/>
11
+ ${J}
12
+ </svg>`}var H;function y(){if(H!==void 0)return H;try{let D=globalThis.require??_;D.resolve("@resvg/resvg-js"),H=D("@resvg/resvg-js")}catch{H=null}return H}function R(D,L=900){let Q=y();if(!Q||typeof Q.Resvg!=="function")return{png:null,available:!1,reason:"raster unavailable (@resvg/resvg-js not installed)"};try{let U=new Q.Resvg(D,{fitTo:{mode:"width",value:L}}).render().asPng();return{png:Uint8Array.from(U),available:!0}}catch(N){return{png:null,available:!1,reason:`raster failed: ${N.message}`}}}function Y(D){return Buffer.from(D).toString("base64")}function v(D){let L=Y(D);return`\x1B]1337;File=${`inline=1;size=${D.length};width=auto;height=auto;preserveAspectRatio=1`}:${L}\x07`}function i(D,L=4096){let Q=Y(D);if(Q.length===0)return"\x1B_Ga=T,f=100,m=0;\x1B\\";let N=[];for(let J=0;J<Q.length;J+=L)N.push(Q.slice(J,J+L));let U="";for(let J=0;J<N.length;J++){let $=J===N.length-1?0:1,M=J===0?`a=T,f=100,m=${$}`:`m=${$}`;U+=`\x1B_G${M};${N[J]}\x1B\\`}return U}function k(D,L){return D==="kitty"?i(L):v(L)}var g=new Set(["iterm.app","wezterm","ghostty"]);function w(D=process.env){let L=(D.LOKI_COCKPIT_PROTOCOL||"").trim().toLowerCase();if(L==="iterm2"||L==="kitty"||L==="none")return L;let Q=(D.KITTY_WINDOW_ID||"").trim(),N=(D.TERM||"").trim().toLowerCase();if(Q.length>0||N==="xterm-kitty")return"kitty";let U=(D.TERM_PROGRAM||"").trim().toLowerCase();if(g.has(U))return"iterm2";return"none"}function f(D,L={}){let Q=S(D);if(L.forceText)return{kind:"fallback",protocol:"none",reason:"--no-image (text/browser fallback)",svg:Q};let N;if(L.protocol&&L.protocol!=="auto")N=L.protocol;else N=w(L.env);if(N==="none")return{kind:"fallback",protocol:N,reason:"no inline-image terminal detected",svg:Q};let U=R(Q);if(!U.available||!U.png)return{kind:"fallback",protocol:N,reason:U.reason||"rasterization unavailable",svg:Q};let J=k(N,U.png);return{kind:"image",protocol:N,data:J,svg:Q}}async function l(){let D=[];for await(let L of process.stdin)D.push(L);return Buffer.concat(D).toString("utf-8")}function n(D){let L="auto",Q=!1,N;for(let U=0;U<D.length;U++){let J=D[U];if(J==="--protocol"){let X=(D[++U]||"auto").toLowerCase();L=X==="iterm2"||X==="kitty"||X==="none"?X:"auto"}else if(J==="--no-image")Q=!0;else if(J==="--svg-out")N=D[++U]}return{protocol:L,noImage:Q,svgOut:N}}async function d(D=process.argv.slice(2)){let{protocol:L,noImage:Q,svgOut:N}=n(D),U;try{let X=await l();U=JSON.parse(X)}catch(X){return process.stderr.write(`FALLBACK could not parse cockpit state: ${X.message}
13
+ `),3}let J=f(U,{protocol:L,forceText:Q});if(N)try{let{writeFileSync:X}=await import("fs");X(N,J.svg)}catch{}if(J.kind==="image"&&J.data)return process.stdout.write(J.data),0;return process.stderr.write(`FALLBACK ${J.reason||"image unavailable"}
14
+ `),3}if(import.meta.main)d().then((D)=>process.exit(D));export{d as main};
15
+
16
+ //# debugId=3D037F5476B14F7264756E2164756E21
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- var q8=Object.defineProperty;var J8=($)=>$;function V8($,Q){this[$]=J8.bind(null,Q)}var b=($,Q)=>{for(var Z in Q)q8($,Z,{get:Q[Z],enumerable:!0,configurable:!0,set:V8.bind(Q,Z)})};var P=($,Q)=>()=>($&&(Q=$($=0)),Q);var J$=import.meta.require;var m1={};b(m1,{lokiDir:()=>j,homeLokiDir:()=>T$,findRepoRootForVersion:()=>$1,REPO_ROOT:()=>h});import{resolve as t,dirname as e$}from"path";import{fileURLToPath as W8}from"url";import{existsSync as N$}from"fs";import{homedir as H8}from"os";function G8(){let $=v1;for(let Q=0;Q<6;Q++){if(N$(t($,"VERSION"))&&N$(t($,"autonomy/run.sh")))return $;let Z=e$($);if(Z===$)break;$=Z}return t(v1,"..","..","..")}function $1($){let Q=$;for(let Z=0;Z<6;Z++){if(N$(t(Q,"VERSION"))&&N$(t(Q,"autonomy/run.sh")))return Q;let z=e$(Q);if(z===Q)break;Q=z}return t($,"..","..","..")}function j(){return process.env.LOKI_DIR??t(process.cwd(),".loki")}function T$(){return t(H8(),".loki")}var v1,h;var C=P(()=>{v1=e$(W8(import.meta.url));h=G8()});import{readFileSync as U8}from"fs";import{resolve as Y8,dirname as B8}from"path";import{fileURLToPath as M8}from"url";function S$(){if(Q$!==null)return Q$;let $="7.124.0";if(typeof $==="string"&&$.length>0)return Q$=$,Q$;try{let Q=B8(M8(import.meta.url)),Z=$1(Q);Q$=U8(Y8(Z,"VERSION"),"utf-8").trim()}catch{Q$="unknown"}return Q$}var Q$=null;var Q1=P(()=>{C()});var p1={};b(p1,{runOrThrow:()=>S8,run:()=>R,readStreamCapped:()=>c1,commandVersion:()=>C8,commandExists:()=>u,ShellError:()=>Z1,MAX_STDOUT_BYTES:()=>u1});async function c1($,Q=u1){let Z=$.getReader(),z=new TextDecoder,X="",q=0;try{while(q<Q){let{done:K,value:W}=await Z.read();if(K)break;if(!W)continue;if(q+=W.byteLength,q>Q){let V=W.byteLength-(q-Q);X+=z.decode(W.subarray(0,V),{stream:!0});break}X+=z.decode(W,{stream:!0})}X+=z.decode()}finally{try{await Z.cancel()}catch{}Z.releaseLock()}return X}async function R($,Q={}){let Z=Bun.spawn({cmd:[...$],stdout:"pipe",stderr:"pipe",env:Q.env?{...process.env,...Q.env}:process.env,cwd:Q.cwd}),z,X;if(Q.timeoutMs&&Q.timeoutMs>0)z=setTimeout(()=>{try{Z.kill("SIGTERM")}catch{}X=setTimeout(()=>{try{Z.kill("SIGKILL")}catch{}},2000)},Q.timeoutMs);try{let[q,K,W]=await Promise.all([c1(Z.stdout),new Response(Z.stderr).text(),Z.exited]);return{stdout:q,stderr:K,exitCode:W}}finally{if(z)clearTimeout(z);if(X)clearTimeout(X)}}async function S8($,Q={}){let Z=await R($,Q);if(Z.exitCode!==0)throw new Z1(`command failed (${Z.exitCode}): ${$.join(" ")}`,Z.exitCode,Z.stdout,Z.stderr);return Z}async function u($){let Q=D8($),Z=await R(["sh","-c",`command -v ${Q}`],{timeoutMs:5000});if(Z.exitCode===0)return Z.stdout.trim()||null;return null}function D8($){if(!/^[A-Za-z0-9._/-]+$/.test($))throw Error(`refused to shell-escape suspect token: ${$}`);return $}async function C8($,Q="--version"){if(!await u($))return null;let z=await R([$,Q],{timeoutMs:5000});if(z.exitCode!==0)return null;return((z.stdout||z.stderr).split(/\r?\n/)[0]?.trim()??"")||null}var u1=16777216,Z1;var o=P(()=>{Z1=class Z1 extends Error{message;exitCode;stdout;stderr;constructor($,Q,Z,z){super($);this.message=$;this.exitCode=Q;this.stdout=Z;this.stderr=z;this.name="ShellError"}}});function r($){return b8?"":$}var b8,M,S,_,tZ,L,k,y,J;var p=P(()=>{b8=(process.env.NO_COLOR??"").length>0;M=r("\x1B[0;31m"),S=r("\x1B[0;32m"),_=r("\x1B[1;33m"),tZ=r("\x1B[0;34m"),L=r("\x1B[0;36m"),k=r("\x1B[1m"),y=r("\x1B[2m"),J=r("\x1B[0m")});import{existsSync as l8}from"fs";async function Z$(){if(A$!==void 0)return A$;let $="/opt/homebrew/bin/python3.12";if(l8($))return A$=$,$;let Q=await u("python3.12");if(Q)return A$=Q,Q;let Z=await u("python3");return A$=Z,Z}async function z$($,Q={}){let Z=await Z$();if(!Z)return{stdout:"",stderr:"python3 not found",exitCode:127};return R([Z,"-c",$],Q)}var A$;var V$=P(()=>{o()});var V0={};b(V0,{runStatus:()=>U3});import{existsSync as v,readFileSync as H$,readdirSync as $0,statSync as Q0}from"fs";import{resolve as D,basename as z3}from"path";import{homedir as X3}from"os";function Z0($){let Q=Math.trunc($);if(Q>=1e6)return`${(Math.trunc(Q/1e6*10)/10).toFixed(1)}M`;if(Q>=1000)return`${(Math.trunc(Q/1000*10)/10).toFixed(1)}K`;return String(Q)}function z0($,Q,Z){if(Q===0)return null;let z=Math.trunc($*100/Q),X=Math.trunc($*C$/Q);if(X>C$)X=C$;let q=C$-X,K=S;if(z>=80)K=M;else if(z>=50)K=_;let W="=".repeat(Math.max(0,X))+" ".repeat(Math.max(0,q)),V=Z0($),H=Z0(Q);return` ${k}${Z}${J} ${K}[${W}]${J} ${z}% (${V} / ${H})`}async function q3(){if(await u("jq"))return!0;return process.stdout.write(`${M}Error: jq is required but not installed.${J}
2
+ var q8=Object.defineProperty;var J8=($)=>$;function V8($,Q){this[$]=J8.bind(null,Q)}var b=($,Q)=>{for(var Z in Q)q8($,Z,{get:Q[Z],enumerable:!0,configurable:!0,set:V8.bind(Q,Z)})};var P=($,Q)=>()=>($&&(Q=$($=0)),Q);var J$=import.meta.require;var m1={};b(m1,{lokiDir:()=>j,homeLokiDir:()=>T$,findRepoRootForVersion:()=>$1,REPO_ROOT:()=>h});import{resolve as t,dirname as e$}from"path";import{fileURLToPath as W8}from"url";import{existsSync as N$}from"fs";import{homedir as H8}from"os";function G8(){let $=v1;for(let Q=0;Q<6;Q++){if(N$(t($,"VERSION"))&&N$(t($,"autonomy/run.sh")))return $;let Z=e$($);if(Z===$)break;$=Z}return t(v1,"..","..","..")}function $1($){let Q=$;for(let Z=0;Z<6;Z++){if(N$(t(Q,"VERSION"))&&N$(t(Q,"autonomy/run.sh")))return Q;let z=e$(Q);if(z===Q)break;Q=z}return t($,"..","..","..")}function j(){return process.env.LOKI_DIR??t(process.cwd(),".loki")}function T$(){return t(H8(),".loki")}var v1,h;var C=P(()=>{v1=e$(W8(import.meta.url));h=G8()});import{readFileSync as U8}from"fs";import{resolve as Y8,dirname as B8}from"path";import{fileURLToPath as M8}from"url";function S$(){if(Q$!==null)return Q$;let $="7.126.0";if(typeof $==="string"&&$.length>0)return Q$=$,Q$;try{let Q=B8(M8(import.meta.url)),Z=$1(Q);Q$=U8(Y8(Z,"VERSION"),"utf-8").trim()}catch{Q$="unknown"}return Q$}var Q$=null;var Q1=P(()=>{C()});var p1={};b(p1,{runOrThrow:()=>S8,run:()=>R,readStreamCapped:()=>c1,commandVersion:()=>C8,commandExists:()=>u,ShellError:()=>Z1,MAX_STDOUT_BYTES:()=>u1});async function c1($,Q=u1){let Z=$.getReader(),z=new TextDecoder,X="",q=0;try{while(q<Q){let{done:K,value:W}=await Z.read();if(K)break;if(!W)continue;if(q+=W.byteLength,q>Q){let V=W.byteLength-(q-Q);X+=z.decode(W.subarray(0,V),{stream:!0});break}X+=z.decode(W,{stream:!0})}X+=z.decode()}finally{try{await Z.cancel()}catch{}Z.releaseLock()}return X}async function R($,Q={}){let Z=Bun.spawn({cmd:[...$],stdout:"pipe",stderr:"pipe",env:Q.env?{...process.env,...Q.env}:process.env,cwd:Q.cwd}),z,X;if(Q.timeoutMs&&Q.timeoutMs>0)z=setTimeout(()=>{try{Z.kill("SIGTERM")}catch{}X=setTimeout(()=>{try{Z.kill("SIGKILL")}catch{}},2000)},Q.timeoutMs);try{let[q,K,W]=await Promise.all([c1(Z.stdout),new Response(Z.stderr).text(),Z.exited]);return{stdout:q,stderr:K,exitCode:W}}finally{if(z)clearTimeout(z);if(X)clearTimeout(X)}}async function S8($,Q={}){let Z=await R($,Q);if(Z.exitCode!==0)throw new Z1(`command failed (${Z.exitCode}): ${$.join(" ")}`,Z.exitCode,Z.stdout,Z.stderr);return Z}async function u($){let Q=D8($),Z=await R(["sh","-c",`command -v ${Q}`],{timeoutMs:5000});if(Z.exitCode===0)return Z.stdout.trim()||null;return null}function D8($){if(!/^[A-Za-z0-9._/-]+$/.test($))throw Error(`refused to shell-escape suspect token: ${$}`);return $}async function C8($,Q="--version"){if(!await u($))return null;let z=await R([$,Q],{timeoutMs:5000});if(z.exitCode!==0)return null;return((z.stdout||z.stderr).split(/\r?\n/)[0]?.trim()??"")||null}var u1=16777216,Z1;var o=P(()=>{Z1=class Z1 extends Error{message;exitCode;stdout;stderr;constructor($,Q,Z,z){super($);this.message=$;this.exitCode=Q;this.stdout=Z;this.stderr=z;this.name="ShellError"}}});function r($){return b8?"":$}var b8,M,S,_,tZ,L,k,y,J;var p=P(()=>{b8=(process.env.NO_COLOR??"").length>0;M=r("\x1B[0;31m"),S=r("\x1B[0;32m"),_=r("\x1B[1;33m"),tZ=r("\x1B[0;34m"),L=r("\x1B[0;36m"),k=r("\x1B[1m"),y=r("\x1B[2m"),J=r("\x1B[0m")});import{existsSync as l8}from"fs";async function Z$(){if(A$!==void 0)return A$;let $="/opt/homebrew/bin/python3.12";if(l8($))return A$=$,$;let Q=await u("python3.12");if(Q)return A$=Q,Q;let Z=await u("python3");return A$=Z,Z}async function z$($,Q={}){let Z=await Z$();if(!Z)return{stdout:"",stderr:"python3 not found",exitCode:127};return R([Z,"-c",$],Q)}var A$;var V$=P(()=>{o()});var V0={};b(V0,{runStatus:()=>U3});import{existsSync as v,readFileSync as H$,readdirSync as $0,statSync as Q0}from"fs";import{resolve as D,basename as z3}from"path";import{homedir as X3}from"os";function Z0($){let Q=Math.trunc($);if(Q>=1e6)return`${(Math.trunc(Q/1e6*10)/10).toFixed(1)}M`;if(Q>=1000)return`${(Math.trunc(Q/1000*10)/10).toFixed(1)}K`;return String(Q)}function z0($,Q,Z){if(Q===0)return null;let z=Math.trunc($*100/Q),X=Math.trunc($*C$/Q);if(X>C$)X=C$;let q=C$-X,K=S;if(z>=80)K=M;else if(z>=50)K=_;let W="=".repeat(Math.max(0,X))+" ".repeat(Math.max(0,q)),V=Z0($),H=Z0(Q);return` ${k}${Z}${J} ${K}[${W}]${J} ${z}% (${V} / ${H})`}async function q3(){if(await u("jq"))return!0;return process.stdout.write(`${M}Error: jq is required but not installed.${J}
3
3
  `),process.stdout.write(`Install with:
4
4
  `),process.stdout.write(` brew install jq (macOS)
5
5
  `),process.stdout.write(` apt install jq (Debian/Ubuntu)
@@ -814,4 +814,4 @@ Set LOKI_LEGACY_BASH=1 to force the bash CLI for every command.
814
814
  `),2}default:return process.stderr.write(`Unknown command: ${Q}
815
815
  `),process.stderr.write(K8),2}}e1();process.on("SIGINT",()=>process.exit(130));process.on("SIGTERM",()=>process.exit(143));var SZ=await NZ(Bun.argv.slice(2));process.exit(SZ);
816
816
 
817
- //# debugId=05FF05D86BAA54F864756E2164756E21
817
+ //# debugId=36875272847D5AB164756E2164756E21
package/mcp/__init__.py CHANGED
@@ -57,4 +57,4 @@ try:
57
57
  except ImportError:
58
58
  __all__ = ['mcp']
59
59
 
60
- __version__ = '7.124.0'
60
+ __version__ = '7.126.0'
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "loki-mode",
3
3
  "mcpName": "io.github.asklokesh/loki-mode",
4
- "version": "7.124.0",
4
+ "version": "7.126.0",
5
5
  "description": "Loki Mode by Autonomi. Autonomous spec-to-product system: takes a PRD, GitHub issue, OpenAPI/JSON/YAML, or one-line brief to a deployed app via the RARV-C closure loop with 8 quality gates. Provider-agnostic (Claude Code, OpenAI Codex, Cline, Aider).",
6
6
  "keywords": [
7
7
  "agent",
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
3
3
  "name": "loki-mode",
4
4
  "displayName": "Loki Mode",
5
- "version": "7.124.0",
5
+ "version": "7.126.0",
6
6
  "description": "Autonomous spec-to-product build system with a built-in trust layer (RARV-C closure loop, 8 quality gates, completion council). Ships Loki's spec-hardening, drift-detection, and deterministic PR verification commands plus the Loki MCP server.",
7
7
  "author": {
8
8
  "name": "Autonomi",