* 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>
- 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
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>
Add missing keys: removeCustomModel, aliasEdit/Title/Placeholder/etc
(10 alias keys), and visibilitySelectOne to match zh.ts.
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
* 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
Expand changelog from 5 to 25 entries covering all changes:
comic theme, kanban parity, model visibility, TTS settings,
Windows/Termux compat, YAML parsing, gateway ownership, etc.
Also backfill zh-TW locale with missing keys (changelog, model
visibility, TTS rate/pitch).
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
* 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
* feat(client): add Traditional Chinese (zh-TW) language support
Update language switcher and i18n configuration to include Traditional Chinese.
Modify locale resolution to prioritize exact matches (zh-TW) over base codes (zh),
ensuring accurate browser language detection. Add complete translation set.
Co-authored-by: Copilot <copilot@github.com>
* feat(i18n): improve BCP-47 locale resolution and browser languages
Refactor resolveLocale to use a normalize helper that correctly maps BCP-47 tags to supported locale keys, properly distinguishing Traditional vs Simplified Chinese variants. Additionally, iterate over navigator.languages instead of relying solely on navigator.language to respect the browser's full language preference list.
Co-authored-by: Copilot <copilot@github.com>
---------
Co-authored-by: Copilot <copilot@github.com>
* fix: comprehensive Windows compatibility and gateway management improvements
This commit addresses multiple Windows compatibility issues and improves
gateway management across all platforms.
## Windows Compatibility Fixes
- Add hermes-path.ts with cross-platform Hermes home/bin detection
- Fix Windows native installation paths (%LOCALAPPDATA%\hermes)
- Update terminal.ts to use PowerShell instead of /bin/bash on Windows
- Fix upload.ts path construction to use path.join() for cross-platform paths
- Fix download.ts to use isAbsolute() for Windows absolute path detection
- Update auth.ts to skip file mode 0o600 on Windows (unsupported)
- Add nodemon.json for cross-platform environment variable handling
## Gateway Management Improvements
- Simplify gateway startup: all platforms use 'run' mode uniformly
- Remove complex init system detection and platform-specific code paths
- Improve PID file validation: use health check instead of port detection
- Remove getPortByPid() method (too complex and error-prone)
- Remove checkPortAvailable() TCP bind test (TIME_WAIT false positives)
- Trust gateway --replace flag to handle real port conflicts
- Add smart PID validation: check if stale process via health check
- Fix port allocation to avoid incrementing when gateway restarts
- Add allocatedPorts.clear() on each startAll() call
- Add clearPidFile() method to clean up stale PID files
## Process Management
- Remove detached:true and unref() from gateway spawn
- Gateway processes now follow parent process lifecycle
- Add process reference storage in ManagedGateway interface
- Improve shutdown logic: call gatewayManager.stopAll() before exit
- Fix Windows process killing: use process.kill(pid) for Windows
- Remove PowerShell command for lock file cleanup (use Node.js fs.unlinkSync)
## Frontend Theme Fixes
- Fix main.ts localStorage key mismatch (hermes_theme → hermes_brightness)
- Add inline script in index.html to prevent FOUC (Flash of Unstyled Content)
- Apply theme classes before Vue mount to avoid visual glitches
## Developer Experience
- Fix nodemon windows-kill popup on Windows by removing signal config
- Add delay and environment variables to nodemon.json
- Add windowsHide: true to all child process spawns
## Breaking Changes
- Gateway management now exclusively uses 'run' mode on all platforms
- systemd/launchd integration removed (use --replace flag instead)
This fix ensures hermes-web-ui works correctly on Windows native
installations while maintaining compatibility with Linux/macOS/WSL2.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Fix gateway lifecycle port handling
* fix: comprehensive Windows compatibility and gateway management improvements
- Simplified hermes CLI binary resolution logic
- Fixed Windows line ending compatibility in profile list parsing
- Migrated gateway restart logic from CLI to GatewayManager
- Added gateway restart to updateCredentials method
- Removed unnecessary gateway restarts from provider operations
- Fixed configuration preservation when switching profiles
- Added nodemon quiet mode and legacy watch to reduce Windows popups
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* revert: change back to nodemon due to tsx compatibility issues
- tsx has compatibility issues with Koa generator functions
- Restored nodemon with simplified configuration
- Added cross-env package for future Windows environment variable needs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: replace nodemon with ts-node-dev to eliminate Windows popup windows
- Installed ts-node-dev as nodemon replacement
- ts-node-dev has better Windows compatibility without console popups
- Supports respawning, inspector debugging, and TypeScript compilation
- Uses cross-env for Windows environment variable support
- Removed nodemon.json configuration file (no longer needed)
Benefits:
- No more Windows console popup windows during development
- Faster restart times compared to nodemon
- Built-in TypeScript compilation without ts-node overhead
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: improve log parsing and Windows compatibility for agent/error logs
- Fixed Pino JSON log parsing bug where logger field incorrectly used obj.msg
- Changed logger field to use obj.name to properly display log source
- Added Windows line ending support (\r\n) for log file listing
- Added support for 'error' log type in addition to 'errors'
- Improved error message extraction from obj.err when available
This fixes the missing agent and error logs issue on Windows.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Fix gateway health checks and shutdown ownership
* Refine auth lock window and dev shutdown
* fix: improve Hermes plugin discovery on Windows by fixing Python path resolution
- Added support for Windows venv Scripts directory structure
- Fixed Python executable path detection for hermes.exe in venv/Scripts/
- Added Windows LOCALAPPDATA hermes-agent directory to search paths
- Improved cross-platform compatibility for plugin discovery
This fixes the "No module named 'hermes_cli'" error on Windows by correctly
locating the Python virtual environment that contains the Hermes modules.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* refactor: improve cross-platform compatibility for Hermes plugin discovery
- Added platform detection to only add Windows-specific paths on Windows
- Prevents potential issues on Unix/Linux/macOS systems
- Ensures LOCALAPPDATA path is only used when available on Windows
- Maintains existing behavior for all platforms
This makes the Windows plugin discovery fix safer for cross-platform usage.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* chore: remove unused development dependencies
- Removed nodemon (replaced by ts-node-dev)
- Removed tsx (had compatibility issues with Koa)
- Removed nodemon.json configuration file
- Cleaned up development tools to only what's actually used
This reduces dependency size and eliminates the windows-kill popup
source that was part of nodemon.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* chore: remove memory system files
- Removed MEMORY.md index file
- Removed memory/ directory and windows-compatibility.md
- Cleaned up unused memory persistence system
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: resolve TypeScript compilation error in plugins.ts
- Added type assertion 'as string[]' after filter(Boolean)
- Fixes TS2769 error: No overload matches this call
- Ensures type compatibility with hasHermesPluginModule function
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: comprehensive Windows compatibility and gateway management improvements
- Fix gateway detection after nodemon restart by adding health check-based detection
- Prevent port conflicts by detecting already-running gateways without PID files
- Switch to serial gateway startup to avoid lock file race conditions
- Return to nodemon from ts-node-dev for development stability
- Always stop gateways on shutdown to prevent orphan processes
- Prevent project root config files from being committed to git
- Fix syntax issues in plugins.ts
Resolves issues where default profile gateway failed to start after
nodemon restart and gateways were incorrectly marked as stopped
despite running on correct ports.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: comic theme multilingual fonts, sidebar collapse fix, plugin discovery for Termux, and cron history
- Add Chinese (ZCOOL KuaiLe), Japanese (Zen Maru Gothic), Korean (Gaegu) handwritten fonts for Comic theme
- Fix collapsed sidebar: hide language switch, stack theme icons vertically
- Add hermes shebang parsing as fallback Python discovery for Termux
- Remove cron source filter from history sessions
- Add 0.5.17 changelog entries for all 8 locales
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix: tolerate duplicate YAML keys in config parsing (closes#628)
Add `{ json: true }` to all 7 `yaml.load()` calls so duplicated mapping
keys (e.g. multiple `mcp_servers:` blocks) no longer crash the API.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix: gateway ownership check requires PID file to prevent cross-profile port hijacking
Remove fallback that assumed ownership of healthy gateways without PID
verification. Now only claims a gateway if PID file exists and process
is alive, preventing one profile from hijacking another's port.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: add comic/doodle theme style with local font
Add a new "comic" theme style that applies hand-drawn aesthetics (Comic Neue
font, bold borders, heavy font weight) while keeping the original light/dark
background colors. Font files are bundled locally to avoid Google Fonts CDN
dependency.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix: update DisplaySettings to use renamed theme API and update brand assets
Rename mode/setMode/ThemeMode to brightness/setBrightness/BrightnessMode
to match the refactored useTheme composable. Update favicon and logo.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Defer all non-user message DB writes until response completion or
abort, instead of writing tool calls immediately during streaming.
This ensures correct message ordering and prevents the abort handler
from overwriting displayed messages with incomplete DB data.
- Remove immediate addMessage() calls from response.output_item.done
- Remove immediate addMessage() from insertResponseTextOnce
- Add flushResponseRunToDb() to batch-write all run messages on
both normal completion (markCompleted) and abort (handleAbort)
- Skip user messages in flush (already written in handleRun)
- Remove refreshActiveSession() from abort.completed frontend handler
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
* refactor: migrate from /v1/runs to /v1/responses streaming API
Replace EventSource-based polling with direct SSE streaming via the
/v1/responses endpoint across all server-side callers (chat-run-socket,
context-compressor, gateway-client, agent-clients). Messages are now
written to DB in real-time during streaming, eliminating post-run sync.
Frontend chat store adds tool_call_id tracking for deduplication.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* chore: bump version to 0.5.16 and add changelog
- Persist real API usage to usage table on response.completed
- Remove unused codex_reasoning_items field from message schema
- Fix unused variable warnings in chat-run-socket
- Bump version to 0.5.16
- Add changelog entries for 0.5.16 (8 locales)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Add a website icon link (globe) alongside the GitHub icon in the
sidebar footer. Shorten version label from "Hermes Web UI" to "Web UI".
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
- Fix kanban loading spinner flickering on auto-refresh (silent mode)
- Fix group chat room-list transparent background on mobile
- Fix group chat sidebar auto-opening on mobile entry
- Fix page-header title overlapped by hamburger button on mobile
- Move hamburger button position to top: 10px
- Add changelog note about upgrading hermes-agent for kanban support
- Add i18n translations for all 8 locales
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
* 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
* feat: add IP-based login brute-force protection
- Per-IP rate limiting: 3 failed login attempts locks the IP for 1 hour
- Separate counters for password login and token auth
- Global safety net: 20 req/min, hard lock after 50 total failures
- Persistent lock state to ~/.hermes-web-ui/.login-lock.json (survives restarts)
- Manual unlock: edit or delete the lock file
- Frontend handles 429/503 responses with localized error messages
- i18n support for 8 languages
* feat: add locked IP management endpoint and UI
- GET /api/auth/locked-ips: list all currently locked IPs (protected)
- DELETE /api/auth/locked-ips/:ip: unlock a specific IP (protected)
- DELETE /api/auth/locked-ips: unlock all IPs (protected)
- AccountSettings: shows locked IPs with remaining time, unlock buttons
- i18n support for 8 languages
- Clean up stale .js artifacts, add .gitignore rule
* fix: cross-type IP lock and IPv6-compatible unlock route
- Password and token login now share IP lock state: if an IP is locked
by either method, ALL auth methods are blocked for that IP
- Changed unlock endpoint from path param to query param (?ip=xxx) to
support IPv6 addresses containing colons
- Merged unlockIp and unlockAll into a single handler
* chore: increase global login rate limit from 20 to 100 requests per minute
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---------
Co-authored-by: ekko <fqsy1416@gmail.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
FUN-Codex: add GPT models (5.5, 5.4, 5.4-mini, 5.3-codex, 5.3-codex-spark)
FUN-Claude: replace with actual Claude models from API (opus-4-7 down to 3-5-haiku)
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
TerminalPanel was connecting on mount even when the drawer was closed
and the terminal tab was inactive. Combined with reconnectAttempts
resetting on every ws.onopen, this caused infinite reconnection loops
that spawned PTY processes until system limits were hit.
- Pass `visible` prop to TerminalPanel, only connect when terminal tab
is actually shown
- Move reconnectAttempts reset from ws.onopen to "created" handler so
only successful PTY creation resets the counter
- Remove unused onMounted import
Fixes#509
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
PR #470 changed the default listen host to undefined, letting Node.js
bind to IPv6 :: on systems that support it. This broke WSL2 where IPv6
dual-stack is unreliable — the server binds to :: but IPv4 127.0.0.1
connections fail, causing the health check to time out.
Revert to 0.0.0.0 as the default. Users who need IPv6 can set
BIND_HOST=:: explicitly.
Fixes#518
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
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>
Allow sending multiple messages while a run is active. Messages are
queued on the server and processed sequentially after each run
completes. Each completed assistant message triggers speech playback
independently, and the UI shows queue status with a badge indicator.
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
The @ symbol is a special character in vue-i18n (used for linked formats).
Removing it from all changelog entries fixes:
- Chinese: @mention → mention
- English: @mention → mention
- All other languages: @mention → mention
This resolves the SyntaxError in message compilation.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Bug: In group chat input, using keyboard (ArrowDown/ArrowUp + Enter) to
select an agent from the @mention dropdown always inserts the wrong agent
name (the first one), regardless of which item is visually highlighted.
Mouse click works correctly.
Root cause: naive-ui's NDropdown has its own internal keyboard state machine
that is independent from the component's activeIndex ref. When Enter is
pressed, NDropdown fires @select using its own stale index before
handleKeydown runs, always selecting the wrong agent. NDropdown exposes no
public API to synchronize its internal state, making this unfixable in place.
Fix: Replace NDropdown with a custom <div class="mention-dropdown">
rendered via v-for, with fully manual keyboard/click/hover control. This
eliminates the dual-state conflict entirely — there's a single activeIndex
for all interactions.
Additional improvements over the previous NDropdown-based implementation:
- Scroll follows the active item automatically (scrollToActive)
- Dropdown flips upward when insufficient space below (smart placement)
- Click-outside-to-close via document-level listener
- Transition animation matching NDropdown's fade-in-scale-up exactly
(0.2s cubic-bezier, scale 0.9->1 with opacity fade)
Co-authored-by: Fix Contributor <fix-contributor@hermes-web-ui.dev>
* feat: add batch delete functionality for chat sessions
Backend:
- Add batchRemove controller to handle bulk session deletion
- Add POST /api/hermes/sessions/batch-delete endpoint
- Support both local session store and CLI deletion
- Return detailed results (deleted, failed, errors)
Frontend:
- Add batch selection mode with checkboxes in SessionListItem
- Add batch selection toggle and select all button
- Add batch delete button with confirmation
- Update ChatPanel to manage selected session IDs
- Add batchDeleteSessions API function
i18n:
- Add batch delete translations for all 8 languages
- Simplify "Web UI/API Server Sessions" to "Sessions"
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: vertically align buttons in session list header
Add inline-flex and center alignment to all buttons in session-list-actions
to ensure proper vertical centering with the title text.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: ensure proper vertical alignment in session list header
- Set fixed height of 22px for session-list-actions
- Add min-height and height to all buttons
- Add line-height to session-list-title for text baseline alignment
- Add min-height: 0 to session-list-header to prevent flex stretch
This ensures the title and all action buttons are perfectly vertically centered.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: call loadSessions after batch delete instead of looping deleteSession
The previous implementation was calling chatStore.deleteSession(id) in a loop
after batch delete API succeeded, which triggered individual delete API calls
for each session - causing n API requests instead of 1.
Now we simply call loadSessions() to refresh the session list from the server
after successful batch deletion, ensuring:
- Only 1 API request for batch delete
- UI stays in sync with server state
- No duplicate API calls
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* refactor: improve update mechanism reliability
Major improvements to the update system:
**Path Resolution:**
- Remove unreliable dirname(process.execPath) assumption
- Use npm from PATH environment variable
- Dynamically get global prefix via `npm prefix -g`
- Calculate CLI path based on actual global install location
**Windows Support:**
- Remove complex cmd.exe wrapper logic
- Directly call npm.cmd (works on all Windows setups)
- Simplified quote handling
**Error Handling:**
- Add fallback error message (err.stderr || err.message || String(err))
- Add default success message when output is empty
- Wrap spawnRestart in try-finally to ensure cleanup
**Timing:**
- Increase timeout from 120s to 10min (slow network support)
- Increase restart delay from 2s to 3s (safer margin)
**Code Quality:**
- Remove unused functions (getNodeBinDir, getWindowsShell, quoteForWindowsCommand)
- Use constants instead of magic numbers (10 * 60 * 1000)
- More maintainable and cross-platform compatible
This fixes issues where updates would fail due to incorrect npm/CLI paths
on systems with non-standard Node.js installations.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>