loki-mode 11.91.0 → 11.92.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 (75) hide show
  1. package/SKILL.md +2 -2
  2. package/VERSION +1 -1
  3. package/autonomy/completion-council.sh +16 -2
  4. package/autonomy/council-v2.sh +10 -2
  5. package/autonomy/grill.sh +4 -1
  6. package/autonomy/lib/done-recognition.sh +12 -4
  7. package/autonomy/lib/prd-enrich.sh +5 -2
  8. package/autonomy/lib/voter-agents.sh +1 -1
  9. package/autonomy/loki +77 -30
  10. package/autonomy/quickstart.sh +13 -2
  11. package/dashboard/__init__.py +1 -1
  12. package/docs/CLI-REFERENCE.md +1 -1
  13. package/docs/INSTALLATION.md +1 -1
  14. package/loki-ts/dist/loki.js +1355 -1354
  15. package/mcp/__init__.py +1 -1
  16. package/package.json +2 -2
  17. package/packages/control-plane/dist/server.js +1444 -1342
  18. package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
  19. package/web-app/dist/assets/{AdminPage-9ggwVri1.js → AdminPage-2eApQhkp.js} +1 -1
  20. package/web-app/dist/assets/{Avatar-B8FkIL3q.js → Avatar-V-WXQ0hZ.js} +1 -1
  21. package/web-app/dist/assets/{Badge-DUwOrMSE.js → Badge-uw9uv8IY.js} +1 -1
  22. package/web-app/dist/assets/{Button-CfNOtUNu.js → Button-34AooGBc.js} +1 -1
  23. package/web-app/dist/assets/{CockpitPage-Tp4zfLg3.js → CockpitPage-DHVPvw4u.js} +1 -1
  24. package/web-app/dist/assets/{ComparePage-CazDogm2.js → ComparePage-CXuFkRpn.js} +1 -1
  25. package/web-app/dist/assets/{ErrorBoundary-CSOUEOuI.js → ErrorBoundary-DpPNWkHN.js} +1 -1
  26. package/web-app/dist/assets/{EvidenceReceiptPanel-BPny501Q.js → EvidenceReceiptPanel-C3Mc9c1x.js} +1 -1
  27. package/web-app/dist/assets/{GitHubIssuesPanel-BhtfBprx.js → GitHubIssuesPanel-Bsqa3l6c.js} +1 -1
  28. package/web-app/dist/assets/{GitHubPRsPanel-Bx2bqoiA.js → GitHubPRsPanel-B0xZbM-K.js} +1 -1
  29. package/web-app/dist/assets/{HomePage-Bgn9XzXY.js → HomePage-D0aizXzO.js} +2 -2
  30. package/web-app/dist/assets/{LoginPage-DEoEr8Qo.js → LoginPage-DjQ5-faQ.js} +1 -1
  31. package/web-app/dist/assets/{MagicPage-qVEnzwnK.js → MagicPage-mzwFEhXD.js} +1 -1
  32. package/web-app/dist/assets/{MetricsPage-BCru8Vw7.js → MetricsPage-Be61Umuv.js} +1 -1
  33. package/web-app/dist/assets/{NotFoundPage-BfyOjcyd.js → NotFoundPage-CjmTN3Z6.js} +1 -1
  34. package/web-app/dist/assets/{ProjectPage-B6ofKWxG.js → ProjectPage-Bj1dJlmV.js} +3 -3
  35. package/web-app/dist/assets/{ProjectsPage-hEPpeCXF.js → ProjectsPage-DPgt37Ev.js} +1 -1
  36. package/web-app/dist/assets/{SettingsPage-xnOPbkyg.js → SettingsPage-CtaHS1ob.js} +1 -1
  37. package/web-app/dist/assets/{ShowcasePage-lhQPmInF.js → ShowcasePage-DD7t6JHO.js} +1 -1
  38. package/web-app/dist/assets/{SystemSettingsPage-B5UxUTUH.js → SystemSettingsPage-CzgVPzMw.js} +1 -1
  39. package/web-app/dist/assets/{TeamsPage-D_BLZ_R6.js → TeamsPage-CBouFUwW.js} +1 -1
  40. package/web-app/dist/assets/{TemplatesPage-CylVy_1x.js → TemplatesPage-BArudpPa.js} +1 -1
  41. package/web-app/dist/assets/{TerminalOutput-Brs2zmhu.js → TerminalOutput-DxA5HoZ5.js} +1 -1
  42. package/web-app/dist/assets/{activity-CKKwgBww.js → activity-BR76ZMBh.js} +1 -1
  43. package/web-app/dist/assets/{bell-Bg8nyAMu.js → bell-Br9K5dz8.js} +1 -1
  44. package/web-app/dist/assets/{bot-BDbOv-DW.js → bot-DWOsO7gw.js} +1 -1
  45. package/web-app/dist/assets/{check-Coz1WWGB.js → check-CbHxZskh.js} +1 -1
  46. package/web-app/dist/assets/{chevron-left-CeLweRux.js → chevron-left-B7VJtFeE.js} +1 -1
  47. package/web-app/dist/assets/{circle-alert-Cey6q-cN.js → circle-alert-DFxljQkZ.js} +1 -1
  48. package/web-app/dist/assets/{clock-XtA5Pfpw.js → clock-BDhyJZBv.js} +1 -1
  49. package/web-app/dist/assets/{cloud-FQ28jZRb.js → cloud-BxVf6gss.js} +1 -1
  50. package/web-app/dist/assets/{code-xml-vDF0KSYX.js → code-xml-BsBy-SZC.js} +1 -1
  51. package/web-app/dist/assets/{database-D_3JabMZ.js → database-Bqz0cKPA.js} +1 -1
  52. package/web-app/dist/assets/{dollar-sign-DuF13H12.js → dollar-sign-Nma2_5tQ.js} +1 -1
  53. package/web-app/dist/assets/{file-code-corner-DGQ1fKi8.js → file-code-corner-DDiKT74Y.js} +1 -1
  54. package/web-app/dist/assets/{file-plus-ClQjx4PE.js → file-plus-Bsi1eh4g.js} +1 -1
  55. package/web-app/dist/assets/{globe-D_3mXRWy.js → globe-BrDJU35Q.js} +1 -1
  56. package/web-app/dist/assets/{hammer-CuUomfVV.js → hammer-Cc0dGdYB.js} +1 -1
  57. package/web-app/dist/assets/{index-D9-QtcQt.js → index-CwRUHGRH.js} +3 -3
  58. package/web-app/dist/assets/{layers-B5R8eQiI.js → layers-dBYYRarz.js} +1 -1
  59. package/web-app/dist/assets/{loader-circle-B6mERdsr.js → loader-circle-Bgp8OiC8.js} +1 -1
  60. package/web-app/dist/assets/{lock-B4ySRbcK.js → lock-mYd7M_sm.js} +1 -1
  61. package/web-app/dist/assets/{package-MHaPM4mF.js → package-Bl6u282j.js} +1 -1
  62. package/web-app/dist/assets/{plus-Cj08kEEm.js → plus-H-VgX3FJ.js} +1 -1
  63. package/web-app/dist/assets/{refresh-cw-DThqwXZE.js → refresh-cw-emJQn2ZS.js} +1 -1
  64. package/web-app/dist/assets/{rotate-ccw-D6FVAHZp.js → rotate-ccw-CTDYewXA.js} +1 -1
  65. package/web-app/dist/assets/{scroll-text-1tS_QOZn.js → scroll-text-Bx_yfYId.js} +1 -1
  66. package/web-app/dist/assets/{server-CtMpOUbw.js → server-CfCbWR2b.js} +1 -1
  67. package/web-app/dist/assets/{shield-alert-BlC4wmkJ.js → shield-alert-ODyUhCBO.js} +1 -1
  68. package/web-app/dist/assets/{thumbs-up-B_AuhFxq.js → thumbs-up-D4rG_0Db.js} +1 -1
  69. package/web-app/dist/assets/{trash-2-CBj_pRfh.js → trash-2-CLW0eSji.js} +1 -1
  70. package/web-app/dist/assets/{trending-down-BZ9AZ6D0.js → trending-down-B_9FnZty.js} +1 -1
  71. package/web-app/dist/assets/{trending-up-BdO4ANqU.js → trending-up-fEvDswGA.js} +1 -1
  72. package/web-app/dist/assets/{upload-D1Cg5cAS.js → upload-DvgEs5QL.js} +1 -1
  73. package/web-app/dist/assets/{usePolling-IHqzRFVn.js → usePolling-KK1QY8nW.js} +1 -1
  74. package/web-app/dist/assets/{user-1UKh3VZH.js → user-Cp4-qLBC.js} +1 -1
  75. 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.91.0
6
+ # Loki Mode v11.92.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
 
@@ -475,4 +475,4 @@ Implemented, planned and deprecated items, with the version each landed in: `ski
475
475
 
476
476
  ---
477
477
 
478
- **v11.91.0 | [Autonomi](https://www.autonomi.dev/) flagship product | core skill**
478
+ **v11.92.0 | [Autonomi](https://www.autonomi.dev/) flagship product | core skill**
package/VERSION CHANGED
@@ -1 +1 @@
1
- 11.91.0
1
+ 11.92.0
@@ -3268,6 +3268,13 @@ ISSUES: CRITICAL:description (optional, one per line per issue)"
3268
3268
  # out of scope when this file is sourced standalone, so each is
3269
3269
  # type-guarded (degrades to the prior bare invocation).
3270
3270
  local _cm_argv=("--model" "$council_model")
3271
+ local _cm_shell
3272
+ _cm_shell="$(
3273
+ type _loki_claude_shell_value >/dev/null 2>&1 \
3274
+ || . "${BASH_SOURCE[0]%/*}/lib/claude-flags.sh" >/dev/null 2>&1 || exit 1
3275
+ _loki_claude_shell_value
3276
+ )" || _cm_shell=""
3277
+ [ -n "$_cm_shell" ] || _cm_shell="${SHELL-}"
3271
3278
  if type loki_subcall_bare_enabled >/dev/null 2>&1 && loki_subcall_bare_enabled; then
3272
3279
  _cm_argv+=("--bare")
3273
3280
  fi
@@ -3299,7 +3306,7 @@ ISSUES: CRITICAL:description (optional, one per line per issue)"
3299
3306
  # required safe default. pipefail (run.sh:172) makes the assignment's
3300
3307
  # $? equal timeout's 124 when the CLI is killed. _provider_rc is read
3301
3308
  # after the case to force a conservative REJECT on timeout.
3302
- verdict=$(echo "$prompt" | timeout "${LOKI_COUNCIL_REVIEW_TIMEOUT:-600}" env CAVEMAN_DEFAULT_MODE=off claude "${_cm_argv[@]}" -p 2>/dev/null)
3309
+ verdict=$(echo "$prompt" | timeout "${LOKI_COUNCIL_REVIEW_TIMEOUT:-600}" env "SHELL=$_cm_shell" CAVEMAN_DEFAULT_MODE=off claude "${_cm_argv[@]}" -p 2>/dev/null)
3303
3310
  _provider_rc=$?
3304
3311
  fi
3305
3312
  ;;
@@ -3476,6 +3483,13 @@ REASON: one-line justification citing path:line evidence"
3476
3483
  # reviewer must never mutate the tree). Gated + opt-out
3477
3484
  # LOKI_BARE_SUBCALLS=0 / LOKI_REVIEW_TOOL_GUARD=0; type-guarded.
3478
3485
  local _co_argv=("--model" "$council_model")
3486
+ local _co_shell
3487
+ _co_shell="$(
3488
+ type _loki_claude_shell_value >/dev/null 2>&1 \
3489
+ || . "${BASH_SOURCE[0]%/*}/lib/claude-flags.sh" >/dev/null 2>&1 || exit 1
3490
+ _loki_claude_shell_value
3491
+ )" || _co_shell=""
3492
+ [ -n "$_co_shell" ] || _co_shell="${SHELL-}"
3479
3493
  if type loki_subcall_bare_enabled >/dev/null 2>&1 && loki_subcall_bare_enabled; then
3480
3494
  _co_argv+=("--bare")
3481
3495
  fi
@@ -3491,7 +3505,7 @@ REASON: one-line justification citing path:line evidence"
3491
3505
  # bash-F3: timeout-guard the devil's-advocate subcall (same 600s
3492
3506
  # default as the member subcalls / Bun council.ts). An empty
3493
3507
  # verdict on timeout hits the conservative REJECT fallback below.
3494
- verdict=$(echo "$prompt" | timeout "${LOKI_COUNCIL_REVIEW_TIMEOUT:-600}" env CAVEMAN_DEFAULT_MODE=off claude "${_co_argv[@]}" -p 2>/dev/null)
3508
+ verdict=$(echo "$prompt" | timeout "${LOKI_COUNCIL_REVIEW_TIMEOUT:-600}" env "SHELL=$_co_shell" CAVEMAN_DEFAULT_MODE=off claude "${_co_argv[@]}" -p 2>/dev/null)
3495
3509
  fi
3496
3510
  ;;
3497
3511
  codex)
@@ -426,6 +426,14 @@ Respond ONLY with a valid JSON object. No markdown fencing."
426
426
  # opt-out LOKI_BARE_SUBCALLS=0 / LOKI_REVIEW_TOOL_GUARD=0;
427
427
  # type-guarded for standalone sourcing.
428
428
  local _c2_argv=("--model" "${_c2_agent_model:-haiku}")
429
+ # Pin SHELL=/bin/bash for the claude child (LOKI_E10_KEEP_USER_SHELL=1 keeps the user shell).
430
+ local _c2_shell
431
+ _c2_shell="$(
432
+ type _loki_claude_shell_value >/dev/null 2>&1 \
433
+ || . "${BASH_SOURCE[0]%/*}/lib/claude-flags.sh" >/dev/null 2>&1 || exit 1
434
+ _loki_claude_shell_value
435
+ )" || _c2_shell=""
436
+ [ -n "$_c2_shell" ] || _c2_shell="${SHELL-}"
429
437
  if type loki_subcall_bare_enabled >/dev/null 2>&1 && loki_subcall_bare_enabled; then
430
438
  _c2_argv+=("--bare")
431
439
  fi
@@ -458,7 +466,7 @@ Respond ONLY with a valid JSON object. No markdown fencing."
458
466
  local _c2_schema_content _c2_json
459
467
  _c2_schema_content="$(cat "$_c2_schema" 2>/dev/null)" || _c2_schema_content=""
460
468
  if [ -n "$_c2_schema_content" ]; then
461
- _c2_json="$(echo "$full_prompt" | CAVEMAN_DEFAULT_MODE=off claude "${_c2_argv[@]}" -p \
469
+ _c2_json="$(echo "$full_prompt" | SHELL="$_c2_shell" CAVEMAN_DEFAULT_MODE=off claude "${_c2_argv[@]}" -p \
462
470
  --json-schema "$_c2_schema_content" --output-format json 2>/dev/null)" || _c2_json=""
463
471
  if [ -n "$_c2_json" ]; then
464
472
  # Pull the schema-validated object out of the envelope.
@@ -480,7 +488,7 @@ except Exception:
480
488
  fi
481
489
  # Fall through to the plain text call (+ sed-carve) on any miss.
482
490
  if [ -z "$result" ]; then
483
- result=$(echo "$full_prompt" | CAVEMAN_DEFAULT_MODE=off claude "${_c2_argv[@]}" -p 2>/dev/null || echo '{"verdict":"INCONCLUSIVE","justification":"review execution failed (no verdict obtained; NOT a rejection)","issues":[]}')
491
+ result=$(echo "$full_prompt" | SHELL="$_c2_shell" CAVEMAN_DEFAULT_MODE=off claude "${_c2_argv[@]}" -p 2>/dev/null || echo '{"verdict":"INCONCLUSIVE","justification":"review execution failed (no verdict obtained; NOT a rejection)","issues":[]}')
484
492
  fi
485
493
  else
486
494
  result='{"verdict":"INCONCLUSIVE","justification":"reviewer CLI unavailable (no verdict obtained; NOT a rejection)","issues":[]}'
package/autonomy/grill.sh CHANGED
@@ -251,6 +251,9 @@ grill_invoke_provider() {
251
251
  _LOKI_PERM_ARGV=(--dangerously-skip-permissions)
252
252
  ! type _loki_claude_permission_argv >/dev/null 2>&1 || _loki_claude_permission_argv
253
253
  local _gr_argv=("${_LOKI_PERM_ARGV[@]}" "--model" "${LOKI_GRILL_MODEL:-sonnet}")
254
+ # Pin SHELL=/bin/bash for the claude child (LOKI_E10_KEEP_USER_SHELL=1 keeps the user shell).
255
+ local _gr_shell
256
+ _gr_shell="$(_loki_claude_shell_value 2>/dev/null || printf '%s' "${SHELL-}")"
254
257
  # lean child flags (text-only role, no tools/MCP/slash commands) and
255
258
  # a ledger line per call via --output-format json (unwrapped below).
256
259
  local _gr_lf _gr_ledger=false
@@ -275,7 +278,7 @@ grill_invoke_provider() {
275
278
  # (not a bare VAR=val prefix) because the call goes through
276
279
  # _grill_with_timeout, where the first token is exec'd as the command.
277
280
  out="$(printf '%s' "$prompt" \
278
- | _grill_with_timeout "${LOKI_GRILL_TIMEOUT:-180}" env CAVEMAN_DEFAULT_MODE=off claude "${_gr_argv[@]}" -p - 2>/dev/null)"
281
+ | _grill_with_timeout "${LOKI_GRILL_TIMEOUT:-180}" env "SHELL=$_gr_shell" CAVEMAN_DEFAULT_MODE=off claude "${_gr_argv[@]}" -p - 2>/dev/null)"
279
282
  if [ "$_gr_ledger" = true ] && [ -n "$out" ]; then
280
283
  loki_child_ledger_append "$role" "$out" >/dev/null 2>&1 || true
281
284
  out="$(printf '%s' "$out" | python3 -I -c 'import json,sys
@@ -141,6 +141,14 @@ _loki_done_recog_invoke() {
141
141
  || . "$(dirname "${BASH_SOURCE[0]}")/../../providers/loader.sh" 2>/dev/null
142
142
  loki_claude_sidecall_allowed 2>/dev/null || return 1
143
143
  command -v claude >/dev/null 2>&1 || return 1
144
+ # Pin SHELL=/bin/bash for the claude child (LOKI_E10_KEEP_USER_SHELL=1 keeps the user shell).
145
+ local _dr_shell
146
+ _dr_shell="$(
147
+ type _loki_claude_shell_value >/dev/null 2>&1 \
148
+ || . "$(dirname "${BASH_SOURCE[0]}")/claude-flags.sh" >/dev/null 2>&1 || exit 1
149
+ _loki_claude_shell_value
150
+ )" || _dr_shell=""
151
+ [ -n "$_dr_shell" ] || _dr_shell="${SHELL-}"
144
152
 
145
153
  # STRUCTURED VERDICT (v8.x): when the CLI supports --json-schema, force valid
146
154
  # JSON so parse_object never has to brace-slice prose. --json-schema takes
@@ -160,11 +168,11 @@ _loki_done_recog_invoke() {
160
168
  _LOKI_PERM_ARGV=(--dangerously-skip-permissions)
161
169
  ! type _loki_claude_permission_argv >/dev/null 2>&1 || _loki_claude_permission_argv
162
170
  if command -v timeout >/dev/null 2>&1; then
163
- _dr_json=$(CAVEMAN_DEFAULT_MODE=off timeout "${LOKI_DONE_RECOG_TIMEOUT}" \
171
+ _dr_json=$(SHELL="$_dr_shell" CAVEMAN_DEFAULT_MODE=off timeout "${LOKI_DONE_RECOG_TIMEOUT}" \
164
172
  claude "${_LOKI_PERM_ARGV[@]}" -p "$prompt" \
165
173
  --json-schema "$_dr_schema_content" --output-format json 2>/dev/null) || _dr_json=""
166
174
  else
167
- _dr_json=$(CAVEMAN_DEFAULT_MODE=off \
175
+ _dr_json=$(SHELL="$_dr_shell" CAVEMAN_DEFAULT_MODE=off \
168
176
  claude "${_LOKI_PERM_ARGV[@]}" -p "$prompt" \
169
177
  --json-schema "$_dr_schema_content" --output-format json 2>/dev/null) || _dr_json=""
170
178
  fi
@@ -197,10 +205,10 @@ except Exception:
197
205
  _LOKI_PERM_ARGV=(--dangerously-skip-permissions)
198
206
  ! type _loki_claude_permission_argv >/dev/null 2>&1 || _loki_claude_permission_argv
199
207
  if command -v timeout >/dev/null 2>&1; then
200
- out=$(CAVEMAN_DEFAULT_MODE=off timeout "${LOKI_DONE_RECOG_TIMEOUT}" \
208
+ out=$(SHELL="$_dr_shell" CAVEMAN_DEFAULT_MODE=off timeout "${LOKI_DONE_RECOG_TIMEOUT}" \
201
209
  claude "${_LOKI_PERM_ARGV[@]}" -p "$prompt" 2>/dev/null) || rc=$?
202
210
  else
203
- out=$(CAVEMAN_DEFAULT_MODE=off \
211
+ out=$(SHELL="$_dr_shell" CAVEMAN_DEFAULT_MODE=off \
204
212
  claude "${_LOKI_PERM_ARGV[@]}" -p "$prompt" 2>/dev/null) || rc=$?
205
213
  fi
206
214
  [ "$rc" -ne 0 ] && return 1
@@ -101,13 +101,16 @@ _loki_prd_enrich_invoke() {
101
101
  _pe_ledger=true
102
102
  _pe_argv+=("--output-format" "json")
103
103
  fi
104
+ # Pin SHELL=/bin/bash for the claude child (LOKI_E10_KEEP_USER_SHELL=1 keeps the user shell).
105
+ local _pe_shell
106
+ _pe_shell="$(_loki_claude_shell_value 2>/dev/null || printf '%s' "${SHELL-}")"
104
107
  if command -v timeout >/dev/null 2>&1; then
105
- out=$(CAVEMAN_DEFAULT_MODE=off timeout "${LOKI_PRD_ENRICH_TIMEOUT}" \
108
+ out=$(SHELL="$_pe_shell" CAVEMAN_DEFAULT_MODE=off timeout "${LOKI_PRD_ENRICH_TIMEOUT}" \
106
109
  claude "${_pe_argv[@]}" -p "$prompt" 2>/dev/null) || rc=$?
107
110
  else
108
111
  # No coreutils timeout (e.g. bare macOS). Run without it; the model
109
112
  # call is a one-shot and the caller still tolerates failure.
110
- out=$(CAVEMAN_DEFAULT_MODE=off \
113
+ out=$(SHELL="$_pe_shell" CAVEMAN_DEFAULT_MODE=off \
111
114
  claude "${_pe_argv[@]}" -p "$prompt" 2>/dev/null) || rc=$?
112
115
  fi
113
116
  if [ "$rc" -eq 0 ] && [ "$_pe_ledger" = true ] && [ -n "$out" ]; then
@@ -401,7 +401,7 @@ loki_council_dispatch_agents() {
401
401
  _va_fmt=(--output-format json)
402
402
  fi
403
403
  response=$(timeout "${LOKI_COUNCIL_REVIEW_TIMEOUT:-600}" \
404
- env CAVEMAN_DEFAULT_MODE=off claude "${_LOKI_PERM_ARGV[@]}" \
404
+ env "SHELL=$(_loki_claude_shell_value 2>/dev/null || printf '%s' "${SHELL-}")" CAVEMAN_DEFAULT_MODE=off claude "${_LOKI_PERM_ARGV[@]}" \
405
405
  ${_va_lean[@]+"${_va_lean[@]}"} \
406
406
  ${_va_fmt[@]+"${_va_fmt[@]}"} \
407
407
  -p "$prompt" \
package/autonomy/loki CHANGED
@@ -143,6 +143,17 @@ _loki_caveman_narration_level() {
143
143
  # claude-flags.sh (like the caveman wrapper above) and fills _LOKI_PERM_ARGV; unset
144
144
  # LOKI_PERMISSION_POLICY=legacy keeps --dangerously-skip-permissions byte-identically.
145
145
  _loki_perm_argv_for() {
146
+ # Also sets _LOKI_CLAUDE_SHELL, the SHELL value every claude spawn in this CLI
147
+ # pins (/bin/bash; LOKI_E10_KEEP_USER_SHELL=1 keeps the user's). Computed in a
148
+ # subshell so the helper's top-level exports never leak. Falls back to the
149
+ # user's SHELL when the lib is unavailable. Spawn sites that need only the
150
+ # shell call this with output discarded.
151
+ _LOKI_CLAUDE_SHELL="$(
152
+ # shellcheck source=autonomy/lib/claude-flags.sh
153
+ . "${_LOKI_SCRIPT_DIR}/lib/claude-flags.sh" >/dev/null 2>&1 || exit 1
154
+ _loki_claude_shell_value
155
+ )" || _LOKI_CLAUDE_SHELL=""
156
+ [ -n "$_LOKI_CLAUDE_SHELL" ] || _LOKI_CLAUDE_SHELL="${SHELL-}"
146
157
  _LOKI_PERM_ARGV=(--dangerously-skip-permissions)
147
158
  # Legacy policy: return before sourcing anything (claude-flags.sh exports caveman vars).
148
159
  [ "${LOKI_PERMISSION_POLICY:-}" = "legacy" ] && return 0
@@ -19851,7 +19862,7 @@ Tasks:
19851
19862
  _loki_perm_argv_for "$codebase_path"
19852
19863
  case "$provider_name" in
19853
19864
  claude)
19854
- { (cd "$codebase_path" && if [ -n "$_loki_mig_cm" ]; then CAVEMAN_DEFAULT_MODE="$_loki_mig_cm" claude "${_LOKI_PERM_ARGV[@]}" -p "$phase_prompt" --output-format stream-json --verbose 2>&1; else claude "${_LOKI_PERM_ARGV[@]}" -p "$phase_prompt" --output-format stream-json --verbose 2>&1; fi) | \
19865
+ { (cd "$codebase_path" && if [ -n "$_loki_mig_cm" ]; then SHELL="$_LOKI_CLAUDE_SHELL" CAVEMAN_DEFAULT_MODE="$_loki_mig_cm" claude "${_LOKI_PERM_ARGV[@]}" -p "$phase_prompt" --output-format stream-json --verbose 2>&1; else SHELL="$_LOKI_CLAUDE_SHELL" claude "${_LOKI_PERM_ARGV[@]}" -p "$phase_prompt" --output-format stream-json --verbose 2>&1; fi) | \
19855
19866
  while IFS= read -r line; do
19856
19867
  # Extract text from stream-json
19857
19868
  if echo "$line" | python3 -c "
@@ -20029,7 +20040,7 @@ IMPORTANT RULES:
20029
20040
  _loki_perm_argv_for "$codebase_path"
20030
20041
  case "$provider_name" in
20031
20042
  claude)
20032
- { (cd "$codebase_path" && if [ -n "$_loki_doc_cm" ]; then CAVEMAN_DEFAULT_MODE="$_loki_doc_cm" claude "${_LOKI_PERM_ARGV[@]}" -p "$doc_prompt" --output-format stream-json --verbose 2>&1; else claude "${_LOKI_PERM_ARGV[@]}" -p "$doc_prompt" --output-format stream-json --verbose 2>&1; fi) | \
20043
+ { (cd "$codebase_path" && if [ -n "$_loki_doc_cm" ]; then SHELL="$_LOKI_CLAUDE_SHELL" CAVEMAN_DEFAULT_MODE="$_loki_doc_cm" claude "${_LOKI_PERM_ARGV[@]}" -p "$doc_prompt" --output-format stream-json --verbose 2>&1; else SHELL="$_LOKI_CLAUDE_SHELL" claude "${_LOKI_PERM_ARGV[@]}" -p "$doc_prompt" --output-format stream-json --verbose 2>&1; fi) | \
20033
20044
  while IFS= read -r line; do
20034
20045
  if echo "$line" | python3 -c "
20035
20046
  import sys, json
@@ -21095,7 +21106,7 @@ Begin healing now. Follow the RARV cycle for each action."
21095
21106
  claude)
21096
21107
  _loki_perm_argv_for "$codebase_path"
21097
21108
  local run_args=("${_LOKI_PERM_ARGV[@]}" -p "$heal_prompt" --output-format stream-json --verbose)
21098
- (cd "$codebase_path" && if [ -n "$_loki_heal_cm" ]; then CAVEMAN_DEFAULT_MODE="$_loki_heal_cm" claude "${run_args[@]}" 2>&1; else claude "${run_args[@]}" 2>&1; fi) | \
21109
+ (cd "$codebase_path" && if [ -n "$_loki_heal_cm" ]; then SHELL="$_LOKI_CLAUDE_SHELL" CAVEMAN_DEFAULT_MODE="$_loki_heal_cm" claude "${run_args[@]}" 2>&1; else SHELL="$_LOKI_CLAUDE_SHELL" claude "${run_args[@]}" 2>&1; fi) | \
21099
21110
  while IFS= read -r line; do
21100
21111
  if echo "$line" | python3 -c "
21101
21112
  import sys, json
@@ -23135,6 +23146,28 @@ print(target)
23135
23146
  PY
23136
23147
  }
23137
23148
 
23149
+ # One line per supported provider (names from SUPPORTED_PROVIDERS in providers/loader.sh), printed once.
23150
+ try_print_provider_setup() {
23151
+ local want="$1" known p hint
23152
+ known="$(sed -n 's/^SUPPORTED_PROVIDERS=(\(.*\))$/\1/p' "$_LOKI_SCRIPT_DIR/../providers/loader.sh" 2>/dev/null | tr -d '"' | head -1)"
23153
+ if [ -z "$known" ]; then
23154
+ echo "loki try: cannot read SUPPORTED_PROVIDERS from providers/loader.sh" >&2
23155
+ return 1
23156
+ fi
23157
+ echo "loki try: no provider is ready for '$want'. Set up one of these, then run loki try again (or preview with --dry-run):"
23158
+ for p in $known; do
23159
+ case "$p" in
23160
+ claude) hint="claude login (or set ANTHROPIC_API_KEY)" ;;
23161
+ codex) hint="codex login (or set OPENAI_API_KEY)" ;;
23162
+ opencode) hint="opencode auth login" ;;
23163
+ aider) hint="install aider and set OPENAI_API_KEY or ANTHROPIC_API_KEY" ;;
23164
+ cline) hint="install the cline CLI and configure its API key" ;;
23165
+ *) hint="install the $p CLI (no login command is mapped for it)" ;;
23166
+ esac
23167
+ echo " $p: $hint"
23168
+ done
23169
+ }
23170
+
23138
23171
  _cmd_try_body() {
23139
23172
  local tmp="$1" url="$2" dry_run="$3" provider="$4" max_cost="$5"
23140
23173
  local dest="$tmp/repo" task
@@ -23167,7 +23200,7 @@ _cmd_try_body() {
23167
23200
  if receipt="$(try_keep_receipt "$dest" "$stamp")"; then
23168
23201
  echo ""
23169
23202
  echo "Receipt: $receipt"
23170
- echo "Check it: loki verify $receipt"
23203
+ echo "Check it: npx loki-mode verify \"$receipt\""
23171
23204
  else
23172
23205
  echo ""
23173
23206
  echo "No receipt was written (run exited $rc)."
@@ -23252,8 +23285,8 @@ cmd_try() {
23252
23285
  *) echo "loki try: unknown provider '$use_provider' (use claude, opencode, codex, cline or aider)" >&2; return 2 ;;
23253
23286
  esac
23254
23287
  if [ "$dry_run" != true ] && ! wow_provider_ready "$use_provider"; then
23255
- echo "loki try: no provider ready for '$use_provider'. Run 'loki doctor', or preview with --dry-run." >&2
23256
- return 1
23288
+ try_print_provider_setup "$use_provider" >&2
23289
+ return 2
23257
23290
  fi
23258
23291
 
23259
23292
  local tmp rc=0
@@ -24270,7 +24303,8 @@ _review_ultra() {
24270
24303
  echo -e "${DIM}Running: claude ${ur_argv[*]}${NC}" >&2
24271
24304
  echo "" >&2
24272
24305
  local ur_rc=0
24273
- claude "${ur_argv[@]}" || ur_rc=$?
24306
+ _loki_perm_argv_for "$PWD" >/dev/null 2>&1 || true
24307
+ SHELL="$_LOKI_CLAUDE_SHELL" claude "${ur_argv[@]}" || ur_rc=$?
24274
24308
  if [ "$ur_rc" -ne 0 ] && [ "$trust_ws" != true ] && [ "$ur_trust_ok" = true ]; then
24275
24309
  echo "If claude reported an untrusted folder, re-run: loki review --ultra --yes --trust-workspace" >&2
24276
24310
  fi
@@ -24397,7 +24431,8 @@ _run_ultracode() {
24397
24431
 
24398
24432
  echo -e "${DIM}Running: claude -p \"ultracode: ...\" --model opus${NC}" >&2
24399
24433
  echo "" >&2
24400
- claude "${uc_argv[@]}"
24434
+ _loki_perm_argv_for "$PWD" >/dev/null 2>&1 || true
24435
+ SHELL="$_LOKI_CLAUDE_SHELL" claude "${uc_argv[@]}"
24401
24436
  return $?
24402
24437
  }
24403
24438
 
@@ -30554,7 +30589,8 @@ cmd_remote() {
30554
30589
  # If workspace isn't trusted, it exits immediately with an error.
30555
30590
  # Use || true to prevent set -e from killing the script before auto-recovery.
30556
30591
  local rc_exit=0
30557
- claude remote-control ${rc_flags[@]+"${rc_flags[@]}"} || rc_exit=$?
30592
+ _loki_perm_argv_for "$PWD" >/dev/null 2>&1 || true
30593
+ SHELL="$_LOKI_CLAUDE_SHELL" claude remote-control ${rc_flags[@]+"${rc_flags[@]}"} || rc_exit=$?
30558
30594
 
30559
30595
  # Exit 0 = normal session end
30560
30596
  if [ $rc_exit -eq 0 ]; then
@@ -30594,7 +30630,8 @@ print('ok')
30594
30630
  echo ""
30595
30631
  echo -e "${GREEN}Launching remote control...${NC}"
30596
30632
  echo ""
30597
- exec claude remote-control ${rc_flags[@]+"${rc_flags[@]}"}
30633
+ _loki_perm_argv_for "$PWD" >/dev/null 2>&1 || true
30634
+ SHELL="$_LOKI_CLAUDE_SHELL" exec claude remote-control ${rc_flags[@]+"${rc_flags[@]}"}
30598
30635
  }
30599
30636
 
30600
30637
  # Syslog/SIEM integration management
@@ -31711,21 +31748,22 @@ METRICS_SCRIPT
31711
31748
 
31712
31749
  # Handle --share flag
31713
31750
  if [ "$share_flag" = true ]; then
31714
- local tmpfile
31715
- tmpfile=$(mktemp "/tmp/loki-metrics-XXXXXX.md")
31751
+ local tmpdir tmpfile
31752
+ tmpdir=$(mktemp -d "${TMPDIR:-/tmp}/loki-metrics.XXXXXXXX") || exit 1
31753
+ tmpfile="$tmpdir/metrics.md"
31716
31754
  echo "$metrics_output" > "$tmpfile"
31717
31755
 
31718
31756
  if ! command -v gh &>/dev/null; then
31719
31757
  echo -e "${RED}gh CLI not found -- cannot share${NC}"
31720
31758
  echo "Install: brew install gh"
31721
- rm -f "$tmpfile"
31759
+ rm -f "$tmpfile"; rmdir "$tmpdir" 2>/dev/null || true
31722
31760
  exit 1
31723
31761
  fi
31724
31762
 
31725
31763
  if ! gh auth status &>/dev/null 2>&1; then
31726
31764
  echo -e "${RED}GitHub CLI not authenticated${NC}"
31727
31765
  echo "Run 'gh auth login' to authenticate."
31728
- rm -f "$tmpfile"
31766
+ rm -f "$tmpfile"; rmdir "$tmpdir" 2>/dev/null || true
31729
31767
  exit 1
31730
31768
  fi
31731
31769
 
@@ -31739,7 +31777,7 @@ METRICS_SCRIPT
31739
31777
  fi
31740
31778
  gist_url=$(gh gist create "$tmpfile" --desc "$gist_desc" $share_visibility 2>&1)
31741
31779
  local gist_exit=$?
31742
- rm -f "$tmpfile"
31780
+ rm -f "$tmpfile"; rmdir "$tmpdir" 2>/dev/null || true
31743
31781
 
31744
31782
  if [ $gist_exit -ne 0 ]; then
31745
31783
  echo -e "${RED}Failed to create gist${NC}"
@@ -32834,7 +32872,8 @@ USER TASK: ${prompt}"
32834
32872
  local agent_exit=0
32835
32873
  case "$provider" in
32836
32874
  claude)
32837
- claude -p "$full_prompt" 2>&1 || agent_exit=$?
32875
+ _loki_perm_argv_for "$PWD" >/dev/null 2>&1 || true
32876
+ SHELL="$_LOKI_CLAUDE_SHELL" claude -p "$full_prompt" 2>&1 || agent_exit=$?
32838
32877
  ;;
32839
32878
  codex)
32840
32879
  codex exec --sandbox workspace-write "$full_prompt" 2>&1 || agent_exit=$?
@@ -32975,7 +33014,7 @@ $diff"
32975
33014
  [ -f ".loki/state/provider" ] && provider=$(cat ".loki/state/provider" 2>/dev/null)
32976
33015
 
32977
33016
  case "$provider" in
32978
- claude) claude -p "$review_prompt" 2>&1 ;;
33017
+ claude) _loki_perm_argv_for "$PWD" >/dev/null 2>&1 || true; SHELL="$_LOKI_CLAUDE_SHELL" claude -p "$review_prompt" 2>&1 ;;
32979
33018
  codex) codex exec --sandbox workspace-write "$review_prompt" 2>&1 ;;
32980
33019
  cline) cline -y "$review_prompt" 2>&1 ;;
32981
33020
  aider) aider --message "$review_prompt" --yes-always --no-auto-commits < /dev/null 2>&1 ;;
@@ -34743,7 +34782,8 @@ _docs_invoke_provider() {
34743
34782
  declare -F loki_child_ledger_append >/dev/null 2>&1 && _ledger=true
34744
34783
  local _fmt=()
34745
34784
  [ "$_ledger" = true ] && _fmt=(--output-format json)
34746
- result=$($t_prefix env CAVEMAN_DEFAULT_MODE=off claude -p ${_lean[@]+"${_lean[@]}"} ${_fmt[@]+"${_fmt[@]}"} --model "${LOKI_DOCS_MODEL:-sonnet}" "$prompt" 2>/dev/null) || exit_code=$?
34785
+ _loki_perm_argv_for "$PWD" >/dev/null 2>&1 || true
34786
+ result=$($t_prefix env "SHELL=$_LOKI_CLAUDE_SHELL" CAVEMAN_DEFAULT_MODE=off claude -p ${_lean[@]+"${_lean[@]}"} ${_fmt[@]+"${_fmt[@]}"} --model "${LOKI_DOCS_MODEL:-sonnet}" "$prompt" 2>/dev/null) || exit_code=$?
34747
34787
  if [ "$_ledger" = true ] && [ -n "$result" ]; then
34748
34788
  loki_child_ledger_append docs "$result" >/dev/null 2>&1 || true
34749
34789
  result=$(printf '%s' "$result" | python3 -c 'import json,sys
@@ -39023,20 +39063,21 @@ cmd_share() {
39023
39063
  esac
39024
39064
 
39025
39065
  # Generate report to temp file
39026
- local tmpfile
39027
- tmpfile=$(mktemp "/tmp/loki-share-XXXXXX.$ext")
39066
+ local tmpdir tmpfile
39067
+ tmpdir=$(mktemp -d "${TMPDIR:-/tmp}/loki-share.XXXXXXXX") || exit 1
39068
+ tmpfile="$tmpdir/session-report.$ext"
39028
39069
 
39029
39070
  echo "Generating session report..."
39030
39071
  if ! "$0" report --format "$format" > "$tmpfile" 2>/dev/null; then
39031
39072
  echo -e "${RED}Failed to generate session report${NC}"
39032
- rm -f "$tmpfile"
39073
+ rm -f "$tmpfile"; rmdir "$tmpdir" 2>/dev/null || true
39033
39074
  exit 1
39034
39075
  fi
39035
39076
 
39036
39077
  # Verify report is not empty
39037
39078
  if [ ! -s "$tmpfile" ]; then
39038
39079
  echo -e "${RED}Generated report is empty${NC}"
39039
- rm -f "$tmpfile"
39080
+ rm -f "$tmpfile"; rmdir "$tmpdir" 2>/dev/null || true
39040
39081
  exit 1
39041
39082
  fi
39042
39083
 
@@ -39076,8 +39117,12 @@ _loki_gist_upload() {
39076
39117
  gist_err=$(cat "$errfile" 2>/dev/null)
39077
39118
  [ "$errfile" != "/dev/null" ] && rm -f "$errfile"
39078
39119
 
39079
- # Cleanup temp file
39120
+ # Cleanup temp file and its private loki-* directory (rmdir only removes
39121
+ # an empty directory).
39080
39122
  rm -f "$file"
39123
+ case "$(basename "$(dirname "$file")")" in
39124
+ loki-*) rmdir "$(dirname "$file")" 2>/dev/null || true ;;
39125
+ esac
39081
39126
 
39082
39127
  if [ $gist_exit -ne 0 ]; then
39083
39128
  echo -e "${RED}Failed to create gist${NC}"
@@ -39200,8 +39245,9 @@ PYEOF
39200
39245
 
39201
39246
  # POST the redacted HTML. Auth header is sent only if a license key exists;
39202
39247
  # OSS users with their own endpoint need no key.
39203
- local tmp_body tmp_code
39204
- tmp_body=$(mktemp "/tmp/loki-hosted-XXXXXX.out")
39248
+ local tmp_body tmp_code tmp_body_dir
39249
+ tmp_body_dir=$(mktemp -d "${TMPDIR:-/tmp}/loki-hosted.XXXXXXXX") || return 1
39250
+ tmp_body="$tmp_body_dir/response.out"
39205
39251
  local -a curl_args=(-sS -o "$tmp_body" -w '%{http_code}' -X POST
39206
39252
  -H "Content-Type: text/html"
39207
39253
  -H "X-Loki-Proof-Id: ${id}"
@@ -39215,7 +39261,7 @@ PYEOF
39215
39261
  if [ "$curl_exit" -ne 0 ]; then
39216
39262
  echo -e "${RED}Failed to reach hosted endpoint (curl exit ${curl_exit}).${NC}" >&2
39217
39263
  echo "Check LOKI_HOSTED_ENDPOINT or publish to a gist: loki proof share ${id}" >&2
39218
- rm -f "$tmp_body"
39264
+ rm -f "$tmp_body"; rmdir "$tmp_body_dir" 2>/dev/null || true
39219
39265
  return 1
39220
39266
  fi
39221
39267
 
@@ -39242,7 +39288,7 @@ except Exception:
39242
39288
  print(url)
39243
39289
  PYEOF
39244
39290
  )
39245
- rm -f "$tmp_body"
39291
+ rm -f "$tmp_body"; rmdir "$tmp_body_dir" 2>/dev/null || true
39246
39292
  if [ -n "$published_url" ]; then
39247
39293
  echo -e "${GREEN}Published: ${published_url}${NC}"
39248
39294
  else
@@ -39259,7 +39305,7 @@ PYEOF
39259
39305
  echo "" >&2
39260
39306
  fi
39261
39307
  echo "Nothing was published. Or publish to a gist: loki proof share ${id}" >&2
39262
- rm -f "$tmp_body"
39308
+ rm -f "$tmp_body"; rmdir "$tmp_body_dir" 2>/dev/null || true
39263
39309
  return 1
39264
39310
  ;;
39265
39311
  esac
@@ -40294,8 +40340,9 @@ PYEOF
40294
40340
  fi
40295
40341
 
40296
40342
  # Copy to a temp file so _loki_gist_upload can remove it after.
40297
- local tmpfile
40298
- tmpfile=$(mktemp "/tmp/loki-proof-XXXXXX.html")
40343
+ local tmpfile tmpdir
40344
+ tmpdir=$(mktemp -d "${TMPDIR:-/tmp}/loki-proof.XXXXXXXX") || exit 1
40345
+ tmpfile="$tmpdir/proof.html"
40299
40346
  cp "$html" "$tmpfile"
40300
40347
  echo "Uploading proof page..."
40301
40348
  local gist_desc="Loki Mode proof-of-run ${id}"
@@ -825,6 +825,17 @@ _qs_classify_invoke() {
825
825
  if command -v timeout >/dev/null 2>&1; then to="timeout"
826
826
  elif command -v gtimeout >/dev/null 2>&1; then to="gtimeout"; fi
827
827
  _LOKI_PERM_ARGV=(--dangerously-skip-permissions)
828
+ # Pin SHELL=/bin/bash for the claude child (LOKI_E10_KEEP_USER_SHELL=1 keeps the user
829
+ # shell). Computed in a subshell so the helper's top-level exports never leak.
830
+ local _qs_shell _qs_shell_lib
831
+ _qs_shell_lib="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd)/lib/claude-flags.sh"
832
+ _qs_shell="$(
833
+ # shellcheck source=/dev/null
834
+ type _loki_claude_shell_value >/dev/null 2>&1 \
835
+ || . "$_qs_shell_lib" >/dev/null 2>&1 || exit 1
836
+ _loki_claude_shell_value
837
+ )" || _qs_shell=""
838
+ [ -n "$_qs_shell" ] || _qs_shell="${SHELL-}"
828
839
  if [ "${LOKI_PERMISSION_POLICY:-}" != "legacy" ]; then
829
840
  # P12-26b: nothing on this path sources claude-flags.sh. Compute in a subshell so its
830
841
  # top-level exports (caveman vars) never leak; fail closed to plan when unavailable.
@@ -844,10 +855,10 @@ _qs_classify_invoke() {
844
855
  fi
845
856
  fi
846
857
  if [ -n "$to" ]; then
847
- out=$(CAVEMAN_DEFAULT_MODE=off "$to" "${LOKI_QUICKSTART_CLASSIFY_TIMEOUT}" \
858
+ out=$(SHELL="$_qs_shell" CAVEMAN_DEFAULT_MODE=off "$to" "${LOKI_QUICKSTART_CLASSIFY_TIMEOUT}" \
848
859
  claude "${_LOKI_PERM_ARGV[@]}" -p "$prompt" 2>/dev/null) || rc=$?
849
860
  else
850
- out=$(CAVEMAN_DEFAULT_MODE=off \
861
+ out=$(SHELL="$_qs_shell" CAVEMAN_DEFAULT_MODE=off \
851
862
  claude "${_LOKI_PERM_ARGV[@]}" -p "$prompt" 2>/dev/null) || rc=$?
852
863
  fi
853
864
  [ "$rc" -ne 0 ] && return 1
@@ -7,6 +7,6 @@ Modules:
7
7
  control: Session control helpers (status, atomic writes, origin check)
8
8
  """
9
9
 
10
- __version__ = "11.91.0"
10
+ __version__ = "11.92.0"
11
11
 
12
12
  __all__ = ["__version__"]
@@ -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.91.0. Do not edit by hand.
3
+ Generated from `loki-ts/src/cli/registry.ts` by `scripts/generate-stale-zero.sh` for v11.92.0. Do not edit by hand.
4
4
  Hidden and legacy-only commands are omitted; see `docs/CLI-INVENTORY.md` for the full inventory.
5
5
 
6
6
  | Command | Description |
@@ -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.91.0
5
+ **Version:** v11.92.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