Files
oh-my-pi/packages/coding-agent/src/slash-commands/builtin-control.ts
T
can1357 8cf3dce6fb refactor(coding-agent): split builtin slash commands by domain
- builtin-registry.ts held a 2341-line array of every command spec with its
  handler inlined, plus the autocomplete builders and the TUI dispatcher.
- Specs moved verbatim into modes, collaboration, session, lifecycle,
  marketplace and control modules; completions moved to builtin-completions.
- builtin-registry.ts is now a 174-line composition/dispatch module and keeps
  all 16 exports. Command order is unchanged, which matters because it drives
  autocomplete ordering and BUILTIN_SLASH_COMMAND_DEFS.
2026-08-08 06:32:01 +02:00

79 lines
2.5 KiB
TypeScript

import { runPauseScreen } from "../modes/components/pause-screen";
import { shutdownHandlerTui } from "./builtin-lifecycle";
import { commandConsumed, errorMessage, usage } from "./helpers/parse";
import type { SlashCommandSpec } from "./types";
export const BUILTIN_CONTROL_SLASH_COMMANDS: ReadonlyArray<SlashCommandSpec> = [
{
name: "force",
description: "Force next turn to use a specific tool",
aliases: ["force:"],
inlineHint: "<tool-name> [prompt]",
allowArgs: true,
getTuiAutocompleteDescription: runtime => {
const count = runtime.ctx.session.getActiveToolNames().length;
return count === 0 ? "Force: no active tools" : `Force: ${count} active tools`;
},
handle: async (command, runtime) => {
const spaceIdx = command.args.indexOf(" ");
const toolName = spaceIdx === -1 ? command.args : command.args.slice(0, spaceIdx);
const prompt = spaceIdx === -1 ? "" : command.args.slice(spaceIdx + 1).trim();
if (!toolName) return usage("Usage: /force:<tool-name> [prompt]", runtime);
try {
runtime.session.setForcedToolChoice(toolName);
} catch (err) {
return usage(errorMessage(err), runtime);
}
await runtime.output(`Next turn forced to use ${toolName}.`);
return prompt ? { prompt } : commandConsumed();
},
handleTui: (command, runtime) => {
const spaceIdx = command.args.indexOf(" ");
const toolName = spaceIdx === -1 ? command.args : command.args.slice(0, spaceIdx);
const prompt = spaceIdx === -1 ? "" : command.args.slice(spaceIdx + 1).trim();
if (!toolName) {
runtime.ctx.showError("Usage: /force:<tool-name> [prompt]");
runtime.ctx.editor.setText("");
return;
}
try {
runtime.ctx.session.setForcedToolChoice(toolName);
runtime.ctx.showStatus(`Next turn forced to use ${toolName}.`);
} catch (error) {
runtime.ctx.showError(errorMessage(error));
runtime.ctx.editor.setText("");
return;
}
runtime.ctx.editor.setText("");
// If a prompt was provided, pass it through as input
if (prompt) return { prompt };
},
},
{
name: "live",
description: "Start Codex-backed realtime voice mode",
handleTui: async (_command, runtime) => {
runtime.ctx.editor.setText("");
await runtime.ctx.handleLiveCommand();
},
},
{
name: "pause",
description: "Freeze all agents (main, subagents, advisor) until resumed",
handleTui: async (_command, runtime) => {
runtime.ctx.editor.setText("");
await runPauseScreen(runtime.ctx);
},
},
{
name: "quit",
aliases: ["q"],
description: "Quit the application",
handleTui: shutdownHandlerTui,
},
];