Expose execution mode in hook listings (#37538)

## What changed

- Add `executionMode` to `HookMetadata` returned by `hooks/list`, with `sync` as the default for compatibility.
- Propagate each discovered hook's `sync` or `async` mode through the app-server protocol and generated schemas.
- Show the execution mode in the TUI hooks browser.

## Testing

- Cover async and default-sync modes in `hooks/list` tests and TUI snapshots.

GitOrigin-RevId: 9c9f2890798fe417face76c15847616b2dea9db4
This commit is contained in:
Abhinav authored and copyberry committed 2026-08-08 04:57:06 +00:00
1 parent 6f647caa9b
commit 3aae5d885b
23 files changed
+75 -3

No files matched your search

@@ -1,4 +1,5 @@
use codex_app_server_protocol::HookEventName;
use codex_app_server_protocol::HookExecutionMode;
use codex_app_server_protocol::HookMetadata;
use codex_app_server_protocol::HookSource;
use codex_app_server_protocol::HookTrustStatus;
@@ -492,6 +493,11 @@ impl HooksBrowserView {
width,
Some(MAX_COMMAND_DETAIL_LINES),
));
let execution_mode = match hook.execution_mode {
HookExecutionMode::Sync => "Sync",
HookExecutionMode::Async => "Async",
};
lines.push(detail_line("Mode", execution_mode));
lines.push(detail_line("Timeout", &format!("{}s", hook.timeout_sec)));
if let Some(limit) = hook.additional_context_limit {
let value = if limit == 0 {
@@ -883,6 +889,7 @@ mod tests {
use crate::test_support::test_path_display;
use codex_app_server_protocol::HookErrorInfo;
use codex_app_server_protocol::HookEventName;
use codex_app_server_protocol::HookExecutionMode;
use codex_app_server_protocol::HookHandlerType;
use codex_app_server_protocol::HookMetadata;
use codex_app_server_protocol::HookSource;
@@ -947,6 +954,7 @@ mod tests {
key: key.to_string(),
event_name,
handler_type: HookHandlerType::Command,
execution_mode: HookExecutionMode::Sync,
is_managed,
matcher: Some("Bash".to_string()),
command: Some(command.to_string()),
@@ -1142,6 +1150,7 @@ mod tests {
/*display_order*/ 0,
);
untrusted_hook.trust_status = HookTrustStatus::Untrusted;
untrusted_hook.execution_mode = HookExecutionMode::Async;
let mut view = HooksBrowserView::new(
vec![untrusted_hook],
Vec::new(),
@@ -12,6 +12,7 @@ expression: "render_lines(&view, 112)"
Matcher Bash
Source User config - /tmp/hooks.json
Command /tmp/pre-tool-use.sh
Mode Sync
Timeout 30s
Context unlimited
Trust Trusted
@@ -14,6 +14,7 @@ expression: "render_lines(&view, 44)"
Command one two three four five six
seven eight nine ten eleven
twelve thirteen fourteen…
Mode Sync
Timeout 30s
Trust Trusted
@@ -13,6 +13,7 @@ expression: "render_lines(&view, 112)"
Matcher Bash
Source Plugin - superpowers@openai-curated
Command ${CODEX_PLUGIN_ROOT}/hooks/pre-tool-use-check.sh
Mode Sync
Timeout 30s
Trust Trusted
@@ -12,6 +12,7 @@ expression: "render_lines(&view, 112)"
Matcher Bash
Source Admin config
Command /enterprise/hooks/permission-check.sh
Mode Sync
Timeout 30s
Trust Managed
@@ -12,6 +12,7 @@ expression: "render_lines(&view, 112)"
Matcher Bash
Source User config - /tmp/hooks.json
Command /tmp/pre-tool-use-check.sh
Mode Sync
Timeout 30s
Trust New hook - review required
@@ -19,6 +19,7 @@ expression: "render_lines(&view, 112)"
Matcher Bash
Source User config - /tmp/hooks.json
Command /tmp/hook-8.sh
Mode Sync
Timeout 30s
Trust Trusted
@@ -13,6 +13,7 @@ expression: "render_lines(&view, 112)"
Matcher Bash
Source Admin config
Command /enterprise/hooks/pre-tool-use-2.sh
Mode Sync
Timeout 30s
Trust Managed
@@ -12,6 +12,7 @@ expression: "render_lines(&view, 112)"
Matcher Bash
Source User config - /tmp/hooks.json
Command ~/bin/untrusted.sh
Mode Async
Timeout 30s
Trust New hook - review required