loki-mode 11.4.2 → 11.6.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.
Files changed (129) hide show
  1. package/SKILL.md +2 -2
  2. package/VERSION +1 -1
  3. package/autonomy/lib/chat.sh +6 -3
  4. package/autonomy/lib/engine10-push.sh +19 -1
  5. package/autonomy/lib/help-core.sh +1 -1
  6. package/autonomy/lib/proof-generator.py +23 -5
  7. package/autonomy/lib/proof-verify.py +607 -5
  8. package/autonomy/lib/run-summary.sh +17 -1
  9. package/autonomy/lib/setup-requirements.json +35 -0
  10. package/autonomy/loki +244 -237
  11. package/autonomy/notification-checker.py +1 -1
  12. package/autonomy/provider-offer.sh +95 -47
  13. package/autonomy/route.sh +38 -6
  14. package/autonomy/run.sh +42 -14
  15. package/autonomy/setup-wizard.sh +19 -10
  16. package/autonomy/verify.sh +40 -1
  17. package/completions/_loki +3 -1
  18. package/completions/loki.bash +9 -3
  19. package/dashboard/__init__.py +3 -10
  20. package/dashboard/control.py +5 -435
  21. package/docs/ARCHITECTURE.md +1 -2
  22. package/docs/CLI-CORE-VERBS.md +2 -6
  23. package/docs/CLI-REFERENCE.md +3 -1
  24. package/docs/COMPONENTS.md +0 -2
  25. package/docs/EVALUATING.md +27 -0
  26. package/docs/HARNESS-INTELLIGENCE-PLAN.md +20 -0
  27. package/docs/INSTALLATION.md +1 -1
  28. package/docs/KNOWN-ISSUES.md +10 -1
  29. package/docs/PROOF-PASSPORT.md +114 -0
  30. package/docs/alternative-installations.md +103 -0
  31. package/docs/authentication.md +19 -1
  32. package/docs/cost-controls.md +139 -0
  33. package/docs/dev/release-checklist.md +9 -8
  34. package/docs/enterprise/security.md +3 -234
  35. package/docs/environment-variables.md +36 -0
  36. package/docs/exit-codes.md +102 -2
  37. package/docs/spec-first-intent.md +29 -0
  38. package/docs/v10/ARCHITECT-CUTS.md +304 -0
  39. package/docs/v10/CLI-MODERN.md +2 -2
  40. package/docs/v10/DECISIONS.md +5 -5
  41. package/docs/v10/ENGINE.md +735 -267
  42. package/docs/v10/GUARDS.md +16 -14
  43. package/docs/v10/GUIDE.md +5 -7
  44. package/docs/v10/PROGRESS.md +12 -1
  45. package/docs/v11/MARKET-SLICES.md +1 -5
  46. package/integrations/openclaw/README.md +20 -0
  47. package/integrations/vibe-kanban.md +12 -50
  48. package/loki-ts/data/model-pricing.json +1 -0
  49. package/loki-ts/dist/loki.js +1156 -1103
  50. package/mcp/__init__.py +1 -1
  51. package/mcp/_sdk_loader.py +1 -1
  52. package/package.json +2 -2
  53. package/packages/control-plane/dist/server.js +2063 -1032
  54. package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
  55. package/plugins/loki-mode/README.md +41 -1
  56. package/plugins/loki-mode/commands/handoff.md +12 -0
  57. package/plugins/loki-mode/commands/loki-verify.md +9 -2
  58. package/plugins/loki-mode/commands/start.md +20 -0
  59. package/plugins/loki-mode/hooks/hooks.json +11 -0
  60. package/plugins/loki-mode/scripts/loki-stop-verify.sh +84 -0
  61. package/references/quality-control.md +1 -116
  62. package/skills/00-index.md +2 -2
  63. package/skills/artifacts.md +0 -22
  64. package/skills/production.md +2 -38
  65. package/web-app/dist/assets/{AdminPage-CYJ2BWRC.js → AdminPage-DhXdJNQk.js} +1 -1
  66. package/web-app/dist/assets/{Avatar-DdK4wynI.js → Avatar-ixVj76fM.js} +1 -1
  67. package/web-app/dist/assets/{Badge-CrX3MI7J.js → Badge-BGMSp22s.js} +1 -1
  68. package/web-app/dist/assets/{Button-709-wwGM.js → Button-pYJc32tG.js} +1 -1
  69. package/web-app/dist/assets/{CockpitPage-BapdTInO.js → CockpitPage-C1JBBouA.js} +1 -1
  70. package/web-app/dist/assets/{ComparePage-DT99pGvA.js → ComparePage-qD0NV4RK.js} +1 -1
  71. package/web-app/dist/assets/{ErrorBoundary-B0uJSys8.js → ErrorBoundary-C-yxO58j.js} +1 -1
  72. package/web-app/dist/assets/{EvidenceReceiptPanel-BtMFgElP.js → EvidenceReceiptPanel-ByPzuE1S.js} +1 -1
  73. package/web-app/dist/assets/{GitHubIssuesPanel-DjJuU941.js → GitHubIssuesPanel-BNv_2BEJ.js} +1 -1
  74. package/web-app/dist/assets/{GitHubPRsPanel-HXfEX1BC.js → GitHubPRsPanel-CuLZQ9CS.js} +1 -1
  75. package/web-app/dist/assets/{HomePage-Cqyves-S.js → HomePage-CS_FW8Je.js} +2 -2
  76. package/web-app/dist/assets/{LoginPage-jUbtC7_Y.js → LoginPage-DwiNf1Wm.js} +1 -1
  77. package/web-app/dist/assets/{MagicPage-DHRsqjgR.js → MagicPage-CmQybLPZ.js} +1 -1
  78. package/web-app/dist/assets/{MetricsPage-B-pED05R.js → MetricsPage-D9ERdpv8.js} +1 -1
  79. package/web-app/dist/assets/{NotFoundPage-CsbUs21R.js → NotFoundPage-D9ccgdbF.js} +1 -1
  80. package/web-app/dist/assets/{ProjectPage-BtlLEQwB.js → ProjectPage-B9Jslmgv.js} +3 -3
  81. package/web-app/dist/assets/{ProjectsPage-DaRbRjSp.js → ProjectsPage-DnU99Go2.js} +1 -1
  82. package/web-app/dist/assets/{SettingsPage-DALrtP3F.js → SettingsPage-DcTyx6wo.js} +1 -1
  83. package/web-app/dist/assets/{ShowcasePage-CoPHSNP0.js → ShowcasePage-jEY9ghSr.js} +1 -1
  84. package/web-app/dist/assets/{SystemSettingsPage-kOuSN50O.js → SystemSettingsPage-CSGltW-8.js} +1 -1
  85. package/web-app/dist/assets/{TeamsPage-DGWK0LMp.js → TeamsPage-gUuJXb9l.js} +1 -1
  86. package/web-app/dist/assets/{TemplatesPage-C-_10CwA.js → TemplatesPage-37Zhe--v.js} +1 -1
  87. package/web-app/dist/assets/{TerminalOutput-Cz_vPbXL.js → TerminalOutput-B09hRwaR.js} +1 -1
  88. package/web-app/dist/assets/{activity-icIsXJVa.js → activity-q_4MY9J0.js} +1 -1
  89. package/web-app/dist/assets/{bell-DbPR2_4r.js → bell-X8OC_PFP.js} +1 -1
  90. package/web-app/dist/assets/{bot-DvjP3Yh5.js → bot-C-N1PUOD.js} +1 -1
  91. package/web-app/dist/assets/{check-D1OBxHeU.js → check-B2c76Jmp.js} +1 -1
  92. package/web-app/dist/assets/{chevron-left-D09jDZ29.js → chevron-left-BF76YLNw.js} +1 -1
  93. package/web-app/dist/assets/{circle-alert-DyZMLOcC.js → circle-alert-AeFKBD8h.js} +1 -1
  94. package/web-app/dist/assets/{clock-CdpdJTId.js → clock-CiXRf-FH.js} +1 -1
  95. package/web-app/dist/assets/{cloud-CoLTlmoj.js → cloud-DKQ8SRJ5.js} +1 -1
  96. package/web-app/dist/assets/{code-xml-DrkE2ZZY.js → code-xml-DEb6jXWP.js} +1 -1
  97. package/web-app/dist/assets/{database-CMQQuM2R.js → database-6W7e-E9c.js} +1 -1
  98. package/web-app/dist/assets/{dollar-sign-CuioDaOG.js → dollar-sign-Ds2GOuyW.js} +1 -1
  99. package/web-app/dist/assets/{file-code-corner-Cx9j9K1S.js → file-code-corner-CZU0jg52.js} +1 -1
  100. package/web-app/dist/assets/{file-plus-CYD2zaaI.js → file-plus-DTVYnXCN.js} +1 -1
  101. package/web-app/dist/assets/{globe-6w-hnQkL.js → globe-0mUzKYDe.js} +1 -1
  102. package/web-app/dist/assets/{hammer-BpqtautL.js → hammer-BMHZg3YX.js} +1 -1
  103. package/web-app/dist/assets/{index-Dzs-9EgJ.js → index-BvOTvjax.js} +3 -3
  104. package/web-app/dist/assets/{layers-D5hd7jb7.js → layers-Df7TdcWB.js} +1 -1
  105. package/web-app/dist/assets/{loader-circle-C6Y9x_7H.js → loader-circle-kPsVfrSY.js} +1 -1
  106. package/web-app/dist/assets/{lock-D51L7rYh.js → lock-CXYcbEc5.js} +1 -1
  107. package/web-app/dist/assets/{package-BJF8hkP8.js → package-Cqhua1ID.js} +1 -1
  108. package/web-app/dist/assets/{plus-D5kUQ79n.js → plus-lseXhsn-.js} +1 -1
  109. package/web-app/dist/assets/{refresh-cw-BKdlCa7F.js → refresh-cw-OZriI6gD.js} +1 -1
  110. package/web-app/dist/assets/{rotate-ccw-_bd_YI1e.js → rotate-ccw-CKCfjPg8.js} +1 -1
  111. package/web-app/dist/assets/{scroll-text-DbkegIxF.js → scroll-text-DoVyyfKb.js} +1 -1
  112. package/web-app/dist/assets/{server-DAwqFIsq.js → server-DGy7TflW.js} +1 -1
  113. package/web-app/dist/assets/{shield-alert-BuR1tPHu.js → shield-alert-BCzRcMXi.js} +1 -1
  114. package/web-app/dist/assets/{thumbs-up-BF6p3mRd.js → thumbs-up-C_znJd5g.js} +1 -1
  115. package/web-app/dist/assets/{trash-2-BVpnkqqz.js → trash-2-BosCbeeA.js} +1 -1
  116. package/web-app/dist/assets/{trending-down-DpsDvRwW.js → trending-down-CkR5zDkV.js} +1 -1
  117. package/web-app/dist/assets/{trending-up-mFogTjt3.js → trending-up-DpUIfOH4.js} +1 -1
  118. package/web-app/dist/assets/{upload-4T8zpBsi.js → upload-CH9aKc8L.js} +1 -1
  119. package/web-app/dist/assets/{usePolling-DPXQv8WO.js → usePolling-pzxrHJeg.js} +1 -1
  120. package/web-app/dist/assets/{user-BYGIFaTm.js → user-B7OHa-VQ.js} +1 -1
  121. package/web-app/dist/index.html +1 -1
  122. package/dashboard/run.py +0 -63
  123. package/docs/openclaw-integration.md +0 -52
  124. package/docs/v10/HANDOFF-NEXT-WEEK.md +0 -40
  125. package/docs/v10/MORNING-BRIEF-1003.md +0 -25
  126. package/docs/v10/MORNING-BRIEF.md +0 -52
  127. package/docs/v10/TODO.md +0 -35
  128. package/mcp/resources.py +0 -351
  129. package/mcp/tools.py +0 -200
package/SKILL.md CHANGED
@@ -3,7 +3,7 @@ name: loki-mode
3
3
  description: An autonomous software factory that knows what it is supposed to deliver, and proves it did. Use when the user says Loki Mode or asks to build, fix or verify software autonomously.
4
4
  ---
5
5
 
6
- # Loki Mode v11.4.2
6
+ # Loki Mode v11.6.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
 
@@ -483,4 +483,4 @@ See `CHANGELOG.md` entries [7.5.7], [7.5.8], [7.5.13] for the per-fix list and r
483
483
 
484
484
  ---
485
485
 
486
- **v11.4.2 | [Autonomi](https://www.autonomi.dev/) flagship product | core skill**
486
+ **v11.6.0 | [Autonomi](https://www.autonomi.dev/) flagship product | core skill**
package/VERSION CHANGED
@@ -1 +1 @@
1
- 11.4.2
1
+ 11.6.0
@@ -107,7 +107,7 @@ _chat_attach_banner() {
107
107
  _chat_send() {
108
108
  local mode="$1" text="$2"
109
109
  if [ "$_CHAT_PROVIDER" = "claude" ]; then
110
- command -v claude >/dev/null 2>&1 || { echo "loki chat: claude CLI not found" >&2; return 1; }
110
+ command -v claude >/dev/null 2>&1 || { echo "loki chat: claude CLI not found. Fix (same as loki doctor):" >&2; _loki_req_fix_line claude >&2; return 1; }
111
111
  local -a args=(-p "$text" --append-system-prompt "$_LOKI_CHAT_SYSTEM_PROMPT")
112
112
  if [ "$mode" = "plan" ]; then args+=(--permission-mode plan); else args+=(--permission-mode acceptEdits); fi
113
113
  [ -n "$_CHAT_MODEL" ] && args+=(--model "$_CHAT_MODEL")
@@ -197,10 +197,13 @@ EOF
197
197
  # /run: the exact run the shell would give: loki start with this session's provider and model.
198
198
  # The summary prints at the end of the run; chat stays open afterwards.
199
199
  _chat_run_start() {
200
- local loki="$1" input="$2" rc=0
200
+ local loki="$1" input="$2" rc=0 t0=$SECONDS
201
201
  local -a args=("start" "$input" --provider "$_CHAT_PROVIDER")
202
202
  [ -n "$_CHAT_MODEL" ] && args+=(--model "$_CHAT_MODEL")
203
203
  "$loki" "${args[@]}" || rc=$?
204
+ # HANDOFF: same file loki start wrote, so chat and the shell show one review view
205
+ # (only when written during this run; a stale file from an earlier run is never shown)
206
+ if [ -f ".loki/review/HANDOFF.md" ] && [ -n "$(find ".loki/review/HANDOFF.md" -mmin "-$(( (SECONDS - t0) / 60 + 1 ))" 2>/dev/null)" ]; then cat ".loki/review/HANDOFF.md"; fi
204
207
  echo "(run finished, exit $rc; chat is still open)"
205
208
  return 0
206
209
  }
@@ -224,7 +227,7 @@ cmd_chat() {
224
227
  done
225
228
 
226
229
  if [ "$tui" = "1" ]; then
227
- command -v claude >/dev/null 2>&1 || { echo "loki chat: claude CLI not found" >&2; return 1; }
230
+ command -v claude >/dev/null 2>&1 || { echo "loki chat: claude CLI not found. Fix (same as loki doctor):" >&2; _loki_req_fix_line claude >&2; return 1; }
228
231
  local -a targs=(--append-system-prompt "$_LOKI_CHAT_SYSTEM_PROMPT")
229
232
  [ -n "${LOKI_MODEL:-}" ] && targs+=(--model "$LOKI_MODEL")
230
233
  exec claude "${targs[@]}"
@@ -95,6 +95,14 @@ _e10_local_push() {
95
95
  log_warn "Not pushing branch '$branch': it is (or may be) the default branch of $origin."
96
96
  return 2
97
97
  fi
98
+ # RECOVERY: remote already at the local commit means a prior attempt landed; push nothing.
99
+ local want have
100
+ want="$(_e10_git -C "$dir" rev-parse -q --verify "refs/heads/$branch" 2>/dev/null)" || want=""
101
+ have="$(_e10_git ls-remote "$origin" "refs/heads/$branch" 2>/dev/null | awk '{print $1; exit}')" || have=""
102
+ if [ -n "$want" ] && [ "$want" = "$have" ]; then
103
+ log_info "push skipped: remote already has $branch at ${want:0:12}"
104
+ return 0
105
+ fi
98
106
  tmp="$(mktemp -d "${TMPDIR:-/tmp}/loki-push.XXXXXX")" || return 1
99
107
  if _e10_git init -q --template= "$tmp" >/dev/null 2>&1 \
100
108
  && _e10_git -C "$tmp" fetch -q --no-tags --update-shallow "$dir" \
@@ -138,7 +146,17 @@ case "$mode" in
138
146
  printf 'local://%s#%s\n' "$_LOKI_PINNED_ORIGIN" "$branch"
139
147
  exit 0
140
148
  fi
141
- _loki_trusted_push _loki_with_github_tokens "$dir" "$branch" || die "push refused or failed (rc=$?)"
149
+ # RECOVERY: a resumed publish skips the push when the remote branch is already at the local commit.
150
+ _e10_want="$(_e10_git -C "$dir" rev-parse -q --verify "refs/heads/$branch" 2>/dev/null)" || _e10_want=""
151
+ _e10_have=""
152
+ case "$branch" in main | master | HEAD) ;; *)
153
+ _e10_have="$(_e10_gh api "repos/$_e10_repo/git/ref/heads/$branch" --jq .object.sha 2>/dev/null)" || _e10_have="" ;;
154
+ esac
155
+ if [ -n "$_e10_want" ] && [ "$_e10_want" = "$_e10_have" ]; then
156
+ log_info "push skipped: remote already has $branch at ${_e10_want:0:12}"
157
+ else
158
+ _loki_trusted_push _loki_with_github_tokens "$dir" "$branch" || die "push refused or failed (rc=$?)"
159
+ fi
142
160
  url="$(_e10_gh pr list --repo "$_e10_repo" --head "$branch" --state open --json url --jq '.[0].url')" \
143
161
  || die "gh pr list failed"
144
162
  if [ -z "$url" ] || [ "$url" = "null" ]; then
@@ -31,7 +31,7 @@ help_core_screen() {
31
31
  echo " agents Agent roles and routing (route shows where a task would go)"
32
32
  echo " doctor [--json] Check your setup is ready"
33
33
  echo ""
34
- echo "Options for 'start': --provider NAME, --model ID, --budget USD, --isolation LVL (isolation dial: none | worktree | docker)"
34
+ echo "Options for 'start': --provider NAME, --model ID, --budget USD (default cap $(loki_budget_default_usd 2>/dev/null)), --isolation LVL (isolation dial: none | worktree | docker)"
35
35
  echo "Also: cost / estimate (spend before you build), resume (continue a paused or interrupted run)"
36
36
  echo "Exit codes: docs/exit-codes.md"
37
37
  echo ""
@@ -40,6 +40,21 @@ from efficiency_cost import collect_efficiency as _collect_efficiency # noqa: E
40
40
  import effort_estimator # noqa: E402
41
41
  from tree_digest import MANIFEST_VERSION, compute_tree_digest # noqa: E402
42
42
  from workspace_diff import collect_workspace_diff # noqa: E402
43
+ import importlib.util as _ilu # noqa: E402
44
+
45
+
46
+ def _load_proof_verify_mod():
47
+ # proof-verify.py is hyphenated (not importable); it owns the verification record.
48
+ spec = _ilu.spec_from_file_location(
49
+ "loki_proof_verify", os.path.join(os.path.dirname(os.path.abspath(__file__)), "proof-verify.py"))
50
+ mod = _ilu.module_from_spec(spec)
51
+ spec.loader.exec_module(mod)
52
+ return mod
53
+
54
+
55
+ _PV = _load_proof_verify_mod()
56
+ _vr_capture_environment = _PV.capture_environment
57
+ _vr_git_dirty = _PV.git_dirty
43
58
 
44
59
 
45
60
  # ---------------------------------------------------------------------------
@@ -1121,8 +1136,6 @@ def _empty_tree_sha(repo_dir):
1121
1136
  # collect_workspace_diff), so uncommitted work is covered.
1122
1137
  _TI_CFG_ALWAYS = re.compile(r"(^|/)(conftest\.py|\.?pytest\.(?:ini|toml)|tox\.ini|jest\.config\.[\w.]+|vitest\.config\.[\w.]+|\.mocharc[\w.]*)$")
1123
1138
  _TI_CFG_SHARED = re.compile(r"(^|/)(setup\.cfg|pyproject\.toml|package\.json)$")
1124
- _TI_TEST_FILE = re.compile(
1125
- r"(^|/)(tests?|__tests__|spec|specs)/|\.(test|spec)\.[\w]+$|(^|/)test_[^/]*\.py$|_test\.(py|go|rs)$|(^|/)conftest\.py$")
1126
1139
  _TI_SKIP_JS = re.compile(
1127
1140
  # options object only as the 2nd argument: title (string or identifier), then `, {`
1128
1141
  r"\b(test|it|describe|suite|context|specify)\s*\(\s*(?:'[^'\n]*'|\"[^\"\n]*\"|`[^`\n]*`|[\w.$]+)\s*,\s*\{[^}]*\b(skip|todo)\s*:\s*(?!(?:false|0|null|undefined)\b)\S"
@@ -1270,7 +1283,7 @@ def _collect_tests_integrity(target_dir, base):
1270
1283
  if u and not u.startswith(".loki/"):
1271
1284
  entries.append(("A", u, u))
1272
1285
  for st, old, new in entries:
1273
- if st in ("D", "R") and _TI_TEST_FILE.search(old):
1286
+ if st in ("D", "R") and _PV._TEST_FILE.search(old):
1274
1287
  weakened.append("test file %s: %s" % ("deleted" if st == "D" else "renamed", old))
1275
1288
  if not greenfield:
1276
1289
  for st, old, new in entries:
@@ -1310,7 +1323,7 @@ def _collect_tests_integrity(target_dir, base):
1310
1323
  edited.append(cur)
1311
1324
  cur, rx, removed_assert = None, None, False
1312
1325
  elif line.startswith("+++ b/"):
1313
- cur = line[6:] if _TI_TEST_FILE.search(line[6:]) else None
1326
+ cur = line[6:] if _PV._TEST_FILE.search(line[6:]) else None
1314
1327
  rx = _ti_skip_re(cur) if cur else None
1315
1328
  elif cur and line.startswith("+") and rx and rx.search(line):
1316
1329
  weakened.append("skip added in %s" % cur)
@@ -1318,7 +1331,7 @@ def _collect_tests_integrity(target_dir, base):
1318
1331
  and _TI_ASSERT.search(line):
1319
1332
  removed_assert = True
1320
1333
  for u in untracked.split("\0"):
1321
- if not u or u.startswith(".loki/") or not _TI_TEST_FILE.search(u):
1334
+ if not u or u.startswith(".loki/") or not _PV._TEST_FILE.search(u):
1322
1335
  continue
1323
1336
  rx = _ti_skip_re(u)
1324
1337
  if not rx:
@@ -1625,6 +1638,9 @@ def _build_proof(args, loki_dir, target_dir, repo_root):
1625
1638
  # recompute it after runner exit to reject proofs followed by code edits.
1626
1639
  "tree_sha256": compute_tree_digest(target_dir),
1627
1640
  "tree_manifest_version": MANIFEST_VERSION,
1641
+ # Execution validity (docs/PROOF-PASSPORT.md): whether the tree
1642
+ # was dirty when the checks ran. None when git could not answer.
1643
+ "dirty": _vr_git_dirty(target_dir),
1628
1644
  }
1629
1645
  facts = {
1630
1646
  "git": git_facts,
@@ -1663,6 +1679,8 @@ def _build_proof(args, loki_dir, target_dir, repo_root):
1663
1679
  # Descriptive; NOT read by _compute_headline (gating is founder-gated).
1664
1680
  "healthcheck": healthcheck,
1665
1681
  "cost": cost,
1682
+ # Environment the checks ran in (measured at generation time).
1683
+ "environment": _vr_capture_environment(),
1666
1684
  "meta": {
1667
1685
  "run_id": run_id,
1668
1686
  "loki_version": loki_version,