mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-09 18:28:15 +01:00
feat(codex): run gstack-codex-probe as a command, one subcommand per probe
Generated skills now execute bin/gstack-codex-probe (select-model, check-auth, show-sandbox, check-sandbox, probe-model, check-version, show-first-use-notice, run-with-timeout, log-event, log-hang, help) and capture its KEY: value lines, so no helper state crosses into the calling shell and the preflight works from bash, zsh or sh. select-model keeps --model > GSTACK_CODEX_MODEL > config.toml precedence; run-with-timeout supervises with the existing gtimeout/timeout/ watchdog chain and returns 124 on a deadline; an unknown subcommand exits 64. Sourcing keeps working for skills rendered before the upgrade and prints one deprecation line naming /gstack-upgrade; it and the zsh self-locate block are removed in a release on or after 2026-10-21 (DX-18). Parity caps raised with measured notes for the longer capture lines. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
7fab2a7139
commit
64e8f90f15
47 files changed
+937
-399
No files matched your search
@@ -48,11 +48,13 @@ fi
|
||||
# capture stderr to $TMPERR for auth error detection (was: 2>/dev/null).
|
||||
[ -n "${TMPERR:-}" ] || TMPERR=$(mktemp "$TMP_ROOT/codex-err-XXXXXX") || { echo "ERROR: mktemp failed in TMP_ROOT=$TMP_ROOT; not running codex without its temp file" >&2; exit 1; }
|
||||
TMPRESP=$(mktemp "$TMP_ROOT/codex-resp-XXXXXX") || { echo "ERROR: mktemp failed in TMP_ROOT=$TMP_ROOT; not running codex without its temp file" >&2; exit 1; }
|
||||
source ~/.claude/skills/gstack/bin/gstack-codex-probe || exit 1
|
||||
_gstack_codex_select_model exec || exit 1
|
||||
_CODEX_PROBE=~/.claude/skills/gstack/bin/gstack-codex-probe
|
||||
_CODEX_OUT=$("$_CODEX_PROBE" select-model exec) || exit 1
|
||||
_CODEX_SEL=$(echo "$_CODEX_OUT" | sed -n 's/^CODEX_SEL: //p')
|
||||
_CODEX_SANDBOX_MODE=$(echo "$_CODEX_OUT" | sed -n 's/^CODEX_SANDBOX: //p')
|
||||
PROMPT_FILE="$(git rev-parse --show-toplevel 2>/dev/null || pwd)/.gstack/tmp/<prompt-file-name>"
|
||||
[ -s "$PROMPT_FILE" ] || { echo "Not run: $PROMPT_FILE is missing or empty, so the prompt was never written. Write it, then run by hand: codex exec - -C $_REPO_ROOT < $PROMPT_FILE" >&2; exit 1; }
|
||||
_gstack_codex_timeout_wrapper 540 codex exec - -C "$_REPO_ROOT" -s "${_GSTACK_CODEX_SANDBOX:?}" -c "model=\"${_GSTACK_CODEX_SEL:?}\"" -c skills.include_instructions=false -c 'model_reasoning_effort="high"' -c 'web_search="cached"' --json -o "$TMPRESP" < "$PROMPT_FILE" 2>"$TMPERR" | tee "$TMPRESP.events" | PYTHONUNBUFFERED=1 "$PYTHON_CMD" -u -c "
|
||||
"$_CODEX_PROBE" run-with-timeout 540 codex exec - -C "$_REPO_ROOT" -s "${_CODEX_SANDBOX_MODE:?}" -c "model=\"${_CODEX_SEL:?}\"" -c skills.include_instructions=false -c 'model_reasoning_effort="high"' -c 'web_search="cached"' --json -o "$TMPRESP" < "$PROMPT_FILE" 2>"$TMPERR" | tee "$TMPRESP.events" | PYTHONUNBUFFERED=1 "$PYTHON_CMD" -u -c "
|
||||
import sys, json
|
||||
turn_completed_count = 0
|
||||
turn_failed = False
|
||||
@@ -94,20 +96,20 @@ elif turn_completed_count == 0:
|
||||
_CODEX_EXIT=${PIPESTATUS[0]:-${pipestatus[1]}} # bash sets PIPESTATUS; zsh (lowercase, 1-indexed) falls through
|
||||
# Fix 1: hang detection — log + surface actionable message
|
||||
if [ "$_CODEX_EXIT" = "124" ]; then
|
||||
_gstack_codex_log_event "codex_timeout" "540"
|
||||
_gstack_codex_log_hang "challenge" "$(wc -c < "$TMPERR" 2>/dev/null || echo 0)"
|
||||
"$_CODEX_PROBE" log-event codex_timeout "540"
|
||||
"$_CODEX_PROBE" log-hang "challenge" "$(wc -c < "$TMPERR" 2>/dev/null || echo 0)"
|
||||
echo "Codex stalled past 9 minutes. Common causes: model API stall, long prompt, network issue. Try re-running. If persistent, split the prompt or check ~/.codex/logs/."
|
||||
elif [ "$_CODEX_EXIT" != "0" ]; then
|
||||
# Surface non-zero exits so the calling agent doesn't read "no output" as
|
||||
# a silent model/API stall.
|
||||
echo "[codex exit $_CODEX_EXIT] $(head -1 "$TMPERR" 2>/dev/null || echo "no stderr captured")"
|
||||
head -20 "$TMPERR" 2>/dev/null | sed 's/^/ /' || true
|
||||
_gstack_codex_log_event "codex_nonzero_exit" "challenge:$_CODEX_EXIT"
|
||||
"$_CODEX_PROBE" log-event codex_nonzero_exit "challenge:$_CODEX_EXIT"
|
||||
fi
|
||||
# Fix 2: surface auth errors from captured stderr instead of dropping them
|
||||
if grep -qiE "auth|login|unauthorized" "$TMPERR" 2>/dev/null; then
|
||||
echo "[codex auth error] $(head -1 "$TMPERR")"
|
||||
_gstack_codex_log_event "codex_auth_failed"
|
||||
"$_CODEX_PROBE" log-event codex_auth_failed
|
||||
fi
|
||||
bun ~/.claude/skills/gstack/lib/outside-review-result.ts --label 'Codex challenge' --exit "$_CODEX_EXIT" --stderr "$TMPERR" --events "$TMPRESP.events" execution "$TMPRESP"
|
||||
rm -f "$TMPRESP" "$TMPRESP.events" "$PROMPT_FILE"
|
||||
|
||||
@@ -39,11 +39,10 @@ fi
|
||||
# capture stderr to $TMPERR for auth error detection (was: 2>/dev/null).
|
||||
[ -n "${TMPERR:-}" ] || TMPERR=$(mktemp "$TMP_ROOT/codex-err-XXXXXX") || { echo "ERROR: mktemp failed in TMP_ROOT=$TMP_ROOT; not running codex without its temp file" >&2; exit 1; }
|
||||
TMPRESP=$(mktemp "$TMP_ROOT/codex-resp-XXXXXX") || { echo "ERROR: mktemp failed in TMP_ROOT=$TMP_ROOT; not running codex without its temp file" >&2; exit 1; }
|
||||
source ~/.claude/skills/gstack/bin/gstack-codex-probe || exit 1
|
||||
_gstack_codex_select_model exec || exit 1
|
||||
{{CODEX_SELECT:exec}}
|
||||
PROMPT_FILE="$(git rev-parse --show-toplevel 2>/dev/null || pwd)/.gstack/tmp/<prompt-file-name>"
|
||||
[ -s "$PROMPT_FILE" ] || { echo "Not run: $PROMPT_FILE is missing or empty, so the prompt was never written. Write it, then run by hand: codex exec - -C $_REPO_ROOT < $PROMPT_FILE" >&2; exit 1; }
|
||||
_gstack_codex_timeout_wrapper 540 codex exec - -C "$_REPO_ROOT" -s "${_GSTACK_CODEX_SANDBOX:?}" {{CODEX_MODEL_CONFIG_FLAG}} -c 'model_reasoning_effort="high"' {{CODEX_WEB_SEARCH_FLAG}} --json -o "$TMPRESP" < "$PROMPT_FILE" 2>"$TMPERR" | tee "$TMPRESP.events" | PYTHONUNBUFFERED=1 "$PYTHON_CMD" -u -c "
|
||||
"$_CODEX_PROBE" run-with-timeout 540 codex exec - -C "$_REPO_ROOT" -s "${_CODEX_SANDBOX_MODE:?}" {{CODEX_MODEL_CONFIG_FLAG}} -c 'model_reasoning_effort="high"' {{CODEX_WEB_SEARCH_FLAG}} --json -o "$TMPRESP" < "$PROMPT_FILE" 2>"$TMPERR" | tee "$TMPRESP.events" | PYTHONUNBUFFERED=1 "$PYTHON_CMD" -u -c "
|
||||
import sys, json
|
||||
turn_completed_count = 0
|
||||
turn_failed = False
|
||||
@@ -85,20 +84,20 @@ elif turn_completed_count == 0:
|
||||
_CODEX_EXIT=${PIPESTATUS[0]:-${pipestatus[1]}} # bash sets PIPESTATUS; zsh (lowercase, 1-indexed) falls through
|
||||
# Fix 1: hang detection — log + surface actionable message
|
||||
if [ "$_CODEX_EXIT" = "124" ]; then
|
||||
_gstack_codex_log_event "codex_timeout" "540"
|
||||
_gstack_codex_log_hang "challenge" "$(wc -c < "$TMPERR" 2>/dev/null || echo 0)"
|
||||
"$_CODEX_PROBE" log-event codex_timeout "540"
|
||||
"$_CODEX_PROBE" log-hang "challenge" "$(wc -c < "$TMPERR" 2>/dev/null || echo 0)"
|
||||
echo "Codex stalled past 9 minutes. Common causes: model API stall, long prompt, network issue. Try re-running. If persistent, split the prompt or check ~/.codex/logs/."
|
||||
elif [ "$_CODEX_EXIT" != "0" ]; then
|
||||
# Surface non-zero exits so the calling agent doesn't read "no output" as
|
||||
# a silent model/API stall.
|
||||
echo "[codex exit $_CODEX_EXIT] $(head -1 "$TMPERR" 2>/dev/null || echo "no stderr captured")"
|
||||
head -20 "$TMPERR" 2>/dev/null | sed 's/^/ /' || true
|
||||
_gstack_codex_log_event "codex_nonzero_exit" "challenge:$_CODEX_EXIT"
|
||||
"$_CODEX_PROBE" log-event codex_nonzero_exit "challenge:$_CODEX_EXIT"
|
||||
fi
|
||||
# Fix 2: surface auth errors from captured stderr instead of dropping them
|
||||
if grep -qiE "auth|login|unauthorized" "$TMPERR" 2>/dev/null; then
|
||||
echo "[codex auth error] $(head -1 "$TMPERR")"
|
||||
_gstack_codex_log_event "codex_auth_failed"
|
||||
"$_CODEX_PROBE" log-event codex_auth_failed
|
||||
fi
|
||||
bun ~/.claude/skills/gstack/lib/outside-review-result.ts --label 'Codex challenge' --exit "$_CODEX_EXIT" --stderr "$TMPERR" --events "$TMPRESP.events" execution "$TMPRESP"
|
||||
rm -f "$TMPRESP" "$TMPRESP.events" "$PROMPT_FILE"
|
||||
|
||||
@@ -101,8 +101,10 @@ fi
|
||||
cd "$_REPO_ROOT" || exit 1
|
||||
PROMPT_FILE="$_REPO_ROOT/.gstack/tmp/<prompt-file-name>"
|
||||
[ -s "$PROMPT_FILE" ] || { echo "Not run: $PROMPT_FILE is missing or empty, so the prompt was never written. Write it, then run by hand: codex exec - -C $_REPO_ROOT < $PROMPT_FILE" >&2; exit 1; }
|
||||
source ~/.claude/skills/gstack/bin/gstack-codex-probe || exit 1
|
||||
_gstack_codex_select_model exec || exit 1
|
||||
_CODEX_PROBE=~/.claude/skills/gstack/bin/gstack-codex-probe
|
||||
_CODEX_OUT=$("$_CODEX_PROBE" select-model exec) || exit 1
|
||||
_CODEX_SEL=$(echo "$_CODEX_OUT" | sed -n 's/^CODEX_SEL: //p')
|
||||
_CODEX_SANDBOX_MODE=$(echo "$_CODEX_OUT" | sed -n 's/^CODEX_SANDBOX: //p')
|
||||
_SID=""
|
||||
if [ "$_CODEX_MODE" = "resume" ]; then
|
||||
_SID=$(cat .context/codex-session-id 2>/dev/null)
|
||||
@@ -111,9 +113,9 @@ fi
|
||||
_LABEL=consult${_SID:+-resume}
|
||||
# Fix 1: wrap with timeout (gtimeout/timeout fallback chain via probe helper)
|
||||
if [ -n "$_SID" ]; then
|
||||
_gstack_codex_timeout_wrapper 540 codex exec resume "$_SID" - -c "sandbox_mode=\"${_GSTACK_CODEX_SANDBOX:?}\"" -c "model=\"${_GSTACK_CODEX_SEL:?}\"" -c skills.include_instructions=false -c 'model_reasoning_effort="medium"' -c 'web_search="cached"' --json -o "$TMPRESP" < "$PROMPT_FILE" 2>"$TMPERR"
|
||||
"$_CODEX_PROBE" run-with-timeout 540 codex exec resume "$_SID" - -c "sandbox_mode=\"${_CODEX_SANDBOX_MODE:?}\"" -c "model=\"${_CODEX_SEL:?}\"" -c skills.include_instructions=false -c 'model_reasoning_effort="medium"' -c 'web_search="cached"' --json -o "$TMPRESP" < "$PROMPT_FILE" 2>"$TMPERR"
|
||||
else
|
||||
_gstack_codex_timeout_wrapper 540 codex exec - -C "$_REPO_ROOT" -s "${_GSTACK_CODEX_SANDBOX:?}" -c "model=\"${_GSTACK_CODEX_SEL:?}\"" -c skills.include_instructions=false -c 'model_reasoning_effort="medium"' -c 'web_search="cached"' --json -o "$TMPRESP" < "$PROMPT_FILE" 2>"$TMPERR"
|
||||
"$_CODEX_PROBE" run-with-timeout 540 codex exec - -C "$_REPO_ROOT" -s "${_CODEX_SANDBOX_MODE:?}" -c "model=\"${_CODEX_SEL:?}\"" -c skills.include_instructions=false -c 'model_reasoning_effort="medium"' -c 'web_search="cached"' --json -o "$TMPRESP" < "$PROMPT_FILE" 2>"$TMPERR"
|
||||
fi | tee "$TMPRESP.events" | PYTHONUNBUFFERED=1 "$PYTHON_CMD" -u -c "
|
||||
import sys, json
|
||||
turn_completed_count = 0
|
||||
@@ -159,15 +161,15 @@ elif turn_completed_count == 0:
|
||||
# Fix 1: hang detection
|
||||
_CODEX_EXIT=${PIPESTATUS[0]:-${pipestatus[1]}} # bash sets PIPESTATUS; zsh (lowercase, 1-indexed) falls through
|
||||
if [ "$_CODEX_EXIT" = "124" ]; then
|
||||
_gstack_codex_log_event "codex_timeout" "540"
|
||||
_gstack_codex_log_hang "$_LABEL" "$(wc -c < "$TMPERR" 2>/dev/null || echo 0)"
|
||||
"$_CODEX_PROBE" log-event codex_timeout "540"
|
||||
"$_CODEX_PROBE" log-hang "$_LABEL" "$(wc -c < "$TMPERR" 2>/dev/null || echo 0)"
|
||||
echo "Codex stalled past 9 minutes. Common causes: model API stall, long prompt, network issue. Try re-running. If persistent, split the prompt or check ~/.codex/logs/."
|
||||
elif [ "$_CODEX_EXIT" != "0" ]; then
|
||||
# Surface non-zero exits so the calling agent doesn't read "no output" as
|
||||
# a silent model/API stall.
|
||||
echo "[codex exit $_CODEX_EXIT] $(head -1 "$TMPERR" 2>/dev/null || echo "no stderr captured")"
|
||||
head -20 "$TMPERR" 2>/dev/null | sed 's/^/ /' || true
|
||||
_gstack_codex_log_event "codex_nonzero_exit" "$_LABEL:$_CODEX_EXIT"
|
||||
"$_CODEX_PROBE" log-event codex_nonzero_exit "$_LABEL:$_CODEX_EXIT"
|
||||
fi
|
||||
bun ~/.claude/skills/gstack/lib/outside-review-result.ts --label 'Codex consult' --exit "$_CODEX_EXIT" --stderr "$TMPERR" --events "$TMPRESP.events" execution "$TMPRESP"
|
||||
rm -f "$PROMPT_FILE"
|
||||
|
||||
@@ -92,8 +92,7 @@ fi
|
||||
cd "$_REPO_ROOT" || exit 1
|
||||
PROMPT_FILE="$_REPO_ROOT/.gstack/tmp/<prompt-file-name>"
|
||||
[ -s "$PROMPT_FILE" ] || { echo "Not run: $PROMPT_FILE is missing or empty, so the prompt was never written. Write it, then run by hand: codex exec - -C $_REPO_ROOT < $PROMPT_FILE" >&2; exit 1; }
|
||||
source ~/.claude/skills/gstack/bin/gstack-codex-probe || exit 1
|
||||
_gstack_codex_select_model exec || exit 1
|
||||
{{CODEX_SELECT:exec}}
|
||||
_SID=""
|
||||
if [ "$_CODEX_MODE" = "resume" ]; then
|
||||
_SID=$(cat .context/codex-session-id 2>/dev/null)
|
||||
@@ -102,9 +101,9 @@ fi
|
||||
_LABEL=consult${_SID:+-resume}
|
||||
# Fix 1: wrap with timeout (gtimeout/timeout fallback chain via probe helper)
|
||||
if [ -n "$_SID" ]; then
|
||||
_gstack_codex_timeout_wrapper 540 codex exec resume "$_SID" - -c "sandbox_mode=\"${_GSTACK_CODEX_SANDBOX:?}\"" {{CODEX_MODEL_CONFIG_FLAG}} -c 'model_reasoning_effort="medium"' {{CODEX_WEB_SEARCH_FLAG}} --json -o "$TMPRESP" < "$PROMPT_FILE" 2>"$TMPERR"
|
||||
"$_CODEX_PROBE" run-with-timeout 540 codex exec resume "$_SID" - -c "sandbox_mode=\"${_CODEX_SANDBOX_MODE:?}\"" {{CODEX_MODEL_CONFIG_FLAG}} -c 'model_reasoning_effort="medium"' {{CODEX_WEB_SEARCH_FLAG}} --json -o "$TMPRESP" < "$PROMPT_FILE" 2>"$TMPERR"
|
||||
else
|
||||
_gstack_codex_timeout_wrapper 540 codex exec - -C "$_REPO_ROOT" -s "${_GSTACK_CODEX_SANDBOX:?}" {{CODEX_MODEL_CONFIG_FLAG}} -c 'model_reasoning_effort="medium"' {{CODEX_WEB_SEARCH_FLAG}} --json -o "$TMPRESP" < "$PROMPT_FILE" 2>"$TMPERR"
|
||||
"$_CODEX_PROBE" run-with-timeout 540 codex exec - -C "$_REPO_ROOT" -s "${_CODEX_SANDBOX_MODE:?}" {{CODEX_MODEL_CONFIG_FLAG}} -c 'model_reasoning_effort="medium"' {{CODEX_WEB_SEARCH_FLAG}} --json -o "$TMPRESP" < "$PROMPT_FILE" 2>"$TMPERR"
|
||||
fi | tee "$TMPRESP.events" | PYTHONUNBUFFERED=1 "$PYTHON_CMD" -u -c "
|
||||
import sys, json
|
||||
turn_completed_count = 0
|
||||
@@ -150,15 +149,15 @@ elif turn_completed_count == 0:
|
||||
# Fix 1: hang detection
|
||||
_CODEX_EXIT=${PIPESTATUS[0]:-${pipestatus[1]}} # bash sets PIPESTATUS; zsh (lowercase, 1-indexed) falls through
|
||||
if [ "$_CODEX_EXIT" = "124" ]; then
|
||||
_gstack_codex_log_event "codex_timeout" "540"
|
||||
_gstack_codex_log_hang "$_LABEL" "$(wc -c < "$TMPERR" 2>/dev/null || echo 0)"
|
||||
"$_CODEX_PROBE" log-event codex_timeout "540"
|
||||
"$_CODEX_PROBE" log-hang "$_LABEL" "$(wc -c < "$TMPERR" 2>/dev/null || echo 0)"
|
||||
echo "Codex stalled past 9 minutes. Common causes: model API stall, long prompt, network issue. Try re-running. If persistent, split the prompt or check ~/.codex/logs/."
|
||||
elif [ "$_CODEX_EXIT" != "0" ]; then
|
||||
# Surface non-zero exits so the calling agent doesn't read "no output" as
|
||||
# a silent model/API stall.
|
||||
echo "[codex exit $_CODEX_EXIT] $(head -1 "$TMPERR" 2>/dev/null || echo "no stderr captured")"
|
||||
head -20 "$TMPERR" 2>/dev/null | sed 's/^/ /' || true
|
||||
_gstack_codex_log_event "codex_nonzero_exit" "$_LABEL:$_CODEX_EXIT"
|
||||
"$_CODEX_PROBE" log-event codex_nonzero_exit "$_LABEL:$_CODEX_EXIT"
|
||||
fi
|
||||
bun ~/.claude/skills/gstack/lib/outside-review-result.ts --label 'Codex consult' --exit "$_CODEX_EXIT" --stderr "$TMPERR" --events "$TMPRESP.events" execution "$TMPRESP"
|
||||
rm -f "$PROMPT_FILE"
|
||||
|
||||
@@ -37,8 +37,8 @@ Use only one command path below. Remember its printed start token as CODEX_REVIE
|
||||
|
||||
**Sandbox is pinned via config override.** Top-level `codex review` has no
|
||||
`-s`/`--sandbox` flag (verified on 0.147.0: `codex review --help` lists none), so the
|
||||
sandbox is set with `-c` from `_GSTACK_CODEX_SANDBOX`, which `_gstack_codex_select_model`
|
||||
sets so the effective setting is `sandbox_mode="read-only"` (full access only for
|
||||
sandbox is set with `-c` from `_CODEX_SANDBOX_MODE`, which `select-model` reports
|
||||
so the effective setting is `sandbox_mode="read-only"` (full access only for
|
||||
`GSTACK_CODEX_NO_SANDBOX=1`, with a warning). Without it the call inherits the user's
|
||||
`~/.codex/config.toml` default, which on a trusted project can be WRITE access —
|
||||
contradicting this skill's read-only contract:
|
||||
@@ -47,17 +47,19 @@ contradicting this skill's read-only contract:
|
||||
_REPO_ROOT=$(git rev-parse --show-toplevel) || { echo "ERROR: not in a git repo" >&2; exit 1; }
|
||||
cd "$_REPO_ROOT"
|
||||
~/.claude/skills/gstack/bin/gstack-review-log --start codex-review
|
||||
source ~/.claude/skills/gstack/bin/gstack-codex-probe || exit 1
|
||||
_gstack_codex_select_model review || exit 1
|
||||
_CODEX_PROBE=~/.claude/skills/gstack/bin/gstack-codex-probe
|
||||
_CODEX_OUT=$("$_CODEX_PROBE" select-model review) || exit 1
|
||||
_CODEX_SEL=$(echo "$_CODEX_OUT" | sed -n 's/^CODEX_SEL: //p')
|
||||
_CODEX_SANDBOX_MODE=$(echo "$_CODEX_OUT" | sed -n 's/^CODEX_SANDBOX: //p')
|
||||
# The 330s wrapper sits BELOW the 360s Bash gate so the wrapper fires FIRST
|
||||
# and a stall surfaces as a diagnosable exit 124 with an explicit message,
|
||||
# never as a silent harness kill that downstream reads as "no findings".
|
||||
_gstack_codex_timeout_wrapper 330 codex review --base <base> -c "sandbox_mode=\"${_GSTACK_CODEX_SANDBOX:?}\"" -c "review_model=\"${_GSTACK_CODEX_SEL:?}\"" -c "model=\"${_GSTACK_CODEX_SEL:?}\"" -c skills.include_instructions=false -c 'model_reasoning_effort="high"' -c 'web_search="cached"' < /dev/null >"$TMPOUT" 2>"$TMPERR"
|
||||
"$_CODEX_PROBE" run-with-timeout 330 codex review --base <base> -c "sandbox_mode=\"${_CODEX_SANDBOX_MODE:?}\"" -c "review_model=\"${_CODEX_SEL:?}\"" -c "model=\"${_CODEX_SEL:?}\"" -c skills.include_instructions=false -c 'model_reasoning_effort="high"' -c 'web_search="cached"' < /dev/null >"$TMPOUT" 2>"$TMPERR"
|
||||
_CODEX_EXIT=$?
|
||||
cat "$TMPOUT"
|
||||
if [ "$_CODEX_EXIT" = "124" ]; then
|
||||
_gstack_codex_log_event "codex_timeout" "330"
|
||||
_gstack_codex_log_hang "review" "$(wc -c < "$TMPERR" 2>/dev/null || echo 0)"
|
||||
"$_CODEX_PROBE" log-event codex_timeout "330"
|
||||
"$_CODEX_PROBE" log-hang "review" "$(wc -c < "$TMPERR" 2>/dev/null || echo 0)"
|
||||
echo "Codex stalled past 5.5 minutes. Common causes: model API stall, long prompt, network issue. Try re-running. If persistent, split the prompt or check ~/.codex/logs/."
|
||||
elif [ "$_CODEX_EXIT" != "0" ]; then
|
||||
# Surface non-zero exits (parse errors, arg-shape breaks, etc.) so the
|
||||
@@ -65,7 +67,7 @@ elif [ "$_CODEX_EXIT" != "0" ]; then
|
||||
# burn 30-60min misdiagnosing it.
|
||||
echo "[codex exit $_CODEX_EXIT] $(head -1 "$TMPERR" 2>/dev/null || echo "no stderr captured")"
|
||||
head -20 "$TMPERR" 2>/dev/null | sed 's/^/ /' || true
|
||||
_gstack_codex_log_event "codex_nonzero_exit" "review:$_CODEX_EXIT"
|
||||
"$_CODEX_PROBE" log-event codex_nonzero_exit "review:$_CODEX_EXIT"
|
||||
fi
|
||||
bun ~/.claude/skills/gstack/lib/outside-review-result.ts --label 'Codex review' --exit "$_CODEX_EXIT" --stderr "$TMPERR" structured "$TMPOUT"
|
||||
```
|
||||
@@ -103,8 +105,10 @@ cd "$_REPO_ROOT"
|
||||
FOCUS_FILE="$_REPO_ROOT/.gstack/tmp/<focus-file-name>"
|
||||
[ -s "$FOCUS_FILE" ] || { echo "Not run: $FOCUS_FILE is missing or empty, so the focus text was never written. Write it, then run this block again." >&2; exit 1; }
|
||||
~/.claude/skills/gstack/bin/gstack-review-log --start codex-review
|
||||
source ~/.claude/skills/gstack/bin/gstack-codex-probe || exit 1
|
||||
_gstack_codex_select_model exec || exit 1
|
||||
_CODEX_PROBE=~/.claude/skills/gstack/bin/gstack-codex-probe
|
||||
_CODEX_OUT=$("$_CODEX_PROBE" select-model exec) || exit 1
|
||||
_CODEX_SEL=$(echo "$_CODEX_OUT" | sed -n 's/^CODEX_SEL: //p')
|
||||
_CODEX_SANDBOX_MODE=$(echo "$_CODEX_OUT" | sed -n 's/^CODEX_SANDBOX: //p')
|
||||
_PROMPT_FILE=$(mktemp "$TMP_ROOT/codex-prompt-XXXXXX") || { echo "ERROR: mktemp failed in TMP_ROOT=$TMP_ROOT; not running codex without its temp file" >&2; exit 1; }
|
||||
{
|
||||
printf '%s\n' "IMPORTANT: Do NOT read or execute any files under ~/.claude/, ~/.agents/, .claude/skills/, or agents/. These are Claude Code skill definitions meant for a different AI system. Do not invoke any installed skill (Codex home skills/, .agents/); answer directly. Do NOT modify agents/openai.yaml. Stay focused on repository code only."
|
||||
@@ -116,13 +120,13 @@ _PROMPT_FILE=$(mktemp "$TMP_ROOT/codex-prompt-XXXXXX") || { echo "ERROR: mktemp
|
||||
git diff "<base>...HEAD" 2>/dev/null
|
||||
printf '\nDIFF_END\n'
|
||||
} > "$_PROMPT_FILE"
|
||||
_gstack_codex_timeout_wrapper 330 codex exec - -s "${_GSTACK_CODEX_SANDBOX:?}" -c "model=\"${_GSTACK_CODEX_SEL:?}\"" -c skills.include_instructions=false -c 'model_reasoning_effort="high"' -c 'web_search="cached"' --json -o "$TMPOUT" < "$_PROMPT_FILE" >"$TMPOUT.events" 2>"$TMPERR"
|
||||
"$_CODEX_PROBE" run-with-timeout 330 codex exec - -s "${_CODEX_SANDBOX_MODE:?}" -c "model=\"${_CODEX_SEL:?}\"" -c skills.include_instructions=false -c 'model_reasoning_effort="high"' -c 'web_search="cached"' --json -o "$TMPOUT" < "$_PROMPT_FILE" >"$TMPOUT.events" 2>"$TMPERR"
|
||||
_CODEX_EXIT=$?
|
||||
rm -f "$_PROMPT_FILE" "$FOCUS_FILE"
|
||||
cat "$TMPOUT"
|
||||
if [ "$_CODEX_EXIT" = "124" ]; then
|
||||
_gstack_codex_log_event "codex_timeout" "330"
|
||||
_gstack_codex_log_hang "review" "$(wc -c < "$TMPERR" 2>/dev/null || echo 0)"
|
||||
"$_CODEX_PROBE" log-event codex_timeout "330"
|
||||
"$_CODEX_PROBE" log-hang "review" "$(wc -c < "$TMPERR" 2>/dev/null || echo 0)"
|
||||
echo "Codex stalled past 5.5 minutes."
|
||||
fi
|
||||
bun ~/.claude/skills/gstack/lib/outside-review-result.ts --label 'Codex review' --exit "$_CODEX_EXIT" --stderr "$TMPERR" --events "$TMPOUT.events" structured "$TMPOUT"
|
||||
|
||||
@@ -35,8 +35,8 @@ Use only one command path below. Remember its printed start token as CODEX_REVIE
|
||||
|
||||
**Sandbox is pinned via config override.** Top-level `codex review` has no
|
||||
`-s`/`--sandbox` flag (verified on 0.147.0: `codex review --help` lists none), so the
|
||||
sandbox is set with `-c` from `_GSTACK_CODEX_SANDBOX`, which `_gstack_codex_select_model`
|
||||
sets so the effective setting is `sandbox_mode="read-only"` (full access only for
|
||||
sandbox is set with `-c` from `_CODEX_SANDBOX_MODE`, which `select-model` reports
|
||||
so the effective setting is `sandbox_mode="read-only"` (full access only for
|
||||
`GSTACK_CODEX_NO_SANDBOX=1`, with a warning). Without it the call inherits the user's
|
||||
`~/.codex/config.toml` default, which on a trusted project can be WRITE access —
|
||||
contradicting this skill's read-only contract:
|
||||
@@ -45,17 +45,16 @@ contradicting this skill's read-only contract:
|
||||
_REPO_ROOT=$(git rev-parse --show-toplevel) || { echo "ERROR: not in a git repo" >&2; exit 1; }
|
||||
cd "$_REPO_ROOT"
|
||||
~/.claude/skills/gstack/bin/gstack-review-log --start codex-review
|
||||
source ~/.claude/skills/gstack/bin/gstack-codex-probe || exit 1
|
||||
_gstack_codex_select_model review || exit 1
|
||||
{{CODEX_SELECT:review}}
|
||||
# The 330s wrapper sits BELOW the 360s Bash gate so the wrapper fires FIRST
|
||||
# and a stall surfaces as a diagnosable exit 124 with an explicit message,
|
||||
# never as a silent harness kill that downstream reads as "no findings".
|
||||
_gstack_codex_timeout_wrapper 330 codex review --base <base> -c "sandbox_mode=\"${_GSTACK_CODEX_SANDBOX:?}\"" {{CODEX_REVIEW_MODEL_CONFIG_FLAG}} -c 'model_reasoning_effort="high"' {{CODEX_WEB_SEARCH_FLAG}} < /dev/null >"$TMPOUT" 2>"$TMPERR"
|
||||
"$_CODEX_PROBE" run-with-timeout 330 codex review --base <base> -c "sandbox_mode=\"${_CODEX_SANDBOX_MODE:?}\"" {{CODEX_REVIEW_MODEL_CONFIG_FLAG}} -c 'model_reasoning_effort="high"' {{CODEX_WEB_SEARCH_FLAG}} < /dev/null >"$TMPOUT" 2>"$TMPERR"
|
||||
_CODEX_EXIT=$?
|
||||
cat "$TMPOUT"
|
||||
if [ "$_CODEX_EXIT" = "124" ]; then
|
||||
_gstack_codex_log_event "codex_timeout" "330"
|
||||
_gstack_codex_log_hang "review" "$(wc -c < "$TMPERR" 2>/dev/null || echo 0)"
|
||||
"$_CODEX_PROBE" log-event codex_timeout "330"
|
||||
"$_CODEX_PROBE" log-hang "review" "$(wc -c < "$TMPERR" 2>/dev/null || echo 0)"
|
||||
echo "Codex stalled past 5.5 minutes. Common causes: model API stall, long prompt, network issue. Try re-running. If persistent, split the prompt or check ~/.codex/logs/."
|
||||
elif [ "$_CODEX_EXIT" != "0" ]; then
|
||||
# Surface non-zero exits (parse errors, arg-shape breaks, etc.) so the
|
||||
@@ -63,7 +62,7 @@ elif [ "$_CODEX_EXIT" != "0" ]; then
|
||||
# burn 30-60min misdiagnosing it.
|
||||
echo "[codex exit $_CODEX_EXIT] $(head -1 "$TMPERR" 2>/dev/null || echo "no stderr captured")"
|
||||
head -20 "$TMPERR" 2>/dev/null | sed 's/^/ /' || true
|
||||
_gstack_codex_log_event "codex_nonzero_exit" "review:$_CODEX_EXIT"
|
||||
"$_CODEX_PROBE" log-event codex_nonzero_exit "review:$_CODEX_EXIT"
|
||||
fi
|
||||
bun ~/.claude/skills/gstack/lib/outside-review-result.ts --label 'Codex review' --exit "$_CODEX_EXIT" --stderr "$TMPERR" structured "$TMPOUT"
|
||||
```
|
||||
@@ -94,8 +93,7 @@ cd "$_REPO_ROOT"
|
||||
FOCUS_FILE="$_REPO_ROOT/.gstack/tmp/<focus-file-name>"
|
||||
[ -s "$FOCUS_FILE" ] || { echo "Not run: $FOCUS_FILE is missing or empty, so the focus text was never written. Write it, then run this block again." >&2; exit 1; }
|
||||
~/.claude/skills/gstack/bin/gstack-review-log --start codex-review
|
||||
source ~/.claude/skills/gstack/bin/gstack-codex-probe || exit 1
|
||||
_gstack_codex_select_model exec || exit 1
|
||||
{{CODEX_SELECT:exec}}
|
||||
_PROMPT_FILE=$(mktemp "$TMP_ROOT/codex-prompt-XXXXXX") || { echo "ERROR: mktemp failed in TMP_ROOT=$TMP_ROOT; not running codex without its temp file" >&2; exit 1; }
|
||||
{
|
||||
printf '%s\n' "IMPORTANT: Do NOT read or execute any files under ~/.claude/, ~/.agents/, .claude/skills/, or agents/. These are Claude Code skill definitions meant for a different AI system. Do not invoke any installed skill (Codex home skills/, .agents/); answer directly. Do NOT modify agents/openai.yaml. Stay focused on repository code only."
|
||||
@@ -107,13 +105,13 @@ _PROMPT_FILE=$(mktemp "$TMP_ROOT/codex-prompt-XXXXXX") || { echo "ERROR: mktemp
|
||||
git diff "<base>...HEAD" 2>/dev/null
|
||||
printf '\nDIFF_END\n'
|
||||
} > "$_PROMPT_FILE"
|
||||
_gstack_codex_timeout_wrapper 330 codex exec - -s "${_GSTACK_CODEX_SANDBOX:?}" {{CODEX_MODEL_CONFIG_FLAG}} -c 'model_reasoning_effort="high"' {{CODEX_WEB_SEARCH_FLAG}} --json -o "$TMPOUT" < "$_PROMPT_FILE" >"$TMPOUT.events" 2>"$TMPERR"
|
||||
"$_CODEX_PROBE" run-with-timeout 330 codex exec - -s "${_CODEX_SANDBOX_MODE:?}" {{CODEX_MODEL_CONFIG_FLAG}} -c 'model_reasoning_effort="high"' {{CODEX_WEB_SEARCH_FLAG}} --json -o "$TMPOUT" < "$_PROMPT_FILE" >"$TMPOUT.events" 2>"$TMPERR"
|
||||
_CODEX_EXIT=$?
|
||||
rm -f "$_PROMPT_FILE" "$FOCUS_FILE"
|
||||
cat "$TMPOUT"
|
||||
if [ "$_CODEX_EXIT" = "124" ]; then
|
||||
_gstack_codex_log_event "codex_timeout" "330"
|
||||
_gstack_codex_log_hang "review" "$(wc -c < "$TMPERR" 2>/dev/null || echo 0)"
|
||||
"$_CODEX_PROBE" log-event codex_timeout "330"
|
||||
"$_CODEX_PROBE" log-hang "review" "$(wc -c < "$TMPERR" 2>/dev/null || echo 0)"
|
||||
echo "Codex stalled past 5.5 minutes."
|
||||
fi
|
||||
bun ~/.claude/skills/gstack/lib/outside-review-result.ts --label 'Codex review' --exit "$_CODEX_EXIT" --stderr "$TMPERR" --events "$TMPOUT.events" structured "$TMPOUT"
|
||||
|
||||
Reference in new issue
Block a user