Skip to content
92 changes: 92 additions & 0 deletions codex-rs/core/config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,82 @@
}
]
},
"HookEntryToml": {
"description": "Single hook entry from configuration.",
"properties": {
"command": {
"description": "The command to execute as argv (program + args).",
"items": {
"type": "string"
},
"type": "array"
},
"matcher": {
"default": null,
"description": "Optional matcher pattern for tool-use hooks.\n\nSupported patterns: - `\"*\"` matches any tool name - `\"prefix*\"` matches tool names starting with `prefix` - `\"exact\"` matches only that exact tool name\n\nNote: suffix patterns like `\"*shell\"` and infix patterns like `\"read_*_file\"` are **not** supported.",
"type": "string"
},
"timeout": {
"default": 30,
"description": "Optional timeout in seconds (default: 30).",
"format": "uint64",
"minimum": 0.0,
"type": "integer"
}
},
"required": [
"command"
],
"type": "object"
},
"HooksConfigToml": {
"description": "All hook entries grouped by event type.",
"properties": {
"after_agent": {
"default": [],
"items": {
"$ref": "#/definitions/HookEntryToml"
},
"type": "array"
},
"notification": {
"default": [],
"items": {
"$ref": "#/definitions/HookEntryToml"
},
"type": "array"
},
"post_tool_use": {
"default": [],
"items": {
"$ref": "#/definitions/HookEntryToml"
},
"type": "array"
},
"pre_tool_use": {
"default": [],
"items": {
"$ref": "#/definitions/HookEntryToml"
},
"type": "array"
},
"stop": {
"default": [],
"items": {
"$ref": "#/definitions/HookEntryToml"
},
"type": "array"
},
"user_prompt_submit": {
"default": [],
"items": {
"$ref": "#/definitions/HookEntryToml"
},
"type": "array"
}
},
"type": "object"
},
"ModeKind": {
"description": "Initial collaboration mode to use when the TUI starts.",
"enum": [
Expand Down Expand Up @@ -1379,6 +1455,22 @@
"default": null,
"description": "Settings that govern if and what will be written to `~/.codex/history.jsonl`."
},
"hooks": {
"allOf": [
{
"$ref": "#/definitions/HooksConfigToml"
}
],
"default": {
"after_agent": [],
"notification": [],
"post_tool_use": [],
"pre_tool_use": [],
"stop": [],
"user_prompt_submit": []
},
"description": "Hook definitions grouped by event type. Each hook specifies a command to execute and optionally a matcher pattern for tool-use events."
},
"instructions": {
"description": "System instructions.",
"type": "string"
Expand Down
13 changes: 13 additions & 0 deletions codex-rs/core/src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,9 @@ pub struct Config {
/// If unset the feature is disabled.
pub notify: Option<Vec<String>>,

/// Hook definitions loaded from config.toml `[hooks]` section.
pub hooks: crate::hooks::config::HooksConfigToml,

/// TUI notifications preference. When set, the TUI will send terminal notifications on
/// approvals and turn completions when not focused.
pub tui_notifications: Notifications,
Expand Down Expand Up @@ -869,6 +872,11 @@ pub struct ConfigToml {
#[serde(default)]
pub notify: Option<Vec<String>>,

/// Hook definitions grouped by event type. Each hook specifies a command
/// to execute and optionally a matcher pattern for tool-use events.
#[serde(default)]
pub hooks: crate::hooks::config::HooksConfigToml,

/// System instructions.
pub instructions: Option<String>,

Expand Down Expand Up @@ -1694,6 +1702,7 @@ impl Config {
forced_auto_mode_downgraded_on_windows,
shell_environment_policy,
notify: cfg.notify,
hooks: cfg.hooks,
user_instructions,
base_instructions,
personality,
Expand Down Expand Up @@ -4008,6 +4017,7 @@ model_verbosity = "high"
shell_environment_policy: ShellEnvironmentPolicy::default(),
user_instructions: None,
notify: None,
hooks: Default::default(),
cwd: fixture.cwd(),
cli_auth_credentials_store_mode: Default::default(),
mcp_servers: Constrained::allow_any(HashMap::new()),
Expand Down Expand Up @@ -4096,6 +4106,7 @@ model_verbosity = "high"
shell_environment_policy: ShellEnvironmentPolicy::default(),
user_instructions: None,
notify: None,
hooks: Default::default(),
cwd: fixture.cwd(),
cli_auth_credentials_store_mode: Default::default(),
mcp_servers: Constrained::allow_any(HashMap::new()),
Expand Down Expand Up @@ -4199,6 +4210,7 @@ model_verbosity = "high"
shell_environment_policy: ShellEnvironmentPolicy::default(),
user_instructions: None,
notify: None,
hooks: Default::default(),
cwd: fixture.cwd(),
cli_auth_credentials_store_mode: Default::default(),
mcp_servers: Constrained::allow_any(HashMap::new()),
Expand Down Expand Up @@ -4288,6 +4300,7 @@ model_verbosity = "high"
shell_environment_policy: ShellEnvironmentPolicy::default(),
user_instructions: None,
notify: None,
hooks: Default::default(),
cwd: fixture.cwd(),
cli_auth_credentials_store_mode: Default::default(),
mcp_servers: Constrained::allow_any(HashMap::new()),
Expand Down
2 changes: 2 additions & 0 deletions codex-rs/core/src/function_tool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@ pub enum FunctionCallError {
MissingLocalShellCallId,
#[error("Fatal error: {0}")]
Fatal(String),
#[error("Tool call blocked: {0}")]
ToolCallBlocked(String),
}
Loading