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 c04e58acecae..618601e6285b 100644
--- a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx
+++ b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx
@@ -353,8 +353,9 @@ export function Session() {
const local = useLocal()
function moveFirstChild() {
- if (children().length === 1) return
- const next = children().find((x) => !!x.parentID)
+ const currentID = session()?.id
+ if (!currentID) return
+ const next = sync.data.session.find((s) => s.parentID === currentID)
if (next) {
navigate({
type: "session",
@@ -364,9 +365,11 @@ export function Session() {
}
function moveChild(direction: number) {
- if (children().length === 1) return
+ const currentParentID = session()?.parentID
+ if (!currentParentID) return
- const sessions = children().filter((x) => !!x.parentID)
+ const sessions = children().filter((x) => x.parentID === currentParentID)
+ if (sessions.length <= 1) return
let next = sessions.findIndex((x) => x.id === session()?.id) - direction
if (next >= sessions.length) next = 0
@@ -959,11 +962,24 @@ export function Session() {
keybind: "session_child_first",
category: "Session",
hidden: true,
+ enabled: !session()?.parentID,
onSelect: (dialog) => {
moveFirstChild()
dialog.clear()
},
},
+ {
+ title: "Go to child session",
+ value: "session.child.first.subagent",
+ keybind: "session_child_first_subagent",
+ category: "Session",
+ hidden: true,
+ enabled: !!session()?.parentID,
+ onSelect: childSessionHandler((dialog) => {
+ moveFirstChild()
+ dialog.clear()
+ }),
+ },
{
title: "Go to parent session",
value: "session.parent",
diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/subagent-footer.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/subagent-footer.tsx
index 55695996076e..4cd472e2e7a7 100644
--- a/packages/opencode/src/cli/cmd/tui/routes/session/subagent-footer.tsx
+++ b/packages/opencode/src/cli/cmd/tui/routes/session/subagent-footer.tsx
@@ -17,18 +17,19 @@ export function SubagentFooter() {
const subagentInfo = createMemo(() => {
const s = session()
- if (!s) return { label: "Subagent", index: 0, total: 0 }
+ if (!s) return { label: "Subagent", index: 0, total: 0, hasChildren: false }
const agentMatch = s.title.match(/@(\w+) subagent/)
const label = agentMatch ? Locale.titlecase(agentMatch[1]) : "Subagent"
- if (!s.parentID) return { label, index: 0, total: 0 }
+ if (!s.parentID) return { label, index: 0, total: 0, hasChildren: false }
const siblings = sync.data.session
.filter((x) => x.parentID === s.parentID)
.toSorted((a, b) => a.time.created - b.time.created)
const index = siblings.findIndex((x) => x.id === s.id)
+ const hasChildren = sync.data.session.some((x) => x.parentID === s.id)
- return { label, index: index + 1, total: siblings.length }
+ return { label, index: index + 1, total: siblings.length, hasChildren }
})
const usage = createMemo(() => {
@@ -58,8 +59,8 @@ export function SubagentFooter() {
const { theme } = useTheme()
const keybind = useKeybind()
const command = useCommandDialog()
- const [hover, setHover] = createSignal<"parent" | "prev" | "next" | null>(null)
- useTerminalDimensions()
+ const [hover, setHover] = createSignal<"parent" | "prev" | "next" | "child" | null>(null)
+ const dimensions = useTerminalDimensions()
return (
@@ -123,6 +124,18 @@ export function SubagentFooter() {
Next {keybind.print("session_child_cycle")}
+
+ setHover("child")}
+ onMouseOut={() => setHover(null)}
+ onMouseUp={() => command.trigger("session.child.first.subagent")}
+ backgroundColor={hover() === "child" ? theme.backgroundElement : theme.backgroundPanel}
+ >
+
+ Child {keybind.print("session_child_first_subagent")}
+
+
+
diff --git a/packages/opencode/src/config/keybinds.ts b/packages/opencode/src/config/keybinds.ts
index a84fc0b37d58..128a92e67e7f 100644
--- a/packages/opencode/src/config/keybinds.ts
+++ b/packages/opencode/src/config/keybinds.ts
@@ -104,6 +104,7 @@ const KeybindsSchema = Schema.Struct({
history_previous: keybind("up", "Previous history item"),
history_next: keybind("down", "Next history item"),
session_child_first: keybind("down", "Go to first child session"),
+ session_child_first_subagent: keybind("down", "Go to first child session (from subagent)"),
session_child_cycle: keybind("right", "Go to next child session"),
session_child_cycle_reverse: keybind("left", "Go to previous child session"),
session_parent: keybind("up", "Go to parent session"),