loki-mode 8.48.0 → 8.50.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 CHANGED
@@ -3,7 +3,7 @@ name: loki-mode
3
3
  description: Autonomous spec-driven build system with a built-in trust layer. It does not call work done until it is verified (RARV-C closure loop, 8 quality gates, completion council, verified-completion evidence gate). Triggers on "Loki Mode". Takes a spec (PRD, GitHub issue, OpenAPI doc, etc.) to deployed product with minimal human intervention. Provider-agnostic. Requires --dangerously-skip-permissions flag.
4
4
  ---
5
5
 
6
- # Loki Mode v8.48.0
6
+ # Loki Mode v8.50.0
7
7
 
8
8
  **You are an autonomous agent. You make decisions. You do not ask questions. You do not stop.**
9
9
 
@@ -469,4 +469,4 @@ See `CHANGELOG.md` entries [7.5.7], [7.5.8], [7.5.13] for the per-fix list and r
469
469
 
470
470
  ---
471
471
 
472
- **v8.48.0 | [Autonomi](https://www.autonomi.dev/) flagship product | ~410 lines core**
472
+ **v8.50.0 | [Autonomi](https://www.autonomi.dev/) flagship product | ~410 lines core**
package/VERSION CHANGED
@@ -1 +1 @@
1
- 8.48.0
1
+ 8.50.0
package/autonomy/run.sh CHANGED
@@ -1111,6 +1111,41 @@ fi
1111
1111
  # Perpetual mode: never stop unless max iterations (ignores all completion signals)
1112
1112
  PERPETUAL_MODE=${LOKI_PERPETUAL_MODE:-false}
1113
1113
 
1114
+ # F4: bound the runaway ceiling for ORDINARY runs.
1115
+ #
1116
+ # MEASURED, not chosen. Real per-iteration wall clock across every recorded run
1117
+ # on this machine: median 718s, max 1746s. So the 1000 default is an 8.3-DAY
1118
+ # ceiling -- and it is the ONLY backstop, because the other two valves ship
1119
+ # disabled: LOKI_BUDGET_LIMIT defaults to "" (check_budget_limit returns
1120
+ # immediately) and LOKI_MAX_DURATION defaults to 0 (check_max_duration returns
1121
+ # "never stop").
1122
+ #
1123
+ # It also contradicts our own documentation. SETUP.md tells users to RAISE the
1124
+ # budget for large work with LOKI_MAX_ITERATIONS=40, and the demo uses 10 -- so
1125
+ # the shipped default is 25x the documented "large" setting.
1126
+ #
1127
+ # What real runs actually use: 1, 1, 3, 4. Every one terminated `completed` via
1128
+ # council approval or a completion promise; NONE hit a cap. Those are the
1129
+ # evidence-driven terminals, and they are unaffected by this -- the cap is a
1130
+ # backstop, not the mechanism.
1131
+ #
1132
+ # 25 is deliberately generous against that evidence (6x the observed maximum),
1133
+ # because the research is explicit that a too-small cap fails runs whose
1134
+ # approach was sound: 1-2 caps fail even when the agent was on track, and the
1135
+ # recommended range is 5-10. This is not a first-pass target; F0 (v8.45.0)
1136
+ # already stops a doomed run at its CAUSE, which is the better instrument.
1137
+ #
1138
+ # TWO GUARDS, both load-bearing:
1139
+ # - an explicit LOKI_MAX_ITERATIONS always wins, so nobody's setting changes
1140
+ # - PERPETUAL_MODE is untouched: it deliberately ignores every completion
1141
+ # signal and relies on max-iterations as its ONLY stop, so lowering the cap
1142
+ # there would silently truncate exactly the runs that opted out of stopping
1143
+ if [ -z "${LOKI_MAX_ITERATIONS:-}" ] \
1144
+ && [ "$PERPETUAL_MODE" != "true" ] \
1145
+ && [ "${LOKI_AUTO_FIX:-}" != "true" ]; then
1146
+ MAX_ITERATIONS="${LOKI_MAX_ITERATIONS_DEFAULT:-25}"
1147
+ fi
1148
+
1114
1149
  # Enterprise background service PIDs (OTEL bridge, audit subscriber, integration sync)
1115
1150
  ENTERPRISE_PIDS=()
1116
1151
 
@@ -10611,7 +10646,21 @@ LOKI_STUCK_JSON
10611
10646
  )" || return 1
10612
10647
  ;;
10613
10648
  *)
10614
- cur="$(head -1 "$reason_file" 2>/dev/null)" || return 1
10649
+ # SKIP the header. These files open with a static banner --
10650
+ # "# Test mutation findings (HIGH blocks this iteration)" -- which is
10651
+ # byte-identical on every run. Comparing it meant EVERY repeated
10652
+ # failure looked "stuck", including a run making real progress
10653
+ # through different findings each iteration. That is the one
10654
+ # direction this valve must never fail in, and a real FireLater run
10655
+ # is what exposed it: gate-stuck-mutation_integrity.last had
10656
+ # recorded the banner, not a cause.
10657
+ #
10658
+ # Take the first line that is neither blank nor a comment, and strip
10659
+ # ANSI colour (the detectors emit it, and the same finding rendered
10660
+ # with and without colour would otherwise compare unequal).
10661
+ cur="$(grep -vE '^[[:space:]]*(#|$)' "$reason_file" 2>/dev/null \
10662
+ | head -1 \
10663
+ | sed 's/\x1b\[[0-9;]*m//g')" || return 1
10615
10664
  ;;
10616
10665
  esac
10617
10666
  [ -n "$cur" ] || return 1
@@ -22897,6 +22946,19 @@ if __name__ == "__main__":
22897
22946
  mk_count=$(track_gate_failure "mock_integrity")
22898
22947
  gate_failures="${gate_failures}mock_integrity,"
22899
22948
  log_warn "Mock integrity gate FAILED ($mk_count consecutive) - CRITICAL/HIGH mock problems"
22949
+ # F0, third gate. Measured on the v8.49.0 FireLater run:
22950
+ # mock_integrity failed 3 times -- MORE than any other
22951
+ # gate -- and was not wired to the stuck check, so an
22952
+ # unfixable mock problem could grind indefinitely.
22953
+ if _loki_gate_stuck "mock_integrity" \
22954
+ "${TARGET_DIR:-.}/.loki/quality/mock-findings.txt" "$mk_count"; then
22955
+ log_error "Mock integrity has failed $mk_count times for the SAME reason. Another iteration would reach the same verdict. Stopping instead of grinding."
22956
+ emit_event_json "gate_stuck" \
22957
+ "gate=mock_integrity" \
22958
+ "consecutive=$mk_count" 2>/dev/null || true
22959
+ save_state "${retry:-0}" "gate_stuck_mock_integrity" 20 2>/dev/null || true
22960
+ return 20
22961
+ fi
22900
22962
  ;;
22901
22963
  *)
22902
22964
  _stg_ok=not_run
@@ -7,7 +7,7 @@ Modules:
7
7
  control: Session control API (start/stop/pause/resume)
8
8
  """
9
9
 
10
- __version__ = "8.48.0"
10
+ __version__ = "8.50.0"
11
11
 
12
12
  # Expose the control app for easy import
13
13
  try:
@@ -65,9 +65,8 @@ work would have touched it.
65
65
 
66
66
  Ranked by measured contribution to iteration count.
67
67
 
68
- **STATUS 2026-08-01: F0, F2 and F3 SHIPPED. F1 was already built (verified, no
69
- work needed). F4's mechanism exists; only its default is open, and that needs
70
- real-build measurement rather than a guess.**
68
+ **STATUS 2026-08-01: ALL ITEMS CLOSED. F0, F2, F3, F4 shipped. F1 was already
69
+ built (verified, no work needed).**
71
70
 
72
71
  ### F0 -- SHIPPED v8.45.0. A gate that cannot pass aborts instead of iterating.
73
72
 
@@ -139,7 +138,7 @@ gates (test_suite, static_analysis, lsp_diagnostics) cost ~6s combined and run
139
138
  edits the offending files, re-runs" -- their headline architectural change.
140
139
  We already have the gates; we just run them too late to help pass 1.
141
140
 
142
- ### F4 -- Iteration budget: mechanism exists, default is the open question
141
+ ### F4 -- SHIPPED v8.49.0. Bounded default, both guards mutation-pinned.
143
142
 
144
143
  Verified: hitting the cap already records the named terminal
145
144
  `max_iterations_reached` with exit 20 (run.sh:21433) -- it does NOT fake
@@ -0,0 +1,179 @@
1
+ # Wang's Five Principles: measured audit and plan
2
+
3
+ Founder ask: make Wang's five agentic-system principles the heart of the Loki
4
+ engine, grounded in researched speed / quality / cost data.
5
+
6
+ **This was asked for and not delivered.** A day was spent on gates, packaging
7
+ and test-detection instead. This is the plan, written against measurement
8
+ rather than intention.
9
+
10
+ The five principles, as Wang states them:
11
+
12
+ 1. **Systems Thinking** -- never goes out of style
13
+ 2. **Speed** -- "one of the most critical things"
14
+ 3. **Reliability** -- "extremely important"
15
+ 4. **Extensibility** -- scale to complex multi-agent setups
16
+ 5. **Feedback Loops + Evals/Metrics** -- *"if you can develop the right agentic
17
+ loop and have the right eval or metric for the agents to optimize, a swarm of
18
+ agents can accomplish more than a team of a hundred engineers"*
19
+
20
+ ---
21
+
22
+ ## 0. The research finding that reframes everything
23
+
24
+ > **"The same model in a different harness routinely drops 10-15 points --
25
+ > pick the harness, not just the model."** (2026 SWE-bench harness comparisons)
26
+
27
+ That is our entire thesis, stated by the market. We cannot train a frontier
28
+ model. **We do not have to.** The harness is worth 10-15 points, and the harness
29
+ is the thing we build.
30
+
31
+ Supporting 2026 data:
32
+
33
+ | finding | number |
34
+ |---|---|
35
+ | Harness delta on an identical model | **10-15 points** |
36
+ | Top of SWE-bench leaderboard | 75-80% (GPT-5.6 Sol 96.2%, Claude Fable 5 95.0% claimed) |
37
+ | Cost per SWE-bench pass, Sonnet 4.5 | **~$14** |
38
+ | Open harness + open weights vs Devin | **~1/20th the cost** |
39
+ | Agent failures traced to planning | 82% |
40
+ | First-iteration pass rate | 47.8% |
41
+ | Resolutions needing user correction | 91.49% |
42
+
43
+ The cost line matters commercially: **a 20x cost spread exists between harnesses
44
+ running comparable models.** Cost-per-resolved-issue is a competitive axis we
45
+ have never measured.
46
+
47
+ ## 1. Honest audit: where we actually stand
48
+
49
+ Measured on this machine, not asserted.
50
+
51
+ | principle | state | evidence |
52
+ |---|---|---|
53
+ | **1 Systems Thinking** | STRONG | 8 quality gates, RARV-C loop, council, Evidence Receipt, dual-route parity enforced by test |
54
+ | **2 Speed** | MEASURED, UNOPTIMISED | agent call = **980s = 96%** of iteration; all gates together = 44s |
55
+ | **3 Reliability** | STRONG, newly so | 73 mutation-proven trust invariants; four gates were shipping broken until v8.38.0 |
56
+ | **4 Extensibility** | STRONG | 4 providers, 41 agent types, MCP (34 tools), plugin marketplace |
57
+ | **5 Feedback Loops / Evals** | **BROKEN** | `cost_usd == 0` on **3 of 5** efficiency records; no eval score for our own harness |
58
+
59
+ **Principle 5 is the gap, and it is the one Wang weights highest.** He states the
60
+ whole thesis conditionally: *"if you can develop the right agentic loop AND have
61
+ the right eval or metric for the agents to optimize."* We have the loop. We do
62
+ not have the metric.
63
+
64
+ ## 2. What "broken" means concretely
65
+
66
+ **Cost is not measured.** The efficiency schema has every field --
67
+ `cost_usd`, `input_tokens`, `output_tokens`, `cache_read_tokens`,
68
+ `cache_creation_tokens`, `model`, `duration_ms` -- and `cost_usd` is **0** on 3
69
+ of 5 records. We cannot answer "what did this issue cost?", which is:
70
+
71
+ - the axis with a measured **20x industry spread**
72
+ - the thing a buyer compares first
73
+ - unmeasurable *after* the fact, because token counts are per-call
74
+
75
+ **Our harness has no eval score.** `benchmarks/` contains a SWE-bench-lite
76
+ dataset and a results directory. There is no recorded score for the current
77
+ harness. So when the research says a harness is worth 10-15 points, **we cannot
78
+ say which side of that we are on.**
79
+
80
+ This is not a small omission. It is the difference between "we believe our
81
+ harness is good" and "our harness scores X, and here is the receipt."
82
+
83
+ ## 3. The plan
84
+
85
+ Ordered by Wang's own weighting: the eval/metric loop first, because he makes
86
+ everything else conditional on it.
87
+
88
+ ### W1 -- Make cost real (unblocks principle 5)
89
+
90
+ `cost_usd == 0` on most records while every input field is present. Fix the
91
+ computation, not the schema.
92
+
93
+ - Compute from `input/output/cache_read/cache_creation` x the model's price.
94
+ All four token counts are already recorded; the pricing table already exists
95
+ (`loki-ts/data/model-pricing.json`, cache tiers included).
96
+ - Emit **cost per iteration** and **cost per resolved issue** -- the second is
97
+ the one with the 20x spread.
98
+ - Guard direction: a missing price must record **unknown**, never 0. A zero is a
99
+ claim that the iteration was free, and it is the claim currently being made.
100
+
101
+ ### W2 -- Score our own harness (completes principle 5)
102
+
103
+ `benchmarks/datasets/swebench-lite.json` exists and is unused for this.
104
+
105
+ - Run the harness against SWE-bench-lite and record the score with the
106
+ Evidence Receipt attached.
107
+ - Report **score AND cost-per-resolved-issue** together. Score alone is what
108
+ everyone publishes; the pair is what nobody does, and it is exactly our
109
+ Evidence Receipt moat applied to ourselves.
110
+ - Re-run per release: this becomes the regression signal for harness quality,
111
+ which today has none.
112
+
113
+ ### W3 -- Attack the 980s (principle 2, speed)
114
+
115
+ Measured: the agent call is **96%** of an iteration. Gates are 44s. Every speed
116
+ knob shipped so far (v8.33.0-v8.35.0) targets the 4%.
117
+
118
+ - The lever is prompt size and cache discipline, not gate ordering. The
119
+ `[CACHE_BREAKPOINT]` split exists; cache reads price at 0.1x input.
120
+ - W1 is the precondition: without real cost numbers we cannot tell whether a
121
+ prompt change helped or hurt.
122
+ - **Do not ship more gate-latency work until this is measured.** It is
123
+ optimising 4% while 96% is unexamined.
124
+
125
+ ### W4 -- Close the loop the metrics feed (principle 5, second half)
126
+
127
+ Wang's phrasing is *"the right agentic loop AND the right metric."* We have
128
+ `LOKI_INJECT_FINDINGS` (findings to next iteration) and `LOKI_AUTO_LEARNINGS`.
129
+ What we lack is the metric flowing back:
130
+
131
+ - Feed cost and iteration count into the run's own decisions, not just the
132
+ receipt. An agent that knows it is on iteration 3 of a budget behaves
133
+ differently from one that does not.
134
+ - This is the piece that turns telemetry into a *feedback loop* rather than a
135
+ report.
136
+
137
+ ### W5 -- Systems thinking: stop shipping half-wired features (principle 1)
138
+
139
+ Not new work; a standing rule earned the hard way. This session found the same
140
+ shape repeatedly: a fact recorded but never rendered, a gate that never ran, a
141
+ detector never packaged, a valve that fired one iteration too late.
142
+
143
+ - Every new capability ships **recorded, rendered, acted on, and
144
+ mutation-proven** -- or it is not shipped.
145
+ - Already enforced by the 73-invariant detector. The rule is written down so it
146
+ survives.
147
+
148
+ ## 4. What we do NOT do
149
+
150
+ - **No model training.** Cursor (custom MoE, ~250 tok/s) and Cognition
151
+ (SWE-1.6, ~950 tok/s) bought speed that way. Not reachable. The 10-15 point
152
+ harness delta is, and it is ours.
153
+ - **No more gate-latency work before W3 is measured.** 44s of gates against a
154
+ 980s agent call.
155
+ - **No published score without its cost.** Score alone is the industry norm and
156
+ it is the half that flatters.
157
+
158
+ ## 5. Acceptance
159
+
160
+ - `cost_usd` is non-zero and correct on **every** efficiency record, or
161
+ explicitly `unknown`
162
+ - a recorded SWE-bench-lite score for our harness, **with cost per resolved
163
+ issue**, regenerated per release
164
+ - a measured before/after on the 980s agent call
165
+
166
+ ## 6. Why this is the edge
167
+
168
+ Wang's claim is conditional on the metric. The market's finding is that the
169
+ harness is worth 10-15 points. Our moat is the Evidence Receipt -- proof that a
170
+ result is real.
171
+
172
+ **Turn the receipt on ourselves**: publish a harness score *and* its cost, both
173
+ provable. Nobody in the category does this. It is the same trust argument that
174
+ sells the product, applied to the product's own claims.
175
+
176
+ Sources: 2026 SWE-bench harness comparisons (morphllm, codesota, awesomeagents),
177
+ agent-evaluation framework surveys 2026, Wang interviews (YC Startup Library,
178
+ CSIS), SlopCodeBench (arXiv 2603.24755), developer-agent misalignment study
179
+ (arXiv 2605.29442).
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- var h_=Object.create;var{getPrototypeOf:v_,defineProperty:rK,getOwnPropertyNames:g_}=Object;var m_=Object.prototype.hasOwnProperty;function u_(Z){return this[Z]}var p_,d_,c_=(Z,X,Q)=>{var Y=Z!=null&&typeof Z==="object";if(Y){var J=X?p_??=new WeakMap:d_??=new WeakMap,z=J.get(Z);if(z)return z}Q=Z!=null?h_(v_(Z)):{};let K=X||!Z||!Z.__esModule?rK(Q,"default",{value:Z,enumerable:!0}):Q;for(let $ of g_(Z))if(!m_.call(K,$))rK(K,$,{get:u_.bind(Z,$),enumerable:!0});if(Y)J.set(Z,K);return K};var qQ=(Z,X)=>()=>(X||Z((X={exports:{}}).exports,X),X.exports);var l_=(Z)=>Z;function i_(Z,X){this[Z]=l_.bind(null,X)}var l0=(Z,X)=>{for(var Q in X)rK(Z,Q,{get:X[Q],enumerable:!0,configurable:!0,set:i_.bind(X,Q)})};var p=(Z,X)=>()=>(Z&&(X=Z(Z=0)),X);var e0=import.meta.require;var kO={};l0(kO,{lokiDir:()=>j0,homeLokiDir:()=>P4,findRepoRootForVersion:()=>eK,REPO_ROOT:()=>r0});import{resolve as n7,dirname as tK}from"path";import{fileURLToPath as a_}from"url";import{existsSync as GQ}from"fs";import{homedir as s_}from"os";function n_(){let Z=RO;for(let X=0;X<6;X++){if(GQ(n7(Z,"VERSION"))&&GQ(n7(Z,"autonomy/run.sh")))return Z;let Q=tK(Z);if(Q===Z)break;Z=Q}return n7(RO,"..","..","..")}function eK(Z){let X=Z;for(let Q=0;Q<6;Q++){if(GQ(n7(X,"VERSION"))&&GQ(n7(X,"autonomy/run.sh")))return X;let Y=tK(X);if(Y===X)break;X=Y}return n7(Z,"..","..","..")}function j0(){return process.env.LOKI_DIR??n7(process.cwd(),".loki")}function P4(){return n7(s_(),".loki")}var RO,r0;var G8=p(()=>{RO=tK(a_(import.meta.url));r0=n_()});import{readFileSync as o_}from"fs";import{resolve as r_,dirname as t_}from"path";import{fileURLToPath as e_}from"url";function f3(){if(h5!==null)return h5;let Z="8.48.0";if(typeof Z==="string"&&Z.length>0)return h5=Z,h5;try{let X=t_(e_(import.meta.url)),Q=eK(X);h5=o_(r_(Q,"VERSION"),"utf-8").trim()}catch{h5="unknown"}return h5}var h5=null;var HQ=p(()=>{G8()});var bO={};l0(bO,{runOrThrow:()=>Of,run:()=>E0,readStreamCapped:()=>UQ,commandVersion:()=>Af,commandExists:()=>X9,ShellError:()=>Z$,MAX_STDOUT_BYTES:()=>yO});async function UQ(Z,X=yO){let Q=Z.getReader(),Y=new TextDecoder,J="",z=0;try{while(z<X){let{done:K,value:$}=await Q.read();if(K)break;if(!$)continue;if(z+=$.byteLength,z>X){let W=$.byteLength-(z-X);J+=Y.decode($.subarray(0,W),{stream:!0});break}J+=Y.decode($,{stream:!0})}J+=Y.decode()}finally{try{await Q.cancel()}catch{}Q.releaseLock()}return J}async function E0(Z,X={}){let Q=Bun.spawn({cmd:[...Z],stdout:"pipe",stderr:"pipe",env:X.env?{...process.env,...X.env}:process.env,cwd:X.cwd}),Y,J;if(X.timeoutMs&&X.timeoutMs>0)Y=setTimeout(()=>{try{Q.kill("SIGTERM")}catch{}J=setTimeout(()=>{try{Q.kill("SIGKILL")}catch{}},2000)},X.timeoutMs);try{let[z,K,$]=await Promise.all([UQ(Q.stdout),new Response(Q.stderr).text(),Q.exited]);return{stdout:z,stderr:K,exitCode:$}}finally{if(Y)clearTimeout(Y);if(J)clearTimeout(J)}}async function Of(Z,X={}){let Q=await E0(Z,X);if(Q.exitCode!==0)throw new Z$(`command failed (${Q.exitCode}): ${Z.join(" ")}`,Q.exitCode,Q.stdout,Q.stderr);return Q}async function X9(Z){let X=Lf(Z),Q=await E0(["sh","-c",`command -v ${X}`],{timeoutMs:5000});if(Q.exitCode===0)return Q.stdout.trim()||null;return null}function Lf(Z){if(!/^[A-Za-z0-9._/-]+$/.test(Z))throw Error(`refused to shell-escape suspect token: ${Z}`);return Z}async function Af(Z,X="--version"){if(!await X9(Z))return null;let Y=await E0([Z,X],{timeoutMs:5000});if(Y.exitCode!==0)return null;return((Y.stdout||Y.stderr).split(/\r?\n/)[0]?.trim()??"")||null}var yO=16777216,Z$;var x9=p(()=>{Z$=class Z$ extends Error{message;exitCode;stdout;stderr;constructor(Z,X,Q,Y){super(Z);this.message=Z;this.exitCode=X;this.stdout=Q;this.stderr=Y;this.name="ShellError"}}});function o7(Z){return jf?"":Z}var jf,L0,k8,p0,ZV0,i0,H8,Q9,v;var S6=p(()=>{jf=(process.env.NO_COLOR??"").length>0;L0=o7("\x1B[0;31m"),k8=o7("\x1B[0;32m"),p0=o7("\x1B[1;33m"),ZV0=o7("\x1B[0;34m"),i0=o7("\x1B[0;36m"),H8=o7("\x1B[1m"),Q9=o7("\x1B[2m"),v=o7("\x1B[0m")});import{existsSync as xf}from"fs";async function E7(){if(k4!==void 0)return k4;let Z="/opt/homebrew/bin/python3.12";if(xf(Z))return k4=Z,Z;let X=await X9("python3.12");if(X)return k4=X,X;let Q=await X9("python3");return k4=Q,Q}async function Y7(Z,X={}){let Q=await E7();if(!Q)return{stdout:"",stderr:"python3 not found",exitCode:127};return E0([Q,"-c",Z],X)}var k4;var r7=p(()=>{x9()});var ZL={};l0(ZL,{runStatus:()=>Yh});import{existsSync as Y9,readFileSync as v3,readdirSync as iO,statSync as aO}from"fs";import{resolve as h8,basename as sf}from"path";import{homedir as nf}from"os";function sO(Z){let X=Math.trunc(Z);if(X>=1e6)return`${(Math.trunc(X/1e6*10)/10).toFixed(1)}M`;if(X>=1000)return`${(Math.trunc(X/1000*10)/10).toFixed(1)}K`;return String(X)}function nO(Z,X,Q){if(X===0)return null;let Y=Math.trunc(Z*100/X),J=Math.trunc(Z*NQ/X);if(J>NQ)J=NQ;let z=NQ-J,K=k8;if(Y>=80)K=L0;else if(Y>=50)K=p0;let $="=".repeat(Math.max(0,J))+" ".repeat(Math.max(0,z)),W=sO(Z),V=sO(X);return` ${H8}${Q}${v} ${K}[${$}]${v} ${Y}% (${W} / ${V})`}async function rf(){if(await X9("jq"))return!0;return process.stdout.write(`${L0}Error: jq is required but not installed.${v}
2
+ var h_=Object.create;var{getPrototypeOf:v_,defineProperty:rK,getOwnPropertyNames:g_}=Object;var m_=Object.prototype.hasOwnProperty;function u_(Z){return this[Z]}var p_,d_,c_=(Z,X,Q)=>{var Y=Z!=null&&typeof Z==="object";if(Y){var J=X?p_??=new WeakMap:d_??=new WeakMap,z=J.get(Z);if(z)return z}Q=Z!=null?h_(v_(Z)):{};let K=X||!Z||!Z.__esModule?rK(Q,"default",{value:Z,enumerable:!0}):Q;for(let $ of g_(Z))if(!m_.call(K,$))rK(K,$,{get:u_.bind(Z,$),enumerable:!0});if(Y)J.set(Z,K);return K};var qQ=(Z,X)=>()=>(X||Z((X={exports:{}}).exports,X),X.exports);var l_=(Z)=>Z;function i_(Z,X){this[Z]=l_.bind(null,X)}var l0=(Z,X)=>{for(var Q in X)rK(Z,Q,{get:X[Q],enumerable:!0,configurable:!0,set:i_.bind(X,Q)})};var p=(Z,X)=>()=>(Z&&(X=Z(Z=0)),X);var e0=import.meta.require;var kO={};l0(kO,{lokiDir:()=>j0,homeLokiDir:()=>P4,findRepoRootForVersion:()=>eK,REPO_ROOT:()=>r0});import{resolve as n7,dirname as tK}from"path";import{fileURLToPath as a_}from"url";import{existsSync as GQ}from"fs";import{homedir as s_}from"os";function n_(){let Z=RO;for(let X=0;X<6;X++){if(GQ(n7(Z,"VERSION"))&&GQ(n7(Z,"autonomy/run.sh")))return Z;let Q=tK(Z);if(Q===Z)break;Z=Q}return n7(RO,"..","..","..")}function eK(Z){let X=Z;for(let Q=0;Q<6;Q++){if(GQ(n7(X,"VERSION"))&&GQ(n7(X,"autonomy/run.sh")))return X;let Y=tK(X);if(Y===X)break;X=Y}return n7(Z,"..","..","..")}function j0(){return process.env.LOKI_DIR??n7(process.cwd(),".loki")}function P4(){return n7(s_(),".loki")}var RO,r0;var G8=p(()=>{RO=tK(a_(import.meta.url));r0=n_()});import{readFileSync as o_}from"fs";import{resolve as r_,dirname as t_}from"path";import{fileURLToPath as e_}from"url";function f3(){if(h5!==null)return h5;let Z="8.50.0";if(typeof Z==="string"&&Z.length>0)return h5=Z,h5;try{let X=t_(e_(import.meta.url)),Q=eK(X);h5=o_(r_(Q,"VERSION"),"utf-8").trim()}catch{h5="unknown"}return h5}var h5=null;var HQ=p(()=>{G8()});var bO={};l0(bO,{runOrThrow:()=>Of,run:()=>E0,readStreamCapped:()=>UQ,commandVersion:()=>Af,commandExists:()=>X9,ShellError:()=>Z$,MAX_STDOUT_BYTES:()=>yO});async function UQ(Z,X=yO){let Q=Z.getReader(),Y=new TextDecoder,J="",z=0;try{while(z<X){let{done:K,value:$}=await Q.read();if(K)break;if(!$)continue;if(z+=$.byteLength,z>X){let W=$.byteLength-(z-X);J+=Y.decode($.subarray(0,W),{stream:!0});break}J+=Y.decode($,{stream:!0})}J+=Y.decode()}finally{try{await Q.cancel()}catch{}Q.releaseLock()}return J}async function E0(Z,X={}){let Q=Bun.spawn({cmd:[...Z],stdout:"pipe",stderr:"pipe",env:X.env?{...process.env,...X.env}:process.env,cwd:X.cwd}),Y,J;if(X.timeoutMs&&X.timeoutMs>0)Y=setTimeout(()=>{try{Q.kill("SIGTERM")}catch{}J=setTimeout(()=>{try{Q.kill("SIGKILL")}catch{}},2000)},X.timeoutMs);try{let[z,K,$]=await Promise.all([UQ(Q.stdout),new Response(Q.stderr).text(),Q.exited]);return{stdout:z,stderr:K,exitCode:$}}finally{if(Y)clearTimeout(Y);if(J)clearTimeout(J)}}async function Of(Z,X={}){let Q=await E0(Z,X);if(Q.exitCode!==0)throw new Z$(`command failed (${Q.exitCode}): ${Z.join(" ")}`,Q.exitCode,Q.stdout,Q.stderr);return Q}async function X9(Z){let X=Lf(Z),Q=await E0(["sh","-c",`command -v ${X}`],{timeoutMs:5000});if(Q.exitCode===0)return Q.stdout.trim()||null;return null}function Lf(Z){if(!/^[A-Za-z0-9._/-]+$/.test(Z))throw Error(`refused to shell-escape suspect token: ${Z}`);return Z}async function Af(Z,X="--version"){if(!await X9(Z))return null;let Y=await E0([Z,X],{timeoutMs:5000});if(Y.exitCode!==0)return null;return((Y.stdout||Y.stderr).split(/\r?\n/)[0]?.trim()??"")||null}var yO=16777216,Z$;var x9=p(()=>{Z$=class Z$ extends Error{message;exitCode;stdout;stderr;constructor(Z,X,Q,Y){super(Z);this.message=Z;this.exitCode=X;this.stdout=Q;this.stderr=Y;this.name="ShellError"}}});function o7(Z){return jf?"":Z}var jf,L0,k8,p0,ZV0,i0,H8,Q9,v;var S6=p(()=>{jf=(process.env.NO_COLOR??"").length>0;L0=o7("\x1B[0;31m"),k8=o7("\x1B[0;32m"),p0=o7("\x1B[1;33m"),ZV0=o7("\x1B[0;34m"),i0=o7("\x1B[0;36m"),H8=o7("\x1B[1m"),Q9=o7("\x1B[2m"),v=o7("\x1B[0m")});import{existsSync as xf}from"fs";async function E7(){if(k4!==void 0)return k4;let Z="/opt/homebrew/bin/python3.12";if(xf(Z))return k4=Z,Z;let X=await X9("python3.12");if(X)return k4=X,X;let Q=await X9("python3");return k4=Q,Q}async function Y7(Z,X={}){let Q=await E7();if(!Q)return{stdout:"",stderr:"python3 not found",exitCode:127};return E0([Q,"-c",Z],X)}var k4;var r7=p(()=>{x9()});var ZL={};l0(ZL,{runStatus:()=>Yh});import{existsSync as Y9,readFileSync as v3,readdirSync as iO,statSync as aO}from"fs";import{resolve as h8,basename as sf}from"path";import{homedir as nf}from"os";function sO(Z){let X=Math.trunc(Z);if(X>=1e6)return`${(Math.trunc(X/1e6*10)/10).toFixed(1)}M`;if(X>=1000)return`${(Math.trunc(X/1000*10)/10).toFixed(1)}K`;return String(X)}function nO(Z,X,Q){if(X===0)return null;let Y=Math.trunc(Z*100/X),J=Math.trunc(Z*NQ/X);if(J>NQ)J=NQ;let z=NQ-J,K=k8;if(Y>=80)K=L0;else if(Y>=50)K=p0;let $="=".repeat(Math.max(0,J))+" ".repeat(Math.max(0,z)),W=sO(Z),V=sO(X);return` ${H8}${Q}${v} ${K}[${$}]${v} ${Y}% (${W} / ${V})`}async function rf(){if(await X9("jq"))return!0;return process.stdout.write(`${L0}Error: jq is required but not installed.${v}
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)
@@ -1227,4 +1227,4 @@ Set LOKI_LEGACY_BASH=1 to force the bash CLI for every command.
1227
1227
  `),2}case"start":{let{runStart:Y}=await Promise.resolve().then(() => (b_(),y_));return Y(Q)}default:return process.stderr.write(`Unknown command: ${X}
1228
1228
  `),process.stderr.write(__),2}}cO();process.on("SIGINT",()=>process.exit(130));process.on("SIGTERM",()=>process.exit(143));var fW0=await _W0(Bun.argv.slice(2));process.exit(fW0);
1229
1229
 
1230
- //# debugId=58CC359F26BB671D64756E2164756E21
1230
+ //# debugId=14E415D3D7DA72EF64756E2164756E21
package/mcp/__init__.py CHANGED
@@ -75,4 +75,4 @@ try:
75
75
  except ImportError:
76
76
  __all__ = ['mcp']
77
77
 
78
- __version__ = '8.48.0'
78
+ __version__ = '8.50.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": "8.48.0",
4
+ "version": "8.50.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": "8.48.0",
5
+ "version": "8.50.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",