feat: register hooks for OpenAI Codex CLI and GitHub Copilot CLI#51
Merged
Conversation
Adds `promptconduit install codex` and `promptconduit install copilot`
(plus matching uninstall) so live event capture covers the two AI tools
we already support transcript sync for.
Codex (6 events at ~/.codex/hooks.json):
- SessionStart, PreToolUse, PermissionRequest, PostToolUse,
UserPromptSubmit, Stop
- Claude-Code-style schema, but timeout is in SECONDS (not millis)
and there is no SessionEnd event in the current spec.
Spec: https://developers.openai.com/codex/hooks
Copilot (13 events at ~/.copilot/hooks/promptconduit.json):
- sessionStart, sessionEnd, userPromptSubmitted, preToolUse,
postToolUse, postToolUseFailure, permissionRequest, agentStop,
subagentStart, subagentStop, errorOccurred, preCompact, notification
- Different schema: {"version": 1, "hooks": {...}} with timeoutSec
and per-handler cross-platform `command` field. Copilot loads every
*.json under ~/.copilot/hooks/, so we own a single dedicated file
(promptconduit.json) — uninstall is just `rm`, no merge/strip
dance needed.
Spec: https://docs.github.com/en/copilot/reference/copilot-cli-reference/cli-hooks-reference
Critical wrinkle handled: Codex's hook payload uses `hook_event_name`,
the same field name as Claude Code, so the existing detectTool
heuristic in cmd/hook.go would otherwise mistag Codex events as
"claude-code". Add a `--tool <name>` flag to the hidden hook
subcommand; install bakes `--tool codex` / `--tool copilot` into the
registered command. Precedence: --tool flag > PROMPTCONDUIT_TOOL env
var > field-presence heuristic. Verified end-to-end against the debug
file log:
[...] Detected tool: codex, hook event: UserPromptSubmit
[...] Created envelope: tool=codex, event=UserPromptSubmit
Tools enum updated in internal/envelope to include "codex" and
"copilot". install/uninstall dispatchers and Long-form help updated.
README "Real-time hooks" table expanded.
Smoke-tested in a fake $HOME:
- install codex → 6 events written, --tool flag in every command
- install copilot → 13 events written, --tool flag in every command,
version:1 wrapper, timeoutSec:30
- uninstall codex → 6 hooks removed
- uninstall copilot → file deleted, ENOENT on second uninstall is
handled gracefully
https://claude.ai/code/session_019CWBC2E8pQuShejfsKYrvp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
promptconduit install codexandpromptconduit install copilot(plus matching uninstall), bringing live event capture to the two AI tools we already support transcript sync for. Closes the "tools we don't support at all" item from the session-running plan.Codex CLI — 6 events at
~/.codex/hooks.jsonPer the canonical spec:
SessionStartstartup|resume|clearPreToolUsePermissionRequestPostToolUseUserPromptSubmitStopClaude-Code-style nested schema, but
timeoutis in seconds (not millis), and the spec has noSessionEndevent.Copilot CLI — 13 events at
~/.copilot/hooks/promptconduit.jsonPer the canonical spec:
sessionStart/sessionEnduserPromptSubmittedpreToolUsepostToolUse/postToolUseFailurepermissionRequestagentStop/subagentStart(agent name) /subagentStoperrorOccurredpreCompactmanual|autonotificationDifferent schema from the other tools:
{"version": 1, "hooks": {...}},timeoutSecnottimeout, per-handler cross-platformcommandfield (we use that single field rather than separatebash/powershell). Copilot loads every*.jsonunder~/.copilot/hooks/, so we own a dedicatedpromptconduit.json— uninstall is justrm, no merge/strip dance.Critical wrinkle: tool detection
Codex's hook payload uses
hook_event_name— the same field name as Claude Code — so the existingdetectToolheuristic incmd/hook.gowould mistag Codex events as"claude-code". Fix: add a--tool <name>flag to the hiddenhooksubcommand and have the install commands bake--tool codex/--tool copilotinto the registered command line.Precedence:
--toolflag >PROMPTCONDUIT_TOOLenv var > existing field-presence heuristic. Existing tools (Claude Code / Cursor / Gemini) are untouched — they continue to be auto-detected.Test plan
go build ./... && go vet ./... && go test ./...cleaninstall codexagainst a fake$HOMEwrites 6 events to~/.codex/hooks.json, each command has--tool codexinstall copilotwrites 13 events withversion: 1,timeoutSec: 30,--tool copilotin every commanduninstall codexremoves 6 hooks;uninstall copilotdeletes the file; seconduninstall copilotreturns cleanly on ENOENThook --tool codexwith debug enabled, confirmed via/tmp/promptconduit-hook.logthatDetected tool: codexandCreated envelope: tool=codex, event=UserPromptSubmitSession running plan — status
WorktreeCreate— decided "skip it (status quo)" — no code change; observability still available via SessionStart's cwdThat closes the hook-coverage epic for now.
https://claude.ai/code/session_019CWBC2E8pQuShejfsKYrvp
Generated by Claude Code