Skip to content

feat(capabilities): CommandBridge for capability-registered slash commands - #272

Open
Leoyzen wants to merge 1 commit into
mainfrom
feat/capability-command-bridge
Open

feat(capabilities): CommandBridge for capability-registered slash commands#272
Leoyzen wants to merge 1 commit into
mainfrom
feat/capability-command-bridge

Conversation

@Leoyzen

@Leoyzen Leoyzen commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

Summary

Connects ExtensionRegistry to protocol servers (ACP, OpenCode) so capabilities implementing CommandResource can register slash commands visible to clients.

The Problem

The architecture had all the right building blocks but they weren't connected:

  • CommandResource protocol existed — capabilities could implement list_commands()/get_command()
  • ExtensionRegistry.get_command_resources(scope) existed — could query for command-producing capabilities
  • SkillManagerCap and McpServerCap implemented CommandResource
  • ❌ Protocol servers NEVER called get_command_resources() — they read from SkillsRegistry only
  • CommandResource was discovery-only — no execution path back to the capability
  • ❌ No unified command bridge connecting ExtensionRegistry → protocol CommandStore

A custom capability implementing CommandResource would have its commands invisible to all protocol servers.

The Solution

CommandBridge — a per-session class that:

  1. Discovers commands from all CommandResource capabilities via ExtensionRegistry
  2. Executes commands via CommandEntry.handler — a callable that routes back to the producing capability
  3. Watches for changes (commands_changed, skills_changed, prompts_changed events)
  4. Converts CommandEntry to protocol-specific formats (SlashedCommand, AvailableCommand)

Changes

Core:

  • CommandEntry.handler field added to resource_protocols.pyCallable[[str, AgentContext], Awaitable[str]] | None = field(default=None, compare=False)
  • "commands_changed" added to ChangeKind Literal
  • New CommandBridge class (src/agentpool/capabilities/command_bridge.py, ~265 LOC)
  • ExtensionRegistry.get_command_resources() reordered to TURN→AGENT→SESSION→POOL

Capability updates:

  • SkillManagerCap.list_commands() — populates handler for local skills, passes through McpServerCap entries unchanged
  • McpServerCap.list_commands() — populates handler wrapping get_prompt()

Protocol server integration:

  • ACP server: per-session CommandBridge, discovery, execution routing with fallback, change watching
  • OpenCode server: new OpenCodeCommandBridge class, GET /command endpoint updated, execution routing, change watcher

Documentation:

  • examples/custom_command_capability.py — end-to-end example
  • AGENTS.md updated with CommandResource, CommandBridge documentation
  • RFC-0058 draft

Test Results

  • ✅ 26 new unit tests (tests/capabilities/test_command_bridge.py) — all passing
  • ✅ Full test suite: 4939 passed, 1 pre-existing failure (test_vision), no regressions
  • ruff check: clean
  • mypy: clean

OpenSpec

  • Change: openspec/changes/capability-command-bridge/ (proposal, design, 7 spec files, 46 tasks)
  • Oracle-verified (3 passes)
  • 39/46 tasks complete (7 protocol integration tests deferred)

Files Changed

  • 20 files changed, 2519 insertions(+), 90 deletions(-)
  • 5 new files (command_bridge.py core, command_bridge.py opencode, test, example, RFC)

…mands

Add CommandBridge connecting ExtensionRegistry to protocol servers (ACP,
OpenCode) so capabilities implementing CommandResource can register
slash commands visible to clients.

Core changes:
- CommandEntry.handler: Callable[[str, AgentContext], Awaitable[str]] | None
  Added to resource_protocols.py with compare=False
- 'commands_changed' added to ChangeKind Literal
- CommandBridge class (command_bridge.py): discover_commands(), execute(),
  watch_changes(), entry_to_slashed_command() — per-session lifecycle
- ExtensionRegistry.get_command_resources() reordered TURN->AGENT->SESSION->POOL
- SkillManagerCap.list_commands() populates handler for local skills,
  passes through McpServerCap entries unchanged
- McpServerCap.list_commands() populates handler wrapping get_prompt()
- ACP server: per-session CommandBridge, discovery, execution routing,
  change watching for commands_changed/skills_changed/prompts_changed
- OpenCode server: OpenCodeCommandBridge class, GET /command updated,
  execution routing with fallback, change watcher updated

Tests: 26 unit tests (test_command_bridge.py) — all passing
Full suite: 4939 passed, 1 pre-existing failure, no regressions

OpenSpec change: openspec/changes/capability-command-bridge/
RFC: docs/rfcs/draft/RFC-0058-capability-command-bridge.md
Example: examples/custom_command_capability.py
@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@Leoyzen
Leoyzen requested a review from Million-mo July 25, 2026 12:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant