Skip to content

feat: add Hermes as a second executor family (backend + CLI)#77

Open
plutoless wants to merge 41 commits into
mainfrom
feat/hermes
Open

feat: add Hermes as a second executor family (backend + CLI)#77
plutoless wants to merge 41 commits into
mainfrom
feat/hermes

Conversation

@plutoless

Copy link
Copy Markdown
Contributor

Summary

Adds Hermes (Nous Research) as a first-class detached executor family, peer to Codex, driven over Hermes's TUI Gateway JSON-RPC stdio app-server. V1 is core run loop only: create session → submit prompt → stream progress → settled answer → cancel → follow-up.

  • New hermes/ adapter (probe, jsonrpc peer, gateway client, session, executor) emitting the generic ExecutorEvent stream — no Codex multi-message-turn coupling.
  • Gateway launched as the Hermes project venv python -m tui_gateway.entry; workspace set via TERMINAL_CWD at spawn, so gateway processes are keyed by working directory and multiplex sessions by params.session_id.
  • Single terminal message.complete selects COMPLETED / CANCELLED / FAILED via payload.status; approval.request/clarify.request → terminal BLOCKED. Follow-ups use session.steer only (no prompt.submit fallback). Gateway crash/EOF and a timeout_seconds liveness bound both surface as observable FAILED (no silent hangs).
  • Capabilities: supports_follow_up + supports_cancel; supports_pause/supports_resume/supports_thread_list false.
  • Single source of truth newbro/executors/families.py::SUPPORTED_EXECUTOR_FAMILIES, aliased by runtime/config.py::SUPPORTED_DETACHED_EXECUTOR_TYPES and referenced by the registry (now validates family membership), both CLI parsers (top-level + detached node), and interactive setup.
  • CLI: newbro executor probe/use --executor hermes, install-hermes, --enabled-executor hermes, and executor setup writes the executors.hermes block.
  • Docs: docs/protocol/hermes-gateway.md (+ real captured fixture), docs/architecture/executors.md, docs/memories.md.

Out of scope (follow-on plan): macOS menu-bar app changes (single-choice executor selector, per-family probe state) — spec §6. Also deferred: Hermes thread import, skills, audio, resume, interactive approval/clarify response wiring.

Design spec: docs/superpowers/specs/2026-06-09-hermes-second-executor-design.md
Implementation plan: docs/superpowers/plans/2026-06-09-hermes-second-executor.md

Test Plan

  • pytest full suite green (747 passed)
  • ruff check clean on new hermes/ adapter + touched CLI
  • Discovery fixture captured against live hermes v0.12.0
  • Unit tests: event mapping (progress/completed/cancelled/failed/blocked), no-fallback follow-up, cancel→interrupt, gateway-EOF→FAILED, timeout→FAILED, registry family validation, both CLI parsers, interactive setup, executor_settings probe/use/install
  • Manual: run a real hermes executor node end-to-end and drive a Bro turn

🤖 Generated with Claude Code

plutoless and others added 30 commits June 9, 2026 03:04
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ed, CLI scope, family selector)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…shared families constant, per-family macOS probe)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…rmat

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Registry create_node and update_node now reject unknown executor families
using SUPPORTED_EXECUTOR_FAMILIES as the whitelist.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds hermes to the executor selection prompt (via SUPPORTED_EXECUTOR_FAMILIES)
and writes an executors.hermes block with a command key in the resolver loop.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…el + dispatch test

- Add PEER_CLOSED sentinel to jsonrpc.py; push it in _read_loop finally so consumers unblock on EOF
- Fan __gateway_closed__ marker to all session queues in _route_events when peer closes
- Handle __gateway_closed__ in _drive_prompt as terminal FAILED (not hang)
- Wire timeout_seconds via asyncio.wait_for in _drive_prompt; yields FAILED on TimeoutError
- Fix _print_human_probe to use payload executor name instead of hardcoded "Codex"
- Add test for cmd_executor routing install-hermes to run_executor_install_hermes

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ect dialog

Make the agent-client picker single-select (Codex default), drop the
'Coming soon'/disabled gate on Hermes, and pass the chosen family into
createExecutorNode. The family is locked to the bound executor for an
existing Bro and once credentials have been issued.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The setup dialog auto-issues connect credentials on mount, which created
the node (and locked the family) before the user could choose. Only lock
the picker for an existing Bro, while an issue is in flight, or once
connected; selecting a different family for a still-pending Bro now deletes
the auto-created node and re-issues for the chosen family.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…x_agent, all-family refresh, defensive install)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…s, binary start gating)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…h-gating, scoped refresh, no-fallback picker)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add PROBEABLE_EXECUTOR_FAMILIES constant, narrow probe/use argparse
choices to it, and make dispatch explicit so acpx is never silently
routed to the codex payload.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
`executor_runtime_ready` generic branch now falls back to the family
name when no `command` is configured, matching the executor node's own
`_build_executors` default, so `executor run --enabled-executor hermes`
is config-free when `hermes` is on PATH.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
plutoless and others added 11 commits June 9, 2026 09:44
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…se/install

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace the single codexStatus/executorProbe/codexSetupLog/codexSetupBusy
fields in AppModel with probeByFamily/statusByFamily/setupLogByFamily/
setupBusyByFamily maps. Add ProbeScope helper to compute which families to
probe, a refreshProbe(for:) scoped single-family probe method, and a real
setUpHermes(for:) mirroring setUpCodex. Update all readers in
ExecutorSettingsView and NewbroExecutorApp to use the maps keyed by "codex".
Codex diagnosis/settings behavior is unchanged.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…n text

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…itor

Replace dual codex/acpx toggles with a single Picker over supportedExecutorFamilies; new profiles start unselected and Save is disabled until a family is explicitly chosen; existing profiles with empty/unrecognised families load unselected with a warning flag. Adds initialPickerFamily() helper and a matching test.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ermes status row from probe

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tall

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@plutoless

Copy link
Copy Markdown
Contributor Author

Update — operator-facing Hermes support added to this branch

Since the original adapter, this branch now also includes:

Web UI

  • Hermes is selectable in the create/connect-a-Bro agent-client picker (was a hardcoded "Coming soon" gate); single-select, family passed into createExecutorNode. Fixed a follow-on where auto-issue-on-mount locked the picker.

CLI

  • executor run --enabled-executor hermes runs config-free when hermes is on PATH (readiness defaults an unconfigured family command to its own name).
  • newbro executor install-hermes runs the vendor installer (install.sh) defensively (stdin /dev/null, bounded timeout), resolves ~/.local/bin/hermes; auth (hermes setup --portal) stays manual.
  • probe --executor hermes --json carries a best-effort authenticated field (hermes auth list).
  • PROBEABLE_EXECUTOR_FAMILIES = (codex, hermes); ACPX is run-only (probe/use reject it; no more silent codex payload).
  • Local config writers enforce the single-family node invariant (single-element enabled_executors).

macOS menu-bar app (spec §6)

  • Per-family probe state (probeByFamily/statusByFamily) with scoped per-family refresh (Codex and Hermes are separate Settings panes; each Refresh probes only its family).
  • Family-aware start diagnosis: Hermes missing → Set Up (install-hermes); present but unauthenticated → Sign-in prompt (hermes setup --portal); authenticated/undetermined → ready (mirrors Codex login-required; nil never blocks).
  • No-fallback single-choice executor picker in the profile editor (Save gated on an explicit family).
  • Sign-in and install-failure surface as informational text / streamed log — no Terminal launcher.

Specs/plans: docs/superpowers/specs/2026-06-09-hermes-second-executor-design.md, …-hermes-macapp-and-cli-design.md (+ matching plans). Two design rounds + grilling.

Verification: pytest 760 passed; swift test 125 passed; feature files ruff-clean. A final opus code review flagged 4 functional defects (set-up-then-start not resuming, scoped refresh not re-deriving diagnoses, Hermes status row, post-install PATH resolution) — all fixed and re-verified.

Out of scope / follow-ups: web picker no-fallback parity; Hermes thread import / skills / audio / interactive approval wiring.

@github-actions

Copy link
Copy Markdown

Vercel preview is ready.

https://newbro-o3nwwhjpd-agora-devx.vercel.app

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