Claude Skill

openrig-herdr

Use when opening OpenRig fleet terminals as a herdr wall — turning a rig, pod, mission, slice, or saved view into live interactive agent tiles via `rig terminal`, watching another rig read-only, or driving herdr on an agent's request ("open all my rigs + a mission as views"). Cov

LLM Mart · 0 points · 12 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download mvschwarz-openrig-skills__canonical_core_openrig-herdr-209030f.zip · 3 KB
Part of mvschwarz/openrig — 47 skills

Install

skills CLI npx skills add https://github.com/mvschwarz/openrig/tree/main/skills/_canonical/core/openrig-herdr
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install mvschwarz-openrig@llmmart
Git git clone https://github.com/mvschwarz/openrig.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole mvschwarz/openrig collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

openrig-herdr

OpenRig decides which agents make up a view (a rig, a pod, a mission, a slice, or a saved group); herdr renders the pixels. A view opens as live, interactive terminal tiles — each tile is a nested tmux attach to a daemon-owned agent session, so you get the real session, not a snapshot. OpenRig owns the semantics; herdr owns the surface. You drive it entirely through the rig terminal CLI, which rides the installed herdr binary at arm's length — never link, embed, or plugin it.

The whole surface — three verbs

rig terminal open <view> [--provider herdr|cmux] [--json]   # herdr is the default provider
rig terminal views [--json]                                 # list openable views (saved + derived)
rig terminal status [--provider] [--json]                   # provider liveness / health

<view> resolves, in order, to one of:

  • a rig name — every live agent in that rig, auto-laid-out;
  • pod:<rig>/<podNamespace> — every live agent in one pod of a rig (the rig's inventory filtered by pod);
  • mission:<id> — the agents working that mission (derived live from topology);
  • slice:<id> — the agents working that slice (derived live);
  • a saved-view name — a user-defined group (see Saved views).

Compose a view from a sentence

An agent asked "open all my rigs plus a mission as views" runs one open per target:

rig terminal open acme-web                     # a whole rig, live agents as tiles
rig terminal open mission:site-relaunch        # exactly the agents working the mission
rig terminal open slice:search-filters      # the agents working one slice

No hand-listing of seats: the mission/slice membership is derived from live topology at open time.

Read the result honestly — partial and degrade

The result is a partition — every seat lands in exactly one bucket, each named:

  • opened — the live agents now showing as tiles.
  • absent — seats in the view that aren't currently live: named and skipped, never silently dropped. A view that opens some of its seats is a success (the partial is disclosed) and exits 0. Only a view where no pane opens exits non-zero.
  • degraded — an agent that structurally cannot tile, named with the reason. The v1 case: an agent on a host registered over HTTP has no ssh path, so its tile can't be composed — it reads as "host <id> is http-registered; tiles need ssh" and is skipped, never dropped. (ssh-reachable hosts tile via an ssh-wrapped attach; full http-host tiling is deferred to the cross-host transport seam.)

Read --json to branch on the partition programmatically; the exit code alone tells you opened-something (0) vs opened-nothing (non-zero).

Read-only — who's interactive, who's watch-only

Read-only is composed into the pane at open time — a read-only tile is a tmux attach -r, the client reports readonly=1, and it physically cannot send input. The current policy, by view kind:

  • A rig view or a pod: view is interactive — you asked for that rig (or pod) directly, so you can drive its agents.
  • mission: and slice: views are read-only by construction — these derived views cut across rigs; you watch and scroll, you don't keystroke into them.
  • A saved view is per-member — each member carries its own readOnly (omit = interactive; true = attach -r).

So you don't have to remember to be careful: the view kind (and, for a saved view, the per-member flag) sets it at open time.

Safety rails (hard — the fleet-safety rail)

  • A tile is a view (a nested tmux attach) of a daemon-owned session. Never move, join, kill, or re-parent a daemon-owned pane. Closing a tile detaches one tmux client — the daemon's session is untouched and its addressing (send/capture/nudge) is unaffected.
  • Host-local read-only viewing mutates nothing. Anything that would change a live daemon session's shared state (e.g. flipping a tmux option on a running seat) is a config/design change — prove it in an isolated environment, never live-flip in production.

Scroll + copy work out of the box

On a freshly-launched agent tile the mouse wheel scrolls the pane's history and a drag-select copies to your system clipboard — with no tmux commands typed. This rides the daemon's terminal defaults (a per-session scroll option set at launch, plus the daemon tmux server's clipboard defaults). Honest timing: agents that were already running before this shipped pick up wheel-scroll at their next natural relaunch (the scroll default is per-session and running seats are never retro-flipped); system-clipboard copy works immediately (it's server-wide).

Limits — state them, don't paper over them

  • Tile chrome v1 = a plain label (agent + slice). Rich per-tile status is roadmap.
  • Duplicate / multi-view membership (the same agent live in two views at once) works — put the duplicates in same-size panes. Different-sized duplicate panes have an inherent tmux multi-client resize mismatch (tmux clamps to the smallest client); it is documented, not fixed — don't expect a setting to remove it.
  • Inner tmux status bar is hidden by default (herdr provides the chrome); one config key (terminal.status_bar) flips it back on for raw-tmux / no-provider surfaces, and the flip applies to future launches only.

Saved views — the library (terminal-views.yaml)

In v1 you create a saved view by hand-authoring terminal-views.yaml — there is no save/write verb (open / views / status are the whole surface; a rig terminal save <id> verb is a named stretch/follow-up). You reopen it like any other view: rig terminal open <id>.

The file lives at the OpenRig home root (resolved via getDefaultOpenRigPath()), is written atomically (tmp + rename), and is byte-stable. Only hand-authored saved views live here — derived views (a rig, pod:<rig>/<pod>, mission:<id>, slice:<id>) are computed live and never written to this file.

Schema — use these field names exactly, in this order; omit optional fields when absent (never write null):

version: 1
views:
  - id: my-view-id             # required — the id `rig terminal open <id>` takes
    name: Human Name           # required
    members:
      - seat: pod-member@rig    # required — the canonical session name
        label: agent . slice    # optional — pane label
        host: some-host-id      # optional — STRUCTURED host id (NEVER a `member@rig@host` string);
                                #            omit for local. ssh-registered hosts tile;
                                #            http-registered hosts honest-degrade (named + skipped, with reason)
        tmuxSession: sessname   # optional — defaults to `seat`
        readOnly: true          # optional — omit = interactive; true = `tmux attach -r`

An agent composing a saved view on request writes this YAML and then opens the id: rig terminal open my-view-id (add --provider cmux for cmux). The library is provider-agnostic — the same saved view opens in herdr or cmux.

AGPL / clean-room

Driving herdr through the rig terminal CLI (which talks to the installed herdr binary over its CLI/socket) is arm's-length and fine. Do not link herdr's source, embed it in-process, or ship a herdr plugin — a plugin needs legal review. This skill and its docs are clean-room: patterns only, never herdr source text.

Files (openrig)
  • SKILL.md 8.1 KB
    ---
    name: openrig-herdr
    description: >
      Use when opening OpenRig fleet terminals as a herdr wall — turning a rig, pod, mission, slice, or
      saved view into live interactive agent tiles via `rig terminal`, watching another rig read-only,
      or driving herdr on an agent's request ("open all my rigs + a mission as views"). Covers the
      `rig terminal open|views|status` verbs, the honest-partial/degrade reading of the result, the
      read-only-by-construction rail for cross-rig views, scroll/copy out of the box, and the
      same-size-only duplicate-pane limit. herdr is the default, proof-gated provider.
    metadata:
      openrig:
        stage: candidate
        sibling_skills:
          - openrig-cmux
          - openrig-user
    ---
    
    # openrig-herdr
    
    OpenRig decides **which** agents make up a view (a rig, a pod, a mission, a slice, or a saved
    group); **herdr** renders the pixels. A view opens as live, interactive terminal tiles — each tile
    is a nested `tmux attach` to a daemon-owned agent session, so you get the real session, not a
    snapshot. OpenRig owns the semantics; herdr owns the surface. You drive it entirely through the
    `rig terminal` CLI, which rides the installed herdr binary at arm's length — never link, embed, or
    plugin it.
    
    ## The whole surface — three verbs
    
    ```bash
    rig terminal open <view> [--provider herdr|cmux] [--json]   # herdr is the default provider
    rig terminal views [--json]                                 # list openable views (saved + derived)
    rig terminal status [--provider] [--json]                   # provider liveness / health
    ```
    
    `<view>` resolves, in order, to one of:
    - a **rig name** — every live agent in that rig, auto-laid-out;
    - **`pod:<rig>/<podNamespace>`** — every live agent in one pod of a rig (the rig's inventory filtered by pod);
    - **`mission:<id>`** — the agents working that mission (derived live from topology);
    - **`slice:<id>`** — the agents working that slice (derived live);
    - a **saved-view name** — a user-defined group (see Saved views).
    
    ## Compose a view from a sentence
    
    An agent asked "open all my rigs plus a mission as views" runs one `open` per target:
    
    ```bash
    rig terminal open acme-web                     # a whole rig, live agents as tiles
    rig terminal open mission:site-relaunch        # exactly the agents working the mission
    rig terminal open slice:search-filters      # the agents working one slice
    ```
    
    No hand-listing of seats: the mission/slice membership is derived from live topology at open time.
    
    ## Read the result honestly — partial and degrade
    
    The result is a partition — every seat lands in exactly one bucket, each **named**:
    
    - **opened** — the live agents now showing as tiles.
    - **absent** — seats in the view that aren't currently live: **named and skipped, never silently
      dropped.** A view that opens *some* of its seats is a success (the partial is disclosed) and exits
      **0**. Only a view where **no** pane opens exits **non-zero**.
    - **degraded** — an agent that structurally cannot tile, named **with the reason**. The v1 case:
      an agent on a host registered over HTTP has no ssh path, so its tile can't be composed — it reads
      as **"host `<id>` is http-registered; tiles need ssh"** and is skipped, never dropped. (ssh-reachable
      hosts tile via an ssh-wrapped attach; full http-host tiling is deferred to the cross-host transport
      seam.)
    
    Read `--json` to branch on the partition programmatically; the exit code alone tells you opened-something
    (0) vs opened-nothing (non-zero).
    
    ## Read-only — who's interactive, who's watch-only
    
    Read-only is composed into the pane at open time — a read-only tile is a `tmux attach -r`, the client
    reports `readonly=1`, and it **physically cannot send input**. The current policy, by view kind:
    
    - **A rig view or a `pod:` view is interactive** — you asked for that rig (or pod) directly, so you
      can drive its agents.
    - **`mission:` and `slice:` views are read-only by construction** — these derived views cut across
      rigs; you watch and scroll, you don't keystroke into them.
    - **A saved view is per-member** — each member carries its own `readOnly` (omit = interactive;
      `true` = `attach -r`).
    
    So you don't have to remember to be careful: the view kind (and, for a saved view, the per-member
    flag) sets it at open time.
    
    ## Safety rails (hard — the fleet-safety rail)
    
    - A tile is a **view** (a nested `tmux attach`) of a daemon-owned session. **Never** move, join, kill,
      or re-parent a daemon-owned pane. Closing a tile detaches one tmux client — the daemon's session is
      untouched and its addressing (send/capture/nudge) is unaffected.
    - Host-local read-only viewing mutates nothing. Anything that would change a **live** daemon session's
      shared state (e.g. flipping a tmux option on a running seat) is a config/design change — prove it in
      an isolated environment, never live-flip in production.
    
    ## Scroll + copy work out of the box
    
    On a freshly-launched agent tile the mouse wheel scrolls the pane's history and a drag-select copies
    to your **system** clipboard — with no tmux commands typed. This rides the daemon's terminal defaults
    (a per-session scroll option set at launch, plus the daemon tmux server's clipboard defaults). Honest
    timing: agents that were already running before this shipped pick up wheel-scroll at their **next
    natural relaunch** (the scroll default is per-session and running seats are never retro-flipped);
    system-clipboard copy works immediately (it's server-wide).
    
    ## Limits — state them, don't paper over them
    
    - **Tile chrome v1 = a plain label** (agent + slice). Rich per-tile status is roadmap.
    - **Duplicate / multi-view membership** (the same agent live in two views at once) works — put the
      duplicates in **same-size panes**. Different-sized duplicate panes have an inherent tmux
      multi-client resize mismatch (tmux clamps to the smallest client); it is **documented, not fixed** —
      don't expect a setting to remove it.
    - **Inner tmux status bar** is hidden by default (herdr provides the chrome); one config key
      (`terminal.status_bar`) flips it back on for raw-tmux / no-provider surfaces, and the flip applies
      to **future launches only**.
    
    ## Saved views — the library (`terminal-views.yaml`)
    
    In v1 you **create** a saved view by **hand-authoring** `terminal-views.yaml` — there is no save/write
    verb (`open` / `views` / `status` are the whole surface; a `rig terminal save <id>` verb is a named
    stretch/follow-up). You **reopen** it like any other view: `rig terminal open <id>`.
    
    The file lives at the OpenRig home root (resolved via `getDefaultOpenRigPath()`), is written
    atomically (tmp + rename), and is byte-stable. **Only hand-authored saved views live here — derived
    views (a rig, `pod:<rig>/<pod>`, `mission:<id>`, `slice:<id>`) are computed live and never written to
    this file.**
    
    Schema — use these field names **exactly**, in this order; **omit** optional fields when absent
    (never write `null`):
    
    ```yaml
    version: 1
    views:
      - id: my-view-id             # required — the id `rig terminal open <id>` takes
        name: Human Name           # required
        members:
          - seat: pod-member@rig    # required — the canonical session name
            label: agent . slice    # optional — pane label
            host: some-host-id      # optional — STRUCTURED host id (NEVER a `member@rig@host` string);
                                    #            omit for local. ssh-registered hosts tile;
                                    #            http-registered hosts honest-degrade (named + skipped, with reason)
            tmuxSession: sessname   # optional — defaults to `seat`
            readOnly: true          # optional — omit = interactive; true = `tmux attach -r`
    ```
    
    An agent composing a saved view on request **writes this YAML** and then opens the id:
    `rig terminal open my-view-id` (add `--provider cmux` for cmux). The library is provider-agnostic —
    the same saved view opens in herdr or cmux.
    
    ## AGPL / clean-room
    
    Driving herdr through the `rig terminal` CLI (which talks to the installed herdr binary over its
    CLI/socket) is arm's-length and fine. Do **not** link herdr's source, embed it in-process, or ship a
    herdr plugin — a plugin needs legal review. This skill and its docs are clean-room: patterns only,
    never herdr source text.
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related