loki-mode 11.90.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.
- package/SKILL.md +2 -2
- package/VERSION +1 -1
- package/autonomy/completion-council.sh +16 -2
- package/autonomy/council-v2.sh +10 -2
- package/autonomy/grill.sh +4 -1
- package/autonomy/lib/done-recognition.sh +12 -4
- package/autonomy/lib/prd-enrich.sh +5 -2
- package/autonomy/lib/voter-agents.sh +1 -1
- package/autonomy/loki +128 -45
- package/autonomy/quickstart.sh +13 -2
- package/completions/_loki +7 -4
- package/completions/loki.bash +3 -3
- package/dashboard/__init__.py +1 -1
- package/docs/CLI-REFERENCE.md +1 -1
- package/docs/INSTALLATION.md +1 -1
- package/docs/v11/VERIFY-PR-SANDBOX.md +1 -1
- package/loki-ts/dist/loki.js +1421 -1414
- package/mcp/__init__.py +1 -1
- package/package.json +2 -2
- package/packages/control-plane/dist/server.js +20346 -20211
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
- package/web-app/dist/assets/{AdminPage-CZL0cONl.js → AdminPage-2eApQhkp.js} +1 -1
- package/web-app/dist/assets/{Avatar-tJZxSP21.js → Avatar-V-WXQ0hZ.js} +1 -1
- package/web-app/dist/assets/{Badge-B-uFJM_y.js → Badge-uw9uv8IY.js} +1 -1
- package/web-app/dist/assets/{Button-DfKU7ctr.js → Button-34AooGBc.js} +1 -1
- package/web-app/dist/assets/{CockpitPage-CRNp09jN.js → CockpitPage-DHVPvw4u.js} +1 -1
- package/web-app/dist/assets/{ComparePage-Cdvjcs57.js → ComparePage-CXuFkRpn.js} +1 -1
- package/web-app/dist/assets/{ErrorBoundary-C_benNK3.js → ErrorBoundary-DpPNWkHN.js} +1 -1
- package/web-app/dist/assets/{EvidenceReceiptPanel-Ch_6YkUO.js → EvidenceReceiptPanel-C3Mc9c1x.js} +1 -1
- package/web-app/dist/assets/{GitHubIssuesPanel-C_a7mAlw.js → GitHubIssuesPanel-Bsqa3l6c.js} +1 -1
- package/web-app/dist/assets/{GitHubPRsPanel-xMr7IKsr.js → GitHubPRsPanel-B0xZbM-K.js} +1 -1
- package/web-app/dist/assets/{HomePage-BVe6s1kz.js → HomePage-D0aizXzO.js} +2 -2
- package/web-app/dist/assets/{LoginPage-DKlLaNw0.js → LoginPage-DjQ5-faQ.js} +1 -1
- package/web-app/dist/assets/{MagicPage-StmxQunX.js → MagicPage-mzwFEhXD.js} +1 -1
- package/web-app/dist/assets/{MetricsPage-C7e2CioT.js → MetricsPage-Be61Umuv.js} +1 -1
- package/web-app/dist/assets/{NotFoundPage-B2IopV0V.js → NotFoundPage-CjmTN3Z6.js} +1 -1
- package/web-app/dist/assets/{ProjectPage-CXs8d6Cx.js → ProjectPage-Bj1dJlmV.js} +3 -3
- package/web-app/dist/assets/{ProjectsPage-BfgMJYYj.js → ProjectsPage-DPgt37Ev.js} +1 -1
- package/web-app/dist/assets/{SettingsPage-CZ8lwCF2.js → SettingsPage-CtaHS1ob.js} +1 -1
- package/web-app/dist/assets/{ShowcasePage-iNCfKZj0.js → ShowcasePage-DD7t6JHO.js} +1 -1
- package/web-app/dist/assets/{SystemSettingsPage-FMV2pNNz.js → SystemSettingsPage-CzgVPzMw.js} +1 -1
- package/web-app/dist/assets/{TeamsPage-D_SzTjuD.js → TeamsPage-CBouFUwW.js} +1 -1
- package/web-app/dist/assets/{TemplatesPage-BMF_6X7R.js → TemplatesPage-BArudpPa.js} +1 -1
- package/web-app/dist/assets/{TerminalOutput-ClZtwhW8.js → TerminalOutput-DxA5HoZ5.js} +1 -1
- package/web-app/dist/assets/{activity-DSOGDSlj.js → activity-BR76ZMBh.js} +1 -1
- package/web-app/dist/assets/{bell-BQaMS_Ge.js → bell-Br9K5dz8.js} +1 -1
- package/web-app/dist/assets/{bot-Iw0qLbSN.js → bot-DWOsO7gw.js} +1 -1
- package/web-app/dist/assets/{check-BNNpt5tE.js → check-CbHxZskh.js} +1 -1
- package/web-app/dist/assets/{chevron-left-DDFdacve.js → chevron-left-B7VJtFeE.js} +1 -1
- package/web-app/dist/assets/{circle-alert-CiRTbi7c.js → circle-alert-DFxljQkZ.js} +1 -1
- package/web-app/dist/assets/{clock-hudCD7-Z.js → clock-BDhyJZBv.js} +1 -1
- package/web-app/dist/assets/{cloud-Brn55LA3.js → cloud-BxVf6gss.js} +1 -1
- package/web-app/dist/assets/{code-xml-kiS4rISP.js → code-xml-BsBy-SZC.js} +1 -1
- package/web-app/dist/assets/{database-BD1l1Tuw.js → database-Bqz0cKPA.js} +1 -1
- package/web-app/dist/assets/{dollar-sign-DT5e3PIo.js → dollar-sign-Nma2_5tQ.js} +1 -1
- package/web-app/dist/assets/{file-code-corner-DmixJzQ5.js → file-code-corner-DDiKT74Y.js} +1 -1
- package/web-app/dist/assets/{file-plus-CeQieVbR.js → file-plus-Bsi1eh4g.js} +1 -1
- package/web-app/dist/assets/{globe-BayFHork.js → globe-BrDJU35Q.js} +1 -1
- package/web-app/dist/assets/{hammer-BzJ_7lDH.js → hammer-Cc0dGdYB.js} +1 -1
- package/web-app/dist/assets/{index-DgDlNUmy.js → index-CwRUHGRH.js} +3 -3
- package/web-app/dist/assets/{layers-CfWES4J2.js → layers-dBYYRarz.js} +1 -1
- package/web-app/dist/assets/{loader-circle-CH0UbcAO.js → loader-circle-Bgp8OiC8.js} +1 -1
- package/web-app/dist/assets/{lock-BuKglb_x.js → lock-mYd7M_sm.js} +1 -1
- package/web-app/dist/assets/{package-BkpU_Qb_.js → package-Bl6u282j.js} +1 -1
- package/web-app/dist/assets/{plus-BFMNyc0G.js → plus-H-VgX3FJ.js} +1 -1
- package/web-app/dist/assets/{refresh-cw-DQnQVKNC.js → refresh-cw-emJQn2ZS.js} +1 -1
- package/web-app/dist/assets/{rotate-ccw-B_M9AdjB.js → rotate-ccw-CTDYewXA.js} +1 -1
- package/web-app/dist/assets/{scroll-text-1P39rc_L.js → scroll-text-Bx_yfYId.js} +1 -1
- package/web-app/dist/assets/{server-BjGwVEsb.js → server-CfCbWR2b.js} +1 -1
- package/web-app/dist/assets/{shield-alert-CKcYjHu8.js → shield-alert-ODyUhCBO.js} +1 -1
- package/web-app/dist/assets/{thumbs-up-BC_5mpCw.js → thumbs-up-D4rG_0Db.js} +1 -1
- package/web-app/dist/assets/{trash-2-CjtQl9fg.js → trash-2-CLW0eSji.js} +1 -1
- package/web-app/dist/assets/{trending-down-D9MnFNOD.js → trending-down-B_9FnZty.js} +1 -1
- package/web-app/dist/assets/{trending-up-DrHz29bk.js → trending-up-fEvDswGA.js} +1 -1
- package/web-app/dist/assets/{upload-D7jmahPb.js → upload-DvgEs5QL.js} +1 -1
- package/web-app/dist/assets/{usePolling-C-zxuzqz.js → usePolling-KK1QY8nW.js} +1 -1
- package/web-app/dist/assets/{user-DE2Mkf9B.js → user-Cp4-qLBC.js} +1 -1
- package/web-app/dist/index.html +1 -1
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
|
-
|
|
23256
|
-
return
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
|
@@ -28178,13 +28213,14 @@ _pr_record_merge() {
|
|
|
28178
28213
|
# exactly 0 reverts in git history. A revert count of null (history
|
|
28179
28214
|
# unreadable), a missing record, an unreadable trust output or an unreadable or
|
|
28180
28215
|
# truncated file list or an unreadable diff all refuse, as does any PR whose
|
|
28181
|
-
# diff touches a symlink (120000) or submodule (160000) mode
|
|
28216
|
+
# diff touches a symlink (120000) or submodule (160000) mode, including a pure
|
|
28217
|
+
# rename of one (modes read from git on the base and head). Protected paths (.github/, .loki/, .env*,
|
|
28182
28218
|
# .envrc, CODEOWNERS, plus the space-separated globs in
|
|
28183
28219
|
# LOKI_EARNED_MERGE_PROTECTED), matched case-insensitively, always stay
|
|
28184
28220
|
# PR-only. The reason for a refusal goes to stdout; the return code is 1.
|
|
28185
28221
|
_pr_earned_merge_check() {
|
|
28186
28222
|
local pr="$1" min="${LOKI_EARNED_MERGE_MIN_VERIFIED:-20}" meta="" num="" want="" lines="" seals=""
|
|
28187
|
-
local kind p lp g row v r got=0 globs=() diff="" bad_mode=""
|
|
28223
|
+
local kind p lp g row v r got=0 globs=() diff="" bad_mode="" renames="" refs="" base="" head="" from to m_old m_new
|
|
28188
28224
|
case "$min" in ''|*[!0-9]*) min=20 ;; esac
|
|
28189
28225
|
[ "$min" -ge 1 ] || min=1
|
|
28190
28226
|
command -v jq >/dev/null 2>&1 || { echo "jq is required to read the Seal record"; return 1; }
|
|
@@ -28229,6 +28265,28 @@ EOF_FILES
|
|
|
28229
28265
|
[ -n "$diff" ] || { echo "the PR's file modes are unreadable"; return 1; }
|
|
28230
28266
|
bad_mode="$(printf '%s\n' "$diff" | awk '/^diff --git /{h=$0} /^(new file mode|deleted file mode|old mode|new mode) (120000|160000)$/{print h; exit} /^index [0-9a-f.]+ (120000|160000)$/{print h; exit}')"
|
|
28231
28267
|
[ -z "$bad_mode" ] || { echo "${bad_mode#diff --git } involves a symlink or submodule"; return 1; }
|
|
28268
|
+
# A pure rename (100% similarity) carries no mode or index line, so the scan
|
|
28269
|
+
# above cannot see a symlink moving. Read both sides' modes from git.
|
|
28270
|
+
renames="$(printf '%s\n' "$diff" | awk '/^rename from /{f=substr($0,13)} /^rename to /{print f "\t" substr($0,11); f=""}')"
|
|
28271
|
+
if [ -n "$renames" ]; then
|
|
28272
|
+
refs="$(gh pr view "$pr" --json baseRefOid,headRefOid -q '.baseRefOid + " " + .headRefOid' 2>/dev/null)" || refs=""
|
|
28273
|
+
base="${refs%% *}"; head="${refs#* }"
|
|
28274
|
+
case "$base$head" in ''|*[!0-9a-f]*) echo "the PR's rename modes are unreadable"; return 1 ;; esac
|
|
28275
|
+
if ! git cat-file -e "${base}^{commit}" 2>/dev/null || ! git cat-file -e "${head}^{commit}" 2>/dev/null; then
|
|
28276
|
+
GIT_TERMINAL_PROMPT=0 git fetch -q origin "pull/${num}/head" >/dev/null 2>&1 || true
|
|
28277
|
+
fi
|
|
28278
|
+
while IFS="$(printf '\t')" read -r from to; do
|
|
28279
|
+
[ -n "$to" ] || continue
|
|
28280
|
+
m_old="$(git ls-tree --full-tree "$base" -- "$from" 2>/dev/null | awk '{print $1; exit}')"
|
|
28281
|
+
m_new="$(git ls-tree --full-tree "$head" -- "$to" 2>/dev/null | awk '{print $1; exit}')"
|
|
28282
|
+
case "$m_old:$m_new" in
|
|
28283
|
+
120000:*|160000:*|*:120000|*:160000) echo "rename from $from to $to involves a symlink or submodule"; return 1 ;;
|
|
28284
|
+
'':*|*:'') echo "rename from $from to $to has unreadable file modes"; return 1 ;;
|
|
28285
|
+
esac
|
|
28286
|
+
done <<EOF_RENAMES
|
|
28287
|
+
$renames
|
|
28288
|
+
EOF_RENAMES
|
|
28289
|
+
fi
|
|
28232
28290
|
return 0
|
|
28233
28291
|
}
|
|
28234
28292
|
|
|
@@ -30531,7 +30589,8 @@ cmd_remote() {
|
|
|
30531
30589
|
# If workspace isn't trusted, it exits immediately with an error.
|
|
30532
30590
|
# Use || true to prevent set -e from killing the script before auto-recovery.
|
|
30533
30591
|
local rc_exit=0
|
|
30534
|
-
|
|
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=$?
|
|
30535
30594
|
|
|
30536
30595
|
# Exit 0 = normal session end
|
|
30537
30596
|
if [ $rc_exit -eq 0 ]; then
|
|
@@ -30571,7 +30630,8 @@ print('ok')
|
|
|
30571
30630
|
echo ""
|
|
30572
30631
|
echo -e "${GREEN}Launching remote control...${NC}"
|
|
30573
30632
|
echo ""
|
|
30574
|
-
|
|
30633
|
+
_loki_perm_argv_for "$PWD" >/dev/null 2>&1 || true
|
|
30634
|
+
SHELL="$_LOKI_CLAUDE_SHELL" exec claude remote-control ${rc_flags[@]+"${rc_flags[@]}"}
|
|
30575
30635
|
}
|
|
30576
30636
|
|
|
30577
30637
|
# Syslog/SIEM integration management
|
|
@@ -31250,6 +31310,7 @@ cmd_metrics() {
|
|
|
31250
31310
|
local last_n=0
|
|
31251
31311
|
local save_file=false
|
|
31252
31312
|
local share_flag=false
|
|
31313
|
+
local share_visibility=""
|
|
31253
31314
|
|
|
31254
31315
|
while [[ $# -gt 0 ]]; do
|
|
31255
31316
|
case "$1" in
|
|
@@ -31266,7 +31327,8 @@ cmd_metrics() {
|
|
|
31266
31327
|
echo " --json Machine-readable JSON output"
|
|
31267
31328
|
echo " --last N Analyze only the last N sessions (default: all)"
|
|
31268
31329
|
echo " --save Write report to METRICS.md in project root"
|
|
31269
|
-
echo " --share Upload report as GitHub Gist (via loki share)"
|
|
31330
|
+
echo " --share Upload report as a secret GitHub Gist (via loki share)"
|
|
31331
|
+
echo " --public With --share, create a PUBLIC gist instead"
|
|
31270
31332
|
echo " --help, -h Show this help"
|
|
31271
31333
|
echo ""
|
|
31272
31334
|
echo "Subcommands:"
|
|
@@ -31277,7 +31339,7 @@ cmd_metrics() {
|
|
|
31277
31339
|
echo " loki metrics --json # Machine-readable output"
|
|
31278
31340
|
echo " loki metrics --last 5 # Last 5 sessions only"
|
|
31279
31341
|
echo " loki metrics --save # Write METRICS.md"
|
|
31280
|
-
echo " loki metrics --share # Share as GitHub Gist"
|
|
31342
|
+
echo " loki metrics --share # Share as a secret GitHub Gist"
|
|
31281
31343
|
echo " loki metrics prometheus # Prometheus metrics from dashboard"
|
|
31282
31344
|
exit 0
|
|
31283
31345
|
;;
|
|
@@ -31286,6 +31348,7 @@ cmd_metrics() {
|
|
|
31286
31348
|
--last=*) last_n="${1#*=}"; shift ;;
|
|
31287
31349
|
--save) save_file=true; shift ;;
|
|
31288
31350
|
--share) share_flag=true; shift ;;
|
|
31351
|
+
--public) share_visibility="--public"; shift ;;
|
|
31289
31352
|
prometheus)
|
|
31290
31353
|
# Legacy Prometheus metrics subcommand
|
|
31291
31354
|
shift
|
|
@@ -31685,21 +31748,22 @@ METRICS_SCRIPT
|
|
|
31685
31748
|
|
|
31686
31749
|
# Handle --share flag
|
|
31687
31750
|
if [ "$share_flag" = true ]; then
|
|
31688
|
-
local tmpfile
|
|
31689
|
-
|
|
31751
|
+
local tmpdir tmpfile
|
|
31752
|
+
tmpdir=$(mktemp -d "${TMPDIR:-/tmp}/loki-metrics.XXXXXXXX") || exit 1
|
|
31753
|
+
tmpfile="$tmpdir/metrics.md"
|
|
31690
31754
|
echo "$metrics_output" > "$tmpfile"
|
|
31691
31755
|
|
|
31692
31756
|
if ! command -v gh &>/dev/null; then
|
|
31693
31757
|
echo -e "${RED}gh CLI not found -- cannot share${NC}"
|
|
31694
31758
|
echo "Install: brew install gh"
|
|
31695
|
-
rm -f "$tmpfile"
|
|
31759
|
+
rm -f "$tmpfile"; rmdir "$tmpdir" 2>/dev/null || true
|
|
31696
31760
|
exit 1
|
|
31697
31761
|
fi
|
|
31698
31762
|
|
|
31699
31763
|
if ! gh auth status &>/dev/null 2>&1; then
|
|
31700
31764
|
echo -e "${RED}GitHub CLI not authenticated${NC}"
|
|
31701
31765
|
echo "Run 'gh auth login' to authenticate."
|
|
31702
|
-
rm -f "$tmpfile"
|
|
31766
|
+
rm -f "$tmpfile"; rmdir "$tmpdir" 2>/dev/null || true
|
|
31703
31767
|
exit 1
|
|
31704
31768
|
fi
|
|
31705
31769
|
|
|
@@ -31708,9 +31772,12 @@ METRICS_SCRIPT
|
|
|
31708
31772
|
project_name=$(basename "$(pwd)")
|
|
31709
31773
|
local gist_desc="Loki Mode productivity report - ${project_name:-project} ($(date +%Y-%m-%d))"
|
|
31710
31774
|
local gist_url
|
|
31711
|
-
|
|
31775
|
+
if [ "$share_visibility" = "--public" ]; then
|
|
31776
|
+
echo -e "${YELLOW}Warning: this gist is PUBLIC and visible to anyone with the URL.${NC}" >&2
|
|
31777
|
+
fi
|
|
31778
|
+
gist_url=$(gh gist create "$tmpfile" --desc "$gist_desc" $share_visibility 2>&1)
|
|
31712
31779
|
local gist_exit=$?
|
|
31713
|
-
rm -f "$tmpfile"
|
|
31780
|
+
rm -f "$tmpfile"; rmdir "$tmpdir" 2>/dev/null || true
|
|
31714
31781
|
|
|
31715
31782
|
if [ $gist_exit -ne 0 ]; then
|
|
31716
31783
|
echo -e "${RED}Failed to create gist${NC}"
|
|
@@ -32805,7 +32872,8 @@ USER TASK: ${prompt}"
|
|
|
32805
32872
|
local agent_exit=0
|
|
32806
32873
|
case "$provider" in
|
|
32807
32874
|
claude)
|
|
32808
|
-
|
|
32875
|
+
_loki_perm_argv_for "$PWD" >/dev/null 2>&1 || true
|
|
32876
|
+
SHELL="$_LOKI_CLAUDE_SHELL" claude -p "$full_prompt" 2>&1 || agent_exit=$?
|
|
32809
32877
|
;;
|
|
32810
32878
|
codex)
|
|
32811
32879
|
codex exec --sandbox workspace-write "$full_prompt" 2>&1 || agent_exit=$?
|
|
@@ -32946,7 +33014,7 @@ $diff"
|
|
|
32946
33014
|
[ -f ".loki/state/provider" ] && provider=$(cat ".loki/state/provider" 2>/dev/null)
|
|
32947
33015
|
|
|
32948
33016
|
case "$provider" in
|
|
32949
|
-
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 ;;
|
|
32950
33018
|
codex) codex exec --sandbox workspace-write "$review_prompt" 2>&1 ;;
|
|
32951
33019
|
cline) cline -y "$review_prompt" 2>&1 ;;
|
|
32952
33020
|
aider) aider --message "$review_prompt" --yes-always --no-auto-commits < /dev/null 2>&1 ;;
|
|
@@ -34714,7 +34782,8 @@ _docs_invoke_provider() {
|
|
|
34714
34782
|
declare -F loki_child_ledger_append >/dev/null 2>&1 && _ledger=true
|
|
34715
34783
|
local _fmt=()
|
|
34716
34784
|
[ "$_ledger" = true ] && _fmt=(--output-format json)
|
|
34717
|
-
|
|
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=$?
|
|
34718
34787
|
if [ "$_ledger" = true ] && [ -n "$result" ]; then
|
|
34719
34788
|
loki_child_ledger_append docs "$result" >/dev/null 2>&1 || true
|
|
34720
34789
|
result=$(printf '%s' "$result" | python3 -c 'import json,sys
|
|
@@ -38915,7 +38984,8 @@ REPORT_SCRIPT
|
|
|
38915
38984
|
|
|
38916
38985
|
cmd_share() {
|
|
38917
38986
|
local format="markdown"
|
|
38918
|
-
|
|
38987
|
+
# Secret by default: --public is passed to gh only on an explicit --public.
|
|
38988
|
+
local visibility=""
|
|
38919
38989
|
|
|
38920
38990
|
while [[ $# -gt 0 ]]; do
|
|
38921
38991
|
case "$1" in
|
|
@@ -38928,20 +38998,22 @@ cmd_share() {
|
|
|
38928
38998
|
echo "returning a shareable URL."
|
|
38929
38999
|
echo ""
|
|
38930
39000
|
echo "Options:"
|
|
38931
|
-
echo " --
|
|
39001
|
+
echo " --public Create a PUBLIC gist, visible to anyone with the URL"
|
|
39002
|
+
echo " --private Create a secret gist (default: secret; accepted for compatibility)"
|
|
38932
39003
|
echo " --format <fmt> Report format: text, markdown, html (default: markdown)"
|
|
38933
39004
|
echo " --help, -h Show this help"
|
|
38934
39005
|
echo ""
|
|
38935
39006
|
echo "Examples:"
|
|
38936
|
-
echo " loki share #
|
|
38937
|
-
echo " loki share --
|
|
38938
|
-
echo " loki share --format html #
|
|
38939
|
-
echo " loki share --
|
|
39007
|
+
echo " loki share # Secret markdown gist (default)"
|
|
39008
|
+
echo " loki share --public # Public gist"
|
|
39009
|
+
echo " loki share --format html # Secret HTML gist"
|
|
39010
|
+
echo " loki share --public --format text # Public text gist"
|
|
38940
39011
|
echo ""
|
|
38941
39012
|
echo "Requires: gh CLI (https://cli.github.com)"
|
|
38942
39013
|
exit 0
|
|
38943
39014
|
;;
|
|
38944
39015
|
--private) visibility=""; shift ;;
|
|
39016
|
+
--public) visibility="--public"; shift ;;
|
|
38945
39017
|
--format) format="${2:-markdown}"; shift 2 ;;
|
|
38946
39018
|
--format=*) format="${1#*=}"; shift ;;
|
|
38947
39019
|
*) echo -e "${RED}Unknown option: $1${NC}" >&2; echo "Run 'loki share --help' for usage." >&2; exit 1 ;;
|
|
@@ -38991,20 +39063,21 @@ cmd_share() {
|
|
|
38991
39063
|
esac
|
|
38992
39064
|
|
|
38993
39065
|
# Generate report to temp file
|
|
38994
|
-
local tmpfile
|
|
38995
|
-
|
|
39066
|
+
local tmpdir tmpfile
|
|
39067
|
+
tmpdir=$(mktemp -d "${TMPDIR:-/tmp}/loki-share.XXXXXXXX") || exit 1
|
|
39068
|
+
tmpfile="$tmpdir/session-report.$ext"
|
|
38996
39069
|
|
|
38997
39070
|
echo "Generating session report..."
|
|
38998
39071
|
if ! "$0" report --format "$format" > "$tmpfile" 2>/dev/null; then
|
|
38999
39072
|
echo -e "${RED}Failed to generate session report${NC}"
|
|
39000
|
-
rm -f "$tmpfile"
|
|
39073
|
+
rm -f "$tmpfile"; rmdir "$tmpdir" 2>/dev/null || true
|
|
39001
39074
|
exit 1
|
|
39002
39075
|
fi
|
|
39003
39076
|
|
|
39004
39077
|
# Verify report is not empty
|
|
39005
39078
|
if [ ! -s "$tmpfile" ]; then
|
|
39006
39079
|
echo -e "${RED}Generated report is empty${NC}"
|
|
39007
|
-
rm -f "$tmpfile"
|
|
39080
|
+
rm -f "$tmpfile"; rmdir "$tmpdir" 2>/dev/null || true
|
|
39008
39081
|
exit 1
|
|
39009
39082
|
fi
|
|
39010
39083
|
|
|
@@ -39015,8 +39088,8 @@ cmd_share() {
|
|
|
39015
39088
|
}
|
|
39016
39089
|
|
|
39017
39090
|
# Internal helper: upload a single file as a GitHub Gist.
|
|
39018
|
-
# Args: $1=file path, $2=description, $3=visibility ("--public"
|
|
39019
|
-
# or "" for gh's default). NOTE: $3 is intentionally left unquoted at the
|
|
39091
|
+
# Args: $1=file path, $2=description, $3=visibility ("--public" for a public
|
|
39092
|
+
# gist, or "" for gh's default, which is a secret gist). NOTE: $3 is intentionally left unquoted at the
|
|
39020
39093
|
# gh call site so an empty value collapses (the --private case sets it to "").
|
|
39021
39094
|
# Removes the input file after the attempt. Prints "Shared: <url>" on success;
|
|
39022
39095
|
# on failure prints the gh error and exits 1.
|
|
@@ -39031,6 +39104,9 @@ _loki_gist_upload() {
|
|
|
39031
39104
|
# "Shared:" line and the ready-to-post hook with multi-line gh chatter.
|
|
39032
39105
|
local gist_out gist_err gist_exit
|
|
39033
39106
|
local errfile
|
|
39107
|
+
if [ "$visibility" = "--public" ]; then
|
|
39108
|
+
echo -e "${YELLOW}Warning: this gist is PUBLIC and visible to anyone with the URL.${NC}" >&2
|
|
39109
|
+
fi
|
|
39034
39110
|
# Fall back to /dev/null if mktemp fails (disk full / unwritable /tmp) so the
|
|
39035
39111
|
# redirect target is always a real path -- never an empty string (2>"" is a
|
|
39036
39112
|
# bash error). We lose the captured stderr text in that rare case, not the
|
|
@@ -39041,8 +39117,12 @@ _loki_gist_upload() {
|
|
|
39041
39117
|
gist_err=$(cat "$errfile" 2>/dev/null)
|
|
39042
39118
|
[ "$errfile" != "/dev/null" ] && rm -f "$errfile"
|
|
39043
39119
|
|
|
39044
|
-
# Cleanup temp file
|
|
39120
|
+
# Cleanup temp file and its private loki-* directory (rmdir only removes
|
|
39121
|
+
# an empty directory).
|
|
39045
39122
|
rm -f "$file"
|
|
39123
|
+
case "$(basename "$(dirname "$file")")" in
|
|
39124
|
+
loki-*) rmdir "$(dirname "$file")" 2>/dev/null || true ;;
|
|
39125
|
+
esac
|
|
39046
39126
|
|
|
39047
39127
|
if [ $gist_exit -ne 0 ]; then
|
|
39048
39128
|
echo -e "${RED}Failed to create gist${NC}"
|
|
@@ -39165,8 +39245,9 @@ PYEOF
|
|
|
39165
39245
|
|
|
39166
39246
|
# POST the redacted HTML. Auth header is sent only if a license key exists;
|
|
39167
39247
|
# OSS users with their own endpoint need no key.
|
|
39168
|
-
local tmp_body tmp_code
|
|
39169
|
-
|
|
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"
|
|
39170
39251
|
local -a curl_args=(-sS -o "$tmp_body" -w '%{http_code}' -X POST
|
|
39171
39252
|
-H "Content-Type: text/html"
|
|
39172
39253
|
-H "X-Loki-Proof-Id: ${id}"
|
|
@@ -39180,7 +39261,7 @@ PYEOF
|
|
|
39180
39261
|
if [ "$curl_exit" -ne 0 ]; then
|
|
39181
39262
|
echo -e "${RED}Failed to reach hosted endpoint (curl exit ${curl_exit}).${NC}" >&2
|
|
39182
39263
|
echo "Check LOKI_HOSTED_ENDPOINT or publish to a gist: loki proof share ${id}" >&2
|
|
39183
|
-
rm -f "$tmp_body"
|
|
39264
|
+
rm -f "$tmp_body"; rmdir "$tmp_body_dir" 2>/dev/null || true
|
|
39184
39265
|
return 1
|
|
39185
39266
|
fi
|
|
39186
39267
|
|
|
@@ -39207,7 +39288,7 @@ except Exception:
|
|
|
39207
39288
|
print(url)
|
|
39208
39289
|
PYEOF
|
|
39209
39290
|
)
|
|
39210
|
-
rm -f "$tmp_body"
|
|
39291
|
+
rm -f "$tmp_body"; rmdir "$tmp_body_dir" 2>/dev/null || true
|
|
39211
39292
|
if [ -n "$published_url" ]; then
|
|
39212
39293
|
echo -e "${GREEN}Published: ${published_url}${NC}"
|
|
39213
39294
|
else
|
|
@@ -39224,7 +39305,7 @@ PYEOF
|
|
|
39224
39305
|
echo "" >&2
|
|
39225
39306
|
fi
|
|
39226
39307
|
echo "Nothing was published. Or publish to a gist: loki proof share ${id}" >&2
|
|
39227
|
-
rm -f "$tmp_body"
|
|
39308
|
+
rm -f "$tmp_body"; rmdir "$tmp_body_dir" 2>/dev/null || true
|
|
39228
39309
|
return 1
|
|
39229
39310
|
;;
|
|
39230
39311
|
esac
|
|
@@ -39495,7 +39576,8 @@ cmd_proof() {
|
|
|
39495
39576
|
echo ""
|
|
39496
39577
|
echo "Options for 'share':"
|
|
39497
39578
|
echo " --yes Skip the redaction-preview confirmation prompt"
|
|
39498
|
-
echo " --
|
|
39579
|
+
echo " --public Create a PUBLIC gist, visible to anyone with the URL"
|
|
39580
|
+
echo " --private Create a secret gist (default: secret; accepted for compatibility)"
|
|
39499
39581
|
echo " --hosted Publish to LOKI_HOSTED_ENDPOINT (open-core seam; no official backend yet)"
|
|
39500
39582
|
echo ""
|
|
39501
39583
|
echo "Proofs are generated automatically at run completion (LOKI_PROOF=0 to opt out)."
|
|
@@ -40153,7 +40235,7 @@ print(json.dumps(doc, indent=2))
|
|
|
40153
40235
|
share)
|
|
40154
40236
|
local id=""
|
|
40155
40237
|
local skip_confirm=0
|
|
40156
|
-
local visibility="
|
|
40238
|
+
local visibility=""
|
|
40157
40239
|
local hosted=0
|
|
40158
40240
|
# every python3 invocation below reads proof.json from inside
|
|
40159
40241
|
# the checkout being shared. Resolve an absolute path once so an
|
|
@@ -40258,8 +40340,9 @@ PYEOF
|
|
|
40258
40340
|
fi
|
|
40259
40341
|
|
|
40260
40342
|
# Copy to a temp file so _loki_gist_upload can remove it after.
|
|
40261
|
-
local tmpfile
|
|
40262
|
-
|
|
40343
|
+
local tmpfile tmpdir
|
|
40344
|
+
tmpdir=$(mktemp -d "${TMPDIR:-/tmp}/loki-proof.XXXXXXXX") || exit 1
|
|
40345
|
+
tmpfile="$tmpdir/proof.html"
|
|
40263
40346
|
cp "$html" "$tmpfile"
|
|
40264
40347
|
echo "Uploading proof page..."
|
|
40265
40348
|
local gist_desc="Loki Mode proof-of-run ${id}"
|
package/autonomy/quickstart.sh
CHANGED
|
@@ -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
|
package/completions/_loki
CHANGED
|
@@ -100,7 +100,7 @@ function _loki {
|
|
|
100
100
|
estimate)
|
|
101
101
|
_arguments \
|
|
102
102
|
'--json[Output machine-readable JSON]' \
|
|
103
|
-
'--model[Model whose
|
|
103
|
+
'--model[Model whose first-run prior to use]:model:' \
|
|
104
104
|
'--provider[Provider whose default model is used]:provider:' \
|
|
105
105
|
'--help[Show help]'
|
|
106
106
|
;;
|
|
@@ -185,7 +185,8 @@ function _loki {
|
|
|
185
185
|
'--json[Machine-readable JSON output]' \
|
|
186
186
|
'--last[Analyze last N sessions]:number:' \
|
|
187
187
|
'--save[Write report to METRICS.md]' \
|
|
188
|
-
'--share[Upload report as GitHub Gist]' \
|
|
188
|
+
'--share[Upload report as a secret GitHub Gist]' \
|
|
189
|
+
'--public[With --share, create a PUBLIC gist]' \
|
|
189
190
|
'--help[Show help]' \
|
|
190
191
|
'1:subcommand:(prometheus)'
|
|
191
192
|
;;
|
|
@@ -199,14 +200,16 @@ function _loki {
|
|
|
199
200
|
;;
|
|
200
201
|
share)
|
|
201
202
|
_arguments \
|
|
202
|
-
'--
|
|
203
|
+
'--public[Create a PUBLIC gist, visible to anyone with the URL]' \
|
|
204
|
+
'--private[Create a secret gist (default)]' \
|
|
203
205
|
'--format[Report format]:format:(text markdown html)' \
|
|
204
206
|
'--help[Show help]'
|
|
205
207
|
;;
|
|
206
208
|
proof)
|
|
207
209
|
_arguments \
|
|
208
210
|
'--yes[Skip redaction-preview confirmation]' \
|
|
209
|
-
'--
|
|
211
|
+
'--public[Create a PUBLIC gist when sharing]' \
|
|
212
|
+
'--private[Create a secret gist when sharing (default)]' \
|
|
210
213
|
'--hosted[Hosted publishing (coming in R9)]' \
|
|
211
214
|
'--dry-run[Scan and list what share would publish; publishes nothing]' \
|
|
212
215
|
'--help[Show help]' \
|
package/completions/loki.bash
CHANGED
|
@@ -355,7 +355,7 @@ _loki_completion() {
|
|
|
355
355
|
|
|
356
356
|
metrics)
|
|
357
357
|
if [[ "$cur" == -* ]]; then
|
|
358
|
-
COMPREPLY=( $(compgen -W "--json --last --save --share --help" -- "$cur") )
|
|
358
|
+
COMPREPLY=( $(compgen -W "--json --last --save --share --public --help" -- "$cur") )
|
|
359
359
|
return 0
|
|
360
360
|
fi
|
|
361
361
|
local metrics_cmds="prometheus"
|
|
@@ -373,7 +373,7 @@ _loki_completion() {
|
|
|
373
373
|
|
|
374
374
|
share)
|
|
375
375
|
if [[ "$cur" == -* ]]; then
|
|
376
|
-
COMPREPLY=( $(compgen -W "--private --format --help" -- "$cur") )
|
|
376
|
+
COMPREPLY=( $(compgen -W "--public --private --format --help" -- "$cur") )
|
|
377
377
|
return 0
|
|
378
378
|
fi
|
|
379
379
|
if [[ "$prev" == "--format" ]]; then
|
|
@@ -384,7 +384,7 @@ _loki_completion() {
|
|
|
384
384
|
|
|
385
385
|
proof)
|
|
386
386
|
if [[ "$cur" == -* ]]; then
|
|
387
|
-
COMPREPLY=( $(compgen -W "--yes --private --hosted --dry-run --out --help" -- "$cur") )
|
|
387
|
+
COMPREPLY=( $(compgen -W "--yes --public --private --hosted --dry-run --out --help" -- "$cur") )
|
|
388
388
|
return 0
|
|
389
389
|
fi
|
|
390
390
|
if [[ $cword -eq 2 ]]; then
|
package/dashboard/__init__.py
CHANGED
package/docs/CLI-REFERENCE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# CLI reference
|
|
2
2
|
|
|
3
|
-
Generated from `loki-ts/src/cli/registry.ts` by `scripts/generate-stale-zero.sh` for v11.
|
|
3
|
+
Generated from `loki-ts/src/cli/registry.ts` by `scripts/generate-stale-zero.sh` for v11.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 |
|
package/docs/INSTALLATION.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Loki Mode, by [Autonomi](https://www.autonomi.dev/), turns a spec or an issue into a verified pull request with a receipt you can check. This page covers installing it, a first run, and the options around it.
|
|
4
4
|
|
|
5
|
-
**Version:** v11.
|
|
5
|
+
**Version:** v11.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
|
|
|
@@ -36,7 +36,7 @@ Deviation from the card: there is no mounted output dir. A writable host mount w
|
|
|
36
36
|
- Oversized output: capped by `--max-output`; `output_truncated` is set.
|
|
37
37
|
- Fork bomb: `--pids-limit 256`. Memory bomb: `--memory`. Disk fill: tmpfs size caps.
|
|
38
38
|
- Forged result: the checked code can print a fake `LOKI_VPR_END` line. A per-run 128-bit nonce is sent to the wrapper on stdin and the checked command runs with stdin from /dev/null; the host accepts only the last line carrying that nonce. Docker's default seccomp profile does NOT block ptrace or process_vm_readv on kernels >= 4.8, and the checked command runs as the same uid as the wrapper inside the container, so a hostile process can read the wrapper's memory and recover the nonce. The nonce therefore only stops accidental or naive forgery; it is not a security boundary. One cross-check is added: the wrapper exits with the check's code and the host rejects (status ERROR) a sentinel that disagrees with docker's own exit code. The PR code can still make its own check report success, which is why `result.json` is a signal about the check and not the final verdict (VPR-2 owns that, and it must not treat a bare COMPLETED exit 0 as proof). A custom seccomp profile denying ptrace is a possible hardening and is not shipped here.
|
|
39
|
-
- Forged report: the report path is a per-run random name given only on the runner's command line, so printed totals cannot forge it.
|
|
39
|
+
- Forged report: the report path is a per-run random name given only on the runner's command line, so printed totals cannot forge it. The checked tests run inside the runner's process or its worker processes, so a hostile test that reads the path from the process command line can register an exit hook that rewrites the file after the runner has written it, and can still forge a pass; the same ptrace-class residual applies.
|
|
40
40
|
- Docker pool exhaustion: reported as BLOCKED, never as a failing check.
|
|
41
41
|
|
|
42
42
|
## Not covered (residual, tracked for VPR-2 review)
|