Skip to content

Commit 87aaa76

Browse files
committed
fix(tui): allow leader-down to navigate into grandchild sessions from any level
1 parent 5c5069b commit 87aaa76

2 files changed

Lines changed: 25 additions & 9 deletions

File tree

packages/opencode/src/cli/cmd/tui/routes/session/index.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -353,8 +353,9 @@ export function Session() {
353353
const local = useLocal()
354354

355355
function moveFirstChild() {
356-
if (children().length === 1) return
357-
const next = children().find((x) => !!x.parentID)
356+
const currentID = session()?.id
357+
if (!currentID) return
358+
const next = sync.data.session.find((s) => s.parentID === currentID)
358359
if (next) {
359360
navigate({
360361
type: "session",
@@ -364,9 +365,11 @@ export function Session() {
364365
}
365366

366367
function moveChild(direction: number) {
367-
if (children().length === 1) return
368+
const currentParentID = session()?.parentID
369+
if (!currentParentID) return
368370

369-
const sessions = children().filter((x) => !!x.parentID)
371+
const sessions = children().filter((x) => x.parentID === currentParentID)
372+
if (sessions.length <= 1) return
370373
let next = sessions.findIndex((x) => x.id === session()?.id) - direction
371374

372375
if (next >= sessions.length) next = 0

packages/opencode/src/cli/cmd/tui/routes/session/subagent-footer.tsx

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,19 @@ export function SubagentFooter() {
1717

1818
const subagentInfo = createMemo(() => {
1919
const s = session()
20-
if (!s) return { label: "Subagent", index: 0, total: 0 }
20+
if (!s) return { label: "Subagent", index: 0, total: 0, hasChildren: false }
2121
const agentMatch = s.title.match(/@(\w+) subagent/)
2222
const label = agentMatch ? Locale.titlecase(agentMatch[1]) : "Subagent"
2323

24-
if (!s.parentID) return { label, index: 0, total: 0 }
24+
if (!s.parentID) return { label, index: 0, total: 0, hasChildren: false }
2525

2626
const siblings = sync.data.session
2727
.filter((x) => x.parentID === s.parentID)
2828
.toSorted((a, b) => a.time.created - b.time.created)
2929
const index = siblings.findIndex((x) => x.id === s.id)
30+
const hasChildren = sync.data.session.some((x) => x.parentID === s.id)
3031

31-
return { label, index: index + 1, total: siblings.length }
32+
return { label, index: index + 1, total: siblings.length, hasChildren }
3233
})
3334

3435
const usage = createMemo(() => {
@@ -58,8 +59,8 @@ export function SubagentFooter() {
5859
const { theme } = useTheme()
5960
const keybind = useKeybind()
6061
const command = useCommandDialog()
61-
const [hover, setHover] = createSignal<"parent" | "prev" | "next" | null>(null)
62-
useTerminalDimensions()
62+
const [hover, setHover] = createSignal<"parent" | "prev" | "next" | "child" | null>(null)
63+
const dimensions = useTerminalDimensions()
6364

6465
return (
6566
<box flexShrink={0}>
@@ -123,6 +124,18 @@ export function SubagentFooter() {
123124
Next <span style={{ fg: theme.textMuted }}>{keybind.print("session_child_cycle")}</span>
124125
</text>
125126
</box>
127+
<Show when={subagentInfo().hasChildren}>
128+
<box
129+
onMouseOver={() => setHover("child")}
130+
onMouseOut={() => setHover(null)}
131+
onMouseUp={() => command.trigger("session.child.first")}
132+
backgroundColor={hover() === "child" ? theme.backgroundElement : theme.backgroundPanel}
133+
>
134+
<text fg={theme.text}>
135+
Child <span style={{ fg: theme.textMuted }}>{keybind.print("session_child_first")}</span>
136+
</text>
137+
</box>
138+
</Show>
126139
</box>
127140
</box>
128141
</box>

0 commit comments

Comments
 (0)