* fix: prevent message send when Chinese IME is composing
- Add e.isComposing check to Enter key handler in ChatInput
- This prevents accidental message sending when pressing Enter to confirm Chinese/Japanese input
- Fixes issue where messages would be sent prematurely when using IME composition
Refs: #issue
* fix: prevent message send when Chinese IME is composing
- Add isComposing state to track IME composition status
- Add onCompositionStart/onCompositionEnd event handlers to textarea
- Check isComposing state in Enter key handler to prevent accidental send
This fixes the issue where pressing Enter to confirm Chinese/Japanese input
would prematurely send the message instead of just confirming the IME selection.
The fix uses explicit composition state tracking instead of relying solely on
e.isComposing, which provides more reliable cross-browser behavior.
---------
Co-authored-by: 代码专家 <coder@openclaw.ai>
- Move guessLanguage, looksLikeCode, autoFormatText to src/lib/autoFormat.ts
- Add comprehensive test suite (23 tests) covering language detection, code detection, and auto-formatting
- Reduce ChatMessage.tsx by ~90 lines
- Total tests: 238 (up from 215)
When selecting a slash command without arguments (e.g. /new, /status, /help)
from the autocomplete menu, the command now executes immediately instead of
getting stuck in a loop where the menu kept intercepting Enter keypresses.
Fixes#17
Replace standalone lazy import of ReactMarkdown + remark-gfm in
ChatInput with the existing LazyMarkdown component, which already
handles lazy loading with remark-gfm, remark-breaks, and
rehype-highlight. Reduces code duplication and ensures consistent
markdown rendering between chat messages and the input preview.
Introduces a `/new` slash command that lets users create a fresh chat
session for the current agent without leaving the chat input.
- Add `createNewSession` to `useGateway` that calls `sessions.create`
on the gateway (with a client-side fallback key when the RPC is
unavailable).
- Register `/new` in the slash-command menu with i18n descriptions
across all 8 supported languages.
- Wire `onNewSession` through `Chat` → `ChatInput` so typing `/new`
triggers session creation.
- Add `extractAgentIdFromKey` and `formatAgentId` helpers to
`sessionName.ts` to derive a human-readable agent name from the
session key (e.g. `agent:my-cool-bot:…` → "My Cool Bot").
- Use the new helpers in `Header` and `App` to show per-session agent
names, especially for sub-agent sessions where the gateway-level
identity differs from the session agent.
Made-with: Cursor
ToolCall.tsx previously imported highlight.js statically, pulling the
entire hljs bundle into the main Chat chunk and preventing Vite from
splitting it into the lazy markdown chunk.
Now hljs is dynamically imported and loaded on first use. This:
- Removes the Vite build warning about mixed static/dynamic imports
- Reduces the Chat chunk by ~1.6 KB
- Consolidates hljs into the lazy markdown chunk
- Renders unhighlighted text instantly, then re-renders with syntax
highlighting once hljs loads (typically < 100ms)
Images sent by the user were transmitted to the gateway correctly but
not shown in the chat UI, making it appear as if attachments were lost.
Now image blocks are included in the user message for immediate visual
feedback.
Closes#14
- Move extractText and extractThinking from useGateway and useSecondarySession into shared lib
- Add comprehensive unit tests (13 tests) for both functions
- Eliminate code duplication between the two hooks
Add a clientId option that can be set via:
- VITE_CLIENT_ID env var at build time
- Advanced section in the login screen at runtime
- Stored in localStorage with other credentials
Defaults to 'webchat' for backward compatibility. Users can set it
to 'openclaw-control-ui' to use OpenClaw's dangerouslyDisableDeviceAuth
bypass without post-install patching.
Closes#11
- ChatInput: add aria-labels to remove file, send shortcut toggle, and stop buttons
- CodeBlock: add aria-labels to word wrap, line numbers, and collapse/expand buttons
- Header: add aria-labels to session info, copy, close, and compact buttons
Add token/password auth mode toggle on the login screen.
When password mode is selected, sends { password } instead of
{ token } in the WebSocket connect handshake.
Also adds clipboard utility tests and fixes credential test
to include authMode field.
When OpenClaw's webchat relays user messages, it wraps them in metadata
(conversation info JSON block + UTC timestamp prefix). This strips the
envelope at render time so users see only their actual text.
- Add hasWebchatEnvelope() and stripWebchatEnvelope() to systemEvent.ts
- Chain webchat + webhook stripping via stripAll() helper in ChatMessage
- Fix 'webhook' label only appearing for actual webhook messages, not
for envelope-stripped webchat messages
Co-authored-by: togotago <drewmfleury@gmail.com>
System events now render as compact pills (label + chevron + timestamp)
that expand on click to reveal the full message content.
- Collapsed (default): rounded-full pill with Zap icon, label, ChevronDown,
and timestamp. Clean single-line appearance.
- Expanded (on click): rounded-xl container with full message text shown
below in whitespace-pre-wrap. Chevron rotates 180deg.
- Added cursor-pointer and hover:bg-pc-elevated/50 for discoverability.
- Removed always-visible truncated text from collapsed state for a cleaner
default appearance.
Co-authored-by: togotago <drewmfleury@gmail.com>