Skip to content

Commit 6bfce60

Browse files
committed
fix(session): ignore stale pending ui state
Inline the app-side running checks and make the tui only treat the trailing assistant as pending so old crashed messages do not keep sessions active or queued.
1 parent 060f482 commit 6bfce60

6 files changed

Lines changed: 14 additions & 65 deletions

File tree

‎packages/app/src/pages/layout/sidebar-items.tsx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import { useLanguage } from "@/context/language"
1515
import { getAvatarColors, type LocalProject, useLayout } from "@/context/layout"
1616
import { useNotification } from "@/context/notification"
1717
import { usePermission } from "@/context/permission"
18-
import { working } from "@/pages/session/activity"
1918
import { messageAgentColor } from "@/utils/agent"
2019
import { sessionPermissionRequest } from "../session/composer/session-request-tree"
2120
import { hasProjectPermissions } from "./helpers"
@@ -205,7 +204,8 @@ export const SessionItem = (props: SessionItemProps): JSX.Element => {
205204
})
206205
const isWorking = createMemo(() => {
207206
if (hasPermissions()) return false
208-
return working(sessionStore.session_status[props.session.id])
207+
const status = sessionStore.session_status[props.session.id]
208+
return status !== undefined && status.type !== "idle"
209209
})
210210

211211
const tint = createMemo(() => {

‎packages/app/src/pages/session.tsx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ import { useSettings } from "@/context/settings"
3939
import { useSync } from "@/context/sync"
4040
import { useTerminal } from "@/context/terminal"
4141
import { type FollowupDraft, sendFollowupDraft } from "@/components/prompt-input/submit"
42-
import { working } from "@/pages/session/activity"
4342
import { createSessionComposerState, SessionComposerRegion } from "@/pages/session/composer"
4443
import { createOpenReviewFile, createSessionTabs, createSizing, focusTerminalById } from "@/pages/session/helpers"
4544
import { MessageTimeline } from "@/pages/session/message-timeline"
@@ -1362,7 +1361,8 @@ export default function Page() {
13621361
})
13631362

13641363
const busy = (sessionID: string) => {
1365-
return working(sync.data.session_status[sessionID])
1364+
const status = sync.data.session_status[sessionID]
1365+
return status !== undefined && status.type !== "idle"
13661366
}
13671367

13681368
const queuedFollowups = createMemo(() => {

‎packages/app/src/pages/session/activity.test.ts‎

Lines changed: 0 additions & 46 deletions
This file was deleted.

‎packages/app/src/pages/session/activity.ts‎

Lines changed: 0 additions & 10 deletions
This file was deleted.

‎packages/app/src/pages/session/message-timeline.tsx‎

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { Spinner } from "@opencode-ai/ui/spinner"
1212
import { SessionTurn } from "@opencode-ai/ui/session-turn"
1313
import { ScrollView } from "@opencode-ai/ui/scroll-view"
1414
import { TextField } from "@opencode-ai/ui/text-field"
15-
import type { Message as MessageType, Part, TextPart, UserMessage } from "@opencode-ai/sdk/v2"
15+
import type { AssistantMessage, Message as MessageType, Part, TextPart, UserMessage } from "@opencode-ai/sdk/v2"
1616
import { showToast } from "@opencode-ai/ui/toast"
1717
import { Binary } from "@opencode-ai/util/binary"
1818
import { getFilename } from "@opencode-ai/util/path"
@@ -27,7 +27,6 @@ import { usePlatform } from "@/context/platform"
2727
import { useSettings } from "@/context/settings"
2828
import { useSDK } from "@/context/sdk"
2929
import { useSync } from "@/context/sync"
30-
import { pending, working } from "@/pages/session/activity"
3130
import { messageAgentColor } from "@/utils/agent"
3231
import { parseCommentNote, readCommentMetadata } from "@/utils/comment-note"
3332

@@ -237,13 +236,17 @@ export function MessageTimeline(props: {
237236
if (!id) return emptyMessages
238237
return sync.data.message[id] ?? emptyMessages
239238
})
240-
const assistant = createMemo(() => pending(sessionMessages()))
239+
const assistant = createMemo(() => {
240+
const item = sessionMessages().findLast((item): item is AssistantMessage => item.role === "assistant")
241+
if (!item || typeof item.time.completed === "number") return
242+
return item
243+
})
241244
const sessionStatus = createMemo(() => {
242245
const id = sessionID()
243246
if (!id) return idle
244247
return sync.data.session_status[id] ?? idle
245248
})
246-
const busy = createMemo(() => working(sessionStatus()))
249+
const busy = createMemo(() => sessionStatus().type !== "idle")
247250
const tint = createMemo(() => messageAgentColor(sessionMessages(), sync.data.agent))
248251

249252
const [slot, setSlot] = createStore({

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,9 @@ export function Session() {
139139
})
140140

141141
const pending = createMemo(() => {
142-
return messages().findLast((x) => x.role === "assistant" && !x.time.completed)?.id
142+
const last = messages().findLast((x) => x.role === "assistant")
143+
if (!last || last.time.completed) return
144+
return last.id
143145
})
144146

145147
const lastAssistant = createMemo(() => {

0 commit comments

Comments
 (0)