Skip to content

fix(hermes): run launched hermes in the user's real ~/.hermes (not isolated)#20

Merged
mattias-lundell merged 1 commit into
mainfrom
fix/hermes-real-home
Jun 16, 2026
Merged

fix(hermes): run launched hermes in the user's real ~/.hermes (not isolated)#20
mattias-lundell merged 1 commit into
mainfrom
fix/hermes-real-home

Conversation

@mattias-lundell

Copy link
Copy Markdown
Member

What

opper launch hermes now runs in the user's real ~/.hermes instead of an isolated HERMES_HOME, so the user's own skills, toolsets, agent preferences, and other providers all load. The Opper bits (the opper model/provider block and the provider plugin) are added transiently and restored on exit.

#17 moved hermes to an isolated home to drop the snapshot dance — but that ignores the user's own config. This brings the real home back, with a clean snapshot/restore.

How

  • Real homehermesHome() resolves process.env.HERMES_HOME ?? ~/.hermes and we run hermes against it (no isolated dir, no HERMES_HOME override to a managed path).
  • Transient configconfig.yaml is whole-file snapshotted (via util/backup.ts takeSnapshot/restoreSnapshot, with rotateBackups) before we write the opper model + providers.opper blocks, and restored on exit. If there was no config, the one we write is deleted. The api key goes via OPPER_API_KEY env, never to disk.
  • Transient plugin — the provider plugin is shipped into ~/.hermes/plugins/model-providers/opper/ and restored on exit: pre-existing files are captured and put back; a dir we created is removed. So a one-off launch leaves the user's plugins untouched.
  • unconfigure drops a leftover plugin dir defensively (in case a launch was killed before restore).

The session grouping + provider affinity (the #17 plugin emitting X-Opper-Trace-Id / X-Opper-Parent-Span-Id) are unchanged.

Test

  • tsc --noEmit clean; full suite green (372). Hermes tests assert: opper model + providers.opper + plugin written mid-launch, real HERMES_HOME + OPPER_API_KEY on the env, a one-off launch leaves nothing behind, and a pre-existing config.yaml + plugin are restored verbatim (including when run() throws).
  • Verified live: a one-shot launch over a real ~/.hermes (seeded with a user model + toolsets) preserved that config, removed the plugin on exit, and still produced a session root trace.

Related

Companion to the pi change (#19), which applies the same "use the user's real home" principle to opper launch pi.

🤖 Generated with Claude Code

#17 launched hermes against an isolated HERMES_HOME, which ignored the user's
own skills, toolsets, agent preferences, and other providers. Run in the real
~/.hermes instead and add the opper model/provider block + the provider plugin
transiently: snapshot config.yaml (whole-file backup via the backup util,
restored on exit) and save/restore the plugin files, so a launch leaves the
user's config exactly as it was while still giving session grouping + provider
affinity via the plugin.

Verified live: a one-shot launch over a real ~/.hermes preserved the user's
config.yaml (model + toolsets) and removed the plugin on exit, and still
produced a `session` root trace.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@mattias-lundell mattias-lundell merged commit fa41757 into main Jun 16, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant