- 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.
- Upgraded pnpm/action-setup from v2 to v4 in both CI and release workflows.
- Updated pnpm version from 8 to 9 to ensure compatibility with the latest features and improvements.
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)
- Changed the OpenClaw submodule URL to the official GitHub repository for proper integration.
- Implemented automatic gateway token generation on first launch, ensuring seamless authentication for users.
- Updated the gateway manager to utilize the generated token for WebSocket connections.
- 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)
OpenClaw's model resolution checks cfg.models.providers[provider] for
baseUrl and API type. Without this config entry, any model for that
provider returns "Unknown model" even if the API key is correct.
- Reverted model names back to user-specified versions
- Added PROVIDER_CONFIGS with baseUrl, api type, and env var name
- setOpenClawDefaultModel() now writes models.providers.openrouter
(and other providers) to openclaw.json so model resolution works
- Config format: { models: { providers: { openrouter: {
baseUrl: "https://openrouter.ai/api/v1",
api: "openai-completions",
apiKey: "OPENROUTER_API_KEY" } } } }
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
OpenClaw expects agents.defaults.model as { primary: "provider/model" }
not a plain string. The previous code wrote a string which caused:
"agents.defaults.model: Invalid input: expected object, received string"
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.
- Add setOpenClawDefaultModel() to write the correct model to
~/.openclaw/openclaw.json based on the selected provider
- Maps: openrouter -> openrouter/anthropic/claude-sonnet-4,
anthropic -> anthropic/claude-sonnet-4, etc.
- Call setOpenClawDefaultModel on provider:save IPC handler
- Fixes "No API key found for provider anthropic" when user
configured OpenRouter (wrong default model was being used)
The <webview> tag had issues with event listener attachment and React
ref handling, causing the loading overlay to stay forever (white screen).
Switched to a standard <iframe> which is simpler and works reliably:
- Uses iframe onLoad/onError instead of webview dom-ready events
- Added 5s fallback timeout to dismiss loading overlay
- The X-Frame-Options/CSP header overrides from session.webRequest
allow the iframe to load the Control UI
Part 1: API Key Integration
- Create electron/utils/openclaw-auth.ts to write keys to
~/.openclaw/agents/main/agent/auth-profiles.json
- Update provider:save and provider:setApiKey IPC handlers to
persist keys to OpenClaw auth-profiles alongside ClawX storage
- Save API key to OpenClaw on successful validation in Setup wizard
- Pass provider API keys as environment variables when starting
the Gateway process (ANTHROPIC_API_KEY, OPENROUTER_API_KEY, etc.)
Part 2: Embed OpenClaw Control UI for Chat
- Replace custom Chat UI with <webview> embedding the Gateway's
built-in Control UI at http://127.0.0.1:{port}/?token={token}
- Add gateway:getControlUiUrl IPC handler to provide tokenized URL
- Enable webviewTag in Electron BrowserWindow preferences
- Override X-Frame-Options/CSP headers to allow webview embedding
- Suppress noisy control-ui token_mismatch stderr messages
- Add loading/error states for the embedded webview
This fixes the "No API key found for provider" error and replaces
the buggy custom chat implementation with OpenClaw's battle-tested
Control UI.
- Fix channels store: use channels.status instead of channels.list
- Fix skills store: use skills.status instead of skills.list
- Fix chat store: correct chat.history response parsing (messages in payload)
- Fix chat store: handle chat.send async flow (ack + event streaming)
- Add chat event handling for streaming AI responses (delta/final/error)
- Wire gateway:chat-message IPC events to chat store
- Fix health check: use WebSocket status instead of nonexistent /health endpoint
- Fix waitForReady: probe via WebSocket instead of HTTP
- Gracefully degrade when methods are unsupported (no white screen)
- Replace mock API key validation with actual API calls to verify keys
- Add validateApiKeyWithProvider() with provider-specific implementations
- Support Anthropic, OpenAI, Google, and OpenRouter validation
- Add OpenRouter as a new provider option in setup wizard and settings
- Fix setup page to call real validation instead of mock length check
- Allow validation during setup before provider is saved
- Return user-friendly error messages instead of raw API errors
- Change submodule URL from local path to https://github.com/openclaw/openclaw.git
- Checkout stable version v2026.2.3
- Add auto-generated gateway token (clawx-xxx) stored in electron-store
- Pass token via --token argument and OPENCLAW_GATEWAY_TOKEN env var
- Include token in WebSocket URL for authentication
- Add --dev and --allow-unconfigured flags for first-time setup
- Add OpenClaw as git submodule at ./openclaw/
- Update GatewayManager to start gateway from submodule path
- Support both production (dist) and development (pnpm dev) modes
- Add IPC handler for OpenClaw status check
- Update Setup wizard to check real OpenClaw submodule status
- Configure electron-builder to include submodule in packaged app
- Add npm scripts for submodule management:
- postinstall: auto-init submodule
- openclaw:init: initialize and install dependencies
- openclaw:install: install dependencies only
- openclaw:build: build OpenClaw
- openclaw:update: update to latest version
- Add markdown rendering with react-markdown and remark-gfm
- Create ChatMessage component with code copy functionality
- Add typing indicator animation during AI response
- Create welcome screen for new users
- Add Textarea component for multi-line input
- Improve message styling with avatars and hover actions
- Add Gateway connection status awareness
- Add prose styling for markdown content
- Add AppUpdater module with update lifecycle management
- Create UpdateSettings UI component with progress display
- Add Progress UI component based on Radix UI
- Create update Zustand store for state management
- Register update IPC handlers in main process
- Auto-check for updates on production startup
- Add commit documentation for commits 2-6