Commit Graph

85 Commits

Author SHA1 Message Date
Zhicheng Han 97b15d6514 test: 添加浏览器烟测套件 (#750)
* test: add Playwright browser smoke suite

* Update playwright.yml

---------

Co-authored-by: ekko <152005280+EKKOLearnAI@users.noreply.github.com>
2026-05-15 17:35:10 +08:00
ekko e0bfa828cb make web ui state directory configurable (#764) 2026-05-15 17:30:27 +08:00
ekko 3d49f778fb align compression token estimates (#749) 2026-05-15 13:50:27 +08:00
ekko f6a6c1c228 fix: reserve web ui port for gateways (#746) 2026-05-15 12:52:45 +08:00
ekko 876aa9ee83 fix: isolate gateway profile environment (#745) 2026-05-15 12:44:36 +08:00
ekko 48dcaee6c2 feat: add bridge session commands (#743) 2026-05-15 12:04:03 +08:00
ekko 7da934fe8b revert: remove i18n lazy loading and highlight.js selective import (#736)
Revert the dynamic import() for i18n locales and highlight.js core+
registration from #696. Dynamic imports create separate chunk files
that cause 404 errors for users after updating when the browser still
references old chunk hashes.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-14 23:32:33 +08:00
ekko d0f1e7d1f2 Fix bridge compression history handling (#726)
* feat(bridge): refactor compression to use DB history and add structured logging

- Extract buildDbHistory() to share message loading between buildCompressedHistory and forceCompressBridgeHistory
- forceCompressBridgeHistory now reads from local DB instead of using Python-provided messages, ensuring consistency with api_server path
- Pass sessionId to compressor for snapshot-aware compression
- Add force_compress flag to bridge chat requests
- Add bridgeLogger structured logging for compression lifecycle
- Simplify schemas, session-sync, and providers

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fix bridge compression history handling

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-14 21:02:59 +08:00
Butter Rice Cake of Gemini f6df0fecfa perf: 优化体积,highlight.js按需导入与i18n按需加载 (#696)
* perf: 优化打包体积,highlight.js按需导入与i18n按需加载

1. highlight.js: 从全量导入改为 core + 注册27种常用语言,减少约500~800KB
2. i18n: 只同步加载en语言包,其他8种语言改为异步加载,首屏减少约350~400KB
3. 使用vue-i18n的setLocaleMessage API动态注册语言包
4. 新增switchLocale函数统一处理语言切换
5. 同步更新相关测试文件的mock路径和API适配

* 修复类型断言
2026-05-14 12:39:36 +08:00
ekko 9170e11715 fix: SkillsUsage 页面样式修复与 API server skill usage 统计 (#698)
* Reapply "feat: 新增 Skills Usage 监控统计与图表 (#668)" (#670)

This reverts commit 91de3b12a1.

* fix: count API-server skill usage

* fix: align SkillsUsageView header with other pages and update sidebar icon

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Zhicheng Han <zhicheng.han@mathematik.uni-goettingen.de>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-14 09:28:51 +08:00
ekko eae7195ba8 Update CLI chat session bridge (#697)
* feat: add CLI chat sessions with Python agent bridge

Introduce a new CLI chat mode that connects Web UI directly to Hermes
Agent's AIAgent via a Python bridge subprocess and Socket.IO, bypassing
the API Server /v1/responses path. Supports streaming, slash commands
(/new, /undo, /retry, /branch, /compress, /save, /title), interrupt,
and steer.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* feat: update CLI chat session bridge

* fix: extend agent bridge startup timeouts

* docs: update bridge chat session design

* feat: align bridge compression and provider registry

* chore: bump version to 0.5.20

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-14 09:03:57 +08:00
ekko 91de3b12a1 Revert "feat: 新增 Skills Usage 监控统计与图表 (#668)" (#670)
This reverts commit ce08d2b05a.
2026-05-13 07:51:29 +08:00
Zhicheng Han ce08d2b05a feat: 新增 Skills Usage 监控统计与图表 (#668)
* feat: add skills usage monitoring

* fix: localize Skills Usage page copy

* fix: keep Skills Usage labels compact
2026-05-13 07:43:25 +08:00
Zhicheng Han c2068302c3 feat: enhance usage analytics dashboard (#666)
- visualize input, output, and cache token segments in usage charts
- add usage period selector for 7d, 30d, 90d, and 365d
- guard usage stats against stale overlapping period requests
- normalize blank model usage into unknown buckets
- add client and server coverage for usage analytics behavior
2026-05-13 07:41:49 +08:00
Zhicheng Han 57cdf87bef Kanban:补齐看板事件、链接与批量操作闭环 (#634)
* feat(kanban): add board-scoped event stream bridge

* test(kanban): align event refresh expectation

* feat(kanban): add links and partial bulk bridge

* test(kanban): align links bulk refresh expectation

* fix(kanban): treat mutation stderr as failed
2026-05-13 07:32:38 +08:00
luSkyl 8b291d7a48 test: fix windows path isolation (#659) 2026-05-12 20:56:04 +08:00
luSkyl c987448f01 fix: harden windows gateway liveness (#658) 2026-05-12 20:44:34 +08:00
ekko 73b919e07c fix: skip model API requests when no auth token is present (#643)
Prevents infinite retry loop on /api/hermes/available-models when
accessing the app without a token, which triggers server-side 429
rate limiting. Both loadModels() and fetchProviders() now bail out
early if hasApiKey() returns false.

Closes #606

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 10:19:14 +08:00
Zhicheng Han c36b320e18 fix: prompt reload for stale Web UI bundle (#641) 2026-05-12 09:03:07 +08:00
Zhicheng Han b8be47d8d6 feat(models): 增加模型显示名重命名 (#614)
* feat(models): add WUI model display aliases

Persist display-only model aliases in Web UI app config, surface them in the model selector/search, and keep canonical model IDs for Hermes calls.

* fix(models): improve WUI model alias editing

* fix(models): clarify unlisted model picker

* fix(models): scope aliases to providers
2026-05-11 22:18:13 +08:00
Zhicheng Han 5e608ea338 fix: recognize Codex credential-pool auth (#617) 2026-05-11 21:36:43 +08:00
Zhicheng Han 7907bbbf61 fix: clear provider auth entries on delete (#616) 2026-05-11 21:30:05 +08:00
Zhicheng Han 6ff1c18ee2 Kanban:补齐任务操作链路,明确能力边界 (#615)
* [verified] fix(kanban): harden WUI parity bridge

- Align board slug normalization with canonical underscore/lowercase/64-char rules
- Validate malformed Kanban action bodies before CLI shell-out
- Narrow task log no-log handling and expose phase-1 capabilities
- Extend client/server regression coverage for parity actions

* fix(kanban): guard archived task detail actions

---------

Co-authored-by: ekko <152005280+EKKOLearnAI@users.noreply.github.com>
2026-05-11 21:26:24 +08:00
Zhicheng Han 3a1893d401 Models:支持在 Web UI 里管理可见模型 (#613)
* feat(models): add WUI model visibility filter

Store provider model visibility in Web UI app config and filter the WUI model picker/model page without rewriting Hermes CLI config or canonical model IDs.

* fix(models): sync sidebar after visibility changes
2026-05-11 21:24:45 +08:00
Zhicheng Han 9c5fe1ec7d fix: initialize session sync test schema (#618) 2026-05-11 21:14:05 +08:00
Zhicheng Han e0e4096605 fix(kanban): include archived tasks in board counts (#619) 2026-05-11 21:09:58 +08:00
Zhicheng Han 0d14afe9b4 fix: harden web ui self-update restart (#552) 2026-05-10 20:18:52 +08:00
Zhicheng Han 838791a740 修复 WUI Kanban 看板选择与隔离 (#594)
* fix: add explicit kanban board selection

* fix: tighten kanban board counts and management
2026-05-10 19:58:44 +08:00
Zhicheng Han 89f0127da6 新增只读 Hermes 插件页 (#592)
* feat: add read-only plugins page

* fix: align plugins page i18n and header
2026-05-10 19:50:39 +08:00
ekko 739c65a4df fix: prevent assistant message merging across tool calls (#593)
Remove run.text accumulator and insertResponseTextOnce that caused
text blocks before and after tool calls to be concatenated into a
single message. Now response.output_text.done only sets finish_reason
without overwriting delta-accumulated content.

- Remove run.text, textInserted from ResponseRunState
- Remove insertResponseTextOnce method
- output_text.done only marks finish_reason='stop' on last message
- response.completed no longer calls insertResponseTextOnce
- Add 7 tests covering flush, abort, and multi-block text separation

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 08:46:12 +08:00
ekko 9045f2a987 Revert "修复审批请求在聊天中无提示且无法响应 (#467)" (#553)
This reverts commit 56c7b59eaf.
2026-05-09 08:36:13 +08:00
Zhicheng Han 56c7b59eaf 修复审批请求在聊天中无提示且无法响应 (#467)
* fix: support run approval prompts in chat

* fix(chat): render approval prompts

* fix(chat): dedupe approval pattern labels

* chore: sync approval flow with current main

- update Hermes Agent approval support guidance to PR #21899
- initialize Hermes table schemas in session-sync tests
2026-05-08 16:59:36 +02:00
ekko 51fde26797 refactor remove upstream env dependency (#551) 2026-05-08 20:46:22 +08:00
ekko bba4920fee fix hermes markdown media and sync retry (#550) 2026-05-08 19:55:55 +08:00
ekko 39acd3574a fix wsl default listen host (#542) 2026-05-08 15:47:03 +08:00
ekko e55792acbb [codex] fix kanban session matching (#538)
* fix kanban session matching

* tighten kanban task session lookup

* remove favicon svg
2026-05-08 13:53:40 +08:00
ekko b0e03ae838 add hermes kanban board (#534) 2026-05-08 11:32:47 +08:00
ekko 173307ef28 feat: add session export with full and compressed modes (#507)
Add export functionality that allows users to download session data
as JSON or plain text, with optional LLM-based context compression
for long conversations. Includes UI controls in chat panel, session
list, and history view, plus i18n strings for all 8 locales.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-07 13:49:57 +08:00
ekko 5df8734495 fix: resolve test failures related to v0.5.12 changes (#491)
* fix: update tests for new batch delete and update mechanism changes

**sessions-routes.test.ts:**
- Add missing batchRemove mock to controller mock
- Fix "No batchRemove export defined" error

**update-controller.test.ts:**
- Update test to expect direct npm/npm.cmd calls instead of dirname(process.execPath)
- Update timeout from 120000 to 10 * 60 * 1000 (10 minutes)
- Update spawn path check to use dynamic global prefix (expect.any)

Tests now match the refactored update mechanism that uses npm prefix -g
for reliable path resolution.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: add speechSynthesis mock to message-item-highlight tests

* test: fix all failing tests

- Add approvals mock to session-settings test
- Fix NSwitch stub to properly emit events
- Update usage stats test expectations for new field structure
- Mock getDb in model-context tests to avoid database lock errors
- Add speechSynthesis API mock to message-item-highlight tests

Related to v0.5.12 feature changes

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-06 21:37:13 +08:00
tw19880217-creator d13423b9dd Fix IPv6 listen default (#470)
Co-authored-by: KK <kk@KKs-Mac-Studio.local>
2026-05-06 15:24:34 +08:00
Zhicheng Han 0209372a6d Fix custom provider context resolution (#468)
Co-authored-by: ekko <152005280+EKKOLearnAI@users.noreply.github.com>
2026-05-06 15:16:44 +08:00
Zhicheng Han f338aeea18 fix: play completion sound in chat (#466) 2026-05-06 14:23:12 +08:00
Zhicheng Han 9ba0ba5185 fix: show cron scheduler history without output artifacts (#463) 2026-05-06 07:44:53 +08:00
ekko 08e1a72793 Release v0.5.8 (#422)
* fix: add missing i18n key and unify session data source (#408)

- Add `chat.sessionNotFound` translation key to all 8 locales
- Fix history page data source inconsistency:
  - Change `getHermesSession` to prioritize database over CLI
  - Now consistent with `listHermesSessions` behavior
  - Prevents "session in list but detail not found" issue
- Update CI workflow to trigger on base branch PRs
- Remove debug log from sessions-db

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: filter special characters and emoji in speech playback (#409)

- Update extractReadableText to filter special characters like *#
- Only keep common punctuation marks for speech synthesis
- Remove emoji, symbols, and special unicode characters
- Improve text-to-speech readability

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: add drawer panel with mobile sidebar support and customizable button (#412)

* feat: add drawer panel with mobile sidebar support

- Add DrawerPanel component with Terminal and Files tabs
- Extract TerminalPanel and FilesPanel from existing views
- Add mobile sidebar toggle functionality with overlay
- Add rainbow breathing light effect to drawer button
- Remove Tools section from AppSidebar (Terminal/Files entries)
- Add i18n support for drawer and file tree
- Optimize mobile button layout and spacing
- Fix z-index hierarchy for proper layering
- Add responsive sidebar behavior (PC: always visible, Mobile: toggle)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: customize drawer button with arc rainbow border

- Change drawer button to semi-circle shape贴着右边
- Add arrow icon pointing left (向左箭头)
- Add rainbow border from top to bottom through semi-circle arc
- Slow down animation from 4s to 8s for smoother effect
- Move drawer button wrapper to messages area only (not贯穿header和input)
- Add semi-transparent accent color background to button

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: resolve profile switching state sync issue (#414) (#415)

* fix: resolve profile switching state sync issue (#414)

Fix bug where switching to a different profile would still show the
old profile name in the UI and prevent switching back to default.

Root cause:
- Frontend relied entirely on fetchProfiles() return value to set
  activeProfileName
- Backend Hermes CLI may return stale active flag due to timing
  issues between profile use and profile list commands
- This caused frontend to display wrong profile and prevented
  switching back to default

Solution:
- Immediately set activeProfileName when switchProfile API succeeds
- Don't rely solely on listProfiles() result which may have stale data
- Use activeProfileName instead of activeProfile?.name in ProfileSelector

Changes:
- profiles store: Set activeProfileName immediately after successful switch
- ProfileSelector: Use activeProfileName computed property
- Add test to verify activeProfileName updates on switch

Fixes #414

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refine: improve error handling for profile switching failures

Add proper error handling for edge cases:
- If fetchProfiles() fails after successful switch, keep the updated
  activeProfileName (don't let fetchProfiles failure undo the switch)
- Add test cases to verify:
  1. API failure doesn't change state
  2. fetchProfiles failure doesn't affect successful switch

This ensures the UI remains consistent even when profile list refresh
fails after a successful profile switch.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refine: add rollback mechanism for profile switching verification

Add backend verification after profile switch:
- Save old activeProfileName before setting new value
- After fetchProfiles, verify backend reports expected active profile
- If backend reports different profile, rollback frontend state and return false
- This handles edge case where API returns 200 but backend didn't actually switch

Test cases:
-  Normal switch: updates and verifies successfully
-  API failure: doesn't change state
-  fetchProfiles failure: assumes success (API returned 200)
-  Backend verification fails: rolls back to old profile

This ensures frontend state always matches backend reality, even in
edge cases where hermes profile use succeeded but gateway/cleanup
steps failed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refine: add user feedback for profile operations

Improve user experience with success/error messages:
- ProfileSelector: Add error message when switch fails
- ProfileCard: Add success message before reload on switch
- ProfileSelector: Use async/await for better error handling
- ProfileCard: Add 500ms delay before reload to show success message

Before: Silent failures, no feedback
After: Clear success/error messages for all operations

Example feedback:
- Success: "已切换到配置 qinghe"
- Failure: "切换配置失败,网关可能需要手动重启"

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: update frontend changelog for v0.5.7 (#419)

* docs: update frontend changelog for v0.5.7

- Update changelog.ts with v0.5.7 release date and changes
- Add i18n translation keys for all languages (en, zh, de, es, fr, ja, ko, pt)
- Include v0.5.7 changelog entries:
  - Optimize context compression and session sync
  - Add startup delays to prevent database race conditions

Changes:
- packages/client/src/data/changelog.ts: Update v0.5.7 entry
- packages/client/src/i18n/locales/*.ts: Add changelog translation section

This enables the changelog modal in the UI to display v0.5.7 release notes.

* feat: add v0.5.7 changelog translations to all supported languages

Add new_0_5_7_1, new_0_5_7_2, and new_0_5_7_3 changelog entries to all
locale files (en, zh, de, es, fr, ja, ko, pt) with proper translations
for each language.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: remove duplicate changelog sections causing syntax errors

Remove duplicate changelog object sections that were causing TypeScript
syntax errors in all locale files (en, zh, de, es, fr, ja, ko, pt).
The actual changelog entries are already correctly placed in the main
changelog section of each file.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: add v0.5.8 changelog and fix profile parsing issue

Add v0.5.8 changelog entries based on PRs merged since v0.5.7:
- Drawer panel with mobile sidebar support (#412)
- Profile switching state sync fix (#414)
- Speech playback special character filtering (#409)
- Missing i18n key and session data source unification (#408)
- Vite build optimization for faster Docker builds (#403)

Also fix issue #417: Profile names with long hyphenated names fail
to parse in profile list regex. Change \s{2,} to \s+ to handle
compressed column spacing when profile names are long.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: remove enter key submit from profile creation and rename modals

Remove @keyup.enter handlers from NInput components in:
- ProfileCreateModal: prevent accidental profile creation when pressing enter
- ProfileRenameModal: prevent accidental profile rename when pressing enter

Users must now explicitly click the confirm button to submit, preventing
unintended profile operations.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: allow free text input for profile names

Remove frontend character filtering from profile creation and rename
modals. Users can now input any characters including spaces and
uppercase letters to test backend Hermes CLI validation.

Changes:
- ProfileCreateModal: Remove toLowerCase() and character filtering
- ProfileRenameModal: Remove toLowerCase() and character filtering
- Use v-model:value binding instead of :value with @input

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: improve error handling for profile creation

Display backend error messages when profile creation fails instead of
generic "failed" message. This helps users understand why their
profile name was rejected (e.g., invalid characters).

Changes:
- API layer: Capture and return error messages from backend
- ProfileCreateModal: Display specific error message from backend

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: add profile name validation with i18n support

Add client-side validation for profile names to prevent invalid input
before sending to backend. Only lowercase letters, numbers, underscores,
and hyphens are allowed.

Changes:
- ProfileCreateModal: Add input validation with real-time feedback
- ProfileRenameModal: Add input validation with real-time feedback
- Add nameValidation i18n key for all 8 languages
- Filter invalid characters on input and show warning message

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor: revert profile parsing regex changes

Revert the regex changes in hermes-cli.ts and gateway-manager.ts
back to requiring \s{2,} (at least 2 spaces). Since frontend now
validates profile names to only allow lowercase letters, numbers,
underscores, and hyphens, the relaxed regex is no longer needed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor: revert profile parsing regex changes

Revert the regex changes in gateway-manager.ts and hermes-cli.ts
back to requiring \s{2,} (at least 2 spaces). Since frontend now
validates profile names to only allow lowercase letters, numbers,
underscores, and hyphens, the relaxed regex is no longer needed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor: remove tooltip from drawer button

Remove the NTooltip wrapper from the floating drawer button.
The "Terminal & Files" tooltip is no longer shown on hover.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update assets images (#421)

Updated two asset images in the client package.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-03 22:10:40 +08:00
ekko 969c7c0e1a feat: add robust LLM JSON parser and fix Group Chat schema (#388)
Add robust LLM JSON parsing utilities to handle unreliable model output:
- Parse tool arguments with tolerance for Python format (single quotes, trailing commas)
- Extract text from Anthropic-style content arrays in streaming events
- Normalize tool_result content to string format per Hermes spec
- Parse message.delta and run.completed output to avoid displaying JSON strings

Fix Group Chat database schema errors:
- Add id column as PRIMARY KEY to gc_room_agents and gc_room_members tables
- Change from composite primary keys to single-column id keys
- Update tests to match new schema structure

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 08:58:14 +08:00
ekko acf4e225e6 feat: rewrite database schema synchronization with automatic recovery (#379)
Complete rewrite of the Hermes SQLite database schema synchronization mechanism
with comprehensive error handling, automatic recovery, and full test coverage.

## Database Schema Synchronization
- **Unified sync mechanism**: Single `syncTable()` function handles all schema changes
- **Automatic column sync**: Adds missing columns and removes extra columns
- **Table rebuilding**: Automatically rebuilds tables when primary keys or types change
- **Data preservation**: Preserves data during schema changes when compatible
- **Index management**: Creates and removes indexes as needed

## Error Recovery & Reliability
- **Automatic backup**: Backs up corrupted database before recovery
- **Retry limiting**: Prevents infinite loops with retry limit
- **Duplicate prevention**: Avoids multiple backup files
- **Safe file operations**: Uses copy+delete instead of rename for safety

## Composite Primary Keys
- Fixed GC_ROOM_AGENTS and GC_ROOM_MEMBERS with proper composite primary keys
- Prevents duplicate entries while allowing same roomId with different agentId/userId

## Test Coverage
- **10 new integration tests** for schema synchronization (tests/server/schema-sync.test.ts)
- **3 updated tests** for Hermes schemas (tests/server/hermes-schemas.test.ts)
- All 327 tests passing (47 test files, 325 passed, 2 skipped)

## Bug Fixes
- Fixed module import issues (unified ES6 imports, removed mixed require())
- Fixed mock issues in sessions routes tests
- Fixed i18n coverage test to handle newly added keys
- Fixed profiles store test to match current implementation

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 19:48:46 +08:00
ekko a948eee4b9 test: fix failing tests for mocks and API return types (#366)
* fix(chat): isolate concurrent session events by refactoring WebSocket event handling

Refactored the WebSocket event handling mechanism to use global listeners with session-specific event routing instead of per-session listeners. This prevents event cross-talk when multiple chat sessions run concurrently.

Key changes:
- Client: Added sessionEventHandlers Map to route events to appropriate sessions
- Client: Registered global listeners once per socket connection
- Server: Extracted message processing logic into handleMessage method
- Server: Improved Hermes session ID tracking with dedicated Map
- Server: Added replaceByHermesSessionId for targeted message replacement

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: fix failing tests for mocks and API return types

- Fixed sessions-routes.test.ts: added missing setWorkspace and listWorkspaceFolders mocks
- Fixed usage-store.test.ts: removed test for non-existent initUsageStore function
- Fixed profiles-store.test.ts: corrected createProfile API return type to { success: true }
- Fixed syntax error in usageStatsMock (ctx.body: → ctx.body =)

All tests now pass (314 passed | 2 skipped).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 08:24:57 +08:00
Zhicheng Han 7f01fdf56e fix: clean up cron job edit payloads (#364)
x找我下,跟你聊聊
2026-05-01 08:12:53 +08:00
Zhicheng Han dac9006b3e fix: align usage analytics with Hermes state db (#350) 2026-04-30 19:46:31 +08:00
Lanke 05f15da90b fix(chat): support code block copy feedback (#349) 2026-04-30 10:36:00 +00:00