Skip to content

feat(agent-init): add Hermes platform support (sable-gyw)#151

Merged
Raftersecurity merged 1 commit into
mainfrom
sable-gyw-hermes-mcp
May 31, 2026
Merged

feat(agent-init): add Hermes platform support (sable-gyw)#151
Raftersecurity merged 1 commit into
mainfrom
sable-gyw-hermes-mcp

Conversation

@Rome-1
Copy link
Copy Markdown
Collaborator

@Rome-1 Rome-1 commented May 31, 2026

Summary

Adds Hermes to the supported-platforms list. MCP-only v0 — mirrors how Gemini and Continue.dev were initially shipped. 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 init --with-hermes

Merges Rafter into ~/.hermes/config.yaml under mcp_servers.rafter (snake_case — distinct from Cursor/Windsurf's mcpServers camelCase). Existing servers and other top-level YAML keys are preserved.

Scope

Implemented (v0):

  • installHermesMcp() (Node) + _install_hermes_mcp() (Python) using js-yaml / PyYAML
  • --with-hermes flag 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.enabled config flag → dry-run plan entry → final-message platform hint
  • recipes/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 configs
  • README updates: badge row, supported-platforms description, install-list table, MCP-based platforms paragraph

Deferred (follow-on beads to be filed once v0 lands):

  • agent verify / agent list / agent status Hermes detection
  • Hook support (no documented Hermes hook surface yet — same posture we took for Gemini and Continue.dev before their hook surfaces stabilized)
  • --local scope (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 built dist/):

  • Creates config.yaml from scratch with mcp_servers.rafter populated
  • Preserves existing mcp_servers entries and other top-level YAML keys
  • Idempotent on a second run
  • Recovers from unreadable / malformed YAML
  • Coerces an array-shaped mcp_servers (wrong shape) into a dict
  • Warns when --with-hermes is requested but ~/.hermes doesn't exist
  • Lists Hermes in the dry-run plan when detected

Python (python/tests/test_agent_init.py::TestInstallHermesMcp, direct installer):

  • Same five core behaviors (fresh-config, preserve, idempotent, unreadable-YAML, array-shape-coerce)

Broader regressions:

  • Python test_agent_init.py full suite: 82 passed
  • Node agent-commands.test.ts full suite: 79 passed

Security review

rafter agent reviewed the diff — verdict GO, no findings. YAML safety verified (js-yaml v4+ DEFAULT_SCHEMA on Node, yaml.safe_load on Python). No new shell, no subprocesses, no network calls. Paths are constructed from os.homedir() / process.cwd() plus hardcoded literals — no user-controlled input reaches a file path.

Tracking

  • Bead: sable-gyw (claimed by me for this PR)
  • Discovered from: customer question about manus.im / n8n integration that sparked a "what's first-class vs primitive" conversation; Hermes was already cited as future work in the platform-parity audit but with a non-existent tracking bead.

🤖 Generated with Claude Code

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 Raftersecurity merged commit 23ae030 into main May 31, 2026
@Raftersecurity Raftersecurity deleted the sable-gyw-hermes-mcp branch May 31, 2026 23:24
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.

2 participants