Removes `docker/agent/Dockerfile` and `docker/workspace/Dockerfile`:
- `docker/agent/Dockerfile` cloned the wrong repo (`outsourc-e/hermes-agent`
is the workspace fork, not the agent) and ran the old `claude` binary
name. It would not build successfully.
- `docker/workspace/Dockerfile` was a dev-mode (`pnpm dev`) variant that
duplicated the production root `Dockerfile` for no benefit; the dev
overlay now reuses the root Dockerfile with hot-build instead.
Updates `docker-compose.dev.yml` to build only the workspace from local
source via the canonical root Dockerfile. The Hermes Agent service stays
on the canonical `nousresearch/hermes-agent:latest` upstream image
(~750k pulls), with a clear note in the overlay header explaining how
to override if a custom agent image is genuinely needed.
Adds a quick-start path table at the top of README pointing 'compose
gig' users straight at the Docker section, and rewrites the dev-overlay
section to match the simpler reality.
This addresses the recurring 'can we get a docker image so I can set
up a compose gig instead of building from source' community ask. The
image already exists at `ghcr.io/outsourc-e/hermes-workspace:latest`,
the compose file just works \u2014 the stale local Dockerfiles were the
only thing making the dev overlay confusing.
Co-authored-by: Aurora release bot <release@outsourc-e.com>
NODE_ENV=production enables the Secure flag on session cookies. Browsers
silently drop Secure cookies over plain HTTP, causing login to fail with
no visible error when HOST=0.0.0.0 is used on a LAN without HTTPS.
- Add startup warning in server-entry.js when non-loopback host +
production + COOKIE_SECURE not explicitly disabled
- Document COOKIE_SECURE=0 in .env.example alongside the existing =1 case
- Add COOKIE_SECURE entry to README env-vars table
Closes#149
Worked with Interstellar Code
(cherry picked from commit d88d899481871f2d9ac5d01f5c318f668d1e6873)
Addresses the 5 security findings from @kiosvantra's audit (thank you!).
## #121 — Path traversal via naive startsWith()
src/routes/api/files.ts: ensureWorkspacePath now uses path.relative()
to enforce the workspace boundary. The previous string-prefix check
accepted sibling paths (e.g. /root/.hermes2 when root is /root/.hermes).
Added regression tests in src/routes/api/-files.test.ts.
## #122 — Deployment defaults expose control plane
server-entry.js: default HOST to 127.0.0.1. If HOST is non-loopback
and HERMES_PASSWORD is unset, the server refuses to start with a
clear banner explaining the fix. An explicit
HERMES_ALLOW_INSECURE_REMOTE=1 escape hatch is available for operators
who understand the risk.
docker-compose.yml: gateway defaults to 127.0.0.1 (no host binding),
workspace publishes on 127.0.0.1:3000 and passes HERMES_PASSWORD /
COOKIE_SECURE / TRUST_PROXY through.
## #123 — Session cookie missing Secure
src/server/auth-middleware.ts: createSessionCookie() now appends
Secure by default in production (and when COOKIE_SECURE=1 overrides).
Docs clarify when dev-HTTP exemption is safe.
## #124 — Dashboard token scraped from HTML
src/server/gateway-capabilities.ts: fetchDashboardToken() now prefers
an explicit HERMES_DASHBOARD_TOKEN (or HERMES_API_TOKEN) env bearer.
The HTML-scrape path remains as a logged fallback for existing
deployments, with a deprecation warning pointing at #124. This removes
the brittle trust boundary in production.
## #125 — x-forwarded-for trusted unconditionally
src/server/auth-middleware.ts + src/server/rate-limit.ts: both IP
resolvers now ignore forwarded headers unless TRUST_PROXY=1 is set.
Without that opt-in, clients cannot spoof local classification or
rotate rate-limit keys via x-forwarded-for. Added regression tests.
## Env + docs
.env.example: new Security section documenting HOST, HERMES_PASSWORD,
COOKIE_SECURE, TRUST_PROXY, HERMES_DASHBOARD_TOKEN, and the bypass.
README.md: Security section updated to reflect the new posture and
credit the audit.
## Verification
- tsc --noEmit: clean
- vitest: 43/43 pass (added 16 new tests across files, auth-middleware,
rate-limit)
- Fail-closed guard verified manually:
HOST=0.0.0.0 \u2192 exit 1 with banner
HOST=0.0.0.0 HERMES_PASSWORD=x \u2192 starts
HOST=0.0.0.0 HERMES_ALLOW_INSECURE_REMOTE=1 \u2192 starts with warn
HOST=127.0.0.1 \u2192 starts
Closes#121, #122, #123, #124, #125
Co-authored-by: Eric <eric@outsourc-e.com>
Adds a Settings > Connection section where users can edit the gateway
and dashboard URLs at runtime. Solves the Tailscale / LAN / remote-host
UX hole @diegodefieth-hash flagged in #101.
Implementation:
- gateway-capabilities.ts now supports setGatewayUrl() / setDashboardUrl()
that update the in-process HERMES_API / HERMES_DASHBOARD_URL values
AND persist to ~/.hermes/workspace-overrides.json. On process start
the overrides file takes precedence over env vars, which still win
over the localhost defaults.
- New PUT /api/connection-settings endpoint. Validates http(s) URLs,
calls the setters, force-reprobes capabilities so the UI sees the
unlock/lock immediately.
- New Connection settings section with two inputs (gateway + dashboard),
Save/Reset buttons, source label, and a Tailscale/remote tip callout.
- Workspace overrides file written with 0600 perms (tokens/URLs are
sensitive context about the user's network topology).
- README updated: no more 'stop + edit .env + start'.
Fixes#101
Co-authored-by: Eric <eric@outsourc-e.com>
The 'dev' and 'start:dev' scripts hardcoded --port 3000 on the CLI,
which collided with Baileys/WhatsApp bridges and other services that
also default to 3000. Users couldn't relocate the workspace without
editing package.json.
Changes:
- Drop --port from the CLI scripts; vite.config.ts now owns the port
- vite.config.ts reads process.env.PORT (default 3000) so users can run:
PORT=4000 pnpm dev
- README snippet updated to mention the override
- Default stays at 3000 so every existing install, docker-compose file,
and reverse-proxy rule keeps working
Fixes#96
Co-authored-by: Eric <eric@outsourc-e.com>
#101 reported that running the workspace on a Tailscale-exposed server
and accessing it from a phone ended up probing 127.0.0.1:8642 instead
of the Tailscale IP. Root cause is user-facing: both HERMES_API_URL and
HERMES_DASHBOARD_URL must be set to reachable URLs at process start,
and the gateway needs API_SERVER_HOST=0.0.0.0.
This PR adds:
- README section 'Running on a remote host (Tailscale / VPN / LAN)' with
a worked example covering both env vars + gateway bind config
- Clearer console warning when the localhost probe fails, pointing users
at the env vars and the gateway bind requirement
No code behaviour change. A UI-side backend-URL override is tracked as
a future enhancement in #101.
Co-authored-by: Eric <eric@outsourc-e.com>
Closes#76.
Clarifies that users who already have a running hermes-agent gateway
(systemd, Docker, pip install, Nous installer, etc.) don't need to
bootstrap a fresh one \u2014 they can point the workspace at the existing
gateway via HERMES_API_URL (and HERMES_API_TOKEN if auth is enabled).
Documents the three requirements on the agent side:
- Gateway bound to a reachable address
- API_SERVER_ENABLED=true for enhanced endpoints
- Matching HERMES_API_TOKEN when API_SERVER_KEY is set
Co-authored-by: Aurora <aurora@outsourc-e.dev>
Swap docker-compose.yml from local builds to pulling the official
upstream images by default. No more 'wait 10 minutes for git clone +
pip install + uv venv' on first run.
- hermes-agent -> nousresearch/hermes-agent:latest (upstream)
- hermes-workspace -> ghcr.io/outsourc-e/hermes-workspace:latest (our GHCR)
Also:
- Persist agent state to a named 'hermes-data' volume mounted at /opt/data
(config, sessions, skills, memory, creds survive container recreation).
- Add docker-compose.dev.yml overlay so contributors can still build from
source via: docker compose -f docker-compose.yml -f docker-compose.dev.yml up --build
- Harden the healthcheck to CMD-SHELL so exit codes propagate.
- README + CHANGELOG updated to match.
Closes#82.
Co-authored-by: Aurora <aurora@outsourc-e.dev>
Community request: pre-built Docker image for Coolify / Easypanel /
Dokploy / Unraid / any PaaS that takes a container URL.
- Add production Dockerfile (multi-stage: build on node:22-slim, run as
non-root, tini PID 1, healthcheck on port 3000).
- Add .github/workflows/docker-publish.yml that builds + pushes on every
commit to main and every v* tag, multi-arch (amd64 + arm64), with
GHCR tags: latest, semver, branch-sha, etc.
- README: add 'Using a Pre-Built Image' section with Coolify/Easypanel
example config and the list of published tags.
First published image will appear at ghcr.io/outsourc-e/hermes-workspace
on next push to main.
User on Discord reported our docs saying ANTHROPIC_API_KEY is required.
It's not — hermes-agent supports Anthropic, OpenAI, OpenRouter (incl. free
models), Google, local Ollama/LM Studio, etc. Users only need the key for
the provider they actually picked in `hermes setup`.
Also replaced the 'pip install hermes-agent' references that snuck in — the
package isn't on PyPI, it installs from source via Nous's official script.
Changes:
- .env.example: list all common provider keys, all commented out, users
uncomment whichever they use
- docker-compose.yml: pass through ANTHROPIC / OPENAI / OPENROUTER / GOOGLE /
GROQ / MISTRAL keys (all optional, whichever is set wins)
- README.md: remove 'ANTHROPIC_API_KEY required' claim, replace pip install
references with the Nous installer path, generalize Docker troubleshooting
to match any provider
- FEATURES-INVENTORY.md: list all supported provider env vars
- Connection error helper now says 'hermes gateway run', not hermes-webapi
- Startup screen no longer tells users to clone outsourc-e/hermes-agent
- Replace editable-install / venv instructions with vanilla pip install +
hermes setup + hermes gateway run
- README troubleshooting line now upgrades stock hermes-agent instead of
suggesting 'git pull && pip install -e .'
This closes the last major user-facing fork confusion inside the workspace UI.
- Add install.sh: preflight-checked installer that pulls vanilla
hermes-agent from PyPI, clones the repo, configures .env, installs
deps. Idempotent, re-runnable.
- README: new 'One-line install' section with curl | bash command.
Demote Manual install section to secondary path.
- Banner tightened: 'v2 — zero-fork. Clone, don't fork.'
- Remove 'Earlier versions required a fork' retrospective from banner;
the fork is gone, we don't need to apologize for it.
- Model switch toast: drop 'enhanced fork' phrasing, use 'enhanced
runtime' (the fork no longer exists as a distinct thing; vanilla
provides the enhanced runtime).
- Update pinned-copy test accordingly.
One-liner for users:
curl -fsSL https://raw.githubusercontent.com/outsourc-e/hermes-workspace/main/install.sh | bash
- Lead with zero-fork banner under the tagline
- Replace all 'clone outsourc-e/hermes-agent fork' instructions with
stock pip install hermes-agent
- Update troubleshooting: upstream now has full endpoint parity
- Keep the migration note so old fork users know to uninstall and
reinstall from PyPI
Closes the last doc gap before v2 tag/push.
* feat: add support for Atomic Chat provider
- Introduced new provider 'Atomic Chat' with associated logo and configuration.
- Updated onboarding and settings components to include Atomic Chat.
- Added necessary files for provider integration, including images and configuration files.
- Updated provider catalog to include details for Atomic Chat.
This enhances the application by allowing users to utilize local LLMs via the Atomic Chat desktop app.
* refactor: remove deprecated configuration files and update README for Atomic Chat
- Deleted obsolete `.pnpm-approved-builds.json` and `mise.toml` files.
- Updated README to reflect the addition of Atomic Chat, including new usage instructions and configuration examples.
- Enhanced onboarding component to support Atomic Chat provider.
- Adjusted provider wizard description to include Atomic Chat alongside Ollama.
---------
Co-authored-by: SankaManka <rita@bagoodex.com>
Adds dedicated section for portable mode (direct to Ollama) and
enhanced mode (through Hermes gateway with custom_providers config).
Updated troubleshooting for common Ollama issues.