fix: surface gateway slash commands in TUI

This commit is contained in:
Peter Steinberger
2026-01-23 18:58:41 +00:00
parent 1af227b619
commit 8195497cec
4 changed files with 28 additions and 2 deletions

View File

@@ -10,6 +10,7 @@ Docs: https://docs.clawd.bot
### Fixes
- TUI: forward unknown slash commands (for example, `/context`) to the Gateway.
- TUI: include Gateway slash commands in autocomplete and `/help`.
- Media: preserve PNG alpha when possible; fall back to JPEG when still over size cap. (#1491) Thanks @robbyczgw-cla.
- Agents: treat plugin-only tool allowlists as opt-ins; keep core tools enabled. (#1467)

View File

@@ -1,6 +1,6 @@
import { describe, expect, it } from "vitest";
import { parseCommand } from "./commands.js";
import { getSlashCommands, parseCommand } from "./commands.js";
describe("tui slash commands", () => {
it("treats /elev as an alias for /elevated", () => {
@@ -13,4 +13,10 @@ describe("tui slash commands", () => {
args: "off",
});
});
it("includes gateway text commands", () => {
const commands = getSlashCommands({});
expect(commands.some((command) => command.name === "context")).toBe(true);
expect(commands.some((command) => command.name === "commands")).toBe(true);
});
});

View File

@@ -1,5 +1,7 @@
import type { SlashCommand } from "@mariozechner/pi-tui";
import { listChatCommands, listChatCommandsForConfig } from "../auto-reply/commands-registry.js";
import { formatThinkingLevels, listThinkingLevelLabels } from "../auto-reply/thinking.js";
import type { ClawdbotConfig } from "../config/types.js";
const VERBOSE_LEVELS = ["on", "off"];
const REASONING_LEVELS = ["on", "off"];
@@ -13,6 +15,7 @@ export type ParsedCommand = {
};
export type SlashCommandOptions = {
cfg?: ClawdbotConfig;
provider?: string;
model?: string;
};
@@ -34,7 +37,7 @@ export function parseCommand(input: string): ParsedCommand {
export function getSlashCommands(options: SlashCommandOptions = {}): SlashCommand[] {
const thinkLevels = listThinkingLevelLabels(options.provider, options.model);
return [
const commands: SlashCommand[] = [
{ name: "help", description: "Show slash command help" },
{ name: "status", description: "Show gateway status summary" },
{ name: "agent", description: "Switch agent (or open picker)" },
@@ -115,6 +118,20 @@ export function getSlashCommands(options: SlashCommandOptions = {}): SlashComman
{ name: "exit", description: "Exit the TUI" },
{ name: "quit", description: "Exit the TUI" },
];
const seen = new Set(commands.map((command) => command.name));
const gatewayCommands = options.cfg ? listChatCommandsForConfig(options.cfg) : listChatCommands();
for (const command of gatewayCommands) {
const aliases = command.textAliases.length > 0 ? command.textAliases : [`/${command.key}`];
for (const alias of aliases) {
const name = alias.replace(/^\//, "").trim();
if (!name || seen.has(name)) continue;
seen.add(name);
commands.push({ name, description: command.description });
}
}
return commands;
}
export function helpText(options: SlashCommandOptions = {}): string {
@@ -122,6 +139,7 @@ export function helpText(options: SlashCommandOptions = {}): string {
return [
"Slash commands:",
"/help",
"/commands",
"/status",
"/agent <id> (or /agents)",
"/session <key> (or /sessions)",

View File

@@ -245,6 +245,7 @@ export async function runTui(opts: TuiOptions) {
editor.setAutocompleteProvider(
new CombinedAutocompleteProvider(
getSlashCommands({
cfg: config,
provider: sessionInfo.modelProvider,
model: sessionInfo.model,
}),