loki-mode 7.7.34 → 7.8.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/run.sh +52 -1
- 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/providers/claude.sh +17 -0
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.
|
|
6
|
+
# Loki Mode v7.8.0
|
|
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.
|
|
384
|
+
**v7.8.0 | [Autonomi](https://www.autonomi.dev/) flagship product | ~260 lines core**
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
7.
|
|
1
|
+
7.8.0
|
package/autonomy/run.sh
CHANGED
|
@@ -11222,6 +11222,26 @@ except Exception as exc:
|
|
|
11222
11222
|
&& loki_claude_flag_supported "--append-system-prompt"; then
|
|
11223
11223
|
_loki_claude_argv+=("--append-system-prompt" "$(_loki_autonomy_override_text)")
|
|
11224
11224
|
fi
|
|
11225
|
+
# v7.8.0: explicit settings precedence. Pin the loaded settings sources
|
|
11226
|
+
# so Loki's invocation does not drift if Claude Code changes its implicit
|
|
11227
|
+
# default. Behavior-neutral (these are the standard sources). Gated +
|
|
11228
|
+
# falls back to the implicit default when unsupported. Opt out with
|
|
11229
|
+
# LOKI_SETTING_SOURCES=off.
|
|
11230
|
+
if [ "${LOKI_SETTING_SOURCES:-on}" != "off" ] \
|
|
11231
|
+
&& type loki_claude_flag_supported >/dev/null 2>&1 \
|
|
11232
|
+
&& loki_claude_flag_supported "--setting-sources"; then
|
|
11233
|
+
_loki_claude_argv+=("--setting-sources" "user,project,local")
|
|
11234
|
+
fi
|
|
11235
|
+
# v7.8.0: stream partial assistant deltas so the dashboard renders the
|
|
11236
|
+
# agent's output in real time instead of only at message boundaries. The
|
|
11237
|
+
# stream-json parser below handles the partial event type additively and
|
|
11238
|
+
# ignores it if unrecognized. Gated + fallback. Opt out with
|
|
11239
|
+
# LOKI_PARTIAL_MESSAGES=off.
|
|
11240
|
+
if [ "${LOKI_PARTIAL_MESSAGES:-on}" != "off" ] \
|
|
11241
|
+
&& type loki_claude_flag_supported >/dev/null 2>&1 \
|
|
11242
|
+
&& loki_claude_flag_supported "--include-partial-messages"; then
|
|
11243
|
+
_loki_claude_argv+=("--include-partial-messages")
|
|
11244
|
+
fi
|
|
11225
11245
|
case "${PROVIDER_NAME:-claude}" in
|
|
11226
11246
|
claude)
|
|
11227
11247
|
# Claude: Full features with stream-json output and agent tracking
|
|
@@ -11365,6 +11385,12 @@ def process_stream():
|
|
|
11365
11385
|
init_orchestrator()
|
|
11366
11386
|
print(f"{MAGENTA}[Orchestrator Active]{NC} Main agent started", flush=True)
|
|
11367
11387
|
|
|
11388
|
+
# v7.8.0: track whether the current assistant message text was already
|
|
11389
|
+
# streamed live via --include-partial-messages stream_event deltas, so the
|
|
11390
|
+
# final assistant block does not re-print it. Reset after each assistant
|
|
11391
|
+
# message. Stays False when partial messages are off (no stream_event lines).
|
|
11392
|
+
streamed_text_blocks = False
|
|
11393
|
+
|
|
11368
11394
|
for line in sys.stdin:
|
|
11369
11395
|
line = line.strip()
|
|
11370
11396
|
if not line:
|
|
@@ -11373,6 +11399,29 @@ def process_stream():
|
|
|
11373
11399
|
data = json.loads(line)
|
|
11374
11400
|
msg_type = data.get("type", "")
|
|
11375
11401
|
|
|
11402
|
+
# v7.8.0: --include-partial-messages emits incremental stream_event
|
|
11403
|
+
# records (content_block_delta) BEFORE the final assistant message.
|
|
11404
|
+
# Render the delta text live so the dashboard/terminal shows progress
|
|
11405
|
+
# in real time, and remember that we streamed it so the final
|
|
11406
|
+
# assistant block does not print the same text again (double-print).
|
|
11407
|
+
# Purely additive: if partial messages are off, no stream_event lines
|
|
11408
|
+
# arrive and this branch never fires.
|
|
11409
|
+
if msg_type == "stream_event":
|
|
11410
|
+
ev = data.get("event", {})
|
|
11411
|
+
ev_type = ev.get("type")
|
|
11412
|
+
if ev_type == "message_start":
|
|
11413
|
+
# New message beginning: reset the streamed-text tracker so
|
|
11414
|
+
# the deltas of this message are tracked independently.
|
|
11415
|
+
streamed_text_blocks = False
|
|
11416
|
+
elif ev_type == "content_block_delta":
|
|
11417
|
+
delta = ev.get("delta", {})
|
|
11418
|
+
if delta.get("type") == "text_delta":
|
|
11419
|
+
dtext = delta.get("text", "")
|
|
11420
|
+
if dtext:
|
|
11421
|
+
print(dtext, end="", flush=True)
|
|
11422
|
+
streamed_text_blocks = True
|
|
11423
|
+
continue
|
|
11424
|
+
|
|
11376
11425
|
if msg_type == "assistant":
|
|
11377
11426
|
# Extract and print assistant text
|
|
11378
11427
|
message = data.get("message", {})
|
|
@@ -11380,7 +11429,9 @@ def process_stream():
|
|
|
11380
11429
|
for item in content:
|
|
11381
11430
|
if item.get("type") == "text":
|
|
11382
11431
|
text = item.get("text", "")
|
|
11383
|
-
if text
|
|
11432
|
+
# Skip if we already streamed this text via stream_event
|
|
11433
|
+
# deltas (avoids printing the full message a second time).
|
|
11434
|
+
if text and not streamed_text_blocks:
|
|
11384
11435
|
print(text, end="", flush=True)
|
|
11385
11436
|
elif item.get("type") == "tool_use":
|
|
11386
11437
|
tool = item.get("name", "unknown")
|
package/dashboard/__init__.py
CHANGED
package/docs/INSTALLATION.md
CHANGED
package/loki-ts/dist/loki.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
var _7=Object.defineProperty;var I7=(K)=>K;function P7(K,$){this[K]=I7.bind(null,$)}var v=(K,$)=>{for(var Q in $)_7(K,Q,{get:$[Q],enumerable:!0,configurable:!0,set:P7.bind($,Q)})};var w=(K,$)=>()=>(K&&($=K(K=0)),$);var t=import.meta.require;var e1={};v(e1,{lokiDir:()=>L,homeLokiDir:()=>k1,findRepoRootForVersion:()=>S1,REPO_ROOT:()=>p});import{resolve as u,dirname as N1}from"path";import{fileURLToPath as L7}from"url";import{existsSync as J1}from"fs";import{homedir as R7}from"os";function E7(){let K=i1;for(let $=0;$<6;$++){if(J1(u(K,"VERSION"))&&J1(u(K,"autonomy/run.sh")))return K;let Q=N1(K);if(Q===K)break;K=Q}return u(i1,"..","..","..")}function S1(K){let $=K;for(let Q=0;Q<6;Q++){if(J1(u($,"VERSION"))&&J1(u($,"autonomy/run.sh")))return $;let X=N1($);if(X===$)break;$=X}return u(K,"..","..","..")}function L(){return process.env.LOKI_DIR??u(process.cwd(),".loki")}function k1(){return u(R7(),".loki")}var i1,p;var g=w(()=>{i1=N1(L7(import.meta.url));p=E7()});import{readFileSync as w7}from"fs";import{resolve as x7,dirname as F7}from"path";import{fileURLToPath as N7}from"url";function G1(){if(o!==null)return o;let K="7.
|
|
2
|
+
var _7=Object.defineProperty;var I7=(K)=>K;function P7(K,$){this[K]=I7.bind(null,$)}var v=(K,$)=>{for(var Q in $)_7(K,Q,{get:$[Q],enumerable:!0,configurable:!0,set:P7.bind($,Q)})};var w=(K,$)=>()=>(K&&($=K(K=0)),$);var t=import.meta.require;var e1={};v(e1,{lokiDir:()=>L,homeLokiDir:()=>k1,findRepoRootForVersion:()=>S1,REPO_ROOT:()=>p});import{resolve as u,dirname as N1}from"path";import{fileURLToPath as L7}from"url";import{existsSync as J1}from"fs";import{homedir as R7}from"os";function E7(){let K=i1;for(let $=0;$<6;$++){if(J1(u(K,"VERSION"))&&J1(u(K,"autonomy/run.sh")))return K;let Q=N1(K);if(Q===K)break;K=Q}return u(i1,"..","..","..")}function S1(K){let $=K;for(let Q=0;Q<6;Q++){if(J1(u($,"VERSION"))&&J1(u($,"autonomy/run.sh")))return $;let X=N1($);if(X===$)break;$=X}return u(K,"..","..","..")}function L(){return process.env.LOKI_DIR??u(process.cwd(),".loki")}function k1(){return u(R7(),".loki")}var i1,p;var g=w(()=>{i1=N1(L7(import.meta.url));p=E7()});import{readFileSync as w7}from"fs";import{resolve as x7,dirname as F7}from"path";import{fileURLToPath as N7}from"url";function G1(){if(o!==null)return o;let K="7.8.0";if(typeof K==="string"&&K.length>0)return o=K,o;try{let $=F7(N7(import.meta.url)),Q=S1($);o=w7(x7(Q,"VERSION"),"utf-8").trim()}catch{o="unknown"}return o}var o=null;var C1=w(()=>{g()});var $0={};v($0,{runOrThrow:()=>S7,run:()=>C,commandVersion:()=>C7,commandExists:()=>b,ShellError:()=>D1});async function C(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[W,z,q]=await Promise.all([new Response(Q.stdout).text(),new Response(Q.stderr).text(),Q.exited]);return{stdout:W,stderr:z,exitCode:q}}finally{if(X)clearTimeout(X);if(Z)clearTimeout(Z)}}async function S7(K,$={}){let Q=await C(K,$);if(Q.exitCode!==0)throw new D1(`command failed (${Q.exitCode}): ${K.join(" ")}`,Q.exitCode,Q.stdout,Q.stderr);return Q}async function b(K){let $=k7(K),Q=await C(["sh","-c",`command -v ${$}`],{timeoutMs:5000});if(Q.exitCode===0)return Q.stdout.trim()||null;return null}function k7(K){if(!/^[A-Za-z0-9._/-]+$/.test(K))throw Error(`refused to shell-escape suspect token: ${K}`);return K}async function C7(K,$="--version"){if(!await b(K))return null;let X=await C([K,$],{timeoutMs:5000});if(X.exitCode!==0)return null;return((X.stdout||X.stderr).split(/\r?\n/)[0]?.trim()??"")||null}var D1;var n=w(()=>{D1=class D1 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 c(K){return D7?"":K}var D7,F,y,N,A6,A,D,S,H;var a=w(()=>{D7=(process.env.NO_COLOR??"").length>0;F=c("\x1B[0;31m"),y=c("\x1B[0;32m"),N=c("\x1B[1;33m"),A6=c("\x1B[0;34m"),A=c("\x1B[0;36m"),D=c("\x1B[1m"),S=c("\x1B[2m"),H=c("\x1B[0m")});import{existsSync as c7}from"fs";async function i(){if(Z1!==void 0)return Z1;let K="/opt/homebrew/bin/python3.12";if(c7(K))return Z1=K,K;let $=await b("python3.12");if($)return Z1=$,$;let Q=await b("python3");return Z1=Q,Q}async function s(K,$={}){let Q=await i();if(!Q)return{stdout:"",stderr:"python3 not found",exitCode:127};return C([Q,"-c",K],$)}var Z1;var z1=w(()=>{n()});var G0={};v(G0,{runStatus:()=>X5});import{existsSync as k,readFileSync as K1,readdirSync as W0,statSync as H0}from"fs";import{resolve as R,basename as a7}from"path";import{homedir as s7}from"os";async function t7(){if(await b("jq"))return!0;return process.stdout.write(`${F}Error: jq is required but not installed.${H}
|
|
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)
|
|
@@ -604,4 +604,4 @@ Set LOKI_LEGACY_BASH=1 to force the bash CLI for every command.
|
|
|
604
604
|
`),2}default:return process.stderr.write(`Unknown command: ${$}
|
|
605
605
|
`),process.stderr.write(j7),2}}process.on("SIGINT",()=>process.exit(130));process.on("SIGTERM",()=>process.exit(143));var Z6=await X6(Bun.argv.slice(2));process.exit(Z6);
|
|
606
606
|
|
|
607
|
-
//# debugId=
|
|
607
|
+
//# debugId=289BCE83EBB8514D64756E2164756E21
|
package/mcp/__init__.py
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "loki-mode",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.8.0",
|
|
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",
|
package/providers/claude.sh
CHANGED
|
@@ -216,6 +216,23 @@ _loki_build_claude_auto_flags() {
|
|
|
216
216
|
&& loki_claude_flag_supported "--append-system-prompt"; then
|
|
217
217
|
_LOKI_CLAUDE_AUTO_FLAGS+=("--append-system-prompt" "$(_loki_autonomy_override_text)")
|
|
218
218
|
fi
|
|
219
|
+
|
|
220
|
+
# --setting-sources (v7.8.0): pin the settings precedence so the invocation
|
|
221
|
+
# does not drift with Claude Code's implicit default. Behavior-neutral.
|
|
222
|
+
# Default-on; opt out with LOKI_SETTING_SOURCES=off.
|
|
223
|
+
if [ "${LOKI_SETTING_SOURCES:-on}" != "off" ] \
|
|
224
|
+
&& loki_claude_flag_supported "--setting-sources"; then
|
|
225
|
+
_LOKI_CLAUDE_AUTO_FLAGS+=("--setting-sources" "user,project,local")
|
|
226
|
+
fi
|
|
227
|
+
|
|
228
|
+
# --include-partial-messages (v7.8.0): stream incremental assistant deltas
|
|
229
|
+
# for real-time dashboard/terminal output. The stream-json parser handles
|
|
230
|
+
# the stream_event type additively and de-dupes against the final message.
|
|
231
|
+
# Default-on; opt out with LOKI_PARTIAL_MESSAGES=off.
|
|
232
|
+
if [ "${LOKI_PARTIAL_MESSAGES:-on}" != "off" ] \
|
|
233
|
+
&& loki_claude_flag_supported "--include-partial-messages"; then
|
|
234
|
+
_LOKI_CLAUDE_AUTO_FLAGS+=("--include-partial-messages")
|
|
235
|
+
fi
|
|
219
236
|
}
|
|
220
237
|
|
|
221
238
|
# The system-prompt text that authorizes autonomous operation and resolves
|