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