loki-mode 7.121.0 → 7.121.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 +2 -2
- package/VERSION +1 -1
- package/autonomy/checklist-verify.py +47 -12
- package/dashboard/__init__.py +1 -1
- package/docs/INSTALLATION.md +1 -1
- package/loki-ts/dist/loki.js +2 -2
- package/mcp/__init__.py +1 -1
- package/package.json +1 -1
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
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 v7.121.
|
|
6
|
+
# Loki Mode v7.121.1
|
|
7
7
|
|
|
8
8
|
**You are an autonomous agent. You make decisions. You do not ask questions. You do not stop.**
|
|
9
9
|
|
|
@@ -408,4 +408,4 @@ See `CHANGELOG.md` entries [7.5.7], [7.5.8], [7.5.13] for the per-fix list and r
|
|
|
408
408
|
|
|
409
409
|
---
|
|
410
410
|
|
|
411
|
-
**v7.121.
|
|
411
|
+
**v7.121.1 | [Autonomi](https://www.autonomi.dev/) flagship product | ~260 lines core**
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
7.121.
|
|
1
|
+
7.121.1
|
|
@@ -142,12 +142,16 @@ def run_check(check: dict, project_dir: str, timeout: int) -> dict:
|
|
|
142
142
|
)
|
|
143
143
|
combined = proc.stdout + proc.stderr
|
|
144
144
|
_low = combined.lower()
|
|
145
|
-
# Trust gate: a tests_pass check REQUIRES that at
|
|
146
|
-
# actually ran
|
|
147
|
-
#
|
|
148
|
-
#
|
|
149
|
-
# verification
|
|
150
|
-
#
|
|
145
|
+
# Trust gate: a tests_pass check REQUIRES POSITIVE PROOF that at
|
|
146
|
+
# least one test actually ran and passed. rc==0 alone is NOT
|
|
147
|
+
# proof: a no-op test script (`echo done`, `exit 0`, `true`, `:`)
|
|
148
|
+
# exits 0 having run ZERO tests -> passing on rc==0 would be a
|
|
149
|
+
# FAKE-GREEN (a required verification green with nothing tested).
|
|
150
|
+
# So we require a runner's "N passed" signal. Absence of that
|
|
151
|
+
# signal on rc==0 is INCONCLUSIVE (None -> pending), never True
|
|
152
|
+
# (fake-green) and never False (that would fake-RED an exotic
|
|
153
|
+
# passing runner). rc!=0 with real failures -> honest False. This
|
|
154
|
+
# is the same inconclusive-never-false moat as grep_codebase.
|
|
151
155
|
no_tests = (
|
|
152
156
|
"no tests found" in _low # jest
|
|
153
157
|
or "no test files found" in _low # vitest
|
|
@@ -155,6 +159,24 @@ def run_check(check: dict, project_dir: str, timeout: int) -> dict:
|
|
|
155
159
|
or "no tests to run" in _low
|
|
156
160
|
or proc.returncode == 5 # pytest: none collected
|
|
157
161
|
)
|
|
162
|
+
# Positive "tests ran and passed" signals across common runners.
|
|
163
|
+
# jest: "Tests: 3 passed" vitest: "Tests 26 passed (26)"
|
|
164
|
+
# pytest:"3 passed in 0.05s" mocha: "3 passing"
|
|
165
|
+
# node:test: "# pass 3" tap: "pass 3"
|
|
166
|
+
# The count MUST be >=1 (`[1-9]\d*`, never a literal 0): a
|
|
167
|
+
# runner can print "0 passed" / "0 passing" (mocha over an
|
|
168
|
+
# empty describe, all-.skip, node:test "# pass 0") on rc=0 with
|
|
169
|
+
# ZERO tests run -- matching a bare `\d+` would re-open the
|
|
170
|
+
# fake-green. A zero count falls through to the inconclusive
|
|
171
|
+
# else -> None (pending), correctly never green.
|
|
172
|
+
_ran_and_passed = bool(
|
|
173
|
+
re.search(r'tests?:\s*[1-9]\d*\s+passed', _low) # jest
|
|
174
|
+
or re.search(r'tests?\s+[1-9]\d*\s+passed', _low) # vitest
|
|
175
|
+
or re.search(r'\b[1-9]\d*\s+passed\b', _low) # pytest/vitest
|
|
176
|
+
or re.search(r'\b[1-9]\d*\s+passing\b', _low) # mocha
|
|
177
|
+
or re.search(r'#\s*pass\s+[1-9]\d*', _low) # node:test
|
|
178
|
+
or re.search(r'\bpass\s+[1-9]\d*\b', _low) # tap
|
|
179
|
+
)
|
|
158
180
|
if no_tests:
|
|
159
181
|
result["passed"] = False
|
|
160
182
|
result["output"] = (
|
|
@@ -162,13 +184,26 @@ def run_check(check: dict, project_dir: str, timeout: int) -> dict:
|
|
|
162
184
|
"(a tests_pass check must run at least one test). "
|
|
163
185
|
"Output: "
|
|
164
186
|
) + combined[:400]
|
|
165
|
-
|
|
166
|
-
#
|
|
167
|
-
#
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
187
|
+
elif proc.returncode != 0:
|
|
188
|
+
# Ran and FAILED -> honest False (blocks). A non-zero exit
|
|
189
|
+
# from a real runner is a genuine negative, not inconclusive.
|
|
190
|
+
result["passed"] = False
|
|
191
|
+
result["output"] = combined[:500]
|
|
192
|
+
elif _ran_and_passed:
|
|
193
|
+
# rc==0 WITH positive "N passed" proof -> True.
|
|
194
|
+
result["passed"] = True
|
|
171
195
|
result["output"] = combined[:500]
|
|
196
|
+
else:
|
|
197
|
+
# rc==0 but NO positive "tests ran" signal (a no-op script,
|
|
198
|
+
# or a runner whose output we do not recognise). We cannot
|
|
199
|
+
# prove tests ran -> INCONCLUSIVE (None -> pending), never a
|
|
200
|
+
# fake-green True and never a fake-RED False.
|
|
201
|
+
result["passed"] = None
|
|
202
|
+
result["output"] = (
|
|
203
|
+
"Test command exited 0 but produced no recognisable "
|
|
204
|
+
"'N passed' signal -- cannot confirm any test ran "
|
|
205
|
+
"(inconclusive, not a pass). Output: "
|
|
206
|
+
) + combined[:350]
|
|
172
207
|
except subprocess.TimeoutExpired:
|
|
173
208
|
result["passed"] = None # timeout = pending (couldn't run)
|
|
174
209
|
result["output"] = f"Timed out after {timeout}s"
|
package/dashboard/__init__.py
CHANGED
package/docs/INSTALLATION.md
CHANGED
|
@@ -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.121.
|
|
5
|
+
**Version:** v7.121.1
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
package/loki-ts/dist/loki.js
CHANGED
|
@@ -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.121.
|
|
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.121.1";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=
|
|
817
|
+
//# debugId=18E173D8ADB8057464756E2164756E21
|
package/mcp/__init__.py
CHANGED
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.121.
|
|
4
|
+
"version": "7.121.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": "7.121.
|
|
5
|
+
"version": "7.121.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",
|