Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 35 additions & 17 deletions packages/opencode/src/cli/cmd/tui/routes/session/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,11 @@ export function Session() {
.filter((x) => x.parentID === parentID || x.id === parentID)
.toSorted((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0))
})
const subagents = createMemo(() => {
return sync.data.session
.filter((x) => x.parentID === route.sessionID)
.toSorted((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0))
})
const messages = createMemo(() => sync.data.message[route.sessionID] ?? [])
const permissions = createMemo(() => {
if (session()?.parentID) return []
Expand Down Expand Up @@ -316,20 +321,14 @@ export function Session() {
const local = useLocal()

function moveFirstChild() {
if (children().length === 1) return
const next = children().find((x) => !!x.parentID)
if (next) {
navigate({
type: "session",
sessionID: next.id,
})
}
const next = subagents()[0]
if (!next) return
navigate({ type: "session", sessionID: next.id })
}

function moveChild(direction: number) {
if (children().length === 1) return

const sessions = children().filter((x) => !!x.parentID)
if (sessions.length === 0) return
let next = sessions.findIndex((x) => x.id === session()?.id) + direction

if (next >= sessions.length) next = 0
Expand Down Expand Up @@ -1124,7 +1123,7 @@ export function Session() {
<UserMessage
index={index()}
onMouseUp={() => {
if (renderer.getSelection()?.getSelectedText()) return
if (renderer.hasSelection) return
dialog.replace(() => (
<DialogMessage
messageID={message.id}
Expand Down Expand Up @@ -1623,13 +1622,16 @@ function InlineTool(props: {
complete: any
pending: string
spinner?: boolean
onClick?: () => void
children: JSX.Element
part: ToolPart
}) {
const [margin, setMargin] = createSignal(0)
const { theme } = useTheme()
const ctx = use()
const sync = useSync()
const renderer = useRenderer()
const [hover, setHover] = createSignal(false)

const permission = createMemo(() => {
const callID = sync.data.permission[ctx.sessionID]?.at(0)?.tool?.callID
Expand Down Expand Up @@ -1678,13 +1680,23 @@ function InlineTool(props: {
return
}
}}
onMouseOver={() => props.onClick && setHover(true)}
onMouseOut={() => setHover(false)}
onMouseUp={() => {
if (renderer.hasSelection) return
props.onClick?.()
}}
>
<Switch>
<Match when={props.spinner}>
<Spinner color={fg()} children={props.children} />
<Spinner color={hover() ? theme.text : fg()} children={props.children} />
</Match>
<Match when={true}>
<text paddingLeft={3} fg={fg()} attributes={denied() ? TextAttributes.STRIKETHROUGH : undefined}>
<text
paddingLeft={3}
fg={hover() ? theme.text : fg()}
attributes={denied() ? TextAttributes.STRIKETHROUGH : undefined}
>
<Show fallback={<>~ {props.pending}</>} when={props.complete}>
<span style={{ fg: props.iconColor }}>{props.icon}</span> {props.children}
</Show>
Expand Down Expand Up @@ -1723,7 +1735,7 @@ function BlockTool(props: {
onMouseOver={() => props.onClick && setHover(true)}
onMouseOut={() => setHover(false)}
onMouseUp={() => {
if (renderer.getSelection()?.getSelectedText()) return
if (renderer.hasSelection) return
props.onClick?.()
}}
>
Expand Down Expand Up @@ -1943,10 +1955,7 @@ function WebSearch(props: ToolProps<any>) {
}

function Task(props: ToolProps<typeof TaskTool>) {
const { theme } = useTheme()
const keybind = useKeybind()
const { navigate } = useRoute()
const local = useLocal()
const sync = useSync()

onMount(() => {
Expand Down Expand Up @@ -1999,6 +2008,15 @@ function Task(props: ToolProps<typeof TaskTool>) {
complete={props.input.description}
pending="Delegating..."
part={props.part}
onClick={
props.metadata.sessionId
? () => {
const id = props.metadata.sessionId
if (!id) return
navigate({ type: "session", sessionID: id })
}
: undefined
}
>
{content()}
</InlineTool>
Expand Down
Loading