loki-mode 7.40.0 → 7.41.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/app-runner.sh +138 -3
- package/autonomy/completion-council.sh +14 -2
- package/autonomy/council-v2.sh +10 -1
- package/autonomy/grill.sh +9 -1
- package/autonomy/lib/claude-flags.sh +321 -0
- package/autonomy/lib/voter-agents.sh +7 -1
- package/autonomy/loki +70 -6
- package/autonomy/run.sh +418 -16
- package/dashboard/__init__.py +1 -1
- package/dashboard/server.py +95 -2
- package/dashboard/static/index.html +58 -32
- package/docs/INSTALLATION.md +15 -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/skills/quality-gates.md +70 -0
package/loki-ts/dist/loki.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
var n6=Object.defineProperty;var a6=($)=>$;function s6($,Q){this[$]=a6.bind(null,Q)}var h=($,Q)=>{for(var Z in Q)n6($,Z,{get:Q[Z],enumerable:!0,configurable:!0,set:s6.bind(Q,Z)})};var L=($,Q)=>()=>($&&(Q=$($=0)),Q);var K$=import.meta.require;var S1={};h(S1,{lokiDir:()=>P,homeLokiDir:()=>o$,findRepoRootForVersion:()=>d$,REPO_ROOT:()=>m});import{resolve as n,dirname as l$}from"path";import{fileURLToPath as t6}from"url";import{existsSync as P$}from"fs";import{homedir as r6}from"os";function i6(){let $=N1;for(let Q=0;Q<6;Q++){if(P$(n($,"VERSION"))&&P$(n($,"autonomy/run.sh")))return $;let Z=l$($);if(Z===$)break;$=Z}return n(N1,"..","..","..")}function d$($){let Q=$;for(let Z=0;Z<6;Z++){if(P$(n(Q,"VERSION"))&&P$(n(Q,"autonomy/run.sh")))return Q;let z=l$(Q);if(z===Q)break;Q=z}return n($,"..","..","..")}function P(){return process.env.LOKI_DIR??n(process.cwd(),".loki")}function o$(){return n(r6(),".loki")}var N1,m;var C=L(()=>{N1=l$(t6(import.meta.url));m=i6()});import{readFileSync as e6}from"fs";import{resolve as $Q,dirname as QQ}from"path";import{fileURLToPath as ZQ}from"url";function F$(){if($$!==null)return $$;let $="7.
|
|
2
|
+
var n6=Object.defineProperty;var a6=($)=>$;function s6($,Q){this[$]=a6.bind(null,Q)}var h=($,Q)=>{for(var Z in Q)n6($,Z,{get:Q[Z],enumerable:!0,configurable:!0,set:s6.bind(Q,Z)})};var L=($,Q)=>()=>($&&(Q=$($=0)),Q);var K$=import.meta.require;var S1={};h(S1,{lokiDir:()=>P,homeLokiDir:()=>o$,findRepoRootForVersion:()=>d$,REPO_ROOT:()=>m});import{resolve as n,dirname as l$}from"path";import{fileURLToPath as t6}from"url";import{existsSync as P$}from"fs";import{homedir as r6}from"os";function i6(){let $=N1;for(let Q=0;Q<6;Q++){if(P$(n($,"VERSION"))&&P$(n($,"autonomy/run.sh")))return $;let Z=l$($);if(Z===$)break;$=Z}return n(N1,"..","..","..")}function d$($){let Q=$;for(let Z=0;Z<6;Z++){if(P$(n(Q,"VERSION"))&&P$(n(Q,"autonomy/run.sh")))return Q;let z=l$(Q);if(z===Q)break;Q=z}return n($,"..","..","..")}function P(){return process.env.LOKI_DIR??n(process.cwd(),".loki")}function o$(){return n(r6(),".loki")}var N1,m;var C=L(()=>{N1=l$(t6(import.meta.url));m=i6()});import{readFileSync as e6}from"fs";import{resolve as $Q,dirname as QQ}from"path";import{fileURLToPath as ZQ}from"url";function F$(){if($$!==null)return $$;let $="7.41.1";if(typeof $==="string"&&$.length>0)return $$=$,$$;try{let Q=QQ(ZQ(import.meta.url)),Z=d$(Q);$$=e6($Q(Z,"VERSION"),"utf-8").trim()}catch{$$="unknown"}return $$}var $$=null;var n$=L(()=>{C()});var C1={};h(C1,{runOrThrow:()=>zQ,run:()=>j,commandVersion:()=>KQ,commandExists:()=>f,ShellError:()=>a$});async function j($,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[W,K,U]=await Promise.all([new Response(Z.stdout).text(),new Response(Z.stderr).text(),Z.exited]);return{stdout:W,stderr:K,exitCode:U}}finally{if(z)clearTimeout(z);if(X)clearTimeout(X)}}async function zQ($,Q={}){let Z=await j($,Q);if(Z.exitCode!==0)throw new a$(`command failed (${Z.exitCode}): ${$.join(" ")}`,Z.exitCode,Z.stdout,Z.stderr);return Z}async function f($){let Q=XQ($),Z=await j(["sh","-c",`command -v ${Q}`],{timeoutMs:5000});if(Z.exitCode===0)return Z.stdout.trim()||null;return null}function XQ($){if(!/^[A-Za-z0-9._/-]+$/.test($))throw Error(`refused to shell-escape suspect token: ${$}`);return $}async function KQ($,Q="--version"){if(!await f($))return null;let z=await j([$,Q],{timeoutMs:5000});if(z.exitCode!==0)return null;return((z.stdout||z.stderr).split(/\r?\n/)[0]?.trim()??"")||null}var a$;var d=L(()=>{a$=class a$ 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 a($){return WQ?"":$}var WQ,T,S,I,TZ,w,R,y,q;var c=L(()=>{WQ=(process.env.NO_COLOR??"").length>0;T=a("\x1B[0;31m"),S=a("\x1B[0;32m"),I=a("\x1B[1;33m"),TZ=a("\x1B[0;34m"),w=a("\x1B[0;36m"),R=a("\x1B[1m"),y=a("\x1B[2m"),q=a("\x1B[0m")});import{existsSync as TQ}from"fs";async function Q$(){if(B$!==void 0)return B$;let $="/opt/homebrew/bin/python3.12";if(TQ($))return B$=$,$;let Q=await f("python3.12");if(Q)return B$=Q,Q;let Z=await f("python3");return B$=Z,Z}async function Z$($,Q={}){let Z=await Q$();if(!Z)return{stdout:"",stderr:"python3 not found",exitCode:127};return j([Z,"-c",$],Q)}var B$;var W$=L(()=>{d()});var t1={};h(t1,{runStatus:()=>gQ});import{existsSync as v,readFileSync as U$,readdirSync as l1,statSync as d1}from"fs";import{resolve as D,basename as xQ}from"path";import{homedir as NQ}from"os";async function DQ(){if(await f("jq"))return!0;return process.stdout.write(`${T}Error: jq is required but not installed.${q}
|
|
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)
|
|
@@ -789,4 +789,4 @@ Set LOKI_LEGACY_BASH=1 to force the bash CLI for every command.
|
|
|
789
789
|
`),2}default:return process.stderr.write(`Unknown command: ${Q}
|
|
790
790
|
`),process.stderr.write(o6),2}}p1();process.on("SIGINT",()=>process.exit(130));process.on("SIGTERM",()=>process.exit(143));var ZZ=await QZ(Bun.argv.slice(2));process.exit(ZZ);
|
|
791
791
|
|
|
792
|
-
//# debugId=
|
|
792
|
+
//# debugId=3FE1A3086D2FDEA764756E2164756E21
|
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.
|
|
4
|
+
"version": "7.41.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 11 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.
|
|
5
|
+
"version": "7.41.1",
|
|
6
6
|
"description": "Autonomous spec-to-product build system with a built-in trust layer (RARV-C closure loop, 11 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",
|
package/skills/quality-gates.md
CHANGED
|
@@ -110,6 +110,34 @@ LOKI_HANDOFF_MD=1 # write a structured handoff doc to
|
|
|
110
110
|
Optional: `LOKI_AUTO_LEARNINGS_EPISODE=1` also writes the learning into
|
|
111
111
|
the Python episodic memory layer via `memory.engine.save_episode`.
|
|
112
112
|
|
|
113
|
+
## Default-on verification-integrity gates (v7.41.1)
|
|
114
|
+
|
|
115
|
+
These three gates are default-ON accuracy guards (opt-out, never opt-in).
|
|
116
|
+
They close "verification theater" gaps where a gate could pass without
|
|
117
|
+
actually verifying. Set each to its off value only to restore the older
|
|
118
|
+
half-blind behavior.
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
LOKI_REVIEW_INCONCLUSIVE_BLOCK=1 # default 1. Treat a code-review round that
|
|
122
|
+
# produced no parseable VERDICT (NO_OUTPUT
|
|
123
|
+
# or zero real verdicts) as a BLOCK instead
|
|
124
|
+
# of a silent pass. Set 0 to disable.
|
|
125
|
+
|
|
126
|
+
LOKI_COMPLETION_TEST_CAPTURE=1 # default 1. The verified-completion gate
|
|
127
|
+
# captures fresh test evidence when
|
|
128
|
+
# test-results.json is absent, instead of
|
|
129
|
+
# passing half-blind. Set 0 to disable.
|
|
130
|
+
|
|
131
|
+
LOKI_AUTO_DOCS=true # default true. Auto-generate the .loki/docs/
|
|
132
|
+
# suite in the loop before the documentation
|
|
133
|
+
# gate scores, instead of nagging the user to
|
|
134
|
+
# run 'loki docs generate'. Set false to disable.
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
The code-review diff also excludes `.loki/` and `.git/` (top-level and
|
|
138
|
+
nested `**/.loki/**`) so reviewers score real source changes, not runtime
|
|
139
|
+
state bloat. This is unconditional, not gated.
|
|
140
|
+
|
|
113
141
|
## Other opt-in environment flags (Release 3)
|
|
114
142
|
|
|
115
143
|
Two more default-off flags added for hybrid search and parallel concurrency.
|
|
@@ -128,6 +156,48 @@ LOKI_CODE_INDEX_AUTOREINDEX=1 # auto incremental re-index of the semantic
|
|
|
128
156
|
# Hybrid Codebase Search)
|
|
129
157
|
```
|
|
130
158
|
|
|
159
|
+
## Output-token compressor (caveman, default-on, Claude-only)
|
|
160
|
+
|
|
161
|
+
[caveman](https://github.com/JuliusBrussee/caveman) is a Claude Code skill that
|
|
162
|
+
instructs the model to compress its OUTPUT tokens only (prose style), keeping all
|
|
163
|
+
technical substance. Loki ACTIVATES it on free-form generation (the main RARV dev
|
|
164
|
+
loop) and HARD-SUPPRESSES it on every parsed-output trust-gate subcall (council
|
|
165
|
+
votes, the code-review `^VERDICT:`, the adversarial probe, the merge-conflict
|
|
166
|
+
resolver, the USAGE.md regen). The suppression is by construction (one shared
|
|
167
|
+
helper sets `CAVEMAN_DEFAULT_MODE=off` on every parsed call site), so compression
|
|
168
|
+
can NEVER flip a verdict or completion decision.
|
|
169
|
+
|
|
170
|
+
The compression level is auto-selected per iteration from the run's RARV tier
|
|
171
|
+
(no user knob): planning iterations (architecture / design) compress at `lite` to
|
|
172
|
+
protect nuance; development / fast / unknown iterations stay at the conservative
|
|
173
|
+
`full`. Inference never picks `ultra` (auto ceiling = `full`); an explicit
|
|
174
|
+
`LOKI_CAVEMAN_LEVEL` overrides the inference entirely, and the never-raise-a-
|
|
175
|
+
user's-lower-global-level guard still applies.
|
|
176
|
+
|
|
177
|
+
Claude-provider-only: on Codex / Cline / Aider the run is byte-identical to
|
|
178
|
+
before. Vendor-less: Loki ships no copy of caveman and bootstraps the pinned
|
|
179
|
+
version on demand (idempotent, cached under `.loki/`). Savings are real but
|
|
180
|
+
bounded (output tokens only); there is no price API, so Loki discloses the
|
|
181
|
+
savings CLASS, never a dollar figure.
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
LOKI_CAVEMAN=0 # opt out (default on). Disables activation; the
|
|
185
|
+
# parsed-subcall suppression still runs (it is a
|
|
186
|
+
# harmless no-op when caveman is absent).
|
|
187
|
+
LOKI_CAVEMAN_LEVEL=full # explicit override (default: auto-inferred from
|
|
188
|
+
# the RARV tier). lite | full | ultra | wenyan |
|
|
189
|
+
# wenyan-lite|full|ultra. Set it to opt out of
|
|
190
|
+
# inference and pin one level.
|
|
191
|
+
LOKI_CAVEMAN_VERSION=1.9.0 # pinned caveman version (upgrade by bumping)
|
|
192
|
+
LOKI_CAVEMAN_AUTO_BOOTSTRAP=0 # disable the on-demand pinned install
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Note: when `LOKI_LEGACY_COMPLETION_MATCH=true` (the legacy prose-grep completion
|
|
196
|
+
path), main-loop activation is automatically disabled so compression cannot
|
|
197
|
+
mangle the prose completion-promise. The default completion path (the
|
|
198
|
+
`loki_complete_task` MCP tool / completion signal file) is immune to compression
|
|
199
|
+
and keeps caveman on.
|
|
200
|
+
|
|
131
201
|
## Verified-completion evidence gate (v7.19.1, default-on)
|
|
132
202
|
|
|
133
203
|
The completion council will not accept a "done" claim without evidence. Before
|