loki-mode 8.9.0 → 8.9.1

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.9.0
6
+ # Loki Mode v8.9.1
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.9.0 | [Autonomi](https://www.autonomi.dev/) flagship product | ~410 lines core**
472
+ **v8.9.1 | [Autonomi](https://www.autonomi.dev/) flagship product | ~410 lines core**
package/VERSION CHANGED
@@ -1 +1 @@
1
- 8.9.0
1
+ 8.9.1
package/autonomy/run.sh CHANGED
@@ -22580,9 +22580,23 @@ if __name__ == "__main__":
22580
22580
  run_memory_consolidation
22581
22581
  # No on_run_complete: a force-stop must never open a "done" PR.
22582
22582
  emit_completion_summary force_stopped
22583
- save_state $retry "force_stopped" 0
22583
+ # Exit 20, not 0. Every other signal here already says this
22584
+ # run is NOT verified-complete -- the header, the warning,
22585
+ # the refusal to open a PR -- but the exit code said the
22586
+ # opposite, and the exit code is the only one a CI job, a
22587
+ # Kubernetes Job, or a shell `&&` actually reads. A
22588
+ # stagnation force-stop was therefore indistinguishable
22589
+ # from success to every automated caller.
22590
+ #
22591
+ # 20 is the established "deterministic terminal failure"
22592
+ # code, already used by max_iterations_reached
22593
+ # (run.sh:20796, :20877) for the same class of outcome:
22594
+ # the run stopped without verifying the work. Retrying is
22595
+ # pointless; a human needs to look. Two terminals with the
22596
+ # same meaning must not report opposite exit codes.
22597
+ save_state $retry "force_stopped" 20
22584
22598
  rm -f "$iter_output" 2>/dev/null
22585
- return 0
22599
+ return 20
22586
22600
  fi
22587
22601
  echo ""
22588
22602
  if loki_is_supervised_simple_web; then
@@ -24610,8 +24624,14 @@ except Exception:
24610
24624
  _final_state_file="$(_loki_state_file)"
24611
24625
  _final_status=$(LOKI_STATE_FILE="$_final_state_file" python3 -c "import json, os; print(json.load(open(os.environ['LOKI_STATE_FILE'])).get('status','unknown'))" 2>/dev/null || echo "unknown")
24612
24626
  case "$_final_status" in
24613
- council_approved|council_force_approved|deterministic_gates_passed|completion_promise_fulfilled|force_stopped|paused|interrupted|stopped)
24627
+ council_approved|council_force_approved|deterministic_gates_passed|completion_promise_fulfilled|paused|interrupted|stopped)
24614
24628
  result=0 ;;
24629
+ # force_stopped belongs HERE too, for the same reason. A council
24630
+ # force-stop (stagnation, or a flood of done-signals) means the run
24631
+ # gave up WITHOUT verifying the work -- the code already says so in
24632
+ # its header, its warning, and its refusal to open a PR. Reporting
24633
+ # it as a clean stop made it indistinguishable from success to the
24634
+ # only consumer that matters to automation: the exit code.
24615
24635
  # budget_exceeded belongs HERE, not with the human-controlled stops.
24616
24636
  # It sat in the result=0 arm on the rationale that "a human will
24617
24637
  # resume", which is true of `paused` (a human pressed pause) and
@@ -7,7 +7,7 @@ Modules:
7
7
  control: Session control API (start/stop/pause/resume)
8
8
  """
9
9
 
10
- __version__ = "8.9.0"
10
+ __version__ = "8.9.1"
11
11
 
12
12
  # Expose the control app for easy import
13
13
  try:
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- var __=Object.create;var{getPrototypeOf:f_,defineProperty:rK,getOwnPropertyNames:h_}=Object;var v_=Object.prototype.hasOwnProperty;function g_(Z){return this[Z]}var m_,u_,p_=(Z,X,Q)=>{var Y=Z!=null&&typeof Z==="object";if(Y){var J=X?m_??=new WeakMap:u_??=new WeakMap,z=J.get(Z);if(z)return z}Q=Z!=null?__(f_(Z)):{};let K=X||!Z||!Z.__esModule?rK(Q,"default",{value:Z,enumerable:!0}):Q;for(let $ of h_(Z))if(!v_.call(K,$))rK(K,$,{get:g_.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 d_=(Z)=>Z;function c_(Z,X){this[Z]=d_.bind(null,X)}var l0=(Z,X)=>{for(var Q in X)rK(Z,Q,{get:X[Q],enumerable:!0,configurable:!0,set:c_.bind(X,Q)})};var p=(Z,X)=>()=>(Z&&(X=Z(Z=0)),X);var e0=import.meta.require;var RO={};l0(RO,{lokiDir:()=>j0,homeLokiDir:()=>P4,findRepoRootForVersion:()=>eK,REPO_ROOT:()=>o0});import{resolve as n7,dirname as tK}from"path";import{fileURLToPath as l_}from"url";import{existsSync as GQ}from"fs";import{homedir as i_}from"os";function a_(){let Z=PO;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(PO,"..","..","..")}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(i_(),".loki")}var PO,o0;var G8=p(()=>{PO=tK(l_(import.meta.url));o0=a_()});import{readFileSync as s_}from"fs";import{resolve as n_,dirname as o_}from"path";import{fileURLToPath as r_}from"url";function _3(){if(h5!==null)return h5;let Z="8.9.0";if(typeof Z==="string"&&Z.length>0)return h5=Z,h5;try{let X=o_(r_(import.meta.url)),Q=eK(X);h5=s_(n_(Q,"VERSION"),"utf-8").trim()}catch{h5="unknown"}return h5}var h5=null;var HQ=p(()=>{G8()});var yO={};l0(yO,{runOrThrow:()=>Uf,run:()=>E0,readStreamCapped:()=>UQ,commandVersion:()=>Of,commandExists:()=>X9,ShellError:()=>Z$,MAX_STDOUT_BYTES:()=>SO});async function UQ(Z,X=SO){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 Uf(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=Bf(Z),Q=await E0(["sh","-c",`command -v ${X}`],{timeoutMs:5000});if(Q.exitCode===0)return Q.stdout.trim()||null;return null}function Bf(Z){if(!/^[A-Za-z0-9._/-]+$/.test(Z))throw Error(`refused to shell-escape suspect token: ${Z}`);return Z}async function Of(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 SO=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 Lf?"":Z}var Lf,L0,k8,p0,rW0,i0,H8,Q9,v;var S6=p(()=>{Lf=(process.env.NO_COLOR??"").length>0;L0=o7("\x1B[0;31m"),k8=o7("\x1B[0;32m"),p0=o7("\x1B[1;33m"),rW0=o7("\x1B[0;34m"),i0=o7("\x1B[0;36m"),H8=o7("\x1B[1m"),Q9=o7("\x1B[2m"),v=o7("\x1B[0m")});import{existsSync as Pf}from"fs";async function D7(){if(k4!==void 0)return k4;let Z="/opt/homebrew/bin/python3.12";if(Pf(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 E7(Z,X={}){let Q=await D7();if(!Q)return{stdout:"",stderr:"python3 not found",exitCode:127};return E0([Q,"-c",Z],X)}var k4;var r7=p(()=>{x9()});var eO={};l0(eO,{runStatus:()=>Xh});import{existsSync as Y9,readFileSync as h3,readdirSync as lO,statSync as iO}from"fs";import{resolve as h8,basename as lf}from"path";import{homedir as af}from"os";function aO(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 sO(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=aO(Z),V=aO(X);return` ${H8}${Q}${v} ${K}[${$}]${v} ${Y}% (${W} / ${V})`}async function nf(){if(await X9("jq"))return!0;return process.stdout.write(`${L0}Error: jq is required but not installed.${v}
2
+ var __=Object.create;var{getPrototypeOf:f_,defineProperty:rK,getOwnPropertyNames:h_}=Object;var v_=Object.prototype.hasOwnProperty;function g_(Z){return this[Z]}var m_,u_,p_=(Z,X,Q)=>{var Y=Z!=null&&typeof Z==="object";if(Y){var J=X?m_??=new WeakMap:u_??=new WeakMap,z=J.get(Z);if(z)return z}Q=Z!=null?__(f_(Z)):{};let K=X||!Z||!Z.__esModule?rK(Q,"default",{value:Z,enumerable:!0}):Q;for(let $ of h_(Z))if(!v_.call(K,$))rK(K,$,{get:g_.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 d_=(Z)=>Z;function c_(Z,X){this[Z]=d_.bind(null,X)}var l0=(Z,X)=>{for(var Q in X)rK(Z,Q,{get:X[Q],enumerable:!0,configurable:!0,set:c_.bind(X,Q)})};var p=(Z,X)=>()=>(Z&&(X=Z(Z=0)),X);var e0=import.meta.require;var RO={};l0(RO,{lokiDir:()=>j0,homeLokiDir:()=>P4,findRepoRootForVersion:()=>eK,REPO_ROOT:()=>o0});import{resolve as n7,dirname as tK}from"path";import{fileURLToPath as l_}from"url";import{existsSync as GQ}from"fs";import{homedir as i_}from"os";function a_(){let Z=PO;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(PO,"..","..","..")}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(i_(),".loki")}var PO,o0;var G8=p(()=>{PO=tK(l_(import.meta.url));o0=a_()});import{readFileSync as s_}from"fs";import{resolve as n_,dirname as o_}from"path";import{fileURLToPath as r_}from"url";function _3(){if(h5!==null)return h5;let Z="8.9.1";if(typeof Z==="string"&&Z.length>0)return h5=Z,h5;try{let X=o_(r_(import.meta.url)),Q=eK(X);h5=s_(n_(Q,"VERSION"),"utf-8").trim()}catch{h5="unknown"}return h5}var h5=null;var HQ=p(()=>{G8()});var yO={};l0(yO,{runOrThrow:()=>Uf,run:()=>E0,readStreamCapped:()=>UQ,commandVersion:()=>Of,commandExists:()=>X9,ShellError:()=>Z$,MAX_STDOUT_BYTES:()=>SO});async function UQ(Z,X=SO){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 Uf(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=Bf(Z),Q=await E0(["sh","-c",`command -v ${X}`],{timeoutMs:5000});if(Q.exitCode===0)return Q.stdout.trim()||null;return null}function Bf(Z){if(!/^[A-Za-z0-9._/-]+$/.test(Z))throw Error(`refused to shell-escape suspect token: ${Z}`);return Z}async function Of(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 SO=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 Lf?"":Z}var Lf,L0,k8,p0,rW0,i0,H8,Q9,v;var S6=p(()=>{Lf=(process.env.NO_COLOR??"").length>0;L0=o7("\x1B[0;31m"),k8=o7("\x1B[0;32m"),p0=o7("\x1B[1;33m"),rW0=o7("\x1B[0;34m"),i0=o7("\x1B[0;36m"),H8=o7("\x1B[1m"),Q9=o7("\x1B[2m"),v=o7("\x1B[0m")});import{existsSync as Pf}from"fs";async function D7(){if(k4!==void 0)return k4;let Z="/opt/homebrew/bin/python3.12";if(Pf(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 E7(Z,X={}){let Q=await D7();if(!Q)return{stdout:"",stderr:"python3 not found",exitCode:127};return E0([Q,"-c",Z],X)}var k4;var r7=p(()=>{x9()});var eO={};l0(eO,{runStatus:()=>Xh});import{existsSync as Y9,readFileSync as h3,readdirSync as lO,statSync as iO}from"fs";import{resolve as h8,basename as lf}from"path";import{homedir as af}from"os";function aO(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 sO(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=aO(Z),V=aO(X);return` ${H8}${Q}${v} ${K}[${$}]${v} ${Y}% (${W} / ${V})`}async function nf(){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)
@@ -1117,7 +1117,7 @@ Stop it first with 'loki stop' or wait for it to finish.
1117
1117
  If you believe the lock is stale, remove '${X}' manually.`;throw Z.log(`[runner] ERROR: ${V}`),process.stderr.write(`${V}
1118
1118
  `),Error("session-singleton: another loki runner is active")}Z.log(`[runner] reaping stale ${X} (PID ${K} not alive)`)}}try{wO(X,`${process.pid}
1119
1119
  `),wO(Q,`bun
1120
- `)}catch(K){Z.log(`[runner] WARN: could not write ${X}: ${K.message}`)}let Y=!1,J=()=>{if(Y)return;Y=!0;try{CO(X)}catch{}try{CO(Q)}catch{}},z=(K)=>{J(),process.kill(process.pid,K)};return process.once("exit",J),process.once("SIGINT",()=>z("SIGINT")),process.once("SIGTERM",()=>z("SIGTERM")),J}function TW0(Z){let X=X7(Z.lokiDir,"logs"),Q=X7(X,`iter-output-${Z.iterationCount}-${Date.now()}.log`);try{wO(Q,"")}catch{}return Q}function cK(Z,X){if(process.env.LOKI_DURABLE_STATE!=="1")return X;if(wW0.has(Z))return 0;if(CW0.has(Z))return 20;return X===0?1:X}async function e6(Z,X,Q,Y){if(Z){try{await Z.saveStateForRunner(X,Q,Y)}catch(J){X.log(`[runner] saveState failed: ${J.message}`)}return}throw X.log("[runner] FATAL: src/runner/state.ts not loadable; refusing to write autonomy-state.json with stub schema"),Error("state.ts module is required but not loadable")}function FW0(Z){let X=Z.baseWaitSeconds*Math.pow(2,Z.retryCount);return Math.min(Z.maxWaitSeconds,Math.max(0,X))}async function DW0(Z,X){let Q=X7(Z.lokiDir,"signals","TASK_COMPLETION_CLAIMED");if(s7(Q))return!0;if(!Z.completionPromise)return!1;if(!s7(X))return!1;try{if(VW0(X).size===0)return!1;return(await E0(["grep","-Fq",Z.completionPromise,X])).exitCode===0}catch{return!1}}var HW0,wW0,CW0;var D_=p(()=>{yT();x9();_T();w2();Bw();Lw();HW0={async checkHumanIntervention(Z){try{switch((await Promise.resolve().then(() => (TO(),MO))).checkHumanIntervention({lokiDirOverride:Z.lokiDir,autonomyMode:Z.autonomyMode==="perpetual"?"perpetual":"standard"}).action){case"stop":return 2;case"pause":case"input":return 1;default:return 0}}catch{let X=X7(Z.lokiDir,"STOP"),Q=X7(Z.lokiDir,"PAUSE");if(s7(X))return 2;if(s7(Q))return 1;return 0}},async isBudgetExceeded(){return!1}};wW0=new Set(["council_approved","council_force_approved","deterministic_gates_passed","completion_promise_fulfilled","force_stopped","paused","interrupted","stopped"]),CW0=new Set(["failed","max_iterations_reached","max_retries_exceeded","budget_exceeded","max_duration_reached","policy_blocked","inconclusive_spec_contradiction"])});var x_={};l0(x_,{runStart:()=>kW0,parseStartArgs:()=>k_});function k9(Z,X){let Q=Z.indexOf(X);return Q>=0&&Q+1<Z.length?Z[Q+1]:void 0}function RW0(){let Z=new Set(I_);for(let X of P_.keys())Z.add(X);for(let X of R_)Z.add(X);return Z.add("--help"),Z.add("-h"),Z}function WQ(Z){if(Z===void 0)return;let X=Number(Z);return Number.isFinite(X)&&X>0?X:void 0}function k_(Z,X=(J)=>process.stderr.write(J),Q=(J)=>process.stdout.write(J),Y=(J,z)=>{process.env[J]=z}){if(Z.includes("--help")||Z.includes("-h"))return Q(E_),0;let J=RW0(),z,K=!1;for(let L=0;L<Z.length;L++){let N=Z[L];if(!N)continue;if(K){if(z===void 0)z=N;continue}if(N==="--"){K=!0;continue}if(N.startsWith("-")&&N!=="-"){let j=N.includes("=")?N.slice(0,N.indexOf("=")):N;if(!J.has(j))return X(`start: flag ${j} is not supported by the Bun (LOKI_SDK_LOOP) runner.
1120
+ `)}catch(K){Z.log(`[runner] WARN: could not write ${X}: ${K.message}`)}let Y=!1,J=()=>{if(Y)return;Y=!0;try{CO(X)}catch{}try{CO(Q)}catch{}},z=(K)=>{J(),process.kill(process.pid,K)};return process.once("exit",J),process.once("SIGINT",()=>z("SIGINT")),process.once("SIGTERM",()=>z("SIGTERM")),J}function TW0(Z){let X=X7(Z.lokiDir,"logs"),Q=X7(X,`iter-output-${Z.iterationCount}-${Date.now()}.log`);try{wO(Q,"")}catch{}return Q}function cK(Z,X){if(process.env.LOKI_DURABLE_STATE!=="1")return X;if(wW0.has(Z))return 0;if(CW0.has(Z))return 20;return X===0?1:X}async function e6(Z,X,Q,Y){if(Z){try{await Z.saveStateForRunner(X,Q,Y)}catch(J){X.log(`[runner] saveState failed: ${J.message}`)}return}throw X.log("[runner] FATAL: src/runner/state.ts not loadable; refusing to write autonomy-state.json with stub schema"),Error("state.ts module is required but not loadable")}function FW0(Z){let X=Z.baseWaitSeconds*Math.pow(2,Z.retryCount);return Math.min(Z.maxWaitSeconds,Math.max(0,X))}async function DW0(Z,X){let Q=X7(Z.lokiDir,"signals","TASK_COMPLETION_CLAIMED");if(s7(Q))return!0;if(!Z.completionPromise)return!1;if(!s7(X))return!1;try{if(VW0(X).size===0)return!1;return(await E0(["grep","-Fq",Z.completionPromise,X])).exitCode===0}catch{return!1}}var HW0,wW0,CW0;var D_=p(()=>{yT();x9();_T();w2();Bw();Lw();HW0={async checkHumanIntervention(Z){try{switch((await Promise.resolve().then(() => (TO(),MO))).checkHumanIntervention({lokiDirOverride:Z.lokiDir,autonomyMode:Z.autonomyMode==="perpetual"?"perpetual":"standard"}).action){case"stop":return 2;case"pause":case"input":return 1;default:return 0}}catch{let X=X7(Z.lokiDir,"STOP"),Q=X7(Z.lokiDir,"PAUSE");if(s7(X))return 2;if(s7(Q))return 1;return 0}},async isBudgetExceeded(){return!1}};wW0=new Set(["council_approved","council_force_approved","deterministic_gates_passed","completion_promise_fulfilled","paused","interrupted","stopped"]),CW0=new Set(["failed","force_stopped","max_iterations_reached","max_retries_exceeded","budget_exceeded","max_duration_reached","policy_blocked","inconclusive_spec_contradiction"])});var x_={};l0(x_,{runStart:()=>kW0,parseStartArgs:()=>k_});function k9(Z,X){let Q=Z.indexOf(X);return Q>=0&&Q+1<Z.length?Z[Q+1]:void 0}function RW0(){let Z=new Set(I_);for(let X of P_.keys())Z.add(X);for(let X of R_)Z.add(X);return Z.add("--help"),Z.add("-h"),Z}function WQ(Z){if(Z===void 0)return;let X=Number(Z);return Number.isFinite(X)&&X>0?X:void 0}function k_(Z,X=(J)=>process.stderr.write(J),Q=(J)=>process.stdout.write(J),Y=(J,z)=>{process.env[J]=z}){if(Z.includes("--help")||Z.includes("-h"))return Q(E_),0;let J=RW0(),z,K=!1;for(let L=0;L<Z.length;L++){let N=Z[L];if(!N)continue;if(K){if(z===void 0)z=N;continue}if(N==="--"){K=!0;continue}if(N.startsWith("-")&&N!=="-"){let j=N.includes("=")?N.slice(0,N.indexOf("=")):N;if(!J.has(j))return X(`start: flag ${j} is not supported by the Bun (LOKI_SDK_LOOP) runner.
1121
1121
  `),X(`Orchestration flags (--parallel, --github, --issue, --sandbox, --api, --bg, mirofish) run on the bash route automatically; if you reached this, run without LOKI_SDK_LOOP.
1122
1122
  `),2;let T=P_.get(j);if(T){Y(T[0],T[1]);continue}if(R_.has(j))continue;if(I_.has(j)&&!N.includes("="))L++;continue}if(z===void 0)z=N}let $=k9(Z,"--prd"),W=k9(Z,"--brief"),V=$??W??z;if(!V)return X(`start: a spec source (PRD path, --prd FILE, --brief TEXT, or issue ref) is required
1123
1123
  `),X(E_),2;let q=k9(Z,"--aider-model");if(q)Y("LOKI_AIDER_MODEL",q);let G=k9(Z,"--aider-flags");if(G)Y("LOKI_AIDER_FLAGS",G);let H=k9(Z,"--cline-model");if(H)Y("LOKI_CLINE_MODEL",H);let B=k9(Z,"--provider");if(B&&!EW0.has(B))return X(`start: unknown --provider '${B}'
@@ -1221,4 +1221,4 @@ Set LOKI_LEGACY_BASH=1 to force the bash CLI for every command.
1221
1221
  `),2}case"start":{let{runStart:Y}=await Promise.resolve().then(() => (S_(),x_));return Y(Q)}default:return process.stderr.write(`Unknown command: ${X}
1222
1222
  `),process.stderr.write(y_),2}}dO();process.on("SIGINT",()=>process.exit(130));process.on("SIGTERM",()=>process.exit(143));var yW0=await SW0(Bun.argv.slice(2));process.exit(yW0);
1223
1223
 
1224
- //# debugId=5ADD816677C89EBB64756E2164756E21
1224
+ //# debugId=AB5E24DA8EAB4A3B64756E2164756E21
package/mcp/__init__.py CHANGED
@@ -75,4 +75,4 @@ try:
75
75
  except ImportError:
76
76
  __all__ = ['mcp']
77
77
 
78
- __version__ = '8.9.0'
78
+ __version__ = '8.9.1'
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.9.0",
4
+ "version": "8.9.1",
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.9.0",
5
+ "version": "8.9.1",
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",