mux-dispatch
Skill11 starsChanged 49 days agoApache-2.0View on GitHub
Delegate tasks to parallel agent sessions via tmux or zellij. Auto-detects the active multiplexer from environment variables. Use when the user asks to delegate, spawn, or run a task in a separate pane with a specific agent.
In this repository83 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- about-konductorSkill
- adr-generatorSkill
- adversarial-code-review-pass-integritySkill
- adversarial-code-review-pass-schemaSkill
- adversarial-code-review-pass-securitySkill
- adversarial-code-reviewSkill
- adversarial-design-reviewSkill
- agents-md-authoringSkill
- app-discoverySkill
- architecture-advisorSkill
- architecture-diagram-generationSkill
- argumentation-referenceSkill
- asana-sprint-planningSkill
- asdlc-aspect-reviewSkill
- asdlc-code-simplifierSkill
- aws-service-validatorSkill
- backend-developmentSkill
- backend-reviewSkill
- claude-teams-behaviorSkill
- cmux-dispatchSkill
- code-reviewSkill
- constraintsSkill
- cost-estimationSkill
- cypress-test-implementationSkill
- decision-researchSkill
- decision-writingSkill
- delegation-protocolSkill
- deliberation-panelSkill
- design-doc-guidelinesSkill
- design-evaluationSkill
- design-impact-reviewSkill
- design-quality-checkSkill
- doc-accuracy-analyzerSkill
- document-formatsSkill
- dom-inspectionSkill
- dynamodb-designSkill
- dynamodb-validationSkill
- e2e-test-strategySkill
- external-researchSkill
- find-aws-skillsSkill
- frontend-developmentSkill
- frontend-reviewSkill
- git-mergeSkill
- git-workflowSkill
- historical-issues-registrySkill
- humanize-writingSkill
- iam-policy-designSkill
- infra-validationSkill
- kiro-design-generationSkill
- kiro-requirements-generationSkill
- kiro-task-generationSkill
- legacy-to-agentic-estimateSkill
- non-functional-requirementsSkill
- persistent-memorySkill
- plan-reviewSkill
- playwright-test-implementationSkill
- policy-validationSkill
- pre-planning-analysisSkill
- The first 60 shown.
The file
We split this skill into the rules it gives an agent
8 rules. About 0 are common, 2 are distinctive, and 6 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
6
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 19
For cmux (macOS): use the cmux-dispatch skill instead.
- Distinctive: line 23
Use this skill when:
- Very specific: line 27
NEVER: use use_subagent when a multiplexer is available — always use this skill instead
- Very specific: line 33
Run this once. It prints the skill's directory.
- Distinctive: line 50
If it exits 1, dispatch can't run: tell the user and fall back to the base orchestrator.
- Very specific: line 69
All flags documented below for tmux-dispatch.sh / zellij-dispatch.sh apply unchanged when calling them through dispatch.sh.
- Very specific: line 192
Before dispatch (read-only): check .wt-ledger.json and git worktree list (ground truth over the ledger, which can go stale) and decide …
- Very specific: line 220
Write agent's first action, before touching any file: if a worktree was named (forms 1 or 2), independently re-run git worktree list (the …
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
mux Dispatch
Runtime Selection
The orchestrator always dispatches via panes. The dispatch script selects the CLI automatically:
- Claude Code (
$CLAUDECODEis set): runsclaude --agent <PREFIX><agent-name> --dangerously-skip-permissions -p "<prompt>"in the pane, where<agent-name>is the exact value passed via--agent(e.g.k-developer). The script never strips a prefix.<PREFIX>is the package-install prefix (e.g.local-your-package-), derived by searching~/.claude/agents/for any installed agent file ending in-<agent-name>.md(local- installs preferred over registry installs, checked as separate tiers). No package name is hardcoded, so this resolves correctly for any installed package. If~/.claude/agents/has no match and the skill ships inside a Claude Code plugin whoseagents/has that agent, the bare name is launched and Claude resolves it to<plugin>:<agent>. A qualified--agent(konductor:k-developer) is launched only if the prefix is this plugin's name (from its.claude-plugin/plugin.json) and the plugin ships that agent; anything else is refused as not installed.--agentmust be a fully-qualified name. If it matches 2+ installed agent files within the same tier (e.g. a partial name likeorchestratormatching bothkonductor-mux-orchestratorandkonductor-cmux-orchestrator), the script errors and lists the candidates rather than guessing.--agentvalues are also restricted to[a-z0-9-]+, optionally prefixed with<plugin>:, before any of this runs. Completion is detected via process exit (claude -p exits on task completion); the script thentouches the.donemarker file. - kiro-cli (default): runs
kiro-cli chat --agent <agent-name> ...in the pane, using the exact--agentvalue passed in — no prefix is added or stripped. Completion is detected via the kiro-clistophook writing the.donefile.
Overview
Spawn agent sessions in tmux or zellij panes so delegated work is visible, interactive, and course-correctable in real time. Auto-detects the active multiplexer via $TMUX (tmux) or $ZELLIJ (zellij).
For cmux (macOS): use the cmux-dispatch skill instead.
Usage
Use this skill when:
- User asks to delegate, spawn, or run a task in a separate pane with a specific agent
- Running on Linux or any platform with tmux or zellij
- NEVER use
use_subagentwhen a multiplexer is available — always use this skill instead
You MUST immediately run the dispatch script without pre-checking the environment. The script handles all validation and exits with a clear error if anything is missing.
Locating dispatch.sh
Run this once. It prints the skill's directory; use that absolute path for
<MUX_DISPATCH_DIR> in every command below. A shell variable doesn't survive to the
next command.
ROOT="$(git rev-parse --show-toplevel 2>/dev/null)"
PROJECT="" CHECKOUT=""
[ -n "$ROOT" ] && [ -f "$ROOT/.konductor/manifest" ] && PROJECT="$ROOT/.konductor/skills/mux-dispatch"
[ -n "$ROOT" ] && grep -qs '"name": *"konductor"' "$ROOT/.claude-plugin/marketplace.json" && CHECKOUT="$ROOT/skills/mux-dispatch"
MUX_DISPATCH_DIR=""
for d in "${CLAUDE_SKILL_DIR}" "${SKILLS_HOME:-$HOME/.konductor/skills}/mux-dispatch" "$PROJECT" "$CHECKOUT"; do
[ -n "$d" ] && [ -f "$d/dispatch.sh" ] && { MUX_DISPATCH_DIR="$d"; break; }
done
[ -n "$MUX_DISPATCH_DIR" ] || { echo "ERROR: dispatch.sh not found; not dispatching" >&2; exit 1; }
echo "MUX_DISPATCH_DIR=$MUX_DISPATCH_DIR"If it exits 1, dispatch can't run: tell the user and fall back to the base orchestrator.
Multiplexer Detection
Always call dispatch.sh. Never detect-then-branch yourself. It detects
the active multiplexer and execs the matching backend script with your
arguments unchanged:
bash "<MUX_DISPATCH_DIR>/dispatch.sh" --agent <name> --task "..." --cwd <path>| Env var set | Backend | Script routed to |
$TMUX | tmux | tmux-dispatch.sh |
$ZELLIJ | zellij | zellij-dispatch.sh |
| Neither | — | Error + use base orchestrator (exit 1) |
All flags documented below for tmux-dispatch.sh / zellij-dispatch.sh apply
unchanged when calling them through dispatch.sh.
Dispatch Scripts
tmux-dispatch.sh
Parameters:
| Flag | Required | Description |
--agent | Yes | Agent name (e.g. k-developer) or a plugin-qualified name (konductor:k-developer). On Claude Code the install prefix is resolved as described above |
--task | Yes | Task prompt to send to the agent |
--cwd | Yes | Absolute path to project root |
--name | No | Pane/window title |
--split right|down | No | Split direction (default: right) |
--tab | No | Create a new window instead of a split |
--close | No | Auto-close pane when agent finishes (panes stay open by default; close via --close or mux-close-pane.sh) |
--interactive | No | Keep the kiro-cli session open for mid-task human interaction (kiro-cli only; Claude Code runs one-shot via -p) |
Examples:
# Delegate implementation (split right, default)
bash "<MUX_DISPATCH_DIR>/tmux-dispatch.sh" \
--agent k-developer \
--cwd /path/to/project \
--task "Implement the user authentication API endpoint"
# Side-by-side split downward
bash "<MUX_DISPATCH_DIR>/tmux-dispatch.sh" \
--agent k-architect \
--cwd /path/to/project \
--split down \
--task "Review the DynamoDB table design"zellij-dispatch.sh
Same flags as tmux-dispatch.sh. Uses env MUX_WORKSPACE_ID=... wrapper to pass the workspace ID (zellij does not support --env on new-pane).
--split stacked is zellij-only — creates a stacked pane via zellij action new-pane --stacked (no --direction; conflicts with --stacked). tmux and cmux do not support stacked panes.
bash "<MUX_DISPATCH_DIR>/zellij-dispatch.sh" \
--agent k-developer \
--cwd /path/to/project \
--task "Implement the user authentication API endpoint"
# Stacked pane (zellij only)
bash "<MUX_DISPATCH_DIR>/zellij-dispatch.sh" \
--agent k-developer \
--cwd /path/to/project \
--split stacked \
--task "Implement the user authentication API endpoint"Completion Detection
Each agent's kiro-cli stop hook writes a done file via mux-completion-hook.sh:
- Path:
/tmp/konductor-mux/<workspace-id>.done - Format:
{"workspace_id": "...", "status": "done|error", "summary": "..."}
Poll (glob-free — an unmatched *.done glob is a hard error under zsh, which
aborts the whole compound command before 2>/dev/null can apply):
find /tmp/konductor-mux -maxdepth 1 -name '*.done' 2>/dev/null
Running the dispatch script, polling, and reading result files are orchestrator direct work, as defined in the Orchestrator Direct Work table of k-orchestrator-routing-rules.md. Run them yourself; never dispatch them to another pane.
The MUX_WORKSPACE_ID env var is set per pane by the dispatch script and read by the completion hook.
Results — write to a file, don't rely on the .done summary
The .done payload's summary field is a short, often-truncated status string
(and is literally "shell fallback" when the hook didn't run and the launcher's
fallback wrote the file instead) — it is not a substitute for the deliverable.
Dispatch prompts SHOULD instruct the child agent to write its full deliverable
to a file, e.g. /tmp/konductor-mux/result-<slug>.md, and the orchestrator
should read that file once .done appears. Use a pane-content dump (see below)
only as a fallback when no result file was written or the pane exited before
producing one.
Peeking at a running pane (polling fallback, before .done appears)
Peek only when the polling fallback in the orchestrator prompt's Completion Detection section calls for it, not on every poll.
# tmux — last 10 lines of a running pane
tmux capture-pane -t <pane-id> -p | tail -10
# zellij — --path (no short form) writes the dump to a file; omitting it
# dumps to stdout, which returns empty here. -f/--full is a separate boolean
# for full scrollback, not a shorthand for --path.
# Pane IDs are NOT unique across concurrent zellij sessions, so pass the
# session name recorded in the dispatch registry (dispatched.json) alongside
# pane_id.
zellij --session <session-name> action dump-screen --pane-id <pane-id> -f --path /tmp/konductor-mux/dump-<pane-id>.txt
cat /tmp/konductor-mux/dump-<pane-id>.txtRegistry entries in /tmp/konductor-mux/dispatched.json record session
alongside pane_id for exactly this reason — always pass both when peeking.
Worktree Provisioning for Write Agents
The rule: every write-agent dispatch task must explicitly name the exact target — never let the agent infer or default. A silent default is the actual collision mechanism: two write agents (any agent that edits, creates, or deletes files) — from the same task or from different tasks — can each independently default into the same working tree and step on each other: half-applied edits, index contention, build contamination. This can happen even when neither dispatch looks "concurrent" on its own. The named target is one of three legitimate forms:
- A new dedicated worktree —
wt-<id>on branchwt-<id>(worktree and branch share one flat name), for the agent to create. - An existing worktree to reuse —
wt-<id>at<path>on branchwt-<id>. - The shared primary tree, on a named feature branch
<branch>— a deliberate, explicit choice, only for a single sequential write agent with no concurrent writer sharing that tree.
Before dispatch (read-only): check .wt-ledger.json and git worktree
list (ground truth over the ledger, which can go stale) and decide which of
the three forms applies for this task.
--cwd points at the shared primary working tree for every write-agent
dispatch, regardless of which of the three forms is named — a worktree named
under forms 1 or 2 may not exist yet at pane-launch time, and the primary
tree is guaranteed to already be a git repository, so git worktree
list/git worktree add work there with no extra cd. Pass the named
target in the dispatched task instead:
bash "<MUX_DISPATCH_DIR>/dispatch.sh" \
--agent k-developer \
--cwd <primary-working-tree> \
--task "Worktree wt-<id> already exists at <path> — cd in, do not create
a new one. [OR: No worktree exists for this task — create wt-<id>
before touching any file.]
[OR: Work directly on branch <branch> in this shared working tree
— no worktree for this task.]
Implement the feature; commit and push the branch you're on; open
a draft CR to mainline."Read-only agents (research, investigation, review) need no worktree
decision at all — they share the primary working tree by default, and
--cwd points directly at the shared tree with no target to name.
Write agent's first action, before touching any file: if a worktree was
named (forms 1 or 2), independently re-run git worktree list (the
orchestrator's read could be stale by dispatch time), then either cd into
the existing worktree or provision it — running $WORKTREE_PROVISION_CMD
wt-<id> if that variable is set in its environment, otherwise git worktree
add (see Provisioning command below). If the shared tree was named (form
3), check out the named branch there.
Provisioning command
The write agent provisions generically via git worktree add, but any
environment that has a more specific worktree tool can override this with
the WORKTREE_PROVISION_CMD environment variable. Set it in the
orchestrator's shell before dispatching — tmux-dispatch.sh and
zellij-dispatch.sh both forward it automatically into the dispatched
pane's launcher script, so no extra flag is needed:
# Default (no WORKTREE_PROVISION_CMD set): plain git worktree, landed under
# a worktrees/ folder at the repo root.
# `git rev-parse --show-toplevel` returns the repo root
# (<workspace-root>/<repo>), 1 level below <workspace-root>, so `/..` reaches
# <workspace-root>.
git worktree add -b wt-<id> "$(git rev-parse --show-toplevel)/../worktrees/wt-<id>"
# Override point — set WORKTREE_PROVISION_CMD to substitute a
# project-specific provisioning command. It is invoked as:
# $WORKTREE_PROVISION_CMD <wt-id>
# and must create (or otherwise make ready) a worktree whose directory
# name / return path corresponds to <wt-id>, landed at
# <workspace-root>/worktrees/wt-<id>.
export WORKTREE_PROVISION_CMD="<your-provisioning-command> --name"This skill documents the hook generically; it does not prescribe what
WORKTREE_PROVISION_CMD should be set to in any specific environment —
environment-specific documentation (outside this package) covers that.
Naming. Worktree and branch share one flat name, wt-<id> (hyphens
only — no slashes). Slashes in a worktree identifier can cause
directory-nesting problems in some worktree tooling (a parent path segment
getting registered as a single entry, masking children).
git worktree add checks out at exactly the path given, creating any
missing intermediate directories.
Sequential handoff is the reuse case (form 2) above, or continuing on the same named shared-tree branch (form 3) — a second write agent continuing the same task gets the same named target in its task, and resumes there. Concurrent collaboration on one target is not supported, by design — whether that target is a worktree or the shared tree, a maker/checker pair never shares it; a checker gets its own separate read-only checkout, never the maker's tree.
This is a best-effort guardrail, not a hard boundary — the agent dispatched into the pane could in principle ignore the named target. Two things provide harder enforcement after the fact:
- The pre-commit hook (husky/lint-staged, or the equivalent for this project) runs inside the tree the agent actually committed from — edits made outside the named target simply will not surface in that commit.
- The CR diff at review time shows exactly which files changed; a human reviewer catches any file that should not have been touched before merge.
Cleanup (removing the worktree and branch) happens only after the agent's draft CR has merged, and only with explicit user confirmation — this skill does not perform cleanup itself.
Best Practices
--cwdis always the shared primary working tree for write-agent dispatch — the dispatched agent acts on whichever target (new worktree, existing worktree, or the shared tree itself) is explicitly named in the task, as its first action from there; the pane launch never depends on a named worktree already existing. Read-only agents also use--cwdpointed at this same shared primary tree, with no target to name.- Default to non-interactive — agent processes task and exits
- Use --interactive for tasks needing human review (specs, design review)
- Always prefer --split (default) — keeps agents visible alongside the orchestrator; panes are auto-equalized via
tmux select-layout tiledafter each dispatch - Use --tab only for long-running background tasks unrelated to the current workflow (e.g. a background watcher, a separate service) — never just because there are many agents
- Zellij note — zellij has no equalize command; use
Alt+[arrow]to manually resize panes
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

