mirror of
https://github.com/EveryInc/compound-engineering-plugin.git
synced 2026-06-19 15:41:46 +02:00
ac672f4715
Codex has been incrementally shipping hook support (PreToolUse, PostToolUse, UserPromptSubmit, SessionStart, Stop), but the Codex converter silently dropped all hooks during conversion -- the only converter that didn't even warn. This adds partial hook conversion for the 5 compatible events and specific warnings for everything unconvertible. - Add CodexHookEventName union, CodexHookCommand, CodexHookMatcher, CodexHooks types and hooks field to CodexBundle - Add CODEX_EVENTS map with toolScoped flag, isBashCompatibleMatcher() helper, and convertHooksForCodex() to the converter - Write .codex/hooks.json with backup support in the writer - Auto-enable [features] codex_hooks = true in config.toml when hooks present - Refactor renderCodexConfig() to options object for extensibility - Update Codex spec with hooks documentation - 18 new tests (12 converter + 6 writer) PostToolUse conversion depends on openai/codex#15531 merging.
6.5 KiB
6.5 KiB
Codex Spec (Config, Prompts, Skills, MCP)
Last verified: 2026-03-23
Primary sources
https://developers.openai.com/codex/config-basic
https://developers.openai.com/codex/config-advanced
https://developers.openai.com/codex/custom-prompts
https://developers.openai.com/codex/skills
https://developers.openai.com/codex/skills/create-skill
https://developers.openai.com/codex/guides/agents-md
https://developers.openai.com/codex/mcp
Config location and precedence
- Codex reads local settings from
~/.codex/config.toml, shared by the CLI and IDE extension. citeturn2view0 - Configuration precedence is: CLI flags -> profile values -> root-level values in
config.toml-> built-in defaults. citeturn2view0 - Codex stores local state under
CODEX_HOME(defaults to~/.codex) and includesconfig.tomlthere. citeturn4view0
Profiles and providers
- Profiles are defined under
[profiles.<name>]and selected withcodex --profile <name>. citeturn4view0 - A top-level
profile = "<name>"sets the default profile; CLI flags can override it. citeturn4view0 - Profiles are experimental and not supported in the IDE extension. citeturn4view0
- Custom model providers can be defined with base URL, wire API, and optional headers, then referenced via
model_provider. citeturn4view0
Custom prompts (slash commands)
- Custom prompts are Markdown files stored under
~/.codex/prompts/. citeturn3view0 - Custom prompts require explicit invocation and aren't shared through the repository; use skills to share or auto-invoke. citeturn3view0
- Prompts are invoked as
/prompts:<name>in the slash command UI. citeturn3view0 - Prompt front matter supports
description:andargument-hint:. citeturn3view0turn2view3 - Prompt arguments support
$1-$9,$ARGUMENTS, and named placeholders like$FILEprovided asKEY=value. citeturn2view3 - Codex ignores non-Markdown files in the prompts directory. citeturn2view3
AGENTS.md instructions
- Codex reads
AGENTS.mdfiles before doing any work and builds a combined instruction chain. citeturn3view1 - Discovery order: global (
~/.codex, usingAGENTS.override.mdthenAGENTS.md) then project directory traversal from repo root to CWD, with override > AGENTS > fallback names. citeturn3view1 - Codex concatenates files from root down; files closer to the working directory appear later and override earlier guidance. citeturn3view1
Skills (Agent Skills)
- A skill is a folder containing
SKILL.mdplus optionalscripts/,references/, andassets/. citeturn3view3turn3view4 SKILL.mduses YAML front matter and requiresnameanddescription. citeturn3view3turn3view4- Required fields are single-line with length limits (name <= 100 chars, description <= 500 chars). citeturn3view4
- At startup, Codex loads only each skill's name/description; full content is injected when invoked. citeturn3view3turn3view4
- Skills can be repo-scoped in
.agents/skills/and are discovered from the current working directory up to the repository root. User-scoped skills live in~/.agents/skills/. citeturn1view1turn1view4 - Inference: some existing tooling and user setups still use
.codex/skills/and~/.codex/skills/as legacy compatibility paths, but those locations are not documented in the current OpenAI Codex skills docs linked above. - Codex also supports admin-scoped skills in
/etc/codex/skillsplus built-in system skills bundled with Codex. citeturn1view4 - Skills can be invoked explicitly using
/skillsor$skill-name. citeturn3view3
MCP (Model Context Protocol)
- MCP configuration lives in
~/.codex/config.tomland is shared by the CLI and IDE extension. citeturn3view2turn3view5 - Each server is configured under
[mcp_servers.<server-name>]. citeturn3view5 - STDIO servers support
command(required),args,env,env_vars, andcwd. citeturn3view5 - Streamable HTTP servers support
url(required),bearer_token_env_var,http_headers, andenv_http_headers. citeturn3view5
Hooks
Codex supports lifecycle hooks via hooks.json, discovered at project level (.codex/hooks.json), user level (~/.codex/hooks.json), and system level (/etc/codex/hooks.json). Hooks must be enabled with codex_hooks = true under [features] in config.toml.
Supported events
| Event | Scope | Capabilities | Upstream PR |
|---|---|---|---|
| PreToolUse | Shell/Bash only | Deny-only decisions; tool name hardcoded to "Bash" | #15211 (merged) |
| PostToolUse | Shell/Bash only | Block + additionalContext; updatedMCPToolOutput rejected |
#15531 (draft) |
| UserPromptSubmit | All prompts | Block + additionalContext; no matchers; blocked prompts never enter history | #14626 (merged) |
| SessionStart | Session lifecycle | additionalContext + should_stop/stop_reason | Exists on main |
| Stop | Session lifecycle | Fires at session end | Exists on main |
hooks.json format
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{ "type": "command", "command": "echo before", "timeout": 30 }
]
}
],
"UserPromptSubmit": [
{
"hooks": [
{ "type": "command", "command": "echo prompt" }
]
}
]
}
}
Converter behavior
- Only
commandtype hooks are converted;promptandagenttypes are skipped with warnings - PreToolUse/PostToolUse matchers must be Bash-compatible (undefined,
*,"",Bash,^Bash$); non-Bash matchers are skipped - Mixed matchers (e.g.
Bash|Write) are skipped entirely - Wildcard matchers on tool-scoped events are normalized to
"Bash" - Non-tool-scoped events (UserPromptSubmit, SessionStart, Stop) omit the
matcherfield - Unsupported events (PostToolUseFailure, PermissionRequest, Notification, SessionEnd, PreCompact, Setup, SubagentStart, SubagentStop) are skipped with warnings
Constraints
- Only
type: "command"hooks are supported (nopromptoragenttypes) - Feature-gated behind
codex_hooks = trueinconfig.toml[features] deny_unknown_fieldson all wire types -- extra fields cause parse failure- Fail-open design: unsupported outputs, malformed JSON, non-zero/non-2 exit codes all resolve to "allow"
- No Windows support (entire hook system disabled)
- No async hooks (
async: trueis recognized but skipped with a warning) - PreToolUse only supports deny decisions (allow/ask/updatedInput/additionalContext all fail open)
- Context injection uses developer messages (not user messages)