mirror of
https://github.com/openai/codex.git
synced 2026-11-05 16:29:31 +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:
1 parent
898f5bfeaa
commit
40e282849c
23 files changed
+436
-25
No files matched your search
@@ -1728,6 +1728,12 @@ impl ChatWidget {
|
||||
is_disabled: true,
|
||||
..Default::default()
|
||||
});
|
||||
items.push(SelectionItem {
|
||||
name: "Hooks".to_string(),
|
||||
description: Some(plugin_hook_summary(plugin)),
|
||||
is_disabled: true,
|
||||
..Default::default()
|
||||
});
|
||||
items.push(SelectionItem {
|
||||
name: "Apps".to_string(),
|
||||
description: Some(plugin_app_summary(plugin)),
|
||||
@@ -2142,6 +2148,29 @@ fn plugin_app_summary(plugin: &PluginDetail) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
fn plugin_hook_summary(plugin: &PluginDetail) -> String {
|
||||
if plugin.hooks.is_empty() {
|
||||
"No plugin hooks.".to_string()
|
||||
} else {
|
||||
let mut event_counts = Vec::<(codex_app_server_protocol::HookEventName, usize)>::new();
|
||||
for hook in &plugin.hooks {
|
||||
if let Some((_, handler_count)) = event_counts
|
||||
.iter_mut()
|
||||
.find(|(event_name, _)| *event_name == hook.event_name)
|
||||
{
|
||||
*handler_count += 1;
|
||||
} else {
|
||||
event_counts.push((hook.event_name, 1));
|
||||
}
|
||||
}
|
||||
event_counts
|
||||
.into_iter()
|
||||
.map(|(event_name, handler_count)| format!("{event_name:?} ({handler_count})"))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
}
|
||||
}
|
||||
|
||||
fn plugin_mcp_summary(plugin: &PluginDetail) -> String {
|
||||
if plugin.mcp_servers.is_empty() {
|
||||
"No plugin MCP servers.".to_string()
|
||||
|
||||
Reference in new issue
Block a user