From 882c2e4c73c5ddffcd14fd7252093a0cd77c115b Mon Sep 17 00:00:00 2001 From: Jason Woltje Date: Sun, 15 Mar 2026 20:37:13 -0500 Subject: [PATCH] feat(types): CommandDef, CommandManifest, slash command socket events - Add CommandDef, CommandArgDef, CommandManifest, SkillCommandDef types - Add slash command payload types (SlashCommandPayload, SlashCommandResultPayload) - Add SystemReloadPayload and CommandManifestPayload - Add ParsedCommand type for TUI-side parsing - Wire new events into ServerToClientEvents and ClientToServerEvents Co-Authored-By: Claude Haiku 4.5 --- packages/types/src/chat/events.ts | 11 ++++ packages/types/src/commands/index.ts | 85 ++++++++++++++++++++++++++++ packages/types/src/index.ts | 1 + 3 files changed, 97 insertions(+) create mode 100644 packages/types/src/commands/index.ts diff --git a/packages/types/src/chat/events.ts b/packages/types/src/chat/events.ts index b8de5d7..5d6bcf2 100644 --- a/packages/types/src/chat/events.ts +++ b/packages/types/src/chat/events.ts @@ -1,3 +1,10 @@ +import type { + CommandManifestPayload, + SlashCommandPayload, + SlashCommandResultPayload, + SystemReloadPayload, +} from '../commands/index.js'; + export interface MessageAckPayload { conversationId: string; messageId: string; @@ -92,6 +99,9 @@ export interface ServerToClientEvents { 'agent:tool:start': (payload: ToolStartPayload) => void; 'agent:tool:end': (payload: ToolEndPayload) => void; 'session:info': (payload: SessionInfoPayload) => void; + 'commands:manifest': (payload: CommandManifestPayload) => void; + 'command:result': (payload: SlashCommandResultPayload) => void; + 'system:reload': (payload: SystemReloadPayload) => void; error: (payload: ErrorPayload) => void; } @@ -99,4 +109,5 @@ export interface ServerToClientEvents { export interface ClientToServerEvents { message: (data: ChatMessagePayload) => void; 'set:thinking': (data: SetThinkingPayload) => void; + 'command:execute': (data: SlashCommandPayload) => void; } diff --git a/packages/types/src/commands/index.ts b/packages/types/src/commands/index.ts new file mode 100644 index 0000000..5c984df --- /dev/null +++ b/packages/types/src/commands/index.ts @@ -0,0 +1,85 @@ +/** Argument definition for a slash command */ +export interface CommandArgDef { + name: string; + type: 'string' | 'enum'; + optional: boolean; + /** For enum type, the allowed values */ + values?: string[]; + description?: string; +} + +/** A single command definition served by the gateway */ +export interface CommandDef { + /** Command name without slash prefix, e.g. "model" */ + name: string; + /** Short aliases, e.g. ["m"] */ + aliases: string[]; + /** Human-readable description */ + description: string; + /** Argument schema */ + args?: CommandArgDef[]; + /** Nested subcommands (e.g. provider → login, logout) */ + subcommands?: CommandDef[]; + /** Origin of this command */ + scope: 'core' | 'agent' | 'skill' | 'plugin' | 'admin'; + /** Where the command executes */ + execution: 'local' | 'socket' | 'rest' | 'hybrid'; + /** Whether this command is currently available */ + available: boolean; +} + +/** Full command manifest pushed from gateway to TUI */ +export interface CommandManifest { + commands: CommandDef[]; + skills: SkillCommandDef[]; + /** Manifest version — TUI compares to detect changes */ + version: number; +} + +/** Skill registered as /skill:name */ +export interface SkillCommandDef { + /** Skill name (used as /skill:{name}) */ + name: string; + description: string; + /** Whether the skill is currently loaded and available */ + available: boolean; +} + +/** Payload for commands:manifest event */ +export interface CommandManifestPayload { + manifest: CommandManifest; +} + +/** Payload for system:reload broadcast */ +export interface SystemReloadPayload { + commands: CommandDef[]; + skills: SkillCommandDef[]; + providers: string[]; + message: string; +} + +/** Client request to execute a slash command via socket */ +export interface SlashCommandPayload { + conversationId: string; + command: string; + args?: string; +} + +/** Server response to a slash command */ +export interface SlashCommandResultPayload { + conversationId: string; + command: string; + success: boolean; + message?: string; + data?: Record; +} + +/** Parsed slash command (TUI-side, not a socket type) */ +export interface ParsedCommand { + /** Command name without slash, e.g. "model", "skill:brave-search" */ + command: string; + /** Arguments string or null */ + args: string | null; + /** Full raw input string */ + raw: string; +} diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 3634278..3c9e2b4 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -4,3 +4,4 @@ export * from './chat/index.js'; export * from './agent/index.js'; export * from './provider/index.js'; export * from './routing/index.js'; +export * from './commands/index.js';