diff --git a/.dev/refactor/roadmap.md b/.dev/refactor/roadmap.md index a8061c7..29ecfb2 100644 --- a/.dev/refactor/roadmap.md +++ b/.dev/refactor/roadmap.md @@ -119,8 +119,9 @@ Status: - Hermes-facing install surfaces exist in three explicit modes: `hermit install --print-hermes-mcp-config`, `hermit install --fix-hermes-mcp`, and `hermit install --test-hermes-mcp`. - The Hermes-facing fix/test surfaces now also accept `--hermes-home` so registration and smoke can be exercised against an isolated Hermes config directory. - `hermit doctor` now also accepts `--hermes-home` so the Hermes MCP diagnostic can inspect the same isolated config target before or after repair. -- `hermit doctor --fix --hermes-home ...` now reports the targeted Hermes config directory back in the repair summary so isolated repair runs are easier to verify in logs. -- Live runtime delivery remains the existing Hermit MCP server path; the Hermes wrapper is a setup/health adapter, not a second runtime. +- `hermit doctor` summary output now echoes `Hermes target: ...` when an isolated config directory is in use, matching the repair path. +- `hermit doctor --fix --hermes-home ...` now reports the targeted Hermes config directory in its repair summary, making isolated smoke runs easier to verify from logs alone. + - Release smoke has already verified npm and PyPI packages can print, register, and test the Hermes-facing MCP configuration without requiring OpenAI API-key onboarding. Deliverables: diff --git a/CHANGELOG.md b/CHANGELOG.md index b550b22..2f1b8a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,7 @@ - Added `hermit install --fix-hermes-mcp` as an explicit Hermes Agent MCP registration path that calls `hermes mcp add hermit-channel --command hermit --args mcp-server` only when requested. - Added `hermit install --test-hermes-mcp` as an explicit live MCP wiring smoke that runs `hermes mcp test hermit-channel` without mutating Hermes config. - Added optional `--hermes-home` targeting for `hermit doctor`, `hermit install --fix-hermes-mcp`, and `hermit install --test-hermes-mcp` so isolated Hermes config directories can be diagnosed, repaired, and smoke-tested without touching the operator's default `~/.hermes`. +- `hermit doctor` now echoes the targeted Hermes config directory in its summary output when `--hermes-home` is active, so isolated diagnostics and repair flows report the same target. - `hermit doctor --fix --hermes-home ...` now echoes the targeted Hermes config directory in its repair summary so operators can verify which isolated config was just modified. - Tightened the Hermes MCP smoke so it treats `hermes mcp test hermit-channel` output such as `Server 'hermit-channel' not found in config` as a failure even when the Hermes CLI exits with status 0. - Tightened `hermit install --fix-hermes-mcp` so it answers Hermes Agent's tool-enable prompt, rejects `Cancelled` output even with exit code 0, and verifies the registration is visible in `hermes mcp list` before reporting success. diff --git a/docs/hermes-setup.md b/docs/hermes-setup.md index e129100..6c7274b 100644 --- a/docs/hermes-setup.md +++ b/docs/hermes-setup.md @@ -74,7 +74,9 @@ hermit doctor --hermes-home /tmp/hermes-home hermit install --test-hermes-mcp --hermes-home /tmp/hermes-home ``` -When you use `doctor --fix --hermes-home`, the repair summary now echoes `Hermes target: ...` so logs make the isolated target explicit. +Both `hermit doctor` and `hermit doctor --fix` now echo `Hermes target: ...` in their summary output so you can confirm which isolated config directory was inspected or repaired. + +That keeps the Hermes MCP registration and live test completely out of your default Hermes profile while you validate the executor lane. Under the hood this executes Hermes Agent's live MCP check for `hermit-channel` without mutating config beyond the explicit `--fix-hermes-mcp` path. diff --git a/hermit_agent/doctor.py b/hermit_agent/doctor.py index 07f75d2..f267fed 100644 --- a/hermit_agent/doctor.py +++ b/hermit_agent/doctor.py @@ -32,6 +32,7 @@ class DiagCheck: @dataclass class DiagReport: checks: list[DiagCheck] = field(default_factory=list) + hermes_home: str | None = None @property def overall(self) -> DiagStatus: @@ -44,6 +45,8 @@ def overall(self) -> DiagStatus: def format(self) -> str: icon = {DiagStatus.PASS: "✅", DiagStatus.WARN: "⚠️ ", DiagStatus.FAIL: "❌"} lines = [f"HermitAgent Doctor — overall: {icon[self.overall]} {self.overall.value}", ""] + if self.hermes_home: + lines.extend([f"Hermes target: {self.hermes_home}", ""]) for c in self.checks: lines.append(f"{icon[c.status]} {c.name}: {c.message}") return "\n".join(lines) @@ -354,7 +357,7 @@ def run_diagnostics(cwd: str | None = None, home: str | None = None, hermes_home _check_agent_learner(home), _check_hermes_mcp(cwd, hermes_home=hermes_home), ] - return DiagReport(checks=checks) + return DiagReport(checks=checks, hermes_home=hermes_home) def format_doctor_fix_summary(*, cwd: str, hermes_home: str | None = None) -> str: diff --git a/tests/test_cli_defaults.py b/tests/test_cli_defaults.py index 5fad0c1..5f44a8f 100644 --- a/tests/test_cli_defaults.py +++ b/tests/test_cli_defaults.py @@ -267,13 +267,15 @@ def test_main_dispatches_doctor(monkeypatch, capsys): class DummyReport: def format(self): - return "HermitAgent Doctor — overall: PASS" + return "HermitAgent Doctor — overall: PASS\n\nHermes target: /tmp/hermes-home" monkeypatch.setattr("hermit_agent.doctor.run_diagnostics", lambda **kwargs: seen.append(kwargs) or DummyReport()) main_mod.main() - assert "HermitAgent Doctor — overall: PASS" in capsys.readouterr().out + out = capsys.readouterr().out + assert "HermitAgent Doctor — overall: PASS" in out + assert "Hermes target: /tmp/hermes-home" in out assert seen == [{"cwd": "/tmp/demo", "hermes_home": "/tmp/hermes-home"}] diff --git a/tests/test_doctor.py b/tests/test_doctor.py index 53ab556..dfadc91 100644 --- a/tests/test_doctor.py +++ b/tests/test_doctor.py @@ -142,6 +142,7 @@ class Result: chk = next(c for c in report.checks if c.name == "Hermes MCP") assert chk.status == DiagStatus.PASS assert "hermit-channel registered" in chk.message + assert "Hermes target: " + str(hermes_home) in report.format() assert calls == [{"args": ["hermes", "mcp", "list", "--json"], "env": {**__import__("os").environ, "HERMES_HOME": str(hermes_home)}}]