Bridge tmux pane lifecycle events into hive-mcp's swarm event backbone.
Problem:
:tmux/pane-created,
:tmux/pane-killed, …) via hive.events. These are local to the
hive-events router and never reach hive-mcp.channel.core, NATS,
or the swarm/sync handlers.Ling/spawn!
flow (or when the JVM spawn path is bypassed for any reason), the
swarm registry never learns about the slave and swarm_status
shows nothing.Solution:
:tmux/pane-created and
:tmux/pane-killed event handlers with wrapping handlers that
preserve the original :tmux/log effect and ALSO emit a new
:swarm/publish-slave-event effect.:swarm/publish-slave-event effect is handled by a fx
registered here; it uses requiring-resolve to locate
hive-mcp.swarm.event-bridge/publish-slave-event! and forwards
the translated payload.Design (SOLID/DDD/FP):
:tmux/pane-* → :slave-* and
forwards via publish-slave-event!. No direct DataScript writes,
no NATS coupling.hive.events (stable re-frame API) and on a
requiring-resolved var from hive-mcp. No compile-time coupling
to hive-mcp.event->slave-type plus a pure payload-translator fn.translate-pane-created, translate-pane-killed)
are side-effect free and trivially testable. Side effects live
at the boundary (publish!, start!, stop!).Loop safety:
publish-slave-event! already handles NATS loop prevention via
the :via :nats-bridge tag. Events emitted from this bridge are
additionally tagged with :source :hive-tmux for traceability.Ling/spawn! path is harmless because
add-slave! in ds-lings is idempotent (upsert-style) and the
swarm/sync handlers reconcile by slave-id.Bridge tmux pane lifecycle events into hive-mcp's swarm event backbone. Problem: - hive-tmux emits re-frame-style events (`:tmux/pane-created`, `:tmux/pane-killed`, …) via `hive.events`. These are local to the hive-events router and never reach `hive-mcp.channel.core`, NATS, or the swarm/sync handlers. - When a tmux pane is created *outside* the standard `Ling/spawn!` flow (or when the JVM spawn path is bypassed for any reason), the swarm registry never learns about the slave and `swarm_status` shows nothing. Solution: - On addon initialization, re-register the `:tmux/pane-created` and `:tmux/pane-killed` event handlers with wrapping handlers that preserve the original `:tmux/log` effect and ALSO emit a new `:swarm/publish-slave-event` effect. - The `:swarm/publish-slave-event` effect is handled by a fx registered here; it uses `requiring-resolve` to locate `hive-mcp.swarm.event-bridge/publish-slave-event!` and forwards the translated payload. - On shutdown, the original handlers are reinstated so that subsequent dispatches fall back to pure logging. Design (SOLID/DDD/FP): - SRP: this ns ONLY translates `:tmux/pane-*` → `:slave-*` and forwards via `publish-slave-event!`. No direct DataScript writes, no NATS coupling. - DIP: depends on `hive.events` (stable re-frame API) and on a `requiring-resolve`d var from hive-mcp. No compile-time coupling to hive-mcp. - OCP: adding a new tmux event → slave event mapping is a single entry in `event->slave-type` plus a pure payload-translator fn. - Pure helpers (`translate-pane-created`, `translate-pane-killed`) are side-effect free and trivially testable. Side effects live at the boundary (`publish!`, `start!`, `stop!`). Loop safety: - `publish-slave-event!` already handles NATS loop prevention via the `:via :nats-bridge` tag. Events emitted from this bridge are additionally tagged with `:source :hive-tmux` for traceability. - Duplication with the JVM `Ling/spawn!` path is harmless because `add-slave!` in ds-lings is idempotent (upsert-style) and the swarm/sync handlers reconcile by slave-id.
(start!)Install the swarm bridge.
:swarm/publish-slave-event effect handler.:tmux/pane-created and
:tmux/pane-killed that keep the original logging behavior and
additionally forward translated events to
hive-mcp.swarm.event-bridge/publish-slave-event!.Idempotent: a second call is a no-op. Returns true on (new) start, false if already running.
Install the swarm bridge. - Registers the `:swarm/publish-slave-event` effect handler. - Re-registers wrapping handlers for `:tmux/pane-created` and `:tmux/pane-killed` that keep the original logging behavior and additionally forward translated events to `hive-mcp.swarm.event-bridge/publish-slave-event!`. Idempotent: a second call is a no-op. Returns true on (new) start, false if already running.
(status)Return current bridge state for diagnostics.
Return current bridge state for diagnostics.
(stop!)Uninstall the swarm bridge.
Reinstates the pure logging handlers for :tmux/pane-created and
:tmux/pane-killed. The :swarm/publish-slave-event effect handler
remains registered but is harmless — no handler will emit it.
Idempotent.
Uninstall the swarm bridge. Reinstates the pure logging handlers for `:tmux/pane-created` and `:tmux/pane-killed`. The `:swarm/publish-slave-event` effect handler remains registered but is harmless — no handler will emit it. Idempotent.
(translate-pane-created {:keys [ling-id cwd] :as _payload})Pure(ish) translation of a :tmux/pane-created payload into a
:slave-spawned event map consumed by
hive-mcp.swarm.event-bridge/publish-slave-event!.
Input payload shape (from hive-tmux.events):
{:ling-id str :pane-id str :cwd str}
Tmux panes always represent depth-1 lings (ling = one pane = one Claude CLI process).
Pure(ish) translation of a `:tmux/pane-created` payload into a
`:slave-spawned` event map consumed by
`hive-mcp.swarm.event-bridge/publish-slave-event!`.
Input payload shape (from `hive-tmux.events`):
{:ling-id str :pane-id str :cwd str}
Tmux panes always represent depth-1 lings (ling = one pane = one
Claude CLI process).(translate-pane-killed {:keys [ling-id] :as _payload})Pure translation of a :tmux/pane-killed payload into a
:slave-killed event map.
Pure translation of a `:tmux/pane-killed` payload into a `:slave-killed` event map.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |