# Human Commands The human-command seam of [`dsh-commands`](../../packages/ui/commands). TUI and ACP adapters use it to discover and directly execute plugin-owned commands for an exact agent without creating a model message. The [command Agent Note](../../.agents/notes/implemented/feature/2026-07-19-plugin-command-registration.md) owns dispatch and lifecycle rationale; the [package README](../../packages/ui/commands/README.md) owns composition and limitations. Source: [`packages/ui/commands/src/index.ts`](../../packages/ui/commands/src/index.ts) ## Surface and input metadata A definition selects one or more adapter identities. The shipped identities are `tui` and `acp`; the string intersection keeps the registry extensible without widening editor autocomplete to plain `string`. ACP currently exposes one unstructured-input hint. ```ts type-equiv /** A UI adapter capable of listing and executing human commands. */ type CommandSurface = 'tui' | 'acp' | (string & {}) ``` ```ts type-equiv /** Immutable command input metadata compatible with ACP unstructured input. */ interface CommandInputDescriptor { /** Placeholder shown before the user supplies free-form input. */ readonly hint: string } ``` ## Definition `CommandDefinition` is the plugin-authored registration. Omitted surfaces resolve to both shipped adapters; the registry validates and freezes a detached effective definition. ```ts type-equiv /** Plugin-owned command registration. */ interface CommandDefinition { /** Lowercase command name without the leading slash. */ readonly name: string /** Human-readable summary used in discovery UI. */ readonly description: string /** Optional free-form input hint advertised to capable clients. */ readonly input?: CommandInputDescriptor /** Surfaces exposing this command; omission means both shipped surfaces. */ readonly surfaces?: readonly CommandSurface[] /** Execute against the receiving agent without sending the command to the model. */ readonly handler: (invocation: CommandInvocation) => CommandResult | Promise } ``` ## Invocation and result The adapter owns cancellation and passes the exact target agent. `rawInput` begins immediately after the parsed name and retains the adapter-delivered separator and suffix. Results are direct UI outcomes, not tool results or session events. ```ts type-equiv /** Invocation passed to one registered command handler. */ interface CommandInvocation { /** Exact agent whose human-facing surface received the command. */ readonly agent: Agent /** UI adapter that dispatched the command. */ readonly surface: CommandSurface /** Exact text following the registered command name, including separator whitespace. */ readonly rawInput: string /** Cancellation signal owned by the dispatching UI request. */ readonly signal: AbortSignal } ``` ```ts type-equiv /** Expected command outcome rendered directly by the dispatching UI. */ type CommandResult = | { readonly kind: 'success'; readonly text?: string } | { readonly kind: 'error'; readonly text: string } ``` ## Discovery and parsing views Adapters receive handler-free immutable descriptors after scope resolution and surface filtering. `parseCommand()` returns `ParsedCommand` before registry resolution; syntax-valid input can still name an unavailable command. ```ts type-equiv /** Handler-free immutable command view returned to UI adapters. */ interface CommandDescriptor { /** Lowercase command name without the leading slash. */ readonly name: string /** Human-readable summary used in discovery UI. */ readonly description: string /** Optional free-form input hint advertised to capable clients. */ readonly input?: CommandInputDescriptor /** Surfaces on which this definition is visible. */ readonly surfaces: readonly CommandSurface[] } ``` ```ts type-equiv /** Syntactically valid slash command before registry resolution. */ interface ParsedCommand { /** Lowercase command name without the leading slash. */ readonly name: string /** Exact text following the command name. */ readonly rawInput: string } ```