Releases: Saleh7/clawkernel
ClawKernel 2026.2.26
2026.2.26
Added
Testing Infrastructure (Vitest)
- Vitest test runner —
vitest+happy-dom+@testing-library/react+@vitest/coverage-v8added. - Test config — new
vitest.config.tswith@alias resolution and focused coverage include list for core business-logic files. - Comprehensive test suite — added
tests/tree:- Unit tests: cron, chat utils, gateway client/store, sessions utils, tool policy, device auth, formatting, text direction, agent status/utils, config utils.
- Integration tests:
use-chathook behavior.
- NPM scripts —
test,test:watch,test:coverageadded topackage.json.
Changed
CI/CD
- GitHub Actions — CI now runs
npm testafterknipand beforebuild.
Build/Repo Hygiene
- Coverage artifacts — added
coverageto.gitignore.
Gateway Client Types & Behavior
GatewayClientOptions— addedconnectFallbackMs?: numberto support deterministic connect-fallback timing in tests.GatewayClient.sendConnectSoon()— fallback timer now respectsopts.connectFallbackMs(defaults to existing constant when not provided).
Chat Utilities
stripThinkingTagsexport — made public for direct unit testing of parser edge cases.
Fixed
Chat Core (use-chat.ts)
- handleLoadMore streaming guard — early return when
chat.runId !== nullprevents message list corruption during active streaming (was: load-more replaced optimistic + stream placeholder messages → duplicate messages) - handleRetry busy guard — added
isBusyRef.currentcheck; prevents parallelchat.sendcalls during active streaming - handleAbort per-frame re-render — uses
runIdRef.currentinstead ofchat.runIdclosure; deps reduced to[client, selectedSession]; eliminates callback re-creation on every streaming delta - handleRetry consolidation — refactored to call
executeSendinstead of duplicating try/catch/request logic; removed fragilefinallyblock (double setState on error path) - Blob URL leak on image compression failure —
previewhoisted above try block;URL.revokeObjectURL(preview)called in catch - Settings schema migration —
localStoragesettings merged withDEFAULT_CHAT_SETTINGSconstant; missing fields from older schema get correct defaults instead ofundefined
Chat Utilities (chat/utils.ts)
- Thinking block extraction —
extractThinkingnow collects all thinking blocks and joins with\n\n(was: only first block,breakon match) - Stateful regex footgun — removed
/gflag from module-levelFILE_BLOCK_REconstant; added at call sites vianew RegExp(source, 'g') - Floating-point quality guard — compression loop guard changed from
> 0.3to> 0.31; avoids one extra compression pass from0.30000000000000004 > 0.3 - generateId uniqueness — fallback (no
crypto.randomUUID) now usescrypto.getRandomValueshex; final fallback addsMath.random()suffix toDate.now()for same-millisecond uniqueness - replaceAll with /g regex — changed redundant
replaceAll(new RegExp(..., 'g'))toreplace(new RegExp(..., 'g'))
Gateway Store (gateway-store.ts)
- Timer leak across connection cycles — compaction/fallback timer handles stored in module-level variables;
clearStatusTimers()called indisconnect(); previous timers cleared before scheduling new ones - Silent eager-fetch errors — added
log.warnfor non-scope/permission errors inconnect()catch block - Stale run indicator — increased
STALE_RUN_MAX_AGE_MSfrom 30s to 120s; matches Gateway's minimum agent timeout for tool-heavy runs - Event handler indirection —
STORE_EVENT_HANDLERSuses direct function references instead of arrow wrappers
Gateway Client (client.ts)
- Reconnect jitter —
secureRandomUnitfallback changed from deterministic0.5toMath.random(); prevents thundering herd whencrypto.getRandomValuesunavailable - Binary encoding APIs — reverted
codePointAt/fromCodePointtocharCodeAt/fromCharCodeindevice-identity.ts; correct API for binary byte data (0-255)
Server (server/index.ts)
- Removed
openBrowser— deleted auto-browser-open feature (--open/-oCLI flag,CK_OPEN_BROWSERenv,spawnimport, Windowscmd.execode path)
Changed
Code Quality
- Complexity reduction —
stripThinkingTagsrewritten from regex state machine to manual parser (smaller functions, no global regex state); component JSX ternaries pre-computed as variables - Type safety —
window.__CK_CONFIG__access replaced with typedgetRuntimeConfig()helper;navigatoraccess viagetBrowserNavigator()withNavigatorWithUADatatype;(navigator as any)eliminated - Index keys eliminated — array index keys replaced with content-based stable keys in
bubble.tsx,session-sidebar.tsx; IIFE pattern refactored to pre-computedkeyedImages/keyedFiles - Base64 overhead comment — documented
TARGET_SIZE * 1.37as// Base64 overhead ratio (~4/3)
Deduplication
extractAgentId/sessionLabel— deleted fromchat/utils.ts;sessionLabeladded tosessions/utils.ts; imports updated inuse-chat.tsandchat/index.tsx- Unused
_settingsparam — removed fromgroupMessages;ChatSettingsimport removed fromchat/utils.ts
Comment Cleanup
- Removed 31 low-value comments (obvious restatements, redundant separator labels, self-documenting component names) across 16 files; preserved all security, protocol, and domain rationale comments
ClawKernel 2026.2.25
🚀 ClawKernel 2026.2.25
A major release adding 5 new pages, a backend foundation, and sweeping
code quality improvements across the entire codebase.
✨ New Pages
| Page | Route | What it does |
|---|---|---|
| Web Search | /search |
Search playground with 5 providers (Brave, Perplexity, Grok, Gemini, Kimi); model selector; streams results via the agent |
| Browser Control | /browser |
Inspect and drive the OpenClaw browser relay — status tiles, HTTP request panel, response viewer, history |
| Audio / TTS | /audio |
Manage TTS providers, test voice output, configure wake words and talk settings |
| Skills | /skills |
View all agent skills grouped by source; enable/disable; install dependencies; set API keys inline |
| Models | /models |
Full model catalog from models.list; routing config; provider status; aliases table |
🏗️ Backend Foundation
- Hono v4 server — compiled to
bin/server.mjs(13 KB) via esbuild; spawned by the CLI - SQLite database —
better-sqlite3+ Drizzle ORM;~/.clawkernel.dbwith WAL mode - REST API —
/api/health,/api/version(update checker with 1h cache),
/api/gateway/restart,/api/prefs - Optional API auth —
CK_API_TOKENenv var; all mutating endpoints requireAuthorization: Bearer - Update Banner — dismissible in-app notification when a newer version is on npm
- Restart Bar — one-click gateway restart from the UI after config changes
📊 Dashboard Enhancements
- Today's Cost tile — live total cost + token count via
usage.cost - Latency tile — color-coded round-trip ms (green < 50ms · orange < 200ms · red > 200ms)
- Cron Summary tile — enabled/failing job count with failure state color
- Chat Notification Toast — preview toast when a chat
finalevent arrives outside/chat - Time Format toggle — 12h/24h preference stored in localStorage; click the status bar clock
📡 Channels
- Full channel status grid with auto-refresh every 30s
- Token setup (Telegram, Discord, Slack) with show/hide toggle
- WhatsApp/Signal QR login modal
- Device pairing management — approve/reject, rotate/revoke tokens
- DM pairing queue per channel
- Pairing Bell — global badge in status bar with live pending count
- Channel Setup Wizard (3-step: Choose → Configure → Done)
- Per-channel enable/disable toggle
⏰ Global Cron Hub
- Dedicated
/cronpage listing all jobs across all agents - 5-step Create Job Wizard (Basics → Schedule → Payload → Delivery → Review)
- 11 schedule presets + custom cron / interval / one-shot
- Inline edit, run now, enable/disable, delete with confirm
- Failure Guide — pattern-matched error diagnosis with actionable fix steps
- Per-job run history with status, duration, model, session ID
- URL deep-linking:
?job=<id>,?show=errors
🐛 Bug Fixes
config.patchhash conflict — retry now matches all 3 Gateway error variants,
including the most common"re-run config.get and retry"message- Cron
mode=nonedelivery — was sendingundefined; Gateway ignored it and kept
the old delivery. Now correctly sends{ mode: 'none' } staggerMslost on edit — value is now carried throughCronSchedule,
formToSchedule, andjobToForm- Cron loading spinner stuck —
setLoading(false)moved tofinallyblock normalizeAgentIdregex —/^-|-$/greplaced with/(?:^-|-$)/g
(ambiguous operator precedence)
🔧 Code Quality
- SonarQube fixes — nested template literals (S4624), ambiguous JSX spacing (S6772),
accessible form labels (S6853), object stringification (S6551) - Complexity reduction — 12 components refactored: extracted named helpers,
early-return branches, anduseMemoconversions; avg complexity reduced by ~50% readonlyprops — all component prop types across 84 files now explicitlyreadonly- Unhandled rejections fixed — all fire-and-forget promise chains now have
.catch() - NaN guards —
formStateToSchedulevalidatesNumber()inputs before sending
to Gateway (everyMs,timeoutSeconds) ActivityItemwrapped inReact.memo— eliminates ~200 unnecessary re-renders
per 15s tick in the activity feed- CI fix — publish job condition corrected from
refs/tags/v*→refs/tags/
(calendar versions don't start withv); automated GitHub Release creation added
📦 Dependencies
New runtime: hono, @hono/node-server, better-sqlite3, drizzle-orm, zod
engines.node updated to >=20 (required by better-sqlite3 v12)
Full Changelog: 2026.2.25...2026.2.25
ClawKernel 2026.2.24
Changelog
[2026.2.24-1] — 2026-02-24-1
Added
-
CI/CD pipeline (
.github/workflows/ci.yml) — matrix on Node 20 & 22, SLSA Level 2 provenance via--provenance, concurrency cancel-in-progress for PRs -
CLI: server banner now prints config file path (
~/.clawkernel.json) so first-time users know where config is stored -
README:
npx clawkernelas primary Quick Start;## CLI Optionssection with all flags; Development section separated from user flow; npm version badge -
package.json: 13 targeted keywords for npm/GitHub discoverability; description leads with product name
Changed
- CSP
connect-src:ws://localhost:* wss:→ws: wss:— allows any self-hosted WebSocket origin loadConfig(): re-validates saved URL scheme on every start — rejects malformed or tampered config- Setup wizard: URL prompt loops until valid
ws:///wss://scheme is entered - Setup wizard: Gateway Token prompt shows
(optional — leave blank if auth.mode is none)hint - Setup wizard: terminal cleared after completion (
\x1b[2J\x1b[H) — server banner appears on a clean screen; scrollback buffer preserved handleSendcallback: stabilized viaisBusyRef+runIdRef— eliminates ~30 fps recreation during streaming- Chat history reload: follows OpenClaw
shouldReloadHistoryForFinalEvent— reloads only when final event carries no valid assistant message HISTORY_PAGE_SIZE = 200constant replaces three hardcodedlimit: 200occurrences- Content type guard:
(c: any)→(c: ChatMessageContent)with'text' in cnarrowing useSessionsPage: removed derivedlistWindowResetKeystring and always-truthyifguard; replaced with explicit individual depsbiome.json: five a11y rules promoted from"off"→"warn"(useButtonType,noSvgWithoutTitle,useKeyWithClickEvents,noStaticElementInteractions,noLabelWithoutControl)ImageLightbox: restructured asrole="dialog" aria-modal="true"with separate backdrop<button tabIndex={-1}>; globalwindowEscape handler viauseEffect— fires regardless of focus position- Drop zone:
<div>→<section aria-label="Chat area">— semantically correct landmark element - Shiki theme toggle:
MutationObserverondocumentElement.class— dark/light switch now triggers live re-highlight
Fixed
- Windows
--openflag:spawn('start', [url])→spawn('cmd', ['/c', 'start', '', url])—startis acmd.exebuilt-in - Two
await import('@/stores/gateway-store')dynamic imports → directuseGatewayStore.getState().client— module was already statically imported main.tsx:getElementById('root')!non-null assertion → explicit null check with descriptive error message- Gap recovery: silent
.catch(() => {})→.catch((err) => log.warn(...)) - Raw
AlertDialogin chat (8 lines, 9 imports) →<ConfirmDialog>shared component agent-files.tsxtabs:<div role="button">containing<button>→ outer<div>+ sibling<button>(label) +<button>(close)bubble.tsx: clickable<img>→<button type="button">witharia-labelandfocus-visibleringsources-panel.tsx: backdrop<div onClick>→<button type="button" tabIndex={-1}>error-boundary.tsx: decorative SVGs missingaria-hidden="true"; reload button missingtype="button"- 24
<button>elements across 14 files missingtype="button"— prevents accidental form submission in all browsers - CI tag trigger:
tags: ['v*']→tags: ['[0-9]*']— calendar versions never matchedv*
Security
- A11y fixes make all interactive elements keyboard-accessible — no mouse-only interactions remain
[2026.2.24] — 2026-02-24
ClawKernel CLI — first public release as an npm package.
Added
CLI — bin/clawkernel.mjs
- Zero-dependency static file server using Node.js built-ins only (
http,fs,path,readline,stream,child_process) - Interactive setup wizard on first run — prompts for Gateway WebSocket URL, auth token, OpenClaw home directory, and dashboard port
- Config persisted at
~/.clawkernel.json— survives restarts, editable with--reset - Runtime config injection:
window.__CK_CONFIG__injected intoindex.htmlat serve time — no rebuild needed to change settings - CLI flags:
--port/-p,--host,--open/-o,--reset,--help/-h NO_COLORand non-TTY detection — clean output in CI and piped environments- SPA fallback — all non-asset routes serve
index.html - Immutable cache headers for hashed Vite assets;
no-storefor HTML - Graceful shutdown on
SIGINTandSIGTERM - Cross-platform browser launch (
open/xdg-open/cmd /c start) - Ctrl+C and Ctrl+D during wizard exit cleanly with no unhandled-rejection warnings
STRUCTURE.md— architecture documentation at project root- Biome for lint + format (replaces ESLint); Knip for dead code detection
Changed
- Project renamed from internal codename Mission Control to ClawKernel
- Removed calendar, notifications, settings, terminal, and logs pages — scope focused on core Gateway operations
Security
- Config file saved with
0o600permissions — readable only by the current OS user - Path traversal prevention — static file handler validates all paths against
DISTboundary .envand all secrets excluded from published package ("files": ["dist/", "bin/"])X-Content-Type-Options: nosniffon all responses
[2026.2.23] — 2026-02-23
Sessions management and Cron job scheduler.
Added
Sessions Page
- Full session list across all agents with real-time state
- Quick filters: All, Active, Idle, Compacted
- Indexed session store for O(1) lookups by session key
- Deferred search with
useDeferredValue— UI stays responsive during fast typing - Sort by: last active, session key, kind
- Virtualized flat list via
@tanstack/react-virtual— handles thousands of sessions without layout jank - Agent grouping view — sessions collapsed under their parent agent with expand/collapse
- Session card: status dot, model badge, token usage, session key, relative timestamps
- Session preview on hover with last message excerpt
- Patch session dialog — edit label, description, and log level live
- Send message dialog — inject a message into any session without opening chat
- Delete session with confirmation dialog
- Bulk delete — multi-select sessions and delete in a single action
- Session history dialog — full message history for any session in a slide-in panel
- Auto-refresh toggle with configurable interval
- Stats bar: total sessions, active count, idle count
Agents — Cron Tab
- Cron job scheduler per agent: create, edit, and delete recurring jobs
- Session target:
main(shared session) orisolated(fresh session per run) - Wake mode:
now(immediate) ornext-heartbeat(aligned to agent heartbeat) - Run history panel per job — expandable list of past executions with status and timing
- Delete job dialog with confirmation
Agents — Activity Tab
- Real-time activity feed for each agent
- Per-event payload inspector — expandable JSON viewer
- Filter by event type
Changed
saveRawConfigWithRetry— hash-conflict safe wrapper for full raw config writes; integrated into agent binding and cloning workflows
[2026.2.22] — 2026-02-22
Real-time chat with streaming, tool calls, and media.
Added
Chat Page
- Real-time streaming chat with RAF-throttled rendering at ~30 fps
- Full message history with paginated
Load More(200 messages per page) - Streaming bubble with animated shimmer during generation
- Tool call rendering — grouped tool calls with collapsible input/output viewer per call
- Thinking block display — collapsible reasoning section (toggle via settings popover)
- Image attachments: drag-and-drop onto chat area, clipboard paste (
Ctrl+V), file picker — JPEG / PNG / WebP / GIF - Image compression before upload with
createImageBitmapfallback for browser compatibility - Image lightbox — click any image to view full size; Escape or backdrop click to close
- Source citations panel — inline
[n]links open a slide-in panel with full source list and clickable URLs - Retry: re-send the last user message without retyping
- Abort: cancel an in-progress generation mid-stream
- Session sidebar: browse and switch sessions, preview last message on hover, manual refresh
- New session button — starts a fresh context for the current agent
- Settings popover: toggle thinking block visibility
- Compaction indicator — shown when the gateway has compacted the context window
- Fallback indicator — shown when the gateway is operating in degraded mode
- Context meter — circular arc showing token usage vs. model limit; pulses red above 80%
- Processing indicator — animated dots during tool execution
- RTL / LTR text direction auto-detection per message
- Keyboard shortcuts:
Escapeclears attachments / closes lightbox / closes sources panel DOMPurifysanitization with strict allowlist — external images blocked, all anchors forcedrel="noreferrer noopener"- Shiki syntax highlighting — 13 languages, lazy-loaded WASM only when code blocks are present
- LRU markdown cache (200 entries, 50 KB max) — avoids re-parsing identical streamed content
- WeakMap text cache for fast message content extraction
- Message queue — incoming events buffered during render to prevent dropped frames
[2026.2.21] — 2026-02-21
Full agent management with 9 dedicated tabs.
Added
Agents Page
- Agent list panel with live status indicators (idle, active, running) and model labels
- Each agent isolated under a
TabErrorBoundary— a crash in one tab never affects others - 9 agent tabs:
- Overview — model selector, system prompt editor, memory settings, token usage stats, quick actions (send message, open new session), Danger Zone (clear all sessions, reset workspace)
- Files — in-browser code editor with multi-tab support, dirty-state dot indicator, save / discar...