Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

feat: add Hermes Agent harness adapter - #322

#322
Open
chrisl10 wants to merge 5 commits into
legioncodeinc:mainlegioncodeinc/honeycomb:mainfrom
chrisl10:feat/hermes-harnesschrisl10/honeycomb:feat/hermes-harnessCopy head branch name to clipboard
Open

feat: add Hermes Agent harness adapter#322
chrisl10 wants to merge 5 commits into
legioncodeinc:mainlegioncodeinc/honeycomb:mainfrom
chrisl10:feat/hermes-harnesschrisl10/honeycomb:feat/hermes-harnessCopy head branch name to clipboard

Conversation

@chrisl10

@chrisl10 chrisl10 commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

What this does

Adds a production Hermes Agent 0.19 harness adapter so Honeycomb can be installed with honeycomb connect hermes.

The adapter:

  • honors $HERMES_HOME, validates explicit profile roots, and defaults to ~/.hermes;
  • maps on_session_start, pre_llm_call, post_tool_call, post_llm_call, and on_session_finalize onto Honeycomb's shared runtime;
  • runs latency-sensitive recall before capturing the current prompt;
  • captures user messages, completed tool results, and assistant responses;
  • performs synchronous model-only recall using Hermes' native { context } response;
  • deliberately does not use pre_tool_call, whose response contract cannot safely support Honeycomb interception;
  • treats on_session_end as a per-turn event and on_session_finalize as final termination;
  • installs explicit .mjs hook/MCP bundles with an absolute Node executable, including Node 22.5 compatibility;
  • records artifact SHA-256 ownership in an atomic manifest, refuses symlink/foreign/modified-target overwrites, and removes only hash-matching files;
  • preserves foreign YAML values, ordering/comments, hooks, MCP servers, and skills through YAML AST edits;
  • fails closed before writing when YAML is malformed or mcp_servers.honeycomb is foreign-owned;
  • leaves Hermes' first-use hook allowlist untouched, requiring normal explicit consent;
  • removes only Honeycomb-owned entries/files and only removes install directories when empty;
  • updates dashboard detection, docs, package gates, and CI/release conformance.

The implementation and protocol oracle are grounded in Hermes Agent 0.19 source and its native shell-hook parser.

Related issue

Closes #319

How it was tested

  • Focused Hermes/connector/conformance/CLI/dashboard suites: 10 files, 83 tests passed.
  • npm run typecheck
  • npm run build
  • npm run pack:check
  • npm run test:packed-cli
  • npm run test:packed-hermes under the current runtime and exact minimum-supported Node 22.5.0
  • Targeted Biome checks and git diff --check
  • Packaged-tarball installation through the installed Honeycomb executable in disposable HOME/HERMES_HOME profiles.
  • Executed all six installed hook paths with native Hermes 0.19 envelopes, including recall mode.
  • Loaded the generated profile through Hermes Agent's actual Python config and shell-hook parser and executed its approved disposable-profile hook specifications.
  • Verified install/uninstall idempotency, ownership-manifest validation, modified-artifact and symlink preservation/refusal, foreign config/comment/root-file preservation, malformed-YAML fail-closed behavior, and foreign MCP refusal.
  • Independent security/code review completed; the initial package/CI coverage blocker was fixed and re-review found no remaining blocking or high-severity findings.

Local npm run ci reaches 472/479 test files and 5210/5230 tests on macOS. Four persistent failures reproduce unchanged on clean upstream/main (onboarding-api, onboarding-api-extended, log-store, and cli-invocation); three timeout-sensitive failures pass when rerun serially. The focused adapter, build, package, formatting, and type gates are green.

Checklist

  • npm run ci passes locally (the four persistent failures reproduce on clean upstream/main; see testing notes)
  • Code is formatted with Biome
  • New behavior has tests
  • New source files carry the license header
  • I've signed the CLA (the bot will confirm)
  • The PR is scoped to one logical change

Summary by CodeRabbit

  • New Features
    • Expanded production support to include the Hermes assistant, including lifecycle hooks and MCP registration.
    • Added the connect <harness> command for wiring supported assistants.
  • Bug Fixes
    • Improved Hermes installed detection and hardened Hermes install/uninstall protections (safe handling of foreign/owned/modified artifacts).
    • Added atomic bundle/config writes and safer cleanup for managed directories.
  • Documentation
    • Refreshed Hermes setup, lifecycle, and connector guidance; updated support status counts.
  • Tests
    • Added Hermes connector/hook conformance and packed Hermes isolation/reversibility coverage.
  • Chores
    • Expanded CI/release and packed CLI conformance gates to include Hermes.

@github-actions

github-actions Bot commented Jul 22, 2026

Copy link
Copy Markdown

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9e9c0b6e-abea-420c-a433-dc204da59299

📥 Commits

Reviewing files that changed from the base of the PR and between 0d76f10 and 13ceb17.

📒 Files selected for processing (4)
  • library/knowledge/private/overview.md
  • src/daemon/runtime/dashboard/harness-detect.ts
  • tests/connectors/hermes.test.ts
  • tests/daemon/runtime/dashboard/harness-detect.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/daemon/runtime/dashboard/harness-detect.test.ts
  • tests/connectors/hermes.test.ts

📝 Walkthrough

Walkthrough

Hermes receives a production connector with native YAML hooks, MCP registration, capture and recall lifecycle handling, ownership-safe installation, CLI wiring, packed conformance checks, and updated support documentation.

Changes

Hermes production integration

Layer / File(s) Summary
Hermes hook protocol and runtime
references/hermes/*, src/hooks/hermes/*, harnesses/hermes/*
Adds Hermes event schemas, capture/recall mappings, model-only context responses, and a stdin/stdout shell-hook binary entrypoint.
Connector filesystem and install contract
src/connectors/contracts.ts, src/connectors/node-fs.ts
Adds atomic writes, empty-directory removal, additional install files, and reusable config patching/removal seams.
Hermes connector installation and removal
src/connectors/hermes.ts, src/connectors/index.ts, src/cli/connector-runner.ts, src/commands/contracts.ts
Adds Hermes YAML hook and MCP installation, ownership manifests, fail-closed safety checks, uninstall cleanup, profile normalization, and connect hermes wiring.
Hermes behavior and safety validation
tests/connectors/*, tests/conformance/*, tests/hooks/hermes/*, tests/mcp/*, tests/cli/*
Tests lifecycle mapping, recall, YAML preservation, ownership safety, uninstall behavior, MCP registration, CLI routing, and filesystem detection.
Packed conformance and release gates
scripts/*, package.json, .github/workflows/*, esbuild.config.mjs
Adds packed Hermes install/uninstall conformance, required bundle checks, CLI inventory updates, CI jobs, release gating, and Hermes bundle aliases.
Harness status and integration documentation
README.md, library/knowledge/*, src/daemon/runtime/dashboard/*, src/hooks/CONVENTIONS.md
Marks Hermes supported, documents its connector and lifecycle behavior, and updates installed-marker and capability reporting.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

Suggested reviewers: thenotoriousllama

Poem

A rabbit hops through YAML bright,
Hooks wake softly in the night.
MCP bundles find their home,
Safe manifests guard the chrome.
Hermes listens, clean and keen—
Four harnesses now are seen!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 39.53% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding a Hermes Agent harness adapter.
Linked Issues check ✅ Passed The changes implement the Hermes adapter, lifecycle mapping, recall, MCP registration, consent, uninstall safety, and tests requested by #319.
Out of Scope Changes check ✅ Passed No clearly unrelated code changes stand out; the docs, CI, packaging, and CLI updates all support the Hermes adapter work.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Comment thread harnesses/hermes/src/index.ts Outdated
Comment thread src/connectors/hermes.ts Outdated
@chrisl10
chrisl10 force-pushed the feat/hermes-harness branch from 6ca6bb2 to adb5e4d Compare July 22, 2026 00:19
Comment thread src/connectors/contracts.ts Outdated
@chrisl10
chrisl10 marked this pull request as draft July 22, 2026 00:34

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🧹 Nitpick comments (2)
src/connectors/hermes.ts (2)

382-389: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Redundant toConfigEntry override — identical to the base default.

Since HERMES_HANDLERS never sets handler.async, this override produces the exact same shape as HarnessConnector.toConfigEntry (type, command, optional timeout, HONEYCOMB_ENTRY_KEY). Removing it and relying on the inherited default reduces duplication and keeps Hermes automatically in sync if the base entry shape ever changes.

♻️ Simplify by dropping the override
-	protected toConfigEntry(handler: HookHandlerEntry): ConfigHookEntry {
-		return {
-			type: "command",
-			command: handler.command,
-			...(handler.timeout === undefined ? {} : { timeout: handler.timeout }),
-			[HONEYCOMB_ENTRY_KEY]: true,
-		};
-	}
-
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/connectors/hermes.ts` around lines 382 - 389, Remove the redundant
toConfigEntry override from the Hermes connector and rely on the inherited
HarnessConnector.toConfigEntry implementation. Keep the existing Hermes handler
configuration and behavior unchanged.

Source: Coding guidelines


275-282: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Reuse the base class's dirOf helper instead of manual slicing.

file.targetPath.slice(0, file.targetPath.lastIndexOf("/")) reimplements dirname logic the base HarnessConnector.install()/.uninstall() already gets via dirOf(...). It's also fragile: if targetPath ever lacked a / (e.g. a future refactor of pluginRoot/handler paths), lastIndexOf returns -1 and .slice(0, -1) silently truncates the last character instead of erroring.

Consider exporting dirOf from contracts.ts and reusing it here for consistency with the base class.

Also applies to: 337-339

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/connectors/hermes.ts` around lines 275 - 282, Export the existing dirOf
helper from contracts.ts and update the file-writing path in the managed-files
loop to call dirOf(file.targetPath) when ensuring the parent directory. Apply
the same replacement to the corresponding path-handling logic around the second
referenced location, removing the manual lastIndexOf/slice dirname
implementation.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/ci.yaml:
- Around line 142-144: Rename the affected workflow steps in quality-gate,
windows-smoke, and macos-service-smoke from Hermes conformance to CLI-only
conformance, since they run only npm run test:packed-cli; leave native Hermes
coverage associated with minimum-node-packed-hermes unless explicitly adding the
Hermes test command to those jobs.

In `@src/daemon/runtime/dashboard/harness-detect.ts`:
- Around line 86-88: Update detectInstalledHarnesses() and its Hermes marker
path configuration to resolve the effective Hermes home from HERMES_HOME,
matching the connector’s existing home-resolution behavior, before probing
capture.js. Ensure the default path remains homedir() when no override is set
and non-default profiles probe their resolved profile home, including through
the dashboard’s default uninstall flow.
- Around line 86-88: Update the Hermes detection path in the paths handler to
target the packaged bundle marker capture.mjs instead of capture.js, preferably
by reusing the shared Hermes handler or bundle constant so detection stays
aligned with shipped artifacts and conformance checks.

In `@src/hooks/CONVENTIONS.md`:
- Line 75: Update the Hermes guidance in the ContextEnvelope and harness
sections to match the production Hermes adapter: treat native `{ context }`
output as model-only rather than user-visible, and remove the claim that no
harness is live-wired. Keep the existing Hermes model-only contract and no
pre-tool interception behavior consistent throughout the document, including the
remaining stale rows.

In `@tests/daemon/runtime/dashboard/harness-detect.test.ts`:
- Around line 80-81: Update the Hermes install fixtures to use capture.mjs
instead of capture.js at
tests/daemon/runtime/dashboard/harness-detect.test.ts:80-81,
tests/daemon/runtime/dashboard/harness-detect.test.ts:137-137, and
tests/daemon/runtime/dashboard/harness-installed-wiring.test.ts:168-168,
preserving the existing test behavior while matching the packaged
harnesses/hermes/bundle/capture.mjs contract.

---

Nitpick comments:
In `@src/connectors/hermes.ts`:
- Around line 382-389: Remove the redundant toConfigEntry override from the
Hermes connector and rely on the inherited HarnessConnector.toConfigEntry
implementation. Keep the existing Hermes handler configuration and behavior
unchanged.
- Around line 275-282: Export the existing dirOf helper from contracts.ts and
update the file-writing path in the managed-files loop to call
dirOf(file.targetPath) when ensuring the parent directory. Apply the same
replacement to the corresponding path-handling logic around the second
referenced location, removing the manual lastIndexOf/slice dirname
implementation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: c1fd0817-cd14-48f9-9ca7-ccedcb445a69

📥 Commits

Reviewing files that changed from the base of the PR and between c1cb6bf and 6ca6bb2.

📒 Files selected for processing (42)
  • .github/workflows/ci.yaml
  • .github/workflows/release.yaml
  • README.md
  • esbuild.config.mjs
  • harnesses/hermes/.mcp.json
  • harnesses/hermes/src/index.ts
  • library/knowledge/private/integrations/harness-integration.md
  • library/knowledge/private/integrations/hook-lifecycle.md
  • library/knowledge/private/overview.md
  • library/knowledge/public/faqs/faq.md
  • library/knowledge/public/overview/glossary.md
  • library/knowledge/public/overview/what-is-honeycomb.md
  • package.json
  • references/hermes/hooks-schema.ts
  • scripts/pack-check.mjs
  • scripts/packed-cli-conformance.mjs
  • scripts/packed-hermes-conformance.mjs
  • src/cli/connector-runner.ts
  • src/commands/contracts.ts
  • src/connectors/contracts.ts
  • src/connectors/hermes.ts
  • src/connectors/index.ts
  • src/connectors/node-fs.ts
  • src/daemon/runtime/dashboard/harness-detect.ts
  • src/daemon/runtime/dashboard/harness-registry.ts
  • src/hooks/CONVENTIONS.md
  • src/hooks/hermes/shim.ts
  • src/hooks/index.ts
  • tests/cli/connector-runner.test.ts
  • tests/cli/harness-reconcile.test.ts
  • tests/commands/lifecycle-verbs.test.ts
  • tests/conformance/hermes-hooks-conformance.test.ts
  • tests/connectors/hermes.test.ts
  • tests/daemon/runtime/dashboard/harness-api.test.ts
  • tests/daemon/runtime/dashboard/harness-detect.test.ts
  • tests/daemon/runtime/dashboard/harness-installed-wiring.test.ts
  • tests/hooks/claude-code/shim.test.ts
  • tests/hooks/harness-identity-stamp.test.ts
  • tests/hooks/hermes/binary-e2e.test.ts
  • tests/hooks/hermes/shim.test.ts
  • tests/hooks/shims-channel.test.ts
  • tests/mcp/registration.test.ts
💤 Files with no reviewable changes (1)
  • harnesses/hermes/.mcp.json

Comment thread .github/workflows/ci.yaml Outdated
Comment thread src/daemon/runtime/dashboard/harness-detect.ts Outdated
Comment thread src/hooks/CONVENTIONS.md
Comment thread tests/daemon/runtime/dashboard/harness-detect.test.ts Outdated
@chrisl10
chrisl10 marked this pull request as ready for review July 22, 2026 01:12

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@library/knowledge/private/overview.md`:
- Line 25: Update the compound modifiers in the overview sentence to use hyphens
where required, including “live-tested,” “end-to-end,” “cross-device,” and any
similarly formed modifiers, while preserving the sentence’s meaning and wording.

In `@src/daemon/runtime/dashboard/harness-detect.ts`:
- Around line 56-57: Update the marker validation flow around
detectInstalledHarnesses to support a per-marker validator: use
fileMarkerExists, backed by statSync(...).isFile(), for Hermes marker paths,
while retaining existsSync for Pi/OpenClaw directory markers. Pass the Hermes
validator through the existing marker definition or selection path without
changing the shared directory-marker behavior.

In `@tests/connectors/hermes.test.ts`:
- Around line 68-82: Strengthen the assertions for config.hooks.post_tool_call
in the Hermes connector test: require exactly one handler and verify its command
is the completed-tool capture command, rather than relying only on every(...).
Keep the existing matcher assertion after confirming the handler exists.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: fddd5e2e-b135-4ea3-98cc-15f812710672

📥 Commits

Reviewing files that changed from the base of the PR and between 6ca6bb2 and 1b6e129.

📒 Files selected for processing (44)
  • .github/workflows/ci.yaml
  • .github/workflows/release.yaml
  • README.md
  • esbuild.config.mjs
  • harnesses/hermes/.mcp.json
  • harnesses/hermes/src/index.ts
  • library/knowledge/private/integrations/harness-integration.md
  • library/knowledge/private/integrations/hook-lifecycle.md
  • library/knowledge/private/overview.md
  • library/knowledge/public/faqs/faq.md
  • library/knowledge/public/overview/glossary.md
  • library/knowledge/public/overview/what-is-honeycomb.md
  • package.json
  • references/hermes/hooks-schema.ts
  • scripts/pack-check.mjs
  • scripts/packed-cli-conformance.mjs
  • scripts/packed-hermes-conformance.mjs
  • src/cli/connector-runner.ts
  • src/commands/contracts.ts
  • src/connectors/contracts.ts
  • src/connectors/hermes.ts
  • src/connectors/index.ts
  • src/connectors/node-fs.ts
  • src/daemon/runtime/dashboard/harness-detect.ts
  • src/daemon/runtime/dashboard/harness-registry.ts
  • src/hooks/CONVENTIONS.md
  • src/hooks/hermes/shim.ts
  • src/hooks/index.ts
  • tests/cli/connector-runner.test.ts
  • tests/cli/daemon-service.test.ts
  • tests/cli/harness-reconcile.test.ts
  • tests/commands/lifecycle-verbs.test.ts
  • tests/conformance/hermes-hooks-conformance.test.ts
  • tests/connectors/hermes.test.ts
  • tests/daemon/runtime/dashboard/harness-api.test.ts
  • tests/daemon/runtime/dashboard/harness-detect.test.ts
  • tests/daemon/runtime/dashboard/harness-installed-wiring.test.ts
  • tests/daemon/runtime/logs/log-store.test.ts
  • tests/hooks/claude-code/shim.test.ts
  • tests/hooks/harness-identity-stamp.test.ts
  • tests/hooks/hermes/binary-e2e.test.ts
  • tests/hooks/hermes/shim.test.ts
  • tests/hooks/shims-channel.test.ts
  • tests/mcp/registration.test.ts
💤 Files with no reviewable changes (1)
  • harnesses/hermes/.mcp.json
🚧 Files skipped from review as they are similar to previous changes (33)
  • library/knowledge/public/overview/what-is-honeycomb.md
  • tests/cli/connector-runner.test.ts
  • library/knowledge/public/faqs/faq.md
  • library/knowledge/public/overview/glossary.md
  • tests/daemon/runtime/dashboard/harness-installed-wiring.test.ts
  • src/connectors/index.ts
  • src/commands/contracts.ts
  • scripts/packed-cli-conformance.mjs
  • README.md
  • harnesses/hermes/src/index.ts
  • tests/commands/lifecycle-verbs.test.ts
  • tests/hooks/hermes/binary-e2e.test.ts
  • library/knowledge/private/integrations/hook-lifecycle.md
  • src/connectors/node-fs.ts
  • references/hermes/hooks-schema.ts
  • package.json
  • tests/conformance/hermes-hooks-conformance.test.ts
  • tests/cli/harness-reconcile.test.ts
  • src/hooks/CONVENTIONS.md
  • tests/hooks/harness-identity-stamp.test.ts
  • tests/mcp/registration.test.ts
  • src/daemon/runtime/dashboard/harness-registry.ts
  • library/knowledge/private/integrations/harness-integration.md
  • src/connectors/contracts.ts
  • tests/hooks/hermes/shim.test.ts
  • esbuild.config.mjs
  • scripts/pack-check.mjs
  • src/connectors/hermes.ts
  • tests/hooks/shims-channel.test.ts
  • scripts/packed-hermes-conformance.mjs
  • src/hooks/hermes/shim.ts
  • src/hooks/index.ts
  • tests/hooks/claude-code/shim.test.ts

Comment thread library/knowledge/private/overview.md Outdated
Comment thread src/daemon/runtime/dashboard/harness-detect.ts
Comment thread tests/connectors/hermes.test.ts Outdated
Comment thread src/daemon/runtime/dashboard/harness-detect.ts
Comment thread src/daemon/runtime/dashboard/harness-detect.ts
Comment thread src/daemon/runtime/dashboard/harness-detect.ts
@chrisl10

Copy link
Copy Markdown
Contributor Author

@thenotoriousllama The code/review matrix is green apart from the repository release gate. This PR comes from a fork, so both jobs in release-gate.yaml are intentionally skipped by the same-repo guard and the required release-gate status is never created. RELEASE-AUTOMATION.md documents the maintainer path for fork contributions: please either move/push this head branch into legioncodeinc/honeycomb so release automation can run, or add the changeset and release-gate status manually. Maintainer edits are enabled on the PR.

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.

feat: add production Hermes Agent harness adapter

1 participant

Morty Proxy This is a proxified and sanitized view of the page, visit original site.