feat(agent-init): add Hermes platform support (sable-gyw)#151
Merged
Conversation
Adds Hermes to the supported-platforms list (now: Claude Code, Codex CLI, OpenClaw, Gemini CLI, Cursor, Windsurf, Continue.dev, Aider, Hermes). MCP-only v0 mirroring how Gemini and Continue.dev were initially shipped. Hooks (preToolUse/postToolUse equivalents) deferred to a follow-on bead pending confirmation Hermes exposes a hook surface. Both runtimes: - `installHermesMcp()` / `_install_hermes_mcp()` — merges Rafter into `~/.hermes/config.yaml` under `mcp_servers.rafter` (snake_case, unlike Cursor/Windsurf which use mcpServers camelCase). Existing servers and other top-level YAML keys preserved. Non-dict mcp_servers is coerced to a dict rather than crashing. Unparseable YAML triggers a warning + fresh-config behavior matching the Aider installer (consistent UX). - `--with-hermes` flag wired end-to-end: option declaration → detection (~/.hermes) → want resolution (excluded from --all in --local since Hermes has no project-local config story) → warning for "requested but not detected" → detected[] entry → install call site → agent.environments.hermes.enabled config flag → dry-run plan entry → final-message platform hint. Recipe at recipes/hermes.md covers automatic + manual setup, documents the four MCP tools Hermes gets (scan_secrets, evaluate_command, read_audit_log, get_config), and warns about YAML round-trip comment loss for hand-curated configs. Tests: 7 Node assertions (subprocess-driven against built dist) and 5 Python assertions (direct installer call) covering: fresh-config creation, existing-server preservation, idempotency, malformed-YAML recovery, array-shape mcp_servers coercion, undetected-warning, and dry-run plan rendering. Deferred (tracked in follow-on beads): - `agent verify` / `agent list` / `agent status` Hermes detection. - Hook support (no documented Hermes hook surface yet). - `--local` scope (Hermes lacks a project-local config story). Replaces the placeholder rf-01b reference in shared-docs/PLATFORM_PARITY_AUDIT.md:248 — that bead never existed; sable-gyw is the real tracking bead. Rafter agent review: GO, no findings. YAML safety verified (js-yaml v4+ DEFAULT_SCHEMA, Python safe_load). No new shell, no subprocesses, no network calls. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Raftersecurity
approved these changes
May 31, 2026
This was referenced Jun 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds Hermes to the supported-platforms list. MCP-only v0 — mirrors how Gemini and Continue.dev were initially shipped. Replaces the placeholder
rf-01breference inshared-docs/PLATFORM_PARITY_AUDIT.md:248(that bead never existed;sable-gywis the real tracking bead).Merges Rafter into
~/.hermes/config.yamlundermcp_servers.rafter(snake_case — distinct from Cursor/Windsurf'smcpServerscamelCase). Existing servers and other top-level YAML keys are preserved.Scope
Implemented (v0):
installHermesMcp()(Node) +_install_hermes_mcp()(Python) usingjs-yaml/ PyYAML--with-hermesflag wired end-to-end on both runtimes: option declaration → detection (~/.hermes) → want resolution → warning for "requested but not detected" → detected[] entry → install call site →agent.environments.hermes.enabledconfig flag → dry-run plan entry → final-message platform hintrecipes/hermes.md— automatic + manual setup, documents the four MCP tools (scan_secrets,evaluate_command,read_audit_log,get_config), warns about YAML round-trip comment loss for hand-curated configsDeferred (follow-on beads to be filed once v0 lands):
agent verify/agent list/agent statusHermes detection--localscope (Hermes lacks a project-local config story)Tests
12 Hermes-specific assertions, all passing locally:
Node (
node/tests/agent-init-hermes.test.ts, subprocess-driven against builtdist/):config.yamlfrom scratch withmcp_servers.rafterpopulatedmcp_serversentries and other top-level YAML keysmcp_servers(wrong shape) into a dict--with-hermesis requested but~/.hermesdoesn't existPython (
python/tests/test_agent_init.py::TestInstallHermesMcp, direct installer):Broader regressions:
test_agent_init.pyfull suite: 82 passedagent-commands.test.tsfull suite: 79 passedSecurity review
rafteragent reviewed the diff — verdict GO, no findings. YAML safety verified (js-yaml v4+ DEFAULT_SCHEMA on Node,yaml.safe_loadon Python). No new shell, no subprocesses, no network calls. Paths are constructed fromos.homedir()/process.cwd()plus hardcoded literals — no user-controlled input reaches a file path.Tracking
sable-gyw(claimed by me for this PR)🤖 Generated with Claude Code