mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-07 01:15:47 +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
+17
-19
@@ -454,8 +454,7 @@ If `NOT_FOUND`: stop and tell the user:
|
||||
|
||||
If `NOT_FOUND`, also log the event:
|
||||
```bash
|
||||
_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || echo off)
|
||||
source ~/.claude/skills/gstack/bin/gstack-codex-probe 2>/dev/null && _gstack_codex_log_event "codex_cli_missing" 2>/dev/null || true
|
||||
~/.claude/skills/gstack/bin/gstack-codex-probe log-event codex_cli_missing 2>/dev/null || true
|
||||
```
|
||||
|
||||
---
|
||||
@@ -464,19 +463,19 @@ source ~/.claude/skills/gstack/bin/gstack-codex-probe 2>/dev/null && _gstack_cod
|
||||
|
||||
Before building expensive prompts, verify Codex has valid auth, that the account
|
||||
can actually USE gstack's selected model, AND the installed CLI version isn't in the
|
||||
known-bad list. Sourcing `gstack-codex-probe` loads the shared helpers that both
|
||||
`/codex` and `/autoplan` use.
|
||||
known-bad list. `gstack-codex-probe` is the shared helper that `/codex`, `/autoplan`
|
||||
and every outside review run as a command, one subcommand per check.
|
||||
|
||||
Model order: a model the user names for this request, `GSTACK_CODEX_MODEL`, Codex
|
||||
`config.toml` `model` (`review_model` first for `codex review`; honors `$CODEX_HOME`),
|
||||
then `gpt-6-astra`. Each call prints `CODEX_MODEL: <model> (<kind>; source: ...)` first.
|
||||
For a named model, pass it as the second argument of every `_gstack_codex_select_model`
|
||||
call, and run `_gstack_codex_select_model exec '<model>'` before the probe below. An
|
||||
invalid or unavailable choice stops with a repair message, never the default.
|
||||
For a named model, add `--model '<model>'` to every `select-model` and `probe-model`
|
||||
call, including the probe below. An invalid or unavailable choice stops with a repair
|
||||
message, never the default.
|
||||
|
||||
```bash
|
||||
_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || echo off)
|
||||
source ~/.claude/skills/gstack/bin/gstack-codex-probe || { echo "HELPER_UNAVAILABLE"; exit 1; }
|
||||
_CODEX_PROBE=~/.claude/skills/gstack/bin/gstack-codex-probe
|
||||
[ -x "$_CODEX_PROBE" ] || { echo "HELPER_UNAVAILABLE"; exit 1; }
|
||||
|
||||
# GSTACK_ACTIVE_HOST names the harness, never the model.
|
||||
if { [ -n "${CODEX_THREAD_ID:-}" ] || [ -n "${CODEX_SANDBOX:-}" ] || [ "${GSTACK_ACTIVE_HOST:-}" = codex ]; }; then
|
||||
@@ -488,20 +487,19 @@ if { [ -n "${CODEX_THREAD_ID:-}" ] || [ -n "${CODEX_SANDBOX:-}" ] || [ "${GSTACK
|
||||
fi
|
||||
exit 78
|
||||
fi
|
||||
if ! _gstack_codex_auth_probe >/dev/null; then
|
||||
_gstack_codex_log_event "codex_auth_failed"
|
||||
if ! "$_CODEX_PROBE" check-auth >/dev/null; then
|
||||
"$_CODEX_PROBE" log-event codex_auth_failed
|
||||
echo "AUTH_FAILED"
|
||||
elif _gstack_codex_sandbox_preflight; then # free; Linux only
|
||||
_gstack_codex_model_probe # ~10s round trip on first run, cached 1h
|
||||
elif "$_CODEX_PROBE" check-sandbox; then # free; Linux only
|
||||
"$_CODEX_PROBE" probe-model exec # ~10s round trip on first run, cached 1h
|
||||
fi
|
||||
_gstack_codex_version_check # warns if known-bad, non-blocking
|
||||
"$_CODEX_PROBE" check-version # warns if known-bad, non-blocking
|
||||
```
|
||||
|
||||
If the runtime guard reports a harness mismatch, stop. Outside coverage is unavailable. Repair with `./setup --host codex`; do not silently substitute another provider or force a same-harness invocation.
|
||||
|
||||
If the output contains `HELPER_UNAVAILABLE`, stop: the gstack helper could not load in
|
||||
this shell. Relay its `gstack: cannot locate ...` line verbatim; it names the shell and
|
||||
links the fix.
|
||||
If the output contains `HELPER_UNAVAILABLE`, stop: `gstack-codex-probe` is missing or
|
||||
not executable in this install. Tell the user to re-run `./setup` (or `/gstack-upgrade`).
|
||||
|
||||
If the output contains `AUTH_FAILED`, stop and tell the user:
|
||||
"No Codex authentication found. Run `codex login` or set `$CODEX_API_KEY` / `$OPENAI_API_KEY`, then re-run this skill."
|
||||
@@ -773,7 +771,7 @@ table-bearing section that must be the file's terminal heading.
|
||||
|
||||
## Model & Reasoning
|
||||
|
||||
**Model:** every Codex call passes the selection above via `-c "model=\"${_GSTACK_CODEX_SEL:?}\"" -c skills.include_instructions=false`.
|
||||
**Model:** every Codex call passes the selection above via `-c "model=\"${_CODEX_SEL:?}\"" -c skills.include_instructions=false`.
|
||||
Native `codex review` selects with `review` and sets both `model` and `review_model`. The
|
||||
flag also keeps installed skills out of Codex's context, so a review cannot become a
|
||||
nested skill run.
|
||||
@@ -871,7 +869,7 @@ If token count is not available, display: `Tokens: unknown`
|
||||
before showing it. Show it in full inside the CODEX SAYS block.
|
||||
- **Add synthesis after, not instead of.** Any Claude commentary comes after the full output.
|
||||
- **Bash gate above the wrapper.** Every Bash call to codex sets its `timeout`
|
||||
parameter ABOVE the inner `_gstack_codex_timeout_wrapper` budget (Review:
|
||||
parameter ABOVE the inner `run-with-timeout` budget (Review:
|
||||
`timeout: 360000` over the 330s wrapper; Challenge/Consult: `timeout: 600000`
|
||||
over the 540s wrappers) so the wrapper fires first with a diagnosable exit 124.
|
||||
- **No double-reviewing.** If the user already ran `/review`, Codex provides a second
|
||||
|
||||
+16
-18
@@ -55,8 +55,7 @@ If `NOT_FOUND`: stop and tell the user:
|
||||
|
||||
If `NOT_FOUND`, also log the event:
|
||||
```bash
|
||||
_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || echo off)
|
||||
source ~/.claude/skills/gstack/bin/gstack-codex-probe 2>/dev/null && _gstack_codex_log_event "codex_cli_missing" 2>/dev/null || true
|
||||
~/.claude/skills/gstack/bin/gstack-codex-probe log-event codex_cli_missing 2>/dev/null || true
|
||||
```
|
||||
|
||||
---
|
||||
@@ -65,35 +64,34 @@ source ~/.claude/skills/gstack/bin/gstack-codex-probe 2>/dev/null && _gstack_cod
|
||||
|
||||
Before building expensive prompts, verify Codex has valid auth, that the account
|
||||
can actually USE gstack's selected model, AND the installed CLI version isn't in the
|
||||
known-bad list. Sourcing `gstack-codex-probe` loads the shared helpers that both
|
||||
`/codex` and `/autoplan` use.
|
||||
known-bad list. `gstack-codex-probe` is the shared helper that `/codex`, `/autoplan`
|
||||
and every outside review run as a command, one subcommand per check.
|
||||
|
||||
Model order: a model the user names for this request, `GSTACK_CODEX_MODEL`, Codex
|
||||
`config.toml` `model` (`review_model` first for `codex review`; honors `$CODEX_HOME`),
|
||||
then `gpt-6-astra`. Each call prints `CODEX_MODEL: <model> (<kind>; source: ...)` first.
|
||||
For a named model, pass it as the second argument of every `_gstack_codex_select_model`
|
||||
call, and run `_gstack_codex_select_model exec '<model>'` before the probe below. An
|
||||
invalid or unavailable choice stops with a repair message, never the default.
|
||||
For a named model, add `--model '<model>'` to every `select-model` and `probe-model`
|
||||
call, including the probe below. An invalid or unavailable choice stops with a repair
|
||||
message, never the default.
|
||||
|
||||
```bash
|
||||
_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || echo off)
|
||||
source ~/.claude/skills/gstack/bin/gstack-codex-probe || { echo "HELPER_UNAVAILABLE"; exit 1; }
|
||||
_CODEX_PROBE=~/.claude/skills/gstack/bin/gstack-codex-probe
|
||||
[ -x "$_CODEX_PROBE" ] || { echo "HELPER_UNAVAILABLE"; exit 1; }
|
||||
|
||||
{{OUTSIDE_SELF_GUARD:codex}}
|
||||
if ! _gstack_codex_auth_probe >/dev/null; then
|
||||
_gstack_codex_log_event "codex_auth_failed"
|
||||
if ! "$_CODEX_PROBE" check-auth >/dev/null; then
|
||||
"$_CODEX_PROBE" log-event codex_auth_failed
|
||||
echo "AUTH_FAILED"
|
||||
elif _gstack_codex_sandbox_preflight; then # free; Linux only
|
||||
_gstack_codex_model_probe # ~10s round trip on first run, cached 1h
|
||||
elif "$_CODEX_PROBE" check-sandbox; then # free; Linux only
|
||||
"$_CODEX_PROBE" probe-model exec # ~10s round trip on first run, cached 1h
|
||||
fi
|
||||
_gstack_codex_version_check # warns if known-bad, non-blocking
|
||||
"$_CODEX_PROBE" check-version # warns if known-bad, non-blocking
|
||||
```
|
||||
|
||||
If the runtime guard reports a harness mismatch, stop. Outside coverage is unavailable. Repair with `./setup --host codex`; do not silently substitute another provider or force a same-harness invocation.
|
||||
|
||||
If the output contains `HELPER_UNAVAILABLE`, stop: the gstack helper could not load in
|
||||
this shell. Relay its `gstack: cannot locate ...` line verbatim; it names the shell and
|
||||
links the fix.
|
||||
If the output contains `HELPER_UNAVAILABLE`, stop: `gstack-codex-probe` is missing or
|
||||
not executable in this install. Tell the user to re-run `./setup` (or `/gstack-upgrade`).
|
||||
|
||||
If the output contains `AUTH_FAILED`, stop and tell the user:
|
||||
"No Codex authentication found. Run `codex login` or set `$CODEX_API_KEY` / `$OPENAI_API_KEY`, then re-run this skill."
|
||||
@@ -338,7 +336,7 @@ If token count is not available, display: `Tokens: unknown`
|
||||
before showing it. Show it in full inside the CODEX SAYS block.
|
||||
- **Add synthesis after, not instead of.** Any Claude commentary comes after the full output.
|
||||
- **Bash gate above the wrapper.** Every Bash call to codex sets its `timeout`
|
||||
parameter ABOVE the inner `_gstack_codex_timeout_wrapper` budget (Review:
|
||||
parameter ABOVE the inner `run-with-timeout` budget (Review:
|
||||
`timeout: 360000` over the 330s wrapper; Challenge/Consult: `timeout: 600000`
|
||||
over the 540s wrappers) so the wrapper fires first with a diagnosable exit 124.
|
||||
- **No double-reviewing.** If the user already ran `/review`, Codex provides a second
|
||||
|
||||
@@ -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