diff --git a/packages/app/src/components/prompt-input.tsx b/packages/app/src/components/prompt-input.tsx index eaeedf087e..1e1be28b59 100644 --- a/packages/app/src/components/prompt-input.tsx +++ b/packages/app/src/components/prompt-input.tsx @@ -240,13 +240,7 @@ export const PromptInput: Component = (props) => { return paths }) const info = createMemo(() => (params.id ? sync.session.get(params.id) : undefined)) - const status = createMemo( - () => - sync.data.session_status[params.id ?? ""] ?? { - type: "idle", - }, - ) - const working = createMemo(() => status()?.type !== "idle") + const working = createMemo(() => sync.data.session_working(params.id ?? "")) const imageAttachments = createMemo(() => prompt.current().filter((part): part is ImageAttachmentPart => part.type === "image"), ) diff --git a/packages/app/src/context/global-sync/child-store.ts b/packages/app/src/context/global-sync/child-store.ts index e8ca597d15..af90fab6b3 100644 --- a/packages/app/src/context/global-sync/child-store.ts +++ b/packages/app/src/context/global-sync/child-store.ts @@ -208,6 +208,9 @@ export function createChildStoreManager(input: { session: [], sessionTotal: 0, session_status: {}, + session_working(id: string) { + return this.session_status[id].type !== "idle" + }, session_diff: {}, todo: {}, permission: {}, diff --git a/packages/app/src/context/global-sync/types.ts b/packages/app/src/context/global-sync/types.ts index 6bf42a0737..43837ac97f 100644 --- a/packages/app/src/context/global-sync/types.ts +++ b/packages/app/src/context/global-sync/types.ts @@ -46,6 +46,7 @@ export type State = { session_status: { [sessionID: string]: SessionStatus } + session_working(id: string): boolean session_diff: { [sessionID: string]: SnapshotFileDiff[] } diff --git a/packages/app/src/pages/layout/sidebar-items.tsx b/packages/app/src/pages/layout/sidebar-items.tsx index 3aac5a6131..77d9a03d9d 100644 --- a/packages/app/src/pages/layout/sidebar-items.tsx +++ b/packages/app/src/pages/layout/sidebar-items.tsx @@ -166,9 +166,7 @@ export const SessionItem = (props: SessionItemProps): JSX.Element => { }) const isWorking = createMemo(() => { if (hasPermissions()) return false - // This matches how the TUI does it - const status = sessionStore.session_status[props.session.id] - return status?.type === "busy" || status?.type === "retry" + return sessionStore.session_working(props.session.id) }) const tint = createMemo(() => messageAgentColor(sessionStore.message[props.session.id], sessionStore.agent)) diff --git a/packages/app/src/pages/layout/sidebar-project.tsx b/packages/app/src/pages/layout/sidebar-project.tsx index 58595c25b9..b910dd2098 100644 --- a/packages/app/src/pages/layout/sidebar-project.tsx +++ b/packages/app/src/pages/layout/sidebar-project.tsx @@ -305,7 +305,7 @@ export const SortableProject = (props: { const isWorking = createMemo(() => dirs().some((directory) => { 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())) diff --git a/packages/app/src/pages/session.tsx b/packages/app/src/pages/session.tsx index 8bc7e6a5ca..1e73ed590f 100644 --- a/packages/app/src/pages/session.tsx +++ b/packages/app/src/pages/session.tsx @@ -1496,10 +1496,7 @@ export default function Page() { return out }) - const busy = (sessionID: string) => { - // This matches how the TUI does it - return (sync.data.session_status[sessionID] ?? { type: "idle" as const }).type !== "idle" - } + const busy = (sessionID: string) => sync.data.session_working(sessionID) const queuedFollowups = createMemo(() => { const id = params.id diff --git a/packages/app/src/pages/session/composer/session-composer-state.ts b/packages/app/src/pages/session/composer/session-composer-state.ts index 525766dcfa..a7213c4a7d 100644 --- a/packages/app/src/pages/session/composer/session-composer-state.ts +++ b/packages/app/src/pages/session/composer/session-composer-state.ts @@ -57,14 +57,7 @@ export function createSessionComposerState(options?: { closeMs?: number | (() => () => todos().length > 0 && todos().every((todo) => todo.status === "completed" || todo.status === "cancelled"), ) - const status = createMemo(() => { - 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 live = createMemo(() => sync.data.session_working(params.id ?? "") || blocked()) const [store, setStore] = createStore({ responding: undefined as string | undefined, diff --git a/packages/app/src/pages/session/use-session-commands.tsx b/packages/app/src/pages/session/use-session-commands.tsx index 922299bec1..b45d110b94 100644 --- a/packages/app/src/pages/session/use-session-commands.tsx +++ b/packages/app/src/pages/session/use-session-commands.tsx @@ -75,8 +75,6 @@ export const useSessionCommands = (actions: SessionCommandContext) => { import.meta.env.VITE_OPENCODE_CHANNEL !== "beta" || settings.general.showFileTree() - const idle = { type: "idle" as const } - const status = () => sync.data.session_status[params.id ?? ""] ?? idle const messages = () => { const id = params.id if (!id) return [] @@ -290,7 +288,7 @@ export const useSessionCommands = (actions: SessionCommandContext) => { const sessionID = params.id if (!sessionID) return - if (status().type !== "idle") { + if (sync.data.session_working(params.id ?? "")) { await sdk.client.session.abort({ sessionID }).catch(() => {}) }