Install
$ agentstack add skill-davidsimoes-claude-skills-shared-delegate ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
/delegate — Spawn + cooperate with child Claude sessions
Takes a task description, opens a new Claude session in tmux pre-loaded with that task, writes a JSON registry entry for cooperation verbs, and hands the parent back a clean handle (tmux location + registry name).
Architecture: cooperation uses tmux send-keys + a JSON registry at ~/.claude/cache/delegate/.json — no MCP dependency. Works even when every MCP server is down.
Arguments: {{ arguments }}
Step 1 — Parse arguments
Accepted forms:
/delegate— spawn with defaults/delegate @ [--name ...]— use file content as the task/delegate list [--prune]— list active children (--pruneremoves dead targets)/delegate status— show child's summary + last-seen + live tail/delegate tell— send message via tmux send-keys/delegate fetch— retrieve last message received from child/delegate close— ask child to wrap up + close window
Flags on spawn:
| Flag | Default | Effect | |------|---------|--------| | --where pane\|window\|session\|worktree\|auto | auto (resolves to pane if parent's window has 1 pane, else window) | tmux placement | | --cwd | inferred from task, else current | working directory of child | | --name | auto-slug from task | tmux window name + registry filename (~/.claude/cache/delegate/.json; slug derived from --name by lowercasing + hyphenating) | | --model opus\|sonnet\|haiku | inherit (no flag) | model override | | --cooperate / --fire-and-forget | --cooperate (true) | whether child should register + message back | | --summary "" | auto | registry summary line (shown in /delegate status) | | --from-file | — | load task body from a file (alternative to inline) | | --no-prefix | (off — default uses ↳ prefix on window/pane name) | suppress visual child marker | | --color | yellow | runs /color in the child session for visual differentiation; pass --no-color to skip | | --no-color | (off) | suppress the auto-/color step | | --permission-mode | auto | sets --permission-mode on the child claude process; auto prevents prompt stalls in unwatched windows | | --no-auto | (off) | revert to claude's default permission mode (removes --permission-mode auto) |
If the user invoked with just a verb (no task body), ask what they want delegated.
Step 2 — Resolve placement
All five placements are implemented. Default: auto — resolves to pane if the calling pane's window has exactly 1 pane (clean split), else window (avoid clutter). This makes most short-lived /delegate calls land as a sibling pane in the parent's window — child output is visible at-a-glance without window switching. Heavy or multi-pane parents fall back to a new window automatically.
Manual override decision tree:
- Debugging / parallel review / side-by-side comparison → explicit
--where pane - Substantive multi-step work in a clean parent window →
autolands here aspane - Substantive multi-step work in an already-busy parent →
autolands here aswindow - Fully isolated context, different repo or life area →
--where session - Risky / sandboxed code changes →
--where worktree
When auto-resolving, tell the user what was picked + why in ONE line before spawning. ("Spawning as pane in current window since it's not split — say if you want a separate window.")
Placement-specific semantics (handled by spawn.sh):
pane:tmux split-window -h -t : -c— target session is current tmux session only. v2 also callstmux select-pane -T '↳ 'to label the pane and enablespane-border-status topso the title shows in the border.window:tmux new-window -t : -n '↳ ' -c— the↳prefix marks this as a child relative to its spawner.session:tmux new-session -d -s -n '↳ ' -c— detached; won't steal focus. Session name itself stays clean (raw ``); only the first window inside gets the prefix. Errors if session name already exists.worktree: same aswindow(with prefix), but claude is invoked withclaude -w. claude creates the git worktree itself. Errors if cwd isn't inside a git repo.
Window/session naming:
--namewins for the base name. The↳prefix is applied automatically to the tmux display name (window or pane title); the registry JSON keeps the un-prefixed name. Use--no-prefixto suppress the visual marker.- Auto-slug from task: first 4–6 significant words, Title Case, joined with spaces, capped at ~30 chars.
- For
--where session, the `is also the tmux session name, so avoid names that collide with existing sessions (tmux has-session -t ` pre-check recommended).
Step 3 — Resolve cwd
- If
--cwdprovided, validate it exists (test -d). - Else look for path hints in the task description (absolute paths,
~/...paths, or project-name keywords matching your dev-root layout — e.g.~/dev//). - Else use the parent's current cwd.
- Confirm with the user if inferred from hint — "cwd: `` — ok?"
Step 4 — Build startup prompt
Load templates/startup-prompt.md and fill placeholders:
{{TASK_BODY}}— the task description (or file contents if--from-file/@pathused){{NAME}}— the child's name (same as tmux window name / registry filename){{PARENT_TARGET}}— the parent's tmuxsession:windowname (fromtmux display-message -p '#S:#W'){{CHILD_TMUX_TARGET}}— where the child will end up (resolved after spawn; see Step 5 helper output){{CWD}}— resolved working directory{{SUMMARY}}—--summaryvalue or auto-generated from task (one line, ≤80 chars){{COOPERATE}}—trueorfalse{{SPAWNED_AT}}— ISO timestamp (date -u +%Y-%m-%dT%H:%M:%SZ){{COOPERATE_INSTRUCTIONS}}— the appropriate section ofreferences/cooperate-instructions.md(don't include both; pick one)
Write the filled prompt to a unique temp file: /tmp/delegate--.md.
Precompute {{CHILD_TMUX_TARGET}} from the parent's tmux session + the resolved placement: :↳ for window/worktree/session placements, or :. for pane (pane index is unknown pre-spawn — for pane placement, leave as the literal ` and the child can fetch its own target via tmux display-message -t "$TMUX_PANE" -p '#S:#I.#P'` if needed).
Step 5 — Launch
Call the spawn helper:
~/.claude/skills/delegate/scripts/spawn.sh \
--name "" \
--cwd "" \
--prompt-file "" \
--where "" \
[--session ""] \
[--model ""] \
[--cooperate "true|false"] \
[--worktree-name ""]
On success it emits one JSON line:
{"session":"main","window":"My Child Task","cwd":"/...","tty":"/dev/ttysNNN","pid":12345,"target":"main:My Child Task","where":"window"}
The spawn script auto-dismisses the startup interstitial:
- Trust-folder prompt — first-run "Do you trust the files in this folder?" is auto-answered with Enter (default yes).
(The dev-channels warning no longer fires since claude() dropped those flags on 2026-04-24.)
Exit codes:
- 0 → success, parse JSON and build handle
- 1 → argument error (fix and retry, don't re-spawn)
- 2 → tmux error (surface to user, don't retry automatically)
- 3 → timeout waiting for claude REPL (window/pane/session exists but REPL never rendered — surface and let user inspect)
Step 6 — Return handle to parent
After successful launch, the spawn helper has already written the initial registry JSON at ~/.claude/cache/delegate/.json (status=initializing, placeholder summary). The child updates summary + status=active on its first turn — no need to poll for it from the parent.
Use the registry field from the spawn helper's JSON output as the path. The slug is the lowercased, hyphen-joined version of ` (e.g., "Deep Delegate" → deep-delegate.json`).
Print the handle in this shape:
✓ Delegated "" to tmux :
cwd:
pid: tty:
registry: ~/.claude/cache/delegate/.json
Follow up:
- /delegate tell "" # send a message via tmux send-keys
- /delegate status "" # read registry + live tail
- /delegate fetch "" # capture-pane the latest child output
- /delegate close "" # ask child to wrap up
- tmux select-window -t "" # jump to it visually
If cooperate=false, omit the follow-up block and add: "Fire-and-forget — no registry, no tracking. Check the tmux window manually."
Step 7 — Cooperation verbs
Supported forms: /delegate list [--prune], /delegate status , /delegate tell , /delegate fetch , /delegate close .
All verbs delegate name resolution and registry I/O to scripts/registry.sh. Use it from your Bash tool — don't reimplement the logic inline.
# Show all children (human table)
~/.claude/skills/delegate/scripts/registry.sh list
# Show as JSON (for parsing)
~/.claude/skills/delegate/scripts/registry.sh list --json
# Fuzzy-resolve a name to a tmux target (exit 0 = single match; 1 = zero or ambiguous)
~/.claude/skills/delegate/scripts/registry.sh resolve ""
# Resolve with full JSON entry
~/.claude/skills/delegate/scripts/registry.sh resolve "" --json
# Status card for one child (registry data + live tail)
~/.claude/skills/delegate/scripts/registry.sh status ""
# Remove stale entries (dead tmux targets + unparseable JSON)
~/.claude/skills/delegate/scripts/registry.sh prune [--dry-run]
Verb implementations (all ` arguments get resolved first via registry.sh resolve`):
/delegate list→registry.sh list(add--jsonfor parseable output)./delegate list --prune→registry.sh prune(the prune subcommand is separate fromlist; the parent-side verb maps to it)./delegate status→registry.sh status./delegate tell→ resolve target, thentmux send-keys -t "" Enter; sleep 1; tmux send-keys -t Enter. Echo the send to the user; don't wait for reply./delegate fetch→ resolve target, thentmux capture-pane -t -p -S -300 | tail -80. Show the latest assistant response./delegate close→ resolve target, clear stray input withC-u, send/close, monitor up to 60s./closesaves the child's work but does NOT terminate the Claude process — then send/exitfor a graceful shutdown. The window auto-closes when the process exits;tmux kill-windowis a fallback only if it lingers (ask the user first). Finallyrm .json.
Full spec (edge cases, exact output formats): references/cooperation-verbs.md.
Key rules:
- Never block waiting for a reply.
/delegate tellfires and returns immediately. Use/delegate fetchto read the child's latest output. - Never force-kill a live Claude process.
/delegate closeruns/close(saves work) then/exit(graceful termination) so the window auto-closes cleanly;tmux kill-windowis a fallback for a lingering shell only, and asks the user first. - The parent's own window is auto-excluded from resolve matches.
registry.shreads$TMUX_PANEto identify the calling pane. (NOT baretmux display-message— that returns the focused pane, not the calling pane.) - Stale registry entries are ignored by resolve and flagged as
☠ stalein list. Run/delegate list --pruneto clean them up.
Design constraints
- Never auto-spawn without user intent.
/delegateis invoked explicitly. Don't auto-trigger from other skills without "y/n ok to delegate?" first. - Never respawn on child crash. If the spawn script returns code 3, surface it. Let the user inspect.
- No MCP dependency for cooperation. Verbs use tmux + the registry. They work even if every MCP server is down.
- No cross-machine. tmux is local. Fail fast if user passes a hint suggesting remote.
- Match model to task weight. If the task description implies judgment-heavy work (security, irreversible deploy, architectural decision) and no
--modelwas passed, suggest--model opusbefore spawning. For pure mechanical work, suggest--model haiku.
References
- New to tmux? Start here:
tmux-primer.md— session/window/pane in plain English, with the placement table. - Startup prompt template:
templates/startup-prompt.md - Cooperation instructions appended to child:
references/cooperate-instructions.md - Cooperation verbs full spec:
references/cooperation-verbs.md - Spawn helper:
scripts/spawn.sh - Registry helper (list / resolve / prune / status):
scripts/registry.sh
Related skills
/close— referenced by the close verb. Not bundled here; the child can still be terminated viatmux kill-windowif you don't have a similar wrap-up skill./loop— a different pattern (recurring self-ping on the current session), not parallel work.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: davidsimoes
- Source: davidsimoes/claude-skills-shared
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.