* fix(hermes): match config items with inline comments
The plugins.enabled / plugins.disabled item scan compared raw line text, so
a YAML inline comment became part of the value it matched against. Three
concrete failures followed on configs users can edit by hand:
- an existing enabled entry carrying a comment ("agency-agents-router # x")
was not recognized, so the plugin was appended a second time;
- a stale disabled entry carrying a comment was not removed, so the
installer reported "enabled plugin ... in config.yaml" while the plugin
stayed disabled;
- the corrupted-glue repair counted "- " in the whole line, so a comment
containing " - " was split into fake list entries: the installer silently
rewrote a comment such as "# keep - rotate this one first" into two
enabled entries.
Strip a trailing YAML comment ("#" only starts one after whitespace) before
matching, counting, and splitting, and use the same value helper in the
post-repair re-check so a quoted entry is recognized too. No config format
or install behavior change beyond those shapes.
check-hermes-config-rewrite.py gains four cases for them plus two general
invariants: the plugin appears exactly once, and the writer may not gain or
lose unrelated enabled entries outside the documented glue repair. The
suite fails on the previous code with exactly those four cases and passes
with this patch.
* test(hermes): pin a quoted entry that also carries a comment
Independent verification on the PR (phant0um) covered an existing quoted
entry with an inline comment (`- "agency-agents-router" # quoted`). The fix
recognizes it through the comment-stripped item value; pin that shape so it
cannot regress. On the previous code the extended suite fails with this case
plus the original four; with the fix all 21 cases pass.
The Hermes installer printed "[OK] enabled plugin" and "Done!" while leaving agency-agents-router disabled or absent. On current Hermes this hit every user: the default plugins: block contains a column-0 "# ====" banner, and `hermes plugins enable/disable` writes enabled:/disabled: below it.
- Bound the enabled: sub-block at the first sibling key; sweep stale entries out of disabled: (Hermes: "an explicit disable wins"); handle inline [], [a,b], disabled: above enabled:, trailing comments, corrupted-scalar recovery; bail on shapes that can't be edited line-wise. (@guozi-lab)
- A column-0 comment no longer ends the plugins: block, and the rewrite's exit status propagates (`|| return 1`) so a bail warns instead of reporting success. (maintainer follow-up)
- check-hermes-config-rewrite.py: 16 cases, including Hermes' real shape.
Verified in real Hermes (official installer, 9a0a162) on configs Hermes wrote itself, with a live turn on local qwen3.8-27b: main -> "agency_agents_delegate does not exist"; this change -> delegated: true, real subagent, real result.
Closes#879
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
ensure_hermes_plugin_enabled() hardcoded a 2-space indent for the inserted `- agency-agents-router` line. Hermes writes plugins.enabled items at 4 spaces, so the new line and the next existing item collapsed into one plain scalar ("agency-agents-router - disk-cleanup") and every previously enabled plugin silently dropped (#839, and #689 diagnosed the same in July). The inserter now matches the existing item indent (default 4), appends after existing entries so order is preserved, and is idempotent on re-run. scripts/check-hermes-config-rewrite.{sh,py} runs seven regression cases; a small workflow runs it on every PR.
Reproduced on main with a 4-space config and verified fixed with this patch; installer suite 36/0; the regression script passes 7/7.
Fixes#839. Closes#689 (same fix, proposed first by @harshsinghmp).
Co-Authored-By: Harsh Singh <32476777+harshsinghmp@users.noreply.github.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>