You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
PR #2534 (closed as merge of issue #2522) narrowed ToolCatalogEntry.source and ToolCatalogGroup.source from "core" | "plugin" to "core" in the UI type system and dropped pluginId?: string. That change was authored on the false premise that the plugin subsystem was being gutted. Deeper investigation (after this batch closed) confirmed the plugin subsystem is kept — it is the fork's primary extensibility mechanism, and the backend actively emits source: "plugin" for plugin-contributed tools.
The UI types therefore lie about the protocol's actual shape.
Both are inside buildPluginGroups (lines 71-123), which is invoked on every tools.catalog RPC when includePlugins !== false (default true). buildPluginGroups calls resolvePluginTools(...) from src/plugins/tools.ts.
Plugins actively register tools
At the time of filing, 10 api.registerTool(...) calls across 5 bundled extensions:
ui/src/ui/types.ts:
ToolCatalogEntry.source: "core" // was: "core" | "plugin"
ToolCatalogGroup.source: "core" // was: "core" | "plugin"
pluginId?: string deleted on both
Current UI runtime deserialization is untyped cast, so the type lie does not throw at runtime — it just makes the type system blind to plugin-sourced tools.
Why this is harmful now
Low immediate impact: #2520 (commit d65576be8a) removed the only UI consumer of the tool catalog (loadToolsCatalog and its panel). Nothing reads the catalog from the UI today.
High latent impact:
Future tool-browsing UI will inherit the narrowed type and silently drop plugin-tool display capability.
Type-aware schema validation (when added) will reject all backend responses containing source: "plugin" as invalid.
Protocol schema at src/gateway/protocol/schema/agents-tools.ts likely still declares source: "core" | "plugin" — the backend wire shape is unchanged. The mismatch between UI types and protocol schema is a quiet contract divergence.
Changes
Revert UI narrowing in ui/src/ui/types.ts:
ToolCatalogEntry.source: widen back to "core" | "plugin"
ToolCatalogGroup.source: widen back to "core" | "plugin"
Restore pluginId?: string on both types (preserve the original backend fidelity)
Verify protocol schema alignment: check src/gateway/protocol/schema/agents-tools.ts still declares the "core" | "plugin" union and emits pluginId. If UI-only fidelity divergence was introduced somewhere else, fix that too.
Do NOT restore ui/src/ui/views/agents.ts or the deleted panel body — that cleanup (gut(ui): remove dead Tools tab from Agents view #2520) was correct independent of the plugin-retention question. Those UI surfaces were removed because the Tools tab was dead UI, not because plugins don't exist.
AC
ToolCatalogEntry.source in ui/src/ui/types.ts is typed "core" | "plugin"
ToolCatalogGroup.source in ui/src/ui/types.ts is typed "core" | "plugin"
Plugin-retention clarified during batch 20260424-6b79 post-run discussion; CLAUDE.md § Fork Context "What's being removed" was updated in a separate PR to remove the stale "plugin system" entry that misled the original gut(ui): remove plugin discriminator from tool catalog types #2522 author
Summary
PR #2534 (closed as merge of issue #2522) narrowed
ToolCatalogEntry.sourceandToolCatalogGroup.sourcefrom"core" | "plugin"to"core"in the UI type system and droppedpluginId?: string. That change was authored on the false premise that the plugin subsystem was being gutted. Deeper investigation (after this batch closed) confirmed the plugin subsystem is kept — it is the fork's primary extensibility mechanism, and the backend actively emitssource: "plugin"for plugin-contributed tools.The UI types therefore lie about the protocol's actual shape.
Evidence
Backend emits
"plugin"via live pathsBoth are inside
buildPluginGroups(lines 71-123), which is invoked on everytools.catalogRPC whenincludePlugins !== false(default true).buildPluginGroupscallsresolvePluginTools(...)fromsrc/plugins/tools.ts.Plugins actively register tools
At the time of filing, 10
api.registerTool(...)calls across 5 bundled extensions:extensions/feishudocx.ts(2),bitable.ts,perm.ts,chat.ts,wiki.ts,drive.tsextensions/voice-callindex.ts:399extensions/tlonindex.ts:138extensions/zalouserindex.ts:16UI narrowed type (after #2534)
Current UI runtime deserialization is untyped cast, so the type lie does not throw at runtime — it just makes the type system blind to plugin-sourced tools.
Why this is harmful now
Low immediate impact: #2520 (commit
d65576be8a) removed the only UI consumer of the tool catalog (loadToolsCatalogand its panel). Nothing reads the catalog from the UI today.High latent impact:
source: "plugin"as invalid.src/gateway/protocol/schema/agents-tools.tslikely still declaressource: "core" | "plugin"— the backend wire shape is unchanged. The mismatch between UI types and protocol schema is a quiet contract divergence.Changes
Revert UI narrowing in
ui/src/ui/types.ts:ToolCatalogEntry.source: widen back to"core" | "plugin"ToolCatalogGroup.source: widen back to"core" | "plugin"pluginId?: stringon both types (preserve the original backend fidelity)Verify protocol schema alignment: check
src/gateway/protocol/schema/agents-tools.tsstill declares the"core" | "plugin"union and emitspluginId. If UI-only fidelity divergence was introduced somewhere else, fix that too.Do NOT restore
ui/src/ui/views/agents.tsor the deleted panel body — that cleanup (gut(ui): remove dead Tools tab from Agents view #2520) was correct independent of the plugin-retention question. Those UI surfaces were removed because the Tools tab was dead UI, not because plugins don't exist.AC
ToolCatalogEntry.sourceinui/src/ui/types.tsis typed"core" | "plugin"ToolCatalogGroup.sourceinui/src/ui/types.tsis typed"core" | "plugin"pluginId?: stringis present on both typespnpm checkgreenpnpm testgreenpnpm test:ui:smokegreenContext
79aa071324)20260424-6b79post-run discussion; CLAUDE.md § Fork Context "What's being removed" was updated in a separate PR to remove the stale "plugin system" entry that misled the original gut(ui): remove plugin discriminator from tool catalog types #2522 author