diff --git a/packages/app/src/components/terminal.tsx b/packages/app/src/components/terminal.tsx index e9df444d3..136de0938 100644 --- a/packages/app/src/components/terminal.tsx +++ b/packages/app/src/components/terminal.tsx @@ -423,7 +423,9 @@ export const Terminal = (props: TerminalProps) => { if (local.autoFocus !== false) focusTerminal() if (typeof document !== "undefined" && document.fonts) { - document.fonts.ready.then(scheduleFit) + document.fonts.ready.then(scheduleFit).catch(() => { + // Ignore font loading errors — scheduleFit is best-effort + }) } const onResize = t.onResize((size) => { @@ -435,7 +437,7 @@ export const Terminal = (props: TerminalProps) => { }) cleanups.push(() => disposeIfDisposable(onData)) const onKey = t.onKey((key) => { - if (key.key == "Enter") { + if (key.key === "Enter") { props.onSubmit?.() } }) diff --git a/packages/app/src/context/global-sync.tsx b/packages/app/src/context/global-sync.tsx index 265b0f682..147fdd53b 100644 --- a/packages/app/src/context/global-sync.tsx +++ b/packages/app/src/context/global-sync.tsx @@ -148,13 +148,17 @@ function createGlobalSync() { }) as typeof setGlobalStore if (projectInit instanceof Promise) { - void projectInit.then(() => { - if (!active) return - if (projectWritten) return - const cached = projectCache.value - if (cached.length === 0) return - setGlobalStore("project", cached) - }) + void projectInit + .then(() => { + if (!active) return + if (projectWritten) return + const cached = projectCache.value + if (cached.length === 0) return + setGlobalStore("project", cached) + }) + .catch(() => { + // Project init failed — ignore; the sync loop will retry + }) } const setSessionTodo = ( @@ -441,6 +445,7 @@ function createGlobalSync() { if (typeof requestAnimationFrame === "function") { eventFrame = requestAnimationFrame(() => { eventFrame = undefined + if (!active) return eventTimer = setTimeout(() => { eventTimer = undefined void globalSDK.event.start() diff --git a/packages/app/src/context/sync.tsx b/packages/app/src/context/sync.tsx index 43edf2865..4e7739c60 100644 --- a/packages/app/src/context/sync.tsx +++ b/packages/app/src/context/sync.tsx @@ -321,6 +321,7 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({ clearSessionPrefetch(directory, sessionIDs) for (const sessionID of sessionIDs) { globalSync.todo.set(sessionID, undefined) + clearOptimistic(directory, sessionID) } setStore( produce((draft) => { diff --git a/packages/app/src/pages/layout.tsx b/packages/app/src/pages/layout.tsx index 07e70ac94..c234e160c 100644 --- a/packages/app/src/pages/layout.tsx +++ b/packages/app/src/pages/layout.tsx @@ -1546,18 +1546,26 @@ export default function Layout(props: ParentProps) { function connectProvider() { const run = ++dialogRun - void import("@/components/dialog-select-provider").then((x) => { - if (dialogDead || dialogRun !== run) return - dialog.show(() => ) - }) + void import("@/components/dialog-select-provider") + .then((x) => { + if (dialogDead || dialogRun !== run) return + dialog.show(() => ) + }) + .catch(() => { + // Chunk failed to load — ignore; user can retry + }) } function openServer() { const run = ++dialogRun - void import("@/components/dialog-select-server").then((x) => { - if (dialogDead || dialogRun !== run) return - dialog.show(() => ) - }) + void import("@/components/dialog-select-server") + .then((x) => { + if (dialogDead || dialogRun !== run) return + dialog.show(() => ) + }) + .catch(() => { + // Chunk failed to load — ignore; user can retry + }) } function openSettingsSurface() { @@ -1774,13 +1782,18 @@ export default function Layout(props: ParentProps) { resolve(result) } else { const run = ++dialogRun - void import("@/components/dialog-select-directory").then((x) => { - if (dialogDead || dialogRun !== run) return - dialog.show( - () => , - () => resolve(null), - ) - }) + void import("@/components/dialog-select-directory") + .then((x) => { + if (dialogDead || dialogRun !== run) return + dialog.show( + () => , + () => resolve(null), + ) + }) + .catch(() => { + // Chunk failed to load — resolve gracefully + resolve(null) + }) } } diff --git a/packages/opencode/src/control-plane/workspace.ts b/packages/opencode/src/control-plane/workspace.ts index 03da67479..f0df9ed87 100644 --- a/packages/opencode/src/control-plane/workspace.ts +++ b/packages/opencode/src/control-plane/workspace.ts @@ -338,20 +338,27 @@ export namespace Workspace { continue } setStatus(space.id, "connected") - await parseSSE(res.body, signal, (evt) => { - const event = evt as SyncEvent.SerializedEvent + try { + await parseSSE(res.body, signal, (evt) => { + const event = evt as SyncEvent.SerializedEvent - try { - if (!event.type.startsWith("server.")) { - SyncEvent.replay(event) + try { + if (!event.type.startsWith("server.")) { + SyncEvent.replay(event) + } + } catch (err) { + log.warn("failed to replay sync event", { + workspaceID: space.id, + error: err, + }) } - } catch (err) { - log.warn("failed to replay sync event", { - workspaceID: space.id, - error: err, - }) - } - }) + }) + } catch (err) { + log.warn("sync stream parse error", { + workspaceID: space.id, + error: err, + }) + } setStatus(space.id, "disconnected") log.info("disconnected to sync: " + space.id) await sleep(250) diff --git a/packages/opencode/src/tool/agent.ts b/packages/opencode/src/tool/agent.ts index 14ef11dd7..b5e6388e3 100644 --- a/packages/opencode/src/tool/agent.ts +++ b/packages/opencode/src/tool/agent.ts @@ -153,6 +153,10 @@ const synthesizeOutput = ( header = "status: running" body = wrapper("") break + default: + header = `status: ${(part as { status: string }).status}` + body = wrapper("") + break } return { diff --git a/packages/opencode/src/tool/apply_patch.ts b/packages/opencode/src/tool/apply_patch.ts index e60d38906..742900b8b 100644 --- a/packages/opencode/src/tool/apply_patch.ts +++ b/packages/opencode/src/tool/apply_patch.ts @@ -32,7 +32,9 @@ function isSensitiveFile(filePath: string) { } function notFound(error: unknown) { - return typeof error === "object" && error !== null && "reason" in error && (error as any).reason?._tag === "NotFound" + if (typeof error !== "object" || error === null || !("reason" in error)) return false + const reason = (error as Record).reason + return typeof reason === "object" && reason !== null && "_tag" in reason && reason._tag === "NotFound" } function safeTotalDiff(changes: Array<{ diff: string; sensitive: boolean }>) {