Skip to content

Commit e045999

Browse files
authored
Merge pull request #194 from BBuf/codex/disable-nested-codex-hooks
Disable hooks for nested Codex helpers
2 parents c4c0f9e + f4e4895 commit e045999

6 files changed

Lines changed: 180 additions & 48 deletions

File tree

hooks/loop-codex-stop-hook.sh

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1174,19 +1174,31 @@ mkdir -p "$CACHE_DIR"
11741174
# portable-timeout.sh already sourced above
11751175

11761176
# Disable native hooks for nested Codex reviewer calls to prevent Stop-hook recursion.
1177-
# Probe whether the installed Codex CLI supports --disable; cache the result per loop
1178-
# so older builds do not fail with an unknown-argument error.
1177+
# Codex has used different hook feature names across releases. Probe each name
1178+
# before disabling it so older CLIs that validate feature names still work.
11791179
CODEX_DISABLE_HOOKS_ARGS=()
1180-
_CODEX_FEATURE_CACHE="$CACHE_DIR/.codex-disable-hooks-supported"
1180+
_CODEX_FEATURE_CACHE="$CACHE_DIR/.codex-disable-hooks-features"
11811181
if [[ -f "$_CODEX_FEATURE_CACHE" ]]; then
1182-
[[ "$(cat "$_CODEX_FEATURE_CACHE")" == "yes" ]] && CODEX_DISABLE_HOOKS_ARGS=(--disable hooks)
1182+
while IFS= read -r feature_name; do
1183+
case "$feature_name" in
1184+
hooks|plugin_hooks|codex_hooks)
1185+
CODEX_DISABLE_HOOKS_ARGS+=("--disable" "$feature_name")
1186+
;;
1187+
esac
1188+
done < "$_CODEX_FEATURE_CACHE"
11831189
else
11841190
CODEX_HELP_OUTPUT="$(codex --help </dev/null 2>&1 || true)"
11851191
if grep -q -- '--disable' <<< "$CODEX_HELP_OUTPUT"; then
1186-
CODEX_DISABLE_HOOKS_ARGS=(--disable hooks)
1187-
echo "yes" > "$_CODEX_FEATURE_CACHE" 2>/dev/null
1192+
_CODEX_DISABLE_HOOK_FEATURES=()
1193+
for feature_name in hooks plugin_hooks codex_hooks; do
1194+
if codex --disable "$feature_name" --help </dev/null >/dev/null 2>&1; then
1195+
CODEX_DISABLE_HOOKS_ARGS+=("--disable" "$feature_name")
1196+
_CODEX_DISABLE_HOOK_FEATURES+=("$feature_name")
1197+
fi
1198+
done
1199+
printf '%s\n' ${_CODEX_DISABLE_HOOK_FEATURES[@]+"${_CODEX_DISABLE_HOOK_FEATURES[@]}"} > "$_CODEX_FEATURE_CACHE" 2>/dev/null || true
11881200
else
1189-
echo "no" > "$_CODEX_FEATURE_CACHE" 2>/dev/null
1201+
: > "$_CODEX_FEATURE_CACHE" 2>/dev/null || true
11901202
fi
11911203
fi
11921204

scripts/ask-codex.sh

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -241,20 +241,31 @@ EOF
241241
# Build Codex Command
242242
# ========================================
243243

244-
# Probe whether the installed Codex CLI supports --disable hooks to prevent
245-
# nested hook recursion when ask-codex.sh is called from inside a running loop.
246-
# Cache the probe result in the skill directory to avoid repeated probes.
244+
# Probe supported hook feature names before disabling them. Codex has used
245+
# different names across releases, and older CLIs reject unknown feature names.
247246
CODEX_DISABLE_HOOKS_ARGS=()
248-
_CODEX_DISABLE_HOOKS_CACHE="$SKILL_DIR/.codex-disable-hooks-supported"
247+
_CODEX_DISABLE_HOOKS_CACHE="$SKILL_DIR/.codex-disable-hooks-features"
249248
if [[ -f "$_CODEX_DISABLE_HOOKS_CACHE" ]]; then
250-
[[ "$(cat "$_CODEX_DISABLE_HOOKS_CACHE")" == "yes" ]] && CODEX_DISABLE_HOOKS_ARGS=(--disable hooks)
249+
while IFS= read -r feature_name; do
250+
case "$feature_name" in
251+
hooks|plugin_hooks|codex_hooks)
252+
CODEX_DISABLE_HOOKS_ARGS+=("--disable" "$feature_name")
253+
;;
254+
esac
255+
done < "$_CODEX_DISABLE_HOOKS_CACHE"
251256
else
252257
CODEX_HELP_OUTPUT="$(codex --help </dev/null 2>&1 || true)"
253258
if grep -q -- '--disable' <<< "$CODEX_HELP_OUTPUT"; then
254-
CODEX_DISABLE_HOOKS_ARGS=(--disable hooks)
255-
echo "yes" > "$_CODEX_DISABLE_HOOKS_CACHE" 2>/dev/null || true
259+
_CODEX_DISABLE_HOOK_FEATURES=()
260+
for feature_name in hooks plugin_hooks codex_hooks; do
261+
if codex --disable "$feature_name" --help </dev/null >/dev/null 2>&1; then
262+
CODEX_DISABLE_HOOKS_ARGS+=("--disable" "$feature_name")
263+
_CODEX_DISABLE_HOOK_FEATURES+=("$feature_name")
264+
fi
265+
done
266+
printf '%s\n' ${_CODEX_DISABLE_HOOK_FEATURES[@]+"${_CODEX_DISABLE_HOOK_FEATURES[@]}"} > "$_CODEX_DISABLE_HOOKS_CACHE" 2>/dev/null || true
256267
else
257-
echo "no" > "$_CODEX_DISABLE_HOOKS_CACHE" 2>/dev/null || true
268+
: > "$_CODEX_DISABLE_HOOKS_CACHE" 2>/dev/null || true
258269
fi
259270
fi
260271

scripts/bitlesson-select.sh

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -193,11 +193,17 @@ run_selector() {
193193
# Capture help output first to avoid pipefail+SIGPIPE interaction when
194194
# grep exits early (after finding a match) before codex finishes writing.
195195
local codex_help_output codex_exec_help_output
196-
codex_help_output=$(codex --help 2>&1) || true
197-
codex_exec_help_output=$(codex exec --help 2>&1) || true
198-
# Probe whether the installed Codex CLI supports --disable flag
196+
codex_help_output=$(codex --help </dev/null 2>&1) || true
197+
codex_exec_help_output=$(codex exec --help </dev/null 2>&1) || true
198+
# Probe supported hook feature names before disabling them. Older Codex
199+
# CLIs reject unknown feature names even when --disable exists.
199200
if grep -q -- '--disable' <<< "$codex_help_output"; then
200-
codex_exec_args+=("--disable" "hooks")
201+
local feature_name
202+
for feature_name in hooks plugin_hooks codex_hooks; do
203+
if codex --disable "$feature_name" --help </dev/null >/dev/null 2>&1; then
204+
codex_exec_args+=("--disable" "$feature_name")
205+
fi
206+
done
201207
fi
202208
# Probe for --skip-git-repo-check and --ephemeral support
203209
if grep -q -- '--skip-git-repo-check' <<< "$codex_exec_help_output"; then

tests/test-ask-codex.sh

Lines changed: 93 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
# MOCK_CODEX_EXIT_CODE - exit code the mock returns (default: 0)
88
# MOCK_CODEX_STDOUT - text the mock writes to stdout
99
# MOCK_CODEX_STDERR - text the mock writes to stderr
10+
# MOCK_CODEX_HELP_OUTPUT - text the mock writes for `codex --help`
11+
# MOCK_CODEX_ARGS_FILE - optional file where non-help argv is captured
1012
#
1113

1214
set -euo pipefail
@@ -40,6 +42,23 @@ cat > "$MOCK_BIN_DIR/codex" << 'MOCK_EOF'
4042
#!/usr/bin/env bash
4143
# Mock codex binary for testing ask-codex.sh
4244
# Controlled via environment variables.
45+
if printf '%s\n' "$@" | grep -qx -- '--help'; then
46+
if [[ "${1:-}" == "--disable" ]]; then
47+
feature="${2:-}"
48+
supported_features=" ${MOCK_CODEX_SUPPORTED_FEATURES:-hooks plugin_hooks codex_hooks} "
49+
if [[ "$supported_features" != *" $feature "* ]]; then
50+
echo "unknown feature: $feature" >&2
51+
exit 2
52+
fi
53+
fi
54+
if [[ -n "${MOCK_CODEX_HELP_OUTPUT:-}" ]]; then
55+
echo "$MOCK_CODEX_HELP_OUTPUT"
56+
fi
57+
exit 0
58+
fi
59+
if [[ -n "${MOCK_CODEX_ARGS_FILE:-}" ]]; then
60+
printf '%s\n' "$@" > "$MOCK_CODEX_ARGS_FILE"
61+
fi
4362
if [[ -n "${MOCK_CODEX_STDERR:-}" ]]; then
4463
echo "$MOCK_CODEX_STDERR" >&2
4564
fi
@@ -63,6 +82,9 @@ reset_mock() {
6382
export MOCK_CODEX_EXIT_CODE="0"
6483
export MOCK_CODEX_STDOUT=""
6584
export MOCK_CODEX_STDERR=""
85+
export MOCK_CODEX_HELP_OUTPUT=""
86+
export MOCK_CODEX_ARGS_FILE=""
87+
export MOCK_CODEX_SUPPORTED_FEATURES="hooks plugin_hooks codex_hooks"
6688
rm -rf "$MOCK_PROJECT/.humanize/skill" 2>/dev/null || true
6789
}
6890

@@ -86,6 +108,7 @@ run_ask_codex_capturing_dir() {
86108
cd "$MOCK_PROJECT"
87109
export CLAUDE_PROJECT_DIR="$MOCK_PROJECT"
88110
export XDG_CACHE_HOME="$RUN_XDG_CACHE_HOME"
111+
export XDG_CONFIG_HOME="$TEST_DIR/no-user-config"
89112
PATH="$MOCK_BIN_DIR:$PATH" bash "$ASK_CODEX_SCRIPT" "$@" 2>&1 >/dev/null
90113
) || RUN_EXIT_CODE=$?
91114
output_path=$(printf '%s\n' "$run_stderr" | grep "^ask-codex: response saved to " | sed 's/^ask-codex: response saved to //')
@@ -114,6 +137,7 @@ run_ask_codex() {
114137
cd "$MOCK_PROJECT"
115138
export CLAUDE_PROJECT_DIR="$MOCK_PROJECT"
116139
export XDG_CACHE_HOME="$TEST_DIR/cache"
140+
export XDG_CONFIG_HOME="$TEST_DIR/no-user-config"
117141
PATH="$MOCK_BIN_DIR:$PATH" bash "$ASK_CODEX_SCRIPT" "$@"
118142
)
119143
}
@@ -253,6 +277,54 @@ else
253277
fail "successful run exits 0" "exit 0" "exit=$EXIT_CODE"
254278
fi
255279

280+
# Test: supported Codex --disable flag disables all known hook features
281+
reset_mock
282+
export MOCK_CODEX_STDOUT="hook-disable-test"
283+
export MOCK_CODEX_HELP_OUTPUT=" --disable <feature> Disable a feature"
284+
export MOCK_CODEX_SUPPORTED_FEATURES="hooks plugin_hooks codex_hooks"
285+
ASK_CODEX_ARGS_FILE="$TEST_DIR/ask-codex-args.txt"
286+
export MOCK_CODEX_ARGS_FILE="$ASK_CODEX_ARGS_FILE"
287+
EXIT_CODE=0
288+
run_ask_codex "hook disable test" > /dev/null 2>&1 || EXIT_CODE=$?
289+
CAPTURED_ARGS="$(cat "$ASK_CODEX_ARGS_FILE" 2>/dev/null || true)"
290+
if [[ $EXIT_CODE -eq 0 ]] \
291+
&& echo "$CAPTURED_ARGS" | grep -qx -- 'exec' \
292+
&& echo "$CAPTURED_ARGS" | grep -qx -- '--disable' \
293+
&& echo "$CAPTURED_ARGS" | grep -qx -- 'hooks' \
294+
&& echo "$CAPTURED_ARGS" | grep -qx -- 'plugin_hooks' \
295+
&& echo "$CAPTURED_ARGS" | grep -qx -- 'codex_hooks'; then
296+
pass "successful run disables all known hook features for nested codex exec"
297+
else
298+
fail "successful run disables all known hook features for nested codex exec" \
299+
"exec args include hooks, plugin_hooks, codex_hooks" \
300+
"exit=$EXIT_CODE, args=$CAPTURED_ARGS"
301+
fi
302+
reset_mock
303+
304+
# Test: older Codex builds only receive supported hook feature names
305+
reset_mock
306+
export MOCK_CODEX_STDOUT="legacy-hook-disable-test"
307+
export MOCK_CODEX_HELP_OUTPUT=" --disable <feature> Disable a feature"
308+
export MOCK_CODEX_SUPPORTED_FEATURES="codex_hooks"
309+
ASK_CODEX_ARGS_FILE="$TEST_DIR/ask-codex-legacy-args.txt"
310+
export MOCK_CODEX_ARGS_FILE="$ASK_CODEX_ARGS_FILE"
311+
EXIT_CODE=0
312+
run_ask_codex "legacy hook disable test" > /dev/null 2>&1 || EXIT_CODE=$?
313+
CAPTURED_ARGS="$(cat "$ASK_CODEX_ARGS_FILE" 2>/dev/null || true)"
314+
if [[ $EXIT_CODE -eq 0 ]] \
315+
&& echo "$CAPTURED_ARGS" | grep -qx -- 'exec' \
316+
&& echo "$CAPTURED_ARGS" | grep -qx -- '--disable' \
317+
&& echo "$CAPTURED_ARGS" | grep -qx -- 'codex_hooks' \
318+
&& ! echo "$CAPTURED_ARGS" | grep -qx -- 'hooks' \
319+
&& ! echo "$CAPTURED_ARGS" | grep -qx -- 'plugin_hooks'; then
320+
pass "successful run disables only supported hook features for older codex"
321+
else
322+
fail "successful run disables only supported hook features for older codex" \
323+
"exec args include only codex_hooks" \
324+
"exit=$EXIT_CODE, args=$CAPTURED_ARGS"
325+
fi
326+
reset_mock
327+
256328
# ========================================
257329
# Error Handling Tests
258330
# ========================================
@@ -519,6 +591,7 @@ run_ask_codex_probe() {
519591
cd "$PROBE_PROJECT"
520592
export CLAUDE_PROJECT_DIR="$PROBE_PROJECT"
521593
export XDG_CACHE_HOME="$TEST_DIR/cache-probe"
594+
export XDG_CONFIG_HOME="$TEST_DIR/no-user-config"
522595
PATH="$PROBE_BIN_DIR:$PATH" bash "$ASK_CODEX_SCRIPT" "$@"
523596
)
524597
}
@@ -545,14 +618,17 @@ reset_mock
545618
export MOCK_CODEX_STDOUT="probe-test-supports"
546619
run_ask_codex_probe "probe disable test" > /dev/null 2>&1 || true
547620

548-
# Check that the cached probe result is "yes" in the skill dir
621+
# Check that the cached probe result lists the supported hook features.
549622
PROBE_SKILL_DIR=$(find "$PROBE_PROJECT/.humanize/skill" -maxdepth 1 -mindepth 1 -type d 2>/dev/null | sort | tail -1)
550-
if [[ -n "$PROBE_SKILL_DIR" ]] && [[ -f "$PROBE_SKILL_DIR/.codex-disable-hooks-supported" ]]; then
551-
PROBE_RESULT=$(cat "$PROBE_SKILL_DIR/.codex-disable-hooks-supported")
552-
if [[ "$PROBE_RESULT" == "yes" ]]; then
553-
pass "auto-probe: cached 'yes' when codex supports --disable"
623+
if [[ -n "$PROBE_SKILL_DIR" ]] && [[ -f "$PROBE_SKILL_DIR/.codex-disable-hooks-features" ]]; then
624+
PROBE_RESULT=$(cat "$PROBE_SKILL_DIR/.codex-disable-hooks-features")
625+
if echo "$PROBE_RESULT" | grep -qx -- 'hooks' \
626+
&& echo "$PROBE_RESULT" | grep -qx -- 'plugin_hooks' \
627+
&& echo "$PROBE_RESULT" | grep -qx -- 'codex_hooks'; then
628+
pass "auto-probe: cached supported hook features when codex supports --disable"
554629
else
555-
fail "auto-probe: cached 'yes' when codex supports --disable" "yes" "$PROBE_RESULT"
630+
fail "auto-probe: cached supported hook features when codex supports --disable" \
631+
"hooks, plugin_hooks, codex_hooks" "$PROBE_RESULT"
556632
fi
557633
else
558634
fail "auto-probe: probe cache file created" "cache file exists" "not found"
@@ -583,6 +659,7 @@ run_ask_codex_probe_no() {
583659
cd "$PROBE_PROJECT_NO"
584660
export CLAUDE_PROJECT_DIR="$PROBE_PROJECT_NO"
585661
export XDG_CACHE_HOME="$TEST_DIR/cache-probe-no"
662+
export XDG_CONFIG_HOME="$TEST_DIR/no-user-config"
586663
PATH="$PROBE_BIN_NO_DIR:$PATH" bash "$ASK_CODEX_SCRIPT" "$@"
587664
)
588665
}
@@ -592,23 +669,25 @@ export MOCK_CODEX_STDOUT="probe-test-no-support"
592669
run_ask_codex_probe_no "probe no-support test" > /dev/null 2>&1 || true
593670

594671
PROBE_NO_SKILL_DIR=$(find "$PROBE_PROJECT_NO/.humanize/skill" -maxdepth 1 -mindepth 1 -type d 2>/dev/null | sort | tail -1)
595-
if [[ -n "$PROBE_NO_SKILL_DIR" ]] && [[ -f "$PROBE_NO_SKILL_DIR/.codex-disable-hooks-supported" ]]; then
596-
PROBE_NO_RESULT=$(cat "$PROBE_NO_SKILL_DIR/.codex-disable-hooks-supported")
597-
if [[ "$PROBE_NO_RESULT" == "no" ]]; then
598-
pass "auto-probe: cached 'no' when codex does not support --disable"
672+
if [[ -n "$PROBE_NO_SKILL_DIR" ]] && [[ -f "$PROBE_NO_SKILL_DIR/.codex-disable-hooks-features" ]]; then
673+
PROBE_NO_RESULT=$(cat "$PROBE_NO_SKILL_DIR/.codex-disable-hooks-features")
674+
if [[ -z "$PROBE_NO_RESULT" ]]; then
675+
pass "auto-probe: cached empty feature list when codex does not support --disable"
599676
else
600-
fail "auto-probe: cached 'no' when codex does not support --disable" "no" "$PROBE_NO_RESULT"
677+
fail "auto-probe: cached empty feature list when codex does not support --disable" \
678+
"(empty)" "$PROBE_NO_RESULT"
601679
fi
602680
else
603681
fail "auto-probe: probe cache file created for no-support case" "cache file exists" "not found"
604682
fi
605683

606684
# Test C: ask-codex.sh script contains the probe implementation
607-
if grep -q "CODEX_DISABLE_HOOKS_ARGS=(--disable hooks)" "$ASK_CODEX_SCRIPT" \
608-
&& grep -q "codex-disable-hooks-supported" "$ASK_CODEX_SCRIPT"; then
685+
if grep -q "for feature_name in hooks plugin_hooks codex_hooks" "$ASK_CODEX_SCRIPT" \
686+
&& grep -q "codex-disable-hooks-features" "$ASK_CODEX_SCRIPT"; then
609687
pass "ask-codex.sh contains nested hook disable auto-probe implementation"
610688
else
611-
fail "ask-codex.sh contains nested hook disable auto-probe implementation" "hooks disable args + probe cache" "not found"
689+
fail "ask-codex.sh contains nested hook disable auto-probe implementation" \
690+
"feature loop + probe cache" "not found"
612691
fi
613692

614693
# ========================================

tests/test-bitlesson-select-routing.sh

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -481,8 +481,10 @@ captured_args="$(cat "$CAPTURE_ARGS")"
481481

482482
if [[ $exit_code -eq 0 ]] \
483483
&& echo "$stdout_out" | grep -q "BL-20260315-tracker-drift" \
484-
&& echo "$captured_args" | grep -q -- '--disable' \
485-
&& echo "$captured_args" | grep -q -- 'hooks' \
484+
&& echo "$captured_args" | grep -qx -- '--disable' \
485+
&& echo "$captured_args" | grep -qx -- 'hooks' \
486+
&& echo "$captured_args" | grep -qx -- 'plugin_hooks' \
487+
&& echo "$captured_args" | grep -qx -- 'codex_hooks' \
486488
&& echo "$captured_args" | grep -q -- '--skip-git-repo-check' \
487489
&& echo "$captured_args" | grep -q -- '--ephemeral' \
488490
&& echo "$captured_args" | grep -q -- 'read-only' \

tests/test-disable-nested-codex-hooks.sh

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -70,14 +70,22 @@ setup_mock_codex() {
7070
mkdir -p "$bin_dir"
7171
cat > "$bin_dir/codex" <<EOF
7272
#!/usr/bin/env bash
73-
# The stop hook probes feature support with \`codex --help\`; advertise
74-
# --disable so the nested invocation is expected to include it.
75-
if [[ "\$1" == "--help" ]]; then
73+
# The stop hook probes feature support with \`codex --help\` and validates each
74+
# known feature with \`codex --disable <feature> --help\`.
75+
if printf '%s\n' "\$@" | grep -qx -- '--help'; then
76+
if [[ "\${1:-}" == "--disable" ]]; then
77+
feature="\${2:-}"
78+
supported_features=" \${MOCK_CODEX_SUPPORTED_FEATURES:-hooks plugin_hooks codex_hooks} "
79+
if [[ "\$supported_features" != *" \$feature "* ]]; then
80+
echo "unknown feature: \$feature" >&2
81+
exit 2
82+
fi
83+
fi
7684
cat <<HELP
7785
Usage: codex [OPTIONS] <COMMAND>
7886
7987
Options:
80-
--disable <HOOK> Disable a specific Codex hook (e.g. hooks)
88+
--disable <HOOK> Disable a specific Codex hook
8189
--skip-git-repo-check Skip git repo validation
8290
HELP
8391
exit 0
@@ -186,13 +194,14 @@ run_loop_hook() {
186194
local repo_dir="$1"
187195
local args_file="$2"
188196
local review_started="$3"
197+
local supported_features="${4:-hooks plugin_hooks codex_hooks}"
189198
local bin_dir="$TEST_DIR/bin-${review_started}"
190199

191200
setup_mock_codex "$bin_dir" "$args_file"
192201
setup_loop_dir "$repo_dir" "$review_started"
193202

194203
set +e
195-
OUTPUT=$(echo '{}' | PATH="$bin_dir:$PATH" CLAUDE_PROJECT_DIR="$repo_dir" bash "$STOP_HOOK" 2>&1)
204+
OUTPUT=$(echo '{}' | MOCK_CODEX_SUPPORTED_FEATURES="$supported_features" PATH="$bin_dir:$PATH" CLAUDE_PROJECT_DIR="$repo_dir" bash "$STOP_HOOK" 2>&1)
196205
EXIT_CODE=$?
197206
set -e
198207

@@ -206,22 +215,22 @@ REPO_IMPL="$TEST_DIR/repo-impl"
206215
setup_repo "$REPO_IMPL"
207216
run_loop_hook "$REPO_IMPL" "$TEST_DIR/impl.args" "false"
208217

209-
if grep -q -- 'exec --disable hooks' "$TEST_DIR/impl.args"; then
210-
pass "implementation-phase stop hook disables hooks for codex exec"
218+
if grep -q -- 'exec --disable hooks --disable plugin_hooks --disable codex_hooks' "$TEST_DIR/impl.args"; then
219+
pass "implementation-phase stop hook disables all known hook features for codex exec"
211220
else
212-
fail "implementation-phase stop hook disables hooks for codex exec" \
213-
"exec --disable hooks" "$(cat "$TEST_DIR/impl.args" 2>/dev/null || echo missing)"
221+
fail "implementation-phase stop hook disables all known hook features for codex exec" \
222+
"exec --disable hooks --disable plugin_hooks --disable codex_hooks" "$(cat "$TEST_DIR/impl.args" 2>/dev/null || echo missing)"
214223
fi
215224

216225
REPO_REVIEW="$TEST_DIR/repo-review"
217226
setup_repo "$REPO_REVIEW"
218227
run_loop_hook "$REPO_REVIEW" "$TEST_DIR/review.args" "true"
219228

220-
if grep -q -- 'review --disable hooks' "$TEST_DIR/review.args"; then
221-
pass "review-phase stop hook disables hooks for codex review"
229+
if grep -q -- 'review --disable hooks --disable plugin_hooks --disable codex_hooks' "$TEST_DIR/review.args"; then
230+
pass "review-phase stop hook disables all known hook features for codex review"
222231
else
223-
fail "review-phase stop hook disables hooks for codex review" \
224-
"review --disable hooks" "$(cat "$TEST_DIR/review.args" 2>/dev/null || echo missing)"
232+
fail "review-phase stop hook disables all known hook features for codex review" \
233+
"review --disable hooks --disable plugin_hooks --disable codex_hooks" "$(cat "$TEST_DIR/review.args" 2>/dev/null || echo missing)"
225234
fi
226235

227236
if ! grep -q 'codex --help 2>&1 | grep -q' "$STOP_HOOK"; then
@@ -250,6 +259,19 @@ else
250259
'must not pass prompt input when `--base` is used' "$(cat "$REVIEW_PROMPT" 2>/dev/null || echo missing)"
251260
fi
252261

262+
REPO_LEGACY="$TEST_DIR/repo-legacy"
263+
setup_repo "$REPO_LEGACY"
264+
run_loop_hook "$REPO_LEGACY" "$TEST_DIR/legacy.args" "false" "codex_hooks"
265+
266+
if grep -q -- 'exec --disable codex_hooks' "$TEST_DIR/legacy.args" \
267+
&& ! grep -q -- '--disable hooks' "$TEST_DIR/legacy.args" \
268+
&& ! grep -q -- 'plugin_hooks' "$TEST_DIR/legacy.args"; then
269+
pass "implementation-phase stop hook disables only supported legacy hook feature"
270+
else
271+
fail "implementation-phase stop hook disables only supported legacy hook feature" \
272+
"exec --disable codex_hooks only" "$(cat "$TEST_DIR/legacy.args" 2>/dev/null || echo missing)"
273+
fi
274+
253275
echo ""
254276
echo "========================================"
255277
echo "Disable Nested Codex Hooks Tests"

0 commit comments

Comments
 (0)