* feat: support profile-aware group chat bridge flows
* feat: route cron jobs through hermes cli
* Fix group chat routing and isolate bridge tests
* Add Grok image-to-video media skill
* Default Grok videos to media directory
* Fix bridge profile fallback and cron repeat clearing
* Refine bridge chat and gateway platform handling
* Filter bridge tool-call text deltas
* Preserve structured bridge chat history
* Prepare beta release build artifacts
* Fix Windows run profile resolution
* Fix Windows path compatibility checks
* Fix profile-scoped model page display
* Hide Windows subprocess windows for jobs and updates
* Hide Windows file backend subprocess windows
* Avoid Windows gateway restart lock conflicts
* Treat Windows gateway lock as running on startup
* Force release Windows gateway lock on restart
* Tighten Windows gateway lock cleanup
* Update chat e2e source expectation
* Bump package version to 0.5.30
---------
Co-authored-by: Codex <codex@openai.com>
- custom_providers: always use user's base_url instead of
PROVIDER_PRESETS matching by name that overwrites local URLs
- JobFormModal: dynamically add connected platform channels
(Telegram, Discord, Slack, WhatsApp, Matrix, WeChat, WeCom,
Feishu, DingTalk) to job deliver target dropdown
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
* 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>
* 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
* 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
* 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
* 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 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>
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>
- Added scanSkillsDir() function that scans both three-level
(skills/<category>/<skill>/SKILL.md) and two-level
(skills/<skill>/SKILL.md) directory structures.
- Flat skills (at two-level) are grouped under a new 'misc'
(雜項) category, displayed with Chinese name '雜項'.
- Updated listFiles() and readFile_() to handle 'misc' category
path mapping correctly.
- All tests pass (347 passed, 3 pre-existing failures unrelated
to this change).
* 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>
* feat: add database table for model context length configuration
- Add model_context table with provider/model/context_limit fields
- Implement UPSERT endpoint for model context configuration
- Add priority lookup: database > config.yaml > custom_providers > cache
- Add frontend click-to-edit UI in ChatInput with tooltip
- Add i18n support for context editing dialog (all 8 locales)
- Use context_limit field consistently across frontend and backend
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: use useMessage() composable instead of window.$message in ChatInput
- Remove incorrect NMessage import (not a component)
- Use useMessage() composable from naive-ui
- Replace window.$message?.xxx() with message.xxx()
- Fixes TypeScript build errors
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>