loki-mode 7.7.30 → 7.7.31
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/README.md +26 -6
- package/SKILL.md +2 -2
- package/VERSION +1 -1
- package/autonomy/run.sh +45 -14
- package/dashboard/__init__.py +1 -1
- package/dashboard/server.py +10 -3
- 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 +32 -0
package/README.md
CHANGED
|
@@ -38,6 +38,26 @@
|
|
|
38
38
|
|
|
39
39
|
## Get Started in 30 Seconds
|
|
40
40
|
|
|
41
|
+
**Prerequisites**
|
|
42
|
+
|
|
43
|
+
Loki drives a coding agent CLI and orchestrates real builds, so it needs a few tools on your PATH. `loki doctor` checks all of these and tells you what is missing.
|
|
44
|
+
|
|
45
|
+
Required:
|
|
46
|
+
|
|
47
|
+
- An agent provider CLI (at least one): [Claude Code](https://docs.claude.com/en/docs/claude-code) (`claude`, Tier 1, recommended), or OpenAI Codex CLI (`codex`), Cline, or Aider.
|
|
48
|
+
- Python 3.10+ (`python3`) for the dashboard, memory system, and orchestration helpers.
|
|
49
|
+
- Git 2.x (`git`) for checkpoints and worktrees.
|
|
50
|
+
- `curl` for installation and network calls.
|
|
51
|
+
|
|
52
|
+
Recommended:
|
|
53
|
+
|
|
54
|
+
- Bun 1.3.0+ (`bun`) for the fast runtime (the recommended install path below installs it).
|
|
55
|
+
- Node.js 18+ and npm if you install via npm instead of Bun.
|
|
56
|
+
- `jq` for nicer JSON handling in shell flows.
|
|
57
|
+
- Docker if you want Loki's App Runner to run containerized projects, or to run Loki itself from the published image.
|
|
58
|
+
|
|
59
|
+
You also need credentials for whichever provider you use (for Claude Code, an authenticated `claude` login or `ANTHROPIC_API_KEY`).
|
|
60
|
+
|
|
41
61
|
**Recommended (Bun, fastest):**
|
|
42
62
|
|
|
43
63
|
```bash
|
|
@@ -66,7 +86,7 @@ loki quick "build a landing page with a signup form"
|
|
|
66
86
|
|--------|---------|-------|
|
|
67
87
|
| **Bun (recommended)** | `bun install -g loki-mode` | Fastest. v8 will be Bun-only. |
|
|
68
88
|
| **Homebrew** | `brew tap asklokesh/tap && brew install loki-mode` | Auto-installs Bun as a dep |
|
|
69
|
-
| **Docker** | `docker pull asklokesh/loki-mode:7.
|
|
89
|
+
| **Docker** | `docker pull asklokesh/loki-mode:7.7.31 && docker run --rm asklokesh/loki-mode:7.7.31 start prd.md` | Bun pre-installed in image |
|
|
70
90
|
| **npm (compat)** | `npm install -g loki-mode` | Works without Bun (bash fallback). Migrate any time with `loki self-update --to bun`. |
|
|
71
91
|
|
|
72
92
|
**Upgrading:**
|
|
@@ -85,12 +105,12 @@ See the [Installation Guide](docs/INSTALLATION.md) for the long form.
|
|
|
85
105
|
|
|
86
106
|
## Runtime Architecture
|
|
87
107
|
|
|
88
|
-
Loki Mode is in
|
|
108
|
+
Loki Mode is in a phased migration from a Bash-based runtime to a TypeScript/Bun runtime. The migration has merged to `main` and ships incrementally with each release.
|
|
89
109
|
|
|
90
110
|
**What ships today:**
|
|
91
111
|
|
|
92
|
-
-
|
|
93
|
-
- Every other command continues to execute on the existing Bash CLI (`autonomy/loki`).
|
|
112
|
+
- Commands routed to the Bun runtime when `bun` is on `PATH` (the router lives in `bin/loki`): `version`, `--version`, `-v`, `status`, `stats`, `doctor`, `provider` (covers `provider show` and `provider list`), `memory` (covers `memory list` and `memory index`), `rollback`, `kpis`, and `internal`.
|
|
113
|
+
- Every other command continues to execute on the existing Bash CLI (`autonomy/loki`), including the autonomous `loki start` / `loki run` loop which remains the Bash orchestrator (`autonomy/run.sh`).
|
|
94
114
|
- If `bun` is not on `PATH`, the shim falls through to Bash silently. Existing users without Bun installed see no behavior change.
|
|
95
115
|
|
|
96
116
|
**Rollback flag:**
|
|
@@ -126,7 +146,7 @@ The next major release sunsets the Bash runtime entirely. There is no firm calen
|
|
|
126
146
|
| Method | Command |
|
|
127
147
|
|--------|---------|
|
|
128
148
|
| **Homebrew** | `brew tap asklokesh/tap && brew install loki-mode` |
|
|
129
|
-
| **Docker** | `docker pull asklokesh/loki-mode:7.
|
|
149
|
+
| **Docker** | `docker pull asklokesh/loki-mode:7.7.31` |
|
|
130
150
|
| **Inside Claude Code** | `claude --dangerously-skip-permissions` then type "Loki Mode" |
|
|
131
151
|
| **Git clone** | `git clone https://github.com/asklokesh/loki-mode.git` |
|
|
132
152
|
|
|
@@ -137,7 +157,7 @@ See the full [Installation Guide](docs/INSTALLATION.md).
|
|
|
137
157
|
<details>
|
|
138
158
|
<summary><strong>Supported spec formats</strong></summary>
|
|
139
159
|
|
|
140
|
-
A "spec" is whatever you hand `loki start`. Loki auto-detects the format and normalises it before the RARV loop. A Markdown PRD is one form of spec; the table below lists every input the
|
|
160
|
+
A "spec" is whatever you hand `loki start`. Loki auto-detects the format and normalises it before the RARV loop. A Markdown PRD is one form of spec; the table below lists every input the CLI accepts.
|
|
141
161
|
|
|
142
162
|
| Format | Example | Notes |
|
|
143
163
|
|--------|---------|-------|
|
package/SKILL.md
CHANGED
|
@@ -3,7 +3,7 @@ name: loki-mode
|
|
|
3
3
|
description: Autonomous spec-to-product system. Triggers on "Loki Mode". Takes a spec (PRD, GitHub issue, OpenAPI doc, etc.) to deployed product via the RARV-C closure loop, with minimal human intervention. Provider-agnostic. Requires --dangerously-skip-permissions flag.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Loki Mode v7.7.
|
|
6
|
+
# Loki Mode v7.7.31
|
|
7
7
|
|
|
8
8
|
**You are an autonomous agent. You make decisions. You do not ask questions. You do not stop.**
|
|
9
9
|
|
|
@@ -381,4 +381,4 @@ See `CHANGELOG.md` entries [7.5.7], [7.5.8], [7.5.13] for the per-fix list and r
|
|
|
381
381
|
|
|
382
382
|
---
|
|
383
383
|
|
|
384
|
-
**v7.7.
|
|
384
|
+
**v7.7.31 | [Autonomi](https://www.autonomi.dev/) flagship product | ~260 lines core**
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
7.7.
|
|
1
|
+
7.7.31
|
package/autonomy/run.sh
CHANGED
|
@@ -11204,13 +11204,31 @@ except Exception as exc:
|
|
|
11204
11204
|
local exit_code=0
|
|
11205
11205
|
# v7.5.12: Mark provider pipeline as active so SIGINT trap can kill it.
|
|
11206
11206
|
LOKI_PROVIDER_ACTIVE=1
|
|
11207
|
+
# v7.7.31: authorize autonomous operation at the system-prompt tier so
|
|
11208
|
+
# the spawned agent does not read the user's global ~/.claude/CLAUDE.md,
|
|
11209
|
+
# judge it to conflict with the loki_system prompt, call AskUserQuestion,
|
|
11210
|
+
# and exit having done nothing. An appended system prompt outranks
|
|
11211
|
+
# CLAUDE.md memory (verified empirically). Default-on; opt out with
|
|
11212
|
+
# LOKI_AUTONOMY_OVERRIDE=off. Only added when the installed CLI supports
|
|
11213
|
+
# the flag and the override helper is in scope (sourced via the provider).
|
|
11214
|
+
# Build the claude flag list as an array. The base flags are always
|
|
11215
|
+
# present so the array is never empty (empty "${arr[@]}" under `set -u`
|
|
11216
|
+
# is an error on bash 3.2, the stock macOS shell). The autonomy override
|
|
11217
|
+
# is appended conditionally.
|
|
11218
|
+
local _loki_claude_argv=("--dangerously-skip-permissions" "--model" "$tier_param")
|
|
11219
|
+
if [ "${LOKI_AUTONOMY_OVERRIDE:-on}" != "off" ] \
|
|
11220
|
+
&& type _loki_autonomy_override_text >/dev/null 2>&1 \
|
|
11221
|
+
&& type loki_claude_flag_supported >/dev/null 2>&1 \
|
|
11222
|
+
&& loki_claude_flag_supported "--append-system-prompt"; then
|
|
11223
|
+
_loki_claude_argv+=("--append-system-prompt" "$(_loki_autonomy_override_text)")
|
|
11224
|
+
fi
|
|
11207
11225
|
case "${PROVIDER_NAME:-claude}" in
|
|
11208
11226
|
claude)
|
|
11209
11227
|
# Claude: Full features with stream-json output and agent tracking
|
|
11210
11228
|
# Uses dynamic tier for model selection based on RARV phase
|
|
11211
11229
|
# Pass tier to Python via environment for dashboard display
|
|
11212
11230
|
{ LOKI_CURRENT_MODEL="$tier_param" \
|
|
11213
|
-
claude
|
|
11231
|
+
claude "${_loki_claude_argv[@]}" -p "$prompt" \
|
|
11214
11232
|
--output-format stream-json --verbose 2>&1 | \
|
|
11215
11233
|
tee -a "$log_file" "$agent_log" "$iter_output" | \
|
|
11216
11234
|
python3 -u -c '
|
|
@@ -11948,21 +11966,34 @@ if __name__ == "__main__":
|
|
|
11948
11966
|
|
|
11949
11967
|
log_info "Press Ctrl+C to cancel"
|
|
11950
11968
|
|
|
11951
|
-
# Countdown with progress
|
|
11969
|
+
# Countdown with progress.
|
|
11970
|
+
# v7.7.31: the countdown now sleeps in short 1s ticks and checks the
|
|
11971
|
+
# STOP/PAUSE signal on every tick. Previously it slept in 10s (or 60s
|
|
11972
|
+
# for long waits) chunks and never read the STOP file, so a dashboard
|
|
11973
|
+
# Stop button or `loki stop` issued DURING the inter-iteration wait did
|
|
11974
|
+
# nothing for up to 60s, and a SIGTERM was deferred by bash until the
|
|
11975
|
+
# current sleep chunk finished. Short ticks make Stop take effect within
|
|
11976
|
+
# ~1s and let the SIGTERM trap fire promptly.
|
|
11952
11977
|
local remaining=$wait_time
|
|
11953
|
-
local
|
|
11954
|
-
|
|
11955
|
-
if [ $wait_time -gt 1800 ]; then
|
|
11956
|
-
interval=60
|
|
11957
|
-
fi
|
|
11958
|
-
|
|
11978
|
+
local _loki_dir_wait="${TARGET_DIR:-.}/.loki"
|
|
11979
|
+
local _last_shown=-1
|
|
11959
11980
|
while [ $remaining -gt 0 ]; do
|
|
11960
|
-
|
|
11961
|
-
|
|
11962
|
-
|
|
11963
|
-
|
|
11964
|
-
|
|
11965
|
-
|
|
11981
|
+
# Honor an immediate stop/pause requested during the wait (dashboard
|
|
11982
|
+
# Stop button, `loki stop`, or a STOP file written by any control).
|
|
11983
|
+
if [ -f "$_loki_dir_wait/STOP" ] || [ -f "$_loki_dir_wait/PAUSE" ]; then
|
|
11984
|
+
echo ""
|
|
11985
|
+
log_warn "Stop/pause signal detected during wait - returning to control loop"
|
|
11986
|
+
break
|
|
11987
|
+
fi
|
|
11988
|
+
# Refresh the human-readable countdown at most once per 10s of change
|
|
11989
|
+
# so we do not spam the terminal while still ticking every second.
|
|
11990
|
+
if [ $((remaining % 10)) -eq 0 ] || [ "$_last_shown" -ne "$remaining" ]; then
|
|
11991
|
+
local human_remaining=$(format_duration $remaining)
|
|
11992
|
+
printf "\r${YELLOW}Resuming in ${human_remaining}...${NC} "
|
|
11993
|
+
_last_shown=$remaining
|
|
11994
|
+
fi
|
|
11995
|
+
sleep 1
|
|
11996
|
+
remaining=$((remaining - 1))
|
|
11966
11997
|
done
|
|
11967
11998
|
echo ""
|
|
11968
11999
|
|
package/dashboard/__init__.py
CHANGED
package/dashboard/server.py
CHANGED
|
@@ -2166,7 +2166,8 @@ async def list_running_projects():
|
|
|
2166
2166
|
path = p.get("path", "")
|
|
2167
2167
|
pid = p.get("pid")
|
|
2168
2168
|
running = False
|
|
2169
|
-
|
|
2169
|
+
has_pid = isinstance(pid, int) and pid > 0
|
|
2170
|
+
if has_pid:
|
|
2170
2171
|
try:
|
|
2171
2172
|
os.kill(pid, 0)
|
|
2172
2173
|
running = True # signal 0 delivered -> pid alive
|
|
@@ -2174,8 +2175,14 @@ async def list_running_projects():
|
|
|
2174
2175
|
running = True # pid exists but owned by another user
|
|
2175
2176
|
except (ProcessLookupError, OSError):
|
|
2176
2177
|
running = False # ESRCH -> dead
|
|
2177
|
-
#
|
|
2178
|
-
|
|
2178
|
+
# session.json is only a FALLBACK for legacy sessions with no recorded
|
|
2179
|
+
# pid. v7.7.31: when a pid IS recorded but dead, that pid is
|
|
2180
|
+
# authoritative -- the orchestrator is gone, so do NOT let a stale
|
|
2181
|
+
# session.json (status still "running" after a hard kill / crash) flip
|
|
2182
|
+
# this back to running. Otherwise the switcher shows a dead session as
|
|
2183
|
+
# running and the Stop button targets a dead pid. Only consult
|
|
2184
|
+
# session.json when no pid was ever recorded.
|
|
2185
|
+
if not running and not has_pid and path:
|
|
2179
2186
|
try:
|
|
2180
2187
|
sess = _Path(path) / ".loki" / "session.json"
|
|
2181
2188
|
if sess.is_file():
|
package/docs/INSTALLATION.md
CHANGED
package/loki-ts/dist/loki.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
var _7=Object.defineProperty;var I7=(K)=>K;function P7(K,$){this[K]=I7.bind(null,$)}var v=(K,$)=>{for(var Q in $)_7(K,Q,{get:$[Q],enumerable:!0,configurable:!0,set:P7.bind($,Q)})};var w=(K,$)=>()=>(K&&($=K(K=0)),$);var t=import.meta.require;var e1={};v(e1,{lokiDir:()=>L,homeLokiDir:()=>k1,findRepoRootForVersion:()=>S1,REPO_ROOT:()=>p});import{resolve as u,dirname as N1}from"path";import{fileURLToPath as L7}from"url";import{existsSync as J1}from"fs";import{homedir as R7}from"os";function E7(){let K=i1;for(let $=0;$<6;$++){if(J1(u(K,"VERSION"))&&J1(u(K,"autonomy/run.sh")))return K;let Q=N1(K);if(Q===K)break;K=Q}return u(i1,"..","..","..")}function S1(K){let $=K;for(let Q=0;Q<6;Q++){if(J1(u($,"VERSION"))&&J1(u($,"autonomy/run.sh")))return $;let X=N1($);if(X===$)break;$=X}return u(K,"..","..","..")}function L(){return process.env.LOKI_DIR??u(process.cwd(),".loki")}function k1(){return u(R7(),".loki")}var i1,p;var g=w(()=>{i1=N1(L7(import.meta.url));p=E7()});import{readFileSync as w7}from"fs";import{resolve as x7,dirname as F7}from"path";import{fileURLToPath as N7}from"url";function G1(){if(o!==null)return o;let K="7.7.
|
|
2
|
+
var _7=Object.defineProperty;var I7=(K)=>K;function P7(K,$){this[K]=I7.bind(null,$)}var v=(K,$)=>{for(var Q in $)_7(K,Q,{get:$[Q],enumerable:!0,configurable:!0,set:P7.bind($,Q)})};var w=(K,$)=>()=>(K&&($=K(K=0)),$);var t=import.meta.require;var e1={};v(e1,{lokiDir:()=>L,homeLokiDir:()=>k1,findRepoRootForVersion:()=>S1,REPO_ROOT:()=>p});import{resolve as u,dirname as N1}from"path";import{fileURLToPath as L7}from"url";import{existsSync as J1}from"fs";import{homedir as R7}from"os";function E7(){let K=i1;for(let $=0;$<6;$++){if(J1(u(K,"VERSION"))&&J1(u(K,"autonomy/run.sh")))return K;let Q=N1(K);if(Q===K)break;K=Q}return u(i1,"..","..","..")}function S1(K){let $=K;for(let Q=0;Q<6;Q++){if(J1(u($,"VERSION"))&&J1(u($,"autonomy/run.sh")))return $;let X=N1($);if(X===$)break;$=X}return u(K,"..","..","..")}function L(){return process.env.LOKI_DIR??u(process.cwd(),".loki")}function k1(){return u(R7(),".loki")}var i1,p;var g=w(()=>{i1=N1(L7(import.meta.url));p=E7()});import{readFileSync as w7}from"fs";import{resolve as x7,dirname as F7}from"path";import{fileURLToPath as N7}from"url";function G1(){if(o!==null)return o;let K="7.7.31";if(typeof K==="string"&&K.length>0)return o=K,o;try{let $=F7(N7(import.meta.url)),Q=S1($);o=w7(x7(Q,"VERSION"),"utf-8").trim()}catch{o="unknown"}return o}var o=null;var C1=w(()=>{g()});var $0={};v($0,{runOrThrow:()=>S7,run:()=>C,commandVersion:()=>C7,commandExists:()=>b,ShellError:()=>D1});async function C(K,$={}){let Q=Bun.spawn({cmd:[...K],stdout:"pipe",stderr:"pipe",env:$.env?{...process.env,...$.env}:process.env,cwd:$.cwd}),X,Z;if($.timeoutMs&&$.timeoutMs>0)X=setTimeout(()=>{try{Q.kill("SIGTERM")}catch{}Z=setTimeout(()=>{try{Q.kill("SIGKILL")}catch{}},2000)},$.timeoutMs);try{let[W,z,q]=await Promise.all([new Response(Q.stdout).text(),new Response(Q.stderr).text(),Q.exited]);return{stdout:W,stderr:z,exitCode:q}}finally{if(X)clearTimeout(X);if(Z)clearTimeout(Z)}}async function S7(K,$={}){let Q=await C(K,$);if(Q.exitCode!==0)throw new D1(`command failed (${Q.exitCode}): ${K.join(" ")}`,Q.exitCode,Q.stdout,Q.stderr);return Q}async function b(K){let $=k7(K),Q=await C(["sh","-c",`command -v ${$}`],{timeoutMs:5000});if(Q.exitCode===0)return Q.stdout.trim()||null;return null}function k7(K){if(!/^[A-Za-z0-9._/-]+$/.test(K))throw Error(`refused to shell-escape suspect token: ${K}`);return K}async function C7(K,$="--version"){if(!await b(K))return null;let X=await C([K,$],{timeoutMs:5000});if(X.exitCode!==0)return null;return((X.stdout||X.stderr).split(/\r?\n/)[0]?.trim()??"")||null}var D1;var n=w(()=>{D1=class D1 extends Error{message;exitCode;stdout;stderr;constructor(K,$,Q,X){super(K);this.message=K;this.exitCode=$;this.stdout=Q;this.stderr=X;this.name="ShellError"}}});function c(K){return D7?"":K}var D7,F,y,N,A6,A,D,S,H;var a=w(()=>{D7=(process.env.NO_COLOR??"").length>0;F=c("\x1B[0;31m"),y=c("\x1B[0;32m"),N=c("\x1B[1;33m"),A6=c("\x1B[0;34m"),A=c("\x1B[0;36m"),D=c("\x1B[1m"),S=c("\x1B[2m"),H=c("\x1B[0m")});import{existsSync as c7}from"fs";async function i(){if(Z1!==void 0)return Z1;let K="/opt/homebrew/bin/python3.12";if(c7(K))return Z1=K,K;let $=await b("python3.12");if($)return Z1=$,$;let Q=await b("python3");return Z1=Q,Q}async function s(K,$={}){let Q=await i();if(!Q)return{stdout:"",stderr:"python3 not found",exitCode:127};return C([Q,"-c",K],$)}var Z1;var z1=w(()=>{n()});var G0={};v(G0,{runStatus:()=>X5});import{existsSync as k,readFileSync as K1,readdirSync as W0,statSync as H0}from"fs";import{resolve as R,basename as a7}from"path";import{homedir as s7}from"os";async function t7(){if(await b("jq"))return!0;return process.stdout.write(`${F}Error: jq is required but not installed.${H}
|
|
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)
|
|
@@ -604,4 +604,4 @@ Set LOKI_LEGACY_BASH=1 to force the bash CLI for every command.
|
|
|
604
604
|
`),2}default:return process.stderr.write(`Unknown command: ${$}
|
|
605
605
|
`),process.stderr.write(j7),2}}process.on("SIGINT",()=>process.exit(130));process.on("SIGTERM",()=>process.exit(143));var Z6=await X6(Bun.argv.slice(2));process.exit(Z6);
|
|
606
606
|
|
|
607
|
-
//# debugId=
|
|
607
|
+
//# debugId=4167329ADA92E7A964756E2164756E21
|
package/mcp/__init__.py
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "loki-mode",
|
|
3
|
-
"version": "7.7.
|
|
3
|
+
"version": "7.7.31",
|
|
4
4
|
"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).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent",
|
package/providers/claude.sh
CHANGED
|
@@ -201,6 +201,38 @@ _loki_build_claude_auto_flags() {
|
|
|
201
201
|
&& loki_claude_flag_supported "--include-hook-events"; then
|
|
202
202
|
_LOKI_CLAUDE_AUTO_FLAGS+=("--include-hook-events")
|
|
203
203
|
fi
|
|
204
|
+
|
|
205
|
+
# --append-system-prompt (v7.7.31): authorize autonomous operation at the
|
|
206
|
+
# system-prompt tier so the spawned agent does not refuse the run. Without
|
|
207
|
+
# this, the agent reads the user's global ~/.claude/CLAUDE.md (which may say
|
|
208
|
+
# "always ask for clarification" / "never commit without permission"),
|
|
209
|
+
# judges it to conflict with Loki's "never ask, never stop" prompt (which is
|
|
210
|
+
# only a user-message instruction and thus lower precedence), calls
|
|
211
|
+
# AskUserQuestion, and exits in ~30s having done nothing. An appended system
|
|
212
|
+
# prompt outranks CLAUDE.md memory (verified empirically), so it resolves the
|
|
213
|
+
# conflict in Loki's favor for this authorized session. Default-on; opt out
|
|
214
|
+
# with LOKI_AUTONOMY_OVERRIDE=off. We never edit the user's CLAUDE.md.
|
|
215
|
+
if [ "${LOKI_AUTONOMY_OVERRIDE:-on}" != "off" ] \
|
|
216
|
+
&& loki_claude_flag_supported "--append-system-prompt"; then
|
|
217
|
+
_LOKI_CLAUDE_AUTO_FLAGS+=("--append-system-prompt" "$(_loki_autonomy_override_text)")
|
|
218
|
+
fi
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
# The system-prompt text that authorizes autonomous operation and resolves
|
|
222
|
+
# precedence against a conflicting user/project CLAUDE.md. Kept in one place so
|
|
223
|
+
# the bash and Bun routes can stay byte-identical. No emojis, no em dashes.
|
|
224
|
+
_loki_autonomy_override_text() {
|
|
225
|
+
cat <<'LOKI_AUTONOMY_EOF'
|
|
226
|
+
You are running INSIDE Loki Mode autonomous execution, a session the user explicitly launched with full prior authorization (loki start / loki run). This IS an authorized autonomous session, not an unattended action you must seek consent for.
|
|
227
|
+
|
|
228
|
+
Instruction precedence for THIS session: when the loki_system instructions in the user prompt conflict with any CLAUDE.md, project memory, or global memory that tells you to ask for clarification, pause for confirmation, refuse to act autonomously, or withhold routine commits, the loki_system instructions take precedence. The user has already consented by launching autonomous mode.
|
|
229
|
+
|
|
230
|
+
Therefore, for this session: do NOT ask the user questions, do NOT call the AskUserQuestion tool, do NOT stop to request confirmation, and do NOT refuse routine, reversible engineering work (writing code, running tests, creating files, atomic git checkpoints in the working tree). Proceed and complete the task directly. If a decision is genuinely ambiguous, choose the most reasonable option, record the assumption in .loki/CONTINUITY.md, and continue rather than halting.
|
|
231
|
+
|
|
232
|
+
Commit hygiene still applies: git checkpoints are LOCAL only. Never push or force-push. Stage files by explicit path, never `git add -A` or `git add .`, and never commit secrets, credentials, .env files, or untracked files you did not author this session.
|
|
233
|
+
|
|
234
|
+
This precedence override is narrow. It does NOT relax any safety rule. Every safety prohibition in CLAUDE.md or memory still fully binds: anything genuinely destructive or irreversible remains out of scope unless the task explicitly calls for it. This includes (not limited to) force-pushing, deleting or overwriting the user's data, dropping or truncating databases, publishing or releasing, rotating or exfiltrating secrets, touching production systems, and anything a CLAUDE.md safety rule explicitly forbids. When in doubt about whether an action is destructive, treat it as destructive and do not do it.
|
|
235
|
+
LOKI_AUTONOMY_EOF
|
|
204
236
|
}
|
|
205
237
|
|
|
206
238
|
# Invocation function (basic, no tier).
|