summaryrefslogtreecommitdiffhomepage
path: root/packages
diff options
context:
space:
mode:
authorAdam <[email protected]>2025-11-18 11:35:17 -0600
committerAdam <[email protected]>2025-11-18 11:35:23 -0600
commit333b8e907bb758adca3da69f4af72b9abe08777a (patch)
tree6d8543480918607a1ce2941123835a4af7e072b4 /packages
parent13f319b64fcfb8ea34871ab5678514c0f5b3a04d (diff)
downloadopencode-333b8e907bb758adca3da69f4af72b9abe08777a.tar.gz
opencode-333b8e907bb758adca3da69f4af72b9abe08777a.zip
fix(desktop): busy state and reactivity
Diffstat (limited to 'packages')
-rw-r--r--packages/desktop/src/components/prompt-input.tsx2
-rw-r--r--packages/desktop/src/context/global-sync.tsx9
-rw-r--r--packages/desktop/src/context/session.tsx22
-rw-r--r--packages/desktop/src/context/sync.tsx1
-rw-r--r--packages/desktop/src/pages/directory-layout.tsx12
-rw-r--r--packages/desktop/src/pages/session.tsx16
6 files changed, 33 insertions, 29 deletions
diff --git a/packages/desktop/src/components/prompt-input.tsx b/packages/desktop/src/components/prompt-input.tsx
index c2948a659..b2e552f71 100644
--- a/packages/desktop/src/components/prompt-input.tsx
+++ b/packages/desktop/src/components/prompt-input.tsx
@@ -266,7 +266,7 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
if (!existing) {
const created = await sdk.client.session.create()
existing = created.data ?? undefined
- if (existing) navigate(`${local.slug()}/session/${existing.id}`)
+ if (existing) navigate(existing.id)
}
if (!existing) return
diff --git a/packages/desktop/src/context/global-sync.tsx b/packages/desktop/src/context/global-sync.tsx
index 99c679c93..785a39928 100644
--- a/packages/desktop/src/context/global-sync.tsx
+++ b/packages/desktop/src/context/global-sync.tsx
@@ -11,6 +11,7 @@ import type {
Project,
FileDiff,
Todo,
+ SessionStatus,
} from "@opencode-ai/sdk"
import { createStore, produce, reconcile } from "solid-js/store"
import { Binary } from "@/utils/binary"
@@ -25,6 +26,9 @@ type State = {
config: Config
path: Path
session: Session[]
+ session_status: {
+ [sessionID: string]: SessionStatus
+ }
session_diff: {
[sessionID: string]: FileDiff[]
}
@@ -68,6 +72,7 @@ export const { use: useGlobalSync, provider: GlobalSyncProvider } = createSimple
agent: [],
provider: [],
session: [],
+ session_status: {},
session_diff: {},
todo: {},
limit: 10,
@@ -108,6 +113,10 @@ export const { use: useGlobalSync, provider: GlobalSyncProvider } = createSimple
case "todo.updated":
setStore("todo", event.properties.sessionID, event.properties.todos)
break
+ case "session.status": {
+ setStore("session_status", event.properties.sessionID, event.properties.status)
+ break
+ }
case "message.updated": {
const messages = store.message[event.properties.info.sessionID]
if (!messages) {
diff --git a/packages/desktop/src/context/session.tsx b/packages/desktop/src/context/session.tsx
index 36319b0c5..64820b6ae 100644
--- a/packages/desktop/src/context/session.tsx
+++ b/packages/desktop/src/context/session.tsx
@@ -58,16 +58,13 @@ export const { use: useSession, provider: SessionProvider } = createSimpleContex
if (!store.messageId) return lastUserMessage()
return userMessages()?.find((m) => m.id === store.messageId)
})
- const working = createMemo(() => {
- if (!params.id) return false
- const last = lastUserMessage()
- if (!last) return false
- const assistantMessages = sync.data.message[params.id]?.filter(
- (m) => m.role === "assistant" && m.parentID == last?.id,
- ) as AssistantMessage[]
- const error = assistantMessages?.find((m) => m?.error)?.error
- return !last?.summary?.body && !error
- })
+ const status = createMemo(
+ () =>
+ sync.data.session_status[params.id] ?? {
+ type: "idle",
+ },
+ )
+ const working = createMemo(() => status()?.type !== "idle")
const cost = createMemo(() => {
const total = pipe(
@@ -102,8 +99,11 @@ export const { use: useSession, provider: SessionProvider } = createSimpleContex
})
return {
- id: params.id,
+ get id() {
+ return params.id
+ },
info,
+ status,
working,
diffs,
prompt: {
diff --git a/packages/desktop/src/context/sync.tsx b/packages/desktop/src/context/sync.tsx
index 14c0309c4..3852a6feb 100644
--- a/packages/desktop/src/context/sync.tsx
+++ b/packages/desktop/src/context/sync.tsx
@@ -26,6 +26,7 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
.slice(0, store.limit)
setStore("session", sessions)
}),
+ status: () => sdk.client.session.status().then((x) => setStore("session_status", x.data!)),
config: () => sdk.client.config.get().then((x) => setStore("config", x.data!)),
changes: () => sdk.client.file.status().then((x) => setStore("changes", x.data!)),
node: () => sdk.client.file.list({ query: { path: "/" } }).then((x) => setStore("node", x.data!)),
diff --git a/packages/desktop/src/pages/directory-layout.tsx b/packages/desktop/src/pages/directory-layout.tsx
index fe35f20f9..fff75d1af 100644
--- a/packages/desktop/src/pages/directory-layout.tsx
+++ b/packages/desktop/src/pages/directory-layout.tsx
@@ -14,12 +14,10 @@ export default function Layout(props: ParentProps) {
return sync.data.projects.find((x) => x.worktree === decoded)?.worktree ?? "/"
})
return (
- <Show when={params.id || true} keyed>
- <SDKProvider directory={directory()}>
- <SyncProvider>
- <LocalProvider>{props.children}</LocalProvider>
- </SyncProvider>
- </SDKProvider>
- </Show>
+ <SDKProvider directory={directory()}>
+ <SyncProvider>
+ <LocalProvider>{props.children}</LocalProvider>
+ </SyncProvider>
+ </SDKProvider>
)
}
diff --git a/packages/desktop/src/pages/session.tsx b/packages/desktop/src/pages/session.tsx
index 01d32a672..c273901cc 100644
--- a/packages/desktop/src/pages/session.tsx
+++ b/packages/desktop/src/pages/session.tsx
@@ -378,15 +378,9 @@ export default function Page() {
>
<For each={session.messages.user()}>
{(message) => {
- const assistantMessages = createMemo(() => {
- if (!session.id) return []
- return sync.data.message[session.id]?.filter(
- (m) => m.role === "assistant" && m.parentID == message.id,
- ) as AssistantMessageType[]
- })
- const error = createMemo(() => assistantMessages().find((m) => m?.error)?.error)
- const working = createMemo(() => !message.summary?.body && !error())
-
+ const working = createMemo(
+ () => message.id === session.messages.last()?.id && session.working(),
+ )
const handleClick = () => session.messages.setActive(message.id)
return (
@@ -473,7 +467,9 @@ export default function Page() {
?.flatMap((m) => sync.data.part[m.id])
.some((p) => p?.type === "tool"),
)
- const working = createMemo(() => !message.summary?.body && !error())
+ const working = createMemo(
+ () => message.id === session.messages.last()?.id && session.working(),
+ )
// allowing time for the animations to finish
createEffect(() => {