mirror of
https://github.com/openai/codex.git
synced 2026-06-01 19:02:59 +00:00
Show plugin hooks in plugin details (#21447)
Supersedes the abandoned #19859, rebuilt on latest `main`. # Why PR #19705 adds discovery for hooks bundled with plugins, but `/plugins` still only shows skills, apps, and MCP servers. This follow-up makes bundled hooks visible in the same plugin detail view so users can inspect the full plugin surface in one place. We also need `PluginHookSummary` to populate Plugin Hooks in the app; `hooks/list` is not enough there because plugin detail needs to show hooks for disabled plugins too. # What - extend `plugin/read` with `PluginHookSummary` entries for bundled hooks - summarize plugin hooks while loading plugin details - render a `Hooks` row in the `/plugins` detail popup <img width="3456" height="848" alt="CleanShot 2026-04-27 at 11 45 34@2x" src="https://github.com/user-attachments/assets/fe3a38d6-a260-4351-8513-fb04c93d725b" />
This commit is contained in:
@@ -17,6 +17,7 @@ use axum::http::Uri;
|
||||
use axum::http::header::AUTHORIZATION;
|
||||
use axum::routing::get;
|
||||
use codex_app_server_protocol::AppInfo;
|
||||
use codex_app_server_protocol::HookEventName;
|
||||
use codex_app_server_protocol::JSONRPCResponse;
|
||||
use codex_app_server_protocol::PluginAuthPolicy;
|
||||
use codex_app_server_protocol::PluginInstallPolicy;
|
||||
@@ -778,6 +779,7 @@ async fn plugin_read_returns_plugin_details_with_bundle_contents() -> Result<()>
|
||||
std::fs::create_dir_all(repo_root.path().join(".git"))?;
|
||||
std::fs::create_dir_all(repo_root.path().join(".agents/plugins"))?;
|
||||
std::fs::create_dir_all(plugin_root.join(".codex-plugin"))?;
|
||||
std::fs::create_dir_all(plugin_root.join("hooks"))?;
|
||||
std::fs::create_dir_all(plugin_root.join("skills/thread-summarizer"))?;
|
||||
std::fs::create_dir_all(plugin_root.join("skills/chatgpt-only"))?;
|
||||
std::fs::write(
|
||||
@@ -881,12 +883,44 @@ description: Visible only for ChatGPT
|
||||
"command": "demo-server"
|
||||
}
|
||||
}
|
||||
}"#,
|
||||
)?;
|
||||
std::fs::write(
|
||||
plugin_root.join("hooks/hooks.json"),
|
||||
r#"{
|
||||
"hooks": {
|
||||
"SessionStart": [
|
||||
{
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "echo startup"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"PreToolUse": [
|
||||
{
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "echo first"
|
||||
},
|
||||
{
|
||||
"type": "command",
|
||||
"command": "echo second"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}"#,
|
||||
)?;
|
||||
std::fs::write(
|
||||
codex_home.path().join("config.toml"),
|
||||
r#"[features]
|
||||
plugins = true
|
||||
plugin_hooks = true
|
||||
|
||||
[[skills.config]]
|
||||
name = "demo-plugin:thread-summarizer"
|
||||
@@ -894,6 +928,9 @@ enabled = false
|
||||
|
||||
[plugins."demo-plugin@codex-curated"]
|
||||
enabled = true
|
||||
|
||||
[hooks.state."demo-plugin@codex-curated:hooks/hooks.json:pre_tool_use:0:0"]
|
||||
enabled = false
|
||||
"#,
|
||||
)?;
|
||||
write_installed_plugin(&codex_home, "codex-curated", "demo-plugin")?;
|
||||
@@ -980,6 +1017,23 @@ enabled = true
|
||||
"Summarize email threads"
|
||||
);
|
||||
assert!(!response.plugin.skills[0].enabled);
|
||||
assert_eq!(
|
||||
response.plugin.hooks,
|
||||
vec![
|
||||
codex_app_server_protocol::PluginHookSummary {
|
||||
key: "demo-plugin@codex-curated:hooks/hooks.json:pre_tool_use:0:0".to_string(),
|
||||
event_name: HookEventName::PreToolUse,
|
||||
},
|
||||
codex_app_server_protocol::PluginHookSummary {
|
||||
key: "demo-plugin@codex-curated:hooks/hooks.json:pre_tool_use:0:1".to_string(),
|
||||
event_name: HookEventName::PreToolUse,
|
||||
},
|
||||
codex_app_server_protocol::PluginHookSummary {
|
||||
key: "demo-plugin@codex-curated:hooks/hooks.json:session_start:0:0".to_string(),
|
||||
event_name: HookEventName::SessionStart,
|
||||
},
|
||||
]
|
||||
);
|
||||
assert_eq!(response.plugin.apps.len(), 1);
|
||||
assert_eq!(response.plugin.apps[0].id, "gmail");
|
||||
assert_eq!(response.plugin.apps[0].name, "gmail");
|
||||
|
||||
Reference in New Issue
Block a user