* feat(chat): add direct live badge to session rows
* fix(live): use session DB for conversations monitor
* docs: add chat vs live monitor direction plan
* fix(search): avoid numeric session search 500 without FTS table
* 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>
* feat: add single-page live session monitor and chat pinning
* fix: restore full test green after main merge
* fix: use Array.from instead of Set spread for ts-node compatibility
[...new Set()] requires downlevelIteration which isn't enabled in
ts-node dev mode, causing sonic-boom crash on startup.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: ekko <fqsy1416@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* 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>
Replace static top-level import with runtime version check and dynamic
import() so Node < 22.5 gracefully falls back to CLI path instead of
crashing at module load time.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
SQLite path was returning null title for sessions without an explicit
title, while the CLI path derives it from the first user message.
Now uses the preview (first user message content) as title fallback,
matching the original CLI behavior.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix#25: job update sends schedule as plain string but upstream expects
{ kind, expr, display } object, causing "'str' object has no attribute 'get'"
- Move hermes-cli.ts, hermes.ts, hermes-profile.ts into services/hermes/
for multi-agent namespacing consistency
- Fix ts-node Set spread compatibility in filesystem.ts
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Set up Vitest with jsdom for client tests, node for server tests
- Add tests for auth service, proxy handler, API client, and profiles store
- Strip Authorization header in proxy to prevent web-ui token leaking to gateway
- Distinguish local BFF vs proxied gateway 401s to avoid false logouts
- Remove unused hero.png asset
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>