opencode-mission-control 1.1.0 → 1.1.1
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/README.md +192 -30
- package/dist/index.js +17849 -7842
- package/package.json +3 -7
package/README.md
CHANGED
|
@@ -17,11 +17,11 @@
|
|
|
17
17
|
<p align="center">
|
|
18
18
|
<a href="#quick-start">Quick Start</a> •
|
|
19
19
|
<a href="#more-usage-examples">Examples</a> •
|
|
20
|
+
<a href="#choosing-between-launch-and-plan">Launch vs Plan</a> •
|
|
20
21
|
<a href="#how-it-works">How It Works</a> •
|
|
21
22
|
<a href="#tools-reference">Tools Reference</a> •
|
|
22
23
|
<a href="#orchestrated-plans">Orchestrated Plans</a> •
|
|
23
24
|
<a href="#configuration">Configuration</a> •
|
|
24
|
-
<a href="#release--npm-deploy">Release</a> •
|
|
25
25
|
<a href="#faq">FAQ</a>
|
|
26
26
|
</p>
|
|
27
27
|
|
|
@@ -163,7 +163,7 @@ AI: → mc_sync(name: "feature-checkout", strategy: "rebase")
|
|
|
163
163
|
|
|
164
164
|
```
|
|
165
165
|
AI: → mc_plan(
|
|
166
|
-
name: "search
|
|
166
|
+
name: "feat: search upgrade",
|
|
167
167
|
mode: "autopilot",
|
|
168
168
|
jobs: [
|
|
169
169
|
{ name: "schema", prompt: "Add search index tables" },
|
|
@@ -177,6 +177,111 @@ Because waiting is overrated.
|
|
|
177
177
|
|
|
178
178
|
---
|
|
179
179
|
|
|
180
|
+
## Choosing Between Launch and Plan
|
|
181
|
+
|
|
182
|
+
The two main entry points — `mc_launch` and `mc_plan` — serve different workflows. Picking the right one saves you time and merge headaches.
|
|
183
|
+
|
|
184
|
+
### Use `mc_launch` when...
|
|
185
|
+
|
|
186
|
+
| Scenario | Why Launch |
|
|
187
|
+
|----------|-----------|
|
|
188
|
+
| **Independent tasks on different files** | No dependency management needed. Launch both, merge in any order. |
|
|
189
|
+
| **Quick experiments or spikes** | Spin up a job, review the diff, keep it or kill it. Zero ceremony. |
|
|
190
|
+
| **You want full manual control** | You decide what merges, when, and in what order. |
|
|
191
|
+
| **More than 3 concurrent jobs** | Plans respect `maxParallel` (default 3). Standalone launches have no limit. |
|
|
192
|
+
|
|
193
|
+
**Typical launch workflow:**
|
|
194
|
+
```
|
|
195
|
+
mc_launch("fix-auth", "Fix the JWT expiry bug in src/auth/")
|
|
196
|
+
mc_launch("add-pricing", "Build pricing table in src/components/pricing/")
|
|
197
|
+
↓ both complete
|
|
198
|
+
mc_diff("fix-auth") → review
|
|
199
|
+
mc_merge("fix-auth") → into main
|
|
200
|
+
mc_diff("add-pricing") → review
|
|
201
|
+
mc_merge("add-pricing") → into main
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Use `mc_plan` when...
|
|
205
|
+
|
|
206
|
+
| Scenario | Why Plan |
|
|
207
|
+
|----------|---------|
|
|
208
|
+
| **Work has a dependency chain** | Job B needs job A to finish first. `dependsOn` handles ordering and code propagation automatically. |
|
|
209
|
+
| **You want automated test gating** | The merge train runs your test suite after each merge and rolls back on failure. You don't get this with standalone launches. |
|
|
210
|
+
| **You want a single PR for a feature** | Plan creates one integration branch and opens a single PR when everything merges. |
|
|
211
|
+
| **You want hands-off execution** | Autopilot mode: launch, merge, test, PR — all automatic. Walk away. |
|
|
212
|
+
|
|
213
|
+
**Typical plan workflow:**
|
|
214
|
+
```
|
|
215
|
+
mc_plan("feat: search upgrade", mode: "autopilot", jobs: [
|
|
216
|
+
{ name: "schema", prompt: "Add search tables..." },
|
|
217
|
+
{ name: "api", prompt: "Build search endpoints...", dependsOn: ["schema"] },
|
|
218
|
+
{ name: "ui", prompt: "Build search UI...", dependsOn: ["api"] }
|
|
219
|
+
])
|
|
220
|
+
↓ automatic
|
|
221
|
+
schema launches → completes → merges into integration branch
|
|
222
|
+
api launches (sees schema's changes) → completes → merges → tests run
|
|
223
|
+
ui launches (sees schema + api changes) → completes → merges → tests run
|
|
224
|
+
↓
|
|
225
|
+
PR created automatically
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Quick Decision Guide
|
|
229
|
+
|
|
230
|
+
```
|
|
231
|
+
Do the jobs touch completely different files?
|
|
232
|
+
YES → mc_launch both in parallel, merge independently.
|
|
233
|
+
|
|
234
|
+
Does job B need code that job A creates?
|
|
235
|
+
YES → mc_plan with dependsOn. B launches from the integration
|
|
236
|
+
branch and sees A's changes.
|
|
237
|
+
|
|
238
|
+
Do you want tests to run after each merge?
|
|
239
|
+
YES → mc_plan (merge train runs testCommand automatically).
|
|
240
|
+
|
|
241
|
+
Do you want one PR for all the work?
|
|
242
|
+
YES → mc_plan.
|
|
243
|
+
|
|
244
|
+
None of the above?
|
|
245
|
+
→ mc_launch. Simpler, more flexible, less overhead.
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### Working With Shared Files
|
|
249
|
+
|
|
250
|
+
The trickiest scenario is when multiple jobs need to edit the **same files** — for example, two features on the same React view. Even if the work is conceptually separate ("left panel" vs "right panel"), git sees two branches editing the same lines of the same file.
|
|
251
|
+
|
|
252
|
+
**The scaffold pattern** solves this by creating file boundaries first:
|
|
253
|
+
|
|
254
|
+
```
|
|
255
|
+
Step 1: Launch a quick scaffolding job
|
|
256
|
+
mc_launch("scaffold", "Split Dashboard.tsx into separate
|
|
257
|
+
LeftPanel and RightPanel component files. Keep them as
|
|
258
|
+
stubs with TODO comments. Update Dashboard.tsx to import
|
|
259
|
+
and render both.")
|
|
260
|
+
|
|
261
|
+
Step 2: Merge the scaffold
|
|
262
|
+
mc_merge("scaffold")
|
|
263
|
+
|
|
264
|
+
Step 3: Launch the real work in parallel — now they touch different files
|
|
265
|
+
mc_launch("left-panel", "Implement LeftPanel in src/components/LeftPanel.tsx...")
|
|
266
|
+
mc_launch("right-panel", "Implement RightPanel in src/components/RightPanel.tsx...")
|
|
267
|
+
|
|
268
|
+
Step 4: Merge both — no conflicts
|
|
269
|
+
mc_merge("left-panel")
|
|
270
|
+
mc_merge("right-panel")
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
The scaffold job takes a couple of minutes and eliminates the merge conflict surface entirely.
|
|
274
|
+
|
|
275
|
+
**If you can't separate the files** (heavy shared state, tightly coupled components), don't force parallelism. Use a plan with `dependsOn` so the second job builds on top of the first, or just run them sequentially with standalone launches.
|
|
276
|
+
|
|
277
|
+
| Overlap Level | Strategy |
|
|
278
|
+
|---------------|----------|
|
|
279
|
+
| **No shared files** | Parallel `mc_launch` |
|
|
280
|
+
| **1-2 shared files** (parent component, types) | Scaffold first, then parallel |
|
|
281
|
+
| **Many shared files** (shared state, hooks, styles) | Sequential — `mc_plan` with `dependsOn` or manual launches |
|
|
282
|
+
|
|
283
|
+
---
|
|
284
|
+
|
|
180
285
|
## Tools Reference
|
|
181
286
|
|
|
182
287
|
### Job Lifecycle
|
|
@@ -302,8 +407,8 @@ Push the job's branch and create a GitHub Pull Request. Requires the `gh` CLI to
|
|
|
302
407
|
| Parameter | Type | Required | Default | Description |
|
|
303
408
|
|-----------|------|----------|---------|-------------|
|
|
304
409
|
| `name` | `string` | Yes | — | Job name |
|
|
305
|
-
| `title` | `string` | No | Job
|
|
306
|
-
| `body` | `string` | No |
|
|
410
|
+
| `title` | `string` | No | Job name | PR title — use [Conventional Commits](https://www.conventionalcommits.org/) format (e.g. `feat: add login`, `fix: resolve timeout`) |
|
|
411
|
+
| `body` | `string` | No | PR template or auto-generated | PR body. If omitted, uses `.github/pull_request_template.md` if found, otherwise generates a summary. |
|
|
307
412
|
| `draft` | `boolean` | No | `false` | Create as draft PR |
|
|
308
413
|
|
|
309
414
|
#### `mc_sync`
|
|
@@ -338,7 +443,7 @@ Create and start a multi-job orchestrated plan.
|
|
|
338
443
|
|
|
339
444
|
| Parameter | Type | Required | Default | Description |
|
|
340
445
|
|-----------|------|----------|---------|-------------|
|
|
341
|
-
| `name` | `string` | Yes | — | Plan name |
|
|
446
|
+
| `name` | `string` | Yes | — | Plan name — used as the PR title, so use [Conventional Commits](https://www.conventionalcommits.org/) format (e.g. `feat: add search`, `fix: resolve auth bugs`) |
|
|
342
447
|
| `jobs` | `JobSpec[]` | Yes | — | Array of job definitions (see below) |
|
|
343
448
|
| `mode` | `"autopilot"` \| `"copilot"` \| `"supervisor"` | No | `"autopilot"` | Execution mode |
|
|
344
449
|
| `placement` | `"session"` \| `"window"` | No | Config default | tmux placement for all jobs in this plan |
|
|
@@ -369,7 +474,7 @@ Create and start a multi-job orchestrated plan.
|
|
|
369
474
|
mc_plan
|
|
370
475
|
│
|
|
371
476
|
├─ Validate (unique names, valid deps, no circular deps)
|
|
372
|
-
|
|
477
|
+
├─ Create integration branch: mc/integration-{plan-id}
|
|
373
478
|
│
|
|
374
479
|
├─ [copilot] ──→ Pause (pending) ──→ mc_plan_approve ──→ Continue
|
|
375
480
|
│
|
|
@@ -419,11 +524,17 @@ Cancel the active plan. Stops all running jobs, deletes the integration branch,
|
|
|
419
524
|
|
|
420
525
|
### Example: Orchestrated Plan
|
|
421
526
|
|
|
527
|
+
This example uses `mc_plan` instead of four separate `mc_launch` calls because:
|
|
528
|
+
- **The API needs the DB schema to exist** — `api-endpoints` imports from the schema tables that `db-schema` creates. With `dependsOn`, the API job launches from the integration branch and can see those tables.
|
|
529
|
+
- **The UI needs the API types** — `dashboard-ui` imports the response types that `api-endpoints` defines.
|
|
530
|
+
- **Docs and UI are independent of each other** — they both depend on `api-endpoints` but don't share files, so the plan runs them in parallel.
|
|
531
|
+
- **One PR for the whole feature** — instead of four separate PRs, the merge train produces a single integration branch.
|
|
532
|
+
|
|
422
533
|
```
|
|
423
534
|
AI: I'll create a plan for the dashboard feature with proper dependencies.
|
|
424
535
|
|
|
425
536
|
→ mc_plan(
|
|
426
|
-
name: "dashboard
|
|
537
|
+
name: "feat: analytics dashboard",
|
|
427
538
|
mode: "autopilot",
|
|
428
539
|
jobs: [
|
|
429
540
|
{
|
|
@@ -450,14 +561,17 @@ AI: I'll create a plan for the dashboard feature with proper dependencies.
|
|
|
450
561
|
|
|
451
562
|
Result:
|
|
452
563
|
• db-schema launches immediately
|
|
453
|
-
• api-endpoints waits for db-schema to merge
|
|
564
|
+
• api-endpoints waits for db-schema to merge — then launches with schema changes visible
|
|
454
565
|
• dashboard-ui and docs wait for api-endpoints — then run in parallel
|
|
455
|
-
•
|
|
566
|
+
• The merge train tests after each merge and rolls back on failure
|
|
567
|
+
• Once all merge successfully, a single PR is created automatically
|
|
456
568
|
```
|
|
457
569
|
|
|
570
|
+
> **Why not `mc_launch`?** You *could* launch these sequentially, merging each into main before starting the next. But you'd lose the automated test gating, the single integration PR, and the parallel execution of `dashboard-ui` and `docs`. The plan handles the dependency graph, merge ordering, and PR creation — you just check `mc_plan_status` or wait for the completion notification.
|
|
571
|
+
|
|
458
572
|
### Merge Train
|
|
459
573
|
|
|
460
|
-
The Merge Train is the engine behind plan integration. Each completed job's branch is merged into a dedicated **integration branch** (`mc/integration
|
|
574
|
+
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
575
|
|
|
462
576
|
1. **Merge** — `git merge --no-ff {job-branch}` into the integration worktree
|
|
463
577
|
2. **Test** — If a `testCommand` is configured (or detected from `package.json`), it runs after each merge
|
|
@@ -582,35 +696,83 @@ OMO detection is automatic — Mission Control checks your `opencode.json` for t
|
|
|
582
696
|
|
|
583
697
|
## FAQ
|
|
584
698
|
|
|
585
|
-
|
|
586
|
-
|
|
699
|
+
<details>
|
|
700
|
+
<summary><strong>Where are worktrees stored?</strong></summary>
|
|
701
|
+
|
|
702
|
+
By default in `~/.local/share/opencode-mission-control/{project}/`. They are real git worktrees — fully functional working copies.
|
|
703
|
+
</details>
|
|
704
|
+
|
|
705
|
+
<details>
|
|
706
|
+
<summary><strong>Can I use this without tmux?</strong></summary>
|
|
707
|
+
|
|
708
|
+
No. tmux is the backbone of session isolation, monitoring, idle detection, and output capture. It's a hard requirement.
|
|
709
|
+
</details>
|
|
710
|
+
|
|
711
|
+
<details>
|
|
712
|
+
<summary><strong>Does it work with VS Code / Cursor?</strong></summary>
|
|
713
|
+
|
|
714
|
+
Yes. You can open any job's worktree directory in your editor. The AI agents run in background tmux sessions independently.
|
|
715
|
+
</details>
|
|
716
|
+
|
|
717
|
+
<details>
|
|
718
|
+
<summary><strong>What happens if my computer restarts?</strong></summary>
|
|
719
|
+
|
|
720
|
+
Mission Control will detect dead tmux panes on the next poll and mark those jobs as failed. Use `mc_cleanup` to clean up.
|
|
721
|
+
</details>
|
|
722
|
+
|
|
723
|
+
<details>
|
|
724
|
+
<summary><strong>How many jobs can I run at once?</strong></summary>
|
|
725
|
+
|
|
726
|
+
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.
|
|
727
|
+
</details>
|
|
728
|
+
|
|
729
|
+
<details>
|
|
730
|
+
<summary><strong>What if two jobs edit the same file?</strong></summary>
|
|
731
|
+
|
|
732
|
+
Each job has its own worktree, so there are no runtime conflicts — they can't step on each other while running. Conflicts surface at merge time when you bring the branches back together (via `mc_merge` or the plan's merge train).
|
|
733
|
+
|
|
734
|
+
To avoid this, use the **scaffold pattern**: launch a quick job to split the shared file into separate components first, merge it, then launch the real work in parallel on the now-separate files. See [Working With Shared Files](#working-with-shared-files) for the full strategy.
|
|
735
|
+
</details>
|
|
736
|
+
|
|
737
|
+
<details>
|
|
738
|
+
<summary><strong>Can I attach to a job's terminal while it's running?</strong></summary>
|
|
739
|
+
|
|
740
|
+
Yes. Use `mc_attach` to get the tmux command, then run it in your terminal. You'll see the live AI session.
|
|
741
|
+
</details>
|
|
742
|
+
|
|
743
|
+
<details>
|
|
744
|
+
<summary><strong>How does the plan merge train handle test failures?</strong></summary>
|
|
587
745
|
|
|
588
|
-
|
|
589
|
-
|
|
746
|
+
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).
|
|
747
|
+
</details>
|
|
590
748
|
|
|
591
|
-
|
|
592
|
-
|
|
749
|
+
<details>
|
|
750
|
+
<summary><strong>Why not just tell my agents to run <code>git worktree add</code> themselves?</strong></summary>
|
|
593
751
|
|
|
594
|
-
|
|
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.
|
|
752
|
+
You absolutely can — worktrees are just git. What you'd be rebuilding manually is everything around them:
|
|
596
753
|
|
|
597
|
-
|
|
598
|
-
|
|
754
|
+
- tmux session isolation with pane-death detection
|
|
755
|
+
- Background monitoring that tracks idle/streaming/completed states
|
|
756
|
+
- The merge train that tests after each integration and rolls back failures
|
|
757
|
+
- Dependency-aware scheduling with `maxParallel` limits
|
|
758
|
+
- The scaffold-and-sync workflow for shared files
|
|
759
|
+
- Automatic PR creation from integration branches
|
|
760
|
+
- The `mc_overview` dashboard that shows you what every agent is doing at a glance
|
|
599
761
|
|
|
600
|
-
|
|
601
|
-
|
|
762
|
+
Mission Control is the orchestration layer on top of worktrees, not the worktrees themselves.
|
|
763
|
+
</details>
|
|
602
764
|
|
|
603
|
-
|
|
604
|
-
|
|
765
|
+
<details>
|
|
766
|
+
<summary><strong>Is this built by the OpenCode team?</strong></summary>
|
|
605
767
|
|
|
606
|
-
|
|
607
|
-
|
|
768
|
+
No. This is an independent community plugin — not affiliated with or endorsed by the OpenCode team.
|
|
769
|
+
</details>
|
|
608
770
|
|
|
609
|
-
|
|
610
|
-
|
|
771
|
+
<details>
|
|
772
|
+
<summary><strong>Do I need to manually install this with npm first?</strong></summary>
|
|
611
773
|
|
|
612
|
-
|
|
613
|
-
|
|
774
|
+
Usually no. Put it in `opencode.json` and let OpenCode handle plugin installation. Manual npm install is mostly for local development or debugging.
|
|
775
|
+
</details>
|
|
614
776
|
|
|
615
777
|
---
|
|
616
778
|
|