loki-mode 8.2.0 → 8.3.1
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 +56 -1
- package/VERSION +1 -1
- package/autonomy/loki +27 -10
- package/dashboard/__init__.py +1 -1
- package/docs/COMPARISON.md +8 -1
- package/docs/EVALUATING.md +142 -0
- 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,12 +15,67 @@ _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.
|
|
18
|
+
**Current release: v8.3.1**
|
|
19
19
|
|
|
20
20
|
</div>
|
|
21
21
|
|
|
22
22
|
---
|
|
23
23
|
|
|
24
|
+
## See the receipt before you install anything
|
|
25
|
+
|
|
26
|
+
Every agent claims it finished. Ours hands you an artifact you can check:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npx loki-mode tour # no install, no API key, no spend, no network
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
That prints a real Evidence Receipt from a past build. Note what it says:
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
Headline: VERIFIED WITH GAPS
|
|
36
|
+
|
|
37
|
+
| Fact | Value |
|
|
38
|
+
| Files changed | 8 |
|
|
39
|
+
| Diff sha256 | c2be6fff3e774c387f276277b25fc424f07b667… |
|
|
40
|
+
| Tests | verified (node-test) |
|
|
41
|
+
| Build | not_run |
|
|
42
|
+
| Security | findings |
|
|
43
|
+
| Cost | $10.3218 |
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**"WITH GAPS" is the point.** Build was not run. Security has findings. The
|
|
47
|
+
receipt says so on its own front page, and separates deterministic FACTS -- the
|
|
48
|
+
diff hash, the test result, the cost -- from AI ASSESSMENTS, because only four
|
|
49
|
+
of the eight quality gates are agent-independent and a receipt that implied
|
|
50
|
+
otherwise would be marketing.
|
|
51
|
+
|
|
52
|
+
Recompute the diff hash yourself and check it matches. That is the whole idea:
|
|
53
|
+
you are not asked to trust the agent's self-report.
|
|
54
|
+
|
|
55
|
+
Self-reported completion is the failure users actually hit. A survey of the
|
|
56
|
+
open issue trackers of seven coding harnesses (OpenHands, Cline, Aider,
|
|
57
|
+
SWE-agent, Roo-Code, OpenCode, Continue) found the recurring complaint is the
|
|
58
|
+
agent silently not doing the work -- "always stuck at Preparing write"
|
|
59
|
+
([opencode#11112](https://github.com/anomalyco/opencode/issues/11112), 76
|
|
60
|
+
comments), "Continue not making changes to code"
|
|
61
|
+
([continue#7143](https://github.com/continuedev/continue/issues/7143)), "Agent
|
|
62
|
+
does not execute functions"
|
|
63
|
+
([continue#5696](https://github.com/continuedev/continue/issues/5696)). None of
|
|
64
|
+
those seven publishes a machine-checkable completion artifact.
|
|
65
|
+
|
|
66
|
+
We have not audited the closed-source products (Cursor, Devin, Replit Agent)
|
|
67
|
+
feature by feature, so treat this as "unclaimed as far as we can verify" rather
|
|
68
|
+
than a proven first. The receipt stands on its own either way: run the tour and
|
|
69
|
+
check the hash.
|
|
70
|
+
|
|
71
|
+
**Evaluating this against something else?** [docs/EVALUATING.md](docs/EVALUATING.md)
|
|
72
|
+
puts a runnable command next to every claim we make, and states plainly what we
|
|
73
|
+
do not have (no enterprise case studies, no independent benchmark placement, and
|
|
74
|
+
generation is not air-gapped). It ends with the one question worth asking any
|
|
75
|
+
agent vendor, including us.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
24
79
|
> **How it works:** Drop a spec -- a PRD, GitHub issue, OpenAPI/JSON/YAML, or one-line brief. Loki Mode classifies complexity (`run.sh:detect_complexity()`), assembles an agent team from 41 specialized agent roles across 8 domains - prompt-defined specifications the orchestrator adopts per phase, with parallel review (blind council) and optional worktree streams on Claude Code, sequential on other providers - and runs autonomous RARV cycles (Reason - Act - Reflect - Verify, see `run.sh:run_autonomous()`) with 8 quality gates (see `skills/quality-gates.md`). Code is not "done" until it passes automated verification. Output is a Git repo with source, tests, configs, and audit logs.
|
|
25
80
|
|
|
26
81
|
---
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
8.
|
|
1
|
+
8.3.1
|
package/autonomy/loki
CHANGED
|
@@ -10772,6 +10772,15 @@ cmd_doctor() {
|
|
|
10772
10772
|
|
|
10773
10773
|
local pass_count=0
|
|
10774
10774
|
local fail_count=0
|
|
10775
|
+
# FUNNEL FIX (v8.2.x): collect the NAME + FIX of every hard failure, not just
|
|
10776
|
+
# a count. A first-time user on a bare machine sees 15 warnings (sentrux, GPG
|
|
10777
|
+
# signing, bash 4, Bun, python3.12, truecolor, inline-image probe -- all
|
|
10778
|
+
# OPTIONAL) around 2 real blockers, then a summary that says only "Some
|
|
10779
|
+
# required prerequisites are missing" without naming them. That is the point
|
|
10780
|
+
# where someone closes the terminal. Naming the blockers and their exact
|
|
10781
|
+
# install command turns a wall of yellow into a two-line to-do.
|
|
10782
|
+
local _doctor_blockers=""
|
|
10783
|
+
_doctor_block() { _doctor_blockers="${_doctor_blockers}\n - $1"; }
|
|
10775
10784
|
local warn_count=0
|
|
10776
10785
|
|
|
10777
10786
|
# Helper: check command exists and optionally check version
|
|
@@ -10784,6 +10793,7 @@ cmd_doctor() {
|
|
|
10784
10793
|
if ! command -v "$cmd" &> /dev/null; then
|
|
10785
10794
|
if [ "$required" = "required" ]; then
|
|
10786
10795
|
echo -e " ${RED}FAIL${NC} $name - not found"
|
|
10796
|
+
_doctor_block "$name is not installed"
|
|
10787
10797
|
fail_count=$((fail_count + 1))
|
|
10788
10798
|
elif [ "$required" = "recommended" ]; then
|
|
10789
10799
|
echo -e " ${YELLOW}WARN${NC} $name - not found (recommended)"
|
|
@@ -10849,6 +10859,7 @@ cmd_doctor() {
|
|
|
10849
10859
|
{ [ "$cur_major" -eq "$min_major" ] 2>/dev/null && [ "$cur_minor" -lt "$min_minor" ] 2>/dev/null; }; then
|
|
10850
10860
|
if [ "$required" = "required" ]; then
|
|
10851
10861
|
echo -e " ${RED}FAIL${NC} $name$version_display - requires >= $min_version"
|
|
10862
|
+
_doctor_block "$name must be >= $min_version"
|
|
10852
10863
|
fail_count=$((fail_count + 1))
|
|
10853
10864
|
else
|
|
10854
10865
|
echo -e " ${YELLOW}WARN${NC} $name$version_display - recommended >= $min_version"
|
|
@@ -10920,6 +10931,7 @@ cmd_doctor() {
|
|
|
10920
10931
|
else
|
|
10921
10932
|
echo -e " ${RED}FAIL${NC} No AI provider CLI installed -- at least one is required"
|
|
10922
10933
|
echo -e " ${YELLOW}Install: npm install -g @anthropic-ai/claude-code${NC}"
|
|
10934
|
+
_doctor_block "No AI provider CLI. Fix: npm install -g @anthropic-ai/claude-code"
|
|
10923
10935
|
fail_count=$((fail_count + 1))
|
|
10924
10936
|
# v7.29.0: on a TTY (non-json), append the consent-gated install offer.
|
|
10925
10937
|
# In report mode the helper is a no-op on non-TTY/CI, so the doctor
|
|
@@ -11024,6 +11036,7 @@ except Exception:
|
|
|
11024
11036
|
_target=$(readlink "$sdir" 2>/dev/null || echo "unknown")
|
|
11025
11037
|
echo -e " ${RED}FAIL${NC} $sname ${DIM}(broken symlink -> $_target)${NC}"
|
|
11026
11038
|
echo -e " ${YELLOW}Fix: loki setup-skill${NC}"
|
|
11039
|
+
_doctor_block "$sname is a broken symlink. Fix: loki setup-skill"
|
|
11027
11040
|
fail_count=$((fail_count + 1))
|
|
11028
11041
|
else
|
|
11029
11042
|
echo -e " ${YELLOW}WARN${NC} $sname ${DIM}(not found - run 'loki setup-skill')${NC}"
|
|
@@ -11187,6 +11200,7 @@ except Exception:
|
|
|
11187
11200
|
if [ -n "$disk_avail" ] && [ "$disk_avail" -gt 0 ] 2>/dev/null; then
|
|
11188
11201
|
if [ "$disk_avail" -lt 1 ]; then
|
|
11189
11202
|
echo -e " ${RED}FAIL${NC} Disk space: ${disk_avail}GB available (need >= 1GB)"
|
|
11203
|
+
_doctor_block "Free up disk: ${disk_avail}GB available, need >= 1GB"
|
|
11190
11204
|
fail_count=$((fail_count + 1))
|
|
11191
11205
|
elif [ "$disk_avail" -lt 5 ]; then
|
|
11192
11206
|
echo -e " ${YELLOW}WARN${NC} Disk space: ${disk_avail}GB available (low)"
|
|
@@ -11289,8 +11303,11 @@ except Exception:
|
|
|
11289
11303
|
echo ""
|
|
11290
11304
|
|
|
11291
11305
|
if [ "$fail_count" -gt 0 ]; then
|
|
11292
|
-
echo -e "${RED}
|
|
11293
|
-
|
|
11306
|
+
echo -e "${RED}Blocking ($fail_count). Everything else above is optional.${NC}"
|
|
11307
|
+
printf '%b\n' "$_doctor_blockers"
|
|
11308
|
+
echo ""
|
|
11309
|
+
echo "Then re-run: loki doctor"
|
|
11310
|
+
echo "Meanwhile 'loki tour' works right now -- no provider, no key, no spend."
|
|
11294
11311
|
return 1
|
|
11295
11312
|
elif [ "$warn_count" -gt 0 ]; then
|
|
11296
11313
|
echo -e "${YELLOW}All required checks passed with some warnings.${NC}"
|
|
@@ -19104,7 +19121,7 @@ $(cat "$f" 2>/dev/null)
|
|
|
19104
19121
|
|
|
19105
19122
|
# --- Tally results ---
|
|
19106
19123
|
local count_critical=0 count_high=0 count_medium=0 count_low=0 count_info=0
|
|
19107
|
-
for f in "${findings[@]}"; do
|
|
19124
|
+
for f in "${findings[@]+"${findings[@]}"}"; do
|
|
19108
19125
|
local sev
|
|
19109
19126
|
sev=$(echo "$f" | cut -d'|' -f3)
|
|
19110
19127
|
case "$sev" in
|
|
@@ -19126,7 +19143,7 @@ $(cat "$f" 2>/dev/null)
|
|
|
19126
19143
|
if [ "$review_format" = "json" ]; then
|
|
19127
19144
|
local json_findings="["
|
|
19128
19145
|
local first=true
|
|
19129
|
-
for f in "${findings[@]}"; do
|
|
19146
|
+
for f in "${findings[@]+"${findings[@]}"}"; do
|
|
19130
19147
|
local f_file f_line f_sev f_cat f_finding f_suggestion
|
|
19131
19148
|
f_file=$(echo "$f" | cut -d'|' -f1)
|
|
19132
19149
|
f_line=$(echo "$f" | cut -d'|' -f2)
|
|
@@ -19155,7 +19172,7 @@ $(cat "$f" 2>/dev/null)
|
|
|
19155
19172
|
# Group by severity
|
|
19156
19173
|
for sev_name in CRITICAL HIGH MEDIUM LOW INFO; do
|
|
19157
19174
|
local printed_header=false
|
|
19158
|
-
for f in "${findings[@]}"; do
|
|
19175
|
+
for f in "${findings[@]+"${findings[@]}"}"; do
|
|
19159
19176
|
local f_sev
|
|
19160
19177
|
f_sev=$(echo "$f" | cut -d'|' -f3)
|
|
19161
19178
|
[ "$f_sev" != "$sev_name" ] && continue
|
|
@@ -30081,7 +30098,7 @@ TEST_SUGGEST_PY
|
|
|
30081
30098
|
|
|
30082
30099
|
# --- Tally findings ---
|
|
30083
30100
|
local count_critical=0 count_high=0 count_medium=0 count_low=0 count_info=0
|
|
30084
|
-
for f in "${findings[@]}"; do
|
|
30101
|
+
for f in "${findings[@]+"${findings[@]}"}"; do
|
|
30085
30102
|
local sev
|
|
30086
30103
|
sev=$(echo "$f" | cut -d'|' -f3)
|
|
30087
30104
|
case "$sev" in
|
|
@@ -30097,7 +30114,7 @@ TEST_SUGGEST_PY
|
|
|
30097
30114
|
# Determine exit code based on --fail-on threshold
|
|
30098
30115
|
local exit_code=0
|
|
30099
30116
|
if [ "$fail_threshold" -lt 99 ]; then
|
|
30100
|
-
for f in "${findings[@]}"; do
|
|
30117
|
+
for f in "${findings[@]+"${findings[@]}"}"; do
|
|
30101
30118
|
local sev sev_num
|
|
30102
30119
|
sev=$(echo "$f" | cut -d'|' -f3)
|
|
30103
30120
|
sev_num=$(_ci_sev_level "$sev")
|
|
@@ -30117,7 +30134,7 @@ TEST_SUGGEST_PY
|
|
|
30117
30134
|
if [ "$ci_format" = "json" ]; then
|
|
30118
30135
|
# JSON output via python for proper escaping
|
|
30119
30136
|
export LOKI_CI_JSON_FINDINGS=""
|
|
30120
|
-
for f in "${findings[@]}"; do
|
|
30137
|
+
for f in "${findings[@]+"${findings[@]}"}"; do
|
|
30121
30138
|
LOKI_CI_JSON_FINDINGS+="${f}"$'\n'
|
|
30122
30139
|
done
|
|
30123
30140
|
export LOKI_CI_JSON_META="ci_env=${ci_env}|pr=${ci_pr_number}|ts=${report_timestamp}|files=${file_count}|exit=${exit_code}"
|
|
@@ -30199,7 +30216,7 @@ CI_JSON_OUT
|
|
|
30199
30216
|
echo ""
|
|
30200
30217
|
for sev_name in CRITICAL HIGH MEDIUM LOW INFO; do
|
|
30201
30218
|
local has_sev=false
|
|
30202
|
-
for f in "${findings[@]}"; do
|
|
30219
|
+
for f in "${findings[@]+"${findings[@]}"}"; do
|
|
30203
30220
|
local f_sev
|
|
30204
30221
|
f_sev=$(echo "$f" | cut -d'|' -f3)
|
|
30205
30222
|
[ "$f_sev" != "$sev_name" ] && continue
|
|
@@ -30259,7 +30276,7 @@ for t in tests:
|
|
|
30259
30276
|
else
|
|
30260
30277
|
for sev_name in CRITICAL HIGH MEDIUM LOW INFO; do
|
|
30261
30278
|
local printed_header=false
|
|
30262
|
-
for f in "${findings[@]}"; do
|
|
30279
|
+
for f in "${findings[@]+"${findings[@]}"}"; do
|
|
30263
30280
|
local f_sev
|
|
30264
30281
|
f_sev=$(echo "$f" | cut -d'|' -f3)
|
|
30265
30282
|
[ "$f_sev" != "$sev_name" ] && continue
|
package/dashboard/__init__.py
CHANGED
package/docs/COMPARISON.md
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
# Autonomous Coding Agents Comparison (2025-2026)
|
|
2
2
|
|
|
3
|
-
> Last
|
|
3
|
+
> **STALE. Last updated January 25, 2026 against v2.36.9; the current release is
|
|
4
|
+
> v8.2.0.** Roughly six months and thirty releases of drift, and every cell in
|
|
5
|
+
> the grids below is a subjective grade assigned by the vendor being graded --
|
|
6
|
+
> which is exactly the kind of comparison a serious evaluator discounts.
|
|
7
|
+
>
|
|
8
|
+
> For claims you can actually check, see **[EVALUATING.md](EVALUATING.md)**: a
|
|
9
|
+
> runnable command next to every assertion, plus an explicit list of what we do
|
|
10
|
+
> not have. This file is kept for historical reference only.
|
|
4
11
|
>
|
|
5
12
|
> A comprehensive comparison of Loki Mode against major autonomous coding agents and AI IDEs in the market.
|
|
6
13
|
> Deep-dive comparisons validated by Opus feedback loops.
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# Evaluating Loki Mode
|
|
2
|
+
|
|
3
|
+
For someone deciding whether to trust an autonomous coding agent with a real
|
|
4
|
+
codebase. Every claim below has a command next to it. Run them; do not take our
|
|
5
|
+
word for it.
|
|
6
|
+
|
|
7
|
+
We have deliberately not written a feature grid scoring ourselves against ten
|
|
8
|
+
competitors. Those grids are written by the vendor being scored, the criteria
|
|
9
|
+
are chosen by the vendor, and no reader can check a single cell. This page only
|
|
10
|
+
makes claims you can falsify in a terminal.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## 1. The agent hands you a receipt, and it admits what it did not verify
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npx loki-mode tour # no install, no API key, no spend, no network
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Output includes:
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
Headline: VERIFIED WITH GAPS
|
|
24
|
+
|
|
25
|
+
| Files changed | 8 |
|
|
26
|
+
| Diff sha256 | c2be6fff3e774c387f276277b25fc424f07b667… |
|
|
27
|
+
| Tests | verified (node-test) |
|
|
28
|
+
| Build | not_run |
|
|
29
|
+
| Security | findings |
|
|
30
|
+
| Cost | $10.3218 |
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**What to notice:** the headline is not "SUCCESS". Build was not run. Security
|
|
34
|
+
has findings. The receipt says so on its own front page.
|
|
35
|
+
|
|
36
|
+
**Why that is the product.** Every coding agent reports its own completion, and
|
|
37
|
+
self-reporting is the thing they are structurally worst at. The receipt
|
|
38
|
+
separates deterministic FACTS (diff hash, test result, cost) from AI
|
|
39
|
+
ASSESSMENTS, because only four of our eight quality gates are agent-independent
|
|
40
|
+
and a receipt implying otherwise would be marketing.
|
|
41
|
+
|
|
42
|
+
**Check it yourself:** recompute the diff sha256 over the same range and confirm
|
|
43
|
+
it matches. If it does not, the receipt is worthless and you should not use us.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## 2. Verification runs air-gapped
|
|
48
|
+
|
|
49
|
+
Deterministic verification makes zero network calls, so it runs inside a
|
|
50
|
+
perimeter on code that may never leave the building.
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
bash tests/test-airgap-verify.sh
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
That test blackholes every proxy variable, strips the environment, and asserts a
|
|
57
|
+
real verdict still comes back. Measured: **8.43 ms**.
|
|
58
|
+
|
|
59
|
+
**Scope, stated honestly:** verification is air-gapped. **Generation is not.**
|
|
60
|
+
Every provider we ship calls a hosted API, and local-weight generation needs
|
|
61
|
+
models you would supply. We are not claiming the generation half, and any vendor
|
|
62
|
+
who claims a fully air-gapped LLM agent without shipping weights is worth a
|
|
63
|
+
second question.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## 3. On an existing codebase, the read-only path is genuinely read-only
|
|
68
|
+
|
|
69
|
+
Brownfield is the harder problem, and the reason to distrust an agent near it is
|
|
70
|
+
obvious. So the entry point writes nothing:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
loki modernize heal ./your-repo --assess
|
|
74
|
+
git status # clean. no scratch files, no .loki/, no commits.
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**Enforced, not promised:**
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
bash tests/test-brownfield-assess-readonly.sh
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
That test hashes every file before and after, compares HEAD, and requires a
|
|
84
|
+
clean working tree. It is content-addressed, so it does not care *how* a write
|
|
85
|
+
might happen.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## 4. The harness is model-invariant (and we do not overclaim it)
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
cat benchmarks/results/cross-model-eval.json
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
- **Claimed:** the same gates run, the same acceptance is checked, and the same
|
|
96
|
+
receipt semantics apply regardless of which model is behind it.
|
|
97
|
+
- **Explicitly NOT claimed:** identical quality or identical speed across
|
|
98
|
+
models. That is not deliverable and we do not assert it.
|
|
99
|
+
|
|
100
|
+
Measured runs are in that file with wall-clock and iteration counts. Two runs is
|
|
101
|
+
two runs; it is not a benchmark suite, and the file says so.
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## 5. Verification is fast enough to embed
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
python3 autonomy/lib/fast_verify.py --path . --diff-base HEAD~1
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Measured on this repository, 1,932 tracked source files: **11,040 ms before,
|
|
112
|
+
19 ms diff-scoped** (298 ms cold, 87 ms warm). That is the difference between a
|
|
113
|
+
check you run at the end and a check something else can call as a dependency.
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## What we do not have
|
|
118
|
+
|
|
119
|
+
Stating this plainly, because you will find it out anyway and it is cheaper for
|
|
120
|
+
both of us if you find it here.
|
|
121
|
+
|
|
122
|
+
- **No published enterprise case studies.** We have adoption signal (fork ratio
|
|
123
|
+
well above the norm for a tool this size) but no named enterprise references.
|
|
124
|
+
- **No independent third-party benchmark placement.** The SWE-bench Verified
|
|
125
|
+
leaderboard is months stale and every entry on it is self-reported, ours would
|
|
126
|
+
be too.
|
|
127
|
+
- **No audit of the closed-source products.** We have verified that seven open
|
|
128
|
+
harnesses (OpenHands, Cline, Aider, SWE-agent, Roo-Code, OpenCode, Continue)
|
|
129
|
+
publish no machine-checkable completion artifact. Cursor, Devin, Replit Agent
|
|
130
|
+
and Claude Code we have **not** audited feature by feature, so treat the
|
|
131
|
+
receipt as "unclaimed as far as we can verify", not as a proven first.
|
|
132
|
+
- **Generation is not air-gapped.** See section 2.
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## The one question worth asking any agent vendor
|
|
137
|
+
|
|
138
|
+
> When your agent says it finished, what artifact can I check that does not come
|
|
139
|
+
> from the agent's own narrative?
|
|
140
|
+
|
|
141
|
+
Ours is the Evidence Receipt, and section 1 is a two-minute test of whether the
|
|
142
|
+
answer holds up. Ask the same question everywhere else.
|
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.
|
|
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.1";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=56EE84E87CC3B43564756E2164756E21
|
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.3.1",
|
|
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.3.1",
|
|
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",
|