Skip to content

fix(plugins): skip foreign-harness manifest dirs during discovery - #101977

Closed
liuhao1024 wants to merge 1 commit into
NousResearch:mainfrom
liuhao1024:liuhao/cron-bugfix-101962
Closed

liuhao1024 wants to merge 1 commit into
NousResearch:mainfrom
liuhao1024:liuhao/cron-bugfix-101962

Conversation

@liuhao1024

Copy link
Copy Markdown

What does this PR do?

Multi-harness plugin repos (e.g. obra/superpowers) ship one plugin.json per other agent harness inside .claude-plugin/, .codex-plugin/, .cursor-plugin/, .devin-plugin/ and .kimi-plugin/. Those manifests are per-harness conventions and can never satisfy the Agent Plugins v1 $schema, so every plugin-discovery pass tried each one, rejected it, and logged a warning — on the reporter's install that is 5 warnings per discovery cycle, ~1,500/day in errors.log.

This PR makes directory discovery skip these well-known foreign-harness manifest directories (option 1 from the issue). A plugin's real Hermes manifest (.hermes-plugin/plugin.yaml or a top-level plugin.yaml/plugin.json) is unaffected, and a genuinely broken portable plugin.json outside these convention directories still surfaces its parse warning.

Related Issue

Fixes #101962

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)

Changes Made

  • hermes_cli/plugins.py: added _FOREIGN_HARNESS_MANIFEST_DIRS (.claude-plugin, .codex-plugin, .cursor-plugin, .devin-plugin, .kimi-plugin) and skip these directory names at any scan depth in _scan_directory_level, with a DEBUG log explaining the skip. No functional change: those plugin.json files could never validate, so nothing that was loadable before is lost.
  • tests/hermes_cli/test_plugin_scanner_recursion.py: regression tests — a superpowers-style layout produces zero Failed to parse warnings while the real .hermes-plugin/plugin.yaml is still discovered; a genuinely broken portable plugin.json still warns.

How to Test

  1. python -m pytest tests/hermes_cli/test_plugin_scanner_recursion.py -q — 14 passed (12 existing + 2 new).
  2. python -m pytest tests/hermes_cli/ -q -k plugin — 625 passed, 1 unrelated pre-existing failure (test_relay_shared_metrics_runtime.py, fails identically on clean upstream/main; nemo_relay module issue, unrelated to plugin scanning).
  3. Manual repro on the fix branch: create ~/.hermes/plugins/superpowers/{.hermes-plugin,.claude-plugin,.codex-plugin,.cursor-plugin,.devin-plugin,.kimi-plugin} with a plugin.yaml in the first and a schema-less plugin.json in each of the others, then run discovery. Observed result: before the fix, 5 × WARNING hermes_cli.plugins: Failed to parse ...: plugin.json declares an unsupported or missing Agent Plugins schema per pass; after the fix, 0 warnings and superpowers/.hermes-plugin still discovered.

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run pytest tests/ -q and all tests pass
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)
  • I've tested on my platform: macOS 15 (arm64)

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — or N/A
  • I've updated cli-config.yaml.example if I added/changed config keys — or N/A
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — or N/A
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide — or N/A (pure directory-name match, no path handling changes)
  • I've updated tool descriptions/schemas if I changed tool behavior — or N/A

For New Skills

N/A — not a skill.

Screenshots / Logs

Before (per discovery pass, ×5 dirs):

WARNING hermes_cli.plugins: Failed to parse .../superpowers/.claude-plugin/plugin.json: plugin.json declares an unsupported or missing Agent Plugins schema

After: no warnings; discovery debug log shows Skipping .../superpowers/.claude-plugin (foreign-harness manifest convention).

Multi-harness plugin repos (e.g. obra/superpowers) ship one plugin.json
per OTHER agent harness inside .claude-plugin/, .codex-plugin/,
.cursor-plugin/, .devin-plugin/ and .kimi-plugin/. Those manifests can
never satisfy the Agent Plugins v1 schema, so every discovery pass
rejected each one and logged a warning — ~1,500 warnings/day on the
reporter's install (NousResearch#101962).

Skip these well-known per-harness convention directories during
directory scanning. A plugin's real Hermes manifest
(.hermes-plugin/plugin.yaml or a top-level plugin.yaml/plugin.json) is
unaffected, and genuinely broken portable manifests still warn.

Fixes NousResearch#101962
@alt-glitch alt-glitch added type/bug Something isn't working P3 Low — cosmetic, nice to have comp/cli CLI entry point, hermes_cli/, setup wizard comp/plugins Plugin system and bundled plugins labels Sep 3, 2026
@Enough1122

Copy link
Copy Markdown

AI code review — automated review for reference; please use your judgment.

Overall: Plugin discovery skips foreign-harness manifest dirs (.claude-plugin, .codex-plugin, .cursor-plugin, .devin-plugin, .kimi-plugin), which can never satisfy the Agent Plugins v1 schema and spammed warnings on every pass (#101962). Real Hermes manifests (.hermes-plugin/plugin.yaml, top-level plugin.yaml/json) are unaffected (plugins.py:31).

Correctness:

  • Skip is name-based at the directory level with a debug (not warning) log — silences exactly the noise class without hiding anything actionable.
  • Tests pin both sides: multi-harness repo discovers the real manifest with zero parse warnings, while a genuinely broken top-level plugin.json still warns.

Non-blocking nits:

  • Hardcoded harness list will need updates as new harnesses appear (e.g. future competitors); consider a pattern (e.g. .*-plugin except known Hermes names) — though an explicit allowlist-style set is safer against skipping a real plugin dir, so the current form is defensible; just note the maintenance spot.
  • A Hermes plugin that legitimately nests a directory named e.g. .cursor-plugin for its own assets would now be invisible — vanishingly unlikely given dot-dir conventions; fine.

Verdict: LGTM. Surgical noise fix with the safety case tested.

@liuhao1024

Copy link
Copy Markdown
Author

Thanks — the explicit set is deliberate over a pattern, since it cannot accidentally skip a real Hermes manifest dir; the maintenance note stands.

@teknium1

Copy link
Copy Markdown
Collaborator

Thanks @liuhao1024 — cherry-picked (re-sited onto hermes_cli/plugins_discovery.py); resolves #101962.

Salvaged into #118841 with your authorship preserved (merge 74f726c). Thank you!

@teknium1 teknium1 closed this Sep 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cli CLI entry point, hermes_cli/, setup wizard comp/plugins Plugin system and bundled plugins P3 Low — cosmetic, nice to have type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Plugin discovery: warning spam for foreign-harness plugin.json manifests (obra/superpowers layout)

4 participants