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 9868d3af..deb2a8c2 100644 --- a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx +++ b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx @@ -12,7 +12,7 @@ import { } from "solid-js" import { Dynamic } from "solid-js/web" import path from "path" -import { useRouteData } from "@tui/context/route" +import { useRoute, useRouteData } from "@tui/context/route" import { useSync } from "@tui/context/sync" import { SplitBorder } from "@tui/component/border" import { useTheme } from "@tui/context/theme" @@ -82,6 +82,7 @@ function use() { export function Session() { const route = useRouteData("session") + const { navigate } = useRoute() const sync = useSync() const kv = useKV() const { theme } = useTheme() @@ -156,6 +157,23 @@ export function Session() { const local = useLocal() + function moveChild(direction: number) { + const parentID = session()?.parentID ?? session()?.id + let children = sync.data.session + .filter((x) => x.parentID === parentID || x.id === parentID) + .toSorted((b, a) => a.id.localeCompare(b.id)) + if (children.length === 1) return + let next = children.findIndex((x) => x.id === session()?.id) + direction + if (next >= children.length) next = 0 + if (next < 0) next = children.length - 1 + if (children[next]) { + navigate({ + type: "session", + sessionID: children[next].id, + }) + } + } + const command = useCommandDialog() command.register(() => [ { @@ -397,6 +415,28 @@ export function Session() { dialog.replace(() => ) }, }, + { + title: "Next child session", + value: "session.child.next", + keybind: "session_child_cycle", + category: "Session", + disabled: true, + onSelect: (dialog) => { + moveChild(1) + dialog.clear() + }, + }, + { + title: "Previous child session", + value: "session.child.previous", + keybind: "session_child_cycle_reverse", + category: "Session", + disabled: true, + onSelect: (dialog) => { + moveChild(-1) + dialog.clear() + }, + }, ]) const revert = createMemo(() => { @@ -458,6 +498,34 @@ export function Session() { > + + + + Previous{" "} + + {keybind.print("session_child_cycle_reverse")} + + + + Viewing subagent session + + + + {keybind.print("session_child_cycle")} + {" "} + Next + + +
@@ -921,16 +989,14 @@ function GenericTool(props: ToolProps) { ) } +type ToolRegistration = { + name: string + container: "inline" | "block" + render?: Component> +} const ToolRegistry = (() => { - const state: Record< - string, - { name: string; container: "inline" | "block"; render?: Component> } - > = {} - function register(input: { - name: string - container: "inline" | "block" - render?: Component> - }) { + const state: Record = {} + function register(input: ToolRegistration) { state[input.name] = input return input } @@ -1094,6 +1160,8 @@ ToolRegistry.register({ container: "block", render(props) { const { theme } = useTheme() + const keybind = useKeybind() + return ( <> @@ -1110,6 +1178,10 @@ ToolRegistry.register({ + + {keybind.print("session_child_cycle")}, {keybind.print("session_child_cycle_reverse")} + to navigate between subagent sessions + ) }, diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index cd0c2e15..de69dc0f 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -474,6 +474,16 @@ export namespace Config { .describe("Insert newline in input"), history_previous: z.string().optional().default("up").describe("Previous history item"), history_next: z.string().optional().default("down").describe("Previous history item"), + session_child_cycle: z + .string() + .optional() + .default("ctrl+right") + .describe("Next child session"), + session_child_cycle_reverse: z + .string() + .optional() + .default("ctrl+left") + .describe("Previous child session"), }) .strict() .meta({ diff --git a/packages/sdk/js/src/gen/types.gen.ts b/packages/sdk/js/src/gen/types.gen.ts index fb0371cd..ce571f49 100644 --- a/packages/sdk/js/src/gen/types.gen.ts +++ b/packages/sdk/js/src/gen/types.gen.ts @@ -166,6 +166,14 @@ export type KeybindsConfig = { * Previous history item */ history_next?: string + /** + * Next child session + */ + session_child_cycle?: string + /** + * Previous child session + */ + session_child_cycle_reverse?: string } export type AgentConfig = { diff --git a/packages/web/src/content/docs/1-0.mdx b/packages/web/src/content/docs/1-0.mdx index 74cc8d13..d9b6dbba 100644 --- a/packages/web/src/content/docs/1-0.mdx +++ b/packages/web/src/content/docs/1-0.mdx @@ -64,5 +64,3 @@ We removed some functionality that we weren't sure anyone actually used. If some - project_init - tool_details - thinking_blocks -- session_child_cycle -- session_child_cycle_reverse