loki-mode 11.3.9 → 11.4.2

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 (100) hide show
  1. package/README.md +34 -18
  2. package/SKILL.md +3 -3
  3. package/VERSION +1 -1
  4. package/agents/custom_agents.py +280 -0
  5. package/autonomy/council-v2.sh +22 -1
  6. package/autonomy/edit.sh +242 -0
  7. package/autonomy/lib/chat.sh +312 -0
  8. package/autonomy/lib/help-core.sh +164 -0
  9. package/autonomy/lib/json-output.sh +38 -0
  10. package/autonomy/lib/run-summary.sh +96 -0
  11. package/autonomy/loki +105 -10
  12. package/autonomy/route.sh +270 -0
  13. package/autonomy/run.sh +6 -0
  14. package/autonomy/setup-wizard.sh +161 -0
  15. package/autonomy/verify.sh +22 -2
  16. package/bin/loki +73 -18
  17. package/completions/_loki +55 -0
  18. package/completions/loki.bash +49 -3
  19. package/dashboard/__init__.py +1 -1
  20. package/docs/CLI-CORE-VERBS.md +112 -0
  21. package/docs/CLI-REFERENCE.md +7 -1
  22. package/docs/COMPARE-OPENCODE.md +94 -0
  23. package/docs/COMPONENTS.md +1 -0
  24. package/docs/INSTALLATION.md +56 -12
  25. package/docs/KNOWN-ISSUES.md +2 -12
  26. package/docs/QUICKSTART.md +108 -0
  27. package/docs/environment-variables.md +9 -2
  28. package/docs/exit-codes.md +29 -12
  29. package/docs/v10/CLI-MODERN.md +10 -4
  30. package/docs/v10/GUIDE.md +270 -44
  31. package/docs/v10/OPENCODE-PARITY-PLAN.md +84 -0
  32. package/loki-ts/dist/loki.js +968 -933
  33. package/mcp/__init__.py +1 -1
  34. package/package.json +2 -2
  35. package/packages/control-plane/dist/server.js +180 -80
  36. package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
  37. package/providers/claude.sh +16 -2
  38. package/providers/model_route_exec.sh +22 -0
  39. package/providers/model_routes.sh +188 -0
  40. package/skills/providers.md +13 -0
  41. package/templates/agents/planner.md +10 -0
  42. package/templates/agents/reviewer.md +10 -0
  43. package/templates/agents/tester.md +10 -0
  44. package/web-app/dist/assets/{AdminPage-QK-i_x-O.js → AdminPage-CYJ2BWRC.js} +1 -1
  45. package/web-app/dist/assets/{Avatar-DblkLNjB.js → Avatar-DdK4wynI.js} +1 -1
  46. package/web-app/dist/assets/{Badge-DIV2ny5H.js → Badge-CrX3MI7J.js} +1 -1
  47. package/web-app/dist/assets/{Button--rePJOlQ.js → Button-709-wwGM.js} +1 -1
  48. package/web-app/dist/assets/{CockpitPage-BZlKxpGy.js → CockpitPage-BapdTInO.js} +1 -1
  49. package/web-app/dist/assets/{ComparePage-3_INSVux.js → ComparePage-DT99pGvA.js} +1 -1
  50. package/web-app/dist/assets/{ErrorBoundary-DHG63CNr.js → ErrorBoundary-B0uJSys8.js} +1 -1
  51. package/web-app/dist/assets/{EvidenceReceiptPanel-DFsBnLlO.js → EvidenceReceiptPanel-BtMFgElP.js} +1 -1
  52. package/web-app/dist/assets/{GitHubIssuesPanel-phPGah98.js → GitHubIssuesPanel-DjJuU941.js} +1 -1
  53. package/web-app/dist/assets/{GitHubPRsPanel-T7KQqJmx.js → GitHubPRsPanel-HXfEX1BC.js} +1 -1
  54. package/web-app/dist/assets/{HomePage-DFjGUF5I.js → HomePage-Cqyves-S.js} +2 -2
  55. package/web-app/dist/assets/{LoginPage-CorUid_5.js → LoginPage-jUbtC7_Y.js} +1 -1
  56. package/web-app/dist/assets/{MagicPage-DofbSxKD.js → MagicPage-DHRsqjgR.js} +1 -1
  57. package/web-app/dist/assets/{MetricsPage-qzrhhfLC.js → MetricsPage-B-pED05R.js} +1 -1
  58. package/web-app/dist/assets/{NotFoundPage-BAZR0mMb.js → NotFoundPage-CsbUs21R.js} +1 -1
  59. package/web-app/dist/assets/{ProjectPage-BOSUzG9J.js → ProjectPage-BtlLEQwB.js} +3 -3
  60. package/web-app/dist/assets/{ProjectsPage-Ba0YLtzD.js → ProjectsPage-DaRbRjSp.js} +1 -1
  61. package/web-app/dist/assets/{SettingsPage-Cr10Ue2K.js → SettingsPage-DALrtP3F.js} +1 -1
  62. package/web-app/dist/assets/{ShowcasePage-Czn655fe.js → ShowcasePage-CoPHSNP0.js} +1 -1
  63. package/web-app/dist/assets/{SystemSettingsPage-Dwjnw6Ob.js → SystemSettingsPage-kOuSN50O.js} +1 -1
  64. package/web-app/dist/assets/{TeamsPage-D8nc69Be.js → TeamsPage-DGWK0LMp.js} +1 -1
  65. package/web-app/dist/assets/{TemplatesPage-DHsaCDGv.js → TemplatesPage-C-_10CwA.js} +1 -1
  66. package/web-app/dist/assets/{TerminalOutput-DBejni2a.js → TerminalOutput-Cz_vPbXL.js} +1 -1
  67. package/web-app/dist/assets/{activity-B2VsBl1C.js → activity-icIsXJVa.js} +1 -1
  68. package/web-app/dist/assets/{bell-CT77Fq2H.js → bell-DbPR2_4r.js} +1 -1
  69. package/web-app/dist/assets/{bot-DfaWgF4H.js → bot-DvjP3Yh5.js} +1 -1
  70. package/web-app/dist/assets/{check-D1yp7Ndv.js → check-D1OBxHeU.js} +1 -1
  71. package/web-app/dist/assets/{chevron-left-B6Pa8IOX.js → chevron-left-D09jDZ29.js} +1 -1
  72. package/web-app/dist/assets/{circle-alert-D5jrL_Y7.js → circle-alert-DyZMLOcC.js} +1 -1
  73. package/web-app/dist/assets/{clock-DIsY_fa_.js → clock-CdpdJTId.js} +1 -1
  74. package/web-app/dist/assets/{cloud-eGwLh1As.js → cloud-CoLTlmoj.js} +1 -1
  75. package/web-app/dist/assets/{code-xml-CGDIcZ3m.js → code-xml-DrkE2ZZY.js} +1 -1
  76. package/web-app/dist/assets/{database-CWpdaykI.js → database-CMQQuM2R.js} +1 -1
  77. package/web-app/dist/assets/{dollar-sign-DZEuTCs6.js → dollar-sign-CuioDaOG.js} +1 -1
  78. package/web-app/dist/assets/{file-code-corner-BHBW6m9v.js → file-code-corner-Cx9j9K1S.js} +1 -1
  79. package/web-app/dist/assets/{file-plus-D4h1jZSR.js → file-plus-CYD2zaaI.js} +1 -1
  80. package/web-app/dist/assets/{globe-CXdqKgwd.js → globe-6w-hnQkL.js} +1 -1
  81. package/web-app/dist/assets/{hammer-B3YuuYI_.js → hammer-BpqtautL.js} +1 -1
  82. package/web-app/dist/assets/{index-BLEnboSv.js → index-Dzs-9EgJ.js} +3 -3
  83. package/web-app/dist/assets/{layers-Dvp5nFtw.js → layers-D5hd7jb7.js} +1 -1
  84. package/web-app/dist/assets/{loader-circle-DodDmIZ3.js → loader-circle-C6Y9x_7H.js} +1 -1
  85. package/web-app/dist/assets/{lock-EiuaH1Ep.js → lock-D51L7rYh.js} +1 -1
  86. package/web-app/dist/assets/{package-Cx4m2hFg.js → package-BJF8hkP8.js} +1 -1
  87. package/web-app/dist/assets/{plus-D-Sd5rpH.js → plus-D5kUQ79n.js} +1 -1
  88. package/web-app/dist/assets/{refresh-cw-C0w1cdmF.js → refresh-cw-BKdlCa7F.js} +1 -1
  89. package/web-app/dist/assets/{rotate-ccw-C_qk6MTT.js → rotate-ccw-_bd_YI1e.js} +1 -1
  90. package/web-app/dist/assets/{scroll-text-DSxiFtkc.js → scroll-text-DbkegIxF.js} +1 -1
  91. package/web-app/dist/assets/{server-NTJt7I8M.js → server-DAwqFIsq.js} +1 -1
  92. package/web-app/dist/assets/{shield-alert-HBxMQOvH.js → shield-alert-BuR1tPHu.js} +1 -1
  93. package/web-app/dist/assets/{thumbs-up-DEgsHzSD.js → thumbs-up-BF6p3mRd.js} +1 -1
  94. package/web-app/dist/assets/{trash-2-px46FnTD.js → trash-2-BVpnkqqz.js} +1 -1
  95. package/web-app/dist/assets/{trending-down-CBosVGKa.js → trending-down-DpsDvRwW.js} +1 -1
  96. package/web-app/dist/assets/{trending-up-Dbd7zrQj.js → trending-up-mFogTjt3.js} +1 -1
  97. package/web-app/dist/assets/{upload-nhdFKAs1.js → upload-4T8zpBsi.js} +1 -1
  98. package/web-app/dist/assets/{usePolling-BgaGdinh.js → usePolling-DPXQv8WO.js} +1 -1
  99. package/web-app/dist/assets/{user-CzIihUy9.js → user-BYGIFaTm.js} +1 -1
  100. package/web-app/dist/index.html +1 -1
@@ -0,0 +1,164 @@
1
+ #!/usr/bin/env bash
2
+ # Core help screen and help topics for `loki help`. Source this file; it
3
+ # defines functions only. The full command table stays in show_help_all
4
+ # (autonomy/loki) and is reached with `loki help all`.
5
+
6
+ # Topics reachable as `loki help <topic>`. Keep in sync with help_topic_text.
7
+ LOKI_HELP_TOPICS="providers exit-codes"
8
+
9
+ help_core_screen() {
10
+ local version="$1"
11
+ echo "Loki Mode v${version}"
12
+ echo ""
13
+ echo "Usage: loki <command> [options]"
14
+ echo ""
15
+ echo "Start:"
16
+ echo " start [SPEC] PRIMARY: build from a PRD file, brief, or issue (owner/repo#N, PROJ-1) (alias: run)"
17
+ echo " chat [--attach] Interactive alternative; --attach joins the current 'loki start' run"
18
+ echo " edit \"<change>\" Make one targeted change to the current repo"
19
+ echo " quick \"<task>\" One small task, no PR"
20
+ echo ""
21
+ echo "Check:"
22
+ echo " status [--json] What is running and where it stands"
23
+ echo " verify [--json] Deterministic verification (CI-gate exit codes)"
24
+ echo " receipt Inspect the proof-of-run receipt (alias of: proof)"
25
+ echo " diff / undo See what a run changed; undo <run> to plan or apply a rollback"
26
+ echo ""
27
+ echo "Configure:"
28
+ echo " setup First-run setup (provider, keys, defaults)"
29
+ echo " config Show or change settings (config list --json)"
30
+ echo " models Model tiers and routes (models --local for local models)"
31
+ echo " agents Agent roles and routing (route shows where a task would go)"
32
+ echo " doctor [--json] Check your setup is ready"
33
+ echo ""
34
+ echo "Options for 'start': --provider NAME, --model ID, --budget USD, --isolation LVL (isolation dial: none | worktree | docker)"
35
+ echo "Also: cost / estimate (spend before you build), resume (continue a paused or interrupted run)"
36
+ echo "Exit codes: docs/exit-codes.md"
37
+ echo ""
38
+ echo "Examples:"
39
+ echo " loki start ./prd.md Build from a spec file"
40
+ echo " loki start owner/repo#123 Build from a GitHub issue"
41
+ echo " loki start ./prd.md --budget 20 Cap spend at 20 USD"
42
+ echo " loki plan ./prd.md Dry run: complexity, cost, plan"
43
+ echo " loki verify --json Machine-readable verification for CI"
44
+ echo " loki resume Continue a paused or interrupted run"
45
+ echo " loki status --json What is running, as JSON"
46
+ echo " loki cost ./prd.md Estimate spend before you build"
47
+ echo " loki doctor --fix Check setup and repair what it can"
48
+ echo ""
49
+ echo "More:"
50
+ echo " loki help all Every command"
51
+ echo " loki help <topic> Topics: ${LOKI_HELP_TOPICS// /, }"
52
+ echo " loki <command> --help Help for one command"
53
+ echo ""
54
+ echo "New here? Run: loki doctor, then loki quickstart"
55
+ }
56
+
57
+ help_topic_text() {
58
+ case "$1" in
59
+ start)
60
+ cat <<'T'
61
+ Starting work
62
+
63
+ loki start ./prd.md Build from a spec file
64
+ loki start owner/repo#123 Build from a GitHub issue
65
+ loki "<task>" Same as quick
66
+ loki quick "add dark mode" One small task, no PR
67
+ loki edit "rename foo to bar" One targeted change
68
+ loki chat Interactive alternative to start (/run inside chat runs loki start)
69
+ loki chat --attach Chat about the current or latest start run (/status /steer /diff /stop)
70
+ loki plan ./prd.md Dry run: complexity, cost, plan
71
+
72
+ Common flags: --provider NAME, --model ID (tier or route, e.g. ollama/qwen3-coder), --budget USD, --simple, --complex,
73
+ --no-dashboard, --spec FILE, --config PATH. Full list: loki help all.
74
+ T
75
+ ;;
76
+ models)
77
+ cat <<'T'
78
+ Models
79
+
80
+ Loki routes work by tier: planning (opus), development (sonnet), fast (haiku).
81
+ loki models Show the model for each tier
82
+ loki models --local Show local models (Ollama, LM Studio, llama.cpp)
83
+ loki config set maxTier sonnet Cap model cost
84
+ loki config set model.development <id> Override one tier
85
+ LOKI_MODEL_OVERRIDE=<id> Force one model id (Anthropic-protocol gateways)
86
+ T
87
+ ;;
88
+ providers)
89
+ cat <<'T'
90
+ Providers
91
+
92
+ Claude Code is the default and the only Tier 1 provider.
93
+ loki provider list Providers and install status
94
+ loki provider set codex Switch provider (claude, codex, cline, aider, opencode)
95
+ loki start ./prd.md --provider cline
96
+
97
+ Tier 2: cline. Tier 3 (sequential, degraded): codex, aider. opencode is model-agnostic.
98
+ T
99
+ ;;
100
+ agents)
101
+ cat <<'T'
102
+ Agents
103
+
104
+ loki agents list|new|show Your own agents (.loki/agents/<name>.md); council reviewers use them
105
+ loki route "<task>" Show which engine, provider and model a task would use
106
+ loki agent --help Lower-level agent commands
107
+
108
+ Roles use Opus for planning, Sonnet for development, Haiku for fast work.
109
+ T
110
+ ;;
111
+ verify)
112
+ cat <<'T'
113
+ Verification
114
+
115
+ loki verify Deterministic PR verification
116
+ loki verify --fast Exogenous checks only, milliseconds, no model call
117
+ loki verify --json One JSON object: command, exit_code, ok, output
118
+ loki verify --pubkey FILE Check a receipt against a public key
119
+ loki receipt Inspect the proof-of-run receipt
120
+ loki undo <run> [--plan] Plan or apply an undo of a run
121
+
122
+ Exit codes: see loki help exit-codes.
123
+ T
124
+ ;;
125
+ exit-codes)
126
+ cat <<'T'
127
+ Exit codes
128
+
129
+ 0 success
130
+ 1 failure
131
+ 2 usage error (unknown command, bad flag)
132
+ 3 missing component
133
+
134
+ Severity rises with the code: a bigger number is never better news.
135
+ Per-command contracts (verify, proof, start under LOKI_DURABLE_STATE=1):
136
+ docs/exit-codes.md
137
+ T
138
+ ;;
139
+ config)
140
+ cat <<'T'
141
+ Configuration
142
+
143
+ loki config Show current configuration
144
+ loki config list --json Machine-readable configuration
145
+ loki config set KEY VALUE Set a value (maxTier, model.planning, ...)
146
+ loki config get KEY Read a value
147
+ loki config validate [FILE] Validate loki.yaml
148
+ loki setup First-run setup
149
+ loki start --config FILE Load settings from a file
150
+
151
+ Precedence: CLI flag > env var > --config file > defaults.
152
+ Environment variables: docs/environment-variables.md
153
+ T
154
+ ;;
155
+ *)
156
+ return 1
157
+ ;;
158
+ esac
159
+ }
160
+
161
+ # Print the topic, or return 1 when $1 is not a topic.
162
+ help_topic() {
163
+ help_topic_text "$1"
164
+ }
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env bash
2
+ # Shared --json helpers. Source this file; it defines functions only.
3
+ #
4
+ # loki_json_requested ARGS... exit 0 when --json is among ARGS
5
+ # loki_json_strip ARGS... print ARGS (one per line) without --json
6
+ # loki_json_wrap NAME CMD ARGS.. run CMD, print one JSON object:
7
+ # {"command":NAME,"exit_code":N,"ok":bool,"output":"..."}
8
+ # and return CMD's exit code. Use ONLY for
9
+ # commands with no native --json output.
10
+
11
+ loki_json_requested() {
12
+ local a
13
+ for a in "$@"; do
14
+ [ "$a" = "--json" ] && return 0
15
+ done
16
+ return 1
17
+ }
18
+
19
+ loki_json_strip() {
20
+ local a
21
+ for a in "$@"; do
22
+ [ "$a" = "--json" ] || printf '%s\n' "$a"
23
+ done
24
+ }
25
+
26
+ loki_json_wrap() {
27
+ local name="$1" out rc
28
+ shift
29
+ out="$("$@" 2>&1)"
30
+ rc=$?
31
+ LOKI_JW_NAME="$name" LOKI_JW_RC="$rc" LOKI_JW_OUT="$out" python3 -c '
32
+ import json, os, re
33
+ rc = int(os.environ["LOKI_JW_RC"])
34
+ out = re.sub(r"\x1b\[[0-9;]*m", "", os.environ["LOKI_JW_OUT"])
35
+ print(json.dumps({"command": os.environ["LOKI_JW_NAME"], "exit_code": rc, "ok": rc == 0, "output": out}))
36
+ '
37
+ return "$rc"
38
+ }
@@ -0,0 +1,96 @@
1
+ #!/usr/bin/env bash
2
+ # OC-OUTPUT: unified end-of-run summary for the legacy engine. Same format as
3
+ # loki-ts/src/util/run_summary.ts (Result, Files, Cost, Elapsed, Receipt, next).
4
+ # Sourced by autonomy/run.sh; defines functions only.
5
+ #
6
+ # loki_run_summary RESULT_CODE [START_SHA]
7
+ # Honors NO_COLOR and LOKI_SUMMARY_JSON=1 (machine summary). LOKI_QUIET=1 is applied by the
8
+ # caller's log threshold (banner noise off); the summary itself always prints.
9
+
10
+ loki_run_summary() {
11
+ # Print once per process even if two exit paths both call it.
12
+ [ "${_LOKI_SUMMARY_PRINTED:-0}" = "1" ] && return 0
13
+ _LOKI_SUMMARY_PRINTED=1
14
+ local code="${1:-0}" start_sha="${2:-${_LOKI_RUN_START_SHA:-}}"
15
+ local loki_dir="${LOKI_DIR:-${TARGET_DIR:-.}/.loki}"
16
+ local result="done-unverified" files="" ins="" del="" shortstat="" cost="" receipt="" next=""
17
+ local elapsed=$(( $(date +%s) - ${SESSION_START_EPOCH:-$(date +%s)} ))
18
+
19
+ # Result: verified only when a proof exists and the run exited 0.
20
+ local rid="" proof=""
21
+ if [ -s "$loki_dir/state/last-proof-id.txt" ]; then rid="$(head -n1 "$loki_dir/state/last-proof-id.txt" 2>/dev/null | tr -d '[:space:]')"; fi
22
+ case "$rid" in *[!A-Za-z0-9._-]*) rid="" ;; esac
23
+ [ -n "$rid" ] && [ -f "$loki_dir/proofs/$rid/proof.json" ] && proof="$loki_dir/proofs/$rid/proof.json"
24
+ case "$code" in
25
+ 0) if [ -n "$proof" ]; then result="verified"; else result="done-unverified"; fi ;;
26
+ 130|143) result="stopped" ;;
27
+ *) result="failed" ;;
28
+ esac
29
+ [ -f "$loki_dir/STOPPED" ] && result="stopped"
30
+ [ -n "$proof" ] && receipt="$proof"
31
+
32
+ # Files changed vs run-start SHA (excluding .loki and .git).
33
+ if [ -n "$start_sha" ]; then
34
+ local range="${start_sha}..HEAD"
35
+ # LOKI_SUMMARY_WORKTREE=1 (loki edit): compare against the working tree, edits are uncommitted.
36
+ [ "${LOKI_SUMMARY_WORKTREE:-0}" = "1" ] && range="${start_sha}"
37
+ shortstat="$( (cd "${TARGET_DIR:-.}" && git diff --shortstat "$range" -- . ':(exclude).loki/' ':(exclude).git/') 2>/dev/null || true )"
38
+ files="$(printf '%s\n' "$shortstat" | grep -oE '[0-9]+ file' | grep -oE '[0-9]+' | head -1)"
39
+ ins="$(printf '%s\n' "$shortstat" | grep -oE '[0-9]+ insertion' | grep -oE '[0-9]+' | head -1)"
40
+ del="$(printf '%s\n' "$shortstat" | grep -oE '[0-9]+ deletion' | grep -oE '[0-9]+' | head -1)"
41
+ [ -z "$files" ] && files=0
42
+ [ -z "$ins" ] && ins=0
43
+ [ -z "$del" ] && del=0
44
+ fi
45
+
46
+ # Cost: legacy cost comes from the context tracker (token estimate), so it is always marked estimated.
47
+ if [ -f "$loki_dir/context/tracking.json" ]; then
48
+ cost="$(LOKI_TRK="$loki_dir/context/tracking.json" python3 -E -c "
49
+ import json, os
50
+ try:
51
+ c = json.load(open(os.environ['LOKI_TRK'])).get('totals', {}).get('total_cost_usd')
52
+ print('' if c is None else '%.2f' % float(c))
53
+ except Exception:
54
+ print('')
55
+ " 2>/dev/null || true)"
56
+ fi
57
+
58
+ # LOKI_SUMMARY_COST: exact cost from the caller (loki edit reads it from the provider).
59
+ local cost_exact=false
60
+ if [ -n "${LOKI_SUMMARY_COST:-}" ]; then cost="$LOKI_SUMMARY_COST"; cost_exact=true; fi
61
+
62
+ case "$result" in
63
+ verified) if [ "${files:-0}" != "0" ] && [ -n "$files" ]; then next="loki diff"; else next="loki status"; fi ;;
64
+ done-unverified) next="loki verify" ;;
65
+ stopped) next="loki status" ;;
66
+ *) if [ -n "$files" ] && [ "$files" != "0" ]; then next="loki undo"; else next="loki doctor"; fi ;;
67
+ esac
68
+
69
+ local mm=$((elapsed / 60)) ss=$((elapsed % 60)) elapsed_h
70
+ if [ "$elapsed" -lt 60 ]; then elapsed_h="${elapsed}s"; else elapsed_h="${mm}m$(printf '%02d' "$ss")s"; fi
71
+
72
+ if [ "${LOKI_SUMMARY_JSON:-0}" = "1" ]; then
73
+ printf '{"result":"%s","files_changed":%s,"insertions":%s,"deletions":%s,"cost_usd":%s,"cost_estimated":%s,"elapsed_s":%s,"receipt":%s,"next":"%s"}\n' \
74
+ "$result" "${files:-null}" "${ins:-null}" "${del:-null}" "${cost:-null}" "$([ "$cost_exact" = true ] && echo false || echo true)" "$elapsed" \
75
+ "$([ -n "$receipt" ] && printf '"%s"' "$receipt" || printf 'null')" "$next"
76
+ return 0
77
+ fi
78
+
79
+ local c0="" c1=""
80
+ if [ -t 1 ] && [ -z "${NO_COLOR+x}" ]; then
81
+ c1=$'\033[0m'
82
+ case "$result" in verified) c0=$'\033[32m' ;; done-unverified) c0=$'\033[33m' ;; *) c0=$'\033[31m' ;; esac
83
+ fi
84
+ local files_h="unknown" cost_h="not measured"
85
+ [ -n "$files" ] && files_h="${files} changed (+${ins} -${del})"
86
+ if [ -n "$cost" ]; then
87
+ if [ "$cost_exact" = true ]; then cost_h="\$${cost}"; else cost_h="\$${cost} (estimated)"; fi
88
+ fi
89
+ printf '\n'
90
+ printf 'Result: %s%s%s\n' "$c0" "$result" "$c1"
91
+ printf 'Files: %s\n' "$files_h"
92
+ printf 'Cost: %s\n' "$cost_h"
93
+ printf 'Elapsed: %s\n' "$elapsed_h"
94
+ [ -n "$receipt" ] && printf 'Receipt: %s\n' "$receipt"
95
+ printf 'next: %s (or: loki chat --attach)\n' "$next"
96
+ }
package/autonomy/loki CHANGED
@@ -123,6 +123,12 @@ _loki_caveman_narration_level() {
123
123
  fi
124
124
  }
125
125
 
126
+ # loki edit: one-pass small change fast path (functions-only, self-guarded).
127
+ if [ -f "$_LOKI_SCRIPT_DIR/edit.sh" ]; then
128
+ # shellcheck source=edit.sh
129
+ source "$_LOKI_SCRIPT_DIR/edit.sh"
130
+ fi
131
+
126
132
  # Quickstart guided interview (v7.29.0): provides cmd_quickstart and its
127
133
  # deterministic offline template matcher. Functions-only file (no top-level
128
134
  # command), sourced here so the dispatch case can call cmd_quickstart. Composes
@@ -1722,7 +1728,14 @@ _help_verify_dsse() {
1722
1728
  echo " 66 no signing key, or no runs"
1723
1729
  }
1724
1730
 
1731
+ # Default help screen: core verbs only. `loki help all` prints show_help_all.
1725
1732
  show_help() {
1733
+ # shellcheck source=/dev/null
1734
+ source "$_LOKI_SCRIPT_DIR/lib/help-core.sh"
1735
+ help_core_screen "$(get_version)"
1736
+ }
1737
+
1738
+ show_help_all() {
1726
1739
  local version=$(get_version)
1727
1740
  # Strip color when stdout is not a TTY (piped/redirected) so captured help
1728
1741
  # output is clean, matching the bare-loki welcome path. Local overrides only.
@@ -1735,6 +1748,7 @@ show_help() {
1735
1748
  echo "Usage: loki <command> [options]"
1736
1749
  echo ""
1737
1750
  echo "New here? Try these in order:"
1751
+ echo " loki setup One-step wizard: tools, provider login, model route, spend cap (--yes for defaults)"
1738
1752
  echo " loki welcome Friendly first-run opener (what Loki is, next steps)"
1739
1753
  echo " loki doctor Check your setup is ready (a few seconds)"
1740
1754
  echo " loki quickstart Guided first build from your idea (no PRD needed)"
@@ -1815,6 +1829,7 @@ show_help() {
1815
1829
  echo ""
1816
1830
  echo "Options for 'start':"
1817
1831
  echo " --provider NAME AI provider: claude (default), codex, cline, aider, opencode"
1832
+ echo " --model ID Model tier or route (e.g. ollama/qwen3-coder)"
1818
1833
  echo " --simple Force simple complexity tier (3 phases)"
1819
1834
  echo " --complex Force complex complexity tier (8 phases)"
1820
1835
  echo " --no-dashboard Disable web dashboard"
@@ -1899,6 +1914,7 @@ show_help() {
1899
1914
  # missing from this list, so a new command cannot ship invisible.
1900
1915
  echo ""
1901
1916
  echo "All commands:"
1917
+ echo " agents chat diff edit models route"
1902
1918
  echo " acp agent analyze api assets audit backlog bench checkpoint (cp) ci cleanup"
1903
1919
  echo " cluster cockpit code compliance completions compound config context (ctx)"
1904
1920
  echo " cost council crash dashboard demo deploy docker docs doctor dogfood"
@@ -1908,7 +1924,7 @@ show_help() {
1908
1924
  echo " next notify onboard open optimize otel outcomes own (handoff) pause plan preview"
1909
1925
  echo " projects proof (receipt) provider quick quickstart rc remote report reset"
1910
1926
  echo " merge resume review rollback run sandbox secrets secure self-update sentrux"
1911
- echo " serve setup-skill share ship spec start state stats status steer stop"
1927
+ echo " serve setup setup-skill share ship spec start state stats status steer stop"
1912
1928
  echo " syslog telemetry template test tour trigger trust trust-metrics"
1913
1929
  echo " ultracode undo update verify version voice watch watchdog web welcome why"
1914
1930
  echo " wiki workspace worktree (wt)"
@@ -2575,7 +2591,8 @@ cmd_start() {
2575
2591
  echo " Token from LOKI_REMOTE_TOKEN / LOKI_REMOTE_TOKEN_FILE"
2576
2592
  echo " (never an argument). Env: LOKI_REMOTE_URL."
2577
2593
  echo " --provider NAME AI provider: claude (default), codex, cline, aider, opencode"
2578
- echo " --allow-haiku Enable Haiku model for the fast tier (default: disabled)"
2594
+ echo " --model NAME Model or route override (for example ollama/qwen3-coder)"
2595
+ echo " --allow-haiku Enable Haiku model for the fast tier (default: disabled)"
2579
2596
  echo " --simple Force simple complexity tier (3 phases)"
2580
2597
  echo " --complex Force complex complexity tier (8 phases)"
2581
2598
  echo " --no-dashboard Disable web dashboard"
@@ -3184,7 +3201,7 @@ cmd_start() {
3184
3201
  ;;
3185
3202
  -*)
3186
3203
  echo -e "${RED}Unknown option: $1${NC}"
3187
- exit 1
3204
+ exit 64
3188
3205
  ;;
3189
3206
  *)
3190
3207
  # Capture first positional arg for unified mode detection.
@@ -12931,6 +12948,16 @@ cmd_config() {
12931
12948
  show)
12932
12949
  cmd_config_show
12933
12950
  ;;
12951
+ list)
12952
+ # HELP slice: `config list [--json]` is `config show` (json: wrapped).
12953
+ # shellcheck source=/dev/null
12954
+ source "$_LOKI_SCRIPT_DIR/lib/json-output.sh"
12955
+ if loki_json_requested "$@"; then
12956
+ loki_json_wrap config-list cmd_config_show
12957
+ else
12958
+ cmd_config_show
12959
+ fi
12960
+ ;;
12934
12961
  init)
12935
12962
  cmd_config_init
12936
12963
  ;;
@@ -12956,9 +12983,10 @@ cmd_config() {
12956
12983
  cmd_config_validate "$@"
12957
12984
  ;;
12958
12985
  *)
12959
- echo -e "${YELLOW}Usage: loki config [show|init|edit|path|set|get|example|schema|validate]${NC}"
12986
+ echo -e "${YELLOW}Usage: loki config [show|list|init|edit|path|set|get|example|schema|validate]${NC}"
12960
12987
  echo ""
12961
12988
  echo " show Show current configuration (default)"
12989
+ echo " list [--json] Same as show; --json emits one JSON object"
12962
12990
  echo " init Create a config file from template"
12963
12991
  echo " edit Open config file in editor"
12964
12992
  echo " path Show config file paths"
@@ -15625,6 +15653,7 @@ cmd_quick() {
15625
15653
  echo ""
15626
15654
  echo "Runs the Loki 10 engine on one small task (no PR is opened). Best for"
15627
15655
  echo "tiny tasks."
15656
+ echo "quick = small task with the verify loop. For a single pass with no loop, use loki edit."
15628
15657
  echo ""
15629
15658
  echo "Examples:"
15630
15659
  echo " loki quick \"add dark mode to this React app\""
@@ -15654,7 +15683,7 @@ cmd_quick() {
15654
15683
  echo " loki quick \"fix the login bug in auth.js\""
15655
15684
  echo " loki quick \"add input validation to the signup form\""
15656
15685
  echo " loki quick \"write unit tests for the API endpoints\""
15657
- exit 2
15686
+ exit 64
15658
15687
  fi
15659
15688
 
15660
15689
  # v7.29.0: provider pre-flight gate. Offer install on a TTY; print honest
@@ -15690,7 +15719,7 @@ cmd_quick() {
15690
15719
  if [ $# -eq 0 ]; then
15691
15720
  echo -e "${RED}Error: No task description provided${NC}"
15692
15721
  echo "Usage: loki quick [--verbose] \"description of what to do\""
15693
- exit 2
15722
+ exit 64
15694
15723
  fi
15695
15724
 
15696
15725
  local task_desc="$*"
@@ -17902,6 +17931,8 @@ cmd_verify() {
17902
17931
  fi
17903
17932
  # shellcheck source=/dev/null
17904
17933
  source "$verify_mod"
17934
+ # verify_main handles --json natively (evidence document on stdout, banner
17935
+ # on stderr); the generic json-output.sh wrapper must not intercept it.
17905
17936
  verify_main "$@"
17906
17937
  return $?
17907
17938
  }
@@ -20794,13 +20825,14 @@ _suggest_command() {
20794
20825
  ultracode council demo dogfood heal modernize import issue github init template \
20795
20826
  status stop pause resume monitor watch watchdog dashboard web open preview share \
20796
20827
  memory context ctx checkpoint state report kpis cost metrics stats logs otel \
20797
- syslog telemetry crash config provider doctor setup-skill onboard quickstart \
20828
+ syslog telemetry crash config provider doctor setup setup-skill onboard quickstart \
20798
20829
  welcome update self-update rollback merge failover cluster enterprise remote deploy docker \
20799
20830
  sandbox api mcp magic compound assets export wiki control docs explain why audit compliance \
20800
20831
  welcome update self-update rollback failover cluster enterprise remote deploy docker \
20801
20832
  sandbox api mcp acp magic compound assets export wiki control docs explain why audit compliance \
20802
20833
  secrets analyze optimize bench ci reset cleanup notify trigger voice sentrux \
20803
- worktree wt projects cp rc trust-metrics serve agent code self_update test help version"
20834
+ worktree wt projects cp rc trust-metrics serve agent code self_update test help version \
20835
+ chat route agents models edit receipt setup diff undo"
20804
20836
  local best
20805
20837
  best=$(printf '%s\n' $known | awk -v t="$typo" '
20806
20838
  function min3(a, b, c) { if (a < b) { if (a < c) return a; return c } if (b < c) return b; return c }
@@ -20968,6 +21000,32 @@ main() {
20968
21000
  quick)
20969
21001
  cmd_quick "$@"
20970
21002
  ;;
21003
+ chat)
21004
+ # shellcheck disable=SC1091
21005
+ source "$_LOKI_SCRIPT_DIR/lib/chat.sh"
21006
+ cmd_chat "$@"
21007
+ ;;
21008
+ edit)
21009
+ cmd_edit "$@"
21010
+ ;;
21011
+ diff)
21012
+ # Show what the last run changed: uncommitted changes, else the HEAD commit.
21013
+ # Extra args pass through to git (for example --stat or a path).
21014
+ if [ "${1:-}" = "--help" ] || [ "${1:-}" = "-h" ]; then
21015
+ echo "Usage: loki diff [git diff args]"
21016
+ echo "Show uncommitted changes; if there are none, show the latest commit."
21017
+ exit 0
21018
+ fi
21019
+ if ! git rev-parse --git-dir >/dev/null 2>&1; then
21020
+ echo "loki diff: not inside a git repository" >&2
21021
+ exit 1
21022
+ fi
21023
+ if git diff --quiet HEAD -- 2>/dev/null; then
21024
+ git show --format='%h %s' "$@" HEAD
21025
+ else
21026
+ git diff "$@" HEAD
21027
+ fi
21028
+ ;;
20971
21029
  monitor)
20972
21030
  cmd_monitor "$@"
20973
21031
  ;;
@@ -20991,6 +21049,11 @@ main() {
20991
21049
  welcome)
20992
21050
  cmd_welcome "$@"
20993
21051
  ;;
21052
+ setup)
21053
+ # shellcheck disable=SC1091
21054
+ . "${SKILL_DIR}/autonomy/setup-wizard.sh"
21055
+ cmd_setup "$@"
21056
+ ;;
20994
21057
  init)
20995
21058
  cmd_init "$@"
20996
21059
  ;;
@@ -21174,6 +21237,9 @@ main() {
21174
21237
  doctor)
21175
21238
  cmd_doctor "$@"
21176
21239
  ;;
21240
+ models)
21241
+ bash "$SKILL_DIR/providers/model_routes.sh" "$@"
21242
+ ;;
21177
21243
  sentrux)
21178
21244
  cmd_sentrux "$@"
21179
21245
  ;;
@@ -21255,6 +21321,9 @@ main() {
21255
21321
  agent)
21256
21322
  cmd_agent "$@"
21257
21323
  ;;
21324
+ agents)
21325
+ cmd_agents "$@"
21326
+ ;;
21258
21327
  template)
21259
21328
  cmd_template "$@"
21260
21329
  ;;
@@ -21401,6 +21470,10 @@ main() {
21401
21470
  # deprecated-alias table; bare help prints the grouped front page.
21402
21471
  if [ "${1:-}" = "aliases" ]; then
21403
21472
  show_help_aliases
21473
+ elif [ "${1:-}" = "all" ]; then
21474
+ show_help_all
21475
+ elif [ -n "${1:-}" ] && case "${1:-}" in providers|exit-codes) true ;; *) false ;; esac && { source "$_LOKI_SCRIPT_DIR/lib/help-core.sh"; help_topic_text "$1"; }; then
21476
+ :
21404
21477
  elif [ -n "${1:-}" ]; then
21405
21478
  # `loki help <command>` reaches the command's own help. Before
21406
21479
  # this, $1 was read only for the literal "aliases" and otherwise
@@ -21470,8 +21543,8 @@ main() {
21470
21543
  echo "Did you mean 'loki ${_suggestion}'?" >&2
21471
21544
  fi
21472
21545
  # Always point to the full command list, even with no near-miss match.
21473
- echo "Run 'loki help' to see every command." >&2
21474
- exit 1
21546
+ echo "Run 'loki help' for the core commands, 'loki help all' for every command." >&2
21547
+ exit 2
21475
21548
  ;;
21476
21549
  esac
21477
21550
  }
@@ -29495,6 +29568,28 @@ PYEOF
29495
29568
  esac
29496
29569
  }
29497
29570
 
29571
+ # User-configurable child agents: .loki/agents/<name>.md, ~/.config/loki/agents/<name>.md
29572
+ cmd_agents() {
29573
+ local sub="${1:-list}"
29574
+ case "$sub" in
29575
+ help|-h|--help)
29576
+ echo "Usage: loki agents <list|new|show|export> [args]"
29577
+ echo " list List configured agents (project overrides user)"
29578
+ echo " new <name> [--user] Scaffold .loki/agents/<name>.md (or ~/.config/loki/agents)"
29579
+ echo " Names reviewer, planner, tester copy the shipped examples"
29580
+ echo " show <name> Show one agent and its system prompt"
29581
+ echo " export --claude [--user] Write agents as Claude Code subagents (.claude/agents/)"
29582
+ echo "Council reviewers use a configured agent named reviewer, tester or security."
29583
+ return 0
29584
+ ;;
29585
+ esac
29586
+ local script_dir helper
29587
+ script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
29588
+ helper="${script_dir}/../agents/custom_agents.py"
29589
+ [ -f "$helper" ] || { echo -e "${RED}Error: agents/custom_agents.py not found${NC}"; return 1; }
29590
+ python3 -I "$helper" "$@"
29591
+ }
29592
+
29498
29593
  # Agent type dispatch (v6.7.0)
29499
29594
  cmd_agent() {
29500
29595
  local subcommand="${1:-list}"