fix: support Codex CLI 0.142 hook schema

This commit is contained in:
thanhnv
2026-07-24 16:49:44 +07:00
parent 6804fd14f4
commit 353d87b6ae
6 changed files with 50 additions and 8 deletions
@@ -184,6 +184,7 @@ echo "$CODEX_BEGIN" | grep -q '"continue": true' && pass "Codex generated hook o
python3 - "$PROJ/.codex/hooks.json" <<'PY' && pass "Codex hooks use the current schema and project-relative bootstrap" || fail "Codex hook contract is stale"
import json,sys
d=json.load(open(sys.argv[1]))
assert set(d) == {"hooks"}
handlers=[h for groups in d["hooks"].values() for group in groups for h in group["hooks"]]
assert handlers and all(h.get("type") == "command" for h in handlers)
assert all(isinstance(h.get("command"), str) for h in handlers)
@@ -241,6 +242,16 @@ EXP="$WORK/existing"; mkdir -p "$EXP/.claude/agents" "$EXP/.claude/skills" "$EXP
cat > "$EXP/.claude/settings.json" <<'EOF'
{ "model": "claude-opus-4-8", "hooks": { "PreToolUse": [ {"matcher":"*","hooks":[{"type":"command","command":"my-existing-hook.sh"}]} ] } }
EOF
cat > "$EXP/.codex/hooks.json" <<'EOF'
{
"description": "CASAN Plan-20 lifecycle hooks. Review with /hooks; the project bootstrap resolves and verifies the pinned global harness.",
"hooks": {
"PreToolUse": [
{"matcher":"*","hooks":[{"type":"command","command":"my-existing-codex-hook.sh"}]}
]
}
}
EOF
echo "agent" > "$EXP/.claude/agents/reviewer.md"; echo "skill" > "$EXP/.claude/skills/deploy.md"
printf '[hooks]\nenabled = true\n\n[mytool]\nfoo = 1\n' > "$EXP/.codex/config.toml"
( cd "$EXP" && "$CASAN" init --project existing-app >/dev/null 2>&1 )
@@ -255,6 +266,17 @@ PY
py_check "$EXP/.claude/settings.json" "my-existing-hook" && pass "existing Claude hook preserved (not clobbered)" || fail "existing hook clobbered"
py_check "$EXP/.claude/settings.json" "casan-hook.py" && pass "CASAN Claude hook merged in" || fail "CASAN hook not merged"
[ "$(python3 -c 'import json;print(json.load(open("'"$EXP"'/.claude/settings.json")).get("model"))')" = "claude-opus-4-8" ] && pass "unrelated settings key (model) preserved" || fail "model key lost"
py_check "$EXP/.codex/hooks.json" "my-existing-codex-hook" && pass "existing Codex hook preserved (not clobbered)" || fail "existing Codex hook clobbered"
python3 - "$EXP/.codex/hooks.json" <<'PY' \
&& pass "obsolete CASAN description migrated for Codex 0.142.5 compatibility" \
|| fail "obsolete Codex description was retained"
import json
import sys
d = json.load(open(sys.argv[1], encoding="utf-8"))
assert "description" not in d
assert set(d) == {"hooks"}
PY
grep -q '\[mytool\]' "$EXP/.codex/config.toml" && pass "existing codex [mytool] preserved" || fail "mytool lost"
[ "$(grep -c '^\[hooks\]' "$EXP/.codex/config.toml")" = "1" ] && pass "codex config.toml has no duplicate [hooks] table" || fail "duplicate [hooks]"
# idempotent