opencode-mission-control 1.0.0
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/LICENSE +21 -0
- package/README.md +665 -0
- package/dist/index.js +21556 -0
- package/package.json +57 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Nigel
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,665 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="assets/banner.png" alt="OpenCode Mission Control" width="100%" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">OpenCode Mission Control</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<strong>Parallelize your AI coding agents. Ship faster.</strong>
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
<a href="https://www.npmjs.com/package/opencode-mission-control"><img src="https://img.shields.io/npm/v/opencode-mission-control.svg" alt="npm version" /></a>
|
|
13
|
+
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT" /></a>
|
|
14
|
+
<a href="https://github.com/nigel-dev/opencode-mission-control/actions/workflows/ci.yml"><img src="https://github.com/nigel-dev/opencode-mission-control/actions/workflows/ci.yml/badge.svg" alt="CI" /></a>
|
|
15
|
+
</p>
|
|
16
|
+
|
|
17
|
+
<p align="center">
|
|
18
|
+
<a href="#quick-start">Quick Start</a> •
|
|
19
|
+
<a href="#more-usage-examples">Examples</a> •
|
|
20
|
+
<a href="#how-it-works">How It Works</a> •
|
|
21
|
+
<a href="#tools-reference">Tools Reference</a> •
|
|
22
|
+
<a href="#orchestrated-plans">Orchestrated Plans</a> •
|
|
23
|
+
<a href="#configuration">Configuration</a> •
|
|
24
|
+
<a href="#release--npm-deploy">Release</a> •
|
|
25
|
+
<a href="#faq">FAQ</a>
|
|
26
|
+
</p>
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## The Problem
|
|
31
|
+
|
|
32
|
+
AI coding is fast, but context switching is slow. Running multiple agents in a single directory leads to file conflicts, messy git history, and "who-changed-what" headaches. You end up waiting for one agent to finish before starting the next, wasting the most valuable resource you have: **your time** (and, occasionally, your patience).
|
|
33
|
+
|
|
34
|
+
## The Solution
|
|
35
|
+
|
|
36
|
+
Mission Control orchestrates **isolated environments** for your AI agents. Each job gets its own git worktree and tmux session — complete filesystem isolation. You can monitor progress, capture output, or attach to any session at any time. When the work is done, sync changes back or create a PR with a single command.
|
|
37
|
+
|
|
38
|
+
For complex multi-task workflows, the **Plan System** handles dependency graphs, merge ordering, automated testing, and PR creation — all orchestrated automatically. Less herding cats, more shipping code.
|
|
39
|
+
|
|
40
|
+
## How It Works
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
┌─────────────────────────┐
|
|
44
|
+
│ Your Main Session │
|
|
45
|
+
│ (Command Center) │
|
|
46
|
+
└────────────┬────────────┘
|
|
47
|
+
│
|
|
48
|
+
mc_launch / mc_plan
|
|
49
|
+
│
|
|
50
|
+
┌───────────────────┼───────────────────┐
|
|
51
|
+
│ │ │
|
|
52
|
+
┌──────┴──────┐ ┌──────┴──────┐ ┌──────┴──────┐
|
|
53
|
+
│ Job A │ │ Job B │ │ Job C │
|
|
54
|
+
│ Worktree │ │ Worktree │ │ Worktree │
|
|
55
|
+
│ + tmux │ │ + tmux │ │ + tmux │
|
|
56
|
+
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘
|
|
57
|
+
│ │ │
|
|
58
|
+
└───────────────────┼───────────────────┘
|
|
59
|
+
│
|
|
60
|
+
mc_diff / mc_pr
|
|
61
|
+
mc_merge / mc_sync
|
|
62
|
+
│
|
|
63
|
+
▼
|
|
64
|
+
┌─────────────────┐
|
|
65
|
+
│ Main Branch │
|
|
66
|
+
└─────────────────┘
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
1. **Launch** — `mc_launch` creates a git worktree + tmux session and starts an AI agent inside it
|
|
70
|
+
2. **Monitor** — The background monitor polls every 10s, tracking output, idle state, and pane death
|
|
71
|
+
3. **Observe** — Use `mc_status`, `mc_capture`, or `mc_attach` to check on progress
|
|
72
|
+
4. **Integrate** — Use `mc_diff` to review, `mc_pr` to create a PR, `mc_merge` to merge, or `mc_sync` to rebase
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Quick Start
|
|
77
|
+
|
|
78
|
+
### Prerequisites
|
|
79
|
+
|
|
80
|
+
| Tool | Required | Purpose |
|
|
81
|
+
|------|----------|---------|
|
|
82
|
+
| **[tmux](https://github.com/tmux/tmux)** | Yes | Session isolation and monitoring |
|
|
83
|
+
| **[git](https://git-scm.com/)** | Yes | Worktree management |
|
|
84
|
+
| **[gh](https://cli.github.com/)** | For `mc_pr` | GitHub PR creation |
|
|
85
|
+
|
|
86
|
+
### Installation (OpenCode Plugin)
|
|
87
|
+
|
|
88
|
+
Most OpenCode setups install plugins listed in `opencode.json` automatically, so you usually **do not** run `npm install` manually.
|
|
89
|
+
|
|
90
|
+
Add this plugin entry:
|
|
91
|
+
|
|
92
|
+
```json
|
|
93
|
+
{
|
|
94
|
+
"plugins": [
|
|
95
|
+
"opencode-mission-control"
|
|
96
|
+
]
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
If you are developing this repository itself, use the local dev flow in [Development](#development).
|
|
101
|
+
|
|
102
|
+
### Your First Job
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
You: "Fix the login bug and add the pricing table — do both at once."
|
|
106
|
+
|
|
107
|
+
AI: Launching two parallel jobs now.
|
|
108
|
+
→ mc_launch(name: "fix-login", prompt: "Fix the authentication bug in...")
|
|
109
|
+
→ mc_launch(name: "add-pricing", prompt: "Create a pricing table component...")
|
|
110
|
+
|
|
111
|
+
You: "How's the login fix going?"
|
|
112
|
+
|
|
113
|
+
AI: → mc_capture(name: "fix-login")
|
|
114
|
+
Still running. Here's the latest output from that session...
|
|
115
|
+
|
|
116
|
+
You: "Login fix looks good. Create a PR."
|
|
117
|
+
|
|
118
|
+
AI: → mc_pr(name: "fix-login", title: "Fix: auth token validation")
|
|
119
|
+
PR created: https://github.com/you/repo/pull/42
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### More Usage Examples
|
|
123
|
+
|
|
124
|
+
#### 1) Run two tasks in parallel, then compare output
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
You: "Run a docs cleanup and a bugfix in parallel."
|
|
128
|
+
|
|
129
|
+
AI: → mc_launch(name: "docs-cleanup", prompt: "Clean up README wording")
|
|
130
|
+
→ mc_launch(name: "fix-auth-timeout", prompt: "Fix token timeout bug")
|
|
131
|
+
|
|
132
|
+
You: "Show me what changed in the bugfix branch."
|
|
133
|
+
|
|
134
|
+
AI: → mc_diff(name: "fix-auth-timeout")
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
#### 2) Monitor everything in one command
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
You: "What's happening right now?"
|
|
141
|
+
|
|
142
|
+
AI: → mc_overview()
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
#### 3) Stop a runaway job and clean up
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
You: "Kill the experiment and remove its worktree."
|
|
149
|
+
|
|
150
|
+
AI: → mc_kill(name: "wild-experiment")
|
|
151
|
+
→ mc_cleanup(name: "wild-experiment", deleteBranch: true)
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
#### 4) Keep a long job current with main
|
|
155
|
+
|
|
156
|
+
```
|
|
157
|
+
You: "Rebase the feature job onto latest main."
|
|
158
|
+
|
|
159
|
+
AI: → mc_sync(name: "feature-checkout", strategy: "rebase")
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
#### 5) Orchestrate dependent work automatically
|
|
163
|
+
|
|
164
|
+
```
|
|
165
|
+
AI: → mc_plan(
|
|
166
|
+
name: "search-upgrade",
|
|
167
|
+
mode: "autopilot",
|
|
168
|
+
jobs: [
|
|
169
|
+
{ name: "schema", prompt: "Add search index tables" },
|
|
170
|
+
{ name: "api", prompt: "Implement search endpoints", dependsOn: ["schema"] },
|
|
171
|
+
{ name: "ui", prompt: "Build search UI", dependsOn: ["api"] }
|
|
172
|
+
]
|
|
173
|
+
)
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Because waiting is overrated.
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## Tools Reference
|
|
181
|
+
|
|
182
|
+
### Job Lifecycle
|
|
183
|
+
|
|
184
|
+
#### `mc_launch`
|
|
185
|
+
|
|
186
|
+
Launch a new parallel AI coding session in an isolated worktree.
|
|
187
|
+
|
|
188
|
+
| Parameter | Type | Required | Default | Description |
|
|
189
|
+
|-----------|------|----------|---------|-------------|
|
|
190
|
+
| `name` | `string` | Yes | — | Job name (used for branch name and tmux target) |
|
|
191
|
+
| `prompt` | `string` | Yes | — | Task prompt for the spawned AI agent |
|
|
192
|
+
| `branch` | `string` | No | `mc/{name}` | Git branch name |
|
|
193
|
+
| `placement` | `"session"` \| `"window"` | No | Config default | `session` creates a new tmux session; `window` adds a window to the current session |
|
|
194
|
+
| `mode` | `"vanilla"` \| `"plan"` \| `"ralph"` \| `"ulw"` | No | Config default | Execution mode (see [OMO Integration](#omo-integration)) |
|
|
195
|
+
| `planFile` | `string` | No | — | Plan file path (for `plan` mode) |
|
|
196
|
+
| `copyFiles` | `string[]` | No | — | Files to copy from main worktree (e.g. `[".env", ".env.local"]`) |
|
|
197
|
+
| `symlinkDirs` | `string[]` | No | — | Directories to symlink (e.g. `["node_modules"]`). `.opencode` is always included. |
|
|
198
|
+
| `commands` | `string[]` | No | — | Shell commands to run after worktree creation (e.g. `["bun install"]`) |
|
|
199
|
+
|
|
200
|
+
**What happens on launch:**
|
|
201
|
+
1. Creates a new git worktree on a dedicated branch
|
|
202
|
+
2. Runs post-create hooks (copy files, create symlinks, run commands)
|
|
203
|
+
3. Spins up a tmux session or window
|
|
204
|
+
4. Starts `opencode --prompt '...'` inside the tmux pane
|
|
205
|
+
5. Sets up pane-died hook for completion detection
|
|
206
|
+
6. Registers the job for background monitoring
|
|
207
|
+
|
|
208
|
+
#### `mc_jobs`
|
|
209
|
+
|
|
210
|
+
List all jobs with their current status.
|
|
211
|
+
|
|
212
|
+
| Parameter | Type | Required | Default | Description |
|
|
213
|
+
|-----------|------|----------|---------|-------------|
|
|
214
|
+
| `status` | `"all"` \| `"running"` \| `"completed"` \| `"failed"` | No | `"all"` | Filter by status |
|
|
215
|
+
|
|
216
|
+
#### `mc_status`
|
|
217
|
+
|
|
218
|
+
Get detailed status of a specific job including branch, worktree path, tmux target, duration, and mode.
|
|
219
|
+
|
|
220
|
+
| Parameter | Type | Required | Description |
|
|
221
|
+
|-----------|------|----------|-------------|
|
|
222
|
+
| `name` | `string` | Yes | Job name |
|
|
223
|
+
|
|
224
|
+
#### `mc_capture`
|
|
225
|
+
|
|
226
|
+
Capture the last N lines of terminal output from a job's tmux pane.
|
|
227
|
+
|
|
228
|
+
| Parameter | Type | Required | Default | Description |
|
|
229
|
+
|-----------|------|----------|---------|-------------|
|
|
230
|
+
| `name` | `string` | Yes | — | Job name |
|
|
231
|
+
| `lines` | `number` | No | `100` | Number of lines to capture |
|
|
232
|
+
|
|
233
|
+
#### `mc_attach`
|
|
234
|
+
|
|
235
|
+
Get the tmux command to attach to a job's terminal session.
|
|
236
|
+
|
|
237
|
+
| Parameter | Type | Required | Description |
|
|
238
|
+
|-----------|------|----------|-------------|
|
|
239
|
+
| `name` | `string` | Yes | Job name |
|
|
240
|
+
|
|
241
|
+
#### `mc_kill`
|
|
242
|
+
|
|
243
|
+
Stop a running job by terminating its tmux session/window.
|
|
244
|
+
|
|
245
|
+
| Parameter | Type | Required | Default | Description |
|
|
246
|
+
|-----------|------|----------|---------|-------------|
|
|
247
|
+
| `name` | `string` | Yes | — | Job name |
|
|
248
|
+
| `force` | `boolean` | No | `false` | Force kill |
|
|
249
|
+
|
|
250
|
+
#### `mc_cleanup`
|
|
251
|
+
|
|
252
|
+
Remove finished job worktrees and metadata.
|
|
253
|
+
|
|
254
|
+
| Parameter | Type | Required | Default | Description |
|
|
255
|
+
|-----------|------|----------|---------|-------------|
|
|
256
|
+
| `name` | `string` | No | — | Specific job to clean up |
|
|
257
|
+
| `all` | `boolean` | No | `false` | Clean up all non-running jobs |
|
|
258
|
+
| `deleteBranch` | `boolean` | No | `false` | Also delete the git branch |
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
### Monitoring & Reporting
|
|
263
|
+
|
|
264
|
+
#### `mc_overview`
|
|
265
|
+
|
|
266
|
+
Get a complete dashboard overview of all Mission Control activity — running jobs, recent completions, failures, active plans, alerts, and suggested next actions. This is the best starting point when checking in on your jobs.
|
|
267
|
+
|
|
268
|
+
*No parameters.*
|
|
269
|
+
|
|
270
|
+
#### `mc_report`
|
|
271
|
+
|
|
272
|
+
Report agent status back to Mission Control. Auto-detects which job is calling based on the current worktree. This tool is designed to be called by spawned agents from within their managed worktrees — it cannot be used from the main session.
|
|
273
|
+
|
|
274
|
+
| Parameter | Type | Required | Default | Description |
|
|
275
|
+
|-----------|------|----------|---------|-------------|
|
|
276
|
+
| `status` | `"working"` \| `"blocked"` \| `"needs_review"` \| `"completed"` \| `"progress"` | Yes | — | Current agent status |
|
|
277
|
+
| `message` | `string` | Yes | — | Human-readable status message |
|
|
278
|
+
| `progress` | `number` | No | — | Completion percentage (0–100) |
|
|
279
|
+
|
|
280
|
+
Reports are used by the monitoring system to:
|
|
281
|
+
- Trigger notifications (e.g., when an agent reports `blocked` or `needs_review`)
|
|
282
|
+
- Signal explicit completion (a `completed` report immediately marks the job as done)
|
|
283
|
+
- Provide progress visibility via `mc_status` and `mc_overview`
|
|
284
|
+
|
|
285
|
+
---
|
|
286
|
+
|
|
287
|
+
### Git Workflow
|
|
288
|
+
|
|
289
|
+
#### `mc_diff`
|
|
290
|
+
|
|
291
|
+
Compare a job's branch against the base branch.
|
|
292
|
+
|
|
293
|
+
| Parameter | Type | Required | Default | Description |
|
|
294
|
+
|-----------|------|----------|---------|-------------|
|
|
295
|
+
| `name` | `string` | Yes | — | Job name |
|
|
296
|
+
| `stat` | `boolean` | No | `false` | Show diffstat summary only |
|
|
297
|
+
|
|
298
|
+
#### `mc_pr`
|
|
299
|
+
|
|
300
|
+
Push the job's branch and create a GitHub Pull Request. Requires the `gh` CLI to be authenticated.
|
|
301
|
+
|
|
302
|
+
| Parameter | Type | Required | Default | Description |
|
|
303
|
+
|-----------|------|----------|---------|-------------|
|
|
304
|
+
| `name` | `string` | Yes | — | Job name |
|
|
305
|
+
| `title` | `string` | No | Job prompt | PR title |
|
|
306
|
+
| `body` | `string` | No | — | PR description |
|
|
307
|
+
| `draft` | `boolean` | No | `false` | Create as draft PR |
|
|
308
|
+
|
|
309
|
+
#### `mc_sync`
|
|
310
|
+
|
|
311
|
+
Pull the latest changes from the base branch into a job's worktree.
|
|
312
|
+
|
|
313
|
+
| Parameter | Type | Required | Default | Description |
|
|
314
|
+
|-----------|------|----------|---------|-------------|
|
|
315
|
+
| `name` | `string` | Yes | — | Job name |
|
|
316
|
+
| `strategy` | `"rebase"` \| `"merge"` | No | `"rebase"` | Sync strategy. Aborts on conflict and reports affected files. |
|
|
317
|
+
|
|
318
|
+
#### `mc_merge`
|
|
319
|
+
|
|
320
|
+
Merge a job's branch back into the main worktree.
|
|
321
|
+
|
|
322
|
+
| Parameter | Type | Required | Default | Description |
|
|
323
|
+
|-----------|------|----------|---------|-------------|
|
|
324
|
+
| `name` | `string` | Yes | — | Job name |
|
|
325
|
+
| `strategy` | `"squash"` \| `"ff-only"` \| `"merge"` | No | Config `mergeStrategy` (default `"squash"`) | Merge strategy. `squash` squashes all commits; `ff-only` rebases then fast-forwards; `merge` creates a merge commit (`--no-ff`). |
|
|
326
|
+
| `squash` | `boolean` | No | `false` | **Deprecated** — use `strategy` instead. If set and no `strategy` is provided, `squash: true` maps to `strategy: "squash"`. |
|
|
327
|
+
| `message` | `string` | No | Auto-generated | Merge commit message |
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
331
|
+
## Orchestrated Plans
|
|
332
|
+
|
|
333
|
+
For workflows with dependencies between jobs, the **Plan System** manages the full lifecycle — from parallel execution to merge ordering to PR creation.
|
|
334
|
+
|
|
335
|
+
### `mc_plan`
|
|
336
|
+
|
|
337
|
+
Create and start a multi-job orchestrated plan.
|
|
338
|
+
|
|
339
|
+
| Parameter | Type | Required | Default | Description |
|
|
340
|
+
|-----------|------|----------|---------|-------------|
|
|
341
|
+
| `name` | `string` | Yes | — | Plan name |
|
|
342
|
+
| `jobs` | `JobSpec[]` | Yes | — | Array of job definitions (see below) |
|
|
343
|
+
| `mode` | `"autopilot"` \| `"copilot"` \| `"supervisor"` | No | `"autopilot"` | Execution mode |
|
|
344
|
+
| `placement` | `"session"` \| `"window"` | No | Config default | tmux placement for all jobs in this plan |
|
|
345
|
+
|
|
346
|
+
**JobSpec fields:**
|
|
347
|
+
|
|
348
|
+
| Field | Type | Required | Description |
|
|
349
|
+
|-------|------|----------|-------------|
|
|
350
|
+
| `name` | `string` | Yes | Unique job name |
|
|
351
|
+
| `prompt` | `string` | Yes | Task prompt for the AI agent |
|
|
352
|
+
| `dependsOn` | `string[]` | No | Job names this job depends on (must complete and merge first) |
|
|
353
|
+
| `touchSet` | `string[]` | No | File globs this job expects to modify |
|
|
354
|
+
| `copyFiles` | `string[]` | No | Files to copy into the worktree |
|
|
355
|
+
| `symlinkDirs` | `string[]` | No | Directories to symlink into the worktree |
|
|
356
|
+
| `commands` | `string[]` | No | Post-creation shell commands |
|
|
357
|
+
|
|
358
|
+
### Plan Modes
|
|
359
|
+
|
|
360
|
+
| Mode | Behavior |
|
|
361
|
+
|------|----------|
|
|
362
|
+
| **Autopilot** | Full hands-off execution. Jobs launch, merge, and a PR is created automatically. |
|
|
363
|
+
| **Copilot** | Plan is created in `pending` state. You review it with `mc_plan_status`, then approve with `mc_plan_approve` to start. |
|
|
364
|
+
| **Supervisor** | Execution pauses at **checkpoints** (`pre_merge`, `on_error`, `pre_pr`) requiring manual `mc_plan_approve` to continue. |
|
|
365
|
+
|
|
366
|
+
### Plan Lifecycle
|
|
367
|
+
|
|
368
|
+
```
|
|
369
|
+
mc_plan
|
|
370
|
+
│
|
|
371
|
+
├─ Validate (unique names, valid deps, no circular deps)
|
|
372
|
+
├─ Create integration branch: mc/integration/{plan-id}
|
|
373
|
+
│
|
|
374
|
+
├─ [copilot] ──→ Pause (pending) ──→ mc_plan_approve ──→ Continue
|
|
375
|
+
│
|
|
376
|
+
├─ Topological sort jobs by dependencies
|
|
377
|
+
├─ Launch jobs (respects maxParallel limit)
|
|
378
|
+
│
|
|
379
|
+
│ ┌──────── Reconciler Loop (5s) ────────┐
|
|
380
|
+
│ │ │
|
|
381
|
+
│ │ • Check dependency satisfaction │
|
|
382
|
+
│ │ • Launch ready jobs │
|
|
383
|
+
│ │ • Process merge train │
|
|
384
|
+
│ │ • [supervisor] Pause at checkpoints │
|
|
385
|
+
│ │ │
|
|
386
|
+
│ └───────────────────────────────────────┘
|
|
387
|
+
│
|
|
388
|
+
├─ Merge Train: merge each job into integration branch
|
|
389
|
+
│ ├─ Merge (--no-ff)
|
|
390
|
+
│ ├─ Run test command (if configured)
|
|
391
|
+
│ ├─ On failure → rollback merge, mark failed
|
|
392
|
+
│ └─ On conflict → abort, mark conflict
|
|
393
|
+
│
|
|
394
|
+
├─ All jobs merged → push integration branch
|
|
395
|
+
└─ Create PR via gh CLI
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
### Plan Control Tools
|
|
399
|
+
|
|
400
|
+
#### `mc_plan_status`
|
|
401
|
+
|
|
402
|
+
Show the current state of the active plan — job statuses, progress, and any checkpoints.
|
|
403
|
+
|
|
404
|
+
*No parameters.*
|
|
405
|
+
|
|
406
|
+
#### `mc_plan_approve`
|
|
407
|
+
|
|
408
|
+
Approve a copilot plan to start execution, or clear a supervisor checkpoint to continue.
|
|
409
|
+
|
|
410
|
+
| Parameter | Type | Required | Description |
|
|
411
|
+
|-----------|------|----------|-------------|
|
|
412
|
+
| `checkpoint` | `"pre_merge"` \| `"on_error"` \| `"pre_pr"` | No | Specific checkpoint to clear (supervisor mode) |
|
|
413
|
+
|
|
414
|
+
#### `mc_plan_cancel`
|
|
415
|
+
|
|
416
|
+
Cancel the active plan. Stops all running jobs, deletes the integration branch, and cleans up state.
|
|
417
|
+
|
|
418
|
+
*No parameters.*
|
|
419
|
+
|
|
420
|
+
### Example: Orchestrated Plan
|
|
421
|
+
|
|
422
|
+
```
|
|
423
|
+
AI: I'll create a plan for the dashboard feature with proper dependencies.
|
|
424
|
+
|
|
425
|
+
→ mc_plan(
|
|
426
|
+
name: "dashboard-feature",
|
|
427
|
+
mode: "autopilot",
|
|
428
|
+
jobs: [
|
|
429
|
+
{
|
|
430
|
+
name: "db-schema",
|
|
431
|
+
prompt: "Add the analytics tables to the database schema"
|
|
432
|
+
},
|
|
433
|
+
{
|
|
434
|
+
name: "api-endpoints",
|
|
435
|
+
prompt: "Create REST endpoints for the analytics dashboard",
|
|
436
|
+
dependsOn: ["db-schema"]
|
|
437
|
+
},
|
|
438
|
+
{
|
|
439
|
+
name: "dashboard-ui",
|
|
440
|
+
prompt: "Build the analytics dashboard React components",
|
|
441
|
+
dependsOn: ["api-endpoints"]
|
|
442
|
+
},
|
|
443
|
+
{
|
|
444
|
+
name: "docs",
|
|
445
|
+
prompt: "Update API documentation for analytics endpoints",
|
|
446
|
+
dependsOn: ["api-endpoints"]
|
|
447
|
+
}
|
|
448
|
+
]
|
|
449
|
+
)
|
|
450
|
+
|
|
451
|
+
Result:
|
|
452
|
+
• db-schema launches immediately
|
|
453
|
+
• api-endpoints waits for db-schema to merge
|
|
454
|
+
• dashboard-ui and docs wait for api-endpoints — then run in parallel
|
|
455
|
+
• Once all merge successfully, a PR is created automatically
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
### Merge Train
|
|
459
|
+
|
|
460
|
+
The Merge Train is the engine behind plan integration. Each completed job's branch is merged into a dedicated **integration branch** (`mc/integration/{plan-id}`):
|
|
461
|
+
|
|
462
|
+
1. **Merge** — `git merge --no-ff {job-branch}` into the integration worktree
|
|
463
|
+
2. **Test** — If a `testCommand` is configured (or detected from `package.json`), it runs after each merge
|
|
464
|
+
3. **Rollback** — If tests fail or time out, the merge is automatically rolled back (`git merge --abort` or `git reset --hard HEAD~1`)
|
|
465
|
+
4. **Conflict detection** — Merge conflicts are caught, reported with file-level detail, and the merge is aborted
|
|
466
|
+
|
|
467
|
+
Once all jobs are merged and tests pass, the integration branch is pushed and a PR is created.
|
|
468
|
+
|
|
469
|
+
---
|
|
470
|
+
|
|
471
|
+
## Slash Commands
|
|
472
|
+
|
|
473
|
+
These commands run directly in the OpenCode chat — instant execution without an AI roundtrip (except `/mc-launch`, which delegates to the AI).
|
|
474
|
+
|
|
475
|
+
| Command | Description |
|
|
476
|
+
|---------|-------------|
|
|
477
|
+
| `/mc` | Show Mission Control dashboard overview (runs `mc_overview`) |
|
|
478
|
+
| `/mc-jobs` | List all jobs and their status |
|
|
479
|
+
| `/mc-launch <prompt>` | Launch a new parallel agent (delegates to AI) |
|
|
480
|
+
| `/mc-status <name>` | Detailed status of a specific job |
|
|
481
|
+
| `/mc-attach <name>` | Get the tmux attach command |
|
|
482
|
+
| `/mc-cleanup [name]` | Clean up finished jobs (all if no name given) |
|
|
483
|
+
|
|
484
|
+
---
|
|
485
|
+
|
|
486
|
+
## Monitoring System
|
|
487
|
+
|
|
488
|
+
Mission Control runs an active background monitor — not a passive wrapper.
|
|
489
|
+
|
|
490
|
+
### How Monitoring Works
|
|
491
|
+
|
|
492
|
+
| Mechanism | Interval | What It Does |
|
|
493
|
+
|-----------|----------|--------------|
|
|
494
|
+
| **Polling** | Every `pollInterval` (default 10s) | Checks if each job's tmux pane is still running |
|
|
495
|
+
| **Pane death detection** | Immediate | tmux `pane-died` hook fires when a pane closes, capturing exit status |
|
|
496
|
+
| **Idle detection** | `idleThreshold` (default 5min) | Hashes terminal output; if unchanged for the threshold period and the session shows the idle prompt (`ctrl+p commands`), marks the job as completed |
|
|
497
|
+
| **Exit code capture** | On pane death | Exit code `0` → completed. Non-zero → failed. |
|
|
498
|
+
| **Session state detection** | On idle check | Distinguishes `idle` (waiting for input), `streaming` (AI is working), and `unknown` states |
|
|
499
|
+
|
|
500
|
+
### Hooks & Lifecycle
|
|
501
|
+
|
|
502
|
+
| Hook | Trigger | Behavior |
|
|
503
|
+
|------|---------|----------|
|
|
504
|
+
| `session.idle` | User's main session goes quiet | Shows toast notification with running job summary (rate-limited to once per 5 minutes) |
|
|
505
|
+
| `session.compacting` | OpenCode compacts context | Injects current job state into the AI's memory so it stays aware of background work |
|
|
506
|
+
| `pane-died` | tmux pane closes | Immediately captures exit status and updates job state |
|
|
507
|
+
|
|
508
|
+
---
|
|
509
|
+
|
|
510
|
+
## Configuration
|
|
511
|
+
|
|
512
|
+
Configuration is stored at `~/.local/share/opencode-mission-control/{project}/config.json`.
|
|
513
|
+
|
|
514
|
+
```json
|
|
515
|
+
{
|
|
516
|
+
"defaultPlacement": "session",
|
|
517
|
+
"pollInterval": 10000,
|
|
518
|
+
"idleThreshold": 300000,
|
|
519
|
+
"worktreeBasePath": "~/.local/share/opencode-mission-control",
|
|
520
|
+
"maxParallel": 3,
|
|
521
|
+
"autoCommit": true,
|
|
522
|
+
"mergeStrategy": "squash",
|
|
523
|
+
"testCommand": "bun test",
|
|
524
|
+
"testTimeout": 600000,
|
|
525
|
+
"worktreeSetup": {
|
|
526
|
+
"copyFiles": [".env", ".env.local"],
|
|
527
|
+
"symlinkDirs": ["node_modules"],
|
|
528
|
+
"commands": ["bun install"]
|
|
529
|
+
},
|
|
530
|
+
"omo": {
|
|
531
|
+
"enabled": true,
|
|
532
|
+
"defaultMode": "vanilla"
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
### Configuration Reference
|
|
538
|
+
|
|
539
|
+
| Field | Type | Default | Description |
|
|
540
|
+
|-------|------|---------|-------------|
|
|
541
|
+
| `defaultPlacement` | `"session"` \| `"window"` | `"session"` | Default tmux placement for new jobs |
|
|
542
|
+
| `pollInterval` | `number` | `10000` | Monitoring poll interval in ms (minimum 10s) |
|
|
543
|
+
| `idleThreshold` | `number` | `300000` | Time in ms before an idle session is marked completed (default 5min) |
|
|
544
|
+
| `worktreeBasePath` | `string` | `~/.local/share/opencode-mission-control` | Root directory for worktrees |
|
|
545
|
+
| `maxParallel` | `number` | `3` | Maximum concurrent jobs in an orchestrated plan |
|
|
546
|
+
| `autoCommit` | `boolean` | `true` | Whether to auto-commit changes in job worktrees before merging |
|
|
547
|
+
| `mergeStrategy` | `"squash"` \| `"ff-only"` \| `"merge"` | `"squash"` | Default merge strategy for `mc_merge` (can be overridden per-merge via the `strategy` param) |
|
|
548
|
+
| `testCommand` | `string` | — | Command to run after each merge in the merge train (e.g. `"bun test"`) |
|
|
549
|
+
| `testTimeout` | `number` | `600000` | Timeout for test command in ms (default 10min) |
|
|
550
|
+
| `worktreeSetup.copyFiles` | `string[]` | — | Files to copy into every new worktree (e.g. `.env`) |
|
|
551
|
+
| `worktreeSetup.symlinkDirs` | `string[]` | — | Directories to symlink into every new worktree (e.g. `node_modules`) |
|
|
552
|
+
| `worktreeSetup.commands` | `string[]` | — | Shell commands to run in every new worktree (e.g. `bun install`) |
|
|
553
|
+
| `omo.enabled` | `boolean` | `false` | Enable Oh-My-OpenCode integration |
|
|
554
|
+
| `omo.defaultMode` | `string` | `"vanilla"` | Default execution mode for spawned agents |
|
|
555
|
+
|
|
556
|
+
### Worktree Setup
|
|
557
|
+
|
|
558
|
+
Every job creates a fresh git worktree. The `worktreeSetup` config (and per-job `copyFiles`/`symlinkDirs`/`commands` params) lets you prepare the environment:
|
|
559
|
+
|
|
560
|
+
- **`copyFiles`** — Copies files from the main worktree (great for `.env`, config files)
|
|
561
|
+
- **`symlinkDirs`** — Creates symlinks to avoid re-downloading (great for `node_modules`, `.cache`)
|
|
562
|
+
- **`commands`** — Runs shell commands after setup (great for `bun install`, `pip install -e .`)
|
|
563
|
+
|
|
564
|
+
Per-job parameters are **merged** with the global `worktreeSetup` config.
|
|
565
|
+
|
|
566
|
+
---
|
|
567
|
+
|
|
568
|
+
## OMO Integration
|
|
569
|
+
|
|
570
|
+
If you use [Oh-My-OpenCode (OMO)](https://github.com/nicholasgriffintn/oh-my-opencode), Mission Control unlocks advanced execution modes for spawned agents. These are **optional** — everything works without OMO installed.
|
|
571
|
+
|
|
572
|
+
| Mode | What It Does |
|
|
573
|
+
|------|--------------|
|
|
574
|
+
| `vanilla` | Standard `opencode --prompt '...'` execution |
|
|
575
|
+
| `plan` | Loads a Sisyphus plan. Copies `.sisyphus/plans` to the worktree and runs `/start-work`. |
|
|
576
|
+
| `ralph` | Starts a self-correcting Ralph Loop via `/ralph-loop` |
|
|
577
|
+
| `ulw` | Activates high-intensity Ultrawork mode via `/ulw-loop` |
|
|
578
|
+
|
|
579
|
+
OMO detection is automatic — Mission Control checks your `opencode.json` for the `oh-my-opencode` plugin.
|
|
580
|
+
|
|
581
|
+
---
|
|
582
|
+
|
|
583
|
+
## FAQ
|
|
584
|
+
|
|
585
|
+
**Q: Where are worktrees stored?**
|
|
586
|
+
A: By default in `~/.local/share/opencode-mission-control/{project}/`. They are real git worktrees — fully functional working copies.
|
|
587
|
+
|
|
588
|
+
**Q: Can I use this without tmux?**
|
|
589
|
+
A: No. tmux is the backbone of session isolation, monitoring, idle detection, and output capture. It's a hard requirement.
|
|
590
|
+
|
|
591
|
+
**Q: Does it work with VS Code / Cursor?**
|
|
592
|
+
A: Yes. You can open any job's worktree directory in your editor. The AI agents run in background tmux sessions independently.
|
|
593
|
+
|
|
594
|
+
**Q: What happens if my computer restarts?**
|
|
595
|
+
A: Mission Control will detect dead tmux panes on the next poll and mark those jobs as failed. Use `mc_cleanup` to clean up.
|
|
596
|
+
|
|
597
|
+
**Q: How many jobs can I run at once?**
|
|
598
|
+
A: As many as your machine can handle. Each job is a real OS process with its own file tree. The `maxParallel` setting only applies to orchestrated plans. Individual `mc_launch` calls have no built-in limit.
|
|
599
|
+
|
|
600
|
+
**Q: What if two jobs edit the same file?**
|
|
601
|
+
A: Since each job has its own worktree, there are no runtime conflicts. Conflicts surface at merge time — either via `mc_merge` or the plan's merge train.
|
|
602
|
+
|
|
603
|
+
**Q: Can I attach to a job's terminal while it's running?**
|
|
604
|
+
A: Yes. Use `mc_attach` to get the tmux command, then run it in your terminal. You'll see the live AI session.
|
|
605
|
+
|
|
606
|
+
**Q: How does the plan merge train handle test failures?**
|
|
607
|
+
A: If the configured `testCommand` fails after a merge, the merge is automatically rolled back. The job is marked as failed and the plan status updates accordingly (in supervisor mode, it pauses for your review).
|
|
608
|
+
|
|
609
|
+
**Q: Is this built by the OpenCode team?**
|
|
610
|
+
A: No. This is an independent community plugin — not affiliated with or endorsed by the OpenCode team.
|
|
611
|
+
|
|
612
|
+
**Q: Do I need to manually install this with npm first?**
|
|
613
|
+
A: Usually no. Put it in `opencode.json` and let OpenCode handle plugin installation. Manual npm install is mostly for local development or debugging.
|
|
614
|
+
|
|
615
|
+
---
|
|
616
|
+
|
|
617
|
+
## Release & npm Deploy
|
|
618
|
+
|
|
619
|
+
This repo uses semantic versioning with **semantic-release** for automated npm releases.
|
|
620
|
+
|
|
621
|
+
How it works:
|
|
622
|
+
|
|
623
|
+
1. Merge a Conventional Commit into `main` (for example: `feat:`, `fix:`, or `BREAKING CHANGE:`).
|
|
624
|
+
2. GitHub Actions runs build + tests.
|
|
625
|
+
3. `semantic-release` calculates the next version, publishes to npm, creates a GitHub Release, and tags automatically.
|
|
626
|
+
|
|
627
|
+
Expected repository secrets:
|
|
628
|
+
|
|
629
|
+
- `NPM_TOKEN` — npm publish token with package publish rights.
|
|
630
|
+
- `GITHUB_TOKEN` — provided automatically by GitHub Actions.
|
|
631
|
+
|
|
632
|
+
If your commit messages are vague, semantic-release gets moody.
|
|
633
|
+
|
|
634
|
+
---
|
|
635
|
+
|
|
636
|
+
## Development
|
|
637
|
+
|
|
638
|
+
```bash
|
|
639
|
+
bun install
|
|
640
|
+
bun run build
|
|
641
|
+
bun test
|
|
642
|
+
```
|
|
643
|
+
|
|
644
|
+
## Contributing
|
|
645
|
+
|
|
646
|
+
Found a bug? Have an idea? Check out [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
647
|
+
|
|
648
|
+
## License
|
|
649
|
+
|
|
650
|
+
MIT
|
|
651
|
+
|
|
652
|
+
## Inspired By
|
|
653
|
+
|
|
654
|
+
This plugin was heavily inspired by great work across the OpenCode ecosystem (any bugs are still 100% mine):
|
|
655
|
+
|
|
656
|
+
- [slkiser/opencode-quota](https://github.com/slkiser/opencode-quota)
|
|
657
|
+
- [shekohex/opencode-pty](https://github.com/shekohex/opencode-pty)
|
|
658
|
+
- [Opencode-DCP/opencode-dynamic-context-pruning](https://github.com/Opencode-DCP/opencode-dynamic-context-pruning)
|
|
659
|
+
- [code-yeongyu/oh-my-opencode](https://github.com/code-yeongyu/oh-my-opencode)
|
|
660
|
+
- [panta82/opencode-notificator](https://github.com/panta82/opencode-notificator)
|
|
661
|
+
- [24601/opencode-zellij-namer](https://github.com/24601/opencode-zellij-namer)
|
|
662
|
+
- [kdcokenny/opencode-background-agents](https://github.com/kdcokenny/opencode-background-agents)
|
|
663
|
+
- [spoons-and-mirrors/subtask2](https://github.com/spoons-and-mirrors/subtask2)
|
|
664
|
+
- [mailshieldai/opencode-canvas](https://github.com/mailshieldai/opencode-canvas)
|
|
665
|
+
- [joshuadavidthomas/opencode-handoff](https://github.com/joshuadavidthomas/opencode-handoff)
|