Human Commands
Input metadata
Section titled “Input metadata”The service exposes one optional unstructured-input hint. Command availability follows plugin composition: every adapter consuming the registry sees every effective definition.
/** Immutable metadata for a command's optional unstructured input. */interface CommandInputDescriptor { /** Placeholder shown before the user supplies free-form input. */ readonly hint: string}Definition
Section titled “Definition”CommandDefinition is the plugin-authored registration. The registry validates and freezes a detached effective definition.
/** 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 /** * Whether `command/run` records `rawInput`. Defaults to true. A command * whose domain event owns the payload sets this false to avoid duplicating * that payload in the session log. */ readonly recordInput?: boolean /** Execute against the receiving agent without sending the command to the model. */ readonly handler: (invocation: CommandInvocation) => CommandResult | Promise<CommandResult>}Invocation and result
Section titled “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.
/** Invocation passed to one registered command handler. */interface CommandInvocation { /** Pairing id already written to this invocation's `command/run` event. */ readonly commandId: CommandId /** Exact agent whose UI received the command. */ readonly agent: Agent /** Exact text following the registered command name, including separator whitespace. */ readonly rawInput: string /** Cancellation signal owned by the dispatching UI request. */ readonly signal: AbortSignal}/** Expected command outcome rendered directly by the dispatching UI. */type CommandResult = | { readonly kind: 'success' readonly text?: string /** Earlier authoritative domain event that owns a richer presentation. */ readonly sourceEventSeq?: number } | { readonly kind: 'error'; readonly text: string }sourceEventSeq is optional and success-only. When present, it names an earlier non-command event in the receiving session log; command/done persists the same reference so a client can combine the command lifecycle with that domain projection without parsing text or relying on adjacent rows.
Discovery and parsing views
Section titled “Discovery and parsing views”Adapters receive handler-free immutable descriptors after scope resolution. parseCommand() returns ParsedCommand before registry resolution; syntax-valid input can still name an unavailable command.
/** 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}/** 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}Cordis API
Section titled “Cordis API”Generated from source by scripts/gen-cordis-catalog.ts (verified fresh by pnpm run verify-cordis-catalog in doc-sync; regenerate with pnpm run gen-cordis-catalog) — this section is byte-identical in both language sides of the page. Signature blocks use a ts cordis-catalog fence and keep the original source JSDoc; dispatch modes are defined in the primer, and the framework-inherited ctx API lives in cordis-api/inherited.md.
ctx.commands — CommandRuntime
Section titled “ctx.commands — CommandRuntime”Human-command registry. Plain-context definitions are global; definitions registered through a command-injected child of an agent context shadow globals for that agent.
/** * Register a global or calling-agent-scoped command. * @param definition - discovery metadata and direct UI handler. * @returns the exact effect disposer that unregisters this definition. */register(definition: CommandDefinition): () => void
/** * List the effective immutable command descriptors for one agent. * @param agent - exact receiving agent and scoped-layer key. * @returns name-sorted descriptors after scoped shadowing. */@Remote list(agent: Agent): readonly CommandDescriptor[]
/** * Resolve one effective command definition. * @param agent - exact receiving agent and scoped-layer key. * @param name - command name without a slash. * @returns the scoped shadow or global definition. */find(agent: Agent, name: string): CommandDefinition | undefined
/** * Parse and execute a known command without sending it to the model. * * A resolved command's lifecycle is logged: `command/run` is appended * before the handler is invoked and `command/done` after settlement (a * thrown or aborted handler settles as `kind: 'error'`). Both are direct * log-only appends — no turn wraps them, and persistence drains them at * ordinary checkpoints. Admission misses (syntax or unknown name) log * nothing — they never entered a handler. A `command/run` append failure * fails the execution loud; a `command/done` append failure on the * handler-failure path is contained so the handler's own error stays the * reported failure. * * @param agent - exact receiving agent. * @param line - complete slash-command line. * @param signal - cancellation signal owned by the UI request. * @returns the settled execution (result + lifecycle pairing id), or * `undefined` when syntax or name does not resolve. */@Remote async execute( agent: Agent, line: string, signal: AbortSignal, ): Promise<CommandExecution | undefined>Types: Agent
Source: packages/interaction/commands/src/index.ts:225
commands/* events
Section titled “commands/* events”commands/change — emit
Section titled “commands/change — emit”A command was registered or unregistered. This is an unfiltered registry notification because a global or scoped change may affect any UI view. Observer failures are contained and cannot veto the registry mutation.
/** * A command was registered or unregistered. This is an unfiltered registry * notification because a global or scoped change may affect any UI view. * Observer failures are contained and cannot veto the registry mutation. * @mode emit */'commands/change'(): void