loki-mode 11.55.2 → 11.56.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/lib/mcp-config.sh +131 -0
- package/dashboard/__init__.py +1 -1
- package/docs/CLI-REFERENCE.md +1 -1
- package/docs/INSTALLATION.md +1 -1
- package/docs/v10/FAILURE-CLASSES.md +12 -0
- package/loki-ts/dist/loki.js +420 -420
- package/mcp/__init__.py +1 -1
- package/package.json +2 -2
- package/packages/control-plane/dist/server.js +4 -1
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
- package/state/manager.ts +57 -14
- package/web-app/dist/assets/{AdminPage-Cq1bWFPJ.js → AdminPage-CmBpiMau.js} +1 -1
- package/web-app/dist/assets/{Avatar-DmLQK54Y.js → Avatar-DKMbfUD3.js} +1 -1
- package/web-app/dist/assets/{Badge-EDrJvqAV.js → Badge-BWnU7YEI.js} +1 -1
- package/web-app/dist/assets/{Button-BTayfRNs.js → Button-DySbWiB2.js} +1 -1
- package/web-app/dist/assets/{CockpitPage-DDxKaKAy.js → CockpitPage-DGn5dhOE.js} +1 -1
- package/web-app/dist/assets/{ComparePage-BEgcZF7Q.js → ComparePage-CWN21Av-.js} +1 -1
- package/web-app/dist/assets/{ErrorBoundary-DH7gH8tH.js → ErrorBoundary-BHRZHMSw.js} +1 -1
- package/web-app/dist/assets/{EvidenceReceiptPanel-BZrWS10j.js → EvidenceReceiptPanel-HZLbQdCW.js} +1 -1
- package/web-app/dist/assets/{GitHubIssuesPanel-TYn02Fhe.js → GitHubIssuesPanel-B9bjy9TY.js} +1 -1
- package/web-app/dist/assets/{GitHubPRsPanel-C9w7zI6N.js → GitHubPRsPanel-CXExgqa1.js} +1 -1
- package/web-app/dist/assets/{HomePage-Ct9msy_p.js → HomePage-C6T4CLSu.js} +2 -2
- package/web-app/dist/assets/{LoginPage-WRpEJmns.js → LoginPage-D0ikzScF.js} +1 -1
- package/web-app/dist/assets/{MagicPage-DJiL6WqU.js → MagicPage-BAOn7PDD.js} +1 -1
- package/web-app/dist/assets/{MetricsPage-2CMKR2Sq.js → MetricsPage-CeH7REnD.js} +1 -1
- package/web-app/dist/assets/{NotFoundPage-Cq2cofyE.js → NotFoundPage-hRysg98x.js} +1 -1
- package/web-app/dist/assets/{ProjectPage-CJjNZdid.js → ProjectPage-CTnLYbKK.js} +3 -3
- package/web-app/dist/assets/{ProjectsPage-7ApVblSL.js → ProjectsPage-DfV2rDNy.js} +1 -1
- package/web-app/dist/assets/{SettingsPage-D5YSUgYn.js → SettingsPage-PDKi8rW-.js} +1 -1
- package/web-app/dist/assets/{ShowcasePage-BORv96H6.js → ShowcasePage-DAXMeHi2.js} +1 -1
- package/web-app/dist/assets/{SystemSettingsPage-DAcoP_xM.js → SystemSettingsPage-w4wEFQ-w.js} +1 -1
- package/web-app/dist/assets/{TeamsPage-Dw032JqQ.js → TeamsPage-M2T8vLDC.js} +1 -1
- package/web-app/dist/assets/{TemplatesPage-BG6bVuMJ.js → TemplatesPage-tWDJLI_1.js} +1 -1
- package/web-app/dist/assets/{TerminalOutput-BB69c1HU.js → TerminalOutput-E9vOt7lb.js} +1 -1
- package/web-app/dist/assets/{activity-TmFvslmE.js → activity-pkruUWrS.js} +1 -1
- package/web-app/dist/assets/{bell-BU2erY_i.js → bell-QWwy_DqT.js} +1 -1
- package/web-app/dist/assets/{bot-DMpSqrIl.js → bot-EkuURDPq.js} +1 -1
- package/web-app/dist/assets/{check-B6QVSMTJ.js → check-gjOQFxmN.js} +1 -1
- package/web-app/dist/assets/{chevron-left-CPeGOhGt.js → chevron-left-CCsNBJRT.js} +1 -1
- package/web-app/dist/assets/{circle-alert-Cwtuu2Xr.js → circle-alert-tbh0eotU.js} +1 -1
- package/web-app/dist/assets/{clock-CwRw08oZ.js → clock-jAqMaUbM.js} +1 -1
- package/web-app/dist/assets/{cloud-DGl4zUQq.js → cloud-BkzP_2O3.js} +1 -1
- package/web-app/dist/assets/{code-xml-CJ-Q1knR.js → code-xml-BO_XLft5.js} +1 -1
- package/web-app/dist/assets/{database-z-xWVQ5b.js → database-BEYnSD3y.js} +1 -1
- package/web-app/dist/assets/{dollar-sign-Cvd44aa9.js → dollar-sign-DCS-4ENC.js} +1 -1
- package/web-app/dist/assets/{file-code-corner-D14LpiMK.js → file-code-corner-CC-AAFuP.js} +1 -1
- package/web-app/dist/assets/{file-plus-ttJnTDT_.js → file-plus-DARaysVE.js} +1 -1
- package/web-app/dist/assets/{globe-DuP7Cua6.js → globe-BChKv8f3.js} +1 -1
- package/web-app/dist/assets/{hammer-CYq2GDHm.js → hammer-NDAi7rpO.js} +1 -1
- package/web-app/dist/assets/{index-CT2oE8Kl.js → index-CfqkxH90.js} +3 -3
- package/web-app/dist/assets/{layers-Bc8WbT9k.js → layers-eMnPES9D.js} +1 -1
- package/web-app/dist/assets/{loader-circle-d2mz7LEV.js → loader-circle-BPBq3q2l.js} +1 -1
- package/web-app/dist/assets/{lock-Ck5Mh1rN.js → lock-Duh0wVt3.js} +1 -1
- package/web-app/dist/assets/{package-BQ9Z6lZq.js → package-DFF4Bb2P.js} +1 -1
- package/web-app/dist/assets/{plus-CM2G1mBi.js → plus-Dlr8W3yV.js} +1 -1
- package/web-app/dist/assets/{refresh-cw-C-UsEISU.js → refresh-cw-DgxH4bSy.js} +1 -1
- package/web-app/dist/assets/{rotate-ccw-BUVkLdye.js → rotate-ccw-DU-Os9wC.js} +1 -1
- package/web-app/dist/assets/{scroll-text-C4dsalAn.js → scroll-text-S4t8mHDF.js} +1 -1
- package/web-app/dist/assets/{server-C-PwNJQZ.js → server-SN6JNCdM.js} +1 -1
- package/web-app/dist/assets/{shield-alert-xlj61qF3.js → shield-alert-CIBehVkH.js} +1 -1
- package/web-app/dist/assets/{thumbs-up-hqfY-fuM.js → thumbs-up-CJ4n3c2X.js} +1 -1
- package/web-app/dist/assets/{trash-2-DeJLxH-E.js → trash-2-BKj6RtAL.js} +1 -1
- package/web-app/dist/assets/{trending-down-DZ8saztL.js → trending-down-DGQkEa36.js} +1 -1
- package/web-app/dist/assets/{trending-up-eNGjwokM.js → trending-up-CNbeB3P5.js} +1 -1
- package/web-app/dist/assets/{upload-Dno5mkwT.js → upload-BcCti89m.js} +1 -1
- package/web-app/dist/assets/{usePolling-CS6DDczq.js → usePolling-6qsv_mtm.js} +1 -1
- package/web-app/dist/assets/{user-CmMF5dGD.js → user-7N9sAvJt.js} +1 -1
- package/web-app/dist/index.html +1 -1
package/SKILL.md
CHANGED
|
@@ -3,7 +3,7 @@ name: loki-mode
|
|
|
3
3
|
description: Runs an autonomous software factory that knows what it is supposed to deliver and proves it did, with a signed receipt. Use when the user says Loki Mode or asks to build, fix or verify software autonomously.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Loki Mode v11.
|
|
6
|
+
# Loki Mode v11.56.0
|
|
7
7
|
|
|
8
8
|
**Current entry points (Loki 10 engine):** `loki "<task>"`, `loki owner/repo#N` and `loki quick "<task>"` run the Loki 10 engine and end with a signed receipt (`loki verify`). `loki backlog owner/repo --all` runs many issues in parallel. Guide: `docs/v10/GUIDE.md`. The skill instructions below, and `loki start`, describe the previous bash loop. PRD-file starts (`loki start ./prd.md`) and the opencode provider still run on it until FC38-SWEEP ports them; the legacy-engine command and the LOKI_ENGINE switch remain removed. Prefer `loki owner/repo#N` for issues.
|
|
9
9
|
|
|
@@ -476,4 +476,4 @@ Implemented, planned and deprecated items, with the version each landed in: `ski
|
|
|
476
476
|
|
|
477
477
|
---
|
|
478
478
|
|
|
479
|
-
**v11.
|
|
479
|
+
**v11.56.0 | [Autonomi](https://www.autonomi.dev/) flagship product | core skill**
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
11.
|
|
1
|
+
11.56.0
|
|
@@ -27,6 +27,11 @@
|
|
|
27
27
|
# element to satisfy Claude's variadic flag.
|
|
28
28
|
# Returns 0 on success, 1 if the bundle
|
|
29
29
|
# emission fails.
|
|
30
|
+
# loki_mcp_launch_for -- emit the per-provider MCP launch as one compact JSON
|
|
31
|
+
# object {"argv":[..],"env":{..}[,"reason":".."]}
|
|
32
|
+
# for claude|codex|opencode|cline|aider. Mirror of
|
|
33
|
+
# mcpLaunchFor in loki-ts/src/providers/mcp_config.ts;
|
|
34
|
+
# tests/providers parity test reads both.
|
|
30
35
|
#
|
|
31
36
|
# No side effects beyond writing .loki/mcp-config.json (idempotent;
|
|
32
37
|
# regenerated each call).
|
|
@@ -183,3 +188,129 @@ loki_mcp_config_argv() {
|
|
|
183
188
|
fi
|
|
184
189
|
return 0
|
|
185
190
|
}
|
|
191
|
+
|
|
192
|
+
# ---------- Per-provider MCP launch (CW-10) ----------
|
|
193
|
+
# Usage: loki_mcp_launch_for <provider> [target_dir]
|
|
194
|
+
# claude: the pre-CW-10 --mcp-config paths, unchanged. codex: `-c mcp_servers.*`
|
|
195
|
+
# overrides. opencode: env OPENCODE_CONFIG_CONTENT. cline/aider/unknown: empty
|
|
196
|
+
# launch plus a reason. Servers for codex/opencode: Loki bundle, project
|
|
197
|
+
# <target_dir>/.mcp.json only when LOKI_MCP_PROJECT=1, ~/.claude/mcp.json overlay;
|
|
198
|
+
# bundle wins a name collision, then project over overlay. `${...}` stays literal.
|
|
199
|
+
loki_mcp_launch_for() {
|
|
200
|
+
local provider="${1:-}" target="${2:-${TARGET_DIR:-.}}"
|
|
201
|
+
local claude_argv="" user_path="" project_path="" lsp_detected=0 lsp_bin cline_ver="unknown" line
|
|
202
|
+
case "$provider" in
|
|
203
|
+
claude)
|
|
204
|
+
claude_argv=$(TARGET_DIR="$target" loki_mcp_config_argv) || return 1
|
|
205
|
+
;;
|
|
206
|
+
codex | opencode)
|
|
207
|
+
TARGET_DIR="$target" loki_mcp_config_path >/dev/null || return 1
|
|
208
|
+
user_path=$(loki_user_mcp_config_path)
|
|
209
|
+
if [ "${LOKI_MCP_PROJECT:-}" = "1" ]; then
|
|
210
|
+
project_path="${target}/.mcp.json"
|
|
211
|
+
fi
|
|
212
|
+
for lsp_bin in typescript-language-server pyright-langserver pylsp gopls rust-analyzer jdtls; do
|
|
213
|
+
if command -v "$lsp_bin" >/dev/null 2>&1; then
|
|
214
|
+
lsp_detected=1
|
|
215
|
+
break
|
|
216
|
+
fi
|
|
217
|
+
done
|
|
218
|
+
;;
|
|
219
|
+
cline)
|
|
220
|
+
if command -v cline >/dev/null 2>&1; then
|
|
221
|
+
line=$(cline --version 2>/dev/null | head -n 1) || line=""
|
|
222
|
+
line="${line#"${line%%[![:space:]]*}"}"
|
|
223
|
+
line="${line%"${line##*[![:space:]]}"}"
|
|
224
|
+
[ -n "$line" ] && cline_ver="$line"
|
|
225
|
+
fi
|
|
226
|
+
;;
|
|
227
|
+
esac
|
|
228
|
+
_MCP_PROVIDER="$provider" _MCP_CLAUDE_ARGV="$claude_argv" _MCP_USER="$user_path" _MCP_PROJECT="$project_path" _MCP_LSP="$lsp_detected" _MCP_CLINE_VER="$cline_ver" python3 -c '
|
|
229
|
+
import json, os, re
|
|
230
|
+
prov = os.environ["_MCP_PROVIDER"]
|
|
231
|
+
NAME = re.compile(r"^[A-Za-z0-9_-]+$")
|
|
232
|
+
MAXB = 1024 * 1024
|
|
233
|
+
|
|
234
|
+
def norm(raw):
|
|
235
|
+
out = {}
|
|
236
|
+
if not isinstance(raw, dict):
|
|
237
|
+
return out
|
|
238
|
+
for name, e in raw.items():
|
|
239
|
+
if not NAME.match(name) or not isinstance(e, dict):
|
|
240
|
+
continue
|
|
241
|
+
cmd = e.get("command")
|
|
242
|
+
if not isinstance(cmd, str) or not cmd:
|
|
243
|
+
continue
|
|
244
|
+
args = e.get("args", [])
|
|
245
|
+
if not isinstance(args, list) or not all(isinstance(a, str) for a in args):
|
|
246
|
+
continue
|
|
247
|
+
env = e.get("env", {})
|
|
248
|
+
if not isinstance(env, dict) or not all(isinstance(v, str) for v in env.values()):
|
|
249
|
+
continue
|
|
250
|
+
out[name] = {"command": cmd, "args": args, "env": env}
|
|
251
|
+
return out
|
|
252
|
+
|
|
253
|
+
def load(p):
|
|
254
|
+
if not p:
|
|
255
|
+
return {}
|
|
256
|
+
try:
|
|
257
|
+
if not os.path.isfile(p) or os.path.getsize(p) > MAXB:
|
|
258
|
+
return {}
|
|
259
|
+
with open(p, encoding="utf-8") as h:
|
|
260
|
+
v = json.load(h)
|
|
261
|
+
return norm(v.get("mcpServers")) if isinstance(v, dict) else {}
|
|
262
|
+
except (OSError, ValueError):
|
|
263
|
+
return {}
|
|
264
|
+
|
|
265
|
+
def dumps(v):
|
|
266
|
+
return json.dumps(v, ensure_ascii=False, separators=(",", ":"))
|
|
267
|
+
|
|
268
|
+
def servers():
|
|
269
|
+
merged = {}
|
|
270
|
+
merged.update(load(os.environ["_MCP_USER"]))
|
|
271
|
+
merged.update(load(os.environ["_MCP_PROJECT"]))
|
|
272
|
+
bundle = {"loki-mode": {"command": "python3", "args": ["-m", "mcp.server"]}}
|
|
273
|
+
if os.environ["_MCP_LSP"] == "1":
|
|
274
|
+
bundle["lsp-proxy"] = {"command": "python3", "args": ["-m", "mcp.lsp_proxy"]}
|
|
275
|
+
merged.update(norm(bundle))
|
|
276
|
+
ordered = {k: merged[k] for k in bundle}
|
|
277
|
+
for k, v in merged.items():
|
|
278
|
+
if k not in ordered:
|
|
279
|
+
ordered[k] = v
|
|
280
|
+
return ordered
|
|
281
|
+
|
|
282
|
+
res = {"argv": [], "env": {}}
|
|
283
|
+
if prov == "claude":
|
|
284
|
+
res["argv"] = ["--mcp-config"] + os.environ["_MCP_CLAUDE_ARGV"].split()
|
|
285
|
+
elif prov == "codex":
|
|
286
|
+
skipped = []
|
|
287
|
+
for n, s in servers().items():
|
|
288
|
+
names = [k for k in s["env"] if NAME.match(k)]
|
|
289
|
+
if any(k in res["env"] and res["env"][k] != s["env"][k] for k in names):
|
|
290
|
+
skipped.append(n)
|
|
291
|
+
continue
|
|
292
|
+
res["argv"] += ["-c", "mcp_servers.%s.command=%s" % (n, dumps(s["command"]))]
|
|
293
|
+
res["argv"] += ["-c", "mcp_servers.%s.args=%s" % (n, dumps(s["args"]))]
|
|
294
|
+
if names:
|
|
295
|
+
for k in names:
|
|
296
|
+
res["env"][k] = s["env"][k]
|
|
297
|
+
res["argv"] += ["-c", "mcp_servers.%s.env_vars=%s" % (n, dumps(names))]
|
|
298
|
+
if skipped:
|
|
299
|
+
res["reason"] = "mcp: skipped %s (env name conflict)" % ",".join(skipped)
|
|
300
|
+
elif prov == "opencode":
|
|
301
|
+
mcp = {}
|
|
302
|
+
for n, s in servers().items():
|
|
303
|
+
e = {"type": "local", "command": [s["command"]] + s["args"], "enabled": True}
|
|
304
|
+
if s["env"]:
|
|
305
|
+
e["environment"] = s["env"]
|
|
306
|
+
mcp[n] = e
|
|
307
|
+
res["env"] = {"OPENCODE_CONFIG_CONTENT": dumps({"mcp": mcp})}
|
|
308
|
+
elif prov == "cline":
|
|
309
|
+
res["reason"] = "mcp: unsupported (cline %s)" % os.environ["_MCP_CLINE_VER"]
|
|
310
|
+
elif prov == "aider":
|
|
311
|
+
res["reason"] = "mcp: unsupported (aider has no MCP support)"
|
|
312
|
+
else:
|
|
313
|
+
res["reason"] = "mcp: unsupported (provider %s)" % prov
|
|
314
|
+
print(dumps(res))
|
|
315
|
+
'
|
|
316
|
+
}
|
package/dashboard/__init__.py
CHANGED
package/docs/CLI-REFERENCE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# CLI reference
|
|
2
2
|
|
|
3
|
-
Generated from `loki-ts/src/cli/registry.ts` by `scripts/generate-stale-zero.sh` for v11.
|
|
3
|
+
Generated from `loki-ts/src/cli/registry.ts` by `scripts/generate-stale-zero.sh` for v11.56.0. Do not edit by hand.
|
|
4
4
|
Hidden and legacy-only commands are omitted; see `docs/v10/CLI-MODERN.md` for the full inventory.
|
|
5
5
|
|
|
6
6
|
| Command | Description |
|
package/docs/INSTALLATION.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Loki Mode, by [Autonomi](https://www.autonomi.dev/), turns a spec or an issue into a verified pull request with a receipt you can check. This page covers installing it, a first run, and the options around it.
|
|
4
4
|
|
|
5
|
-
**Version:** v11.
|
|
5
|
+
**Version:** v11.56.0
|
|
6
6
|
|
|
7
7
|
**Engine note:** `loki start` is the primary command. `loki start`, `loki "<task>"`, `loki owner/repo#N` and `loki quick` all run the Loki 10 engine, whatever the flag order or input form (PRD file, issue ref, task or one-word brief). The previous loop runs only on `--engine legacy`, `LOKI_ENGINE=legacy`, or for one call when a flag Loki 10 cannot honor is present. See the [user guide](v10/GUIDE.md) and the [5-minute quickstart](QUICKSTART.md).
|
|
8
8
|
|
|
@@ -1443,3 +1443,15 @@ L0 review rule (ENGINE-LAWS.md L0): a fix that adds an `if` or a regex about the
|
|
|
1443
1443
|
- Siblings swept: all 14 literals in loki-ts/tests, replaced in one change; per-test `, N)` timeouts are explicit single-test budgets and are not in this class.
|
|
1444
1444
|
- Mechanism: loki-ts/tests/preload.ts exports `setLoadAwareTimeout(baseMs)`: baseMs times clamp(ceil(2 * loadavg1 / cpus), 1, 10). `LOKI_TEST_TIMEOUT_SCALE` (positive number, capped at 10) replaces the factor; `LOKI_TEST_TIMEOUT_MS` is a floor that wins when larger. A guard in loki-ts/tests/util fails on any direct `setDefaultTimeout(` call in tests.
|
|
1445
1445
|
- Fixture: loki-ts/tests/util/test_timeout_guard.test.ts tests FC-TEST-TIMEOUT-OVERRIDES-CLI, including a subprocess run through the real setLoadAwareTimeout path (env knob lifts the budget, a real hang still times out).
|
|
1446
|
+
|
|
1447
|
+
- Siblings swept: every registered MCP tool and resource, via the runtime-derived guard in tests/mcp/test_phase1_tools.py (seeds this cache with the marker; the observer now also sees os.scandir, os.stat, Path.iterdir and glob); the JS mirror declares its fields in src/protocols and counts them in tests/protocols/mcp-server.test.js.
|
|
1448
|
+
- Mechanism: part 1 (this change) moves loki_verify_fast findings under untrusted_content via _UNTRUSTED_FIELDS. The verdict-suppression half is open in #319 (cache entries must be authenticated or re-derived, then the row is closed).
|
|
1449
|
+
- Fixture: tests/mcp/test_phase1_tools.py test_stored_text_appears_only_inside_untrusted_content (red with loki_verify_fast trusted: leaks ['loki_verify_fast']; green after).
|
|
1450
|
+
|
|
1451
|
+
## FC-STATE-MANAGER-ROOT-IGNORED A process-wide state manager singleton ignored its lokiDir after first use, and a per-root cache would grow without bound
|
|
1452
|
+
- User-visible vs raw: user-visible. getStateManager({ lokiDir }) for a second .loki directory returned the first directory's manager, so reads and writes for run B landed in run A's state; a long-lived process serving many roots would have leaked one open watcher per root once keyed naively.
|
|
1453
|
+
- Law: a keyed accessor honours its key on every call; a cache that holds OS resources is bounded and releases what it evicts.
|
|
1454
|
+
- Cause (measured): state/manager.ts kept one module-level defaultManager and created it from the first call's options only.
|
|
1455
|
+
- Siblings swept: state/manager.py get_state_manager has the same single-default shape and is to follow the same keying rule (separate branch); no other TS caller passes arguments to getStateManager.
|
|
1456
|
+
- Mechanism: one per-root cache in state/manager.ts keyed by the (st_dev, st_ino) of the .loki directory (symlinks and case spellings share a manager), capped by LOKI_STATE_MANAGER_MAX (default 8), least recently used evicted and stop()ped.
|
|
1457
|
+
- Fixture: loki-ts/tests/state_manager.test.ts (under loki-ts so bun and CI discover it). Red on origin/main (2 fail), green after (5 pass or 4 pass and 1 skip on a case-sensitive volume); mutations: no eviction, eviction without stop, path-string key, constant key, no LRU touch each go red.
|