feat(agents): add NousResearch Hermes adapter#42
Conversation
|
QA'd against a real Confirmed against the real config
Fix before mergeMAJOR
MINOR NIT FYI (not a bug)My profiles use scoped gortex servers ( Happy to re-run this QA on a revised branch. |
Wire the gortex MCP server into NousResearch Hermes (~/.hermes), a
user-level CLI agent-orchestrator that consumes MCP servers. Hermes
users previously had to hand-author the server stanza and any usage
guidance; this brings Hermes to parity with the Claude Code / Antigravity
user-level treatment (MCP wiring + an instruction surface).
internal/agents/hermes — new user-mode adapter:
- Detect: `hermes` on PATH or ~/.hermes present.
- Upserts a `gortex` stdio server (command, args:[mcp], connect_timeout,
timeout) under the snake_case `mcp_servers` map of the global
~/.hermes/config.yaml AND every existing ~/.hermes/profiles/*/config.yaml.
Hermes profiles can re-declare their own server map, so writing only
the global stanza is not guaranteed to reach every profile; touching
each existing profile config makes the tools resolve everywhere
(existing profiles only — we never create new ones).
- Installs a user-level skill at ~/.hermes/skills/gortex/SKILL.md
(Hermes frontmatter: name/description/version/metadata.hermes) teaching
the agent to prefer graph tools and documenting multi-repo scoping.
internal/agents.MergeYAML — comment-preserving YAML merge helper (a
yaml.Node round-trip, not a map round-trip which would drop every comment),
plus YAMLMapValue / YAMLSetMapValue / YAMLScalar / UpsertYAMLMapEntry.
Honours the existing atomic-write + .bak-on-malformed contract.
Wiring: register hermes in the init/install registry, add the wizard
label + detail, an ~/.hermes preserved-note in `uninstall`, and
ReadYAML / WriteYAML test helpers. `init doctor` reports it automatically.
Implements the adapter requested in #38; QA against a real ~/.hermes
(global stanza vs. per-profile resolution, comment preservation) pending.
Bring the Hermes user-level skill surface to parity with Claude Code by installing the per-task routing playbooks alongside the master `gortex` skill: explore, impact, debug, refactor, rename, safe-edit, fix-all, extract-function, cross-repo-usage, dataflow-trace, add-test, incident-investigation, episode-replay, co-change, onboarding, quality-audit, architecture-review, pr-review. The bodies are reused verbatim from internal/agents/claudecode (single source of truth — the two agents never drift) and re-wrapped with Hermes frontmatter (name + description carried over, version, metadata.hermes tags + category). Hermes turns every installed skill into a /skill-name slash command, so the /gortex-*-style cross-references in the bodies resolve to the sibling skills installed here. gortex-guide is excluded: the native master `gortex` skill already fills the guide role. Installed at ~/.hermes/skills/<name>/SKILL.md, skipped when already present so user edits survive. Plan/doctor report them all.
Two data-touching bugs in the comment-preserving YAML merge, surfaced by QA on the Hermes adapter (#42): - MergeYAML wrote a malformed / non-mapping file's .bak during the parse phase, before the DryRun check, so `gortex init --dry-run` mutated disk. The backup bytes are now captured and written only in the real-apply branch. - UpsertYAMLMapEntry silently swapped a non-mapping value under the outer key (a null / scalar / sequence `mcp_servers:`) for a fresh map, dropping the original node with no .bak and no error. A null value (every server commented out) is now populated in place — keeping the key's comment — while a non-null scalar or sequence is refused as schema-invalid, leaving the file untouched. Also detect and match the file's existing indent width on re-encode instead of forcing 2-space; block sequences are still re-indented one level, a yaml.v3 encoder limitation documented at the detection site. Regression tests cover the dry-run-no-backup, non-map-refusal, null-populate, and indent-width paths.
Follow-ups from the same QA pass, none data-mutating: - Aggregate per-profile write failures onto a new Result.Warnings field and surface them in the install summary, so a failed profile no longer hides behind Configured=true (those profiles don't inherit the global stanza). - resolveGortexCommand prefers a real installed binary: it trusts os.Executable() only when it points at a `gortex` outside the temp dir (a `go run` build is ephemeral and may even be named gortex), else falls back to LookPath, else the bare name. - Write skills under skills/<category>/<name>/ (reusing the routing taxonomy) instead of cluttering the skills root, and fix the uninstall note so the gortex-* routing skills aren't left orphaned. - Add platforms + related_skills to the master and routing frontmatter, and a slash-command index to the master skill, derived from the installed routing set so it can't drift. - Drop a stray space in the ~/.hermes/config.yaml wizard / uninstall hints.
|
Hey @rolldav! I have an issue with the whole-file re-indent (MINOR - 3 - Whole-file re-indent on merge). I can address this only partially unless you can give me hints about conventions. For now, I added detection of the current file indentation and inherited it to match the file's own indent width (a 4-space config is re-emitted at 4-space, not forced to 2). The residual is the indentless block sequence style: The only way to eliminate that diff is to stop whole-document re-encoding and surgically byte-splice just the changed key; that's a larger change I deferred since the result is semantically identical and comment-preserving. Fixes for the remaining issues are in the branch. |
|
Re-QA'd the revised branch at Verified fixedMAJOR
MINOR / NIT
Idempotency holds (second run = all-skip, byte-stable). MINOR-3 (re-indent) — your questionYou read the convention right: my hand-maintained configs use indentless block sequences (items at the parent key's column), which Regression sweep of
|
|
Thank you for the help @rolldav! |
Wire the gortex MCP server into NousResearch Hermes (~/.hermes), a user-level CLI agent-orchestrator that consumes MCP servers. Hermes users previously had to hand-author the server stanza and any usage guidance; this brings Hermes to parity with the Claude Code / Antigravity user-level treatment (MCP wiring + an instruction surface).
internal/agents/hermes — new user-mode adapter:
hermeson PATH or ~/.hermes present.gortexstdio server (command, args:[mcp], connect_timeout, timeout) under the snake_casemcp_serversmap of the global~/.hermes/config.yamlAND every existing~/.hermes/profiles/*/config.yaml. Hermes profiles can redeclare their own server map, so writing only the global stanza does not guarantee reaching every profile; touching each existing profile config ensures the tools resolve everywhere (existing profiles only — we never create new ones).~/.hermes/skills/gortex/SKILL.md(Hermes frontmatter: name/description/version/metadata.hermes), teaching the agent to prefer graph tools and documenting multi-repo scoping.Extra:
Wiring: register hermes in the init/install registry, add the wizard label + detail, an
~/.hermespreserved-note inuninstall, and ReadYAML / WriteYAML test helpers.init doctorreports it automatically.Implements the adapter requested in #38; QA against a real
~/.hermes(global stanza vs. per-profile resolution, comment preservation) pending.