Commit Graph
53 Commits
Author SHA1 Message Date
ekkoandClaude Opus 4.6 0446385a37 chore: add v0.4.8 changelog and improve scroll behavior (#234)
* chore: add v0.4.8 changelog and improve scroll behavior

- Add v0.4.8 changelog entries for recent fixes
- Fix forced scroll to bottom when returning from other tabs
- Smooth session switch with loading transition overlay
- Auto-scroll to bottom after mermaid diagram rendering
- Bump version to 0.4.8

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

* fix: replace blob URLs with persistent download URLs and add image preview

- Replace blob URLs with /api/hermes/download URLs after upload so
  attachments survive page refresh
- Add click-to-preview overlay for image attachments
- Move upload directory from /tmp to ~/.hermes-web-ui/upload

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

* fix: replace findLast with reverse+find for ES2022 compat

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

* chore: bump TypeScript lib target from ES2022 to ES2023

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

* docs: add changelog entries for blob URL fix, image preview and upload dir

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-26 13:28:08 +08:00
ekkoandClaude Opus 4.6 bc66998650 chore: remove old changelog entries (v0.4.1, v0.4.2, v0.4.3) (#233)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-26 12:06:36 +08:00
ekkoandClaude Opus 4.6 8db644496e fix(sessions): optimize N+1 queries and fix search 500 on non-CJK input (#230)
Replace per-session SQL queries in listSessionSummaries/searchSessionSummaries
with a single bulk load via loadAllSessions() + in-memory map traversal,
eliminating N+1 round-trips. Fix search 500 error for pure numbers,
English letters, and other FTS5-incompatible input by extending the
catch fallback beyond CJK-only to all FTS query failures.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-26 10:44:51 +08:00
ekkoandClaude Opus 4.6 3993dda013 docs: add v0.4.7 changelog and remove unused assets (#216)
* fix: align group chat room sidebar background with session list

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

* docs: add v0.4.7 changelog and remove v0.4.3/v0.4.1 entries

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

* chore: remove unused video.mp4 asset

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-25 20:39:53 +08:00
ekkoandClaude Opus 4.6 94e6d7bbb9 fix: align group chat room sidebar background with session list (#214)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-25 20:26:43 +08:00
ekkoandClaude Opus 4.6 bc3e1b2971 docs: update README screenshots and bump version to 0.4.7 (#213)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-25 20:19:48 +08:00
ekkoandClaude Opus 4.6 bc9b43f06a fix: model switch reset, custom provider resolution and base_url_env cleanup (#212)
* fix: reset entire config.model on model switch

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

* fix: resolve custom provider from CLI config and clean base_url_env on delete

- When config.model.provider is "custom" (set by hermes CLI), match
  base_url + model against custom_providers to resolve custom:name
- Clear base_url_env from .env when deleting a builtin provider

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-25 19:38:46 +08:00
ekkoandClaude Opus 4.6 65e712edfc fix: group chat UX polish and model switch cleanup (#205)
* fix(chat): clamp context remaining tokens to 0 instead of showing negative

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

* fix: group chat mention popup position, timestamp style, and model switch cleanup

- Move @ mention popup above input to avoid blocking the textarea
- Fix .msg-time scoping (was nested inside .msg-header, now top-level)
- Reduce timestamp opacity and set to 12px for subtler display
- Clean up stale base_url/api_key from config.yaml on model switch

Closes #204

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

* fix: remove unused variables in GroupChatInput

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-25 16:16:11 +08:00
ekkoandClaude Opus 4.6 a2c57ccaf0 fix(chat): clamp context remaining tokens to 0 instead of showing negative (#202)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-25 14:23:37 +08:00
ekkoandClaude Opus 4.6 c1e72942ad fix(docker): skip prepare script during npm install (#196)
#142 added a `prepare` script that triggers `npm run build` when
dist/ is missing. During Docker build, `npm install` runs before
source files and tsconfig.json are copied, causing build failure.
Use --ignore-scripts to defer build to the explicit step.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-24 23:52:54 +08:00
ekkoandClaude Opus 4.6 833fe06f92 fix: restore fetchAvailableModels to fix provider lost as custom (#194)
* fix: restore fetchAvailableModels to fix provider lost as custom (#174)

#174 replaced fetchAvailableModels with fetchConfigModels, but
config/models response lacks default_provider, label, base_url and
api_key fields. This caused selectedProvider to always be empty,
making all models appear as "custom" in the model selector.

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

* chore: bump version to 0.4.6

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-24 23:30:34 +08:00
ekkoandClaude Opus 4.6 70ed0e0dc2 revert: harden Hermes stream recovery around tool-call boundaries (#189) (#192)
Reverts #189 due to reported bugs.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-24 22:18:32 +08:00
ekkoandClaude Opus 4.6 bff6f844e6 docs: add group chat feature to README (#190)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-24 21:47:10 +08:00
ekkoandClaude Opus 4.6 edd41e6eb7 fix: group chat mobile UX and UI polish (#188)
* fix: group chat UI background colors and replace console.log in context-engine

- Set message list background to $bg-card to match single chat
- Set status-bar background to transparent
- Replace all console.log/warn with logger in context-engine compressor

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

* fix: group chat mobile UX improvements

- Add backdrop overlay for mobile sidebar with tap-to-close
- Auto-collapse sidebar on room select in mobile
- Move timestamp below message bubble
- Widen msg-body max-width to 85% to match single chat
- Add left padding to chat-header to avoid hamburger overlap

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-24 21:28:06 +08:00
ekkoandClaude Opus 4.6 3df369afc0 chore: add changelog for v0.4.5 (#187)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-24 20:54:06 +08:00
ba72264542 feat: group chat session lifecycle, typing recovery, mention highlighting (#186)
* feat: restore group chat system with Socket.IO and SQLite persistence

- GroupChatServer: Socket.IO server with room management, message history, typing indicators
- SQLite storage for rooms, messages, and agent configuration
- AgentClients: manages AI agent connections via socket.io-client, forwards @mentions to Hermes gateway
- REST API: room CRUD, agent management, invite codes
- Agent auto-restoration on server restart
- Tests for all REST endpoints

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

* docs: add context-engine design document for group chat compression

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

* fix: handle special-character session search

* fix: keep unicode dotted session search on quoted FTS path

* feat: add context engine and group chat frontend UI

- Context engine: three-zone compression (head/tail/summary) with LLM
  summarization, incremental updates, TTL cache, and graceful degradation
- Frontend: group chat page with Socket.IO client, room sidebar, message
  list, agent/member display, create/join-by-code modals
- Integration: wire context engine into agent-clients before /v1/runs
- Refactor ChatStorage to use global DB (getDb/ensureTable) with gc_ prefix
- Add i18n keys for group chat to all 8 locales
- Add sidebar nav entry and router for group chat page

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

* fix: remove leftover main branch code from merge conflict resolution

The `isNumericQuery`, `hasUnsafeChars`, and `runLikeContentSearch` functions
no longer exist — they were replaced by HEAD's `shouldUseLiteralContentSearch`
and `runLiteralContentSearch`. This dead code block caused a TypeScript
compile error after the merge.

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

* fix: install missing socket.io dep and type ack params

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

* fix: enable WebSocket proxy and fix socket.io transport for group chat

- Add ws: true to Vite proxy config so WebSocket upgrade requests
  are forwarded to the backend
- Allow both polling and websocket transports on server and client
  (polling as fallback when WebSocket upgrade fails through proxy)

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

* fix: separate socket.io path from REST routes for group chat

socket.io was mounted at /api/hermes/group-chat which intercepted all
REST requests to /api/hermes/group-chat/rooms etc, returning
"Transport unknown". Changed socket.io path to /api/hermes/group-chat/ws
to avoid conflicts.

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

* feat: improve group chat UI, agent management, and socket.io reliability

- Redesign GroupChatPanel with Naive UI, stacked agent avatars, and popover management
- Match GroupChatInput style with single chat input, add IME composition handling
- Add agent add/remove per room with profile selection and duplicate prevention
- Use @multiavatar for SVG avatar generation with caching
- Decouple joinRoom from socket.io, use REST API for data loading
- Switch socket.io to default path with /group-chat namespace to avoid proxy conflicts
- Restore agent connections after server is listening
- Add getRoomDetail REST endpoint and duplicate agent prevention (409)

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

* feat: server-side @mention routing with context compression status and queue

- Move @mention detection from agent socket listeners to server-side processMentions()
- Add per-room processing lock to block mention dispatch during compression
- Queue mentions during processing, drain only the latest when ready
- Emit context_status events (compressing/replying/ready) to room via Socket.IO
- Frontend displays compression status indicator above input
- Token-based compression trigger (100k threshold) with CJK-aware estimation
- Fix compressor type errors (countTokens parameter type)

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

* feat: improve group chat profile handling and session sync

Refine group chat room/session behavior with per-room compression controls, sidebar updates, and better stale session cleanup so multi-profile group chat state stays consistent.

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

* feat: group chat improvements — session lifecycle, typing recovery, mention highlighting

- Fix cross-profile session deletion with deferred delete queue
- Move saveSessionProfile to after gateway response confirmation
- Replace all console.log with logger in group-chat modules
- Add server-side typing/context_status state tracking for room rejoin
- Fix @ mention popup position to follow cursor
- Add @ mention highlighting (blue) in chat message content
- Fix mention regex to match all occurrences after HTML tags
- Enable esbuild minify and treeShaking
- Move @multiavatar/multiavatar to devDependencies
- Add i18n keys for group chat features
- Update tests for new functionality

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

* chore: bump version to 0.4.5 and move @multiavatar to devDependencies

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Zhicheng Han <zhicheng.han@mathematik.uni-goettingen.de>
2026-04-24 20:41:14 +08:00
82965ae6e2 refactor: rewrite model-context to use js-yaml, add context_length to provider form (#177)
* fix: context-length API returns 200K instead of actual model context

Two bugs cause the /api/hermes/sessions/context-length endpoint to
always return DEFAULT_CONTEXT_LENGTH (200K):

1. getModelContextLength ignores config.yaml model.context_length
   The function only checks models_dev_cache.json (which doesn't
   exist in default installations) and falls back to the hardcoded
   200K default, completely ignoring the user's explicit
   model.context_length setting in config.yaml.

2. getDefaultModel regex fails when api_key/base_url come before default
   The regex /^model:\s*\n\s+default:\s*(.+)$/m assumes 'default' is
   the first child key under 'model:', but when api_key or base_url
   appear first in the YAML, the match fails. This causes
   getModelContextLength to short-circuit to DEFAULT_CONTEXT_LENGTH
   before even reaching the cache lookup.

Fix:
- Add getDefaultModelRobust() that extracts the entire model: block
  first, then searches for default: within it
- Add getConfigContextLength() that reads model.context_length from
  config.yaml as a fallback (matching hermes-agent priority)
- Update getModelContextLength() resolution order:
  1. models_dev_cache.json (existing)
  2. config.yaml model.context_length (new)
  3. DEFAULT_CONTEXT_LENGTH (existing fallback)

Closes #169

* refactor: rewrite model-context to use js-yaml, add context_length to provider form

- Replace fragile regex-based YAML parsing with js-yaml for reliable config.yaml reads
- Fix context_length resolution priority: config.yaml override > custom_providers > models_dev_cache > 200K default
- Add context_length input field when adding custom providers in ProviderFormModal
- Backend: persist context_length to custom_providers models.<model>.context_length in config.yaml
- Add i18n keys (contextLength, contextLengthPlaceholder) to all 8 locales

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

* fix: use NInputNumber instead of NInput type=number for context_length

NInput does not support type="number" in Naive UI.

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

---------

Co-authored-by: devilardis <53129661@qq.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-24 11:18:11 +08:00
ekkoandClaude Opus 4.6 f8283729ba refactor: replace jobs proxy with local controller and optimize model loading (#174)
* refactor: replace jobs proxy with local controller and optimize model loading

- Add local jobs controller that directly fetches upstream gateway with
  profile support and 30s timeout, replacing unreliable proxy catch-all
- Upstream errors (non-200) return 502 instead of leaking to frontend
- Switch loadModels() from fetchAvailableModels (slow, fetches all
  provider APIs) to fetchConfigModels (reads config.yaml only)
- Hide logo dance video in sidebar

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

* fix: resolve TypeScript errors from previous refactor

- Remove unused imports (danceVideo, useTheme) in AppSidebar
- Map ConfigModelsResponse.groups to AvailableModelGroup[] format

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-24 09:57:30 +08:00
88c7e25f78 fix(i18n): add i18n support for custom model feature in ModelSelector (#172)
* feat(models): add custom model name input with provider selector

- Add custom model input field at bottom of model selector modal
- Add provider dropdown to specify target provider for custom model
- Track custom models in app store and display with CUSTOM badge
- Merge custom model into provider group list
- Fix custom provider models being overwritten by API response (keep both)

* Upload screenshot

* fix(i18n): add i18n support for custom model feature in ModelSelector

Replace hardcoded English strings (CUSTOM badge, placeholder, hint) with
vue-i18n t() calls and add corresponding translation keys to all 8 locales
(en, zh, ja, ko, fr, es, de, pt).

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

---------

Co-authored-by: toller892 <892@users.noreply.github.com>
Co-authored-by: Tony <125938283+toller892@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-24 08:49:45 +08:00
ekkoandClaude Opus 4.6 b4359ccddb fix: clear all localStorage on logout (#161)
Previously only cleared the auth token, leaving server URL, active
profile, chat caches and other data behind.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-23 19:52:06 +08:00
ekkoandClaude Opus 4.6 30c94b226a fix: add periodic log rotation to prevent unbounded log growth (#160)
Log rotation previously only ran at startup, causing logs to grow
indefinitely on long-running processes (reported up to 71GB/day).
Now checks file size every 60 seconds and truncates when exceeding 3MB.

Fixes #155

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-23 19:49:31 +08:00
ekkoandClaude Opus 4.6 14e9f4a870 docs: add sponsor (爱发电) link to README (#156)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-23 16:47:19 +08:00
ekkoandClaude Opus 4.6 93719fb04b docs: update README and OpenAPI spec to v0.4.4 (#147)
- Add File Browser, Session search, Authentication sections to README (EN + ZH)
- Update Model Management with Nous Portal auth and non-v1 URL support
- Update OpenAPI spec from 0.2.6 to 0.4.4
- Add 30+ new endpoints: Auth, Files, Download, Gateways, Codex/Nous OAuth, Update
- Add PUT provider endpoint for updating existing providers
- Update HealthResponse with webui_version, webui_update_available, node_version fields

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-23 13:12:40 +08:00
ekkoandClaude Opus 4.6 1abe308742 feat: add Node.js version warning, fix provider URL detection, and add v0.4.4 changelog (#146)
- Display persistent warning bar when Node.js version < 23
- Fix provider model fetching to support non-v1 API versions (e.g. /v4)
- Add v0.4.4 changelog entries to frontend
- Bump version to 0.4.4

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-23 12:57:42 +08:00
ekkoandClaude Opus 4.6 1f91b902da fix: handle special char search 500 & polish live badge (#144)
* fix(search): handle numeric query FTS errors regardless of table existence

Remove the `no such table: messages_fts` condition so numeric queries
fall back to LIKE search on any FTS failure (malformed MATCH, missing
table, etc.).

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

* fix(search): handle special char queries, polish live badge UI

- Add hasUnsafeChars() to catch FTS5-breaking queries (¥, @, #, etc.)
  and fall back to LIKE search, preventing 500 errors
- Polish session live badge: smaller size, remove border/shadow,
  add pulsing dot indicator for a cleaner look
- Remove spinner drop-shadow glow effect

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-23 11:18:56 +08:00
ekkoandClaude Opus 4.6 32dc084b66 fix: support both Codex and Nous auth structures in OAuth provider detection (#141)
The isOAuthAuthorized check only looked for Codex's nested
`providers.{key}.tokens.access_token` structure, missing Nous's flat
`providers.nous.access_token`. Now checks both paths so all OAuth
providers are correctly detected and displayed in the provider list.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-23 08:48:06 +08:00
ekkoandClaude Opus 4.6 df797d09b2 feat: add StepFun and Nous Portal provider support (#140)
- Add StepFun provider (API key auth, STEPFUN_API_KEY)
- Add Nous Portal provider with full OAuth device code flow
  (device code request → poll for token → mint agent key → save to auth.json)
- Add NousLoginModal component for OAuth UI (user code display + verification link)
- Update ProviderFormModal to handle Nous OAuth flow (hide API key fields)
- Add nous-auth backend controller and routes
- Update PROVIDER_ENV_MAP with stepfun and nous entries
- Add i18n translations for Nous OAuth in all 8 locales

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-23 08:39:19 +08:00
ekkoandClaude Opus 4.6 5537383bdb chore: optimize npm keywords and description for GitHub search discoverability (#135)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-22 22:04:26 +08:00
ekkoandClaude Opus 4.6 70ddbd0bcd feat: add username/password login, account settings, and changelog (#133) (#134)
- Add username/password login as additional auth mechanism alongside existing token
- First login must use token; password can be configured in Settings > Account
- Password login returns the existing static token (no auth middleware changes)
- Add account settings: setup, change password, change username, remove password
- Add logout button to sidebar footer
- Add version changelog popup (click version number in sidebar)
- Support all 8 locales (en, zh, de, es, fr, ja, ko, pt)
- Bump version to 0.4.3

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-22 20:27:33 +08:00
ekkoandClaude Opus 4.6 6f69c69802 feat: add token usage tracking, context display, and dynamic context length (#132)
* fix: specify TS_NODE_PROJECT for dev:server script

ts-node/register resolves tsconfig from the entry file upward,
finding the root solution-style tsconfig.json (no compilerOptions).
This causes target to default to ES3, breaking MapIterator spread
syntax (TS2802). Set TS_NODE_PROJECT env var to point to the server
tsconfig which targets ES2024.

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

* feat: add token usage tracking, context display, and dynamic context length

- Intercept SSE proxy to capture run.completed events and persist token
  usage (input_tokens, output_tokens) per session to SQLite/JSON store
- Display context usage bar in ChatInput showing used/total/remaining tokens
- Resolve actual context length from Hermes models_dev_cache.json based
  on the active profile's default model (fallback 200K), with 5min in-memory cache
- Move sessions-db.ts to db/hermes/ for unified database layer
- Add usage store with SQLite + JSON fallback (auto-migration via ensureTable)
- Fix proxy SSE path regex to match rewritten upstream path
- Fix route ordering: /sessions/usage before /sessions/:id to avoid 404
- Fetch per-session usage on session enter instead of batch
- Add unit tests for usage-store, db index, and proxy SSE interception

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-22 16:14:50 +08:00
ekkoandClaude Opus 4.6 ce3bf5f3eb fix: specify TS_NODE_PROJECT for dev:server script (#129)
ts-node/register resolves tsconfig from the entry file upward,
finding the root solution-style tsconfig.json (no compilerOptions).
This causes target to default to ES3, breaking MapIterator spread
syntax (TS2802). Set TS_NODE_PROJECT env var to point to the server
tsconfig which targets ES2024.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-22 14:03:59 +08:00
ekkoandClaude Opus 4.6 42a5e4052a chore: bump version to 0.4.2-beta.1 and improve chat UX (#122)
* chore: bump version to 0.4.2-beta.1 and improve chat UX

- Bump version to 0.4.2-beta.1
- Fix live monitor session selected style to match chat session style
- Add thin scrollbar with stable gutter to live monitor sidebar
- Fix live monitor detail scroll on mobile
- Show new chat button as icon-only on mobile using JS detection

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

* chore: fix version to 0.4.2

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-22 08:47:44 +08:00
ekkoandClaude Opus 4.6 83ad9642e2 fix(models): fix builtin provider detection and model matching (#120)
- Add glm-coding-plan to PROVIDER_ENV_MAP for proper env mapping
- Rename GLMCodingPlan value from 'glm' to 'glm-coding-plan' (kebab-case)
- Match custom providers against PROVIDER_PRESETS to reuse builtin models
- Fix provider key matching in create/update (use entry.name consistently)
- Clear stale base_url/api_key from config on provider create
- Clear model config when all providers are removed
- Add gateway restart on provider remove

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-22 00:11:39 +08:00
ekkoandClaude Opus 4.6 c4bea63a5e docs: update CLAUDE.md to reflect current project architecture (#115)
Sync CLAUDE.md with actual codebase structure:
- Add controller layer (thin-router, fat-controller pattern)
- Fix service paths (services/hermes/hermes-cli.ts)
- Document 8 locales, Vitest testing, esbuild bundling
- Add new modules: composables, profiles, gateways, codex-auth
- Fix route registration (routes/index.ts, not routes/hermes/index.ts)
- Add missing env vars (UPLOAD_DIR, CORS_ORIGINS, HERMES_BIN)
- Update bootstrap sequence and auth middleware docs

Also change docker-publish workflow to manual trigger only,
and remove dev branch from build workflow trigger.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-21 19:39:02 +08:00
ekkoandClaude Opus 4.6 81dad4c939 fix(docker): use if/else to map amd64 to x64 for Node.js download (#110)
dpkg returns 'amd64' but nodejs.org uses 'x64' in tarball filenames.
Shell substitution may not work in all shells, use explicit if/else.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-21 16:11:40 +08:00
ekkoandClaude Opus 4.6 fd02c01148 fix(docker): map amd64 to x64 for Node.js download URL (#109)
dpkg returns 'amd64' but nodejs.org uses 'x64' in tarball filenames.
Without this mapping, AMD64 builds fail with curl 404.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-21 15:59:51 +08:00
ekkoandClaude Opus 4.6 ed1f7d8301 fix(docker): split RUN steps to fix Node.js install on multi-platform build (#108)
Separate apt-get install from Node.js download into two RUN layers.
The piped curl|tar command fails with 404 when ca-certificates from
apt layer is not yet available during parallel multi-platform build.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-21 15:36:47 +08:00
ekkoandClaude Opus 4.6 832029a5b3 fix(docker): use tar.gz instead of tar.xz for Node.js binary (#107)
xz-utils is not available in the base image, causing ARM64 build to
fail with "File format not recognized".

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-21 15:21:28 +08:00
fdafb4e842 fix(docker): use official Node.js binary and remove unnecessary deps (#103)
* feat(chat): polish syntax highlighting and tool payload rendering (#94)

* [verified] feat(chat): polish syntax highlighting and tool payload rendering

* [verified] fix(chat): tighten large tool payload rendering

* docs: update data volume path in Docker docs

Align documentation with docker-compose.yml change:
hermes-web-ui-data -> hermes-web-ui, /app/dist/data -> /root/.hermes-web-ui

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

* refactor: bundle server build and restructure service modules

- Add build-server.mjs script for standalone server compilation
- Add logger service with structured output
- Restructure auth, gateway-manager, hermes-cli, hermes services
- Update docker-compose volume mount path
- Update tsconfig and entry point for bundled server

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

* refactor: separate controllers from routes and centralize route registration

- Extract business logic from route handlers into controllers/
- Add centralized route registry in routes/index.ts with public/auth/protected layers
- Replace global auth whitelist with sequential middleware registration
- Extract shared helpers to services/config-helpers.ts
- Allow custom provider name to be user-editable in ProviderFormModal
- Deduplicate custom providers by poolKey instead of base_url in getAvailable

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

* fix: auth bypass via path case, SPA serving, and provider improvements

- Fix auth bypass: path case-insensitive check for /api, /v1, /upload
- Fix SPA returning 401: skip auth for non-API paths (static files)
- Fix profile switch: use local loading state instead of shared store ref
- Auto-append /v1 to base_url when fetching models (frontend + backend)
- Guard .env writing to built-in providers only
- Add builtin field to provider presets, enable base_url input in form
- Print auth token to console on startup (pino only writes to file)

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

* fix(docker): correct volume mount path and update Node.js to 23

- Fix webui volume mount from /root/.hermes-web-ui to /home/agent/.hermes-web-ui
  (container runs as agent user, homedir() returns /home/agent)
- Update Node.js from 22 to 23 in Dockerfile

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

* ci: add ARM64 support for Docker image build

Add QEMU and multi-platform build (linux/amd64,linux/arm64) so
the image works on Apple Silicon and ARM-based NAS devices.

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

* fix(docker): use official Node.js binary and remove unnecessary deps

- Replace NodeSource with official Node.js binary (fixes ARM64 GPG error)
- Remove python3/python3-yaml (not needed, base image already has Python)
- Keep make/g++ for node-pty native compilation

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

---------

Co-authored-by: Zhicheng Han <43314240+hanzckernel@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-21 14:44:51 +08:00
7e739b70a2 ci: add ARM64 support for Docker image build (#101)
* feat(chat): polish syntax highlighting and tool payload rendering (#94)

* [verified] feat(chat): polish syntax highlighting and tool payload rendering

* [verified] fix(chat): tighten large tool payload rendering

* docs: update data volume path in Docker docs

Align documentation with docker-compose.yml change:
hermes-web-ui-data -> hermes-web-ui, /app/dist/data -> /root/.hermes-web-ui

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

* refactor: bundle server build and restructure service modules

- Add build-server.mjs script for standalone server compilation
- Add logger service with structured output
- Restructure auth, gateway-manager, hermes-cli, hermes services
- Update docker-compose volume mount path
- Update tsconfig and entry point for bundled server

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

* refactor: separate controllers from routes and centralize route registration

- Extract business logic from route handlers into controllers/
- Add centralized route registry in routes/index.ts with public/auth/protected layers
- Replace global auth whitelist with sequential middleware registration
- Extract shared helpers to services/config-helpers.ts
- Allow custom provider name to be user-editable in ProviderFormModal
- Deduplicate custom providers by poolKey instead of base_url in getAvailable

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

* fix: auth bypass via path case, SPA serving, and provider improvements

- Fix auth bypass: path case-insensitive check for /api, /v1, /upload
- Fix SPA returning 401: skip auth for non-API paths (static files)
- Fix profile switch: use local loading state instead of shared store ref
- Auto-append /v1 to base_url when fetching models (frontend + backend)
- Guard .env writing to built-in providers only
- Add builtin field to provider presets, enable base_url input in form
- Print auth token to console on startup (pino only writes to file)

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

* fix(docker): correct volume mount path and update Node.js to 23

- Fix webui volume mount from /root/.hermes-web-ui to /home/agent/.hermes-web-ui
  (container runs as agent user, homedir() returns /home/agent)
- Update Node.js from 22 to 23 in Dockerfile

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

* ci: add ARM64 support for Docker image build

Add QEMU and multi-platform build (linux/amd64,linux/arm64) so
the image works on Apple Silicon and ARM-based NAS devices.

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

---------

Co-authored-by: Zhicheng Han <43314240+hanzckernel@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-21 14:22:22 +08:00
5a114d97f6 fix(docker): correct volume mount path and update Node.js to 23 (#99)
* feat(chat): polish syntax highlighting and tool payload rendering (#94)

* [verified] feat(chat): polish syntax highlighting and tool payload rendering

* [verified] fix(chat): tighten large tool payload rendering

* docs: update data volume path in Docker docs

Align documentation with docker-compose.yml change:
hermes-web-ui-data -> hermes-web-ui, /app/dist/data -> /root/.hermes-web-ui

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

* refactor: bundle server build and restructure service modules

- Add build-server.mjs script for standalone server compilation
- Add logger service with structured output
- Restructure auth, gateway-manager, hermes-cli, hermes services
- Update docker-compose volume mount path
- Update tsconfig and entry point for bundled server

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

* refactor: separate controllers from routes and centralize route registration

- Extract business logic from route handlers into controllers/
- Add centralized route registry in routes/index.ts with public/auth/protected layers
- Replace global auth whitelist with sequential middleware registration
- Extract shared helpers to services/config-helpers.ts
- Allow custom provider name to be user-editable in ProviderFormModal
- Deduplicate custom providers by poolKey instead of base_url in getAvailable

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

* fix: auth bypass via path case, SPA serving, and provider improvements

- Fix auth bypass: path case-insensitive check for /api, /v1, /upload
- Fix SPA returning 401: skip auth for non-API paths (static files)
- Fix profile switch: use local loading state instead of shared store ref
- Auto-append /v1 to base_url when fetching models (frontend + backend)
- Guard .env writing to built-in providers only
- Add builtin field to provider presets, enable base_url input in form
- Print auth token to console on startup (pino only writes to file)

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

* fix(docker): correct volume mount path and update Node.js to 23

- Fix webui volume mount from /root/.hermes-web-ui to /home/agent/.hermes-web-ui
  (container runs as agent user, homedir() returns /home/agent)
- Update Node.js from 22 to 23 in Dockerfile

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

---------

Co-authored-by: Zhicheng Han <43314240+hanzckernel@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-21 13:19:25 +08:00
477af66232 fix: auth bypass, SPA serving, and provider improvements (#97)
* feat(chat): polish syntax highlighting and tool payload rendering (#94)

* [verified] feat(chat): polish syntax highlighting and tool payload rendering

* [verified] fix(chat): tighten large tool payload rendering

* docs: update data volume path in Docker docs

Align documentation with docker-compose.yml change:
hermes-web-ui-data -> hermes-web-ui, /app/dist/data -> /root/.hermes-web-ui

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

* refactor: bundle server build and restructure service modules

- Add build-server.mjs script for standalone server compilation
- Add logger service with structured output
- Restructure auth, gateway-manager, hermes-cli, hermes services
- Update docker-compose volume mount path
- Update tsconfig and entry point for bundled server

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

* refactor: separate controllers from routes and centralize route registration

- Extract business logic from route handlers into controllers/
- Add centralized route registry in routes/index.ts with public/auth/protected layers
- Replace global auth whitelist with sequential middleware registration
- Extract shared helpers to services/config-helpers.ts
- Allow custom provider name to be user-editable in ProviderFormModal
- Deduplicate custom providers by poolKey instead of base_url in getAvailable

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

* fix: auth bypass via path case, SPA serving, and provider improvements

- Fix auth bypass: path case-insensitive check for /api, /v1, /upload
- Fix SPA returning 401: skip auth for non-API paths (static files)
- Fix profile switch: use local loading state instead of shared store ref
- Auto-append /v1 to base_url when fetching models (frontend + backend)
- Guard .env writing to built-in providers only
- Add builtin field to provider presets, enable base_url input in form
- Print auth token to console on startup (pino only writes to file)

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

---------

Co-authored-by: Zhicheng Han <43314240+hanzckernel@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-21 12:35:48 +08:00
ekkoandClaude Opus 4.6 21296a416b fix: require auth for file upload and add 50MB size limit (#87)
* refactor: extract inline middleware from index.ts into separate modules

- Extract update middleware to routes/update.ts
- Extract health middleware and version logic to routes/health.ts
- Extract shutdown logic to services/shutdown.ts
- Extract gateway init to services/gateway-bootstrap.ts
- Remove unused variables, fix duplicate app creation
- Bump version to 0.4.0

index.ts: 260 lines → 80 lines

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

* fix: require auth for file upload and add 50MB size limit

Fixes #86

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-21 07:43:05 +08:00
ekkoandClaude Opus 4.6 c1b4e6d596 refactor: extract inline middleware from index.ts into separate modules (#85)
- Extract update middleware to routes/update.ts
- Extract health middleware and version logic to routes/health.ts
- Extract shutdown logic to services/shutdown.ts
- Extract gateway init to services/gateway-bootstrap.ts
- Remove unused variables, fix duplicate app creation
- Bump version to 0.4.0

index.ts: 260 lines → 80 lines

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-20 20:37:32 +08:00
ekko aa8dd65f95 Merge pull request #83 from EKKOLearnAI/dev
ci: add PR build check workflow and PR template
2026-04-20 20:11:33 +08:00
ekko 4c35225591 Merge pull request #80 from EKKOLearnAI/dev
fix: workflow trigger and server data volume mapping
2026-04-20 19:17:51 +08:00
ekko dca52061bd Merge pull request #76 from lingganwu/my-custom
Add GitHub Actions workflow for Docker image build
2026-04-20 18:52:27 +08:00
ekko a3d38fa5d5 Merge pull request #58 from EKKOLearnAI/dev
fix: provider-aware model selection (#52)
2026-04-19 15:08:12 +08:00
ekko da7910f934 Merge pull request #44 from 0xnuu/pr/chat-resilience-sidebar
feat(chat): improve resilience and collapsible sidebar
2026-04-18 14:32:36 +08:00
ekko a036569041 Merge pull request #16 from P2K0/feat/docker-compose-gateway-stability
feat: add docker-compose deployment and harden gateway startup
2026-04-17 08:11:04 +08:00
ekko d7d62e5f6c Merge pull request #15 from later0day/later0day/fix-node-pty-helper-perms
Prevent macOS terminal sessions from failing after node-pty installs
2026-04-17 08:10:58 +08:00
ekko 5143a264c5 Merge pull request #3 from cl1107/main
feat(chat): 修复输入法回车发送消息的问题
2026-04-13 18:29:46 +08:00
ekko 8663704133 Merge pull request #1 from cl1107/main
feat(sessions): 添加会话重命名功能和工具调用详情展示
2026-04-13 00:08:42 +08:00