Compare commits

...
Sign in to create a new pull request.

3 commits

Author SHA1 Message Date
Brendan Allan
2524d39a1d
fix(app): use session_working helper for busy state checks 2026-05-13 09:00:40 +08:00
LukeParkerDev
9ad4403df7 fix(app): show retry sessions as working 2026-05-13 09:16:33 +10:00
LukeParkerDev
ad318bce65 fix(app): use session status for busy state 2026-05-13 09:07:48 +10:00
8 changed files with 10 additions and 37 deletions

View file

@ -240,13 +240,7 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
return paths return paths
}) })
const info = createMemo(() => (params.id ? sync.session.get(params.id) : undefined)) const info = createMemo(() => (params.id ? sync.session.get(params.id) : undefined))
const status = createMemo( const working = createMemo(() => sync.data.session_working(params.id ?? ""))
() =>
sync.data.session_status[params.id ?? ""] ?? {
type: "idle",
},
)
const working = createMemo(() => status()?.type !== "idle")
const imageAttachments = createMemo(() => const imageAttachments = createMemo(() =>
prompt.current().filter((part): part is ImageAttachmentPart => part.type === "image"), prompt.current().filter((part): part is ImageAttachmentPart => part.type === "image"),
) )

View file

@ -208,6 +208,9 @@ export function createChildStoreManager(input: {
session: [], session: [],
sessionTotal: 0, sessionTotal: 0,
session_status: {}, session_status: {},
session_working(id: string) {
return this.session_status[id].type !== "idle"
},
session_diff: {}, session_diff: {},
todo: {}, todo: {},
permission: {}, permission: {},

View file

@ -46,6 +46,7 @@ export type State = {
session_status: { session_status: {
[sessionID: string]: SessionStatus [sessionID: string]: SessionStatus
} }
session_working(id: string): boolean
session_diff: { session_diff: {
[sessionID: string]: SnapshotFileDiff[] [sessionID: string]: SnapshotFileDiff[]
} }

View file

@ -166,18 +166,7 @@ export const SessionItem = (props: SessionItemProps): JSX.Element => {
}) })
const isWorking = createMemo(() => { const isWorking = createMemo(() => {
if (hasPermissions()) return false if (hasPermissions()) return false
const pending = (sessionStore.message[props.session.id] ?? []).findLast( return sessionStore.session_working(props.session.id)
(message) =>
message.role === "assistant" &&
typeof (message as { time?: { completed?: unknown } }).time?.completed !== "number",
)
const status = sessionStore.session_status[props.session.id]
return (
pending !== undefined ||
status?.type === "busy" ||
status?.type === "retry" ||
(status !== undefined && status.type !== "idle")
)
}) })
const tint = createMemo(() => messageAgentColor(sessionStore.message[props.session.id], sessionStore.agent)) const tint = createMemo(() => messageAgentColor(sessionStore.message[props.session.id], sessionStore.agent))

View file

@ -305,7 +305,7 @@ export const SortableProject = (props: {
const isWorking = createMemo(() => const isWorking = createMemo(() =>
dirs().some((directory) => { dirs().some((directory) => {
const [store] = globalSync.child(directory, { bootstrap: false }) const [store] = globalSync.child(directory, { bootstrap: false })
return Object.values(store.session_status).some((status) => status?.type === "busy" || status?.type === "retry") return Object.keys(store.session_status).some((id) => store.session_working(id))
}), }),
) )
const projectSessions = createMemo(() => sortedRootSessions(projectStore(), props.sortNow())) const projectSessions = createMemo(() => sortedRootSessions(projectStore(), props.sortNow()))

View file

@ -1496,12 +1496,7 @@ export default function Page() {
return out return out
}) })
const busy = (sessionID: string) => { const busy = (sessionID: string) => sync.data.session_working(sessionID)
if ((sync.data.session_status[sessionID] ?? { type: "idle" as const }).type !== "idle") return true
return (sync.data.message[sessionID] ?? []).some(
(item) => item.role === "assistant" && typeof item.time.completed !== "number",
)
}
const queuedFollowups = createMemo(() => { const queuedFollowups = createMemo(() => {
const id = params.id const id = params.id

View file

@ -57,14 +57,7 @@ export function createSessionComposerState(options?: { closeMs?: number | (() =>
() => todos().length > 0 && todos().every((todo) => todo.status === "completed" || todo.status === "cancelled"), () => todos().length > 0 && todos().every((todo) => todo.status === "completed" || todo.status === "cancelled"),
) )
const status = createMemo(() => { const live = createMemo(() => sync.data.session_working(params.id ?? "") || blocked())
const id = params.id
if (!id) return idle
return sync.data.session_status[id] ?? idle
})
const busy = createMemo(() => status().type !== "idle")
const live = createMemo(() => busy() || blocked())
const [store, setStore] = createStore({ const [store, setStore] = createStore({
responding: undefined as string | undefined, responding: undefined as string | undefined,

View file

@ -75,8 +75,6 @@ export const useSessionCommands = (actions: SessionCommandContext) => {
import.meta.env.VITE_OPENCODE_CHANNEL !== "beta" || import.meta.env.VITE_OPENCODE_CHANNEL !== "beta" ||
settings.general.showFileTree() settings.general.showFileTree()
const idle = { type: "idle" as const }
const status = () => sync.data.session_status[params.id ?? ""] ?? idle
const messages = () => { const messages = () => {
const id = params.id const id = params.id
if (!id) return [] if (!id) return []
@ -290,7 +288,7 @@ export const useSessionCommands = (actions: SessionCommandContext) => {
const sessionID = params.id const sessionID = params.id
if (!sessionID) return if (!sessionID) return
if (status().type !== "idle") { if (sync.data.session_working(params.id ?? "")) {
await sdk.client.session.abort({ sessionID }).catch(() => {}) await sdk.client.session.abort({ sessionID }).catch(() => {})
} }