* fix(start): use server-entry wrapper for production
* fix(swarm): reconcile oneshot checkpoints and ignore phantom blockers
* fix(profiles): sync editable descriptions from profile config
* fix: show cron jobs across Hermes profiles
* fix(capabilities): clarify dashboard-backed API detection
* feat: make Conductor use native Swarm fallback
Treat Workspace-native Swarm as the official Conductor fallback when the dashboard mission API is unavailable. Preserve dashboard-first dispatch, native status/cancel handling, provider-neutral setup docs, and regression coverage for gateway capability detection, swarm health, roster/profile handling, and native Conductor responses.
* fix(usage-meter): reposition menu trigger for better alignment
- Adjusted the position of the menu trigger in the usage meter component to enhance layout consistency and user experience.
fix(chat-panel): adjust position of chat panel toggle button
- Updated the positioning of the chat panel toggle button to improve visibility and accessibility by changing its bottom and right offsets.
* fix(stt): wire Groq/OpenAI voice transcription into chat
* Fix Workspace Kanban loopback dashboard link
* fix(update): do not open historical release notes on startup
* fix(chat): clear stale thinking runs reliably
* fix(dashboard): trust sessions endpoint for status
* fix(settings): address review — local default, OAuth lifecycle, validation
* fix(dashboard): always scrape live session token from HTML
* fix(chat): avoid portable history replay on bound sessions
* fix(settings): remove dead smart routing controls
* fix(tasks-api): guard against HTML catch-all in probeBackend
The /api/hermes-tasks route was renamed to /api/claude-tasks in commit
efcb7d14, but the probe logic still listed the old route as a candidate.
When probed, the SPA catch-all returned a 200 HTML response instead of
a 404, so probeBackend() treated it as a valid (empty) backend and then
failed when the actual task fetch threw.
Fixes:
- probeBackend() now checks Content-Type: application/json and returns
-1 for non-JSON responses, so future route renames degrade gracefully.
- resolveBackend() now only selects hermes if hermesCount > 0, defaulting
to claude-tasks (the active backend post rename) when hermes is absent.
* fix(terminal): default cwd to ~ and fallback if path missing
PTY helper chdir fails when ~/.hermes is absent (common in Docker).
Default shell cwd to home; server falls back to HOME if cwd does not exist.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(settings): satisfy lint on custom providers UI
* fix(docker): add -m flag to useradd so workspace home dir is created
Without -m, the system account has no /home/workspace directory.
The auth middleware tries to write the session store at
/home/workspace/.hermes/workspace-sessions.json; mkdirSync fails with
EACCES because /home/ is root-owned (755), causing the 'Failed to
persist session store' warning and a 500 on every authenticated route.
Adding -m causes useradd to create and chown /home/workspace correctly
so the session store can be written on first login.
* fix(tasks): preserve real session links and restore task launch flow
* fix(launchd): install macOS plist from server-entry template
* fix(docker): expose dashboard API and persist workspace volumes
* fix(jobs): serialize deliver targets for cron API
* Make Hermes Workspace installable as PWA
* chore(deps): pin direct tanstack versions
* feat: align semantic Hermes swarm agents
Add semantic swarm roster metadata, profile/tool/skill docs, shared semantic worker ID validation, focused roster regression coverage, and one-shot checkpoint capture for dispatch smoke tests.
* fix(conductor): pass through sessionKeyPrefix from portable spawn result
sessionKeyPrefix was hardcoded to null in conductor-spawn.ts, breaking
async session resolution when the dashboard backend returns a prefix.
Now mirrors the sessionKey pattern and passes through the value from
the spawn result.
Co-authored-by: Hermes Agent
* feat(swarm): bridge workspace kanban to native Hermes
* fix(chat): keep portable main pinned without breaking resolved sessions
* Add Windows startup script for Hermes Workspace
Document PowerShell usage for launching and restarting gateway + workspace via WSL tmux.
Co-Authored-By: Oz <oz-agent@warp.dev>
* fix(config): name Hermes Agent in restart notice
* fix(swarm): reconcile aggregate semantic worker exports
---------
Co-authored-by: Aurora release bot <release@outsourc-e.com>
Co-authored-by: motoki takahashi <motokitakahashi@motokinoMac-mini.local>
Co-authored-by: Vicky Wonder <vicky@openclaw.ai>
Co-authored-by: Vitaliy Isikov <visikov+supagoku@gmail.com>
Co-authored-by: Hermes Agent <hermes-agent@local>
Co-authored-by: Nikolay Mohr <nikomohr96@gmail.com>
Co-authored-by: Niko Mohr <niko@friendsfromcollege.de>
Co-authored-by: wtchronos <262830926+wtchronos@users.noreply.github.com>
Co-authored-by: Dak0verflow <dakotaferris@gmail.com>
Co-authored-by: norema <mamadou.marone.19@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: daoyuan <ludaoyuan1989@gmail.com>
Co-authored-by: firemountain <firemountain@gmail.com>
Co-authored-by: RAZSOC Local <razsoc@local>
Co-authored-by: Waylon Kenning <waylonkenning@Waylons-MacBook-Pro.local>
Co-authored-by: Kublai <kublai@kublai.local>
Co-authored-by: justa <justa@local>
Co-authored-by: Oz <oz-agent@warp.dev>
129 lines
5.4 KiB
YAML
129 lines
5.4 KiB
YAML
# Hermes Workspace + Agent — Docker Compose Setup
|
|
#
|
|
# Requirements:
|
|
# - Docker & Docker Compose
|
|
# - At least one LLM provider key in .env (ANTHROPIC_API_KEY,
|
|
# OPENAI_API_KEY, OPENROUTER_API_KEY, GOOGLE_API_KEY, …) OR a
|
|
# reachable local server (Ollama, LM Studio, etc.)
|
|
#
|
|
# Quick Start:
|
|
# 1. cp .env.example .env
|
|
# 2. Add at least one provider key (whichever you use)
|
|
# 3. docker compose up
|
|
# 4. Open http://localhost:3000
|
|
#
|
|
# Images:
|
|
# This file pulls pre-built images by default — no local build required.
|
|
# - nousresearch/hermes-agent:latest (Hermes Agent, Dockerfile upstream)
|
|
# - ghcr.io/outsourc-e/hermes-workspace:latest (this workspace)
|
|
#
|
|
# To build from source instead (e.g. for development), use:
|
|
# docker compose -f docker-compose.yml -f docker-compose.dev.yml up
|
|
#
|
|
# Persistent data:
|
|
# `hermes-agent-data` — agent config, sessions, skills, memory, credentials.
|
|
# Mounted at /opt/data in the agent container and /home/workspace/.hermes
|
|
# in the workspace container (read-write for config reads; the agent is
|
|
# the primary writer).
|
|
# `hermes-workspace-files` — files created from the Workspace file browser.
|
|
# Both volumes survive container recreation and `docker compose down`.
|
|
# Only `docker compose down -v` removes them.
|
|
#
|
|
# Troubleshooting:
|
|
# - See README.md "Docker" troubleshooting section
|
|
# - Check logs: docker compose logs hermes-agent
|
|
# - Agent must expose port 8642
|
|
|
|
services:
|
|
# The Hermes Agent gateway + dashboard APIs.
|
|
# Gateway runs in the foreground on :8642. Dashboard runs as a background
|
|
# process on :9119 and is reachable only on the private Docker network.
|
|
hermes-agent:
|
|
image: nousresearch/hermes-agent:latest
|
|
restart: unless-stopped
|
|
# The Hermes Agent image entrypoint defaults to the interactive CLI which exits
|
|
# immediately under `docker compose up -d`. We override here to start the
|
|
# gateway, which is the long-running API/health server the Workspace needs.
|
|
# See #360.
|
|
command: ["gateway", "run"]
|
|
env_file:
|
|
- .env
|
|
environment:
|
|
# Pass through whichever provider keys are set in .env. hermes-agent
|
|
# uses the one that matches the provider configured in
|
|
# ~/.hermes/config.yaml (or whatever `hermes setup` picked).
|
|
ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY:-}
|
|
OPENAI_API_KEY: ${OPENAI_API_KEY:-}
|
|
OPENROUTER_API_KEY: ${OPENROUTER_API_KEY:-}
|
|
GOOGLE_API_KEY: ${GOOGLE_API_KEY:-}
|
|
GROQ_API_KEY: ${GROQ_API_KEY:-}
|
|
MISTRAL_API_KEY: ${MISTRAL_API_KEY:-}
|
|
HERMES_UID: '10010'
|
|
HERMES_DASHBOARD: '1'
|
|
HERMES_DASHBOARD_HOST: 0.0.0.0
|
|
HERMES_DASHBOARD_PORT: '9119'
|
|
# Authentication for the gateway when exposing off-loopback.
|
|
# In the default compose setup the gateway is reachable from the
|
|
# workspace container over the docker network on hermes-agent:8642,
|
|
# so an empty key works for localhost-only Docker installs. For any
|
|
# deployment that publishes 8642 on the host or a LAN IP, set a
|
|
# strong API_SERVER_KEY in .env — the workspace passes it through
|
|
# as HERMES_API_TOKEN below. See #122.
|
|
API_SERVER_KEY: ${API_SERVER_KEY:-}
|
|
# Bind inside the container so the workspace can reach the gateway over
|
|
# Docker DNS. The host publish below remains loopback-only.
|
|
API_SERVER_HOST: 0.0.0.0
|
|
API_SERVER_ENABLED: 'true'
|
|
volumes:
|
|
- hermes-agent-data:/opt/data
|
|
healthcheck:
|
|
test: ['CMD-SHELL', 'curl -fsS http://localhost:8642/health && curl -fsS http://localhost:9119/api/status || exit 1']
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
start_period: 30s
|
|
ports:
|
|
- '127.0.0.1:8642:8642'
|
|
|
|
# The Hermes Workspace Web UI
|
|
# Connects to hermes-agent at http://hermes-agent:8642
|
|
hermes-workspace:
|
|
image: ghcr.io/outsourc-e/hermes-workspace:latest
|
|
restart: unless-stopped
|
|
depends_on:
|
|
hermes-agent:
|
|
condition: service_healthy
|
|
env_file:
|
|
- .env
|
|
environment:
|
|
HERMES_HOME: /home/workspace/.hermes
|
|
HERMES_WORKSPACE_DIR: /workspace
|
|
# Internal Docker network URL (not localhost!)
|
|
HERMES_API_URL: http://hermes-agent:8642
|
|
HERMES_DASHBOARD_URL: http://hermes-agent:9119
|
|
# Must match API_SERVER_KEY on the hermes-agent side when that is set
|
|
HERMES_API_TOKEN: ${API_SERVER_KEY:-}
|
|
# Workspace session password. REQUIRED when HOST is non-loopback (the
|
|
# default for Docker images, so the container binds 0.0.0.0:3000).
|
|
# Pick a strong secret. See #122.
|
|
# HERMES_PASSWORD is preferred; CLAUDE_PASSWORD remains as a back-compat
|
|
# fallback for compose files that pre-date the rename.
|
|
HERMES_PASSWORD: ${HERMES_PASSWORD:-${CLAUDE_PASSWORD:-}}
|
|
# Enable the Secure flag on session cookies when terminated behind
|
|
# HTTPS (reverse proxy / Tailscale Funnel / Cloudflare Tunnel). See #123.
|
|
COOKIE_SECURE: ${COOKIE_SECURE:-}
|
|
# Trust proxy-forwarded headers (x-forwarded-for / x-real-ip) for IP
|
|
# classification. Leave unset unless you deploy behind a trusted proxy
|
|
# that sanitizes these headers — otherwise a client can spoof its IP
|
|
# and bypass local-classification / rate limiting. See #125.
|
|
TRUST_PROXY: ${TRUST_PROXY:-}
|
|
volumes:
|
|
- hermes-agent-data:/home/workspace/.hermes
|
|
- hermes-workspace-files:/workspace
|
|
ports:
|
|
- '127.0.0.1:3000:3000'
|
|
|
|
volumes:
|
|
hermes-agent-data:
|
|
hermes-workspace-files:
|