opencode-multiplexer 0.1.1 → 0.2.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.
@@ -0,0 +1,41 @@
1
+ name: Publish to npm
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*'
7
+
8
+ jobs:
9
+ publish:
10
+ name: Publish
11
+ runs-on: ubuntu-latest
12
+ environment: prod
13
+ permissions:
14
+ id-token: write # required for OIDC trusted publishing
15
+
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+
19
+ - name: Setup Node.js
20
+ uses: actions/setup-node@v4
21
+ with:
22
+ node-version: '24'
23
+ registry-url: 'https://registry.npmjs.org'
24
+
25
+ - name: Setup bun
26
+ uses: oven-sh/setup-bun@v2
27
+
28
+ - name: Install dependencies
29
+ run: npm ci
30
+
31
+ - name: Type check
32
+ run: npx tsc --noEmit
33
+
34
+ # - name: Test
35
+ # run: npm test
36
+
37
+ - name: Build
38
+ run: npm run build
39
+
40
+ - name: Publish to npm
41
+ run: npm publish
package/README.md CHANGED
@@ -1,38 +1,53 @@
1
- # OpenCode Multiplexer a.k.a. OCMux
1
+ # OCMux — OpenCode Multiplexer
2
2
 
3
- A terminal multiplexer for [opencode](https://opencode.ai) AI coding agent sessions. Manage multiple parallel opencode instances across different projects from a single dashboard.
3
+ [![npm version](https://img.shields.io/npm/v/opencode-multiplexer?style=flat-square)](https://www.npmjs.com/package/opencode-multiplexer)
4
+ [![platform](https://img.shields.io/badge/platform-macOS%20%7C%20Linux-111827?style=flat-square)](#requirements)
5
+ [![license](https://img.shields.io/badge/license-ISC-0f766e?style=flat-square)](./LICENSE)
6
+ [![opencode](https://img.shields.io/badge/built%20for-opencode-7c3aed?style=flat-square)](https://opencode.ai)
4
7
 
5
- ## Overview
8
+ A terminal multiplexer for [opencode](https://opencode.ai) AI coding agent sessions.
6
9
 
7
- When working with several opencode sessions simultaneously across different repositories, switching between terminal panes and losing track of which agent needs attention becomes a friction point. OCMux addresses this by providing a single TUI that aggregates all running opencode instances, shows their real-time status, and lets you jump between them efficiently.
10
+ **Run multiple opencode sessions across different projects from one fast, focused dashboard**—see which agents are working, idle, blocked on your input, or failing, then jump into the right session instantly.
8
11
 
9
- Key capabilities:
12
+ When you're juggling several repositories at once, OCMux removes the friction of switching panes, losing context, and missing the moment an agent needs you.
10
13
 
11
- - Dashboard view showing all running opencode sessions with live status indicators (working, needs input, idle, error)
12
- - Expandable subagent tree per session, showing what child agents are running and their status
13
- - Read conversation history for any session without attaching to it
14
- - Send messages directly to sessions spawned via OCMux (which run a background HTTP server)
15
- - Cycle through agent modes (Orchestrator, Chat, Code) and models per session
16
- - Spawn new sessions with a folder picker, attaching immediately to the new session
17
- - Kill instances directly from the dashboard
18
- - Vim-style navigation throughout (j/k, Ctrl-U/D, G/gg)
14
+ ## Demo
15
+
16
+ ### Instantly see your current sessions and attach to existing work
17
+
18
+ ![OCMux dashboard showing active opencode sessions across projects with quick attach support](docs/output1.gif)
19
+
20
+ > OCMux stays responsive to your existing working sessions and lets you attach to them without hunting through terminal panes.
21
+
22
+ ### Track agent status, subagents, and sessions that need your attention
23
+
24
+ ![OCMux session list showing working, idle, and needs-input states with expandable subagent trees](docs/output2.gif)
25
+
26
+ > Live status indicators show whether an agent is working, idle, or waiting on you. You can also inspect subagents and attach to them directly.
27
+
28
+ ### Start new sessions or kill existing ones without leaving the dashboard
29
+
30
+ ![OCMux creating and managing opencode sessions directly from the terminal dashboard](docs/output3.gif)
19
31
 
32
+ > Spawn a new session, jump into it immediately, or terminate a session right from OCMux.
20
33
 
21
- ## Requirements
34
+ ## Install
35
+
36
+ ### Requirements
22
37
 
23
38
  - [Bun](https://bun.sh) runtime
24
39
  - [opencode](https://opencode.ai) installed and available on `PATH`
25
40
  - macOS or Linux
26
41
  - Optional: [fzf](https://github.com/junegunn/fzf) for the folder picker when spawning new sessions
27
42
 
28
-
29
- ## Installation
43
+ ### Install from npm
30
44
 
31
45
  ```bash
32
46
  npm install -g opencode-multiplexer
47
+ ocmux
33
48
  ```
34
49
 
35
- Or run directly from source:
50
+ ### Run from source
36
51
 
37
52
  ```bash
38
53
  git clone https://github.com/joeyism/opencode-multiplexer
@@ -41,21 +56,38 @@ bun install
41
56
  bun src/index.tsx
42
57
  ```
43
58
 
59
+ ## Features
60
+
61
+ OCMux gives you a single TUI for managing several opencode sessions at once.
62
+
63
+ - Dashboard view showing all running opencode sessions with live status indicators (working, needs input, idle, error)
64
+ - Expandable subagent tree per session, showing what child agents are running and their status
65
+ - Read conversation history for any session without attaching to it
66
+ - Send messages directly to sessions spawned via OCMux (which run a background HTTP server)
67
+ - Cycle through agent modes (Orchestrator, Chat, Code) and models per session
68
+ - Spawn new sessions with a folder picker, attaching immediately to the new session
69
+ - Kill instances directly from the dashboard
70
+ - Vim-style navigation throughout (`j`/`k`, `Ctrl-U`/`Ctrl-D`, `G`/`gg`)
71
+
72
+ ## Usage
44
73
 
45
- ## How it works
74
+ ### Overview
75
+
76
+ When working with several opencode sessions simultaneously across different repositories, switching between terminal panes and losing track of which agent needs attention becomes a friction point. OCMux addresses this by providing a single TUI that aggregates all running opencode instances, shows their real-time status, and lets you jump between them efficiently.
77
+
78
+ ### How it works
46
79
 
47
80
  OCMux discovers opencode instances in two ways:
48
81
 
49
- **Existing sessions** (started outside OCMux): OCMux scans for running `opencode` processes using `ps`, identifies their working directories, and matches them to sessions in the shared opencode SQLite database at `~/.local/share/opencode/opencode.db`. These sessions are read-only in OCMux -- you can view the conversation history, but to send messages you must attach to the TUI.
82
+ **Existing sessions** (started outside OCMux): OCMux scans for running `opencode` processes using `ps`, identifies their working directories, and matches them to sessions in the shared opencode SQLite database at `~/.local/share/opencode/opencode.db`. These sessions are read-only in OCMux you can view the conversation history, but to send messages you must attach to the TUI.
50
83
 
51
84
  **Spawned sessions** (started via OCMux): When you create a new session from within OCMux, it starts `opencode serve --port X` as a background process. This exposes an HTTP API that OCMux uses to send messages directly, cycle agent modes, and list available models. The session persists after you leave the conversation view.
52
85
 
53
86
  The dashboard polls every 2 seconds and updates status indicators automatically.
54
87
 
88
+ ### Dashboard
55
89
 
56
- ## Dashboard
57
-
58
- ```
90
+ ```text
59
91
  OCMux
60
92
  [Orchestrator] opus-4-6 [NORMAL] 73%
61
93
  ─────────────────────────────────────────────────────────────────────────
@@ -66,7 +98,7 @@ The dashboard polls every 2 seconds and updates status indicators automatically.
66
98
  k/j: nav Enter: open Tab: expand a: attach x: kill n: new q: quit
67
99
  ```
68
100
 
69
- Status indicators:
101
+ #### Status indicators
70
102
 
71
103
  | Symbol | Meaning |
72
104
  |--------|---------|
@@ -75,8 +107,23 @@ Status indicators:
75
107
  | `○` white | Idle |
76
108
  | `✗` red | Error in the last tool call |
77
109
 
78
- Pressing Tab on an instance expands its subagent tree, showing what child sessions are running beneath it. Each child shows its agent type (`[fixer]`, `[explorer]`, etc.), title, model, and how long ago it was active. Subagents can themselves be expanded if they spawned further children.
110
+ Pressing `Tab` on an instance expands its subagent tree, showing what child sessions are running beneath it. Each child shows its agent type (`[fixer]`, `[explorer]`, etc.), title, model, and how long ago it was active. Subagents can themselves be expanded if they spawned further children.
111
+
112
+ ### Spawned vs discovered sessions
113
+
114
+ Sessions spawned via OCMux (`n`) run as `opencode serve --port X` in the background. These sessions:
115
+
116
+ - Show `[live]` in the conversation header
117
+ - Support inline messaging from the conversation view
118
+ - Allow cycling agent modes with `Tab`
119
+ - Persist when you exit the conversation view
120
+ - Can be killed from the dashboard with `x`
121
+
122
+ Sessions discovered from existing `opencode` processes show `[read-only]`. These support:
79
123
 
124
+ - Full conversation history viewing
125
+ - Attaching to the TUI with `a` or `i` to send messages
126
+ - Agent mode display (read from the last assistant message)
80
127
 
81
128
  ## Keybindings
82
129
 
@@ -120,7 +167,6 @@ Pressing Tab on an instance expands its subagent tree, showing what child sessio
120
167
  | `Ctrl-X E` | Open current text in `$EDITOR` |
121
168
  | `Esc` | Exit insert mode, return to normal mode |
122
169
 
123
-
124
170
  ## Configuration
125
171
 
126
172
  Config file: `~/.config/ocmux/config.json`
@@ -163,24 +209,6 @@ All fields are optional. Unspecified fields use the defaults shown below.
163
209
  }
164
210
  ```
165
211
 
166
-
167
- ## Spawned vs discovered sessions
168
-
169
- Sessions spawned via OCMux (`n`) run as `opencode serve --port X` in the background. These sessions:
170
-
171
- - Show `[live]` in the conversation header
172
- - Support inline messaging from the conversation view
173
- - Allow cycling agent modes with Tab
174
- - Persist when you exit the conversation view
175
- - Can be killed from the dashboard with `x`
176
-
177
- Sessions discovered from existing `opencode` processes show `[read-only]`. These support:
178
-
179
- - Full conversation history viewing
180
- - Attaching to the TUI with `a` or `i` to send messages
181
- - Agent mode display (read from the last assistant message)
182
-
183
-
184
212
  ## Architecture
185
213
 
186
214
  OCMux reads session data directly from opencode's SQLite database (`~/.local/share/opencode/opencode.db`), which it shares with the opencode TUI. This means it sees all sessions instantly without any IPC or polling overhead beyond the 2-second refresh cycle.
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-multiplexer",
3
- "version": "0.1.1",
3
+ "version": "0.2.1",
4
4
  "type": "module",
5
5
  "description": "Multiplexer for opencode AI coding agent sessions",
6
6
  "keywords": ["opencode", "ai", "agent", "tui", "multiplexer"],
@@ -9,7 +9,7 @@
9
9
  },
10
10
  "scripts": {
11
11
  "dev": "bun src/index.tsx",
12
- "build": "bun build src/index.tsx --outdir dist --target bun"
12
+ "build": "bun build src/index.tsx --outdir dist --target bun --external react-devtools-core"
13
13
  },
14
14
  "dependencies": {
15
15
  "@opencode-ai/sdk": "^1.2.27",
@@ -25,5 +25,13 @@
25
25
  "@types/react": "^19.2.14",
26
26
  "typescript": "^5.9.3"
27
27
  },
28
- "license": "ISC"
28
+ "license": "ISC",
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "https://github.com/joeyism/opencode-multiplexer"
32
+ },
33
+ "homepage": "https://github.com/joeyism/opencode-multiplexer",
34
+ "bugs": {
35
+ "url": "https://github.com/joeyism/opencode-multiplexer/issues"
36
+ }
29
37
  }
package/src/poller.ts CHANGED
@@ -77,7 +77,10 @@ function getRunningOpencodeProcesses(): RunningProcess[] {
77
77
  const trimmed = line.trim()
78
78
 
79
79
  // Match TUI: "opencode" or "opencode -s {sessionId}"
80
- const tuiMatch = trimmed.match(/^(\d+)\s+opencode(?:\s+-s\s+(\S+))?$/)
80
+ // Linux: "node /path/to/opencode" wrapper is 1:1 with real sessions. macOS: bare "opencode".
81
+ // Never match ".opencode" — it's always a child process or orphaned subagent.
82
+ // NOTE: Does not match standalone binaries ("/usr/local/bin/opencode") — assumes npm/nvm/bun wrapper on Linux.
83
+ const tuiMatch = trimmed.match(/^(\d+)\s+(?:(?:node|bun|deno)\s+\S*\/opencode|opencode)(?:\s+-s\s+(\S+))?$/)
81
84
  if (tuiMatch) {
82
85
  const pid = parseInt(tuiMatch[1]!, 10)
83
86
  const sessionId = tuiMatch[2] ?? null
@@ -87,7 +90,8 @@ function getRunningOpencodeProcesses(): RunningProcess[] {
87
90
  }
88
91
 
89
92
  // Match serve: "opencode serve --port {port} ..."
90
- const serveMatch = trimmed.match(/^(\d+)\s+opencode\s+serve\s+.*--port\s+(\d+)/)
93
+ // Linux: "node /path/to/opencode" wrapper. macOS: bare "opencode".
94
+ const serveMatch = trimmed.match(/^(\d+)\s+(?:(?:node|bun|deno)\s+\S*\/opencode|opencode)\s+serve\s+.*--port\s+(\d+)/)
91
95
  if (serveMatch) {
92
96
  const pid = parseInt(serveMatch[1]!, 10)
93
97
  const port = parseInt(serveMatch[2]!, 10)
@@ -110,7 +110,8 @@ function findPidByWorktree(worktree: string): number | null {
110
110
  for (const line of psOutput.split("\n")) {
111
111
  const trimmed = line.trim()
112
112
  // Match both TUI and serve patterns
113
- const match = trimmed.match(/^(\d+)\s+opencode(?:\s+serve|\s+-s\s+\S+)?/)
113
+ // Linux: "node /path/to/opencode" wrapper. macOS: bare "opencode".
114
+ const match = trimmed.match(/^(\d+)\s+(?:(?:node|bun|deno)\s+\S*\/opencode|opencode)(?:\s+serve|\s+-s\s+\S+)?/)
114
115
  if (!match) continue
115
116
  const pid = parseInt(match[1]!, 10)
116
117
  try {