feat(ui): add plugin command registry

This commit is contained in:
Tianyi Cui
2026-07-19 22:11:59 +08:00
parent 25555c9cfc
commit 2850c22b7a
110 changed files with 2000 additions and 130 deletions

View File

@@ -198,6 +198,28 @@ export const SERVICE_API: readonly ServiceApiEntry[] = [
},
],
},
{
key: 'commands',
summary: 'Human-command registry.',
methods: [
{
signature: 'register(definition: CommandDefinition): () => void',
jsDoc: '/**\n * Register a global or calling-agent-scoped command.\n * @param definition - discovery metadata, surface mask, and direct UI handler.\n * @returns the exact effect disposer that unregisters this definition.\n */',
},
{
signature: 'list(agent: Agent, surface: CommandSurface): readonly CommandDescriptor[]',
jsDoc: '/**\n * List the effective immutable command descriptors for one agent and surface.\n * @param agent - exact receiving agent and scoped-layer key.\n * @param surface - UI adapter requesting discovery metadata.\n * @returns name-sorted descriptors after scoped shadowing and surface filtering.\n */',
},
{
signature: 'find(agent: Agent, surface: CommandSurface, name: string): CommandDefinition | undefined',
jsDoc: '/**\n * Resolve one effective command definition.\n * @param agent - exact receiving agent and scoped-layer key.\n * @param surface - UI adapter performing the lookup.\n * @param name - command name without a slash.\n * @returns the scoped shadow or global definition when visible on the surface.\n */',
},
{
signature: 'async execute( agent: Agent, surface: CommandSurface, line: string, signal: AbortSignal, ): Promise<CommandResult | undefined>',
jsDoc: '/**\n * Parse and execute a known command without sending it to the model.\n * @param agent - exact receiving agent.\n * @param surface - dispatching UI adapter.\n * @param line - complete slash-command line.\n * @param signal - cancellation signal owned by the UI request.\n * @returns a detached result, or `undefined` when syntax/name/surface does not resolve.\n */',
},
],
},
{
key: 'compact',
summary: 'Abstract compaction service.',
@@ -786,6 +808,13 @@ export const EVENT_API: readonly EventApiEntry[] = [
jsDoc: '/**\n * Ask composed answerers for one decision. Return an outcome to claim the\n * request or call `next()`; failure yields the fail-closed default.\n * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.\n * @param req - the pending decision (agent, tool identity, reason, signal).\n * @mode waterfall\n */',
summary: 'Ask composed answerers for one decision.',
},
{
name: 'commands/change',
mode: 'emit',
signature: '\'commands/change\'(): void',
jsDoc: '/**\n * A command was registered or unregistered. This is an unfiltered registry\n * notification because a global or scoped change may affect any UI view.\n * @mode emit\n */',
summary: 'A command was registered or unregistered.',
},
{
name: 'fs/edit-intent',
mode: 'waterfall',
@@ -1108,6 +1137,30 @@ export const TYPE_API: readonly TypeApiEntry[] = [
name: 'CollectedOutput',
declaration: 'export interface CollectedOutput {\n text: string;\n truncated: boolean;\n spillPath?: string;\n}',
},
{
name: 'CommandDefinition',
declaration: 'export interface CommandDefinition {\n readonly name: string;\n readonly description: string;\n readonly input?: CommandInputDescriptor;\n readonly surfaces?: readonly CommandSurface[];\n readonly handler: (invocation: CommandInvocation) => CommandResult | Promise<CommandResult>;\n}',
},
{
name: 'CommandDescriptor',
declaration: 'export interface CommandDescriptor {\n readonly name: string;\n readonly description: string;\n readonly input?: CommandInputDescriptor;\n readonly surfaces: readonly CommandSurface[];\n}',
},
{
name: 'CommandInputDescriptor',
declaration: 'export interface CommandInputDescriptor {\n readonly hint: string;\n}',
},
{
name: 'CommandInvocation',
declaration: 'export interface CommandInvocation {\n readonly agent: Agent;\n readonly surface: CommandSurface;\n readonly rawInput: string;\n readonly signal: AbortSignal;\n}',
},
{
name: 'CommandResult',
declaration: 'export type CommandResult = {\n readonly kind: \'success\';\n readonly text?: string;\n} | {\n readonly kind: \'error\';\n readonly text: string;\n};',
},
{
name: 'CommandSurface',
declaration: 'export type CommandSurface = \'tui\' | \'acp\' | (string & {});',
},
{
name: 'CompactAgentContext',
declaration: 'export interface CompactAgentContext {\n session: Session;\n options: {\n provider?: string;\n model?: string;\n };\n}',