From b18933f19c8f3ed731afd3c6eec0387790df617d Mon Sep 17 00:00:00 2001 From: Bohdan Triapitsyn Date: Sat, 29 Aug 2026 23:22:27 +0300 Subject: [PATCH] feat(chat): surface failed turns and add error diagnostics to the status report A turn that OpenCode stopped could end with nothing on screen: the session.error event was only turned into a sidebar badge, its message was dropped (the notification expected a different shape than OpenCode sends), and a send that was accepted but never answered looked the same as success. - The chat shows what OpenCode reported under the last message while that turn is the latest one, and names a user message an idle session has left unanswered for five seconds. - The last 20 session errors are kept in memory and listed in the status report (Ctrl/Cmd+Shift+L, also `__opencodeDebug.statusReport()`), next to rejected sends, the managed OpenCode process's last error and stderr tail, and the OpenCode and desktop log file locations. - The OpenCode health probe hits /global/health instead of a route that does not exist, and probe URLs resolve against the page for web runtimes. --- .../ui/src/components/chat/ChatContainer.tsx | 2 + .../components/chat/SessionErrorNotice.tsx | 112 ++++++++++++++++++ packages/ui/src/lib/debug.ts | 15 +++ packages/ui/src/lib/i18n/messages/de.ts | 3 + packages/ui/src/lib/i18n/messages/en.ts | 3 + packages/ui/src/lib/i18n/messages/es.ts | 3 + packages/ui/src/lib/i18n/messages/fr.ts | 3 + packages/ui/src/lib/i18n/messages/ja.ts | 3 + packages/ui/src/lib/i18n/messages/ko.ts | 3 + packages/ui/src/lib/i18n/messages/pl.ts | 3 + packages/ui/src/lib/i18n/messages/pt-BR.ts | 3 + packages/ui/src/lib/i18n/messages/tr.ts | 3 + packages/ui/src/lib/i18n/messages/uk.ts | 3 + packages/ui/src/lib/i18n/messages/zh-CN.ts | 3 + packages/ui/src/lib/i18n/messages/zh-TW.ts | 3 + packages/ui/src/lib/openCodeStatus.ts | 99 +++++++++++++++- packages/ui/src/sync/DOCUMENTATION.md | 16 +++ packages/ui/src/sync/notification-store.ts | 15 ++- .../ui/src/sync/session-error-log.test.ts | 32 +++++ packages/ui/src/sync/session-error-log.ts | 59 +++++++++ packages/ui/src/sync/sync-context.tsx | 11 +- 21 files changed, 390 insertions(+), 7 deletions(-) create mode 100644 packages/ui/src/components/chat/SessionErrorNotice.tsx create mode 100644 packages/ui/src/sync/session-error-log.test.ts create mode 100644 packages/ui/src/sync/session-error-log.ts diff --git a/packages/ui/src/components/chat/ChatContainer.tsx b/packages/ui/src/components/chat/ChatContainer.tsx index ddcb0fc3..5c70ee79 100644 --- a/packages/ui/src/components/chat/ChatContainer.tsx +++ b/packages/ui/src/components/chat/ChatContainer.tsx @@ -28,6 +28,7 @@ import { QuestionCard } from './QuestionCard'; import { hasActiveQuestionToolInCurrentTurn, recoverPendingQuestionWithRetry } from '@/sync/question-recovery'; import { StatusRowContainer } from './StatusRowContainer'; import { SessionRecapNote } from '@/components/chat/SessionRecapSpacer'; +import { SessionErrorNotice } from '@/components/chat/SessionErrorNotice'; import ScrollToBottomButton from './components/ScrollToBottomButton'; import { PromptNavigatorRail } from './components/PromptNavigatorRail'; import { useAuthSessionStore } from '@/lib/runtime-auth-expiry'; @@ -375,6 +376,7 @@ const ChatViewport = React.memo(({ )} +