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.
Files changed (4) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +665 -0
  3. package/dist/index.js +21556 -0
  4. 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> &bull;
19
+ <a href="#more-usage-examples">Examples</a> &bull;
20
+ <a href="#how-it-works">How It Works</a> &bull;
21
+ <a href="#tools-reference">Tools Reference</a> &bull;
22
+ <a href="#orchestrated-plans">Orchestrated Plans</a> &bull;
23
+ <a href="#configuration">Configuration</a> &bull;
24
+ <a href="#release--npm-deploy">Release</a> &bull;
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)