From 6a17aabd9f2b6ae7bfda2b0b49d66d5b0100696d Mon Sep 17 00:00:00 2001 From: Zhaoxiaoguang001 <3357983213@qq.com> Date: Thu, 14 May 2026 06:28:22 +0800 Subject: [PATCH 1/3] feat: add Hermes Agent integration --- .../integrations/hermes/__init__.py | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 src/specify_cli/integrations/hermes/__init__.py diff --git a/src/specify_cli/integrations/hermes/__init__.py b/src/specify_cli/integrations/hermes/__init__.py new file mode 100644 index 0000000000..c8810d4c94 --- /dev/null +++ b/src/specify_cli/integrations/hermes/__init__.py @@ -0,0 +1,78 @@ +"""Hermes Agent integration — skills-based agent. + +Hermes Agent (https://github.com/NousResearch/hermes-agent) is an open-source +AI agent framework by Nous Research. It uses the ``.hermes/skills/`` directory +for agent skills, following the same ``speckit-/SKILL.md`` layout as +Claude Code and Codex. + +Usage:: + + specify init my-project --integration hermes + specify init --here --ai hermes +""" + +from __future__ import annotations + +from ..base import IntegrationOption, SkillsIntegration + + +class HermesIntegration(SkillsIntegration): + """Integration for Hermes Agent skills.""" + + key = "hermes" + config = { + "name": "Hermes Agent", + "folder": ".hermes/", + "commands_subdir": "skills", + "install_url": "https://github.com/NousResearch/hermes-agent", + "requires_cli": True, + } + registrar_config = { + "dir": ".hermes/skills", + "format": "markdown", + "args": "$ARGUMENTS", + "extension": "/SKILL.md", + } + context_file = "AGENTS.md" + + @classmethod + def options(cls) -> list[IntegrationOption]: + return [ + IntegrationOption( + "--skills", + is_flag=True, + default=True, + help="Install as agent skills (default for Hermes Agent)", + ), + ] + + def build_exec_args( + self, + prompt: str, + *, + model: str | None = None, + output_json: bool = True, + ) -> list[str] | None: + """Build Hermes CLI invocation for programmatic dispatch. + + Uses ``hermes chat -q`` for one-shot queries, mapping slash-command + invocations to the appropriate skill-based dispatch. + """ + args = [self.key, "chat", "-Q"] + + if model: + args.extend(["-m", model]) + if output_json: + args.append("--json") + + # If prompt starts with a slash command, pass it directly + # so Hermes can dispatch to the appropriate skill. + if prompt.startswith("/"): + command, _, remainder = prompt[1:].partition(" ") + args.extend(["-s", command]) + if remainder: + args.extend(["-q", remainder]) + else: + args.extend(["-q", prompt]) + + return args From cd91046cc4964259acccd66991f9f26edee61a7d Mon Sep 17 00:00:00 2001 From: Zhaoxiaoguang001 <3357983213@qq.com> Date: Thu, 14 May 2026 06:28:23 +0800 Subject: [PATCH 2/3] feat: add Hermes Agent integration --- tests/integrations/test_integration_hermes.py | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 tests/integrations/test_integration_hermes.py diff --git a/tests/integrations/test_integration_hermes.py b/tests/integrations/test_integration_hermes.py new file mode 100644 index 0000000000..a43bb2ee0e --- /dev/null +++ b/tests/integrations/test_integration_hermes.py @@ -0,0 +1,33 @@ +"""Tests for HermesIntegration.""" + +from .test_integration_base_skills import SkillsIntegrationTests + + +class TestHermesIntegration(SkillsIntegrationTests): + KEY = "hermes" + FOLDER = ".hermes/" + COMMANDS_SUBDIR = "skills" + REGISTRAR_DIR = ".hermes/skills" + CONTEXT_FILE = "AGENTS.md" + + +class TestHermesAutoPromote: + """--ai hermes auto-promotes to integration path.""" + + def test_ai_hermes_without_ai_skills_auto_promotes(self, tmp_path): + """--ai hermes should work the same as --integration hermes.""" + from typer.testing import CliRunner + from specify_cli import app + + runner = CliRunner() + target = tmp_path / "test-proj" + result = runner.invoke(app, [ + "init", str(target), + "--ai", "hermes", + "--no-git", + "--ignore-agent-tools", + "--script", "sh", + ]) + + assert result.exit_code == 0, f"init --ai hermes failed: {result.output}" + assert (target / ".hermes" / "skills" / "speckit-plan" / "SKILL.md").exists() From e83cd543aac38de881853f6a89c23e8040c3a81a Mon Sep 17 00:00:00 2001 From: Zhaoxiaoguang001 <3357983213@qq.com> Date: Thu, 14 May 2026 06:28:57 +0800 Subject: [PATCH 3/3] feat: add Hermes Agent integration --- src/specify_cli/integrations/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/specify_cli/integrations/__init__.py b/src/specify_cli/integrations/__init__.py index 4a78e7d035..ad1440d074 100644 --- a/src/specify_cli/integrations/__init__.py +++ b/src/specify_cli/integrations/__init__.py @@ -61,6 +61,7 @@ def _register_builtins() -> None: from .gemini import GeminiIntegration from .generic import GenericIntegration from .goose import GooseIntegration + from .hermes import HermesIntegration from .iflow import IflowIntegration from .junie import JunieIntegration from .kilocode import KilocodeIntegration @@ -93,6 +94,7 @@ def _register_builtins() -> None: _register(GeminiIntegration()) _register(GenericIntegration()) _register(GooseIntegration()) + _register(HermesIntegration()) _register(IflowIntegration()) _register(JunieIntegration()) _register(KilocodeIntegration())