loki-mode 7.85.0 → 7.86.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 +76 -0
- package/SKILL.md +4 -2
- package/VERSION +1 -1
- package/dashboard/__init__.py +1 -1
- package/dashboard/server.py +56 -0
- package/dashboard/static/index.html +93 -0
- package/docs/INSTALLATION.md +2 -2
- 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/README.md
CHANGED
|
@@ -45,6 +45,82 @@ _The free, source-available autonomous coding agent by [Autonomi](https://www.au
|
|
|
45
45
|
|
|
46
46
|
---
|
|
47
47
|
|
|
48
|
+
## Loki does not lie about "done"
|
|
49
|
+
|
|
50
|
+
Most coding agents declare a task done by telling you so in a transcript. The
|
|
51
|
+
transcript is the agent's own narration; there is nothing to check. Loki Mode
|
|
52
|
+
takes a different stance: it does not call work done until the work is verified,
|
|
53
|
+
and every build produces an **Evidence Receipt** you can re-verify yourself.
|
|
54
|
+
|
|
55
|
+
The receipt separates two things most tools blur together:
|
|
56
|
+
|
|
57
|
+
- **Facts** -- deterministic, non-LLM, and re-derivable by anyone: the git diff
|
|
58
|
+
(base/head SHAs, file/insertion/deletion counts, a `diff_sha256`), the test
|
|
59
|
+
command that ran with its exit code, the build command with its exit code, and
|
|
60
|
+
each quality-gate verdict. A skeptic can recompute every one of these from the
|
|
61
|
+
same repo state.
|
|
62
|
+
- **Assessments** -- AI judgments such as the review council's verdict. These are
|
|
63
|
+
labeled explicitly as judgment, not proof, and never make the headline green on
|
|
64
|
+
their own.
|
|
65
|
+
|
|
66
|
+
The receipt's headline is computed only from the facts:
|
|
67
|
+
|
|
68
|
+
- **VERIFIED** -- tests recorded a real command, ran, and exited 0; the diff is
|
|
69
|
+
non-empty; nothing was skipped.
|
|
70
|
+
- **VERIFIED WITH GAPS** -- some facts checked out, but something was not run or
|
|
71
|
+
was inconclusive. Every gap is listed by name, so silence never reads as a pass.
|
|
72
|
+
- **NOT VERIFIED** -- a test, build, or gate ran and failed (or there was nothing
|
|
73
|
+
to verify).
|
|
74
|
+
|
|
75
|
+
This is honesty-of-done, not a claim of perfection. The receipt proves the
|
|
76
|
+
completion claim is backed by deterministic evidence and is independently
|
|
77
|
+
re-checkable; it does not claim the generated code is bug-free.
|
|
78
|
+
|
|
79
|
+
### Verify it yourself
|
|
80
|
+
|
|
81
|
+
Receipts are written to `.loki/proofs/<run_id>/` automatically at run completion
|
|
82
|
+
(opt out with `LOKI_PROOF=0`). Inspect and re-check them with `loki proof`
|
|
83
|
+
(aliased as `loki receipt`):
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
loki proof list # every receipt: run id, time, council verdict, cost, files
|
|
87
|
+
loki proof show <id> # the full proof.json (facts, assessments, honesty)
|
|
88
|
+
loki proof verify <id> # re-check the receipt against the repo (exit 0 clean, 1 tamper/drift)
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
`loki proof verify` does two independent checks and prints the result as JSON:
|
|
92
|
+
|
|
93
|
+
- **Tamper check** -- recomputes the receipt's integrity hash and compares it to
|
|
94
|
+
the recorded one. If anyone edited the receipt after it was written, `hash_ok`
|
|
95
|
+
is `false`.
|
|
96
|
+
- **Drift check** -- re-runs the diff from the recorded base SHA against the
|
|
97
|
+
current repo and compares the file/insertion/deletion counts and `diff_sha256`
|
|
98
|
+
to what the receipt recorded. If the repo no longer matches, `diff_drift` is
|
|
99
|
+
`true`.
|
|
100
|
+
|
|
101
|
+
A clean receipt prints `"ok": true` and exits 0. A tampered or drifted receipt
|
|
102
|
+
exits 1. When a check cannot run (for example a receipt with no recorded base
|
|
103
|
+
SHA), the verifier reports it as unverifiable rather than passing it silently.
|
|
104
|
+
|
|
105
|
+
```json
|
|
106
|
+
{
|
|
107
|
+
"hash_ok": true,
|
|
108
|
+
"diff_drift": false,
|
|
109
|
+
"gpg_ok": "n/a",
|
|
110
|
+
"degraded": [],
|
|
111
|
+
"reason": "",
|
|
112
|
+
"ok": true
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
You can share a receipt as a self-contained HTML page (`loki proof open <id>`),
|
|
117
|
+
or publish it as a GitHub Gist with `loki proof share <id>` (opt-in; the page is
|
|
118
|
+
redacted before it leaves your machine). An optional, off-by-default GPG detached
|
|
119
|
+
signature (`LOKI_PROOF_GPG_KEY`) lets a third party confirm the receipt came from
|
|
120
|
+
you.
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
48
124
|
## Get Started in 30 Seconds
|
|
49
125
|
|
|
50
126
|
```bash
|
package/SKILL.md
CHANGED
|
@@ -3,12 +3,14 @@ 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.86.0
|
|
7
7
|
|
|
8
8
|
**You are an autonomous agent. You make decisions. You do not ask questions. You do not stop.**
|
|
9
9
|
|
|
10
10
|
**Spec in, verified product out.** Spec-driven: a "spec" is whatever describes the work -- a Markdown PRD, a GitHub issue, an OpenAPI doc, a Jira ticket (a PRD is one form of spec). The differentiator is the trust layer: Loki does not call work done until it is verified. The RARV-C closure loop, 8 quality gates, the completion council, and the verified-completion evidence gate must all clear before completion is accepted.
|
|
11
11
|
|
|
12
|
+
**Evidence Receipt (verify it yourself).** Every run writes a receipt to `.loki/proofs/<run_id>/` (opt out with `LOKI_PROOF=0`) that separates deterministic FACTS (git diff with base/head SHAs and a `diff_sha256`, the test command + exit code, the build command + exit code, each gate verdict) from AI ASSESSMENTS (the council verdict, labeled judgment not proof). The headline is computed only from the facts: VERIFIED (tests ran a real command and exited 0, diff non-empty, nothing skipped), VERIFIED WITH GAPS (each gap listed by name), or NOT VERIFIED (a check ran and failed). Inspect and re-check with `loki proof list|show <id>|verify <id>` (aliased `loki receipt`); `loki proof verify` re-hashes the receipt (tamper) and re-derives the diff from the recorded base SHA against the live repo (drift), exiting 0 clean / 1 tamper-or-drift. This is honesty-of-done, not a claim that the code is bug-free.
|
|
13
|
+
|
|
12
14
|
**Provider-agnostic (stable since v5.0.0):** runs on Claude/Codex/Cline/Aider with abstract model tiers and degraded mode for non-Claude providers; no vendor lock-in. Gemini deprecated v7.5.18. See `skills/providers.md`. **Current track (v7.7.x):** LSP grounding as first-class agent tool (v7.7.0-v7.7.9; lsp_get_diagnostics actually-returns-diagnostics regression fix v7.7.14), provider_source cli (v7.7.11-v7.7.12 bash/bun parity), Docker/bash-3.2 robustness (v7.7.13), audit chain cross-file verification fix (v7.7.15), Phase 1 RARV-C closure (real provider judges, gate-failure flock, synthetic PRD e2e, status `--json`).
|
|
13
15
|
|
|
14
16
|
**Runtime migration:** Bash-to-Bun migration. Read-only commands (`version`, `status`, `stats`, `doctor`, `provider show/list`, `memory list/index`) flow through Bun runtime via `bin/loki` since v7.3.0. Every other command remains on the Bash runtime (`autonomy/loki`). Rollback: `LOKI_LEGACY_BASH=1`. See `UPGRADING.md` and `docs/architecture/ADR-001-runtime-migration.md`.
|
|
@@ -406,4 +408,4 @@ See `CHANGELOG.md` entries [7.5.7], [7.5.8], [7.5.13] for the per-fix list and r
|
|
|
406
408
|
|
|
407
409
|
---
|
|
408
410
|
|
|
409
|
-
**v7.
|
|
411
|
+
**v7.86.0 | [Autonomi](https://www.autonomi.dev/) flagship product | ~260 lines core**
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
7.
|
|
1
|
+
7.86.0
|
package/dashboard/__init__.py
CHANGED
package/dashboard/server.py
CHANGED
|
@@ -10110,6 +10110,62 @@ async def list_proofs():
|
|
|
10110
10110
|
return {"proofs": items}
|
|
10111
10111
|
|
|
10112
10112
|
|
|
10113
|
+
@app.get("/api/proofs/summary",
|
|
10114
|
+
dependencies=[Depends(auth.require_scope("read"))])
|
|
10115
|
+
async def proofs_summary():
|
|
10116
|
+
"""Honest aggregate over the active project's Evidence Receipts.
|
|
10117
|
+
|
|
10118
|
+
Counts are computed ONLY from real proof.json files; nothing is invented.
|
|
10119
|
+
The single source of truth for "verified" is the v1.1 deterministic
|
|
10120
|
+
honesty.headline (proof-generator.py::_compute_headline), which a forger
|
|
10121
|
+
cannot turn green without real exit_code:0 evidence. Buckets:
|
|
10122
|
+
|
|
10123
|
+
verified -> honesty.headline == "VERIFIED"
|
|
10124
|
+
with_gaps -> honesty.headline == "VERIFIED WITH GAPS"
|
|
10125
|
+
not_verified -> honesty.headline == "NOT VERIFIED"
|
|
10126
|
+
unknown -> no honesty block (schema v1.0 proofs) or any other/
|
|
10127
|
+
missing headline. We refuse to count these as verified
|
|
10128
|
+
because we cannot prove they were.
|
|
10129
|
+
|
|
10130
|
+
Empty or missing proofs dir -> all zeros (200), an honest empty state.
|
|
10131
|
+
Mirrors list_proofs' iteration + _safe_json_read so the counts can never
|
|
10132
|
+
drift from what the list endpoint shows.
|
|
10133
|
+
"""
|
|
10134
|
+
proofs_dir = _proofs_dir()
|
|
10135
|
+
total = verified = with_gaps = not_verified = unknown = 0
|
|
10136
|
+
try:
|
|
10137
|
+
entries = sorted(proofs_dir.iterdir())
|
|
10138
|
+
except (OSError, FileNotFoundError):
|
|
10139
|
+
entries = []
|
|
10140
|
+
for entry in entries:
|
|
10141
|
+
if not entry.is_dir():
|
|
10142
|
+
continue
|
|
10143
|
+
proof_json = entry / "proof.json"
|
|
10144
|
+
if not proof_json.is_file():
|
|
10145
|
+
continue
|
|
10146
|
+
data = _safe_json_read(proof_json, default=None)
|
|
10147
|
+
if not isinstance(data, dict):
|
|
10148
|
+
continue
|
|
10149
|
+
total += 1
|
|
10150
|
+
honesty = data.get("honesty")
|
|
10151
|
+
headline = honesty.get("headline") if isinstance(honesty, dict) else None
|
|
10152
|
+
if headline == "VERIFIED":
|
|
10153
|
+
verified += 1
|
|
10154
|
+
elif headline == "VERIFIED WITH GAPS":
|
|
10155
|
+
with_gaps += 1
|
|
10156
|
+
elif headline == "NOT VERIFIED":
|
|
10157
|
+
not_verified += 1
|
|
10158
|
+
else:
|
|
10159
|
+
unknown += 1
|
|
10160
|
+
return {
|
|
10161
|
+
"total_receipts": total,
|
|
10162
|
+
"verified": verified,
|
|
10163
|
+
"with_gaps": with_gaps,
|
|
10164
|
+
"not_verified": not_verified,
|
|
10165
|
+
"unknown": unknown,
|
|
10166
|
+
}
|
|
10167
|
+
|
|
10168
|
+
|
|
10113
10169
|
@app.get("/api/proofs/{run_id}", dependencies=[Depends(auth.require_scope("read"))])
|
|
10114
10170
|
async def get_proof(run_id: str):
|
|
10115
10171
|
"""Return the redacted proof.json for one run."""
|
|
@@ -204,6 +204,41 @@
|
|
|
204
204
|
font-weight: 500;
|
|
205
205
|
}
|
|
206
206
|
|
|
207
|
+
/* Verified-receipts badge: an honest trust signal next to the brand.
|
|
208
|
+
Counts are pulled live from /api/proofs/summary and reflect only real,
|
|
209
|
+
deterministic Evidence Receipts. Hidden until we have data; shows a muted
|
|
210
|
+
"No receipts yet" at zero; never a fabricated number. */
|
|
211
|
+
.receipts-badge {
|
|
212
|
+
display: none;
|
|
213
|
+
align-items: center;
|
|
214
|
+
gap: 5px;
|
|
215
|
+
margin-top: 6px;
|
|
216
|
+
padding: 3px 8px;
|
|
217
|
+
width: fit-content;
|
|
218
|
+
max-width: 100%;
|
|
219
|
+
border: 1px solid var(--loki-border);
|
|
220
|
+
border-radius: 999px;
|
|
221
|
+
background: var(--loki-bg-card);
|
|
222
|
+
font-family: 'Inter', system-ui, sans-serif;
|
|
223
|
+
font-size: 10px;
|
|
224
|
+
font-weight: 500;
|
|
225
|
+
line-height: 1.2;
|
|
226
|
+
color: var(--loki-text-secondary);
|
|
227
|
+
cursor: default;
|
|
228
|
+
}
|
|
229
|
+
.receipts-badge.show { display: inline-flex; }
|
|
230
|
+
.receipts-badge.empty { color: var(--loki-text-muted); }
|
|
231
|
+
.receipts-badge .receipts-dot {
|
|
232
|
+
width: 6px;
|
|
233
|
+
height: 6px;
|
|
234
|
+
border-radius: 50%;
|
|
235
|
+
background: var(--loki-success);
|
|
236
|
+
flex: 0 0 auto;
|
|
237
|
+
}
|
|
238
|
+
.receipts-badge.empty .receipts-dot { background: var(--loki-text-muted); }
|
|
239
|
+
.receipts-badge .receipts-verified { color: var(--loki-success); font-weight: 600; }
|
|
240
|
+
.receipts-badge.empty .receipts-verified { color: var(--loki-text-muted); font-weight: 500; }
|
|
241
|
+
|
|
207
242
|
/* Navigation: the only scrolling region. min-height:0 + overflow-y:auto so
|
|
208
243
|
a long grouped nav scrolls within the sidebar while the header + footer
|
|
209
244
|
stay pinned. */
|
|
@@ -851,6 +886,15 @@
|
|
|
851
886
|
</button>
|
|
852
887
|
<span class="logo-brand">Loki Mode</span>
|
|
853
888
|
<span class="logo-subtitle">powered by Autonomi</span>
|
|
889
|
+
<!-- Verified-receipts badge: honest trust signal. Populated at runtime
|
|
890
|
+
from /api/proofs/summary; hidden until data arrives, shows a muted
|
|
891
|
+
empty state at zero, and degrades silently if the endpoint is
|
|
892
|
+
unavailable. Every receipt is a deterministic, re-verifiable
|
|
893
|
+
Evidence Receipt (loki proof verify). -->
|
|
894
|
+
<span class="receipts-badge" id="receipts-badge" role="status">
|
|
895
|
+
<span class="receipts-dot" aria-hidden="true"></span>
|
|
896
|
+
<span id="receipts-badge-text"></span>
|
|
897
|
+
</span>
|
|
854
898
|
<!-- v7.84 single project switcher: ONE searchable <select> with two
|
|
855
899
|
<optgroup>s ("Running" and "All projects"), built at runtime from
|
|
856
900
|
/api/running-projects. A running-app count pill sits beside it; the
|
|
@@ -15250,6 +15294,55 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
15250
15294
|
} catch (err) { /* polling fallback still covers it */ }
|
|
15251
15295
|
})();
|
|
15252
15296
|
|
|
15297
|
+
// Verified-receipts badge: honest trust signal beside the brand. Fetches the
|
|
15298
|
+
// real aggregate from /api/proofs/summary and shows "N receipts - M
|
|
15299
|
+
// verified". At zero it shows a muted "No receipts yet"; if the endpoint is
|
|
15300
|
+
// unavailable it stays hidden (no error spew). We never display a number the
|
|
15301
|
+
// data does not support: "verified" here is the deterministic
|
|
15302
|
+
// honesty.headline == VERIFIED count, re-verifiable via loki proof verify.
|
|
15303
|
+
(function initReceiptsBadge() {
|
|
15304
|
+
var badge = document.getElementById('receipts-badge');
|
|
15305
|
+
var textEl = document.getElementById('receipts-badge-text');
|
|
15306
|
+
if (!badge || !textEl) return;
|
|
15307
|
+
|
|
15308
|
+
function plural(n, word) { return n + ' ' + word + (n === 1 ? '' : 's'); }
|
|
15309
|
+
|
|
15310
|
+
function render(s) {
|
|
15311
|
+
var total = (s && typeof s.total_receipts === 'number') ? s.total_receipts : 0;
|
|
15312
|
+
var verified = (s && typeof s.verified === 'number') ? s.verified : 0;
|
|
15313
|
+
if (total <= 0) {
|
|
15314
|
+
// Honest empty state: no fabricated number.
|
|
15315
|
+
badge.classList.add('empty');
|
|
15316
|
+
textEl.textContent = 'No receipts yet';
|
|
15317
|
+
badge.title = 'Evidence Receipts appear here once Loki completes a '
|
|
15318
|
+
+ 'verified run. Each is deterministic and re-verifiable with '
|
|
15319
|
+
+ '"loki proof verify".';
|
|
15320
|
+
badge.classList.add('show');
|
|
15321
|
+
return;
|
|
15322
|
+
}
|
|
15323
|
+
badge.classList.remove('empty');
|
|
15324
|
+
// "N receipts - M verified" with the verified count emphasized.
|
|
15325
|
+
textEl.innerHTML = plural(total, 'receipt') + ' - '
|
|
15326
|
+
+ '<span class="receipts-verified"></span> verified';
|
|
15327
|
+
var vEl = textEl.querySelector('.receipts-verified');
|
|
15328
|
+
if (vEl) vEl.textContent = String(verified);
|
|
15329
|
+
badge.title = plural(verified, 'receipt') + ' of ' + total
|
|
15330
|
+
+ ' verified by a deterministic Evidence Receipt (re-verifiable with '
|
|
15331
|
+
+ '"loki proof verify"). "Verified" means tests passed with real '
|
|
15332
|
+
+ 'exit-code evidence, not an LLM opinion.';
|
|
15333
|
+
badge.classList.add('show');
|
|
15334
|
+
}
|
|
15335
|
+
|
|
15336
|
+
function poll() {
|
|
15337
|
+
fetch('/api/proofs/summary', { headers: { 'Accept': 'application/json' } })
|
|
15338
|
+
.then(function (r) { return r.ok ? r.json() : null; })
|
|
15339
|
+
.then(function (d) { if (d) render(d); })
|
|
15340
|
+
.catch(function () { /* endpoint unavailable: leave badge hidden */ });
|
|
15341
|
+
}
|
|
15342
|
+
poll();
|
|
15343
|
+
setInterval(poll, 30000);
|
|
15344
|
+
})();
|
|
15345
|
+
|
|
15253
15346
|
// Mobile menu toggle
|
|
15254
15347
|
var mobileMenuBtn = document.getElementById('mobile-menu-btn');
|
|
15255
15348
|
var sidebar = document.getElementById('sidebar');
|
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.86.0
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -395,7 +395,7 @@ provider works inside the container. Provide auth with your Anthropic API key:
|
|
|
395
395
|
# Run Loki Mode in Docker (Claude provider, API-key auth)
|
|
396
396
|
docker run --rm -e ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" \
|
|
397
397
|
-v $(pwd):/workspace -w /workspace \
|
|
398
|
-
asklokesh/loki-mode:7.
|
|
398
|
+
asklokesh/loki-mode:7.86.0 start ./my-spec.md
|
|
399
399
|
```
|
|
400
400
|
|
|
401
401
|
##### docker compose + .env (no host install)
|
package/loki-ts/dist/loki.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
var QQ=Object.defineProperty;var ZQ=($)=>$;function zQ($,Q){this[$]=ZQ.bind(null,Q)}var b=($,Q)=>{for(var Z in Q)QQ($,Z,{get:Q[Z],enumerable:!0,configurable:!0,set:zQ.bind(Q,Z)})};var L=($,Q)=>()=>($&&(Q=$($=0)),Q);var q$=import.meta.require;var h1={};b(h1,{lokiDir:()=>P,homeLokiDir:()=>i$,findRepoRootForVersion:()=>t$,REPO_ROOT:()=>g});import{resolve as a,dirname as r$}from"path";import{fileURLToPath as XQ}from"url";import{existsSync as R$}from"fs";import{homedir as KQ}from"os";function qQ(){let $=b1;for(let Q=0;Q<6;Q++){if(R$(a($,"VERSION"))&&R$(a($,"autonomy/run.sh")))return $;let Z=r$($);if(Z===$)break;$=Z}return a(b1,"..","..","..")}function t$($){let Q=$;for(let Z=0;Z<6;Z++){if(R$(a(Q,"VERSION"))&&R$(a(Q,"autonomy/run.sh")))return Q;let z=r$(Q);if(z===Q)break;Q=z}return a($,"..","..","..")}function P(){return process.env.LOKI_DIR??a(process.cwd(),".loki")}function i$(){return a(KQ(),".loki")}var b1,g;var C=L(()=>{b1=r$(XQ(import.meta.url));g=qQ()});import{readFileSync as VQ}from"fs";import{resolve as JQ,dirname as UQ}from"path";import{fileURLToPath as WQ}from"url";function E$(){if(Q$!==null)return Q$;let $="7.
|
|
2
|
+
var QQ=Object.defineProperty;var ZQ=($)=>$;function zQ($,Q){this[$]=ZQ.bind(null,Q)}var b=($,Q)=>{for(var Z in Q)QQ($,Z,{get:Q[Z],enumerable:!0,configurable:!0,set:zQ.bind(Q,Z)})};var L=($,Q)=>()=>($&&(Q=$($=0)),Q);var q$=import.meta.require;var h1={};b(h1,{lokiDir:()=>P,homeLokiDir:()=>i$,findRepoRootForVersion:()=>t$,REPO_ROOT:()=>g});import{resolve as a,dirname as r$}from"path";import{fileURLToPath as XQ}from"url";import{existsSync as R$}from"fs";import{homedir as KQ}from"os";function qQ(){let $=b1;for(let Q=0;Q<6;Q++){if(R$(a($,"VERSION"))&&R$(a($,"autonomy/run.sh")))return $;let Z=r$($);if(Z===$)break;$=Z}return a(b1,"..","..","..")}function t$($){let Q=$;for(let Z=0;Z<6;Z++){if(R$(a(Q,"VERSION"))&&R$(a(Q,"autonomy/run.sh")))return Q;let z=r$(Q);if(z===Q)break;Q=z}return a($,"..","..","..")}function P(){return process.env.LOKI_DIR??a(process.cwd(),".loki")}function i$(){return a(KQ(),".loki")}var b1,g;var C=L(()=>{b1=r$(XQ(import.meta.url));g=qQ()});import{readFileSync as VQ}from"fs";import{resolve as JQ,dirname as UQ}from"path";import{fileURLToPath as WQ}from"url";function E$(){if(Q$!==null)return Q$;let $="7.86.0";if(typeof $==="string"&&$.length>0)return Q$=$,Q$;try{let Q=UQ(WQ(import.meta.url)),Z=t$(Q);Q$=VQ(JQ(Z,"VERSION"),"utf-8").trim()}catch{Q$="unknown"}return Q$}var Q$=null;var e$=L(()=>{C()});var g1={};b(g1,{runOrThrow:()=>HQ,run:()=>F,readStreamCapped:()=>m1,commandVersion:()=>BQ,commandExists:()=>f,ShellError:()=>$1,MAX_STDOUT_BYTES:()=>v1});async function m1($,Q=v1){let Z=$.getReader(),z=new TextDecoder,X="",q=0;try{while(q<Q){let{done:K,value:U}=await Z.read();if(K)break;if(!U)continue;if(q+=U.byteLength,q>Q){let J=U.byteLength-(q-Q);X+=z.decode(U.subarray(0,J),{stream:!0});break}X+=z.decode(U,{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,U]=await Promise.all([m1(Z.stdout),new Response(Z.stderr).text(),Z.exited]);return{stdout:q,stderr:K,exitCode:U}}finally{if(z)clearTimeout(z);if(X)clearTimeout(X)}}async function HQ($,Q={}){let Z=await F($,Q);if(Z.exitCode!==0)throw new $1(`command failed (${Z.exitCode}): ${$.join(" ")}`,Z.exitCode,Z.stdout,Z.stderr);return Z}async function f($){let Q=GQ($),Z=await F(["sh","-c",`command -v ${Q}`],{timeoutMs:5000});if(Z.exitCode===0)return Z.stdout.trim()||null;return null}function GQ($){if(!/^[A-Za-z0-9._/-]+$/.test($))throw Error(`refused to shell-escape suspect token: ${$}`);return $}async function BQ($,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 v1=16777216,$1;var d=L(()=>{$1=class $1 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 s($){return YQ?"":$}var YQ,O,S,_,_Z,I,k,h,V;var c=L(()=>{YQ=(process.env.NO_COLOR??"").length>0;O=s("\x1B[0;31m"),S=s("\x1B[0;32m"),_=s("\x1B[1;33m"),_Z=s("\x1B[0;34m"),I=s("\x1B[0;36m"),k=s("\x1B[1m"),h=s("\x1B[2m"),V=s("\x1B[0m")});import{existsSync as jQ}from"fs";async function Z$(){if(Y$!==void 0)return Y$;let $="/opt/homebrew/bin/python3.12";if(jQ($))return Y$=$,$;let Q=await f("python3.12");if(Q)return Y$=Q,Q;let Z=await f("python3");return Y$=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 Y$;var V$=L(()=>{d()});var X0={};b(X0,{runStatus:()=>oQ});import{existsSync as y,readFileSync as U$,readdirSync as r1,statSync as t1}from"fs";import{resolve as D,basename as vQ}from"path";import{homedir as mQ}from"os";function i1($){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 e1($,Q,Z){if(Q===0)return null;let z=Math.trunc($*100/Q),X=Math.trunc($*N$/Q);if(X>N$)X=N$;let q=N$-X,K=S;if(z>=80)K=O;else if(z>=50)K=_;let U="=".repeat(Math.max(0,X))+" ".repeat(Math.max(0,q)),J=i1($),W=i1(Q);return` ${k}${Z}${V} ${K}[${U}]${V} ${z}% (${J} / ${W})`}async function fQ(){if(await f("jq"))return!0;return process.stdout.write(`${O}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)
|
|
@@ -796,4 +796,4 @@ Set LOKI_LEGACY_BASH=1 to force the bash CLI for every command.
|
|
|
796
796
|
`),2}default:return process.stderr.write(`Unknown command: ${Q}
|
|
797
797
|
`),process.stderr.write($Q),2}}s1();process.on("SIGINT",()=>process.exit(130));process.on("SIGTERM",()=>process.exit(143));var qZ=await KZ(Bun.argv.slice(2));process.exit(qZ);
|
|
798
798
|
|
|
799
|
-
//# debugId=
|
|
799
|
+
//# debugId=5E11AD9E3DCEB72F64756E2164756E21
|
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.86.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.86.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",
|