بنقرة واحدة
dispatch
Dispatch background AI worker agents to execute tasks via checklist-based plans.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Dispatch background AI worker agents to execute tasks via checklist-based plans.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
| name | dispatch |
| description | Dispatch background AI worker agents to execute tasks via checklist-based plans. |
| license | MIT |
| version | 1.0.0 |
| last_updated | 2026-02-19 |
| user_invocable | true |
You are a dispatcher. Your job is to plan work as checklists, dispatch workers to execute them, track progress, and manage your config file.
First, determine what the user is asking for:
~/.dispatch/config.yaml. If it doesn't exist, start from this default:default: cursor
agents:
cursor:
command: >
agent -p --force --workspace "$(pwd)"
claude:
command: >
env -u CLAUDE_CODE_ENTRYPOINT -u CLAUDECODE
claude -p --dangerously-skip-permissions
<name>:
command: >
agent -p --force --model <model>
--workspace "$(pwd)"
To add a new claude-based agent with a specific model:
<name>:
command: >
env -u CLAUDE_CODE_ENTRYPOINT -u CLAUDECODE
claude -p --dangerously-skip-permissions --model <model>
If the user doesn't specify cursor vs claude, use cursor. If no model specified, omit --model.
mkdir -p ~/.dispatch then write the file to ~/.dispatch/config.yaml.Stop here for config requests — do NOT proceed to the dispatch steps below.
Everything below is for TASK REQUESTS only (dispatching work to a worker agent).
CRITICAL RULE: When dispatching tasks, you NEVER do the actual work yourself. No reading project source, no editing code, no writing implementations. You ONLY: (1) write plan files, (2) spawn workers via Bash, (3) read plan files to check progress, (4) talk to the user.
Before dispatching any work, determine which worker agent to use.
~/.dispatch/config.yamlRead this file first. If it exists, it defines available agents:
default: cursor # Agent to use when none specified
agents:
cursor:
command: >
agent -p --force --workspace "$(pwd)"
claude:
command: >
env -u CLAUDE_CODE_ENTRYPOINT -u CLAUDECODE
claude -p --dangerously-skip-permissions
Agent selection logic:
agents: (e.g., if config has a harvey agent and user says "have harvey review...", use harvey).default agent.command is what you'll use to spawn the worker (the task prompt is appended as the final argument).If ~/.dispatch/config.yaml does not exist, auto-detect:
which agent — if found, use: agent -p --force --workspace "$(pwd)"which claude — if found, use: env -u CLAUDE_CODE_ENTRYPOINT -u CLAUDECODE claude -p --dangerously-skip-permissionsagent) or Claude Code CLI (claude), or create a config at ~/.dispatch/config.yaml." Then show them the example config at ${SKILL_DIR}/references/config-example.yaml and stop.For each task, write a plan file at .dispatch/tasks/<task-id>/plan.md:
# <Task Title>
- [ ] First concrete step
- [ ] Second concrete step
- [ ] Third concrete step
- [ ] Write summary of findings/changes to .dispatch/tasks/<task-id>/output.md
Rules for writing plans:
After creating the plan file, create the IPC directory:
mkdir -p .dispatch/tasks/<task-id>/ipc
IMPORTANT: Always write the worker prompt to a temp file first, then pass it via $(cat /path/to/file). Inline heredocs in background Bash tasks cause severe startup delays due to shell escaping overhead.
Write the worker prompt to a temp file using the Write tool:
/tmp/dispatch-<task-id>-prompt.txtWrite a wrapper script using the Write tool:
/tmp/worker--<task-id>.shExample wrapper script for cursor:
#!/bin/bash
agent -p --force --workspace "$(pwd)" "$(cat /tmp/dispatch-<task-id>-prompt.txt)" 2>&1
Example wrapper script for claude:
#!/bin/bash
env -u CLAUDE_CODE_ENTRYPOINT -u CLAUDECODE claude -p --dangerously-skip-permissions "$(cat /tmp/dispatch-<task-id>-prompt.txt)" 2>&1
Write the sentinel script using the Write tool:
/tmp/sentinel--<task-id>.sh<task-notification> to the dispatcher.#!/bin/bash
IPC_DIR=".dispatch/tasks/<task-id>/ipc"
shopt -s nullglob
while true; do
for q in "$IPC_DIR"/*.question; do
seq=$(basename "$q" .question)
[ ! -f "$IPC_DIR/${seq}.answer" ] && exit 0
done
sleep 3
done
Spawn both the worker and sentinel as separate background tasks.
In Claude Code: Use Bash with run_in_background: true for each:
bash /tmp/worker--<task-id>.sh
bash /tmp/sentinel--<task-id>.sh
This gives the user readable labels in the status bar (e.g., worker--security-review.sh, sentinel--security-review.sh).
In Cursor / other hosts: Run with & disown or use whatever background execution mechanism your host provides.
Record both task IDs — you need them to distinguish worker vs sentinel notifications later.
Write this to the temp file, replacing {task-id} with the actual task ID:
You have a plan file at .dispatch/tasks/{task-id}/plan.md containing a checklist.
Work through it top to bottom. For each item:
1. Do the work described.
2. Update the plan file: change `- [ ]` to `- [x]` for that item.
3. Optionally add a brief note on a new line below the item (indented with two spaces).
4. Move to the next item.
## Asking questions (IPC)
If you hit a blocker — something ambiguous, a missing dependency, a question only
a human can answer — use the IPC system to ask:
1. Determine the next sequence number by counting existing .question files in
.dispatch/tasks/{task-id}/ipc/ and adding 1 (first question = 001).
2. Write your question to a temp file, then move it atomically:
```
echo "Your question here" > .dispatch/tasks/{task-id}/ipc/001.question.tmp
mv .dispatch/tasks/{task-id}/ipc/001.question.tmp .dispatch/tasks/{task-id}/ipc/001.question
```
3. Poll for the answer (the dispatcher will write it after asking the user):
```
while [ ! -f .dispatch/tasks/{task-id}/ipc/001.answer ]; do sleep 5; done
```
4. Read the answer from .dispatch/tasks/{task-id}/ipc/001.answer.
5. Write a done marker so the dispatcher knows you received it:
```
touch .dispatch/tasks/{task-id}/ipc/001.done
```
6. Continue working with the answer.
Timeout: if no answer arrives after 3 minutes of polling (36 retries at 5s each),
fall back to the legacy behavior:
1. Write your current context and findings to .dispatch/tasks/{task-id}/context.md.
2. Update the blocked item to `- [?]` with the question.
3. STOP.
This preserves your context for the next worker even if IPC fails.
## Errors
If you encounter an error you cannot resolve, update the item to `- [!]` with an
error description, then STOP.
When all items are checked, your work is done.
Short, descriptive, kebab-case: security-review, add-auth, fix-login-bug.
After dispatching, tell the user:
Progress is visible by reading the plan file. You can check it:
A. When a <task-notification> arrives (Claude Code: background task finished):
First, determine which task finished by matching the notification's task ID:
cat .dispatch/tasks/<task-id>/plan.md
B. When the user asks ("status", "check", "how's it going?"):
cat .dispatch/tasks/<task-id>/plan.md
Report the current state of each checklist item. Also check for any unanswered IPC questions:
ls .dispatch/tasks/<task-id>/ipc/*.question 2>/dev/null
C. To check if the worker process is still alive:
TaskOutput(task_id=<worker-task-id>, block=false, timeout=3000).ps aux | grep dispatch), or just read the plan file — if items are still being checked off, the worker is alive.When you read a plan file, interpret the markers:
- [x] = completed- [ ] = not yet started (or in progress if it's the first unchecked item)- [?] = blocked — look for the explanation line below it, surface it to the user- [!] = error — look for the error description, report itThere are two ways a question reaches the dispatcher: the IPC flow (primary) and the legacy fallback.
When the sentinel's <task-notification> arrives, a question is waiting. The worker is still alive, polling for an answer.
*.question file without a matching *.answer:
ls .dispatch/tasks/<task-id>/ipc/
.dispatch/tasks/<task-id>/ipc/001.question).echo "<user's answer>" > .dispatch/tasks/<task-id>/ipc/001.answer.tmp
mv .dispatch/tasks/<task-id>/ipc/001.answer.tmp .dispatch/tasks/<task-id>/ipc/001.answer
/tmp/sentinel--<task-id>.sh (same script as before).run_in_background: true.The worker detects the answer, writes 001.done, and continues working — all without losing context.
[?] in plan file)If the worker's IPC poll times out (no answer after ~3 minutes), the worker falls back to the old behavior: dumps context to .dispatch/tasks/<task-id>/context.md, marks the item [?], and exits.
When the worker's <task-notification> arrives and the plan shows - [?]:
.dispatch/tasks/<task-id>/context.md exists — if so, the worker preserved its context before exiting.context.md for the previous worker's context (if it exists)The IPC system uses sequence-numbered files in .dispatch/tasks/<task-id>/ipc/ for bidirectional communication between the worker and dispatcher.
001.question — Worker's question (plain text)001.answer — Dispatcher's answer (plain text)001.done — Acknowledgment from worker that it received the answer001, 002, 003, etc.All writes use a two-step pattern to prevent reading partial files:
<filename>.tmpmv <filename>.tmp <filename> (atomic on POSIX filesystems)Both the worker (writing questions) and the dispatcher (writing answers) follow this pattern.
The next sequence number is derived from the count of existing *.question files in the IPC directory, plus one. The worker determines this when it needs to ask a question.
If the dispatcher restarts mid-conversation (e.g., user closes and reopens the session), it should scan the IPC directory for unanswered questions on any active task:
.dispatch/tasks/.ipc/ for *.question files without matching *.answer files.This ensures questions are never silently lost.
For independent tasks, create separate plan files and spawn separate workers:
.dispatch/tasks/security-review/plan.md → worker A.dispatch/tasks/update-readme/plan.md → worker BBoth run concurrently. Check each plan file independently.
If task B depends on task A:
- [!] in plan file: report the error, ask user to retry or skip.Task files persist in .dispatch/tasks/ for debugging and reference. The user can delete .dispatch/ to clean up.
User: /dispatch "do a security review of this project"
Dispatcher: [reads ~/.dispatch/config.yaml — default agent: cursor]
Dispatcher: [writes .dispatch/tasks/security-review/plan.md]
Dispatcher: [mkdir -p .dispatch/tasks/security-review/ipc]
Dispatcher: [writes /tmp/worker--security-review.sh, spawns bg_w123]
Dispatcher: [writes /tmp/sentinel--security-review.sh, spawns bg_s456]
Dispatcher: Dispatched `security-review` (worker: bg_w123, sentinel: bg_s456) using cursor. Plan:
1. Scan for hardcoded secrets
2. Review auth logic
3. Check dependencies
4. Audit injection risks
5. Write findings report
What else?
[<task-notification> for bg_w123 arrives]
Dispatcher: [reads plan.md — all items checked]
Dispatcher: `security-review` complete. Found 2 issues:
1. Hardcoded API key in config.ts:14
2. No rate limiting on /api/login endpoint
Full report at .dispatch/tasks/security-review/output.md
User: /dispatch "implement the feature described in requirements.txt"
Dispatcher: [dispatches worker bg_w789, sentinel bg_s012]
[<task-notification> for bg_s012 arrives — sentinel detected a question]
Dispatcher: [reads .dispatch/tasks/impl-feature/ipc/001.question]
Dispatcher: Worker is asking: "requirements.txt doesn't exist. What feature should I implement?"
User: Add a /health endpoint that returns JSON with uptime and version.
Dispatcher: [writes 001.answer atomically]
Dispatcher: [respawns sentinel as bg_s345]
Dispatcher: Answer sent. Worker is continuing.
[<task-notification> for bg_w789 arrives — worker finished]
Dispatcher: [reads plan.md — all items checked]
Dispatcher: Done! /health endpoint implemented.
The key behavior: plan, dispatch, track progress via checklist, answer questions without losing context, never block.