diff --git a/packages/opencode/src/cli/cmd/tui/app.tsx b/packages/opencode/src/cli/cmd/tui/app.tsx index 713def2e5af..1e17bd7d84f 100644 --- a/packages/opencode/src/cli/cmd/tui/app.tsx +++ b/packages/opencode/src/cli/cmd/tui/app.tsx @@ -391,10 +391,52 @@ function App() { slash: { name: "mcps", }, + keybind: "mcp_toggle", onSelect: () => { dialog.replace(() => ) }, }, + ...Array.from({ length: 10 }, (_, i) => { + const slot = i + 1 + return { + title: `Toggle MCP slot ${slot}`, + value: `mcp.toggle.${slot}`, + category: "Agent", + keybind: `mcp_toggle_${slot}` as keyof typeof sync.data.config.keybinds, + hidden: true, + onSelect: async () => { + const mcpNames = Object.keys(sync.data.mcp).sort() + const mcpName = mcpNames[i] + if (!mcpName) { + toast.show({ + variant: "warning", + message: `No MCP configured in slot ${slot}`, + duration: 2000, + }) + return + } + try { + await local.mcp.toggle(mcpName) + const status = await sdk.client.mcp.status() + if (status.data) { + sync.set("mcp", status.data) + } + const isEnabled = local.mcp.isEnabled(mcpName) + toast.show({ + variant: "info", + message: `${mcpName}: ${isEnabled ? "enabled" : "disabled"}`, + duration: 2000, + }) + } catch (error) { + toast.show({ + variant: "error", + message: `Failed to toggle ${mcpName}: ${error}`, + duration: 3000, + }) + } + }, + } + }), { title: "Agent cycle", value: "agent.cycle", @@ -513,6 +555,7 @@ function App() { title: "Toggle console", category: "System", value: "app.console", + keybind: "console_toggle", onSelect: (dialog) => { renderer.console.toggle() dialog.clear() diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx index d36a7d20994..b68cbf730ea 100644 --- a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx +++ b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx @@ -522,6 +522,7 @@ export function Session() { name: "timestamps", aliases: ["toggle-timestamps"], }, + keybind: "timestamps_toggle", onSelect: (dialog) => { setTimestamps((prev) => (prev === "show" ? "hide" : "show")) dialog.clear() @@ -535,11 +536,25 @@ export function Session() { name: "thinking", aliases: ["toggle-thinking"], }, + keybind: "thinking_toggle", onSelect: (dialog) => { setShowThinking((prev) => !prev) dialog.clear() }, }, + { + title: "Toggle diff wrapping", + value: "session.toggle.diffwrap", + category: "Session", + slash: { + name: "diffwrap", + }, + keybind: "diffwrap_toggle", + onSelect: (dialog) => { + setDiffWrapMode((prev) => (prev === "word" ? "none" : "word")) + dialog.clear() + }, + }, { title: showDetails() ? "Hide tool details" : "Show tool details", value: "session.toggle.actions", diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index 7969e307957..19c4920e703 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -681,6 +681,21 @@ export namespace Config { sidebar_toggle: z.string().optional().default("b").describe("Toggle sidebar"), scrollbar_toggle: z.string().optional().default("none").describe("Toggle session scrollbar"), username_toggle: z.string().optional().default("none").describe("Toggle username visibility"), + console_toggle: z.string().optional().default("none").describe("Toggle console"), + mcp_toggle: z.string().optional().default("none").describe("Toggle MCP dialog"), + mcp_toggle_1: z.string().optional().default("none").describe("Toggle MCP slot 1"), + mcp_toggle_2: z.string().optional().default("none").describe("Toggle MCP slot 2"), + mcp_toggle_3: z.string().optional().default("none").describe("Toggle MCP slot 3"), + mcp_toggle_4: z.string().optional().default("none").describe("Toggle MCP slot 4"), + mcp_toggle_5: z.string().optional().default("none").describe("Toggle MCP slot 5"), + mcp_toggle_6: z.string().optional().default("none").describe("Toggle MCP slot 6"), + mcp_toggle_7: z.string().optional().default("none").describe("Toggle MCP slot 7"), + mcp_toggle_8: z.string().optional().default("none").describe("Toggle MCP slot 8"), + mcp_toggle_9: z.string().optional().default("none").describe("Toggle MCP slot 9"), + mcp_toggle_10: z.string().optional().default("none").describe("Toggle MCP slot 10"), + timestamps_toggle: z.string().optional().default("none").describe("Toggle timestamps visibility"), + thinking_toggle: z.string().optional().default("none").describe("Toggle thinking visibility"), + diffwrap_toggle: z.string().optional().default("none").describe("Toggle diff wrapping"), status_view: z.string().optional().default("s").describe("View status"), session_export: z.string().optional().default("x").describe("Export session to editor"), session_new: z.string().optional().default("n").describe("Create a new session"), @@ -716,6 +731,7 @@ export namespace Config { messages_previous: z.string().optional().default("none").describe("Navigate to previous message"), messages_last_user: z.string().optional().default("none").describe("Navigate to last user message"), messages_copy: z.string().optional().default("y").describe("Copy message"), + session_copy: z.string().optional().default("none").describe("Copy session transcript"), messages_undo: z.string().optional().default("u").describe("Undo message"), messages_redo: z.string().optional().default("r").describe("Redo message"), messages_toggle_conceal: z diff --git a/packages/sdk/js/src/v2/gen/types.gen.ts b/packages/sdk/js/src/v2/gen/types.gen.ts index cb2f586775a..a66b0fbeb80 100644 --- a/packages/sdk/js/src/v2/gen/types.gen.ts +++ b/packages/sdk/js/src/v2/gen/types.gen.ts @@ -964,6 +964,26 @@ export type KeybindsConfig = { * Toggle username visibility */ username_toggle?: string + /** + * Toggle console + */ + console_toggle?: string + /** + * Toggle MCP dialog + */ + mcp_toggle?: string + /** + * Toggle timestamps visibility + */ + timestamps_toggle?: string + /** + * Toggle thinking visibility + */ + thinking_toggle?: string + /** + * Toggle diff wrapping + */ + diffwrap_toggle?: string /** * View status */ @@ -1072,6 +1092,10 @@ export type KeybindsConfig = { * Copy message */ messages_copy?: string + /** + * Copy session transcript + */ + session_copy?: string /** * Undo message */