Multiplexer Gap Scan
Apply when asked to check the latest versions of the supported multiplexers, find what the seam is
missing, survey multiplexers cyber-mux does not yet drive, and file issues — for cyber-mux only.
This skill has two axes. Run both unless the request names one:
- Depth — new capabilities in the backends already driven (steps 1–8).
- Breadth — multiplexers not driven at all that now deserve an adapter (step 9).
Drivable backends
Derive this list from the filesystem — ls packages/cyber-mux/src/mux.*.ts — rather than trusting
the table below, which is a convenience and will rot as backends land. Each adapter maps to one
upstream release source:
| Backend |
Adapter source |
Upstream releases |
| tmux |
packages/cyber-mux/src/mux.tmux.ts |
gh release list --repo tmux/tmux |
| wezterm |
packages/cyber-mux/src/mux.wezterm.ts |
gh release list --repo wezterm/wezterm |
| zellij |
packages/cyber-mux/src/mux.zellij.ts |
gh release list --repo zellij-org/zellij |
| herdr |
packages/cyber-mux/src/mux.herdr.ts |
gh release list --repo herdrdev/herdr; else herdr --version |
| cmux |
packages/cyber-mux/src/mux.cmux.ts |
gh release list --repo manaflow-ai/cmux; docs at cmux.com/docs/api |
| otty |
packages/cyber-mux/src/mux.otty.ts |
docs at docs.otty.sh/reference/cli |
Do not scan screen — recognized and honored as an override so the value is reported truthfully,
then rejected by name, because it has no stable per-pane identity for driver-created panes (the
45-screen-adapter ADR).
Workflow
Read the baseline version per backend. The version each adapter is verified against lives in
code comments — grep -nE 'verified against|Requires|≥|[0-9]+\.[0-9]+\.[0-9]+' <adapter source> —
and in apps/website/src/content/docs/multiplexers.md. Record the highest verified version per
backend as its baseline.
Resolve the latest upstream release per backend from the release source above. Prefer the
latest stable tag (skip pre-releases/nightlies for wezterm; take the newest dated stable). For
herdr, if the GitHub repo is unreachable, fall back to the locally installed herdr --version.
Skip backends where latest ≤ baseline — no gap to file. Report them as up to date.
For each backend where latest > baseline, read the changelog between the two versions
(gh api repos/<owner>/<repo>/releases, or the repo's CHANGELOG.md). Extract every new or
changed pane-control capability: new CLI verbs, new flags, newly addressable surfaces,
per-pane state feeds, or behavior changes to a capability the seam already normalizes.
Map each candidate against the seam (packages/cyber-mux/src/mux.ts — the MuxAdapter
contract and its capability interfaces). A candidate is a gap only when all hold:
- the seam exposes no method for it;
- it is not already covered by an open or closed issue (
gh issue list --state all --search "<keyword>");
- it is a capability cyber-mux would plausibly adopt, not a backend-internal detail.
Classify each gap by normalization altitude, mirroring issue #97:
- real-everywhere — every backend can realize it (native or by polling an existing read); belongs on the seam as a shared primitive.
- backend-specific — only one backend can know it (e.g. a derived agent state); belongs on a capability interface that other adapters refuse by name.
Confirm the gap list with the user before filing — issue creation is outward-facing. Present
the classified list; file only what they approve, or all of it if they said to proceed.
File one issue per approved gap via the create-issue skill (it dedupes before filing).
Match the repo's issue shape from #97: a ## Proposed section (the seam signature + how each
backend realizes it), and a normalization-altitude note stating real-everywhere vs
backend-specific-refuse. Label enhancement. End the body with an italic
*Filed by mux-gap-scan against <backend> <latest>.* footer.
Report a summary table: backend, baseline → latest, gaps found, issues filed (with URLs),
gaps skipped (already tracked or declined).
Breadth: multiplexers not yet driven
A backend can also be missing entirely. Depth alone never finds one, because a project with no
adapter has no baseline to beat.
Read the verdicts already recorded, before probing anything. Past sweeps left their findings
in the ADR log — packages/cyber-mux/.agents/spec/design/decisions/README.md, searched for
backend-survey. This is the breadth twin of step 5's dedup search, and it is what stops a sweep
re-deriving a no someone already paid for. A recorded verdict is re-probed only when its own
recheck trigger has fired:
undrivable — durable. Do not re-probe absent a rewrite of the project's control surface.
blocked-upstream — re-probe when the named missing feature may have landed; the verdict
records what to look for, so check that, not the whole CLI.
viable — already has an issue. Confirm the issue, do not re-file.
Sweep for candidate multiplexers above 500 stars. The threshold is a discovery filter, not a
verdict — it is the level at which a project is likely to still exist next year and to have
documented its CLI. Query GitHub directly rather than recalling star counts, which go stale:
gh api "search/repositories?q=terminal+multiplexer+stars:%3E500&sort=stars&per_page=15" \
-q '.items[]|"\(.stargazers_count)\t\(.full_name)\t\(.language)\t\(.description)"'
Run it for more than one phrasing — terminal multiplexer, tmux alternative, terminal workspace panes — since projects self-describe inconsistently and single-query results are
incomplete. Drop anything that is not a pane host: editor plugins, themes, remote-control
front-ends, and terminal emulators with no multiplexing.
Gate each candidate on per-pane CLI drivability, in this order. Stars decide what to look at;
these decide what is possible. Read the project's own CLI reference — not its README — and stop
at the first gate it fails:
- Stable per-pane identity, addressable from outside. A relative selector alone
(
focused, main, next) is not identity. This is the gate screen fails architecturally,
and the one zellij only passed at 0.44.
- The birth command emits the new pane's id —
open() must return an OpenedPane with a
real id. Every current adapter gets it from the create command itself.
- Pane enumeration —
listPanes is required, and a listing is also the recovery path when a
create is silent (the snapshot-before/diff-after shape in mux.zellij.ts).
A candidate failing only the last two is blocked on additive upstream CLI features; one
failing the first is architecturally undrivable, like screen. Say which — they are very
different asks, and the second is not worth an issue against this repo.
File a prospective-backend issue per viable candidate, same confirmation rule as step 6.
State the star count and date, quote the CLI reference verbatim for each gate it clears or
fails, and name whether it is blocked upstream or ready to adapt. Label enhancement, and add
help wanted where a live binary is needed that this machine cannot run. Footer:
*Filed by mux-gap-scan (breadth sweep).*
Record a verdict for EVERY candidate gated — including the ones you file nothing for. This
is the step that makes the sweep cumulative instead of repeated. A candidate that fails gate 1
gets no issue, so without this its assessment is lost the moment the run ends and the next sweep
pays for it again.
Append one section to the ADR log
(packages/cyber-mux/.agents/spec/design/decisions/README.md), which is append-only — add a
section, never edit an existing one. Match the log's house shape:
Decisions (`backend-survey-YYYY-MM` — feasibility verdicts for multiplexers not yet driven):
- **<project> — VERDICT: viable | blocked-upstream | undrivable | not-a-multiplexer.**
<stars> stars, probed <date> against <the CLI reference URL, not the README>. Gate 1
(per-pane identity): <cleared, quoting the selector syntax | failed, quoting what it offers
instead>. Gate 2 (id at birth): … Gate 3 (enumeration): … <For blocked-upstream: the RECHECK
TRIGGER — the exact feature whose arrival would change this.> <For viable: the issue URL.>
Record the date and the version or commit probed, not just the verdict. A verdict without
them cannot be trusted later, because the thing it describes moves. This is the same
deliver-tense discipline the adapter headers use for verified against <version>.
Verdicts are descriptive, not gates: recording undrivable closes nothing and forbids nothing
if the project changes. It records what was true, when, and what would have to change.
Anti-patterns
- Filing an issue for a capability the seam already exposes, or one already tracked — always run the dedup search in step 5.
- Scanning
screen, or trusting the backend table over ls packages/cyber-mux/src/mux.*.ts.
- Treating a wezterm nightly/dated pre-release as the baseline-beating "latest".
- Filing without user confirmation.
- Treating a star count as a feasibility verdict, or recalling one instead of querying it.
- Judging a candidate's drivability from its README rather than its CLI reference.
- Gating a candidate and recording nothing because it failed — a
no is the verdict most worth
keeping, since it is the one no issue will preserve.
- Re-probing a candidate whose recorded verdict has no fired recheck trigger.
- Editing an existing ADR section instead of appending a new one.
References
- create-issue skill — duplicate search and issue authoring.
- Seam contract:
packages/cyber-mux/src/mux.ts.
- Reference gap issue shape: https://github.com/cyberuni/cyber-mux/issues/97
- Why per-pane identity is the gate: the
45-screen-adapter ADR in
packages/cyber-mux/.agents/spec/design/decisions/README.md.
1---2name: mux-gap-scan3description: Use this skill when checking supported multiplexers for new releases, finding seam gaps, surveying multiplexers cyber-mux does not yet drive, and filing gap issues.4---56# Multiplexer Gap Scan78Apply when asked to check the latest versions of the supported multiplexers, find what the seam is9missing, survey multiplexers cyber-mux does not yet drive, and file issues — for cyber-mux only.1011This skill has **two axes**. Run both unless the request names one:1213- **Depth** — new capabilities in the backends already driven (steps 1–8).14- **Breadth** — multiplexers not driven at all that now deserve an adapter (step 9).1516## Drivable backends1718Derive this list from the filesystem — `ls packages/cyber-mux/src/mux.*.ts` — rather than trusting19the table below, which is a convenience and will rot as backends land. Each adapter maps to one20upstream release source:2122| Backend | Adapter source | Upstream releases |23| --- | --- | --- |24| tmux | `packages/cyber-mux/src/mux.tmux.ts` | `gh release list --repo tmux/tmux` |25| wezterm | `packages/cyber-mux/src/mux.wezterm.ts` | `gh release list --repo wezterm/wezterm` |26| zellij | `packages/cyber-mux/src/mux.zellij.ts` | `gh release list --repo zellij-org/zellij` |27| herdr | `packages/cyber-mux/src/mux.herdr.ts` | `gh release list --repo herdrdev/herdr`; else `herdr --version` |28| cmux | `packages/cyber-mux/src/mux.cmux.ts` | `gh release list --repo manaflow-ai/cmux`; docs at cmux.com/docs/api |29| otty | `packages/cyber-mux/src/mux.otty.ts` | docs at docs.otty.sh/reference/cli |3031Do **not** scan `screen` — recognized and honored as an override so the value is reported truthfully,32then rejected by name, because it has no stable per-pane identity for driver-created panes (the33`45-screen-adapter` ADR).3435## Workflow36371. **Read the baseline version per backend.** The version each adapter is verified against lives in38 code comments — `grep -nE 'verified against|Requires|≥|[0-9]+\.[0-9]+\.[0-9]+' <adapter source>` —39 and in `apps/website/src/content/docs/multiplexers.md`. Record the highest verified version per40 backend as its baseline.41422. **Resolve the latest upstream release per backend** from the release source above. Prefer the43 latest **stable** tag (skip pre-releases/nightlies for wezterm; take the newest dated stable). For44 herdr, if the GitHub repo is unreachable, fall back to the locally installed `herdr --version`.45463. **Skip backends where latest ≤ baseline** — no gap to file. Report them as up to date.47484. **For each backend where latest > baseline, read the changelog between the two versions**49 (`gh api repos/<owner>/<repo>/releases`, or the repo's `CHANGELOG.md`). Extract every new or50 changed **pane-control** capability: new CLI verbs, new flags, newly addressable surfaces,51 per-pane state feeds, or behavior changes to a capability the seam already normalizes.52535. **Map each candidate against the seam** (`packages/cyber-mux/src/mux.ts` — the `MuxAdapter`54 contract and its capability interfaces). A candidate is a **gap** only when all hold:55 - the seam exposes no method for it;56 - it is not already covered by an open or closed issue (`gh issue list --state all --search "<keyword>"`);57 - it is a capability cyber-mux would plausibly adopt, not a backend-internal detail.5859 Classify each gap by normalization altitude, mirroring issue #97:60 - **real-everywhere** — every backend can realize it (native or by polling an existing read); belongs on the seam as a shared primitive.61 - **backend-specific** — only one backend can know it (e.g. a derived agent state); belongs on a capability interface that other adapters refuse by name.62636. **Confirm the gap list with the user before filing** — issue creation is outward-facing. Present64 the classified list; file only what they approve, or all of it if they said to proceed.65667. **File one issue per approved gap** via the **create-issue** skill (it dedupes before filing).67 Match the repo's issue shape from #97: a `## Proposed` section (the seam signature + how each68 backend realizes it), and a normalization-altitude note stating real-everywhere vs69 backend-specific-refuse. Label `enhancement`. End the body with an italic70 `*Filed by mux-gap-scan against <backend> <latest>.*` footer.71728. **Report a summary table**: backend, baseline → latest, gaps found, issues filed (with URLs),73 gaps skipped (already tracked or declined).7475## Breadth: multiplexers not yet driven7677A backend can also be missing entirely. Depth alone never finds one, because a project with no78adapter has no baseline to beat.79809. **Read the verdicts already recorded, before probing anything.** Past sweeps left their findings81 in the ADR log — `packages/cyber-mux/.agents/spec/design/decisions/README.md`, searched for82 `backend-survey`. This is the breadth twin of step 5's dedup search, and it is what stops a sweep83 re-deriving a `no` someone already paid for. A recorded verdict is re-probed only when its own84 recheck trigger has fired:8586 - **`undrivable`** — durable. Do not re-probe absent a rewrite of the project's control surface.87 - **`blocked-upstream`** — re-probe when the named missing feature may have landed; the verdict88 records what to look for, so check that, not the whole CLI.89 - **`viable`** — already has an issue. Confirm the issue, do not re-file.909110. **Sweep for candidate multiplexers above 500 stars.** The threshold is a *discovery filter*, not a92 verdict — it is the level at which a project is likely to still exist next year and to have93 documented its CLI. Query GitHub directly rather than recalling star counts, which go stale:9495 ```bash96 gh api "search/repositories?q=terminal+multiplexer+stars:%3E500&sort=stars&per_page=15" \97 -q '.items[]|"\(.stargazers_count)\t\(.full_name)\t\(.language)\t\(.description)"'98 ```99100 Run it for more than one phrasing — `terminal multiplexer`, `tmux alternative`, `terminal101 workspace panes` — since projects self-describe inconsistently and single-query results are102 incomplete. Drop anything that is not a pane host: editor plugins, themes, remote-control103 front-ends, and terminal emulators with no multiplexing.10410511. **Gate each candidate on per-pane CLI drivability, in this order.** Stars decide what to look at;106 these decide what is possible. Read the project's own CLI reference — not its README — and stop107 at the first gate it fails:108109 - **Stable per-pane identity, addressable from outside.** A relative selector alone110 (`focused`, `main`, `next`) is not identity. This is the gate `screen` fails architecturally,111 and the one zellij only passed at 0.44.112 - **The birth command emits the new pane's id** — `open()` must return an `OpenedPane` with a113 real id. Every current adapter gets it from the create command itself.114 - **Pane enumeration** — `listPanes` is required, and a listing is also the recovery path when a115 create is silent (the snapshot-before/diff-after shape in `mux.zellij.ts`).116117 A candidate failing only the last two is **blocked on additive upstream CLI features**; one118 failing the first is **architecturally undrivable**, like `screen`. Say which — they are very119 different asks, and the second is not worth an issue against this repo.12012112. **File a prospective-backend issue per viable candidate**, same confirmation rule as step 6.122 State the star count and date, quote the CLI reference verbatim for each gate it clears or123 fails, and name whether it is blocked upstream or ready to adapt. Label `enhancement`, and add124 `help wanted` where a live binary is needed that this machine cannot run. Footer:125 `*Filed by mux-gap-scan (breadth sweep).*`12612713. **Record a verdict for EVERY candidate gated — including the ones you file nothing for.** This128 is the step that makes the sweep cumulative instead of repeated. A candidate that fails gate 1129 gets no issue, so without this its assessment is lost the moment the run ends and the next sweep130 pays for it again.131132 Append one section to the ADR log133 (`packages/cyber-mux/.agents/spec/design/decisions/README.md`), which is append-only — add a134 section, never edit an existing one. Match the log's house shape:135136 ```markdown137 Decisions (`backend-survey-YYYY-MM` — feasibility verdicts for multiplexers not yet driven):138139 - **<project> — VERDICT: viable | blocked-upstream | undrivable | not-a-multiplexer.**140 <stars> stars, probed <date> against <the CLI reference URL, not the README>. Gate 1141 (per-pane identity): <cleared, quoting the selector syntax | failed, quoting what it offers142 instead>. Gate 2 (id at birth): … Gate 3 (enumeration): … <For blocked-upstream: the RECHECK143 TRIGGER — the exact feature whose arrival would change this.> <For viable: the issue URL.>144 ```145146 Record the **date and the version or commit probed**, not just the verdict. A verdict without147 them cannot be trusted later, because the thing it describes moves. This is the same148 deliver-tense discipline the adapter headers use for `verified against <version>`.149150 Verdicts are descriptive, not gates: recording `undrivable` closes nothing and forbids nothing151 if the project changes. It records what was true, when, and what would have to change.152153## Anti-patterns154155- Filing an issue for a capability the seam already exposes, or one already tracked — always run the dedup search in step 5.156- Scanning `screen`, or trusting the backend table over `ls packages/cyber-mux/src/mux.*.ts`.157- Treating a wezterm nightly/dated pre-release as the baseline-beating "latest".158- Filing without user confirmation.159- Treating a star count as a feasibility verdict, or recalling one instead of querying it.160- Judging a candidate's drivability from its README rather than its CLI reference.161- Gating a candidate and recording nothing because it failed — a `no` is the verdict most worth162 keeping, since it is the one no issue will preserve.163- Re-probing a candidate whose recorded verdict has no fired recheck trigger.164- Editing an existing ADR section instead of appending a new one.165166## References167168- create-issue skill — duplicate search and issue authoring.169- Seam contract: `packages/cyber-mux/src/mux.ts`.170- Reference gap issue shape: https://github.com/cyberuni/cyber-mux/issues/97171- Why per-pane identity is the gate: the `45-screen-adapter` ADR in172 `packages/cyber-mux/.agents/spec/design/decisions/README.md`.