You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Observed when a Codex coding session opens in Crow:
cd /Users/danny/Projects/devroot/rm/crow-491-reinstall-skill-button && /Users/danny/.nvm/versions/node/v22.22.2/bin/codex
⚠ `[features].codex_hooks` is deprecated. Use `[features].hooks` instead.
Enable it with `--enable hooks` or `[features].hooks` in config.toml.
╭───────────────────────────────────────────────────╮
│ >_ OpenAI Codex (v0.139.0) │
│ model: gpt-5.5 medium /model to change │
│ directory: ~/…/rm/crow-491-reinstall-skill-button │
╰───────────────────────────────────────────────────╯
⚠ skipping async hook in /Users/danny/.codex/hooks.json: async hooks are not supported yet
⚠ skipping async hook in /Users/danny/.codex/hooks.json: async hooks are not supported yet
Two distinct bugs, one launch flow, both in Packages/CrowCodex/Sources/CrowCodex/OpenAICodexAgent.swift and its hook writer.
Bug 1: Codex launches with no prompt — agent sits idle waiting for the user to type
Root cause:OpenAICodexAgent.autoLaunchCommand(...) returns a bare "codex\n" (see the existing code path that I read in earlier diagnostics — function around line 47-64 in current HEAD). The inline comment even says "Bare codex launch — the user types their prompt into the TUI." That was an MVP choice when Codex support was first added — but it makes Codex coding sessions functionally non-autonomous: Crow opens the worktree, Codex starts, no prompt is delivered, the agent just waits at an empty TUI for the user to paste in the ticket context manually.
By comparison, the Claude Code launcher feeds the agent a prompt via claude --permission-mode plan "$(cat <prompt-file>)" (see crow-workspace/setup.sh and Claude's autoLaunchCommand). The Codex equivalent should send the same prompt content into Codex's CLI so the session starts already working.
Fix shape:
Confirm via codex --help which entry point accepts a non-interactive prompt — likely codex exec "<prompt>" (one-shot) or a positional/--message form for the interactive TUI. From the Codex docs, codex (interactive TUI) accepts an initial message as a positional argument: codex "your prompt here". Update OpenAICodexAgent.autoLaunchCommand to:
publicfunc autoLaunchCommand(
session:Session,
worktreePath:String,...)->String?{guard session.kind ==.work else{returnnil}
// Read the same prompt file Claude's path uses — same content, same location.
letpromptPath="\(devRoot)/.claude/prompts/crow-prompt-\(session.name).md"
// Codex takes an initial positional message. Quote and escape so multi-line
// content + shell metacharacters reach the CLI intact. Newline at the end
// submits.
return"codex \"$(cat \(posixQuote(promptPath)))\"\n"}
If the positional doesn't accept the full prompt body cleanly (size limits, multiline), fall back to codex exec with the prompt file via stdin: codex exec < <prompt-file> (then the session runs the prompt non-interactively, completes the round, exits — not ideal for an interactive session but workable for one-shot work).
Acceptance for Bug 1:
Launching a Codex coding session against any ticket opens the Codex TUI with the ticket's prompt already submitted as the first message. Codex starts working without the user typing anything.
The prompt content matches what the Claude Code path would have sent (same crow-prompt-<session>.md source).
session.kind == .review still returns nil (review-on-Codex is still gated out, per the existing comment).
⚠ [features].codex_hooks is deprecated. Use [features].hooks instead. — Codex CLI evolved its config.toml feature-flag name; Crow's hook config writer still uses the old key.
⚠ skipping async hook in /Users/danny/.codex/hooks.json: async hooks are not supported yet (×2) — Crow declares async hooks (probably to mirror Claude Code's hook pattern), but Codex's hook system is sync-only. The hooks Crow registered are being silently no-op'd every launch.
Root cause:OpenAICodexAgent.swift references a hookConfigWriter: any HookConfigWriter = CodexHookConfigWriter() (see line 16 area). That writer is what produces:
Whatever updates ~/.codex/config.toml for the feature flag.
~/.codex/hooks.json with the hook definitions.
Both writes need updating to match current Codex CLI (v0.139.0):
config.toml feature flag — change [features].codex_hooks to [features].hooks. If the writer is the source of that key, fix the key it writes. If the user wrote it manually (legacy from a previous Crow install), the writer should detect a codex_hooks = … value on read, migrate to hooks = …, and remove the legacy key.
hooks.json async declarations — find the hook definitions Crow writes (likely in CodexHookConfigWriter.swift), drop the async: true (or whatever Crow flags those hooks with), or omit them entirely if they only make sense as async. If Crow's session-state plumbing relies on those hooks firing to detect activity/completion, those signals are silently lost today — the Codex session state from Crow's POV may be unreliable.
Document why these hooks exist. The codex hooks Crow registers are presumably about detecting agent state for the same purposes ClaudeCodeAgent uses hooks (auto-respond, completion detection, the card-color update from Cursor sessions don't update card color on completion (status indicator stuck) #428). If the async hooks are being silently dropped today, those features are silently broken for Codex sessions even when the agent does run. Worth verifying alongside this fix.
Acceptance for Bug 2:
A fresh Crow launch with Codex configured produces no [features].codex_hooks is deprecated warning from Codex's startup.
No ⚠ skipping async hook ... warnings — either all Codex hooks are sync (and registered correctly), or the unsupported hooks are removed from hooks.json so Codex doesn't see them.
Whatever session-state signals Crow expects from Codex's hooks (state, agent-waiting events, completion) actually fire — verify the auto-respond and card-color flows work for a Codex session, not just for Claude Code.
Migrate legacy [features].codex_hooks entries in user config.toml: read, rename to hooks, log a one-line migration notice. Idempotent — running twice is a no-op the second time.
Critical files
Purpose
Path
Agent launcher (Bug 1)
Packages/CrowCodex/Sources/CrowCodex/OpenAICodexAgent.swift (autoLaunchCommand, ~lines 47-64 of current HEAD)
Hook config writer (Bug 2)
Packages/CrowCodex/Sources/CrowCodex/CodexHookConfigWriter.swift (or wherever the conformer to HookConfigWriter lives for Codex)
Prompt-file convention to mirror
Packages/CrowClaude/Sources/CrowClaude/ClaudeCodeAgent.swift + crow/skills/crow-workspace/setup.sh:572 for the crow-prompt-<session>.md path
Where codex --help confirms the CLI form
Local — runtime check, no source path
Out of scope
Codex-as-reviewer (still gated to .work per the existing guard). Reviews-on-Codex is its own ticket if/when it makes sense.
Sync vs async hook architecture redesign — this ticket just gets Crow back to a working state with Codex's current sync-only hook model. If Crow's auto-respond integration needs async semantics that Codex doesn't support, that's a follow-up with Codex's roadmap, not this ticket.
Cursor sessions don't update card color on completion (status indicator stuck) #428 — Cursor session card color doesn't update on completion. Identical category of problem to Bug 2's "async hooks silently dropped, so completion detection is silently broken." Worth checking if Codex sessions have the same card-color drift after this lands.
Observed when a Codex coding session opens in Crow:
Two distinct bugs, one launch flow, both in
Packages/CrowCodex/Sources/CrowCodex/OpenAICodexAgent.swiftand its hook writer.Bug 1: Codex launches with no prompt — agent sits idle waiting for the user to type
Root cause:
OpenAICodexAgent.autoLaunchCommand(...)returns a bare"codex\n"(see the existing code path that I read in earlier diagnostics — function around line 47-64 in current HEAD). The inline comment even says "Barecodexlaunch — the user types their prompt into the TUI." That was an MVP choice when Codex support was first added — but it makes Codex coding sessions functionally non-autonomous: Crow opens the worktree, Codex starts, no prompt is delivered, the agent just waits at an empty TUI for the user to paste in the ticket context manually.By comparison, the Claude Code launcher feeds the agent a prompt via
claude --permission-mode plan "$(cat <prompt-file>)"(seecrow-workspace/setup.shand Claude'sautoLaunchCommand). The Codex equivalent should send the same prompt content into Codex's CLI so the session starts already working.Fix shape:
Confirm via
codex --helpwhich entry point accepts a non-interactive prompt — likelycodex exec "<prompt>"(one-shot) or a positional/--messageform for the interactive TUI. From the Codex docs,codex(interactive TUI) accepts an initial message as a positional argument:codex "your prompt here". UpdateOpenAICodexAgent.autoLaunchCommandto:If the positional doesn't accept the full prompt body cleanly (size limits, multiline), fall back to
codex execwith the prompt file via stdin:codex exec < <prompt-file>(then the session runs the prompt non-interactively, completes the round, exits — not ideal for an interactive session but workable for one-shot work).Acceptance for Bug 1:
crow-prompt-<session>.mdsource).session.kind == .reviewstill returnsnil(review-on-Codex is still gated out, per the existing comment).Bug 2: Crow writes deprecated
[features].codex_hooks+ async hooks Codex can't runSymptoms (from the launch above):
⚠ [features].codex_hooks is deprecated. Use [features].hooks instead.— Codex CLI evolved itsconfig.tomlfeature-flag name; Crow's hook config writer still uses the old key.⚠ skipping async hook in /Users/danny/.codex/hooks.json: async hooks are not supported yet(×2) — Crow declares async hooks (probably to mirror Claude Code's hook pattern), but Codex's hook system is sync-only. The hooks Crow registered are being silently no-op'd every launch.Root cause:
OpenAICodexAgent.swiftreferences ahookConfigWriter: any HookConfigWriter = CodexHookConfigWriter()(see line 16 area). That writer is what produces:~/.codex/config.tomlfor the feature flag.~/.codex/hooks.jsonwith the hook definitions.Both writes need updating to match current Codex CLI (v0.139.0):
config.tomlfeature flag — change[features].codex_hooksto[features].hooks. If the writer is the source of that key, fix the key it writes. If the user wrote it manually (legacy from a previous Crow install), the writer should detect acodex_hooks = …value on read, migrate tohooks = …, and remove the legacy key.hooks.jsonasync declarations — find the hook definitions Crow writes (likely inCodexHookConfigWriter.swift), drop theasync: true(or whatever Crow flags those hooks with), or omit them entirely if they only make sense as async. If Crow's session-state plumbing relies on those hooks firing to detect activity/completion, those signals are silently lost today — the Codex session state from Crow's POV may be unreliable.Document why these hooks exist. The codex hooks Crow registers are presumably about detecting agent state for the same purposes ClaudeCodeAgent uses hooks (auto-respond, completion detection, the card-color update from Cursor sessions don't update card color on completion (status indicator stuck) #428). If the async hooks are being silently dropped today, those features are silently broken for Codex sessions even when the agent does run. Worth verifying alongside this fix.
Acceptance for Bug 2:
[features].codex_hooks is deprecatedwarning from Codex's startup.⚠ skipping async hook ...warnings — either all Codex hooks are sync (and registered correctly), or the unsupported hooks are removed fromhooks.jsonso Codex doesn't see them.[features].codex_hooksentries in user config.toml: read, rename tohooks, log a one-line migration notice. Idempotent — running twice is a no-op the second time.Critical files
Packages/CrowCodex/Sources/CrowCodex/OpenAICodexAgent.swift(autoLaunchCommand, ~lines 47-64 of current HEAD)Packages/CrowCodex/Sources/CrowCodex/CodexHookConfigWriter.swift(or wherever the conformer toHookConfigWriterlives for Codex)Packages/CrowClaude/Sources/CrowClaude/ClaudeCodeAgent.swift+crow/skills/crow-workspace/setup.sh:572for thecrow-prompt-<session>.mdpathcodex --helpconfirms the CLI formOut of scope
.workper the existing guard). Reviews-on-Codex is its own ticket if/when it makes sense.Related
autoLaunchCommandhas the same issue, fix it in parallel under that ticket or roll it in here.defaults.binaries. Adjacent (where the binary lives) but separate from this ticket (how Crow invokes it).🐦⬛ Created with Crow via Claude Code