@pruddiman/dispatch 1.4.4 → 1.5.0-beta.07e10a8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "@pruddiman/dispatch",
3
- "version": "1.4.4",
3
+ "version": "1.5.0-beta.07e10a8",
4
4
  "description": "AI agent orchestration CLI — parse markdown task files, dispatch each unit of work to code agents (OpenCode, GitHub Copilot, etc.), and commit results with conventional commits",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "dispatch": "dist/cli.js"
8
8
  },
9
9
  "files": [
10
- "dist"
10
+ "dist",
11
+ "skills"
11
12
  ],
12
13
  "scripts": {
13
14
  "build": "tsup",
@@ -27,7 +28,8 @@
27
28
  "orchestration",
28
29
  "dispatch",
29
30
  "tasks",
30
- "markdown"
31
+ "markdown",
32
+ "beta"
31
33
  ],
32
34
  "license": "MIT",
33
35
  "repository": {
@@ -43,23 +45,33 @@
43
45
  "node": ">=20.12.0"
44
46
  },
45
47
  "dependencies": {
46
- "@anthropic-ai/claude-agent-sdk": "^0.2.63",
48
+ "@anthropic-ai/claude-agent-sdk": "^0.2.98",
47
49
  "@azure/identity": "^4.13.0",
48
- "@inquirer/prompts": "^8.3.0",
50
+ "@github/copilot-sdk": "^0.2.1",
51
+ "@modelcontextprotocol/sdk": "^1.29.0",
49
52
  "@octokit/auth-oauth-device": "^7.1.5",
50
53
  "@octokit/rest": "^21.1.1",
51
- "@openai/codex": "^0.1.0",
52
- "@opencode-ai/sdk": "^1.2.10",
54
+ "@openai/codex-sdk": "^0.118.0",
55
+ "@opencode-ai/sdk": "^1.4.2",
53
56
  "azure-devops-node-api": "^14.1.0",
57
+ "better-sqlite3": "^12.8.0",
54
58
  "chalk": "^5.4.1",
55
59
  "commander": "^14.0.3",
56
60
  "glob": "^11.0.1",
57
- "open": "^10.2.0"
61
+ "ink": "^6.0.0",
62
+ "ink-select-input": "^6.0.0",
63
+ "ink-spinner": "^5.0.0",
64
+ "ink-text-input": "^6.0.0",
65
+ "open": "^10.2.0",
66
+ "react": "^19.0.0",
67
+ "zod": "^4.3.6"
58
68
  },
59
69
  "devDependencies": {
60
- "@github/copilot-sdk": "^0.1.32",
70
+ "@types/better-sqlite3": "^7.6.13",
61
71
  "@types/node": "^22.13.4",
72
+ "@types/react": "^19.0.0",
62
73
  "@vitest/coverage-v8": "^4.0.18",
74
+ "ink-testing-library": "^4.0.0",
63
75
  "semantic-release": "^25.0.3",
64
76
  "tsup": "^8.4.0",
65
77
  "typescript": "^5.7.3",
@@ -0,0 +1,144 @@
1
+ ---
2
+ name: dispatch
3
+ description: >
4
+ Orchestrate work using the Dispatch MCP server (@pruddiman/dispatch). Use when the
5
+ user wants to spec issues, dispatch tasks, plan execution order, manage
6
+ dependencies between issues, or run any dispatch operation. Covers correct
7
+ spec ordering, dependency analysis, and the spec-plan-execute pipeline.
8
+ metadata:
9
+ author: pruddiman
10
+ version: "2.1.0"
11
+ license: MIT
12
+ ---
13
+
14
+ # Dispatch Orchestration
15
+
16
+ Dispatch turns issues into working code: fetch work items → generate structured specs → plan and execute tasks in isolated AI sessions → commit and open PRs.
17
+
18
+ **Pipeline:** Issues → `spec_generate` → Spec files → `dispatch_run` → Plan → Execute → Commit/PR
19
+
20
+ Use MCP tools directly. Do not shell out to the `dispatch` CLI.
21
+
22
+ ## MCP Tool Reference
23
+
24
+ | Category | Tool | What it does |
25
+ |---|---|---|
26
+ | **Spec** | `spec_generate` | Generate spec files from issue IDs, glob pattern, or inline text |
27
+ | | `spec_list` | List spec files in `.dispatch/specs/` |
28
+ | | `spec_read` | Read a spec file's contents |
29
+ | | `spec_runs_list` | List recent spec generation runs |
30
+ | | `spec_run_status` | Get status of a specific spec run by runId |
31
+ | **Dispatch** | `dispatch_run` | Execute dispatch pipeline for one or more issues |
32
+ | | `dispatch_dry_run` | Preview tasks without executing (synchronous) |
33
+ | **Monitor** | `status_get` | Get run status and per-task details by runId |
34
+ | | `runs_list` | List recent dispatch runs (filter by status) |
35
+ | | `issues_list` | List open issues from the configured datasource |
36
+ | | `issues_fetch` | Fetch full details for specific issues |
37
+ | **Recovery** | `run_retry` | Re-run all failed tasks from a previous run |
38
+ | | `task_retry` | Retry a single failed task by taskId |
39
+ | **Config** | `config_get` | Read the current Dispatch configuration |
40
+
41
+ ## Async Pattern — runId + Polling
42
+
43
+ `spec_generate` and `dispatch_run` are **fire-and-forget**: they return a `runId` immediately; progress arrives as logging notifications.
44
+
45
+ **Always poll for completion before moving to the next step:**
46
+
47
+ ```
48
+ # After spec_generate
49
+ loop: status = spec_run_status({ runId }); break if status.status in ["completed","failed"]
50
+
51
+ # After dispatch_run
52
+ loop: status = status_get({ runId }); break if status.run.status in ["completed","failed"]
53
+ ```
54
+
55
+ `dispatch_dry_run` is synchronous — returns results directly, no runId.
56
+
57
+ ## Pipeline Phases
58
+
59
+ | Phase | When to use |
60
+ |---|---|
61
+ | `spec_generate` | Issue is vague/complex, needs task breakdown, or involves multiple agents. Skip if a good spec already exists. |
62
+ | Planning (default) | Complex tasks, unfamiliar code, refactors. Skip with `noPlan: true` for mechanical/obvious changes. |
63
+ | `dispatch_dry_run` | Always dry-run before dispatching an unfamiliar spec to verify task count and ordering. |
64
+
65
+ ## Spec Ordering — The Core Discipline
66
+
67
+ **This is the most critical part of using Dispatch correctly.**
68
+
69
+ ### The Rule
70
+
71
+ **Never spec an issue whose prerequisites have not been fully implemented and merged.**
72
+
73
+ The spec agent explores the *current* codebase. If issue B depends on code that issue A creates, and A hasn't been executed yet, B's spec will be wrong — written against a codebase missing B's foundations. A spec that exists for A is not enough; A must be fully executed and its code present on disk.
74
+
75
+ ### Dependency Analysis
76
+
77
+ Before speccing anything:
78
+
79
+ 1. `issues_list` → `issues_fetch` to read all issue descriptions.
80
+ 2. Map dependencies: if B imports or calls something A creates, B depends on A.
81
+ 3. Group into layers: Layer 0 = no deps. Layer 1 = depends on layer 0. Etc.
82
+ 4. Independent issues within a layer can be specced and executed concurrently.
83
+
84
+ ### Execution Pattern
85
+
86
+ ```
87
+ Layer 0 (no deps): spec_generate → poll → dispatch_run → poll
88
+
89
+ Layer 1 (needs 0): spec_generate → poll → dispatch_run → poll
90
+
91
+ Layer 2 (needs 1): spec_generate → poll → dispatch_run → poll
92
+ ```
93
+
94
+ Spec layer N only after layer N-1 is **executed and complete** — not just specced.
95
+
96
+ ### Concrete Example
97
+
98
+ ```
99
+ Issues: #10 user model, #11 user API (needs #10), #12 admin dashboard (needs #11)
100
+ #20 logging (independent), #21 request tracing (needs #20)
101
+
102
+ Layer 0: #10, #20 → spec + dispatch together (concurrent, no prerequisites)
103
+ Layer 1: #11, #21 → spec + dispatch after layer 0 done (concurrent within layer)
104
+ Layer 2: #12 → spec + dispatch after layer 1 done
105
+ ```
106
+
107
+ ### Anti-Patterns
108
+
109
+ ```
110
+ # BAD: speccing everything at once — #11's spec references code that doesn't exist yet
111
+ spec_generate({ issues: "10,11,12,20,21" })
112
+
113
+ # BAD: not waiting for spec before dispatch — spec may still be running
114
+ rid = spec_generate({ issues: "42" }); dispatch_run({ issueIds: ["42"] })
115
+
116
+ # BAD: speccing layer 1 before layer 0 is executed — spec alone is not enough
117
+ spec_generate({ issues: "10" })
118
+ spec_generate({ issues: "11" }) # WRONG: #10's code doesn't exist yet
119
+ ```
120
+
121
+ ### Pre-Spec Checklist
122
+
123
+ Before calling `spec_generate` on any issue:
124
+
125
+ 1. What code does it depend on? (imports, APIs, schemas, utilities)
126
+ 2. Does that code exist in the codebase *right now*? (verify with grep/glob)
127
+ 3. If not — which issue creates it? Execute that issue first, fully.
128
+ 4. Are there other issues at the same dependency layer? Spec them together.
129
+
130
+ ## Task Ordering Inside Specs
131
+
132
+ `spec_generate` tags tasks automatically. You do not write P/S/I tags — understand them to read generated specs:
133
+
134
+ - `(P)` **Parallel-safe** — runs concurrently with adjacent `(P)` tasks
135
+ - `(S)` **Serial/dependent** — waits for all prior tasks, then runs alone (caps the current group)
136
+ - `(I)` **Isolated/barrier** — runs completely alone; used for validation steps (tests, lint, build)
137
+
138
+ See [references/ordering-reference.md](references/ordering-reference.md) for the full grouping algorithm and edge cases.
139
+
140
+ ## References
141
+
142
+ - [references/workflow-recipes.md](references/workflow-recipes.md) — single issue, multi-issue, retry, and feature-branch recipes
143
+ - [references/ordering-reference.md](references/ordering-reference.md) — P/S/I grouping algorithm with walkthrough examples
144
+ - [references/troubleshooting.md](references/troubleshooting.md) — symptom/cause/fix for common failures
@@ -0,0 +1,215 @@
1
+ # P/S/I Ordering Reference
2
+
3
+ Detailed reference for Dispatch's task grouping algorithm and execution ordering.
4
+
5
+ ## The `groupTasksByMode()` Algorithm
6
+
7
+ The algorithm in `src/parser.ts` converts a flat list of tagged tasks into ordered execution groups:
8
+
9
+ ```
10
+ Input: flat list of tasks, each with mode: "parallel" | "serial" | "isolated"
11
+ Output: array of groups (Task[][]), executed sequentially
12
+ ```
13
+
14
+ **Rules:**
15
+
16
+ 1. **Parallel `(P)`** — accumulate into the current group
17
+ 2. **Serial `(S)`** — append to the current group, then start a new empty group (acts as a "cap")
18
+ 3. **Isolated `(I)`** — flush any accumulated tasks as their own group, then create a solo group for the isolated task
19
+
20
+ After processing all tasks, any remaining accumulated parallel tasks form a final group.
21
+
22
+ ## Walkthrough Examples
23
+
24
+ ### Example 1: Mixed modes
25
+
26
+ ```markdown
27
+ - [ ] (P) Task A
28
+ - [ ] (P) Task B
29
+ - [ ] (S) Task C
30
+ - [ ] (P) Task D
31
+ - [ ] (P) Task E
32
+ - [ ] (I) Task F
33
+ - [ ] (P) Task G
34
+ ```
35
+
36
+ **Step-by-step:**
37
+
38
+ | Task | Mode | Action | Current group | Groups so far |
39
+ |------|------|--------|--------------|---------------|
40
+ | A | P | accumulate | [A] | [] |
41
+ | B | P | accumulate | [A, B] | [] |
42
+ | C | S | cap group | [] | [[A, B, C]] |
43
+ | D | P | accumulate | [D] | [[A, B, C]] |
44
+ | E | P | accumulate | [D, E] | [[A, B, C]] |
45
+ | F | I | flush + solo | [] | [[A, B, C], [D, E], [F]] |
46
+ | G | P | accumulate | [G] | [[A, B, C], [D, E], [F]] |
47
+ | end | — | flush remaining | [] | [[A, B, C], [D, E], [F], [G]] |
48
+
49
+ **Result:** `[[A, B, C], [D, E], [F], [G]]`
50
+
51
+ **Execution:**
52
+ 1. A, B run concurrently → C runs (S caps the group, so C waits for A and B)
53
+ 2. D, E run concurrently
54
+ 3. F runs alone (isolated)
55
+ 4. G runs alone (only task in its group)
56
+
57
+ ### Example 2: All parallel
58
+
59
+ ```markdown
60
+ - [ ] (P) Task A
61
+ - [ ] (P) Task B
62
+ - [ ] (P) Task C
63
+ ```
64
+
65
+ **Result:** `[[A, B, C]]` — all three run concurrently in one group.
66
+
67
+ ### Example 3: All serial
68
+
69
+ ```markdown
70
+ - [ ] (S) Task A
71
+ - [ ] (S) Task B
72
+ - [ ] (S) Task C
73
+ ```
74
+
75
+ **Result:** `[[A], [B], [C]]` — each runs alone, sequentially.
76
+
77
+ ### Example 4: Parallel then isolated validation
78
+
79
+ ```markdown
80
+ - [ ] (P) Implement feature module
81
+ - [ ] (P) Write unit tests for feature
82
+ - [ ] (P) Update documentation
83
+ - [ ] (I) Run full test suite
84
+ - [ ] (I) Run linter
85
+ ```
86
+
87
+ **Result:** `[[module, tests, docs], [test suite], [linter]]`
88
+
89
+ **Execution:**
90
+ 1. Module, tests, and docs all run concurrently
91
+ 2. Full test suite runs alone
92
+ 3. Linter runs alone
93
+
94
+ ### Example 5: Serial dependency chain
95
+
96
+ ```markdown
97
+ - [ ] (P) Create database schema migration
98
+ - [ ] (P) Add seed data script
99
+ - [ ] (S) Run migration and seed the database
100
+ - [ ] (P) Implement API endpoints using new schema
101
+ - [ ] (P) Write API integration tests
102
+ - [ ] (I) Run all tests
103
+ ```
104
+
105
+ **Result:** `[[schema, seed, run migration], [endpoints, tests], [run all tests]]`
106
+
107
+ **Execution:**
108
+ 1. Schema and seed created concurrently, then migration runs (S caps)
109
+ 2. Endpoints and tests written concurrently (safe — schema exists now)
110
+ 3. Full test suite runs alone
111
+
112
+ ### Example 6: Isolated as a phase gate
113
+
114
+ ```markdown
115
+ - [ ] (P) Refactor module A
116
+ - [ ] (P) Refactor module B
117
+ - [ ] (I) Run tests to verify refactors
118
+ - [ ] (P) Update module C (imports from A and B)
119
+ - [ ] (P) Update module D (imports from A and B)
120
+ - [ ] (I) Run final test suite
121
+ ```
122
+
123
+ **Result:** `[[A, B], [verify], [C, D], [final tests]]`
124
+
125
+ The first `(I)` acts as a phase gate — it verifies the refactors before dependent work begins.
126
+
127
+ ## Edge Cases
128
+
129
+ ### Single task
130
+
131
+ ```markdown
132
+ - [ ] (P) Only task
133
+ ```
134
+
135
+ **Result:** `[[Only task]]` — works fine regardless of mode prefix.
136
+
137
+ ### Serial followed immediately by parallel
138
+
139
+ ```markdown
140
+ - [ ] (S) Setup step
141
+ - [ ] (P) Task A
142
+ - [ ] (P) Task B
143
+ ```
144
+
145
+ **Result:** `[[Setup step], [A, B]]` — serial creates its own group, then parallel tasks accumulate.
146
+
147
+ ### Isolated at the very start
148
+
149
+ ```markdown
150
+ - [ ] (I) Clean build artifacts
151
+ - [ ] (P) Task A
152
+ - [ ] (P) Task B
153
+ ```
154
+
155
+ **Result:** `[[Clean], [A, B]]` — isolated runs first (no prior tasks to flush), then parallel group.
156
+
157
+ ### No mode prefix (defaults to serial)
158
+
159
+ ```markdown
160
+ - [ ] Task without prefix
161
+ - [ ] (P) Parallel task
162
+ ```
163
+
164
+ **Result:** `[[no-prefix, parallel]]` — the untagged task is treated as serial, which caps the group after it. But since the parallel task follows, it starts a new group... Actually: the untagged task (serial) starts accumulating, the `(P)` task accumulates into the same group. Then `(S)` caps — but there's no `(S)`. The untagged task is serial, so it caps immediately: `[[no-prefix], [parallel]]`.
165
+
166
+ **Takeaway:** Always tag explicitly. Untagged = serial = immediate group cap.
167
+
168
+ ## Common Patterns
169
+
170
+ ### The "implement then validate" pattern
171
+ ```markdown
172
+ - [ ] (P) Implement feature X
173
+ - [ ] (P) Implement feature Y
174
+ - [ ] (I) Run tests
175
+ ```
176
+ Best for: independent features that need a shared validation gate.
177
+
178
+ ### The "foundation then consumers" pattern
179
+ ```markdown
180
+ - [ ] (S) Create shared utility/interface
181
+ - [ ] (P) Consumer A uses the utility
182
+ - [ ] (P) Consumer B uses the utility
183
+ - [ ] (I) Run tests
184
+ ```
185
+ Best for: creating something that multiple subsequent tasks depend on.
186
+
187
+ ### The "phased rollout" pattern
188
+ ```markdown
189
+ - [ ] (P) Phase 1 task A
190
+ - [ ] (P) Phase 1 task B
191
+ - [ ] (I) Verify phase 1
192
+ - [ ] (P) Phase 2 task A (depends on phase 1)
193
+ - [ ] (P) Phase 2 task B (depends on phase 1)
194
+ - [ ] (I) Verify phase 2
195
+ ```
196
+ Best for: large changes that need intermediate verification.
197
+
198
+ ### The "all parallel" pattern
199
+ ```markdown
200
+ - [ ] (P) Independent change A
201
+ - [ ] (P) Independent change B
202
+ - [ ] (P) Independent change C
203
+ - [ ] (I) Run tests
204
+ ```
205
+ Best for: maximum throughput when all tasks are truly independent.
206
+
207
+ ## Troubleshooting
208
+
209
+ | Symptom | Likely cause | Diagnostic | Fix |
210
+ |---|---|---|---|
211
+ | Task reads a file that doesn't exist | Task should be `(S)` not `(P)` — it ran before the task that creates the file | Check which prior task creates the file | Move the dependent task after its prerequisite with `(S)` |
212
+ | File has conflicts or garbled content | Two `(P)` tasks in the same group wrote to the same file | Check task descriptions for shared file targets | Make one task `(S)` after the other |
213
+ | Tasks run slower than expected | Too many `(S)` tags killing parallelism | Count `(P)` vs `(S)` tags — most tasks should be `(P)` | Audit each `(S)` for genuine dependency |
214
+ | Isolated task fails | Prior parallel tasks didn't complete correctly | Check logs for failures in the preceding group | Fix the failing task; `(I)` correctly waited for it |
215
+ | Wrong execution order | Misunderstanding of how `(S)` caps groups | Use `--dry-run` to preview grouping | Reorder tasks and re-tag |
@@ -0,0 +1,34 @@
1
+ # Troubleshooting
2
+
3
+ ## Dispatch / Spec Failures
4
+
5
+ | Symptom | Cause | Fix |
6
+ |---|---|---|
7
+ | Spec references code that doesn't exist | Prerequisite issue hasn't been executed | Execute the prerequisite first, then call `spec_generate` again |
8
+ | `dispatch_run` tasks fail — "file not found" or "symbol not found" | Task depends on code from a prior issue that isn't done | Execute issues in dependency order; re-spec if needed |
9
+ | Spec quality is poor / tasks seem wrong | Spec was generated before prerequisite code existed | Execute prerequisites, then `spec_generate` the issue again |
10
+ | Planner times out | Complex task or slow codebase exploration | Pass `planTimeout` (minutes) to `dispatch_run`, or `noPlan: true` for simpler tasks |
11
+ | Too slow — everything sequential | Independent issues dispatched one at a time | Identify independent issues and spec/execute with `concurrency` > 1 |
12
+ | `spec_run_status` shows `failed` | Spec pipeline error | Check `error` field in status response; re-run `spec_generate` |
13
+ | `status_get` shows tasks stuck in `running` | Agent hung | Use `run_retry` to re-run; check logs via logging notifications |
14
+ | Dispatched before spec finished | Polling skipped between `spec_generate` and `dispatch_run` | Always poll `spec_run_status` to `completed` before calling `dispatch_run` |
15
+
16
+ ## Task Ordering Issues (Inside Specs)
17
+
18
+ | Symptom | Likely cause | Fix |
19
+ |---|---|---|
20
+ | Task reads a file that doesn't exist | Task ran in parallel before the task that creates the file | The task should be `(S)` not `(P)` — report to spec author or regenerate |
21
+ | File has conflicts or garbled content | Two `(P)` tasks wrote to the same file concurrently | One task needs to be `(S)` after the other |
22
+ | Tasks run slower than expected | Too many `(S)` tags killing parallelism | Audit each `(S)` — most tasks should be `(P)` |
23
+ | Isolated task fails | Prior parallel tasks didn't complete correctly | Fix the failing task; `(I)` correctly waited for it |
24
+ | Wrong execution order | Misunderstanding of how `(S)` caps groups | Use `dispatch_dry_run` to preview grouping before executing |
25
+
26
+ ## Dependency Order Violations
27
+
28
+ These produce subtle, hard-to-debug failures. When in doubt, verify with `issues_fetch` and grep/glob the codebase before speccing.
29
+
30
+ | Scenario | What goes wrong | Correct action |
31
+ |---|---|---|
32
+ | Specced B before A is executed | B's spec is written against missing code; tasks will fail or be wrong | Execute A fully, then `spec_generate` B |
33
+ | Specced A and B together (B depends on A) | B's spec has no A code to reference | Spec them in separate layers |
34
+ | Re-specced an issue after its dependency changed | Spec may now be stale | Re-spec again after verifying dependencies exist |
@@ -0,0 +1,105 @@
1
+ # Workflow Recipes
2
+
3
+ Common dispatch workflows. All async tools require polling — see SKILL.md for the polling pattern.
4
+
5
+ ## Single Issue — Full Pipeline
6
+
7
+ ```
8
+ # 1. Generate spec
9
+ rid_spec = spec_generate({ issues: "42" })
10
+ poll spec_run_status({ runId: rid_spec }) until completed
11
+
12
+ # 2. Review the spec (optional but recommended)
13
+ spec_list({})
14
+ spec_read({ file: "42-my-issue.md" })
15
+
16
+ # 3. Preview tasks (optional but recommended for unfamiliar specs)
17
+ dispatch_dry_run({ issueIds: ["42"] })
18
+
19
+ # 4. Execute
20
+ rid_run = dispatch_run({ issueIds: ["42"] })
21
+ poll status_get({ runId: rid_run }) until completed
22
+ ```
23
+
24
+ ## Multiple Independent Issues
25
+
26
+ ```
27
+ # Spec all at once (safe — no dependencies between them)
28
+ rid_spec = spec_generate({ issues: "42,43,44" })
29
+ poll spec_run_status({ runId: rid_spec }) until completed
30
+
31
+ # Execute concurrently
32
+ rid_run = dispatch_run({ issueIds: ["42", "43", "44"], concurrency: 3 })
33
+ poll status_get({ runId: rid_run }) until completed
34
+ ```
35
+
36
+ ## Dependent Issue Chain
37
+
38
+ ```
39
+ # Layer 0 — no dependencies
40
+ rid_s0 = spec_generate({ issues: "42" })
41
+ poll spec_run_status({ runId: rid_s0 }) until completed
42
+ rid_r0 = dispatch_run({ issueIds: ["42"] })
43
+ poll status_get({ runId: rid_r0 }) until completed
44
+
45
+ # Layer 1 — safe now that #42 is implemented and its code exists
46
+ rid_s1 = spec_generate({ issues: "43" })
47
+ poll spec_run_status({ runId: rid_s1 }) until completed
48
+ rid_r1 = dispatch_run({ issueIds: ["43"] })
49
+ poll status_get({ runId: rid_r1 }) until completed
50
+ ```
51
+
52
+ ## Regenerate a Spec (Respec)
53
+
54
+ ```
55
+ # Call spec_generate again — it overwrites the existing spec file
56
+ rid = spec_generate({ issues: "42" })
57
+ poll spec_run_status({ runId: rid }) until completed
58
+ ```
59
+
60
+ Use this when prerequisite code has changed or the original spec was generated too early.
61
+
62
+ ## Skip Planning (Simple Tasks)
63
+
64
+ ```
65
+ rid = dispatch_run({ issueIds: ["42"], noPlan: true })
66
+ poll status_get({ runId: rid }) until completed
67
+ ```
68
+
69
+ Good for: typo fixes, config changes, adding a single obvious field.
70
+
71
+ ## From Inline Description (No Issue)
72
+
73
+ ```
74
+ rid = spec_generate({ issues: "add dark mode toggle to settings page" })
75
+ poll spec_run_status({ runId: rid }) until completed
76
+ # then dispatch as normal
77
+ ```
78
+
79
+ ## Retry Failed Tasks
80
+
81
+ ```
82
+ # Inspect the failure
83
+ status = status_get({ runId: "abc-123" })
84
+
85
+ # Retry all failures in the run
86
+ rid_retry = run_retry({ runId: "abc-123" })
87
+ poll status_get({ runId: rid_retry }) until completed
88
+
89
+ # Or retry a single specific task
90
+ rid_task = task_retry({ runId: "abc-123", taskId: "42:3" })
91
+ poll status_get({ runId: rid_task }) until completed
92
+ ```
93
+
94
+ ## Check Recent Activity
95
+
96
+ ```
97
+ runs_list({}) # all recent dispatch runs
98
+ runs_list({ status: "failed" }) # only failures
99
+ runs_list({ status: "running" }) # currently in-progress
100
+ spec_runs_list({}) # recent spec generation runs
101
+ ```
102
+
103
+ ## Feature Branch (Group Multiple Issues into One PR)
104
+
105
+ Run dispatch with `--feature` via the CLI, or dispatch issues sequentially and they'll be grouped if you use a shared branch. Consult the Dispatch README for the `--feature` flag usage.