loki-mode 7.51.0 → 7.52.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 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, 8 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.51.0
6
+ # Loki Mode v7.52.0
7
7
 
8
8
  **You are an autonomous agent. You make decisions. You do not ask questions. You do not stop.**
9
9
 
@@ -407,4 +407,4 @@ See `CHANGELOG.md` entries [7.5.7], [7.5.8], [7.5.13] for the per-fix list and r
407
407
 
408
408
  ---
409
409
 
410
- **v7.51.0 | [Autonomi](https://www.autonomi.dev/) flagship product | ~260 lines core**
410
+ **v7.52.0 | [Autonomi](https://www.autonomi.dev/) flagship product | ~260 lines core**
package/VERSION CHANGED
@@ -1 +1 @@
1
- 7.51.0
1
+ 7.52.0
@@ -2038,7 +2038,7 @@ ISSUES: CRITICAL:description (optional, one per line per issue)"
2038
2038
  ;;
2039
2039
  codex)
2040
2040
  if command -v codex &>/dev/null; then
2041
- verdict=$(codex exec --full-auto "$prompt" 2>/dev/null)
2041
+ verdict=$(codex exec --sandbox workspace-write "$prompt" 2>/dev/null)
2042
2042
  fi
2043
2043
  ;;
2044
2044
  gemini)
@@ -2139,7 +2139,7 @@ REASON: your reasoning"
2139
2139
  ;;
2140
2140
  codex)
2141
2141
  if command -v codex &>/dev/null; then
2142
- verdict=$(codex exec --full-auto "$prompt" 2>/dev/null)
2142
+ verdict=$(codex exec --sandbox workspace-write "$prompt" 2>/dev/null)
2143
2143
  fi
2144
2144
  ;;
2145
2145
  gemini)
package/autonomy/grill.sh CHANGED
@@ -227,7 +227,7 @@ grill_invoke_provider() {
227
227
  return $GRILL_EXIT_ERROR
228
228
  fi
229
229
  local out
230
- out="$(printf '%s' "$prompt" | _grill_with_timeout "${LOKI_GRILL_TIMEOUT:-180}" codex exec --full-auto - 2>/dev/null)"
230
+ out="$(printf '%s' "$prompt" | _grill_with_timeout "${LOKI_GRILL_TIMEOUT:-180}" codex exec --sandbox workspace-write - 2>/dev/null)"
231
231
  if [ -z "$out" ]; then
232
232
  _grill_err "provider returned no output"
233
233
  return $GRILL_EXIT_ERROR
@@ -63,31 +63,35 @@ loki_remaining_budget() {
63
63
  local budget_file="${TARGET_DIR:-.}/.loki/metrics/budget.json"
64
64
  local spend="0"
65
65
  if [ -f "$budget_file" ]; then
66
- spend=$(python3 -c "
67
- import json, sys
66
+ # Pass the path via env var (os.environ), NOT string interpolation, so a
67
+ # path containing a single quote (or other python/shell-breaking char)
68
+ # cannot break the parse. Single-quoted program -> bash interpolates nothing.
69
+ spend=$(_LOKI_BUDGET_FILE="$budget_file" python3 -c '
70
+ import json, os, sys
68
71
  try:
69
- with open('$budget_file') as f:
72
+ with open(os.environ["_LOKI_BUDGET_FILE"]) as f:
70
73
  d = json.load(f)
71
- v = d.get('current_spend', 0)
74
+ v = d.get("current_spend", 0)
72
75
  print(float(v))
73
76
  except Exception:
74
77
  print(0)
75
- " 2>/dev/null)
78
+ ' 2>/dev/null)
76
79
  fi
77
80
  # Compute remaining via python3 (bash floats are unreliable across awk/bc variations).
78
- python3 -c "
79
- import sys
81
+ # Pass limit/spend via env vars too (same hardening; single-quoted program).
82
+ _LOKI_BUDGET_LIMIT="$limit" _LOKI_BUDGET_SPEND="$spend" python3 -c '
83
+ import os, sys
80
84
  try:
81
- limit = float('$limit')
82
- spend = float('$spend')
85
+ limit = float(os.environ["_LOKI_BUDGET_LIMIT"])
86
+ spend = float(os.environ["_LOKI_BUDGET_SPEND"])
83
87
  rem = limit - spend
84
88
  # Strictly positive; otherwise emit nothing (caller decides whether to bail or warn).
85
89
  if rem > 0:
86
90
  # Round to 2 decimal places for the CLI.
87
- print(f'{rem:.2f}')
91
+ print(f"{rem:.2f}")
88
92
  except Exception:
89
93
  pass
90
- " 2>/dev/null
94
+ ' 2>/dev/null
91
95
  }
92
96
 
93
97
  # ---------- Fallback model ----------
@@ -57,7 +57,7 @@ def invoke_llm(prompt, timeout=120):
57
57
 
58
58
  cmds = {
59
59
  "claude": ["claude", "-p", prompt],
60
- "codex": ["codex", "exec", "--full-auto", prompt],
60
+ "codex": ["codex", "exec", "--sandbox", "workspace-write", prompt],
61
61
  "cline": ["cline", "-y", prompt],
62
62
  "aider": ["aider", "--message", prompt, "--yes-always", "--no-auto-commits"],
63
63
  }
package/autonomy/loki CHANGED
@@ -3785,7 +3785,7 @@ cmd_provider_info() {
3785
3785
  echo "Name: Codex CLI"
3786
3786
  echo "Vendor: OpenAI"
3787
3787
  echo "CLI: codex"
3788
- echo "Flag: --full-auto"
3788
+ echo "Flag: --sandbox workspace-write"
3789
3789
  echo ""
3790
3790
  echo "Features:"
3791
3791
  echo " - Autonomous mode"
@@ -11641,7 +11641,7 @@ except Exception: pass
11641
11641
  done; } && phase_exit=0 || phase_exit=$?
11642
11642
  ;;
11643
11643
  codex)
11644
- (cd "$codebase_path" && codex exec --full-auto "$phase_prompt" 2>&1) || phase_exit=$?
11644
+ (cd "$codebase_path" && codex exec --sandbox workspace-write "$phase_prompt" 2>&1) || phase_exit=$?
11645
11645
  ;;
11646
11646
  cline)
11647
11647
  (cd "$codebase_path" && cline -y "$phase_prompt" 2>&1) || phase_exit=$?
@@ -11814,7 +11814,7 @@ except Exception: pass
11814
11814
  done; } && doc_exit=0 || doc_exit=$?
11815
11815
  ;;
11816
11816
  codex)
11817
- (cd "$codebase_path" && codex exec --full-auto "$doc_prompt" 2>&1) || doc_exit=$?
11817
+ (cd "$codebase_path" && codex exec --sandbox workspace-write "$doc_prompt" 2>&1) || doc_exit=$?
11818
11818
  ;;
11819
11819
  cline)
11820
11820
  (cd "$codebase_path" && cline -y "$doc_prompt" 2>&1) || doc_exit=$?
@@ -12445,7 +12445,7 @@ except Exception: pass
12445
12445
  done && heal_exit=0 || heal_exit=$?
12446
12446
  ;;
12447
12447
  codex)
12448
- (cd "$codebase_path" && codex exec --full-auto "$heal_prompt" 2>&1) || heal_exit=$?
12448
+ (cd "$codebase_path" && codex exec --sandbox workspace-write "$heal_prompt" 2>&1) || heal_exit=$?
12449
12449
  ;;
12450
12450
  cline)
12451
12451
  (cd "$codebase_path" && cline -y "$heal_prompt" 2>&1) || heal_exit=$?
@@ -22069,7 +22069,7 @@ USER TASK: ${prompt}"
22069
22069
  claude -p "$full_prompt" 2>&1 || agent_exit=$?
22070
22070
  ;;
22071
22071
  codex)
22072
- codex exec --full-auto "$full_prompt" 2>&1 || agent_exit=$?
22072
+ codex exec --sandbox workspace-write "$full_prompt" 2>&1 || agent_exit=$?
22073
22073
  ;;
22074
22074
  cline)
22075
22075
  cline -y "$full_prompt" 2>&1 || agent_exit=$?
@@ -22200,7 +22200,7 @@ $diff"
22200
22200
 
22201
22201
  case "$provider" in
22202
22202
  claude) claude -p "$review_prompt" 2>&1 ;;
22203
- codex) codex exec --full-auto "$review_prompt" 2>&1 ;;
22203
+ codex) codex exec --sandbox workspace-write "$review_prompt" 2>&1 ;;
22204
22204
  cline) cline -y "$review_prompt" 2>&1 ;;
22205
22205
  *) echo -e "${RED}Unknown provider: $provider${NC}"; return 1 ;;
22206
22206
  esac
@@ -23870,7 +23870,7 @@ _docs_invoke_provider() {
23870
23870
  result=$($t_prefix env CAVEMAN_DEFAULT_MODE=off claude -p "$prompt" 2>/dev/null) || exit_code=$?
23871
23871
  ;;
23872
23872
  codex)
23873
- result=$($t_prefix codex exec --full-auto "$prompt" 2>/dev/null) || exit_code=$?
23873
+ result=$($t_prefix codex exec --sandbox workspace-write "$prompt" 2>/dev/null) || exit_code=$?
23874
23874
  ;;
23875
23875
  cline)
23876
23876
  result=$($t_prefix cline -y "$prompt" 2>/dev/null) || exit_code=$?
package/autonomy/run.sh CHANGED
@@ -3264,7 +3264,7 @@ spawn_worktree_session() {
3264
3264
  fi
3265
3265
  ;;
3266
3266
  codex)
3267
- codex exec --full-auto --skip-git-repo-check \
3267
+ codex exec --sandbox workspace-write --skip-git-repo-check \
3268
3268
  "Loki Mode: $task_prompt. Read .loki/CONTINUITY.md for context." \
3269
3269
  >> "$log_file" 2>&1 || _wt_exit=$?
3270
3270
  ;;
@@ -3480,7 +3480,7 @@ Output ONLY the resolved file content with no conflict markers. No explanations.
3480
3480
  resolution=$(CAVEMAN_DEFAULT_MODE=off claude "${_cr_argv[@]}" -p "$conflict_prompt" --output-format text 2>/dev/null)
3481
3481
  ;;
3482
3482
  codex)
3483
- resolution=$(codex exec --full-auto --skip-git-repo-check "$conflict_prompt" 2>/dev/null)
3483
+ resolution=$(codex exec --sandbox workspace-write --skip-git-repo-check "$conflict_prompt" 2>/dev/null)
3484
3484
  ;;
3485
3485
  cline)
3486
3486
  resolution=$(invoke_cline_capture "$conflict_prompt" 2>/dev/null)
@@ -6199,7 +6199,7 @@ check_command_allowed() {
6199
6199
  # run.sh does not directly execute arbitrary shell commands from user or agent
6200
6200
  # input. Command execution is handled by the AI CLI's own permission model:
6201
6201
  # - Claude Code: --dangerously-skip-permissions (with its own allowlist)
6202
- # - Codex CLI: --full-auto or exec --dangerously-bypass-approvals-and-sandbox
6202
+ # - Codex CLI: exec --sandbox workspace-write or exec --dangerously-bypass-approvals-and-sandbox
6203
6203
  #
6204
6204
  # HUMAN_INPUT.md content is injected as a text prompt to the AI agent (not
6205
6205
  # executed as a shell command), and is already guarded by:
@@ -8637,7 +8637,7 @@ _dispatch_reviewer() {
8637
8637
  --output-format text > "$review_output" 2>/dev/null
8638
8638
  ;;
8639
8639
  codex)
8640
- codex exec --full-auto --skip-git-repo-check "$prompt_text" \
8640
+ codex exec --sandbox workspace-write --skip-git-repo-check "$prompt_text" \
8641
8641
  > "$review_output" 2>/dev/null
8642
8642
  ;;
8643
8643
  cline)
@@ -9361,7 +9361,7 @@ ADVERSARIAL_EOF
9361
9361
  ;;
9362
9362
  codex)
9363
9363
  if command -v codex &>/dev/null; then
9364
- codex exec --full-auto --skip-git-repo-check "$adversarial_prompt" \
9364
+ codex exec --sandbox workspace-write --skip-git-repo-check "$adversarial_prompt" \
9365
9365
  > "$result_file" 2>/dev/null || true
9366
9366
  fi
9367
9367
  ;;
@@ -14717,7 +14717,7 @@ if __name__ == "__main__":
14717
14717
  # Uses dynamic tier from RARV phase (tier_param already set above)
14718
14718
  { LOKI_CODEX_REASONING_EFFORT="$tier_param" \
14719
14719
  CODEX_MODEL_REASONING_EFFORT="$tier_param" \
14720
- codex exec --full-auto --skip-git-repo-check \
14720
+ codex exec --sandbox workspace-write --skip-git-repo-check \
14721
14721
  "$prompt" 2>&1 | tee -a "$log_file" "$agent_log" "$iter_output"; \
14722
14722
  } && exit_code=0 || exit_code=$?
14723
14723
  ;;
@@ -7,7 +7,7 @@ Modules:
7
7
  control: Session control API (start/stop/pause/resume)
8
8
  """
9
9
 
10
- __version__ = "7.51.0"
10
+ __version__ = "7.52.0"
11
11
 
12
12
  # Expose the control app for easy import
13
13
  try:
@@ -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.51.0
5
+ **Version:** v7.52.0
6
6
 
7
7
  ---
8
8
 
@@ -396,7 +396,7 @@ provider works inside the container. Provide auth with your Anthropic API key:
396
396
  # Run Loki Mode in Docker (Claude provider, API-key auth)
397
397
  docker run --rm -e ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" \
398
398
  -v $(pwd):/workspace -w /workspace \
399
- asklokesh/loki-mode:7.51.0 start ./my-spec.md
399
+ asklokesh/loki-mode:7.52.0 start ./my-spec.md
400
400
  ```
401
401
 
402
402
  ##### docker compose + .env (no host install)
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- var r6=Object.defineProperty;var t6=($)=>$;function i6($,Q){this[$]=t6.bind(null,Q)}var h=($,Q)=>{for(var Z in Q)r6($,Z,{get:Q[Z],enumerable:!0,configurable:!0,set:i6.bind(Q,Z)})};var L=($,Q)=>()=>($&&(Q=$($=0)),Q);var K$=import.meta.require;var D1={};h(D1,{lokiDir:()=>P,homeLokiDir:()=>n$,findRepoRootForVersion:()=>o$,REPO_ROOT:()=>g});import{resolve as n,dirname as d$}from"path";import{fileURLToPath as e6}from"url";import{existsSync as P$}from"fs";import{homedir as $Q}from"os";function QQ(){let $=S1;for(let Q=0;Q<6;Q++){if(P$(n($,"VERSION"))&&P$(n($,"autonomy/run.sh")))return $;let Z=d$($);if(Z===$)break;$=Z}return n(S1,"..","..","..")}function o$($){let Q=$;for(let Z=0;Z<6;Z++){if(P$(n(Q,"VERSION"))&&P$(n(Q,"autonomy/run.sh")))return Q;let z=d$(Q);if(z===Q)break;Q=z}return n($,"..","..","..")}function P(){return process.env.LOKI_DIR??n(process.cwd(),".loki")}function n$(){return n($Q(),".loki")}var S1,g;var b=L(()=>{S1=d$(e6(import.meta.url));g=QQ()});import{readFileSync as ZQ}from"fs";import{resolve as zQ,dirname as XQ}from"path";import{fileURLToPath as KQ}from"url";function j$(){if($$!==null)return $$;let $="7.51.0";if(typeof $==="string"&&$.length>0)return $$=$,$$;try{let Q=XQ(KQ(import.meta.url)),Z=o$(Q);$$=ZQ(zQ(Z,"VERSION"),"utf-8").trim()}catch{$$="unknown"}return $$}var $$=null;var a$=L(()=>{b()});var b1={};h(b1,{runOrThrow:()=>qQ,run:()=>k,commandVersion:()=>WQ,commandExists:()=>f,ShellError:()=>s$});async function k($,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[q,K,W]=await Promise.all([new Response(Z.stdout).text(),new Response(Z.stderr).text(),Z.exited]);return{stdout:q,stderr:K,exitCode:W}}finally{if(z)clearTimeout(z);if(X)clearTimeout(X)}}async function qQ($,Q={}){let Z=await k($,Q);if(Z.exitCode!==0)throw new s$(`command failed (${Z.exitCode}): ${$.join(" ")}`,Z.exitCode,Z.stdout,Z.stderr);return Z}async function f($){let Q=VQ($),Z=await k(["sh","-c",`command -v ${Q}`],{timeoutMs:5000});if(Z.exitCode===0)return Z.stdout.trim()||null;return null}function VQ($){if(!/^[A-Za-z0-9._/-]+$/.test($))throw Error(`refused to shell-escape suspect token: ${$}`);return $}async function WQ($,Q="--version"){if(!await f($))return null;let z=await k([$,Q],{timeoutMs:5000});if(z.exitCode!==0)return null;return((z.stdout||z.stderr).split(/\r?\n/)[0]?.trim()??"")||null}var s$;var d=L(()=>{s$=class s$ 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 JQ?"":$}var JQ,T,S,_,wZ,I,R,y,V;var c=L(()=>{JQ=(process.env.NO_COLOR??"").length>0;T=a("\x1B[0;31m"),S=a("\x1B[0;32m"),_=a("\x1B[1;33m"),wZ=a("\x1B[0;34m"),I=a("\x1B[0;36m"),R=a("\x1B[1m"),y=a("\x1B[2m"),V=a("\x1B[0m")});import{existsSync as wQ}from"fs";async function Q$(){if(G$!==void 0)return G$;let $="/opt/homebrew/bin/python3.12";if(wQ($))return G$=$,$;let Q=await f("python3.12");if(Q)return G$=Q,Q;let Z=await f("python3");return G$=Z,Z}async function Z$($,Q={}){let Z=await Q$();if(!Z)return{stdout:"",stderr:"python3 not found",exitCode:127};return k([Z,"-c",$],Q)}var G$;var q$=L(()=>{d()});var e1={};h(e1,{runStatus:()=>uQ});import{existsSync as v,readFileSync as W$,readdirSync as d1,statSync as o1}from"fs";import{resolve as C,basename as DQ}from"path";import{homedir as CQ}from"os";function n1($){let Q=Math.trunc($);if(Q>=1e6)return`${(Math.trunc(Q/1e6*10)/10).toFixed(1)}M`;if(Q>=1000)return`${(Math.trunc(Q/1000*10)/10).toFixed(1)}K`;return String(Q)}function a1($,Q,Z){if(Q===0)return null;let z=Math.trunc($*100/Q),X=Math.trunc($*k$/Q);if(X>k$)X=k$;let q=k$-X,K=S;if(z>=80)K=T;else if(z>=50)K=_;let W="=".repeat(Math.max(0,X))+" ".repeat(Math.max(0,q)),J=n1($),U=n1(Q);return` ${R}${Z}${V} ${K}[${W}]${V} ${z}% (${J} / ${U})`}async function hQ(){if(await f("jq"))return!0;return process.stdout.write(`${T}Error: jq is required but not installed.${V}
2
+ var r6=Object.defineProperty;var t6=($)=>$;function i6($,Q){this[$]=t6.bind(null,Q)}var h=($,Q)=>{for(var Z in Q)r6($,Z,{get:Q[Z],enumerable:!0,configurable:!0,set:i6.bind(Q,Z)})};var L=($,Q)=>()=>($&&(Q=$($=0)),Q);var K$=import.meta.require;var D1={};h(D1,{lokiDir:()=>P,homeLokiDir:()=>n$,findRepoRootForVersion:()=>o$,REPO_ROOT:()=>g});import{resolve as n,dirname as d$}from"path";import{fileURLToPath as e6}from"url";import{existsSync as P$}from"fs";import{homedir as $Q}from"os";function QQ(){let $=S1;for(let Q=0;Q<6;Q++){if(P$(n($,"VERSION"))&&P$(n($,"autonomy/run.sh")))return $;let Z=d$($);if(Z===$)break;$=Z}return n(S1,"..","..","..")}function o$($){let Q=$;for(let Z=0;Z<6;Z++){if(P$(n(Q,"VERSION"))&&P$(n(Q,"autonomy/run.sh")))return Q;let z=d$(Q);if(z===Q)break;Q=z}return n($,"..","..","..")}function P(){return process.env.LOKI_DIR??n(process.cwd(),".loki")}function n$(){return n($Q(),".loki")}var S1,g;var b=L(()=>{S1=d$(e6(import.meta.url));g=QQ()});import{readFileSync as ZQ}from"fs";import{resolve as zQ,dirname as XQ}from"path";import{fileURLToPath as KQ}from"url";function j$(){if($$!==null)return $$;let $="7.52.0";if(typeof $==="string"&&$.length>0)return $$=$,$$;try{let Q=XQ(KQ(import.meta.url)),Z=o$(Q);$$=ZQ(zQ(Z,"VERSION"),"utf-8").trim()}catch{$$="unknown"}return $$}var $$=null;var a$=L(()=>{b()});var b1={};h(b1,{runOrThrow:()=>qQ,run:()=>k,commandVersion:()=>WQ,commandExists:()=>f,ShellError:()=>s$});async function k($,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[q,K,W]=await Promise.all([new Response(Z.stdout).text(),new Response(Z.stderr).text(),Z.exited]);return{stdout:q,stderr:K,exitCode:W}}finally{if(z)clearTimeout(z);if(X)clearTimeout(X)}}async function qQ($,Q={}){let Z=await k($,Q);if(Z.exitCode!==0)throw new s$(`command failed (${Z.exitCode}): ${$.join(" ")}`,Z.exitCode,Z.stdout,Z.stderr);return Z}async function f($){let Q=VQ($),Z=await k(["sh","-c",`command -v ${Q}`],{timeoutMs:5000});if(Z.exitCode===0)return Z.stdout.trim()||null;return null}function VQ($){if(!/^[A-Za-z0-9._/-]+$/.test($))throw Error(`refused to shell-escape suspect token: ${$}`);return $}async function WQ($,Q="--version"){if(!await f($))return null;let z=await k([$,Q],{timeoutMs:5000});if(z.exitCode!==0)return null;return((z.stdout||z.stderr).split(/\r?\n/)[0]?.trim()??"")||null}var s$;var d=L(()=>{s$=class s$ 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 JQ?"":$}var JQ,T,S,_,wZ,I,R,y,V;var c=L(()=>{JQ=(process.env.NO_COLOR??"").length>0;T=a("\x1B[0;31m"),S=a("\x1B[0;32m"),_=a("\x1B[1;33m"),wZ=a("\x1B[0;34m"),I=a("\x1B[0;36m"),R=a("\x1B[1m"),y=a("\x1B[2m"),V=a("\x1B[0m")});import{existsSync as wQ}from"fs";async function Q$(){if(G$!==void 0)return G$;let $="/opt/homebrew/bin/python3.12";if(wQ($))return G$=$,$;let Q=await f("python3.12");if(Q)return G$=Q,Q;let Z=await f("python3");return G$=Z,Z}async function Z$($,Q={}){let Z=await Q$();if(!Z)return{stdout:"",stderr:"python3 not found",exitCode:127};return k([Z,"-c",$],Q)}var G$;var q$=L(()=>{d()});var e1={};h(e1,{runStatus:()=>uQ});import{existsSync as v,readFileSync as W$,readdirSync as d1,statSync as o1}from"fs";import{resolve as C,basename as DQ}from"path";import{homedir as CQ}from"os";function n1($){let Q=Math.trunc($);if(Q>=1e6)return`${(Math.trunc(Q/1e6*10)/10).toFixed(1)}M`;if(Q>=1000)return`${(Math.trunc(Q/1000*10)/10).toFixed(1)}K`;return String(Q)}function a1($,Q,Z){if(Q===0)return null;let z=Math.trunc($*100/Q),X=Math.trunc($*k$/Q);if(X>k$)X=k$;let q=k$-X,K=S;if(z>=80)K=T;else if(z>=50)K=_;let W="=".repeat(Math.max(0,X))+" ".repeat(Math.max(0,q)),J=n1($),U=n1(Q);return` ${R}${Z}${V} ${K}[${W}]${V} ${z}% (${J} / ${U})`}async function hQ(){if(await f("jq"))return!0;return process.stdout.write(`${T}Error: jq is required but not installed.${V}
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)
@@ -790,4 +790,4 @@ Set LOKI_LEGACY_BASH=1 to force the bash CLI for every command.
790
790
  `),2}default:return process.stderr.write(`Unknown command: ${Q}
791
791
  `),process.stderr.write(s6),2}}l1();process.on("SIGINT",()=>process.exit(130));process.on("SIGTERM",()=>process.exit(143));var KZ=await XZ(Bun.argv.slice(2));process.exit(KZ);
792
792
 
793
- //# debugId=8015709BAB9E625464756E2164756E21
793
+ //# debugId=D3609A2FE6BB9BAE64756E2164756E21
@@ -482,8 +482,10 @@ class DebateRunner:
482
482
  if provider == "claude":
483
483
  return ["claude", "--dangerously-skip-permissions", "-p", prompt]
484
484
  if provider == "codex":
485
- # Codex uses `exec --full-auto` with the prompt as positional.
486
- return ["codex", "exec", "--full-auto", prompt]
485
+ # Codex uses `exec --sandbox workspace-write` with the prompt as
486
+ # positional (codex 0.132.0 deprecated --full-auto; workspace-write
487
+ # is the documented replacement, exec is non-interactive by default).
488
+ return ["codex", "exec", "--sandbox", "workspace-write", prompt]
487
489
  if provider == "gemini":
488
490
  return ["gemini", "--approval-mode=yolo", prompt]
489
491
  if provider == "cline":
@@ -180,7 +180,7 @@ class ComponentGenerator:
180
180
  if provider == "claude":
181
181
  cmd = base_cmd + [binary, "-p", prompt]
182
182
  elif provider == "codex":
183
- cmd = base_cmd + [binary, "exec", "--full-auto", prompt]
183
+ cmd = base_cmd + [binary, "exec", "--sandbox", "workspace-write", prompt]
184
184
  elif provider == "gemini":
185
185
  cmd = base_cmd + [binary, "--approval-mode=yolo", prompt]
186
186
  elif provider == "cline":
package/mcp/__init__.py CHANGED
@@ -57,4 +57,4 @@ try:
57
57
  except ImportError:
58
58
  __all__ = ['mcp']
59
59
 
60
- __version__ = '7.51.0'
60
+ __version__ = '7.52.0'
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.51.0",
4
+ "version": "7.52.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 8 quality gates. Provider-agnostic (Claude Code, OpenAI Codex, Cline, Aider).",
6
6
  "keywords": [
7
7
  "agent",
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
3
3
  "name": "loki-mode",
4
4
  "displayName": "Loki Mode",
5
- "version": "7.51.0",
5
+ "version": "7.52.0",
6
6
  "description": "Autonomous spec-to-product build system with a built-in trust layer (RARV-C closure loop, 8 quality gates, completion council). Ships Loki's spec-hardening, drift-detection, and deterministic PR verification commands plus the Loki MCP server.",
7
7
  "author": {
8
8
  "name": "Autonomi",
@@ -29,10 +29,14 @@ PROVIDER_CLI="codex"
29
29
 
30
30
  # CLI Invocation
31
31
  # Note: codex uses positional prompt after "exec" subcommand
32
- # VERIFIED: exec --full-auto confirmed in codex exec --help (v0.98.0)
33
- # --full-auto: sets --ask-for-approval on-request + --sandbox workspace-write (v0.98.0)
32
+ # VERIFIED: codex 0.132.0 deprecates --full-auto (prints a deprecation warning
33
+ # and the flag is gone from `codex exec --help`). Use --sandbox workspace-write,
34
+ # which is the documented replacement and the sandbox --full-auto expanded to.
35
+ # `codex exec` is the non-interactive subcommand: it runs at approval "never"
36
+ # with no --ask-for-approval flag, so --sandbox workspace-write alone keeps the
37
+ # loop fully autonomous (verified against codex 0.132.0: no approval prompt).
34
38
  # Alternative: "exec --dangerously-bypass-approvals-and-sandbox" (legacy, no sandbox)
35
- PROVIDER_AUTONOMOUS_FLAG="exec --full-auto --skip-git-repo-check"
39
+ PROVIDER_AUTONOMOUS_FLAG="exec --sandbox workspace-write --skip-git-repo-check"
36
40
  PROVIDER_PROMPT_FLAG=""
37
41
  PROVIDER_PROMPT_POSITIONAL=true
38
42
 
@@ -124,7 +128,7 @@ provider_version() {
124
128
  provider_invoke() {
125
129
  local prompt="$1"
126
130
  shift
127
- codex exec --full-auto --skip-git-repo-check \
131
+ codex exec --sandbox workspace-write --skip-git-repo-check \
128
132
  --model "$PROVIDER_MODEL_DEVELOPMENT" \
129
133
  "$prompt" "$@"
130
134
  }
@@ -182,11 +186,13 @@ resolve_model_for_tier() {
182
186
 
183
187
  # Tier-aware invocation.
184
188
  #
185
- # v7.4.18: aligned with codex CLI v0.125.0 (latest as of 2026-04-26).
186
- # Replaced --full-auto preset with the explicit flags it expands to:
187
- # --ask-for-approval never
188
- # --sandbox danger-full-access
189
- # Forward-compatible if the preset is renamed; readable in process listings.
189
+ # Aligned with codex CLI 0.132.0 (verified: --full-auto deprecated/removed
190
+ # from `codex exec --help`). `codex exec` is the non-interactive subcommand and
191
+ # runs at approval "never" with no --ask-for-approval flag, so --sandbox
192
+ # workspace-write alone keeps the loop autonomous (verified: no approval prompt
193
+ # on codex 0.132.0). workspace-write is the documented --full-auto replacement
194
+ # and the safer default (scoped disk writes) over danger-full-access; readable
195
+ # in process listings.
190
196
  #
191
197
  # Optional env knobs:
192
198
  # LOKI_CODEX_WEB_SEARCH=true enable codex --search (live web)
@@ -227,8 +233,7 @@ provider_invoke_with_tier() {
227
233
  LOKI_CODEX_REASONING_EFFORT="$effort" \
228
234
  CODEX_MODEL_REASONING_EFFORT="$effort" \
229
235
  codex exec \
230
- --ask-for-approval never \
231
- --sandbox danger-full-access \
236
+ --sandbox workspace-write \
232
237
  --skip-git-repo-check \
233
238
  --model "$model" \
234
239
  "${extra_flags[@]}" \
@@ -286,7 +286,7 @@ All CLI flags have been verified against actual CLI help output:
286
286
  | Provider | Flag | Verified Version | Notes |
287
287
  |----------|------|------------------|-------|
288
288
  | Claude | `--dangerously-skip-permissions` | v2.1.34 | Autonomous mode |
289
- | Codex | `--full-auto` | v0.98.0 | Recommended; legacy: `exec --dangerously-bypass-approvals-and-sandbox` |
289
+ | Codex | `--sandbox workspace-write` | v0.132.0 | Recommended (--full-auto deprecated 0.125+); legacy: `exec --dangerously-bypass-approvals-and-sandbox` |
290
290
  | Cline | `--auto-approve` | latest | Autonomous mode |
291
291
  | Aider | `--yes-always` | latest | Autonomous mode |
292
292
 
@@ -231,13 +231,16 @@ Claude models support an `effort` parameter that controls reasoning depth withou
231
231
 
232
232
  **Note:** The effort parameter and thinking prefixes serve different purposes. Effort controls the model's internal reasoning budget; thinking prefixes guide the structure of the response.
233
233
 
234
- ### Codex --full-auto Flag
234
+ ### Codex --sandbox workspace-write Flag
235
235
 
236
- Codex CLI v0.98.0 supports `--full-auto` as the recommended autonomous mode flag, replacing the verbose `exec --dangerously-bypass-approvals-and-sandbox` invocation:
236
+ Codex CLI deprecated `--full-auto` in v0.125+ (removed from `codex exec --help`,
237
+ emits a deprecation warning if used). The documented replacement is
238
+ `--sandbox workspace-write`. The `exec` subcommand is non-interactive by default
239
+ (approval: never), so the sandbox flag alone keeps the loop autonomous:
237
240
 
238
241
  ```bash
239
- # Recommended (v0.98.0+)
240
- codex --full-auto "$prompt"
242
+ # Recommended (codex 0.125+)
243
+ codex exec --sandbox workspace-write "$prompt"
241
244
 
242
245
  # Legacy (still supported)
243
246
  codex exec --dangerously-bypass-approvals-and-sandbox "$prompt"
@@ -6,7 +6,7 @@ Loki Mode supports four AI providers for autonomous execution.
6
6
 
7
7
  > **CLI Flags Verified:** The autonomous mode flags have been verified against actual CLI help output:
8
8
  > - Claude: `--dangerously-skip-permissions` (verified)
9
- > - Codex: `exec --full-auto --skip-git-repo-check` (the harness invocation; --skip-git-repo-check required on fresh non-git dirs) or `exec --dangerously-bypass-approvals-and-sandbox` (legacy)
9
+ > - Codex: `exec --sandbox workspace-write --skip-git-repo-check` (the harness invocation; --skip-git-repo-check required on fresh non-git dirs; --full-auto deprecated in codex 0.125+, workspace-write is the documented replacement) or `exec --dangerously-bypass-approvals-and-sandbox` (legacy)
10
10
 
11
11
  | Feature | Claude Code | OpenAI Codex | Cline CLI | Aider |
12
12
  |---------|-------------|--------------|-----------|-------|
@@ -70,7 +70,7 @@ Task(model="haiku", ...) # Fast tier (parallelize)
70
70
  **Invocation:**
71
71
  ```bash
72
72
  # Recommended (v0.98.0+)
73
- codex exec --full-auto --skip-git-repo-check "$prompt"
73
+ codex exec --sandbox workspace-write --skip-git-repo-check "$prompt"
74
74
 
75
75
  # Legacy (still supported)
76
76
  codex exec --dangerously-bypass-approvals-and-sandbox "$prompt"