loki-mode 8.41.0 → 8.44.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.41.0
6
+ # Loki Mode v8.44.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.41.0 | [Autonomi](https://www.autonomi.dev/) flagship product | ~410 lines core**
472
+ **v8.44.0 | [Autonomi](https://www.autonomi.dev/) flagship product | ~410 lines core**
package/VERSION CHANGED
@@ -1 +1 @@
1
- 8.41.0
1
+ 8.44.0
package/autonomy/loki CHANGED
@@ -1460,6 +1460,29 @@ cmd_start() {
1460
1460
  # first start. Writes ~/.loki/.welcomed and never repeats; non-blocking,
1461
1461
  # and never auto-opens a browser in CI or non-interactive shells.
1462
1462
  cmd_welcome_maybe_firstrun 2>/dev/null || true
1463
+
1464
+ # Tell the user when their install is stale, on the command they ACTUALLY
1465
+ # run. The hint existed but was wired only into `doctor` and `version` --
1466
+ # neither of which anyone runs before a build -- so a stale install stayed
1467
+ # invisible for as long as it took someone to go looking.
1468
+ #
1469
+ # That is not hypothetical. This machine was 4 releases behind (8.8.0 vs
1470
+ # 8.41.0) while running builds, and that specific gap mattered: v8.38.0
1471
+ # fixed four quality-gate detectors that had NEVER shipped, so on 8.8.0
1472
+ # mutation-integrity fail-closed on every iteration and first-pass
1473
+ # completion was impossible no matter how good the output was. The user had
1474
+ # no way to know from the tool.
1475
+ #
1476
+ # Cheap and fail-silent by construction: the result is cached for 24h, the
1477
+ # registry call has a 1.5s hard timeout, and any failure prints nothing
1478
+ # rather than guessing (see maybe_print_update_hint).
1479
+ # NOT `2>/dev/null`: the hint is PRINTED ON STDERR, so redirecting stderr
1480
+ # discards the only thing this call exists to produce. A first draft did
1481
+ # exactly that and the feature was silently dead. The function is already
1482
+ # fail-silent internally (opt-out, CI, non-TTY, timeout, unparseable
1483
+ # version all return 0 without output), so no guard is needed here.
1484
+ maybe_print_update_hint || true
1485
+
1463
1486
  local args=()
1464
1487
  local prd_file=""
1465
1488
  local provider=""
@@ -11603,6 +11626,38 @@ else:
11603
11626
  fi
11604
11627
  echo ""
11605
11628
 
11629
+ # INSTALL INTEGRITY: the quality gates shell out to detector scripts. If the
11630
+ # package shipped without them, four gates fail-CLOSED on every iteration --
11631
+ # correct behaviour (a missing detector must never read as "nothing found"),
11632
+ # but it means the build can never pass and first-pass completion is
11633
+ # impossible no matter how good the output is.
11634
+ #
11635
+ # That shipped: package.json's files[] had no tests/ entry until v8.38.0, so
11636
+ # every npm install had zero detectors. `doctor` reported a healthy system
11637
+ # the whole time, because it only ever checked for external COMMANDS -- not
11638
+ # for the files this package is supposed to contain. A broken install and a
11639
+ # healthy one were indistinguishable from the one command meant to tell them
11640
+ # apart.
11641
+ echo -e "${BOLD}Install integrity:${NC}"
11642
+ local _det_missing="" _det
11643
+ for _det in detect-test-mutations detect-mock-problems \
11644
+ detect-semantic-test-problems detect-invariant-violations; do
11645
+ if [ -f "${_LOKI_SCRIPT_DIR}/../tests/${_det}.sh" ]; then
11646
+ pass_count=$((pass_count + 1))
11647
+ else
11648
+ _det_missing="${_det_missing} ${_det}.sh"
11649
+ fi
11650
+ done
11651
+ if [ -z "$_det_missing" ]; then
11652
+ echo -e " ${GREEN}OK${NC} Quality-gate detectors present (4/4)"
11653
+ else
11654
+ echo -e " ${RED}FAIL${NC} Quality-gate detectors MISSING:${_det_missing}"
11655
+ echo -e " ${DIM} These gates fail-closed, so every iteration will be blocked.${NC}"
11656
+ _doctor_block "Incomplete install: quality-gate detectors are missing. Reinstall: bun install -g loki-mode"
11657
+ fail_count=$((fail_count + 1))
11658
+ fi
11659
+ echo ""
11660
+
11606
11661
  # Summary
11607
11662
  echo -e "${BOLD}Summary:${NC} ${GREEN}$pass_count passed${NC}, ${RED}$fail_count failed${NC}, ${YELLOW}$warn_count warnings${NC}"
11608
11663
  echo ""
package/autonomy/run.sh CHANGED
@@ -23036,8 +23036,30 @@ if __name__ == "__main__":
23036
23036
  # v7.5.3 Phase 1 hook: persist structured findings +
23037
23037
  # auto-write learnings (one shell-out per iteration).
23038
23038
  # Best-effort; never fails the main loop.
23039
- if [ "${LOKI_INJECT_FINDINGS:-1}" != "0" ] && command -v bun >/dev/null 2>&1; then
23040
- bun "${SCRIPT_DIR}/../loki-ts/dist/loki.js" internal phase1-hooks reflect "$ITERATION_COUNT" 2>/dev/null || true
23039
+ if [ "${LOKI_INJECT_FINDINGS:-1}" != "0" ]; then
23040
+ if command -v bun >/dev/null 2>&1; then
23041
+ bun "${SCRIPT_DIR}/../loki-ts/dist/loki.js" internal phase1-hooks reflect "$ITERATION_COUNT" 2>/dev/null || true
23042
+ else
23043
+ # DEGRADED, and said so. Findings injection is what
23044
+ # tells the next iteration WHAT to fix; without it the
23045
+ # agent knows only that it failed. Research puts "the
23046
+ # agent did not attempt to recover from an error" at
23047
+ # 56% of all agent failures, and a feedback loop that
23048
+ # silently stops feeding back manufactures exactly that
23049
+ # shape -- the next iteration then looks like the model
23050
+ # failing, when it was never told what went wrong.
23051
+ #
23052
+ # Defaults ON but was gated on `command -v bun`, so on a
23053
+ # machine without bun it degraded with no signal at all.
23054
+ # A missing capability must be visible; a silent one is
23055
+ # worse than an absent feature because it misattributes
23056
+ # the failure.
23057
+ log_warn "Findings injection unavailable (bun not found): the next iteration will be told it failed but NOT what to fix. Install bun, or set LOKI_INJECT_FINDINGS=0 to silence this."
23058
+ emit_event_json "capability_degraded" \
23059
+ "capability=inject_findings" \
23060
+ "reason=bun_not_found" \
23061
+ "impact=next_iteration_lacks_structured_findings" 2>/dev/null || true
23062
+ fi
23041
23063
  fi
23042
23064
  fi
23043
23065
  emit_stage_complete "code_review" "$_stg_ok" "$_stg_t0"
@@ -7,7 +7,7 @@ Modules:
7
7
  control: Session control API (start/stop/pause/resume)
8
8
  """
9
9
 
10
- __version__ = "8.41.0"
10
+ __version__ = "8.44.0"
11
11
 
12
12
  # Expose the control app for easy import
13
13
  try:
@@ -0,0 +1,161 @@
1
+ # Fastest First-Pass Full Completion
2
+
3
+ Founder ask: **fastest first-pass full completion.** No waiting through a second
4
+ iteration. Highest quality output. Grounded in researched competitor data, not
5
+ test auditing.
6
+
7
+ This replaces the speed framing of `SPEED-AND-FIRST-PASS-PLAN.md`. That plan
8
+ optimised the *duration* of iterations. This one attacks the *number* of them,
9
+ which is what the founder actually asked for and where the evidence points.
10
+
11
+ ---
12
+
13
+ ## 1. The research says the bottleneck is not the model
14
+
15
+ | finding | number | source |
16
+ |---|---|---|
17
+ | Agent failures traced to **planning, before the first line of code** | **82%** | loadsys 2026 failure-rate analysis |
18
+ | First-iteration aggregate pass rate | **47.8%** | SlopCodeBench (arXiv 2603.24755) |
19
+ | Failures where the agent **did not attempt to recover** from an error | **56%** | same |
20
+ | Visible resolutions **requiring explicit user correction** | **91.49%** | 20,574-session misalignment study (arXiv 2605.29442) |
21
+ | Typical iteration cycles per task | **3-5** | Anthropic SWE-bench internal |
22
+ | Cursor Agent Loop default iteration cap | **8** | Cursor 2026 breakdown |
23
+
24
+ Two conclusions, and they point the same way:
25
+
26
+ 1. **Second iterations are caused upstream of the model.** 82% of failures are
27
+ already determined before code is written. Making the model faster or the
28
+ council shorter cannot fix a task that was mis-specified.
29
+ 2. **Nobody has solved this.** Cursor ships an 8-iteration cap. Devin resolves
30
+ 51.5% of issues. The category *assumes* iteration. First-pass completion is
31
+ an unclaimed position, not a race we are losing.
32
+
33
+ **Strategic consequence.** We cannot out-model Cursor (custom MoE, ~250 tok/s)
34
+ or Cognition (SWE-1.6, ~950 tok/s). We do not have to. The measured
35
+ bottleneck -- specification quality and error recovery -- is harness work, and
36
+ harness work is the thing we can actually do.
37
+
38
+ ## 2. Our own data says exactly the same thing
39
+
40
+ Every recorded run on this machine:
41
+
42
+ | project | iterations | gates that failed |
43
+ |---|---:|---|
44
+ | FireLater | 3 | static_analysis 2, **mutation_integrity 3**, code_review 2 |
45
+ | anonima | 4 | code_review 1 |
46
+ | autonomi-engine-runs | 1 | none |
47
+ | loki-mode | 1 | none |
48
+
49
+ **Perfect correlation: every multi-iteration run had a failing gate; every
50
+ single-iteration run had none.** Iterations are not the model failing to
51
+ finish. They are gates rejecting work and sending it back.
52
+
53
+ That reframes the goal precisely:
54
+
55
+ > **First-pass completion = the first iteration passes every gate.**
56
+ > Not "the model tries harder". Not "fewer gates".
57
+
58
+ And it explains the founder's 21-minute FireLater run better than any latency
59
+ measurement: `mutation_integrity` failed **3 of 3 iterations in 0-1 seconds
60
+ each** -- the detector was never packaged (fixed v8.38.0), so the gate could
61
+ never pass. **First-pass completion was arithmetically impossible.** No speed
62
+ work would have touched it.
63
+
64
+ ## 3. The plan
65
+
66
+ Ranked by measured contribution to iteration count.
67
+
68
+ ### F0 -- A gate that cannot pass must abort, not iterate (highest value)
69
+
70
+ FireLater burned 3 iterations against a gate whose detector did not exist. The
71
+ gate correctly fail-closed each time; nothing noticed it was failing for the
72
+ same unfixable reason.
73
+
74
+ - Detect a gate failing with an **identical cause** across iterations and stop
75
+ with a named terminal reason instead of re-running the model.
76
+ - This is the 56% "did not attempt to recover" bucket, inverted: when recovery
77
+ is *impossible*, the honest move is to say so in iteration 1.
78
+ - **Already half-built:** `#87` does exactly this for spec contradictions
79
+ (fail FAST + HONEST + NAMED rather than grinding to max-iterations). Extend
80
+ that proven pattern to unfixable gate failures.
81
+ - Guard rails: only on a byte-identical repeated cause, never a first failure,
82
+ and it must map to a terminal-failure exit -- never a fake green.
83
+
84
+ ### F1 -- Front-load the 82%: make the spec gate the first-pass gate
85
+
86
+ `LOKI_SPEC_GRILL` already interrogates the spec before the loop and defaults
87
+ ON. That is the correct lever for the 82% planning bucket, and it is already
88
+ paid for.
89
+
90
+ - Measure what it actually catches per run (it is unmeasured today).
91
+ - Extend interrogation from *contradictions* to the ambiguity classes the
92
+ 20,574-session study names: unstated acceptance criteria, unstated scope
93
+ bounds, unstated interaction contracts.
94
+ - **Research constraint, load-bearing:** auto-generated context files measured
95
+ **-3% success, +20% cost**; human-written ones **+4%**. So this must produce
96
+ *questions and resolutions*, never a generated context blob.
97
+
98
+ ### F2 -- Findings injection must not be silently optional
99
+
100
+ `LOKI_INJECT_FINDINGS` defaults on, but the injection is gated on
101
+ `command -v bun`. **Without bun, the agent is told it failed and not what to
102
+ fix** -- the exact "no error recovery" shape that is 56% of failures.
103
+
104
+ - Make the fallback explicit: if findings cannot be injected, say so loudly.
105
+ - A silent degradation of the feedback loop is worse than a missing feature,
106
+ because the next iteration looks like a model failure.
107
+
108
+ ### F3 -- Verify before the gate, not after
109
+
110
+ 47.8% first-iteration pass rate is the industry number. The cheap deterministic
111
+ gates (test_suite, static_analysis, lsp_diagnostics) cost ~6s combined and run
112
+ *after* the model has already declared done.
113
+
114
+ - Have the agent run them **during** iteration 1 and fix what they report,
115
+ before the iteration closes.
116
+ - Cursor's Agent Loop is exactly this: "runs the test suite, reads stderr,
117
+ edits the offending files, re-runs" -- their headline architectural change.
118
+ We already have the gates; we just run them too late to help pass 1.
119
+
120
+ ### F4 -- Iteration budget as a measured decision
121
+
122
+ Research: 1-2 iteration caps fail even when the approach was sound; 5-10 is the
123
+ recommended range. We ship `LOKI_MAX_ITERATIONS=1000`.
124
+
125
+ - The goal is not a small cap. It is **finishing in one** and stopping honestly
126
+ when one is not enough.
127
+ - Pairs with F0: a cap is a blunt instrument; a named terminal reason is a
128
+ diagnosis.
129
+
130
+ ## 4. What we do NOT do
131
+
132
+ - **No model training.** Cursor and Cognition bought speed with custom models.
133
+ Not reachable, and claiming otherwise would be dishonest.
134
+ - **No generated context files.** Measured -3% success, +20% cost.
135
+ - **No weakening of gates to raise first-pass rate.** A gate that stops
136
+ blocking does not improve completion; it fakes it. Every item above either
137
+ fixes the *cause* of a failure or reports it honestly.
138
+
139
+ ## 5. Acceptance
140
+
141
+ The measurement is already built (`scripts/measure-run.sh`, v8.37.0):
142
+
143
+ > a scoped GitHub issue completes in **one iteration**, with every gate
144
+ > genuinely passing, and when it cannot, the run stops in iteration 1 with a
145
+ > named reason instead of grinding.
146
+
147
+ Baseline to beat, from our own table: FireLater 3 iterations, anonima 4.
148
+
149
+ ## 6. Why this is a real edge
150
+
151
+ The category has conceded iteration -- Cursor caps it at 8, Devin checkpoints
152
+ through it. Nobody markets first-pass completion because nobody has it.
153
+
154
+ Our moat is the Evidence Receipt: we can *prove* an iteration passed every
155
+ gate. Combining that with genuine first-pass completion is a claim no
156
+ competitor can make, and it is reachable with harness work rather than a
157
+ frontier lab.
158
+
159
+ Sources: SlopCodeBench (arXiv 2603.24755), developer-agent misalignment study
160
+ (arXiv 2605.29442), loadsys 2026 agent failure-rate analysis, Cursor 2026 agent
161
+ loop breakdown, Devin SWE-bench reporting.
@@ -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.41.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.44.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)
@@ -1222,4 +1222,4 @@ Set LOKI_LEGACY_BASH=1 to force the bash CLI for every command.
1222
1222
  `),2}case"start":{let{runStart:Y}=await Promise.resolve().then(() => (b_(),y_));return Y(Q)}default:return process.stderr.write(`Unknown command: ${X}
1223
1223
  `),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);
1224
1224
 
1225
- //# debugId=FB3BEB7088BC3BFB64756E2164756E21
1225
+ //# debugId=E6F40E8D30865CF164756E2164756E21
package/mcp/__init__.py CHANGED
@@ -75,4 +75,4 @@ try:
75
75
  except ImportError:
76
76
  __all__ = ['mcp']
77
77
 
78
- __version__ = '8.41.0'
78
+ __version__ = '8.44.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.41.0",
4
+ "version": "8.44.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.41.0",
5
+ "version": "8.44.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",