Skip to content

feat(windows): native Codex hook transport (queue + out-of-sandbox dispatcher)#305

Open
So-Mu3 wants to merge 1 commit into
fujibee:mainfrom
So-Mu3:feat/codex-windows-native-hook-transport
Open

feat(windows): native Codex hook transport (queue + out-of-sandbox dispatcher)#305
So-Mu3 wants to merge 1 commit into
fujibee:mainfrom
So-Mu3:feat/codex-windows-native-hook-transport

Conversation

@So-Mu3

@So-Mu3 So-Mu3 commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Problem

Inside the Codex Windows sandbox, msys/cygwin binaries die at startup with fatal error - CreateFileMapping ... Win32 error 5. The commandWindows generated by windows_wrap() launches Git Bash inside that sandbox, so the codex SessionStart/SessionEnd hooks always fail with hook exited with code 1 — regardless of bash path or wrapper tweaks, since any msys child stays inside the sandbox boundary.

Design

Generalizes the existing AGMSG_CODEX_BRIDGE_LAUNCHER request-file pattern (#41) to the whole hook transport:

  • In-sandbox (hook): scripts/windows/hook-enqueue.ps1 — pure PowerShell, no external processes, always exits 0 (fail-open; a broken delivery must never fail the session). Atomically writes one request file (header + hook stdin JSON) to run/hook-queue/, falling back to the project's .agmsg/hook-queue/.
  • Out-of-sandbox (resident): scripts/windows/hook-dispatcher.ps1 — single instance (pidfile), polls the queue dirs (1s), replays each request through Git Bash (session-start.sh / session-end.sh, stored stdin piped through), logs to run/hook-dispatcher.log (1MB truncate). install-hook-dispatcher.ps1 -Register|-Unregister|-Status manages a logon scheduled task.
  • Selection: new type-manifest key hook_windows_transport=queue (codex only). Types without the key keep the legacy windows_wrap() behavior — claude-code is untouched. Stop/turn hooks are out of scope (they need synchronous stdout, which a queue cannot provide).
  • The codex delivery plug maintains run/hook-projects.list (on_enable/on_disable) so the dispatcher knows which projects' fallback queues to watch.

Verification

  • bats tests/test_delivery.bats: 125/125 pass (3 new tests: queue commandWindows generation, legacy fallback regression, project-list add/remove/dedup).
  • End-to-end on Windows 11 + Codex 0.142.5 (real environment): codex exec shows hook: SessionStart Completed, request enqueued in-sandbox and consumed by the dispatcher, session-start.sh exit 0. Before the change the same environment reproducibly failed.

Notes

  • PowerShell scripts pass [ScriptBlock]::Create syntax checks; dispatcher registration requires the user to run install-hook-dispatcher.ps1 -Register once (documented in docs/codex-monitor-beta.md).
  • Hook stdout is not propagated to the session in queue mode; the codex SessionStart path does not rely on it (bridge/request handling only).

🤖 Generated with Claude Code

Route Codex SessionStart and SessionEnd hooks through a native
PowerShell queue so sandboxed sessions do not launch Git Bash directly.
Inside the Codex Windows sandbox, msys/cygwin binaries die at startup
(CreateFileMapping Win32 error 5), so the legacy windows_wrap()
commandWindows always fails with "hook exited with code 1".

The hook now runs scripts/windows/hook-enqueue.ps1 (pure PowerShell,
fail-open, always exit 0), which atomically writes a request file to
run/hook-queue (or the project's .agmsg/hook-queue fallback). An
out-of-sandbox dispatcher (hook-dispatcher.ps1, single instance,
registered as a logon task via install-hook-dispatcher.ps1 -Register)
replays the request through Git Bash where it works.

Selection is manifest-driven (hook_windows_transport=queue, codex only);
types without the key keep the legacy Git Bash wrapper. Stop/turn hooks
are unchanged (they need synchronous stdout). Verified end-to-end on
Windows 11 with Codex 0.142.5: SessionStart Completed, request consumed,
session-start.sh exit 0.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant