Skip to content

fix(hermes): preserve YAML list indentation (2-space flush style)#345

Open
marcosdanielsf wants to merge 1 commit into
colbymchenry:mainfrom
marcosdanielsf:fix/hermes-yaml-list-indent
Open

fix(hermes): preserve YAML list indentation (2-space flush style)#345
marcosdanielsf wants to merge 1 commit into
colbymchenry:mainfrom
marcosdanielsf:fix/hermes-yaml-list-indent

Conversation

@marcosdanielsf
Copy link
Copy Markdown

Summary

The Hermes installer target assumed list items were indented 4 spaces under their parent key, but YAML accepts both the 4-space style and the more common 2-space flush style:

```yaml

flush (2 spaces) — broke before this fix

platform_toolsets:
cli:

  • hermes-cli
  • mcp-codegraph

nested (4 spaces) — worked before, still works

platform_toolsets:
cli:
- hermes-cli
- mcp-codegraph
```

Two bugs surfaced on flush-style configs:

  1. `childRange()` used `/^ \S/` to detect sibling keys, so a list item like ` - mcp-codegraph` was misread as the next child key — the range closed early and `upsertCodeGraphToolset` either failed to find the `cli` block or inserted into the wrong place.
  2. When appending a new entry, the installer hardcoded 4-space indentation, mixing styles inside a single list.

Fix

  • Tighten the sibling-key regex in `childRange()` to require an actual mapping key (`^ [A-Za-z_][\w-]*:`), so list lines no longer terminate the range.
  • Add `listItemIndent()` to detect the indentation of existing list items and reuse it when appending `- mcp-codegraph`.
  • Default the bootstrap insert (when no `cli:` block exists yet) to 2-space flush style, matching the in-repo Hermes config format.

Test plan

  • Existing test suite updated to assert the flush-style output (` - hermes-cli` instead of ` - hermes-cli`).
  • `npm test -- tests/installer-targets.test.ts` — 82/82 passing locally.
  • Reproduced the original break against a real Hermes config with flush-style lists; with this patch the installer is idempotent on both styles.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: be47413e6a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

// - file
// A line beginning with " -" is still part of the current child, not
// the next platform key. Only a sibling mapping key ends this child.
if (/^ [A-Za-z_][A-Za-z0-9_-]*:\s*(?:#.*)?$/.test(line)) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Detect sibling keys that have inline YAML values

The new sibling-boundary regex only matches lines like " key:" and ignores valid siblings such as " other: { ... }" or " discord: [ ... ]". In those configs, childRange() no longer stops at the next sibling, so calls like removeCodeGraphMcpServer()/upsertCodeGraphMcpServer() and upsertCodeGraphToolset() can treat subsequent sibling entries as part of the current block, leading to accidental deletion or malformed insertion when rewriting the file.

Useful? React with 👍 / 👎.

// - file
// A line beginning with " -" is still part of the current child, not
// the next platform key. Only a sibling mapping key ends this child.
if (/^ [A-Za-z_][A-Za-z0-9_-]*:\s*(?:#.*)?$/.test(line)) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Handle quoted and numeric sibling YAML keys

The new boundary check in childRange() assumes sibling keys must match [A-Za-z_][A-Za-z0-9_-]*, but YAML allows keys like 'x.y': and 1st:. In files that use those valid key forms under mcp_servers or platform_toolsets, range detection runs past the actual sibling boundary, so install/uninstall can splice through unrelated sections instead of only the target child block.

Useful? React with 👍 / 👎.

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