loki-mode 7.32.3 → 7.33.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/completion-council.sh +30 -2
- package/autonomy/council-v2.sh +14 -1
- package/autonomy/grill.sh +27 -1
- package/autonomy/lib/claude-flags.sh +96 -0
- package/autonomy/run.sh +69 -4
- package/dashboard/__init__.py +1 -1
- package/docs/INSTALLATION.md +1 -1
- package/loki-ts/dist/loki.js +2 -2
- package/mcp/__init__.py +1 -1
- package/package.json +1 -1
- package/providers/claude.sh +14 -0
package/SKILL.md
CHANGED
|
@@ -3,7 +3,7 @@ name: loki-mode
|
|
|
3
3
|
description: Autonomous spec-driven build system with a built-in trust layer. It does not call work done until it is verified (RARV-C closure loop, 11 quality gates, completion council, verified-completion evidence gate). Triggers on "Loki Mode". Takes a spec (PRD, GitHub issue, OpenAPI doc, etc.) to deployed product with minimal human intervention. Provider-agnostic. Requires --dangerously-skip-permissions flag.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Loki Mode v7.
|
|
6
|
+
# Loki Mode v7.33.0
|
|
7
7
|
|
|
8
8
|
**You are an autonomous agent. You make decisions. You do not ask questions. You do not stop.**
|
|
9
9
|
|
|
@@ -398,4 +398,4 @@ See `CHANGELOG.md` entries [7.5.7], [7.5.8], [7.5.13] for the per-fix list and r
|
|
|
398
398
|
|
|
399
399
|
---
|
|
400
400
|
|
|
401
|
-
**v7.
|
|
401
|
+
**v7.33.0 | [Autonomi](https://www.autonomi.dev/) flagship product | ~260 lines core**
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
7.
|
|
1
|
+
7.33.0
|
|
@@ -1759,7 +1759,23 @@ ISSUES: CRITICAL:description (optional, one per line per issue)"
|
|
|
1759
1759
|
claude)
|
|
1760
1760
|
if command -v claude &>/dev/null; then
|
|
1761
1761
|
local council_model="${PROVIDER_MODEL_FAST:-haiku}"
|
|
1762
|
-
|
|
1762
|
+
# EMBED 2 + 3 (v7.33.0). Council member completion vote. The
|
|
1763
|
+
# $prompt is fully self-contained (evidence + instructions +
|
|
1764
|
+
# strict VOTE/REASON/ISSUES output format, piped via stdin) and
|
|
1765
|
+
# the verdict is captured. So --bare (cheap, no hooks/LSP/CLAUDE.
|
|
1766
|
+
# md/MCP) and --disallowedTools (a voting reviewer must never
|
|
1767
|
+
# mutate the tree) both apply. Gated + opt-out
|
|
1768
|
+
# LOKI_BARE_SUBCALLS=0 / LOKI_REVIEW_TOOL_GUARD=0. Helpers may be
|
|
1769
|
+
# out of scope when this file is sourced standalone, so each is
|
|
1770
|
+
# type-guarded (degrades to the prior bare invocation).
|
|
1771
|
+
local _cm_argv=("--model" "$council_model")
|
|
1772
|
+
if type loki_subcall_bare_enabled >/dev/null 2>&1 && loki_subcall_bare_enabled; then
|
|
1773
|
+
_cm_argv+=("--bare")
|
|
1774
|
+
fi
|
|
1775
|
+
if type loki_review_guard_enabled >/dev/null 2>&1 && loki_review_guard_enabled; then
|
|
1776
|
+
_cm_argv+=("--disallowedTools" "$(loki_review_guard_denylist)")
|
|
1777
|
+
fi
|
|
1778
|
+
verdict=$(echo "$prompt" | claude "${_cm_argv[@]}" -p 2>/dev/null | tail -20)
|
|
1763
1779
|
fi
|
|
1764
1780
|
;;
|
|
1765
1781
|
codex)
|
|
@@ -1842,7 +1858,19 @@ REASON: your reasoning"
|
|
|
1842
1858
|
claude)
|
|
1843
1859
|
if command -v claude &>/dev/null; then
|
|
1844
1860
|
local council_model="${PROVIDER_MODEL_FAST:-haiku}"
|
|
1845
|
-
|
|
1861
|
+
# EMBED 2 + 3 (v7.33.0). Contrarian (devil's-advocate) vote --
|
|
1862
|
+
# an adversarial reviewer. Self-contained $prompt via stdin,
|
|
1863
|
+
# verdict captured. --bare + --disallowedTools both apply (a
|
|
1864
|
+
# reviewer must never mutate the tree). Gated + opt-out
|
|
1865
|
+
# LOKI_BARE_SUBCALLS=0 / LOKI_REVIEW_TOOL_GUARD=0; type-guarded.
|
|
1866
|
+
local _co_argv=("--model" "$council_model")
|
|
1867
|
+
if type loki_subcall_bare_enabled >/dev/null 2>&1 && loki_subcall_bare_enabled; then
|
|
1868
|
+
_co_argv+=("--bare")
|
|
1869
|
+
fi
|
|
1870
|
+
if type loki_review_guard_enabled >/dev/null 2>&1 && loki_review_guard_enabled; then
|
|
1871
|
+
_co_argv+=("--disallowedTools" "$(loki_review_guard_denylist)")
|
|
1872
|
+
fi
|
|
1873
|
+
verdict=$(echo "$prompt" | claude "${_co_argv[@]}" -p 2>/dev/null | tail -20)
|
|
1846
1874
|
fi
|
|
1847
1875
|
;;
|
|
1848
1876
|
codex)
|
package/autonomy/council-v2.sh
CHANGED
|
@@ -263,7 +263,20 @@ Respond ONLY with a valid JSON object. No markdown fencing."
|
|
|
263
263
|
case "${PROVIDER_NAME:-claude}" in
|
|
264
264
|
claude)
|
|
265
265
|
if command -v claude &>/dev/null; then
|
|
266
|
-
|
|
266
|
+
# EMBED 2 + 3 (v7.33.0). Council-v2 reviewer verdict. $full_prompt
|
|
267
|
+
# is self-contained (evidence + PRD + strict JSON output, via
|
|
268
|
+
# stdin) and the JSON result is captured. --bare + --disallowedTools
|
|
269
|
+
# both apply (a reviewer must never mutate the tree). Gated +
|
|
270
|
+
# opt-out LOKI_BARE_SUBCALLS=0 / LOKI_REVIEW_TOOL_GUARD=0;
|
|
271
|
+
# type-guarded for standalone sourcing.
|
|
272
|
+
local _c2_argv=("--model" "haiku")
|
|
273
|
+
if type loki_subcall_bare_enabled >/dev/null 2>&1 && loki_subcall_bare_enabled; then
|
|
274
|
+
_c2_argv+=("--bare")
|
|
275
|
+
fi
|
|
276
|
+
if type loki_review_guard_enabled >/dev/null 2>&1 && loki_review_guard_enabled; then
|
|
277
|
+
_c2_argv+=("--disallowedTools" "$(loki_review_guard_denylist)")
|
|
278
|
+
fi
|
|
279
|
+
result=$(echo "$full_prompt" | claude "${_c2_argv[@]}" -p 2>/dev/null || echo '{"verdict":"REJECT","reasoning":"review execution failed","issues":[]}')
|
|
267
280
|
else
|
|
268
281
|
result='{"verdict":"REJECT","reasoning":"reviewer CLI unavailable","issues":[]}'
|
|
269
282
|
fi
|
package/autonomy/grill.sh
CHANGED
|
@@ -38,6 +38,16 @@ GRILL_EXIT_ERROR=3
|
|
|
38
38
|
GRILL_DIR_DEFAULT=".loki/grill"
|
|
39
39
|
GRILL_REPORT_NAME="report.md"
|
|
40
40
|
|
|
41
|
+
# Source the claude-flags helper (idempotent, guarded) so the v7.33.0 embeds
|
|
42
|
+
# (--bare / --disallowedTools) are available in grill's standalone invocation
|
|
43
|
+
# path. Best-effort: if the file is missing the type-guards at the call site
|
|
44
|
+
# degrade to the prior bare invocation.
|
|
45
|
+
_grill_flags_helper="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/lib/claude-flags.sh"
|
|
46
|
+
if [ -f "$_grill_flags_helper" ]; then
|
|
47
|
+
# shellcheck disable=SC1090
|
|
48
|
+
. "$_grill_flags_helper"
|
|
49
|
+
fi
|
|
50
|
+
|
|
41
51
|
_grill_log() { printf '[grill] %s\n' "$*" >&2; }
|
|
42
52
|
_grill_err() { printf '[grill][error] %s\n' "$*" >&2; }
|
|
43
53
|
|
|
@@ -178,8 +188,24 @@ grill_invoke_provider() {
|
|
|
178
188
|
local out
|
|
179
189
|
# Single-shot, non-interactive. Same pattern as the in-loop
|
|
180
190
|
# adversarial reviewer (run.sh:7807) and USAGE regen (run.sh:9832).
|
|
191
|
+
# EMBED 2 + 3 (v7.33.0). The devil's-advocate grill is a cheap
|
|
192
|
+
# self-contained adversarial subcall (the entire spec + interrogation
|
|
193
|
+
# instructions are in $prompt, piped via -p -; output captured). So:
|
|
194
|
+
# EMBED 2 (--bare): no hooks/LSP/CLAUDE.md/MCP needed; cheaper.
|
|
195
|
+
# Opt out LOKI_BARE_SUBCALLS=0.
|
|
196
|
+
# EMBED 3 (--disallowedTools): a grill agent interrogates a spec and
|
|
197
|
+
# must never mutate the tree (defense-in-depth). Deny Edit/Write/
|
|
198
|
+
# NotebookEdit + git mutations. Opt out LOKI_REVIEW_TOOL_GUARD=0.
|
|
199
|
+
# Type-guarded so an environment without the helper degrades cleanly.
|
|
200
|
+
local _gr_argv=("--dangerously-skip-permissions" "--model" "${LOKI_GRILL_MODEL:-sonnet}")
|
|
201
|
+
if type loki_subcall_bare_enabled >/dev/null 2>&1 && loki_subcall_bare_enabled; then
|
|
202
|
+
_gr_argv+=("--bare")
|
|
203
|
+
fi
|
|
204
|
+
if type loki_review_guard_enabled >/dev/null 2>&1 && loki_review_guard_enabled; then
|
|
205
|
+
_gr_argv+=("--disallowedTools" "$(loki_review_guard_denylist)")
|
|
206
|
+
fi
|
|
181
207
|
out="$(printf '%s' "$prompt" \
|
|
182
|
-
| _grill_with_timeout "${LOKI_GRILL_TIMEOUT:-180}" claude
|
|
208
|
+
| _grill_with_timeout "${LOKI_GRILL_TIMEOUT:-180}" claude "${_gr_argv[@]}" -p - 2>/dev/null)"
|
|
183
209
|
if [ -z "$out" ]; then
|
|
184
210
|
_grill_err "provider returned no output (timeout or invocation error)"
|
|
185
211
|
return $GRILL_EXIT_ERROR
|
|
@@ -130,3 +130,99 @@ loki_claude_flag_supported() {
|
|
|
130
130
|
*) return 1 ;;
|
|
131
131
|
esac
|
|
132
132
|
}
|
|
133
|
+
|
|
134
|
+
# ---------- v7.33.0 cheap-subcall + reviewer-guard flag emitters ----------
|
|
135
|
+
# These centralize three Claude Code 2.1.170 embeds so every cheap NON-MAIN
|
|
136
|
+
# subcall site emits the same gated flags. Each emitter prints its flags to
|
|
137
|
+
# stdout (space-free per element via one-per-line is not needed; callers read
|
|
138
|
+
# them into an array with command substitution + word-splitting on the single
|
|
139
|
+
# token they emit, OR append the function output as additional argv elements).
|
|
140
|
+
# All are default-ON, opt-out via env, and gated on loki_claude_flag_supported
|
|
141
|
+
# so an older CLI degrades gracefully (emits nothing).
|
|
142
|
+
|
|
143
|
+
# EMBED 2 -- --bare (cheap NON-MAIN subcalls only). Minimal mode. Per
|
|
144
|
+
# `claude --help` it SKIPS hooks, LSP, plugin sync, attribution, auto-memory,
|
|
145
|
+
# background prefetches, keychain reads, and CLAUDE.md AUTO-discovery. It does
|
|
146
|
+
# NOT nullify explicit --mcp-config/--settings/--agents (the help lists those as
|
|
147
|
+
# the way to "explicitly provide context" UNDER --bare); what it drops is the
|
|
148
|
+
# IMPLICIT/auto-discovered context. Therefore --bare is ONLY safe on subcalls
|
|
149
|
+
# whose prompt is fully self-contained (the entire instruction set + context is
|
|
150
|
+
# passed via -p), and NEVER on the main RARV loop or on any call that relies on
|
|
151
|
+
# auto-discovered CLAUDE.md / hooks / auto-memory.
|
|
152
|
+
#
|
|
153
|
+
# AUTH GATE (critical): --bare sets CLAUDE_CODE_SIMPLE=1 and per `claude --help`
|
|
154
|
+
# reads Anthropic auth STRICTLY from ANTHROPIC_API_KEY or an apiKeyHelper via
|
|
155
|
+
# --settings -- "OAuth and keychain are never read". A subscription/OAuth user
|
|
156
|
+
# (no ANTHROPIC_API_KEY) gets "Not logged in" on every --bare subcall, which
|
|
157
|
+
# exits 0 with the error on stdout, so a council vote parses as the default
|
|
158
|
+
# REJECT and the loop silently corrupts. So --bare is enabled ONLY when an
|
|
159
|
+
# API-key auth path exists (ANTHROPIC_API_KEY set, or an apiKeyHelper configured
|
|
160
|
+
# in settings); otherwise it emits nothing and the subcall runs full-auth, the
|
|
161
|
+
# same as before this embed. Subscription users are thus unaffected by default.
|
|
162
|
+
# Default-ON (when auth-safe); opt out entirely with LOKI_BARE_SUBCALLS=0.
|
|
163
|
+
# Predicate so call sites can append "--bare" to their argv array uniformly:
|
|
164
|
+
# loki_subcall_bare_enabled && argv+=("--bare")
|
|
165
|
+
loki_subcall_bare_enabled() {
|
|
166
|
+
[ "${LOKI_BARE_SUBCALLS:-1}" = "0" ] && return 1
|
|
167
|
+
# API-key auth required (see AUTH GATE above). ANTHROPIC_API_KEY is the
|
|
168
|
+
# common case; apiKeyHelper covers the settings-configured helper. Anything
|
|
169
|
+
# else (OAuth/keychain subscription) must NOT use --bare. Trim the key so a
|
|
170
|
+
# whitespace-only value does not count as set (it would fail --bare auth).
|
|
171
|
+
local _key
|
|
172
|
+
_key="$(printf '%s' "${ANTHROPIC_API_KEY:-}" | tr -d '[:space:]')"
|
|
173
|
+
if [ -z "$_key" ] && ! _loki_apikey_helper_configured; then
|
|
174
|
+
return 1
|
|
175
|
+
fi
|
|
176
|
+
loki_claude_flag_supported "--bare"
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
# True when an apiKeyHelper is configured in any Claude settings source, which
|
|
180
|
+
# (unlike OAuth/keychain) IS honored under --bare. Best-effort, read-only.
|
|
181
|
+
_loki_apikey_helper_configured() {
|
|
182
|
+
local f
|
|
183
|
+
for f in "$HOME/.claude/settings.json" "$HOME/.config/claude/settings.json" \
|
|
184
|
+
"${CLAUDE_CONFIG_DIR:-$HOME/.claude}/settings.json" \
|
|
185
|
+
"$PWD/.claude/settings.json" "$PWD/.claude/settings.local.json"; do
|
|
186
|
+
[ -f "$f" ] || continue
|
|
187
|
+
# Require "apiKeyHelper" : "<non-empty value>" (a real key:value pair),
|
|
188
|
+
# not the bare token in a comment/prose. Tolerates whitespace around the
|
|
189
|
+
# colon. Not a full JSON parse, but rejects the obvious false-positives.
|
|
190
|
+
grep -Eq '"apiKeyHelper"[[:space:]]*:[[:space:]]*"[^"]+"' "$f" 2>/dev/null && return 0
|
|
191
|
+
done
|
|
192
|
+
return 1
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
# EMBED 3 -- --disallowedTools (reviewer / adversarial subcalls). Motivation: a
|
|
196
|
+
# parallel agent once ran `git reset --hard` and wiped uncommitted work, so a
|
|
197
|
+
# reviewer/voter subcall should not casually mutate the tree. Per `claude --help`
|
|
198
|
+
# the value is a comma-or-space-separated list of tool names (e.g. "Bash(git *)
|
|
199
|
+
# Edit"); Bash(...) matching is command-PREFIX based (the `cmd:*` form).
|
|
200
|
+
#
|
|
201
|
+
# SCOPE / LIMITS (honest -- this is a denylist, NOT a sandbox):
|
|
202
|
+
# - Denies the direct file-mutation tools (Edit, Write, NotebookEdit).
|
|
203
|
+
# - Denies the common git MUTATION forms: the bare subcommand (`git reset:*`)
|
|
204
|
+
# AND the global-flag-prefixed evasions (`git -C:*`, `git --git-dir:*`,
|
|
205
|
+
# `git -c:*`) that slip a flag before the subcommand so the bare prefix
|
|
206
|
+
# does not match. Read-only git (diff/log/show/status) stays allowed.
|
|
207
|
+
# - It does NOT and cannot block every mutation path: a determined agent can
|
|
208
|
+
# still write via `Bash(echo > f)`, `sed -i`, `cp/mv/tee`, `python -c`, etc.
|
|
209
|
+
# This is a guardrail that raises the cost of the casual/common destructive
|
|
210
|
+
# command, not a guarantee the tree is immutable. The real safety net is
|
|
211
|
+
# that the integrator commits before any agent wave (see CLAUDE.md).
|
|
212
|
+
# The flag is variadic (<tools...>), so we emit ONE comma-separated token to
|
|
213
|
+
# avoid swallowing the following -p prompt as additional tool names.
|
|
214
|
+
# Default-ON; opt out with LOKI_REVIEW_TOOL_GUARD=0.
|
|
215
|
+
# Predicate + denylist so call sites append uniformly:
|
|
216
|
+
# if loki_review_guard_enabled; then
|
|
217
|
+
# argv+=("--disallowedTools" "$(loki_review_guard_denylist)")
|
|
218
|
+
# fi
|
|
219
|
+
loki_review_guard_enabled() {
|
|
220
|
+
[ "${LOKI_REVIEW_TOOL_GUARD:-1}" = "0" ] && return 1
|
|
221
|
+
loki_claude_flag_supported "--disallowedTools"
|
|
222
|
+
}
|
|
223
|
+
loki_review_guard_denylist() {
|
|
224
|
+
# Comma-separated single token. Bash(cmd:*) is command-prefix matching.
|
|
225
|
+
# The `git -C:*` / `git --git-dir:*` / `git -c:*` entries close the
|
|
226
|
+
# global-flag-before-subcommand evasion of the bare git-mutation rules.
|
|
227
|
+
printf '%s' "Edit,Write,NotebookEdit,Bash(git commit:*),Bash(git reset:*),Bash(git push:*),Bash(git checkout:*),Bash(git clean:*),Bash(git rm:*),Bash(git stash:*),Bash(git -C:*),Bash(git --git-dir:*),Bash(git -c:*)"
|
|
228
|
+
}
|
package/autonomy/run.sh
CHANGED
|
@@ -3248,7 +3248,18 @@ Output ONLY the resolved file content with no conflict markers. No explanations.
|
|
|
3248
3248
|
|
|
3249
3249
|
case "${PROVIDER_NAME:-claude}" in
|
|
3250
3250
|
claude)
|
|
3251
|
-
|
|
3251
|
+
# EMBED 2 (v7.33.0): --bare on this cheap NON-MAIN subcall.
|
|
3252
|
+
# Reasoning: $conflict_prompt is fully self-contained -- it
|
|
3253
|
+
# carries the complete instruction set AND the entire conflicted
|
|
3254
|
+
# file content inline, and the agent's output is captured to a
|
|
3255
|
+
# variable (the shell, not the agent, writes the resolved file).
|
|
3256
|
+
# It needs no hooks, LSP, CLAUDE.md auto-discovery, or MCP, so
|
|
3257
|
+
# --bare is safe and cheaper. Gated + opt-out LOKI_BARE_SUBCALLS=0.
|
|
3258
|
+
local _cr_argv=("--dangerously-skip-permissions")
|
|
3259
|
+
if type loki_subcall_bare_enabled >/dev/null 2>&1 && loki_subcall_bare_enabled; then
|
|
3260
|
+
_cr_argv+=("--bare")
|
|
3261
|
+
fi
|
|
3262
|
+
resolution=$(claude "${_cr_argv[@]}" -p "$conflict_prompt" --output-format text 2>/dev/null)
|
|
3252
3263
|
;;
|
|
3253
3264
|
codex)
|
|
3254
3265
|
resolution=$(codex exec --full-auto --skip-git-repo-check "$conflict_prompt" 2>/dev/null)
|
|
@@ -7803,7 +7814,31 @@ BUILD_PROMPT
|
|
|
7803
7814
|
# Mythos 5 (Project Glasswing), not Fable. If a future change
|
|
7804
7815
|
# adds --model here, the security-sentinel reviewer must be
|
|
7805
7816
|
# pinned to opus, never fable.
|
|
7806
|
-
|
|
7817
|
+
# EMBED 2 + 3 (v7.33.0). This is a 3-reviewer council
|
|
7818
|
+
# subcall. $prompt_text is fully self-contained (built above
|
|
7819
|
+
# into $review_prompt_file with the diff, changed files,
|
|
7820
|
+
# checks, and strict VERDICT/FINDINGS output format), output
|
|
7821
|
+
# is captured to $review_output, and it deliberately does NOT
|
|
7822
|
+
# pass --model or go through buildAutoFlags. So:
|
|
7823
|
+
# EMBED 2 (--bare): the prompt needs no hooks/LSP/CLAUDE.md/
|
|
7824
|
+
# MCP discovery, so --bare is safe and cheaper. Opt out
|
|
7825
|
+
# LOKI_BARE_SUBCALLS=0.
|
|
7826
|
+
# EMBED 3 (--disallowedTools): raise the cost of a reviewer
|
|
7827
|
+
# casually mutating the tree (a parallel agent once ran
|
|
7828
|
+
# `git reset --hard` and wiped uncommitted work). Deny
|
|
7829
|
+
# Edit/Write/NotebookEdit + git mutation forms (incl. the
|
|
7830
|
+
# git -C / --git-dir evasions); read-only git stays allowed.
|
|
7831
|
+
# Guardrail, not a sandbox -- echo>/sed -i/etc. remain; the
|
|
7832
|
+
# real net is commit-before-agent-wave. Opt out
|
|
7833
|
+
# LOKI_REVIEW_TOOL_GUARD=0. See loki_review_guard_denylist.
|
|
7834
|
+
local _rv_argv=("--dangerously-skip-permissions")
|
|
7835
|
+
if type loki_subcall_bare_enabled >/dev/null 2>&1 && loki_subcall_bare_enabled; then
|
|
7836
|
+
_rv_argv+=("--bare")
|
|
7837
|
+
fi
|
|
7838
|
+
if type loki_review_guard_enabled >/dev/null 2>&1 && loki_review_guard_enabled; then
|
|
7839
|
+
_rv_argv+=("--disallowedTools" "$(loki_review_guard_denylist)")
|
|
7840
|
+
fi
|
|
7841
|
+
claude "${_rv_argv[@]}" -p "$prompt_text" \
|
|
7807
7842
|
--output-format text > "$review_output" 2>/dev/null
|
|
7808
7843
|
;;
|
|
7809
7844
|
codex)
|
|
@@ -8016,7 +8051,25 @@ ADVERSARIAL_EOF
|
|
|
8016
8051
|
case "${PROVIDER_NAME:-claude}" in
|
|
8017
8052
|
claude)
|
|
8018
8053
|
if command -v claude &>/dev/null; then
|
|
8019
|
-
|
|
8054
|
+
# EMBED 2 + 3 (v7.33.0). Adversarial probe subcall.
|
|
8055
|
+
# $adversarial_prompt is fully self-contained (instructions +
|
|
8056
|
+
# changed files + diff inlined via the heredoc above) and output
|
|
8057
|
+
# is captured to $result_file. So:
|
|
8058
|
+
# EMBED 2 (--bare): no hooks/LSP/CLAUDE.md/MCP needed; cheaper.
|
|
8059
|
+
# Opt out LOKI_BARE_SUBCALLS=0.
|
|
8060
|
+
# EMBED 3 (--disallowedTools): keep an adversarial agent from
|
|
8061
|
+
# casually mutating the tree. Deny Edit/Write/NotebookEdit +
|
|
8062
|
+
# git mutation forms (incl. git -C / --git-dir evasions);
|
|
8063
|
+
# read-only git stays allowed. Guardrail, not a sandbox.
|
|
8064
|
+
# Opt out LOKI_REVIEW_TOOL_GUARD=0.
|
|
8065
|
+
local _adv_argv=("--dangerously-skip-permissions")
|
|
8066
|
+
if type loki_subcall_bare_enabled >/dev/null 2>&1 && loki_subcall_bare_enabled; then
|
|
8067
|
+
_adv_argv+=("--bare")
|
|
8068
|
+
fi
|
|
8069
|
+
if type loki_review_guard_enabled >/dev/null 2>&1 && loki_review_guard_enabled; then
|
|
8070
|
+
_adv_argv+=("--disallowedTools" "$(loki_review_guard_denylist)")
|
|
8071
|
+
fi
|
|
8072
|
+
claude "${_adv_argv[@]}" -p "$adversarial_prompt" \
|
|
8020
8073
|
--output-format text > "$result_file" 2>/dev/null || true
|
|
8021
8074
|
fi
|
|
8022
8075
|
;;
|
|
@@ -10041,9 +10094,21 @@ ${_commits}"
|
|
|
10041
10094
|
|
|
10042
10095
|
# Use haiku for cheap, fast generation. --dangerously-skip-permissions
|
|
10043
10096
|
# because this is a one-shot non-interactive call.
|
|
10097
|
+
# EMBED 2 (v7.33.0): --bare on this cheap NON-MAIN haiku subcall. The
|
|
10098
|
+
# USAGE.md-regen prompt ($_ic_prompt, piped via -p -) is fully self-contained
|
|
10099
|
+
# (project tree + manifests + entrypoint contents + commits inlined) and the
|
|
10100
|
+
# output is captured, not written by the agent. No hooks/LSP/CLAUDE.md/MCP
|
|
10101
|
+
# needed, so --bare is safe and cheaper. Opt out LOKI_BARE_SUBCALLS=0.
|
|
10102
|
+
# Always at least --dangerously-skip-permissions, so the array is never
|
|
10103
|
+
# empty (empty "${arr[@]}" under set -u errors on bash 3.2, stock macOS).
|
|
10104
|
+
local _ic_argv=("--dangerously-skip-permissions")
|
|
10105
|
+
if type loki_subcall_bare_enabled >/dev/null 2>&1 && loki_subcall_bare_enabled; then
|
|
10106
|
+
_ic_argv+=("--bare")
|
|
10107
|
+
fi
|
|
10108
|
+
_ic_argv+=("--model" "haiku")
|
|
10044
10109
|
local _ic_out
|
|
10045
10110
|
_ic_out=$(printf '%s' "$_ic_prompt" \
|
|
10046
|
-
| timeout 60 claude
|
|
10111
|
+
| timeout 60 claude "${_ic_argv[@]}" -p - 2>/dev/null \
|
|
10047
10112
|
| head -200)
|
|
10048
10113
|
# Sanity check: response must look like Markdown (starts with # or ##).
|
|
10049
10114
|
if [ -z "$_ic_out" ] || ! printf '%s' "$_ic_out" | head -1 | grep -qE '^#'; then
|
package/dashboard/__init__.py
CHANGED
package/docs/INSTALLATION.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
The flagship product of [Autonomi](https://www.autonomi.dev/). Loki Mode is a spec-driven autonomous builder with a built-in trust layer that takes any spec to a deployed product and verifies completion with evidence (quality gates plus a completion council), not just a "done" claim. Complete installation instructions for all platforms and use cases.
|
|
4
4
|
|
|
5
|
-
**Version:** v7.
|
|
5
|
+
**Version:** v7.33.0
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
package/loki-ts/dist/loki.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
var n6=Object.defineProperty;var a6=($)=>$;function s6($,Q){this[$]=a6.bind(null,Q)}var h=($,Q)=>{for(var Z in Q)n6($,Z,{get:Q[Z],enumerable:!0,configurable:!0,set:s6.bind(Q,Z)})};var L=($,Q)=>()=>($&&(Q=$($=0)),Q);var K$=import.meta.require;var S1={};h(S1,{lokiDir:()=>P,homeLokiDir:()=>o$,findRepoRootForVersion:()=>d$,REPO_ROOT:()=>m});import{resolve as n,dirname as l$}from"path";import{fileURLToPath as t6}from"url";import{existsSync as P$}from"fs";import{homedir as r6}from"os";function i6(){let $=N1;for(let Q=0;Q<6;Q++){if(P$(n($,"VERSION"))&&P$(n($,"autonomy/run.sh")))return $;let Z=l$($);if(Z===$)break;$=Z}return n(N1,"..","..","..")}function d$($){let Q=$;for(let Z=0;Z<6;Z++){if(P$(n(Q,"VERSION"))&&P$(n(Q,"autonomy/run.sh")))return Q;let z=l$(Q);if(z===Q)break;Q=z}return n($,"..","..","..")}function P(){return process.env.LOKI_DIR??n(process.cwd(),".loki")}function o$(){return n(r6(),".loki")}var N1,m;var C=L(()=>{N1=l$(t6(import.meta.url));m=i6()});import{readFileSync as e6}from"fs";import{resolve as $Q,dirname as QQ}from"path";import{fileURLToPath as ZQ}from"url";function F$(){if($$!==null)return $$;let $="7.
|
|
2
|
+
var n6=Object.defineProperty;var a6=($)=>$;function s6($,Q){this[$]=a6.bind(null,Q)}var h=($,Q)=>{for(var Z in Q)n6($,Z,{get:Q[Z],enumerable:!0,configurable:!0,set:s6.bind(Q,Z)})};var L=($,Q)=>()=>($&&(Q=$($=0)),Q);var K$=import.meta.require;var S1={};h(S1,{lokiDir:()=>P,homeLokiDir:()=>o$,findRepoRootForVersion:()=>d$,REPO_ROOT:()=>m});import{resolve as n,dirname as l$}from"path";import{fileURLToPath as t6}from"url";import{existsSync as P$}from"fs";import{homedir as r6}from"os";function i6(){let $=N1;for(let Q=0;Q<6;Q++){if(P$(n($,"VERSION"))&&P$(n($,"autonomy/run.sh")))return $;let Z=l$($);if(Z===$)break;$=Z}return n(N1,"..","..","..")}function d$($){let Q=$;for(let Z=0;Z<6;Z++){if(P$(n(Q,"VERSION"))&&P$(n(Q,"autonomy/run.sh")))return Q;let z=l$(Q);if(z===Q)break;Q=z}return n($,"..","..","..")}function P(){return process.env.LOKI_DIR??n(process.cwd(),".loki")}function o$(){return n(r6(),".loki")}var N1,m;var C=L(()=>{N1=l$(t6(import.meta.url));m=i6()});import{readFileSync as e6}from"fs";import{resolve as $Q,dirname as QQ}from"path";import{fileURLToPath as ZQ}from"url";function F$(){if($$!==null)return $$;let $="7.33.0";if(typeof $==="string"&&$.length>0)return $$=$,$$;try{let Q=QQ(ZQ(import.meta.url)),Z=d$(Q);$$=e6($Q(Z,"VERSION"),"utf-8").trim()}catch{$$="unknown"}return $$}var $$=null;var n$=L(()=>{C()});var C1={};h(C1,{runOrThrow:()=>zQ,run:()=>j,commandVersion:()=>KQ,commandExists:()=>f,ShellError:()=>a$});async function j($,Q={}){let Z=Bun.spawn({cmd:[...$],stdout:"pipe",stderr:"pipe",env:Q.env?{...process.env,...Q.env}:process.env,cwd:Q.cwd}),z,X;if(Q.timeoutMs&&Q.timeoutMs>0)z=setTimeout(()=>{try{Z.kill("SIGTERM")}catch{}X=setTimeout(()=>{try{Z.kill("SIGKILL")}catch{}},2000)},Q.timeoutMs);try{let[W,K,U]=await Promise.all([new Response(Z.stdout).text(),new Response(Z.stderr).text(),Z.exited]);return{stdout:W,stderr:K,exitCode:U}}finally{if(z)clearTimeout(z);if(X)clearTimeout(X)}}async function zQ($,Q={}){let Z=await j($,Q);if(Z.exitCode!==0)throw new a$(`command failed (${Z.exitCode}): ${$.join(" ")}`,Z.exitCode,Z.stdout,Z.stderr);return Z}async function f($){let Q=XQ($),Z=await j(["sh","-c",`command -v ${Q}`],{timeoutMs:5000});if(Z.exitCode===0)return Z.stdout.trim()||null;return null}function XQ($){if(!/^[A-Za-z0-9._/-]+$/.test($))throw Error(`refused to shell-escape suspect token: ${$}`);return $}async function KQ($,Q="--version"){if(!await f($))return null;let z=await j([$,Q],{timeoutMs:5000});if(z.exitCode!==0)return null;return((z.stdout||z.stderr).split(/\r?\n/)[0]?.trim()??"")||null}var a$;var d=L(()=>{a$=class a$ extends Error{message;exitCode;stdout;stderr;constructor($,Q,Z,z){super($);this.message=$;this.exitCode=Q;this.stdout=Z;this.stderr=z;this.name="ShellError"}}});function a($){return WQ?"":$}var WQ,T,S,I,TZ,w,R,y,q;var c=L(()=>{WQ=(process.env.NO_COLOR??"").length>0;T=a("\x1B[0;31m"),S=a("\x1B[0;32m"),I=a("\x1B[1;33m"),TZ=a("\x1B[0;34m"),w=a("\x1B[0;36m"),R=a("\x1B[1m"),y=a("\x1B[2m"),q=a("\x1B[0m")});import{existsSync as TQ}from"fs";async function Q$(){if(B$!==void 0)return B$;let $="/opt/homebrew/bin/python3.12";if(TQ($))return B$=$,$;let Q=await f("python3.12");if(Q)return B$=Q,Q;let Z=await f("python3");return B$=Z,Z}async function Z$($,Q={}){let Z=await Q$();if(!Z)return{stdout:"",stderr:"python3 not found",exitCode:127};return j([Z,"-c",$],Q)}var B$;var W$=L(()=>{d()});var t1={};h(t1,{runStatus:()=>gQ});import{existsSync as v,readFileSync as U$,readdirSync as l1,statSync as d1}from"fs";import{resolve as D,basename as xQ}from"path";import{homedir as NQ}from"os";async function DQ(){if(await f("jq"))return!0;return process.stdout.write(`${T}Error: jq is required but not installed.${q}
|
|
3
3
|
`),process.stdout.write(`Install with:
|
|
4
4
|
`),process.stdout.write(` brew install jq (macOS)
|
|
5
5
|
`),process.stdout.write(` apt install jq (Debian/Ubuntu)
|
|
@@ -789,4 +789,4 @@ Set LOKI_LEGACY_BASH=1 to force the bash CLI for every command.
|
|
|
789
789
|
`),2}default:return process.stderr.write(`Unknown command: ${Q}
|
|
790
790
|
`),process.stderr.write(o6),2}}p1();process.on("SIGINT",()=>process.exit(130));process.on("SIGTERM",()=>process.exit(143));var ZZ=await QZ(Bun.argv.slice(2));process.exit(ZZ);
|
|
791
791
|
|
|
792
|
-
//# debugId=
|
|
792
|
+
//# debugId=27D659E047A7DB5564756E2164756E21
|
package/mcp/__init__.py
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "loki-mode",
|
|
3
3
|
"mcpName": "io.github.asklokesh/loki-mode",
|
|
4
|
-
"version": "7.
|
|
4
|
+
"version": "7.33.0",
|
|
5
5
|
"description": "Loki Mode by Autonomi. Autonomous spec-to-product system: takes a PRD, GitHub issue, OpenAPI/JSON/YAML, or one-line brief to a deployed app via the RARV-C closure loop with 11 quality gates. Provider-agnostic (Claude Code, OpenAI Codex, Cline, Aider).",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"agent",
|
package/providers/claude.sh
CHANGED
|
@@ -190,6 +190,20 @@ _loki_build_claude_auto_flags() {
|
|
|
190
190
|
for _mcp_path in $_mcp_argv; do
|
|
191
191
|
_LOKI_CLAUDE_AUTO_FLAGS+=("$_mcp_path")
|
|
192
192
|
done
|
|
193
|
+
# EMBED 1 (v7.33.0): --strict-mcp-config. ONLY emitted alongside an
|
|
194
|
+
# actual --mcp-config bundle (never bare). Per `claude --help` it
|
|
195
|
+
# makes the agent load servers ONLY from --mcp-config, ignoring ALL
|
|
196
|
+
# other MCP sources (auto-discovered project .mcp.json AND any
|
|
197
|
+
# settings-injected configs). Note the bundle already includes the
|
|
198
|
+
# user's ~/.claude/mcp.json overlay explicitly, so the common
|
|
199
|
+
# user-MCP case is preserved; what is dropped is any MCP config not
|
|
200
|
+
# in the explicit bundle, making the run reproducible.
|
|
201
|
+
# Default-ON; opt out with LOKI_STRICT_MCP=0. Gated on CLI support so
|
|
202
|
+
# an older claude degrades gracefully.
|
|
203
|
+
if [ "${LOKI_STRICT_MCP:-1}" != "0" ] \
|
|
204
|
+
&& loki_claude_flag_supported "--strict-mcp-config"; then
|
|
205
|
+
_LOKI_CLAUDE_AUTO_FLAGS+=("--strict-mcp-config")
|
|
206
|
+
fi
|
|
193
207
|
fi
|
|
194
208
|
fi
|
|
195
209
|
|