loki-mode 8.53.0 → 8.55.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 +2 -2
- package/VERSION +1 -1
- package/autonomy/crash.sh +17 -1
- package/autonomy/lib/proof-verify.py +49 -0
- package/dashboard/__init__.py +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 v8.
|
|
6
|
+
# Loki Mode v8.55.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.
|
|
472
|
+
**v8.55.0 | [Autonomi](https://www.autonomi.dev/) flagship product | ~410 lines core**
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
8.
|
|
1
|
+
8.55.0
|
package/autonomy/crash.sh
CHANGED
|
@@ -213,6 +213,22 @@ loki_show_disclosure_once() {
|
|
|
213
213
|
return 0
|
|
214
214
|
fi
|
|
215
215
|
mkdir -p "$config_root" 2>/dev/null || return 0
|
|
216
|
-
|
|
216
|
+
# A DIRECTORY at $config is a real, reachable state and must not print.
|
|
217
|
+
#
|
|
218
|
+
# LOKI_DIR is the PROJECT .loki when a build is running (not ~/.loki), and
|
|
219
|
+
# a project's .loki/config is legitimately a directory -- so this appended
|
|
220
|
+
# to a directory. `2>/dev/null` cannot suppress it: a redirect failure is
|
|
221
|
+
# reported by the SHELL before the redirection is applied, so every user
|
|
222
|
+
# saw a raw error on stdout at startup:
|
|
223
|
+
#
|
|
224
|
+
# .../autonomy/crash.sh: line 216: .loki/config: Is a directory
|
|
225
|
+
#
|
|
226
|
+
# Observed on a real `loki start` run. The sentinel is back-compat only, so
|
|
227
|
+
# skipping it when the path is not a writable file costs nothing; printing
|
|
228
|
+
# a shell error into the first screen a user sees costs trust.
|
|
229
|
+
if [ -d "$config" ]; then
|
|
230
|
+
return 0
|
|
231
|
+
fi
|
|
232
|
+
{ echo "DISCLOSURE_SHOWN=true" >> "$config"; } 2>/dev/null || true
|
|
217
233
|
return 0
|
|
218
234
|
}
|
|
@@ -589,10 +589,59 @@ def verify_integrity(proof):
|
|
|
589
589
|
"misrepresent the facts" % (recorded_headline, derived)
|
|
590
590
|
)
|
|
591
591
|
|
|
592
|
+
# COST COHERENCE. The receipt is the product's trust artifact, and the
|
|
593
|
+
# verifier checked hashes, diffs, gates and the headline -- but never cost.
|
|
594
|
+
# A receipt could therefore claim ANY cost, $0.00 or $10,000, and
|
|
595
|
+
# `loki proof verify` would still pass it.
|
|
596
|
+
#
|
|
597
|
+
# That was not hypothetical. A real FireLater receipt shipped
|
|
598
|
+
# {"usd": 0.0, ..., "available": true} -- a shareable document asserting the
|
|
599
|
+
# run was FREE, because the collector keyed availability on a record file
|
|
600
|
+
# existing rather than carrying data (fixed v8.52.0). The verifier could not
|
|
601
|
+
# see it.
|
|
602
|
+
#
|
|
603
|
+
# This checks INTERNAL COHERENCE, which is what a verifier can honestly
|
|
604
|
+
# assert: the receipt must not contradict itself. It deliberately does NOT
|
|
605
|
+
# re-price the run -- that would require the token counts and price table at
|
|
606
|
+
# verify time, and a verifier that guesses is worse than one that abstains.
|
|
607
|
+
#
|
|
608
|
+
# The incoherent shapes:
|
|
609
|
+
# available=True with every field zero/None -> claims measurement, has none
|
|
610
|
+
# available=False with a non-zero usd -> claims unmeasured, shows a number
|
|
611
|
+
# usd present but no tokens at all -> a cost from nowhere
|
|
612
|
+
result["cost_coherent"] = None
|
|
613
|
+
_cost = proof.get("cost") if isinstance(proof.get("cost"), dict) else None
|
|
614
|
+
if _cost is not None:
|
|
615
|
+
_avail = _cost.get("available")
|
|
616
|
+
_usd = _cost.get("usd")
|
|
617
|
+
_toks = [
|
|
618
|
+
_cost.get(k) for k in
|
|
619
|
+
("input_tokens", "output_tokens", "cache_read_tokens", "cache_creation_tokens")
|
|
620
|
+
]
|
|
621
|
+
_any_tok = any(isinstance(t, (int, float)) and t > 0 for t in _toks)
|
|
622
|
+
_usd_pos = isinstance(_usd, (int, float)) and _usd > 0
|
|
623
|
+
|
|
624
|
+
_bad = ""
|
|
625
|
+
if _avail is True and not _any_tok and not _usd_pos:
|
|
626
|
+
_bad = ("cost.available is true but every token count and usd is "
|
|
627
|
+
"zero or absent; the receipt claims a measurement it does "
|
|
628
|
+
"not have (an unmeasured run is unknown, not free)")
|
|
629
|
+
elif _avail is False and (_usd_pos or _any_tok):
|
|
630
|
+
_bad = ("cost.available is false but the receipt carries non-zero "
|
|
631
|
+
"cost or token values")
|
|
632
|
+
elif _usd_pos and not _any_tok:
|
|
633
|
+
_bad = ("cost.usd is non-zero but no tokens were recorded; the "
|
|
634
|
+
"cost has no basis in the receipt")
|
|
635
|
+
|
|
636
|
+
result["cost_coherent"] = not _bad
|
|
637
|
+
if _bad and not result["reason"]:
|
|
638
|
+
result["reason"] = _bad
|
|
639
|
+
|
|
592
640
|
result["ok"] = bool(
|
|
593
641
|
result["hash_ok"]
|
|
594
642
|
and result["gpg_ok"] in (True, "n/a")
|
|
595
643
|
and result["headline_consistent"] is not False
|
|
644
|
+
and result["cost_coherent"] is not False
|
|
596
645
|
)
|
|
597
646
|
if result["ok"]:
|
|
598
647
|
result["reason"] = ""
|
package/dashboard/__init__.py
CHANGED
package/loki-ts/dist/loki.js
CHANGED
|
@@ -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.
|
|
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.55.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)
|
|
@@ -1227,4 +1227,4 @@ Set LOKI_LEGACY_BASH=1 to force the bash CLI for every command.
|
|
|
1227
1227
|
`),2}case"start":{let{runStart:Y}=await Promise.resolve().then(() => (b_(),y_));return Y(Q)}default:return process.stderr.write(`Unknown command: ${X}
|
|
1228
1228
|
`),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);
|
|
1229
1229
|
|
|
1230
|
-
//# debugId=
|
|
1230
|
+
//# debugId=16FDE245B508551364756E2164756E21
|
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": "8.
|
|
4
|
+
"version": "8.55.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.
|
|
5
|
+
"version": "8.55.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",
|