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