loki-mode 7.9.0 → 7.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-to-product system. Triggers on "Loki Mode". Takes a spec (PRD, GitHub issue, OpenAPI doc, etc.) to deployed product via the RARV-C closure loop, with minimal human intervention. Provider-agnostic. Requires --dangerously-skip-permissions flag.
4
4
  ---
5
5
 
6
- # Loki Mode v7.9.0
6
+ # Loki Mode v7.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
 
@@ -381,4 +381,4 @@ See `CHANGELOG.md` entries [7.5.7], [7.5.8], [7.5.13] for the per-fix list and r
381
381
 
382
382
  ---
383
383
 
384
- **v7.9.0 | [Autonomi](https://www.autonomi.dev/) flagship product | ~260 lines core**
384
+ **v7.9.1 | [Autonomi](https://www.autonomi.dev/) flagship product | ~260 lines core**
package/VERSION CHANGED
@@ -1 +1 @@
1
- 7.9.0
1
+ 7.9.1
@@ -143,7 +143,15 @@ def _collect_council(loki_dir):
143
143
  if isinstance(verdicts, list) and verdicts:
144
144
  last = verdicts[-1]
145
145
  if isinstance(last, dict):
146
- final_verdict = str(last.get("verdict") or last.get("decision") or "")
146
+ # completion-council.sh writes verdicts[] entries as
147
+ # {iteration, timestamp, approve, reject, result} where "result" is
148
+ # APPROVED / REJECTED. Older/alt shapes may use verdict/decision.
149
+ final_verdict = str(
150
+ last.get("result")
151
+ or last.get("verdict")
152
+ or last.get("decision")
153
+ or ""
154
+ )
147
155
  else:
148
156
  final_verdict = str(last)
149
157
  threshold = state.get("threshold")
@@ -171,6 +179,29 @@ def _collect_council(loki_dir):
171
179
  "summary": str(rec.get("summary") or rec.get("rationale") or ""),
172
180
  })
173
181
 
182
+ # Fallback: completion-council.sh records the aggregate tally in state.json
183
+ # (approve_votes / reject_votes) and the per-iteration detail under
184
+ # council/votes/iteration-N/, which may not be present as flat *.json here.
185
+ # If we found no per-reviewer files but the council ran, synthesize a single
186
+ # tally row from the aggregate so the proof's council section is populated
187
+ # rather than blank (the council outcome is the central trust signal).
188
+ approve_votes = state.get("approve_votes")
189
+ reject_votes = state.get("reject_votes")
190
+ if not reviewers and (enabled or verdicts or approve_votes or reject_votes):
191
+ a = int(approve_votes or 0)
192
+ r = int(reject_votes or 0)
193
+ if a or r or final_verdict:
194
+ reviewers.append({
195
+ "role": "council (aggregate)",
196
+ "vote": final_verdict or ("APPROVED" if a > r else "REJECTED"),
197
+ "summary": "%d approve / %d reject across council voting" % (a, r),
198
+ })
199
+ # Derive a human threshold ratio when not explicitly recorded.
200
+ if threshold is None and (a or r):
201
+ total = a + r
202
+ if total:
203
+ threshold = "%d/%d" % (a, total)
204
+
174
205
  return {
175
206
  "enabled": enabled,
176
207
  "final_verdict": final_verdict,
@@ -7,7 +7,7 @@ Modules:
7
7
  control: Session control API (start/stop/pause/resume)
8
8
  """
9
9
 
10
- __version__ = "7.9.0"
10
+ __version__ = "7.9.1"
11
11
 
12
12
  # Expose the control app for easy import
13
13
  try:
@@ -2,7 +2,7 @@
2
2
 
3
3
  The flagship product of [Autonomi](https://www.autonomi.dev/). Complete installation instructions for all platforms and use cases.
4
4
 
5
- **Version:** v7.9.0
5
+ **Version:** v7.9.1
6
6
 
7
7
  ---
8
8
 
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- var N7=Object.defineProperty;var k7=(K)=>K;function D7(K,$){this[K]=k7.bind(null,$)}var v=(K,$)=>{for(var Q in $)N7(K,Q,{get:$[Q],enumerable:!0,configurable:!0,set:D7.bind($,Q)})};var E=(K,$)=>()=>(K&&($=K(K=0)),$);var $1=import.meta.require;var z0={};v(z0,{lokiDir:()=>R,homeLokiDir:()=>v1,findRepoRootForVersion:()=>y1,REPO_ROOT:()=>c});import{resolve as p,dirname as b1}from"path";import{fileURLToPath as C7}from"url";import{existsSync as O1}from"fs";import{homedir as h7}from"os";function b7(){let K=Z0;for(let $=0;$<6;$++){if(O1(p(K,"VERSION"))&&O1(p(K,"autonomy/run.sh")))return K;let Q=b1(K);if(Q===K)break;K=Q}return p(Z0,"..","..","..")}function y1(K){let $=K;for(let Q=0;Q<6;Q++){if(O1(p($,"VERSION"))&&O1(p($,"autonomy/run.sh")))return $;let X=b1($);if(X===$)break;$=X}return p(K,"..","..","..")}function R(){return process.env.LOKI_DIR??p(process.cwd(),".loki")}function v1(){return p(h7(),".loki")}var Z0,c;var g=E(()=>{Z0=b1(C7(import.meta.url));c=b7()});import{readFileSync as y7}from"fs";import{resolve as v7,dirname as g7}from"path";import{fileURLToPath as m7}from"url";function T1(){if(r!==null)return r;let K="7.9.0";if(typeof K==="string"&&K.length>0)return r=K,r;try{let $=g7(m7(import.meta.url)),Q=y1($);r=y7(v7(Q,"VERSION"),"utf-8").trim()}catch{r="unknown"}return r}var r=null;var g1=E(()=>{g()});var U0={};v(U0,{runOrThrow:()=>f7,run:()=>N,commandVersion:()=>p7,commandExists:()=>y,ShellError:()=>m1});async function N(K,$={}){let Q=Bun.spawn({cmd:[...K],stdout:"pipe",stderr:"pipe",env:$.env?{...process.env,...$.env}:process.env,cwd:$.cwd}),X,Z;if($.timeoutMs&&$.timeoutMs>0)X=setTimeout(()=>{try{Q.kill("SIGTERM")}catch{}Z=setTimeout(()=>{try{Q.kill("SIGKILL")}catch{}},2000)},$.timeoutMs);try{let[z,H,V]=await Promise.all([new Response(Q.stdout).text(),new Response(Q.stderr).text(),Q.exited]);return{stdout:z,stderr:H,exitCode:V}}finally{if(X)clearTimeout(X);if(Z)clearTimeout(Z)}}async function f7(K,$={}){let Q=await N(K,$);if(Q.exitCode!==0)throw new m1(`command failed (${Q.exitCode}): ${K.join(" ")}`,Q.exitCode,Q.stdout,Q.stderr);return Q}async function y(K){let $=u7(K),Q=await N(["sh","-c",`command -v ${$}`],{timeoutMs:5000});if(Q.exitCode===0)return Q.stdout.trim()||null;return null}function u7(K){if(!/^[A-Za-z0-9._/-]+$/.test(K))throw Error(`refused to shell-escape suspect token: ${K}`);return K}async function p7(K,$="--version"){if(!await y(K))return null;let X=await N([K,$],{timeoutMs:5000});if(X.exitCode!==0)return null;return((X.stdout||X.stderr).split(/\r?\n/)[0]?.trim()??"")||null}var m1;var l=E(()=>{m1=class m1 extends Error{message;exitCode;stdout;stderr;constructor(K,$,Q,X){super(K);this.message=K;this.exitCode=$;this.stdout=Q;this.stderr=X;this.name="ShellError"}}});function d(K){return c7?"":K}var c7,A,h,w,u6,_,k,D,U;var o=E(()=>{c7=(process.env.NO_COLOR??"").length>0;A=d("\x1B[0;31m"),h=d("\x1B[0;32m"),w=d("\x1B[1;33m"),u6=d("\x1B[0;34m"),_=d("\x1B[0;36m"),k=d("\x1B[1m"),D=d("\x1B[2m"),U=d("\x1B[0m")});import{existsSync as e7}from"fs";async function Q1(){if(V1!==void 0)return V1;let K="/opt/homebrew/bin/python3.12";if(e7(K))return V1=K,K;let $=await y("python3.12");if($)return V1=$,$;let Q=await y("python3");return V1=Q,Q}async function t(K,$={}){let Q=await Q1();if(!Q)return{stdout:"",stderr:"python3 not found",exitCode:127};return N([Q,"-c",K],$)}var V1;var W1=E(()=>{l()});var A0={};v(A0,{runStatus:()=>B5});import{existsSync as C,readFileSync as Z1,readdirSync as G0,statSync as B0}from"fs";import{resolve as S,basename as Z5}from"path";import{homedir as z5}from"os";async function U5(){if(await y("jq"))return!0;return process.stdout.write(`${A}Error: jq is required but not installed.${U}
2
+ var N7=Object.defineProperty;var k7=(K)=>K;function D7(K,$){this[K]=k7.bind(null,$)}var v=(K,$)=>{for(var Q in $)N7(K,Q,{get:$[Q],enumerable:!0,configurable:!0,set:D7.bind($,Q)})};var E=(K,$)=>()=>(K&&($=K(K=0)),$);var $1=import.meta.require;var z0={};v(z0,{lokiDir:()=>R,homeLokiDir:()=>v1,findRepoRootForVersion:()=>y1,REPO_ROOT:()=>c});import{resolve as p,dirname as b1}from"path";import{fileURLToPath as C7}from"url";import{existsSync as O1}from"fs";import{homedir as h7}from"os";function b7(){let K=Z0;for(let $=0;$<6;$++){if(O1(p(K,"VERSION"))&&O1(p(K,"autonomy/run.sh")))return K;let Q=b1(K);if(Q===K)break;K=Q}return p(Z0,"..","..","..")}function y1(K){let $=K;for(let Q=0;Q<6;Q++){if(O1(p($,"VERSION"))&&O1(p($,"autonomy/run.sh")))return $;let X=b1($);if(X===$)break;$=X}return p(K,"..","..","..")}function R(){return process.env.LOKI_DIR??p(process.cwd(),".loki")}function v1(){return p(h7(),".loki")}var Z0,c;var g=E(()=>{Z0=b1(C7(import.meta.url));c=b7()});import{readFileSync as y7}from"fs";import{resolve as v7,dirname as g7}from"path";import{fileURLToPath as m7}from"url";function T1(){if(r!==null)return r;let K="7.9.1";if(typeof K==="string"&&K.length>0)return r=K,r;try{let $=g7(m7(import.meta.url)),Q=y1($);r=y7(v7(Q,"VERSION"),"utf-8").trim()}catch{r="unknown"}return r}var r=null;var g1=E(()=>{g()});var U0={};v(U0,{runOrThrow:()=>f7,run:()=>N,commandVersion:()=>p7,commandExists:()=>y,ShellError:()=>m1});async function N(K,$={}){let Q=Bun.spawn({cmd:[...K],stdout:"pipe",stderr:"pipe",env:$.env?{...process.env,...$.env}:process.env,cwd:$.cwd}),X,Z;if($.timeoutMs&&$.timeoutMs>0)X=setTimeout(()=>{try{Q.kill("SIGTERM")}catch{}Z=setTimeout(()=>{try{Q.kill("SIGKILL")}catch{}},2000)},$.timeoutMs);try{let[z,H,V]=await Promise.all([new Response(Q.stdout).text(),new Response(Q.stderr).text(),Q.exited]);return{stdout:z,stderr:H,exitCode:V}}finally{if(X)clearTimeout(X);if(Z)clearTimeout(Z)}}async function f7(K,$={}){let Q=await N(K,$);if(Q.exitCode!==0)throw new m1(`command failed (${Q.exitCode}): ${K.join(" ")}`,Q.exitCode,Q.stdout,Q.stderr);return Q}async function y(K){let $=u7(K),Q=await N(["sh","-c",`command -v ${$}`],{timeoutMs:5000});if(Q.exitCode===0)return Q.stdout.trim()||null;return null}function u7(K){if(!/^[A-Za-z0-9._/-]+$/.test(K))throw Error(`refused to shell-escape suspect token: ${K}`);return K}async function p7(K,$="--version"){if(!await y(K))return null;let X=await N([K,$],{timeoutMs:5000});if(X.exitCode!==0)return null;return((X.stdout||X.stderr).split(/\r?\n/)[0]?.trim()??"")||null}var m1;var l=E(()=>{m1=class m1 extends Error{message;exitCode;stdout;stderr;constructor(K,$,Q,X){super(K);this.message=K;this.exitCode=$;this.stdout=Q;this.stderr=X;this.name="ShellError"}}});function d(K){return c7?"":K}var c7,A,h,w,u6,_,k,D,U;var o=E(()=>{c7=(process.env.NO_COLOR??"").length>0;A=d("\x1B[0;31m"),h=d("\x1B[0;32m"),w=d("\x1B[1;33m"),u6=d("\x1B[0;34m"),_=d("\x1B[0;36m"),k=d("\x1B[1m"),D=d("\x1B[2m"),U=d("\x1B[0m")});import{existsSync as e7}from"fs";async function Q1(){if(V1!==void 0)return V1;let K="/opt/homebrew/bin/python3.12";if(e7(K))return V1=K,K;let $=await y("python3.12");if($)return V1=$,$;let Q=await y("python3");return V1=Q,Q}async function t(K,$={}){let Q=await Q1();if(!Q)return{stdout:"",stderr:"python3 not found",exitCode:127};return N([Q,"-c",K],$)}var V1;var W1=E(()=>{l()});var A0={};v(A0,{runStatus:()=>B5});import{existsSync as C,readFileSync as Z1,readdirSync as G0,statSync as B0}from"fs";import{resolve as S,basename as Z5}from"path";import{homedir as z5}from"os";async function U5(){if(await y("jq"))return!0;return process.stdout.write(`${A}Error: jq is required but not installed.${U}
3
3
  `),process.stdout.write(`Install with:
4
4
  `),process.stdout.write(` brew install jq (macOS)
5
5
  `),process.stdout.write(` apt install jq (Debian/Ubuntu)
@@ -667,4 +667,4 @@ Set LOKI_LEGACY_BASH=1 to force the bash CLI for every command.
667
667
  `),2}default:return process.stderr.write(`Unknown command: ${$}
668
668
  `),process.stderr.write(S7),2}}process.on("SIGINT",()=>process.exit(130));process.on("SIGTERM",()=>process.exit(143));var x6=await w6(Bun.argv.slice(2));process.exit(x6);
669
669
 
670
- //# debugId=9104CD592ACBA35B64756E2164756E21
670
+ //# debugId=7022BA0BF583F56764756E2164756E21
package/mcp/__init__.py CHANGED
@@ -57,4 +57,4 @@ try:
57
57
  except ImportError:
58
58
  __all__ = ['mcp']
59
59
 
60
- __version__ = '7.9.0'
60
+ __version__ = '7.9.1'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "loki-mode",
3
- "version": "7.9.0",
3
+ "version": "7.9.1",
4
4
  "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 11 quality gates. Provider-agnostic (Claude Code, OpenAI Codex, Cline, Aider).",
5
5
  "keywords": [
6
6
  "agent",