loki-mode 7.99.0 → 7.100.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/README.md +23 -1
- package/SKILL.md +2 -2
- package/VERSION +1 -1
- package/autonomy/loki +131 -0
- package/autonomy/run.sh +28 -1
- package/completions/_loki +1 -0
- package/completions/loki.bash +1 -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/memory/retrieval.py +17 -5
- package/package.json +1 -1
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
- package/skills/fixtures/demo-receipt/README.md +18 -0
- package/skills/fixtures/demo-receipt/proof.json +166 -0
package/README.md
CHANGED
|
@@ -140,11 +140,33 @@ status check in your repository's branch-protection settings.
|
|
|
140
140
|
|
|
141
141
|
```bash
|
|
142
142
|
bun install -g loki-mode # install (npm/brew/Docker also work, see below)
|
|
143
|
+
loki quickstart # one guided command: your first real build
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
`loki quickstart` is the recommended way to start. It asks a few quick questions
|
|
147
|
+
(setup check, one-line idea, template pick, plan review), quotes the real
|
|
148
|
+
cost/time estimate before anything is spent, and then runs the build. Pressing
|
|
149
|
+
Enter through every step builds the sample Todo app.
|
|
150
|
+
|
|
151
|
+
Want a taste with zero key and zero spend first? Run:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
loki demo --offline # replay a real sample Evidence Receipt (no key, no spend)
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
It replays a real past build's Evidence Receipt so you can see Loki's honest
|
|
158
|
+
verdict (VERIFIED / VERIFIED WITH GAPS / NOT VERIFIED) in seconds, with no
|
|
159
|
+
provider, no API key, no spend, and no network. It is a sample (a replay), not a
|
|
160
|
+
verdict on your own code.
|
|
161
|
+
|
|
162
|
+
Prefer the explicit, scriptable path? Scaffold a PRD and run the build yourself:
|
|
163
|
+
|
|
164
|
+
```bash
|
|
143
165
|
loki init my-app --template simple-todo-app # scaffold a starter PRD
|
|
144
166
|
cd my-app && loki start prd.md # autonomous build from the spec
|
|
145
167
|
```
|
|
146
168
|
|
|
147
|
-
|
|
169
|
+
One thing to know first: Loki drives a separate coding-agent CLI (Claude Code is the recommended one) and needs it plus a couple of common tools on your PATH. Run `loki doctor` any time and it tells you exactly what is present and what is missing, with a copy-pasteable install command for each gap.
|
|
148
170
|
|
|
149
171
|
```bash
|
|
150
172
|
loki doctor # check your setup before the first build
|
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.
|
|
6
|
+
# Loki Mode v7.100.0
|
|
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.
|
|
411
|
+
**v7.100.0 | [Autonomi](https://www.autonomi.dev/) flagship product | ~260 lines core**
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
7.
|
|
1
|
+
7.100.0
|
package/autonomy/loki
CHANGED
|
@@ -11380,15 +11380,23 @@ cmd_demo() {
|
|
|
11380
11380
|
echo "runs 'loki start' to build it end-to-end. Shows a summary when done"
|
|
11381
11381
|
echo "and offers to open the result in a browser."
|
|
11382
11382
|
echo ""
|
|
11383
|
+
echo "With --offline, instead replays a bundled real Evidence Receipt so"
|
|
11384
|
+
echo "you can see what Loki produces with no provider, no API key, no"
|
|
11385
|
+
echo "spend, and no network. This is a sample (a replay of a past build),"
|
|
11386
|
+
echo "not a verdict on your own code."
|
|
11387
|
+
echo ""
|
|
11383
11388
|
echo "Usage: loki demo [options]"
|
|
11384
11389
|
echo ""
|
|
11385
11390
|
echo "Options:"
|
|
11391
|
+
echo " --offline Replay a bundled sample receipt (no key, no spend)"
|
|
11386
11392
|
echo " --dir PATH Use a specific directory instead of a temp dir"
|
|
11387
11393
|
echo " --keep Keep the temp directory on exit (default: kept)"
|
|
11388
11394
|
echo " --provider P AI provider to use (default: claude)"
|
|
11389
11395
|
echo " --dry-run Show what would happen without running"
|
|
11390
11396
|
echo ""
|
|
11391
11397
|
echo "Examples:"
|
|
11398
|
+
echo " loki demo --offline # Replay a sample receipt (no spend)"
|
|
11399
|
+
echo " loki tour # Same as 'loki demo --offline'"
|
|
11392
11400
|
echo " loki demo # Build todo app in temp dir"
|
|
11393
11401
|
echo " loki demo --dir ~/demo-project # Build in specific directory"
|
|
11394
11402
|
echo " loki demo --provider codex # Use Codex instead of Claude"
|
|
@@ -11411,6 +11419,7 @@ cmd_demo() {
|
|
|
11411
11419
|
local demo_dir=""
|
|
11412
11420
|
local provider=""
|
|
11413
11421
|
local dry_run=false
|
|
11422
|
+
local offline=false
|
|
11414
11423
|
local start_args=()
|
|
11415
11424
|
# v7.29.0 (feature #4): demo now shows the FORCED-simple cost estimate
|
|
11416
11425
|
# before spending and asks for confirmation. --yes / LOKI_ASSUME_YES skip
|
|
@@ -11459,6 +11468,10 @@ cmd_demo() {
|
|
|
11459
11468
|
dry_run=true
|
|
11460
11469
|
shift
|
|
11461
11470
|
;;
|
|
11471
|
+
--offline|--tour)
|
|
11472
|
+
offline=true
|
|
11473
|
+
shift
|
|
11474
|
+
;;
|
|
11462
11475
|
*)
|
|
11463
11476
|
echo -e "${RED}Unknown option: $1${NC}"
|
|
11464
11477
|
echo "Run 'loki demo --help' for usage."
|
|
@@ -11467,6 +11480,60 @@ cmd_demo() {
|
|
|
11467
11480
|
esac
|
|
11468
11481
|
done
|
|
11469
11482
|
|
|
11483
|
+
# Offline taste path (feature #2): replay a bundled REAL Evidence Receipt
|
|
11484
|
+
# with NO provider, NO key, NO spend, NO network. This is the zero-friction
|
|
11485
|
+
# path a newcomer can run before installing or authenticating anything, so
|
|
11486
|
+
# it MUST run before (and bypass) the provider_offer_gate below. It never
|
|
11487
|
+
# builds, never calls cmd_start, and returns in well under 10s.
|
|
11488
|
+
#
|
|
11489
|
+
# Fake-green guardrail: the headline shown is the bundled receipt's REAL
|
|
11490
|
+
# honest headline (rendered by the same render_evidence_receipt_md the PR
|
|
11491
|
+
# path uses, which is never green unless genuinely VERIFIED). It is framed
|
|
11492
|
+
# as a SAMPLE/replay -- never presented as a verdict on the user's code.
|
|
11493
|
+
if [ "$offline" = true ]; then
|
|
11494
|
+
local sample_proof="$SKILL_DIR/skills/fixtures/demo-receipt/proof.json"
|
|
11495
|
+
if [ ! -f "$sample_proof" ]; then
|
|
11496
|
+
echo -e "${RED}Error: bundled sample receipt not found.${NC}" >&2
|
|
11497
|
+
echo "Expected at: $sample_proof" >&2
|
|
11498
|
+
return 1
|
|
11499
|
+
fi
|
|
11500
|
+
if ! declare -f render_evidence_receipt_md >/dev/null 2>&1; then
|
|
11501
|
+
echo -e "${RED}Error: receipt renderer unavailable.${NC}" >&2
|
|
11502
|
+
echo "Expected autonomy/lib/proof-pr.sh to be sourced." >&2
|
|
11503
|
+
return 1
|
|
11504
|
+
fi
|
|
11505
|
+
|
|
11506
|
+
echo -e "${BOLD}Loki Mode v$version - Sample Receipt (offline replay)${NC}"
|
|
11507
|
+
echo ""
|
|
11508
|
+
echo -e "${YELLOW}This is a SAMPLE: a replay of a real past build, not a"
|
|
11509
|
+
echo -e "verdict on your code. No provider, no API key, no spend, no"
|
|
11510
|
+
echo -e "network were used to show it.${NC}"
|
|
11511
|
+
echo ""
|
|
11512
|
+
echo -e "${DIM}It is what Loki produces after a build: an Evidence Receipt"
|
|
11513
|
+
echo -e "with an honest headline you can recompute yourself.${NC}"
|
|
11514
|
+
echo ""
|
|
11515
|
+
|
|
11516
|
+
# Print-only renderer; always returns 0. The headline label inside is
|
|
11517
|
+
# the receipt's genuine honesty.headline.
|
|
11518
|
+
render_evidence_receipt_md "$sample_proof" "" ""
|
|
11519
|
+
|
|
11520
|
+
# The receipt prints a "verify it yourself" command. For a real build
|
|
11521
|
+
# that command works against .loki/proofs/. This bundled sample is for
|
|
11522
|
+
# display only (no local proof store entry, hash neutralized), so make
|
|
11523
|
+
# that explicit rather than let a newcomer run a command that fails.
|
|
11524
|
+
echo ""
|
|
11525
|
+
echo -e "${DIM}The 'verify it yourself' command above is what you run against the"
|
|
11526
|
+
echo -e "real builds you create (their proofs live in .loki/proofs/). This"
|
|
11527
|
+
echo -e "bundled sample is for display only.${NC}"
|
|
11528
|
+
|
|
11529
|
+
echo ""
|
|
11530
|
+
echo -e "${DIM}---------------------------------------${NC}"
|
|
11531
|
+
echo -e "${BOLD}That was a sample. Build your own:${NC}"
|
|
11532
|
+
echo -e " ${CYAN}loki quickstart${NC} # one guided command, your first real build"
|
|
11533
|
+
echo -e " ${CYAN}loki demo${NC} # build a bundled sample app for real"
|
|
11534
|
+
return 0
|
|
11535
|
+
fi
|
|
11536
|
+
|
|
11470
11537
|
# v7.29.0: provider pre-flight gate (skipped for --dry-run, which never
|
|
11471
11538
|
# spends). On a TTY, offer to install; on non-TTY/CI, print honest manual
|
|
11472
11539
|
# instructions and exit 2 before any spend. Detect-first, so the nested
|
|
@@ -16450,6 +16517,17 @@ main() {
|
|
|
16450
16517
|
demo)
|
|
16451
16518
|
cmd_demo "$@"
|
|
16452
16519
|
;;
|
|
16520
|
+
tour)
|
|
16521
|
+
# Zero-key/zero-spend taste path: an alias for 'demo --offline' that
|
|
16522
|
+
# replays a bundled real Evidence Receipt. --help routes straight to
|
|
16523
|
+
# the demo help (which documents --offline / tour); otherwise inject
|
|
16524
|
+
# --offline ahead of any user args.
|
|
16525
|
+
if [ "${1:-}" = "--help" ] || [ "${1:-}" = "-h" ]; then
|
|
16526
|
+
cmd_demo --help
|
|
16527
|
+
else
|
|
16528
|
+
cmd_demo --offline "$@"
|
|
16529
|
+
fi
|
|
16530
|
+
;;
|
|
16453
16531
|
quickstart)
|
|
16454
16532
|
cmd_quickstart "$@"
|
|
16455
16533
|
;;
|
|
@@ -31218,6 +31296,59 @@ PYEOF
|
|
|
31218
31296
|
echo "Ready to post:"
|
|
31219
31297
|
echo " ${hook}"
|
|
31220
31298
|
fi
|
|
31299
|
+
|
|
31300
|
+
# Copy-paste "Verified by Loki" markdown badge (word-of-mouth
|
|
31301
|
+
# loop). The badge color + message derive ONLY from the receipt's
|
|
31302
|
+
# honest headline (honesty.headline), which proof-generator
|
|
31303
|
+
# computes deterministically from real facts and which is
|
|
31304
|
+
# impossible to forge from an LLM opinion. We exact-match the
|
|
31305
|
+
# three headline strings:
|
|
31306
|
+
# VERIFIED -> brightgreen "verified"
|
|
31307
|
+
# VERIFIED WITH GAPS -> orange "verified with gaps"
|
|
31308
|
+
# NOT VERIFIED -> red "not verified"
|
|
31309
|
+
# Anything else (missing/null/legacy proof) OMITS the badge: we
|
|
31310
|
+
# never paint a non-VERIFIED receipt green, and we do not force a
|
|
31311
|
+
# fine old-format proof red. We deliberately do NOT fall back to
|
|
31312
|
+
# council.final_verdict here -- that is an LLM verdict and the
|
|
31313
|
+
# exact fake-green path the headline exists to override.
|
|
31314
|
+
# The badge links to the gist we just published (no new egress).
|
|
31315
|
+
# shields.io static/v1 query endpoint avoids structural hyphens.
|
|
31316
|
+
local badge
|
|
31317
|
+
badge=$(LOKI_PROOF_JSON="$pj" LOKI_GIST_URL="$LOKI_LAST_GIST_URL" python3 - <<'PYEOF' 2>/dev/null || true
|
|
31318
|
+
import json, os
|
|
31319
|
+
from urllib.parse import quote
|
|
31320
|
+
try:
|
|
31321
|
+
d = json.load(open(os.environ["LOKI_PROOF_JSON"]))
|
|
31322
|
+
except Exception:
|
|
31323
|
+
d = {}
|
|
31324
|
+
headline = (d.get("honesty") or {}).get("headline")
|
|
31325
|
+
# Exact-match ONLY. council.final_verdict is intentionally NOT consulted: it is
|
|
31326
|
+
# an LLM opinion, the precise fake-green source the deterministic headline
|
|
31327
|
+
# overrides. Unmapped headline -> no entry -> badge omitted.
|
|
31328
|
+
mapping = {
|
|
31329
|
+
"VERIFIED": ("verified", "brightgreen"),
|
|
31330
|
+
"VERIFIED WITH GAPS": ("verified with gaps", "orange"),
|
|
31331
|
+
"NOT VERIFIED": ("not verified", "red"),
|
|
31332
|
+
}
|
|
31333
|
+
entry = mapping.get(headline)
|
|
31334
|
+
url = os.environ.get("LOKI_GIST_URL", "").strip()
|
|
31335
|
+
# Omit the badge for any unmapped headline (never green, never forced red),
|
|
31336
|
+
# and when we have no link target to point at.
|
|
31337
|
+
if entry and url:
|
|
31338
|
+
message, color = entry
|
|
31339
|
+
badge_img = (
|
|
31340
|
+
"https://img.shields.io/static/v1?label=Loki"
|
|
31341
|
+
"&message=" + quote(message)
|
|
31342
|
+
+ "&color=" + color
|
|
31343
|
+
)
|
|
31344
|
+
print("[]({url})".format(msg=message, img=badge_img, url=url))
|
|
31345
|
+
PYEOF
|
|
31346
|
+
)
|
|
31347
|
+
if [ -n "$badge" ]; then
|
|
31348
|
+
echo ""
|
|
31349
|
+
echo "Markdown badge (paste into a README or PR):"
|
|
31350
|
+
echo " ${badge}"
|
|
31351
|
+
fi
|
|
31221
31352
|
fi
|
|
31222
31353
|
exit 0
|
|
31223
31354
|
;;
|
package/autonomy/run.sh
CHANGED
|
@@ -11246,6 +11246,7 @@ start_dashboard() {
|
|
|
11246
11246
|
local original_port=$DASHBOARD_PORT
|
|
11247
11247
|
local max_attempts=10
|
|
11248
11248
|
local attempt=0
|
|
11249
|
+
local DASHBOARD_REUSED=0
|
|
11249
11250
|
|
|
11250
11251
|
while lsof -i :$DASHBOARD_PORT &>/dev/null && [ $attempt -lt $max_attempts ]; do
|
|
11251
11252
|
# Check if it's our own dashboard
|
|
@@ -11254,7 +11255,24 @@ start_dashboard() {
|
|
|
11254
11255
|
# Only kill if it's a Python/uvicorn dashboard process
|
|
11255
11256
|
local proc_cmd=$(ps -p "$existing_pid" -o comm= 2>/dev/null || true)
|
|
11256
11257
|
if [[ "$proc_cmd" == *python* ]] || [[ "$proc_cmd" == *uvicorn* ]]; then
|
|
11257
|
-
|
|
11258
|
+
# Never kill a HEALTHY dashboard already serving here: it is almost
|
|
11259
|
+
# always the user's own live dashboard (open in their browser), and
|
|
11260
|
+
# killing it on `loki start` drops their session mid-use. A healthy
|
|
11261
|
+
# server is reusable by this build too, so probe /api/status and, if
|
|
11262
|
+
# it answers 200, REUSE it (skip starting our own). Only kill a
|
|
11263
|
+
# dashboard process that is NOT serving (a genuinely stuck/dead one).
|
|
11264
|
+
# Opt out with LOKI_DASHBOARD_FORCE_RECLAIM=1.
|
|
11265
|
+
local _dash_alive=""
|
|
11266
|
+
if [ "${LOKI_DASHBOARD_FORCE_RECLAIM:-}" != "1" ] && command -v curl >/dev/null 2>&1; then
|
|
11267
|
+
_dash_alive=$(curl -s -o /dev/null -w '%{http_code}' --max-time 1 \
|
|
11268
|
+
"http://127.0.0.1:${DASHBOARD_PORT}/api/status" 2>/dev/null || true)
|
|
11269
|
+
fi
|
|
11270
|
+
if [ "$_dash_alive" = "200" ]; then
|
|
11271
|
+
log_info "Reusing the healthy dashboard already serving on port $DASHBOARD_PORT (not killing it)."
|
|
11272
|
+
DASHBOARD_REUSED=1
|
|
11273
|
+
break
|
|
11274
|
+
fi
|
|
11275
|
+
log_step "Killing stuck dashboard on port $DASHBOARD_PORT (PID: $existing_pid, not serving)..."
|
|
11258
11276
|
kill "$existing_pid" 2>/dev/null || true
|
|
11259
11277
|
sleep 1
|
|
11260
11278
|
break
|
|
@@ -11276,6 +11294,15 @@ start_dashboard() {
|
|
|
11276
11294
|
return 1
|
|
11277
11295
|
fi
|
|
11278
11296
|
|
|
11297
|
+
# If we found a HEALTHY dashboard already serving on the port, reuse it: do
|
|
11298
|
+
# NOT launch a second server (that would fight for the port / kill the user's
|
|
11299
|
+
# live one). The existing server already serves this project's state.
|
|
11300
|
+
if [ "${DASHBOARD_REUSED:-0}" = "1" ]; then
|
|
11301
|
+
export LOKI_DASHBOARD_PORT="$DASHBOARD_PORT"
|
|
11302
|
+
log_info "Dashboard already live on port $DASHBOARD_PORT; reusing it."
|
|
11303
|
+
return 0
|
|
11304
|
+
fi
|
|
11305
|
+
|
|
11279
11306
|
# Start FastAPI dashboard server (unified UI + API)
|
|
11280
11307
|
log_step "Starting unified dashboard server..."
|
|
11281
11308
|
local log_file=".loki/dashboard/logs/dashboard.log"
|
package/completions/_loki
CHANGED
|
@@ -125,6 +125,7 @@ function _loki_commands {
|
|
|
125
125
|
'quickstart:Guided first build from your idea'
|
|
126
126
|
'monitor:Monitor Docker Compose services with auto-fix'
|
|
127
127
|
'demo:Interactive 60-second demo'
|
|
128
|
+
'tour:Offline sample receipt replay (no key, no spend)'
|
|
128
129
|
'init:Interactive PRD builder'
|
|
129
130
|
'stop:Stop execution'
|
|
130
131
|
'pause:Pause execution'
|
package/completions/loki.bash
CHANGED
|
@@ -5,7 +5,7 @@ _loki_completion() {
|
|
|
5
5
|
_init_completion || return
|
|
6
6
|
|
|
7
7
|
# Main subcommands (must match autonomy/loki main case statement)
|
|
8
|
-
local main_commands="start quick monitor demo init stop pause resume status next ship dashboard web serve api sandbox notify import github issue config provider reset memory compound checkpoint council dogfood projects enterprise secrets doctor watchdog audit metrics syslog onboard share proof explain plan report cost kpis stats test ci watch telemetry agent context ctx code run export review optimize heal modernize migrate cluster worktree wt trigger failover remote deploy docker mcp magic assets analyze compliance crash open otel preview quickstart rc rollback self-update sentrux setup-skill spec state template trust trust-metrics ultracode update verify voice why wiki bench cleanup logs grill docs cp version completions help"
|
|
8
|
+
local main_commands="start quick monitor demo tour init stop pause resume status next ship dashboard web serve api sandbox notify import github issue config provider reset memory compound checkpoint council dogfood projects enterprise secrets doctor watchdog audit metrics syslog onboard share proof explain plan report cost kpis stats test ci watch telemetry agent context ctx code run export review optimize heal modernize migrate cluster worktree wt trigger failover remote deploy docker mcp magic assets analyze compliance crash open otel preview quickstart rc rollback self-update sentrux setup-skill spec state template trust trust-metrics ultracode update verify voice why wiki bench cleanup logs grill docs cp version completions help"
|
|
9
9
|
|
|
10
10
|
# 1. If we are on the first argument (subcommand)
|
|
11
11
|
if [[ $cword -eq 1 ]]; then
|
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.
|
|
5
|
+
**Version:** v7.100.0
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
package/loki-ts/dist/loki.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
var z8=Object.defineProperty;var X8=($)=>$;function K8($,Q){this[$]=X8.bind(null,Q)}var b=($,Q)=>{for(var Z in Q)z8($,Z,{get:Q[Z],enumerable:!0,configurable:!0,set:K8.bind(Q,Z)})};var L=($,Q)=>()=>($&&(Q=$($=0)),Q);var J$=import.meta.require;var y1={};b(y1,{lokiDir:()=>P,homeLokiDir:()=>T$,findRepoRootForVersion:()=>e$,REPO_ROOT:()=>h});import{resolve as t,dirname as i$}from"path";import{fileURLToPath as q8}from"url";import{existsSync as E$}from"fs";import{homedir as J8}from"os";function V8(){let $=h1;for(let Q=0;Q<6;Q++){if(E$(t($,"VERSION"))&&E$(t($,"autonomy/run.sh")))return $;let Z=i$($);if(Z===$)break;$=Z}return t(h1,"..","..","..")}function e$($){let Q=$;for(let Z=0;Z<6;Z++){if(E$(t(Q,"VERSION"))&&E$(t(Q,"autonomy/run.sh")))return Q;let z=i$(Q);if(z===Q)break;Q=z}return t($,"..","..","..")}function P(){return process.env.LOKI_DIR??t(process.cwd(),".loki")}function T$(){return t(J8(),".loki")}var h1,h;var C=L(()=>{h1=i$(q8(import.meta.url));h=V8()});import{readFileSync as W8}from"fs";import{resolve as U8,dirname as H8}from"path";import{fileURLToPath as G8}from"url";function N$(){if(Q$!==null)return Q$;let $="7.
|
|
2
|
+
var z8=Object.defineProperty;var X8=($)=>$;function K8($,Q){this[$]=X8.bind(null,Q)}var b=($,Q)=>{for(var Z in Q)z8($,Z,{get:Q[Z],enumerable:!0,configurable:!0,set:K8.bind(Q,Z)})};var L=($,Q)=>()=>($&&(Q=$($=0)),Q);var J$=import.meta.require;var y1={};b(y1,{lokiDir:()=>P,homeLokiDir:()=>T$,findRepoRootForVersion:()=>e$,REPO_ROOT:()=>h});import{resolve as t,dirname as i$}from"path";import{fileURLToPath as q8}from"url";import{existsSync as E$}from"fs";import{homedir as J8}from"os";function V8(){let $=h1;for(let Q=0;Q<6;Q++){if(E$(t($,"VERSION"))&&E$(t($,"autonomy/run.sh")))return $;let Z=i$($);if(Z===$)break;$=Z}return t(h1,"..","..","..")}function e$($){let Q=$;for(let Z=0;Z<6;Z++){if(E$(t(Q,"VERSION"))&&E$(t(Q,"autonomy/run.sh")))return Q;let z=i$(Q);if(z===Q)break;Q=z}return t($,"..","..","..")}function P(){return process.env.LOKI_DIR??t(process.cwd(),".loki")}function T$(){return t(J8(),".loki")}var h1,h;var C=L(()=>{h1=i$(q8(import.meta.url));h=V8()});import{readFileSync as W8}from"fs";import{resolve as U8,dirname as H8}from"path";import{fileURLToPath as G8}from"url";function N$(){if(Q$!==null)return Q$;let $="7.100.0";if(typeof $==="string"&&$.length>0)return Q$=$,Q$;try{let Q=H8(G8(import.meta.url)),Z=e$(Q);Q$=W8(U8(Z,"VERSION"),"utf-8").trim()}catch{Q$="unknown"}return Q$}var Q$=null;var $1=L(()=>{C()});var u1={};b(u1,{runOrThrow:()=>x8,run:()=>F,readStreamCapped:()=>f1,commandVersion:()=>N8,commandExists:()=>f,ShellError:()=>Q1,MAX_STDOUT_BYTES:()=>m1});async function f1($,Q=m1){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 F($,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([f1(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 x8($,Q={}){let Z=await F($,Q);if(Z.exitCode!==0)throw new Q1(`command failed (${Z.exitCode}): ${$.join(" ")}`,Z.exitCode,Z.stdout,Z.stderr);return Z}async function f($){let Q=E8($),Z=await F(["sh","-c",`command -v ${Q}`],{timeoutMs:5000});if(Z.exitCode===0)return Z.stdout.trim()||null;return null}function E8($){if(!/^[A-Za-z0-9._/-]+$/.test($))throw Error(`refused to shell-escape suspect token: ${$}`);return $}async function N8($,Q="--version"){if(!await f($))return null;let z=await F([$,Q],{timeoutMs:5000});if(z.exitCode!==0)return null;return((z.stdout||z.stderr).split(/\r?\n/)[0]?.trim()??"")||null}var m1=16777216,Q1;var d=L(()=>{Q1=class Q1 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 S8?"":$}var S8,T,S,_,lZ,I,k,y,J;var c=L(()=>{S8=(process.env.NO_COLOR??"").length>0;T=r("\x1B[0;31m"),S=r("\x1B[0;32m"),_=r("\x1B[1;33m"),lZ=r("\x1B[0;34m"),I=r("\x1B[0;36m"),k=r("\x1B[1m"),y=r("\x1B[2m"),J=r("\x1B[0m")});import{existsSync as u8}from"fs";async function Z$(){if(A$!==void 0)return A$;let $="/opt/homebrew/bin/python3.12";if(u8($))return A$=$,$;let Q=await f("python3.12");if(Q)return A$=Q,Q;let Z=await f("python3");return A$=Z,Z}async function z$($,Q={}){let Z=await Z$();if(!Z)return{stdout:"",stderr:"python3 not found",exitCode:127};return F([Z,"-c",$],Q)}var A$;var V$=L(()=>{d()});var q0={};b(q0,{runStatus:()=>W3});import{existsSync as v,readFileSync as U$,readdirSync as i1,statSync as e1}from"fs";import{resolve as D,basename as $3}from"path";import{homedir as Q3}from"os";function $0($){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 Q0($,Q,Z){if(Q===0)return null;let z=Math.trunc($*100/Q),X=Math.trunc($*D$/Q);if(X>D$)X=D$;let q=D$-X,K=S;if(z>=80)K=T;else if(z>=50)K=_;let W="=".repeat(Math.max(0,X))+" ".repeat(Math.max(0,q)),V=$0($),U=$0(Q);return` ${k}${Z}${J} ${K}[${W}]${J} ${z}% (${V} / ${U})`}async function z3(){if(await f("jq"))return!0;return process.stdout.write(`${T}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)
|
|
@@ -802,4 +802,4 @@ Set LOKI_LEGACY_BASH=1 to force the bash CLI for every command.
|
|
|
802
802
|
`),2}default:return process.stderr.write(`Unknown command: ${Q}
|
|
803
803
|
`),process.stderr.write(Z8),2}}r1();process.on("SIGINT",()=>process.exit(130));process.on("SIGTERM",()=>process.exit(143));var FZ=await jZ(Bun.argv.slice(2));process.exit(FZ);
|
|
804
804
|
|
|
805
|
-
//# debugId=
|
|
805
|
+
//# debugId=D8F1E717478FB03A64756E2164756E21
|
package/mcp/__init__.py
CHANGED
package/memory/retrieval.py
CHANGED
|
@@ -856,12 +856,24 @@ class MemoryRetrieval:
|
|
|
856
856
|
return self.retrieve_by_keyword(
|
|
857
857
|
query.split(), collection)[:top_k]
|
|
858
858
|
|
|
859
|
-
# Generate query embedding
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
#
|
|
859
|
+
# Generate query embedding and search the vector index. If the embedding
|
|
860
|
+
# engine has fallen back to a different model/dimension since the index
|
|
861
|
+
# was built, the query vector dimension will not match the stored index
|
|
862
|
+
# and VectorSearchIndex.search raises ValueError. That must NOT crash
|
|
863
|
+
# retrieval or return wrong-dimension neighbors -- degrade to keyword
|
|
864
|
+
# search (the honest, accurate fallback), same as the staleness path.
|
|
863
865
|
index = self.vector_indices[collection]
|
|
864
|
-
|
|
866
|
+
try:
|
|
867
|
+
query_embedding = self.embedding_engine.embed(query)
|
|
868
|
+
results = index.search(query_embedding, top_k)
|
|
869
|
+
except ValueError as exc:
|
|
870
|
+
logger.info(
|
|
871
|
+
"%s vector search failed (%s); likely an embedding "
|
|
872
|
+
"dimension change since index build. Falling back to keyword "
|
|
873
|
+
"search for accuracy.",
|
|
874
|
+
collection, exc,
|
|
875
|
+
)
|
|
876
|
+
return self.retrieve_by_keyword(query.split(), collection)[:top_k]
|
|
865
877
|
|
|
866
878
|
# Convert to standard format
|
|
867
879
|
items: List[Dict[str, Any]] = []
|
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.100.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": "7.
|
|
5
|
+
"version": "7.100.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",
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Demo Evidence Receipt fixture
|
|
2
|
+
|
|
3
|
+
`proof.json` here is a real Loki Mode Evidence Receipt, copied from an actual
|
|
4
|
+
build and sanitized (no machine paths, no secrets). It is bundled so that
|
|
5
|
+
`loki demo --offline` (and `loki tour`) can show a newcomer a real receipt with
|
|
6
|
+
zero provider, zero key, zero spend, and zero network.
|
|
7
|
+
|
|
8
|
+
What is real: the headline (`VERIFIED WITH GAPS`), the test result, the security
|
|
9
|
+
findings, the cost, and the diff stats are the genuine recorded results of that
|
|
10
|
+
build.
|
|
11
|
+
|
|
12
|
+
What is changed for sanitization: `run_id`, `loki_version`, timestamps, the
|
|
13
|
+
spec brief, and `verification.hash` are neutralized. `verification.hash` is set
|
|
14
|
+
to `sample-not-reproducible` on purpose so this replay fixture is never mistaken
|
|
15
|
+
for a locally-reproducible run. It is for display only.
|
|
16
|
+
|
|
17
|
+
This is a SAMPLE (a replay of a past real build), not a verdict on the user's
|
|
18
|
+
own code. The CLI labels it as such.
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema_version": "1.1",
|
|
3
|
+
"run_id": "run-sample-demo-replay",
|
|
4
|
+
"generated_at": "2026-06-27T17:21:37Z",
|
|
5
|
+
"loki_version": "sample",
|
|
6
|
+
"started_at": "2026-06-27T16:42:44Z",
|
|
7
|
+
"wall_clock_sec": 2333,
|
|
8
|
+
"spec": {
|
|
9
|
+
"source": "./.loki/generated-prd.md",
|
|
10
|
+
"brief": "Sample Evidence Receipt bundled with Loki Mode for the offline demo (loki demo --offline / loki tour). Copied from a real build and sanitized: no machine paths, no secrets. The verification facts below (tests, security, cost, diff) are the real recorded results of that build. This file is for replay/display only."
|
|
11
|
+
},
|
|
12
|
+
"provider": {
|
|
13
|
+
"name": "claude",
|
|
14
|
+
"model": "opus"
|
|
15
|
+
},
|
|
16
|
+
"iterations": {
|
|
17
|
+
"count": 3,
|
|
18
|
+
"succeeded": 3,
|
|
19
|
+
"failed": 0
|
|
20
|
+
},
|
|
21
|
+
"files_changed": {
|
|
22
|
+
"count": 8,
|
|
23
|
+
"insertions": 1413,
|
|
24
|
+
"deletions": 35,
|
|
25
|
+
"files": [
|
|
26
|
+
{ "path": "API.md", "insertions": 227, "deletions": 0, "status": "modified" },
|
|
27
|
+
{ "path": "ARCHITECTURE.md", "insertions": 197, "deletions": 0, "status": "modified" },
|
|
28
|
+
{ "path": "CLAUDE.md", "insertions": 94, "deletions": 0, "status": "modified" },
|
|
29
|
+
{ "path": "COMPONENTS.md", "insertions": 206, "deletions": 0, "status": "modified" },
|
|
30
|
+
{ "path": "DECISIONS.md", "insertions": 146, "deletions": 0, "status": "modified" },
|
|
31
|
+
{ "path": "README.md", "insertions": 157, "deletions": 35, "status": "modified" },
|
|
32
|
+
{ "path": "SETUP.md", "insertions": 236, "deletions": 0, "status": "modified" },
|
|
33
|
+
{ "path": "TESTING.md", "insertions": 150, "deletions": 0, "status": "modified" }
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
"diffs": null,
|
|
37
|
+
"council": {
|
|
38
|
+
"enabled": true,
|
|
39
|
+
"final_verdict": "",
|
|
40
|
+
"threshold": null,
|
|
41
|
+
"reviewers": [],
|
|
42
|
+
"findings_link": null
|
|
43
|
+
},
|
|
44
|
+
"quality_gates": {
|
|
45
|
+
"passed": 0,
|
|
46
|
+
"total": 0,
|
|
47
|
+
"gates": []
|
|
48
|
+
},
|
|
49
|
+
"cost": {
|
|
50
|
+
"usd": 10.3218,
|
|
51
|
+
"input_tokens": 18484,
|
|
52
|
+
"output_tokens": 43491,
|
|
53
|
+
"cache_read_tokens": 5868340,
|
|
54
|
+
"cache_creation_tokens": 246851
|
|
55
|
+
},
|
|
56
|
+
"deployment": {
|
|
57
|
+
"deployed_url": null,
|
|
58
|
+
"public_url": null
|
|
59
|
+
},
|
|
60
|
+
"facts": {
|
|
61
|
+
"git": {
|
|
62
|
+
"base_sha": "255d91cf3d688a42a6e9a5f0e1c042ecfc29de0c",
|
|
63
|
+
"head_sha": "a42cb14ae996eb7459c81b7a43c5686f3612072e",
|
|
64
|
+
"diff": {
|
|
65
|
+
"count": 8,
|
|
66
|
+
"insertions": 1413,
|
|
67
|
+
"deletions": 35,
|
|
68
|
+
"files": [
|
|
69
|
+
{ "path": "API.md", "insertions": 227, "deletions": 0, "status": "modified" },
|
|
70
|
+
{ "path": "ARCHITECTURE.md", "insertions": 197, "deletions": 0, "status": "modified" },
|
|
71
|
+
{ "path": "CLAUDE.md", "insertions": 94, "deletions": 0, "status": "modified" },
|
|
72
|
+
{ "path": "COMPONENTS.md", "insertions": 206, "deletions": 0, "status": "modified" },
|
|
73
|
+
{ "path": "DECISIONS.md", "insertions": 146, "deletions": 0, "status": "modified" },
|
|
74
|
+
{ "path": "README.md", "insertions": 157, "deletions": 35, "status": "modified" },
|
|
75
|
+
{ "path": "SETUP.md", "insertions": 236, "deletions": 0, "status": "modified" },
|
|
76
|
+
{ "path": "TESTING.md", "insertions": 150, "deletions": 0, "status": "modified" }
|
|
77
|
+
]
|
|
78
|
+
},
|
|
79
|
+
"diff_sha256": "c2be6fff3e774c387f276277b25fc424f07b667b0f2c73d8804f954f37bd1356"
|
|
80
|
+
},
|
|
81
|
+
"build": {
|
|
82
|
+
"command": "",
|
|
83
|
+
"exit_code": null,
|
|
84
|
+
"ran": false,
|
|
85
|
+
"duration_sec": null,
|
|
86
|
+
"status": "not_run"
|
|
87
|
+
},
|
|
88
|
+
"tests": {
|
|
89
|
+
"runner": "node-test",
|
|
90
|
+
"command": "node-test",
|
|
91
|
+
"exit_code": 0,
|
|
92
|
+
"passed_count": null,
|
|
93
|
+
"failed_count": null,
|
|
94
|
+
"status": "verified",
|
|
95
|
+
"duration_sec": null
|
|
96
|
+
},
|
|
97
|
+
"quality_gates": [],
|
|
98
|
+
"security": {
|
|
99
|
+
"ran": true,
|
|
100
|
+
"total": 2,
|
|
101
|
+
"active": 2,
|
|
102
|
+
"waived": 0,
|
|
103
|
+
"high_active": 0,
|
|
104
|
+
"status": "findings",
|
|
105
|
+
"findings": [
|
|
106
|
+
{ "rule": "cors-wildcard-credentials", "severity": "MEDIUM", "waived": false },
|
|
107
|
+
{ "rule": "cors-wildcard-credentials", "severity": "MEDIUM", "waived": false }
|
|
108
|
+
]
|
|
109
|
+
},
|
|
110
|
+
"cost": {
|
|
111
|
+
"usd": 10.3218,
|
|
112
|
+
"input_tokens": 18484,
|
|
113
|
+
"output_tokens": 43491,
|
|
114
|
+
"cache_read_tokens": 5868340,
|
|
115
|
+
"cache_creation_tokens": 246851
|
|
116
|
+
},
|
|
117
|
+
"meta": {
|
|
118
|
+
"run_id": "run-sample-demo-replay",
|
|
119
|
+
"loki_version": "sample",
|
|
120
|
+
"provider": "claude",
|
|
121
|
+
"model": "opus",
|
|
122
|
+
"started_at": "2026-06-27T16:42:44Z",
|
|
123
|
+
"generated_at": "2026-06-27T17:21:37Z",
|
|
124
|
+
"wall_clock_sec": 2333
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
"assessments": {
|
|
128
|
+
"_note": "AI judgment, not deterministic proof",
|
|
129
|
+
"council": {
|
|
130
|
+
"enabled": true,
|
|
131
|
+
"final_verdict": "",
|
|
132
|
+
"threshold": null,
|
|
133
|
+
"reviewers": [],
|
|
134
|
+
"findings_link": null
|
|
135
|
+
},
|
|
136
|
+
"completion_claim": {
|
|
137
|
+
"claimed": true,
|
|
138
|
+
"evidence_gate_verdict": "pass"
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
"honesty": {
|
|
142
|
+
"headline": "VERIFIED WITH GAPS",
|
|
143
|
+
"degraded": [
|
|
144
|
+
{
|
|
145
|
+
"item": "build",
|
|
146
|
+
"status": "not_run",
|
|
147
|
+
"reason": "build not run"
|
|
148
|
+
}
|
|
149
|
+
],
|
|
150
|
+
"evidence_gate": {
|
|
151
|
+
"ran": true,
|
|
152
|
+
"verdict": "pass",
|
|
153
|
+
"baseline_established": true
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
"redaction": {
|
|
157
|
+
"applied": false,
|
|
158
|
+
"rules_version": "1.0",
|
|
159
|
+
"redactions_count": 0
|
|
160
|
+
},
|
|
161
|
+
"verification": {
|
|
162
|
+
"hash": "sample-not-reproducible",
|
|
163
|
+
"algo": "sha256",
|
|
164
|
+
"scope": "integrity"
|
|
165
|
+
}
|
|
166
|
+
}
|