diff --git a/src/browser/components/ChatInputToasts.tsx b/src/browser/components/ChatInputToasts.tsx index 89cb5a7245..f1304828b9 100644 --- a/src/browser/components/ChatInputToasts.tsx +++ b/src/browser/components/ChatInputToasts.tsx @@ -130,6 +130,34 @@ export const createCommandToast = (parsed: ParsedCommand): Toast | null => { ), }; + case "command-missing-args": + return { + id: Date.now().toString(), + type: "error", + title: "Missing Arguments", + message: `/${parsed.command} requires arguments`, + solution: ( + <> + Usage: + {parsed.usage} + + ), + }; + + case "command-invalid-args": + return { + id: Date.now().toString(), + type: "error", + title: "Invalid Argument", + message: `'${parsed.input}' is not valid for /${parsed.command}`, + solution: ( + <> + Usage: + {parsed.usage} + + ), + }; + case "unknown-command": { const cmd = "/" + parsed.command + (parsed.subcommand ? " " + parsed.subcommand : ""); return { diff --git a/src/browser/utils/slashCommands/registry.ts b/src/browser/utils/slashCommands/registry.ts index e55ecbaada..6ed0bc8e01 100644 --- a/src/browser/utils/slashCommands/registry.ts +++ b/src/browser/utils/slashCommands/registry.ts @@ -186,23 +186,26 @@ const clearCommandDefinition: SlashCommandDefinition = { }, }; +const TRUNCATE_USAGE = "/truncate <0-100> (percentage to remove)"; + const truncateCommandDefinition: SlashCommandDefinition = { key: "truncate", description: "Truncate conversation history by percentage (0-100)", handler: ({ cleanRemainingTokens }): ParsedCommand => { if (cleanRemainingTokens.length === 0) { return { - type: "unknown-command", + type: "command-missing-args", command: "truncate", - subcommand: undefined, + usage: TRUNCATE_USAGE, }; } if (cleanRemainingTokens.length > 1) { return { - type: "unknown-command", + type: "command-invalid-args", command: "truncate", - subcommand: cleanRemainingTokens[1], + input: cleanRemainingTokens.join(" "), + usage: TRUNCATE_USAGE, }; } @@ -212,9 +215,10 @@ const truncateCommandDefinition: SlashCommandDefinition = { if (isNaN(pct) || pct < 0 || pct > 100) { return { - type: "unknown-command", + type: "command-invalid-args", command: "truncate", - subcommand: pctStr, + input: pctStr, + usage: TRUNCATE_USAGE, }; } @@ -632,6 +636,8 @@ function parseMCPNameCommand( return { name, command }; } +const IDLE_USAGE = "/idle or /idle off"; + const idleCommandDefinition: SlashCommandDefinition = { key: "idle", description: "Configure idle compaction for this project. Usage: /idle or /idle off", @@ -639,9 +645,9 @@ const idleCommandDefinition: SlashCommandDefinition = { handler: ({ cleanRemainingTokens }): ParsedCommand => { if (cleanRemainingTokens.length === 0) { return { - type: "unknown-command", + type: "command-missing-args", command: "idle", - subcommand: undefined, + usage: IDLE_USAGE, }; } @@ -655,9 +661,10 @@ const idleCommandDefinition: SlashCommandDefinition = { const hours = parseInt(arg, 10); if (isNaN(hours) || hours < 1) { return { - type: "unknown-command", + type: "command-invalid-args", command: "idle", - subcommand: arg, + input: arg, + usage: IDLE_USAGE, }; } @@ -678,7 +685,11 @@ const mcpCommandDefinition: SlashCommandDefinition = { if (sub === "add" || sub === "edit") { const parsed = parseMCPNameCommand(sub, cleanRemainingTokens, rawInput); if (!parsed) { - return { type: "unknown-command", command: "mcp", subcommand: sub }; + return { + type: "command-missing-args", + command: `mcp ${sub}`, + usage: `/mcp ${sub} `, + }; } return { type: sub === "add" ? "mcp-add" : "mcp-edit", ...parsed }; } @@ -686,7 +697,11 @@ const mcpCommandDefinition: SlashCommandDefinition = { if (sub === "remove") { const name = cleanRemainingTokens[1]; if (!name) { - return { type: "unknown-command", command: "mcp", subcommand: "remove" }; + return { + type: "command-missing-args", + command: "mcp remove", + usage: "/mcp remove ", + }; } return { type: "mcp-remove", name }; } diff --git a/src/browser/utils/slashCommands/types.ts b/src/browser/utils/slashCommands/types.ts index 26b8680550..c5a684f51c 100644 --- a/src/browser/utils/slashCommands/types.ts +++ b/src/browser/utils/slashCommands/types.ts @@ -37,6 +37,8 @@ export type ParsedCommand = | { type: "plan-open" } | { type: "init" } | { type: "unknown-command"; command: string; subcommand?: string } + | { type: "command-missing-args"; command: string; usage: string } + | { type: "command-invalid-args"; command: string; input: string; usage: string } | { type: "idle-compaction"; hours: number | null } | null;