Revert the dynamic import() for i18n locales and highlight.js core+
registration from #696. Dynamic imports create separate chunk files
that cause 404 errors for users after updating when the browser still
references old chunk hashes.
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
When starting gateways, automatically switch to 'default' profile if
current profile is not 'default'. This ensures consistent gateway startup
behavior and prevents port conflicts from different profile configurations.
Changes:
- Check current profile before starting gateways
- Execute 'hermes profile use default' if needed
- Wait 2 seconds for profile switch to take effect
- Update internal GatewayManager state
- Add detailed logging for the switching process
* 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>
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