* 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>
The regex `^(\w[\w\s]*?)` could not match keys containing dots (`.env`,
`SOUL.md`), so `hasEnv` and `hasSoulMd` were always `undefined` → false.
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
Add comprehensive debug logging throughout the gateway lifecycle to
help troubleshoot nodemon restart issues on Windows, where SIGTERM
is used instead of SIGUSR2.
Changes:
- Enhanced shutdown handler to log all signals and env var states
- Gateway manager now logs process detachment mode explicitly
- Added environment variable confirmation on bootstrap
- Updated gateway-development.md with new debug logs and troubleshooting steps
Benefits:
- Easier troubleshooting of gateway lifecycle issues
- Clear visibility into signal handling during nodemon restarts
- Better cross-platform development experience
- Production behavior remains unchanged
Testing:
- ✅ Windows: Gateways persist across nodemon restarts
- ✅ macOS/Linux: Existing SIGUSR2 behavior preserved
- ✅ Production: Default shutdown cleanup unchanged
- ✅ Backward compatibility: No breaking changes
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Set HERMES_WEB_UI_STOP_GATEWAYS_ON_SHUTDOWN=0 in nodemon.json so
nodemon restarts don't kill running gateways. Production behavior
unchanged (stops owned gateways by default).
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
- Refactor port detection into reusable getListeningPids/killListeningPids
- Add ss command fallback when lsof is unavailable
- Extract readPidFile for cleaner PID file reading
- Remove unnecessary PowerShell candidate from Windows shell detection
- Add PID validity check in gateway_state.json fallback (Number.isFinite + > 0)
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
* refactor(docker): merge two-container setup into single container
The Web UI already manages the Hermes Agent gateway lifecycle internally
via GatewayManager (spawn hermes gateway run --replace), making the
separate hermes-agent container redundant. The Dockerfile is built on
the hermes-agent base image, so all CLI tooling is already included.
- Remove hermes-agent service and shared volume from docker-compose.yml
- Remove gateway port mapping (8642-8670) — internal-only now
- Update docs/docker.md, README.md, README_zh.md for single-container setup
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* docs: remove version tag from image references
Use ekkoye8888/hermes-web-ui instead of ekkoye8888/hermes-web-ui:latest
to avoid pinning a specific version in documentation.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
- Emit tool.started on response.output_item.added instead of .done
- Track startedAt timestamp for each tool call to calculate duration
- Include duration (2 decimal places) and error status in tool.completed
- Fix response.completed fallback to emit tool.started before tool.completed
- Update website license from MIT to BSL-1.1
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Two issues prevented the gateway from starting in docker-compose:
1. gateway-manager used 'hermes-agent' as default host when running inside
a container, causing startAll() to skip gateway startup (remote host
guard) and proxy requests to an unreachable hostname. Changed to use
GATEWAY_HOST env var with fallback to '127.0.0.1' so the webui container
manages its own gateway via the shared hermes binary.
2. hermes refuses to run as root inside the official Docker image. The
hermes-webui container overrides the entrypoint (bypassing the privilege-
drop script), so the node process runs as root. Added
HERMES_ALLOW_ROOT_GATEWAY=1 to docker-compose.yml to allow this.
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>
- copilot-models.ts: add windowsHide to `gh auth token` call
- file-provider.ts: add shared execOpts with windowsHide for all
docker/ssh/singularity calls
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>
Use independent OPENCODE_ZEN_API_KEY and OPENCODE_GO_API_KEY
instead of shared OPENCODE_API_KEY, preventing cross-provider config coupling.
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.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>
Reduce the message count threshold that triggers LLM-based context
compression to avoid excessively long histories before compression kicks in.
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
* fix: lower context compression message threshold from 200 to 150
Reduce the message count threshold that triggers LLM-based context
compression to avoid excessively long histories before compression kicks in.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* feat: convert image uploads to base64 multimodal format for API
Images sent by users are now read from disk, converted to base64 data
URLs, and sent as input_image parts in the /v1/responses API request
instead of being replaced with text placeholders. File attachments remain
as text mentions.
- convertContentBlocks returns multimodal array instead of plain text
- Input is wrapped in [{role:"user", content:[...]}] format for gateway
- History conversion extracts text only (no base64 in conversation_history)
- Add debug logging for request input preview
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* chore: remove debug console.log from chat-run-socket
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
- Switch from MIT to Business Source License 1.1 (non-commercial use,
auto-converts to Apache 2.0 on 2029-05-10)
- Remove third-party brand keywords from package.json (chatgpt, claude,
openai, gemini, deepseek, telegram, discord, slack, whatsapp, etc.)
- Remove afdian sponsor links from README.md and README_zh.md
- Update license references in both READMEs to BSL-1.1
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>