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 4878c5af80..c96fdf268e 100644 --- a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx +++ b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx @@ -1960,12 +1960,15 @@ function Task(props: ToolProps) { const { navigate } = useRoute() const sync = useSync() - onMount(() => { - if (props.metadata.sessionId && !sync.data.message[props.metadata.sessionId]?.length) - void sync.session.sync(props.metadata.sessionId) + createEffect(() => { + const sessionID = props.metadata.sessionId + if (!sessionID) return + if (sync.data.message[sessionID]?.length) return + void sync.session.sync(sessionID) }) - const messages = createMemo(() => sync.data.message[props.metadata.sessionId ?? ""] ?? []) + const childSessionID = createMemo(() => props.metadata.sessionId) + const messages = createMemo(() => sync.data.message[childSessionID() ?? ""] ?? []) const tools = createMemo(() => { return messages().flatMap((msg) => @@ -1979,7 +1982,16 @@ function Task(props: ToolProps) { tools().findLast((x) => (x.state.status === "running" || x.state.status === "completed") && x.state.title), ) - const isRunning = createMemo(() => props.part.state.status === "running") + const isBackground = createMemo(() => props.metadata.background === true) + const isBackgroundRunning = createMemo(() => { + const sessionID = childSessionID() + if (!isBackground() || !sessionID) return false + const status = sync.data.session_status[sessionID]?.type + if (status === "busy" || status === "retry") return true + if (status === "idle") return false + return !messages().some((x) => x.role === "assistant" && x.time.completed) + }) + const isRunning = createMemo(() => props.part.state.status === "running" || isBackgroundRunning()) const duration = createMemo(() => { const first = messages().find((x) => x.role === "user")?.time.created @@ -1990,8 +2002,7 @@ function Task(props: ToolProps) { const content = createMemo(() => { if (!props.input.description) return "" - const description = - props.metadata.background === true ? `${props.input.description} (background)` : props.input.description + const description = isBackground() ? `${props.input.description} (background)` : props.input.description let content = [`${Locale.titlecase(props.input.subagent_type ?? "General")} Task — ${description}`] if (isRunning() && tools().length > 0) { @@ -2003,7 +2014,7 @@ function Task(props: ToolProps) { } else content.push(`↳ ${tools().length} toolcalls`) } - if (props.part.state.status === "completed") { + if (!isRunning() && props.part.state.status === "completed") { content.push(`└ ${tools().length} toolcalls · ${Locale.duration(duration())}`) } @@ -2018,8 +2029,9 @@ function Task(props: ToolProps) { pending="Delegating..." part={props.part} onClick={() => { - if (props.metadata.sessionId) { - navigate({ type: "session", sessionID: props.metadata.sessionId }) + const sessionID = childSessionID() + if (sessionID) { + navigate({ type: "session", sessionID }) } }} >