loki-mode 8.3.1 → 8.3.3
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/README.md +1 -1
- package/VERSION +1 -1
- package/autonomy/quickstart.sh +50 -22
- package/dashboard/__init__.py +1 -1
- package/loki-ts/dist/loki.js +2 -2
- package/package.json +1 -1
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@ _The free, source-available autonomous coding agent by [Autonomi](https://www.au
|
|
|
15
15
|
|
|
16
16
|
[Website](https://www.autonomi.dev/) | [Documentation](wiki/Home.md) | [Installation](docs/INSTALLATION.md) | [Changelog](CHANGELOG.md) | [Purple Lab -- deprecated v7.44.0](#purple-lab)
|
|
17
17
|
|
|
18
|
-
**Current release: v8.3.
|
|
18
|
+
**Current release: v8.3.3**
|
|
19
19
|
|
|
20
20
|
</div>
|
|
21
21
|
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
8.3.
|
|
1
|
+
8.3.3
|
package/autonomy/quickstart.sh
CHANGED
|
@@ -174,17 +174,30 @@ _qs_score_templates() {
|
|
|
174
174
|
local tdir; tdir="$(_qs_templates_dir)"
|
|
175
175
|
local brief_lc; brief_lc=$(printf '%s' "$brief" | tr '[:upper:]' '[:lower:]')
|
|
176
176
|
|
|
177
|
-
declare -A scores
|
|
177
|
+
# BASH 3.2 COMPATIBLE. This used `declare -A scores`, a bash 4 associative
|
|
178
|
+
# array. macOS ships bash 3.2.57 as /bin/bash (frozen since 2007, GPLv2,
|
|
179
|
+
# and Apple will not update it), so on the stock shell of the most common
|
|
180
|
+
# developer platform this function printed
|
|
181
|
+
# declare: -A: invalid option
|
|
182
|
+
# and returned ZERO templates. The function body parses fine, which is why
|
|
183
|
+
# sourcing looked healthy and the failure only appeared when CALLED --
|
|
184
|
+
# and the test harness runs under homebrew bash 5, so nothing caught it.
|
|
185
|
+
# `loki quickstart` is the guided first build we point new users at, so
|
|
186
|
+
# this was a first-run failure on Macs.
|
|
187
|
+
#
|
|
188
|
+
# Scores are kept in a flat "name<TAB>score" list instead. Same semantics,
|
|
189
|
+
# portable to 3.2, and the final sort was already doing the ordering work.
|
|
190
|
+
local scores=""
|
|
178
191
|
local name f
|
|
179
192
|
while IFS= read -r f; do
|
|
180
193
|
[ -z "$f" ] && continue
|
|
181
194
|
name=$(basename "$f" .md)
|
|
182
195
|
[ "$name" = "README" ] && continue
|
|
183
|
-
scores
|
|
196
|
+
scores="${scores}${name}\t0\n"
|
|
184
197
|
done < <(ls "$tdir"/*.md 2>/dev/null)
|
|
185
198
|
|
|
186
199
|
# No templates resolvable: fall back to the guaranteed default only.
|
|
187
|
-
if [ "$
|
|
200
|
+
if [ -z "$scores" ]; then
|
|
188
201
|
printf 'simple-todo-app\n'
|
|
189
202
|
return 0
|
|
190
203
|
fi
|
|
@@ -192,37 +205,52 @@ _qs_score_templates() {
|
|
|
192
205
|
local -a tokens
|
|
193
206
|
read -ra tokens <<< "$(printf '%s' "$brief_lc" | tr -cs 'a-z0-9' ' ')"
|
|
194
207
|
|
|
195
|
-
|
|
208
|
+
# Build the additive score deltas, then fold them in once with awk. Doing
|
|
209
|
+
# the arithmetic in awk rather than a bash re-write loop keeps this O(n) and
|
|
210
|
+
# avoids quoting a growing string repeatedly.
|
|
211
|
+
local deltas="" tok kw tmpl wt
|
|
196
212
|
for tok in "${tokens[@]}"; do
|
|
197
213
|
[ -z "$tok" ] && continue
|
|
198
214
|
_qs_is_stopword "$tok" && continue
|
|
199
|
-
|
|
215
|
+
# +2 per template whose hyphenated name contains the token.
|
|
216
|
+
while IFS=$'\t' read -r name _; do
|
|
217
|
+
[ -z "$name" ] && continue
|
|
200
218
|
case "-$name-" in
|
|
201
|
-
*"-$tok-"*)
|
|
219
|
+
*"-$tok-"*) deltas="${deltas}${name}\t2\n";;
|
|
202
220
|
esac
|
|
203
|
-
done
|
|
221
|
+
done < <(printf '%b' "$scores")
|
|
222
|
+
# Curated keyword weights.
|
|
204
223
|
while IFS=: read -r kw tmpl wt; do
|
|
205
224
|
[ -z "$kw" ] && continue
|
|
206
225
|
[ -z "$wt" ] && wt=3
|
|
207
|
-
if [ "$tok" = "$kw" ]
|
|
208
|
-
|
|
226
|
+
if [ "$tok" = "$kw" ]; then
|
|
227
|
+
deltas="${deltas}${tmpl}\t${wt}\n"
|
|
209
228
|
fi
|
|
210
229
|
done < <(_qs_keyword_map)
|
|
211
230
|
done
|
|
212
231
|
|
|
213
|
-
# Guaranteed default baseline.
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
#
|
|
219
|
-
# (
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
232
|
+
# Guaranteed default baseline: simple-todo-app gets +1 and wins exact ties.
|
|
233
|
+
deltas="${deltas}simple-todo-app\t1\n"
|
|
234
|
+
|
|
235
|
+
# Fold: keep only names that are REAL templates (a keyword map entry naming
|
|
236
|
+
# a template that does not exist must not invent one), sum the deltas, then
|
|
237
|
+
# sort by score desc, priority asc (simple-todo-app=0 wins ties), name asc.
|
|
238
|
+
printf '%b' "$scores" > /dev/null # (no-op guard: scores is always non-empty here)
|
|
239
|
+
{
|
|
240
|
+
printf '%b' "$scores"
|
|
241
|
+
printf '%b' "$deltas"
|
|
242
|
+
} | awk -F'\t' '
|
|
243
|
+
NF < 2 { next }
|
|
244
|
+
# First pass marker: names present in the base list are valid templates.
|
|
245
|
+
{ sum[$1] += $2; if (!($1 in seen) && $2 == 0) seen[$1] = 1 }
|
|
246
|
+
END {
|
|
247
|
+
for (n in sum) {
|
|
248
|
+
if (!(n in seen)) continue
|
|
249
|
+
prio = (n == "simple-todo-app") ? 0 : 1
|
|
250
|
+
printf "%d\t%d\t%s\n", sum[n], prio, n
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
' | sort -t"$(printf '\t')" -k1,1nr -k2,2n -k3,3 | head -3 | cut -f3
|
|
226
254
|
}
|
|
227
255
|
|
|
228
256
|
# _qs_template_summary <name>: a short one-line description for the picker.
|
package/dashboard/__init__.py
CHANGED
package/loki-ts/dist/loki.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
var S_=Object.create;var{getPrototypeOf:y_,defineProperty:oK,getOwnPropertyNames:b_}=Object;var __=Object.prototype.hasOwnProperty;function f_(Z){return this[Z]}var h_,v_,g_=(Z,X,Q)=>{var Y=Z!=null&&typeof Z==="object";if(Y){var J=X?h_??=new WeakMap:v_??=new WeakMap,z=J.get(Z);if(z)return z}Q=Z!=null?S_(y_(Z)):{};let K=X||!Z||!Z.__esModule?oK(Q,"default",{value:Z,enumerable:!0}):Q;for(let $ of b_(Z))if(!__.call(K,$))oK(K,$,{get:f_.bind(Z,$),enumerable:!0});if(Y)J.set(Z,K);return K};var VQ=(Z,X)=>()=>(X||Z((X={exports:{}}).exports,X),X.exports);var m_=(Z)=>Z;function u_(Z,X){this[Z]=m_.bind(null,X)}var c0=(Z,X)=>{for(var Q in X)oK(Z,Q,{get:X[Q],enumerable:!0,configurable:!0,set:u_.bind(X,Q)})};var p=(Z,X)=>()=>(Z&&(X=Z(Z=0)),X);var t0=import.meta.require;var IO={};c0(IO,{lokiDir:()=>j0,homeLokiDir:()=>I4,findRepoRootForVersion:()=>tK,REPO_ROOT:()=>Q8});import{resolve as s7,dirname as rK}from"path";import{fileURLToPath as p_}from"url";import{existsSync as qQ}from"fs";import{homedir as d_}from"os";function c_(){let Z=EO;for(let X=0;X<6;X++){if(qQ(s7(Z,"VERSION"))&&qQ(s7(Z,"autonomy/run.sh")))return Z;let Q=rK(Z);if(Q===Z)break;Z=Q}return s7(EO,"..","..","..")}function tK(Z){let X=Z;for(let Q=0;Q<6;Q++){if(qQ(s7(X,"VERSION"))&&qQ(s7(X,"autonomy/run.sh")))return X;let Y=rK(X);if(Y===X)break;X=Y}return s7(Z,"..","..","..")}function j0(){return process.env.LOKI_DIR??s7(process.cwd(),".loki")}function I4(){return s7(d_(),".loki")}var EO,Q8;var G8=p(()=>{EO=rK(p_(import.meta.url));Q8=c_()});import{readFileSync as l_}from"fs";import{resolve as i_,dirname as a_}from"path";import{fileURLToPath as s_}from"url";function _3(){if(f5!==null)return f5;let Z="8.3.
|
|
2
|
+
var S_=Object.create;var{getPrototypeOf:y_,defineProperty:oK,getOwnPropertyNames:b_}=Object;var __=Object.prototype.hasOwnProperty;function f_(Z){return this[Z]}var h_,v_,g_=(Z,X,Q)=>{var Y=Z!=null&&typeof Z==="object";if(Y){var J=X?h_??=new WeakMap:v_??=new WeakMap,z=J.get(Z);if(z)return z}Q=Z!=null?S_(y_(Z)):{};let K=X||!Z||!Z.__esModule?oK(Q,"default",{value:Z,enumerable:!0}):Q;for(let $ of b_(Z))if(!__.call(K,$))oK(K,$,{get:f_.bind(Z,$),enumerable:!0});if(Y)J.set(Z,K);return K};var VQ=(Z,X)=>()=>(X||Z((X={exports:{}}).exports,X),X.exports);var m_=(Z)=>Z;function u_(Z,X){this[Z]=m_.bind(null,X)}var c0=(Z,X)=>{for(var Q in X)oK(Z,Q,{get:X[Q],enumerable:!0,configurable:!0,set:u_.bind(X,Q)})};var p=(Z,X)=>()=>(Z&&(X=Z(Z=0)),X);var t0=import.meta.require;var IO={};c0(IO,{lokiDir:()=>j0,homeLokiDir:()=>I4,findRepoRootForVersion:()=>tK,REPO_ROOT:()=>Q8});import{resolve as s7,dirname as rK}from"path";import{fileURLToPath as p_}from"url";import{existsSync as qQ}from"fs";import{homedir as d_}from"os";function c_(){let Z=EO;for(let X=0;X<6;X++){if(qQ(s7(Z,"VERSION"))&&qQ(s7(Z,"autonomy/run.sh")))return Z;let Q=rK(Z);if(Q===Z)break;Z=Q}return s7(EO,"..","..","..")}function tK(Z){let X=Z;for(let Q=0;Q<6;Q++){if(qQ(s7(X,"VERSION"))&&qQ(s7(X,"autonomy/run.sh")))return X;let Y=rK(X);if(Y===X)break;X=Y}return s7(Z,"..","..","..")}function j0(){return process.env.LOKI_DIR??s7(process.cwd(),".loki")}function I4(){return s7(d_(),".loki")}var EO,Q8;var G8=p(()=>{EO=rK(p_(import.meta.url));Q8=c_()});import{readFileSync as l_}from"fs";import{resolve as i_,dirname as a_}from"path";import{fileURLToPath as s_}from"url";function _3(){if(f5!==null)return f5;let Z="8.3.3";if(typeof Z==="string"&&Z.length>0)return f5=Z,f5;try{let X=a_(s_(import.meta.url)),Q=tK(X);f5=l_(i_(Q,"VERSION"),"utf-8").trim()}catch{f5="unknown"}return f5}var f5=null;var GQ=p(()=>{G8()});var xO={};c0(xO,{runOrThrow:()=>qf,run:()=>E0,readStreamCapped:()=>HQ,commandVersion:()=>Hf,commandExists:()=>X9,ShellError:()=>eK,MAX_STDOUT_BYTES:()=>kO});async function HQ(Z,X=kO){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([HQ(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 qf(Z,X={}){let Q=await E0(Z,X);if(Q.exitCode!==0)throw new eK(`command failed (${Q.exitCode}): ${Z.join(" ")}`,Q.exitCode,Q.stdout,Q.stderr);return Q}async function X9(Z){let X=Gf(Z),Q=await E0(["sh","-c",`command -v ${X}`],{timeoutMs:5000});if(Q.exitCode===0)return Q.stdout.trim()||null;return null}function Gf(Z){if(!/^[A-Za-z0-9._/-]+$/.test(Z))throw Error(`refused to shell-escape suspect token: ${Z}`);return Z}async function Hf(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 kO=16777216,eK;var k9=p(()=>{eK=class eK 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 n7(Z){return Uf?"":Z}var Uf,M0,k8,l0,dW0,a0,H8,Q9,g;var S6=p(()=>{Uf=(process.env.NO_COLOR??"").length>0;M0=n7("\x1B[0;31m"),k8=n7("\x1B[0;32m"),l0=n7("\x1B[1;33m"),dW0=n7("\x1B[0;34m"),a0=n7("\x1B[0;36m"),H8=n7("\x1B[1m"),Q9=n7("\x1B[2m"),g=n7("\x1B[0m")});import{existsSync as Ff}from"fs";async function F7(){if(R4!==void 0)return R4;let Z="/opt/homebrew/bin/python3.12";if(Ff(Z))return R4=Z,Z;let X=await X9("python3.12");if(X)return R4=X,X;let Q=await X9("python3");return R4=Q,Q}async function D7(Z,X={}){let Q=await F7();if(!Q)return{stdout:"",stderr:"python3 not found",exitCode:127};return E0([Q,"-c",Z],X)}var R4;var o7=p(()=>{k9()});var rO={};c0(rO,{runStatus:()=>tf});import{existsSync as Y9,readFileSync as h3,readdirSync as dO,statSync as cO}from"fs";import{resolve as h8,basename as pf}from"path";import{homedir as df}from"os";function lO(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 iO(Z,X,Q){if(X===0)return null;let Y=Math.trunc(Z*100/X),J=Math.trunc(Z*BQ/X);if(J>BQ)J=BQ;let z=BQ-J,K=k8;if(Y>=80)K=M0;else if(Y>=50)K=l0;let $="=".repeat(Math.max(0,J))+" ".repeat(Math.max(0,z)),W=lO(Z),V=lO(X);return` ${H8}${Q}${g} ${K}[${$}]${g} ${Y}% (${W} / ${V})`}async function lf(){if(await X9("jq"))return!0;return process.stdout.write(`${M0}Error: jq is required but not installed.${g}
|
|
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)
|
|
@@ -1206,4 +1206,4 @@ Set LOKI_LEGACY_BASH=1 to force the bash CLI for every command.
|
|
|
1206
1206
|
`),2}case"start":{let{runStart:Y}=await Promise.resolve().then(() => (R_(),P_));return Y(Q)}default:return process.stderr.write(`Unknown command: ${X}
|
|
1207
1207
|
`),process.stderr.write(k_),2}}uO();process.on("SIGINT",()=>process.exit(130));process.on("SIGTERM",()=>process.exit(143));var DW0=await FW0(Bun.argv.slice(2));process.exit(DW0);
|
|
1208
1208
|
|
|
1209
|
-
//# debugId=
|
|
1209
|
+
//# debugId=0387E93FA065D70464756E2164756E21
|
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.3.
|
|
4
|
+
"version": "8.3.3",
|
|
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.3.
|
|
5
|
+
"version": "8.3.3",
|
|
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",
|