- Included @testing-library/jest-dom version 6.9.1 to enhance testing capabilities.
- Updated pnpm-lock.yaml to reflect the new dependency and its resolution details.
- Removed unused version click handling from Sidebar component to streamline code.
- Deleted the .eslintrc.cjs file to simplify configuration management.
- Updated lint scripts in package.json to remove unnecessary extensions for linting.
- Added new devDependencies for ESLint and globals to enhance linting capabilities.
Chat page:
- Move session selector, refresh, thinking toggle to the Header bar
(same level as "Chat" title) instead of inside the chat content area
- Add "New Session" button (+ icon) to create fresh chat sessions
- Remove duplicate toolbar from chat body
Settings page:
- Remove max-w-2xl constraint so cards fill available width
- Redesign provider cards: compact layout with key + actions in one row
- Shorten API key display (sk-...df67 format instead of full masked key)
- Move edit/delete/star buttons inside the key row background area
- Remove duplicate "AI Providers" heading (already in card header)
- Move ChatToolbar (session selector, refresh, thinking toggle) from
the Chat page body into the Header component, so controls appear
at the same level as the "Chat" title
- Add New Session button (+) to create a fresh conversation
- Add newSession action to chat store
- Header conditionally renders ChatToolbar only on /chat route
- Chat page fills full content area without duplicate toolbar
Replace the iframe-based Control UI embed with a native React
implementation that communicates directly with the Gateway via
gateway:rpc IPC calls and chat event streaming.
New components:
- ChatToolbar: session selector dropdown, refresh button, thinking toggle
- ChatMessage: message bubbles with markdown (react-markdown + GFM),
collapsible thinking blocks, tool use cards, image attachments
- ChatInput: textarea with Enter to send, Shift+Enter for new line
- message-utils: extractText/extractThinking/extractImages/extractToolUse
ported from OpenClaw's message-extract.ts
Rewritten chat store with:
- Session management (sessions.list, switchSession)
- Proper chat.history loading with raw message preservation
- chat.send with idempotencyKey and run tracking
- Streaming via handleChatEvent (delta/final/error/aborted)
- Thinking toggle (show/hide reasoning blocks)
The Dashboard crashed with 'channels.slice is not a function' because
channels.status returns a deeply nested object per channel ID, not a
Channel[] array. Same issue with skills.status.
For now, use empty arrays since channel/skill management is deferred
to their dedicated pages. Will properly parse the complex response
format when those pages are implemented.
- The session.webRequest.onHeadersReceived was stripping X-Frame-Options
and modifying CSP for ALL responses including the Vite dev server,
which could break the main app rendering. Now only applies to
gateway URLs (127.0.0.1:18789 / localhost:18789).
- Dashboard: only fetch channels/skills when gateway is running
- Dashboard: guard against non-array channels/skills data
- Gateway store: use dynamic import() instead of require() for chat
store to avoid ESM/CJS issues in Vite
If setup was previously completed but no provider API keys were saved
(due to the legacy bug where validation didn't persist keys), the app
now detects this on startup and redirects to the setup wizard so the
user can re-enter their key with the fixed save flow.