@gbasin/agentboard 0.38.0 → 0.38.2

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 (2) hide show
  1. package/README.md +182 -201
  2. package/package.json +6 -5
package/README.md CHANGED
@@ -6,283 +6,264 @@
6
6
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.x-3178c6?logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
7
7
  [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/gbasin/agentboard)
8
8
 
9
- Agentboard is a Web GUI for `tmux` that's optimized for agent TUI's (`claude`, `codex`, etc). A lighter-weight, agent-optimized alternative to Blink, Termux, etc.
9
+ Agentboard is a web UI for `tmux`, built for running coding agents such as Claude Code and Codex. Start your agents on a desktop or server, then watch and steer them from any browser, including your phone.
10
10
 
11
- Run your desktop/server, then connect from your phone or laptop over Tailscale/LAN. You get a shared workspace across devices.
11
+ Every session lives in tmux, so your agents keep running when you close the tab, and the same sessions are available from every device.
12
12
 
13
- - iOS Safari mobile experience with:
14
- - Paste support (including images)
15
- - Touch scrolling, tap-to-click, and long-press selection in fullscreen Claude Code sessions
16
- - Mobile-friendly copy prompts when browser clipboard writes need a user gesture
17
- - Virtual arrow keys / d-pad
18
- - Quick keys toolbar (ctrl, esc, etc.)
19
- - Claude Code fullscreen renderer support by default, with mouse scrolling, click handling, in-app selection, and clipboard forwarding through the browser terminal
20
- - Out-of-the-box log tracking and matching for Claude, Codex, and Pi — auto-matches sessions to active tmux windows, with one-click Wake for Hibernating and History sessions.
21
- - Shows the last user prompt for each session, so you can remember what each agent is working on
22
- - Hibernate sessions to close their tmux window while keeping them visible across restarts for manual Wake
13
+ <p align="center">
14
+ <img src="assets/readme/hero.webp" width="880" alt="Agentboard in a desktop browser window, with a phone in front of it. The desktop sidebar lists agent sessions with their status, age, last prompt and pull request chips; one session waits for permission. The terminal shows a Claude Code session refactoring a router, with a Media 2 pill in its corner. The phone shows the same session's terminal with a quick-keys toolbar.">
15
+ </p>
16
+ <p align="center"><sub>The same tmux sessions on a laptop and a phone.</sub></p>
23
17
 
24
- ## How It Works
18
+ ## Features
25
19
 
26
- ```
27
- ┌─────────────┐ SSH ┌─────────────┐
28
- │ Remote Host ├───────────►│ │ WebSocket ┌────────────┐
29
- │ (tmux) │ │ Agentboard ├──────────────►│ Browser │
30
- └─────────────┘ tmux │ Server │ │ (React + │
31
- ┌─────────────┐ CLI │ │ │ xterm.js) │
32
- │ Local tmux ├───────────►│ - discover │ └────────────┘
33
- │ sessions │ │ sessions │
34
- └─────────────┘ │ - parse │
35
- ┌─────────────┐ read │ agent │
36
- │ Agent logs ├───────────►│ logs │
37
- │ ~/.claude/ │ └─────────────┘
38
- └─────────────┘
39
- ```
20
+ <table>
21
+ <tr>
22
+ <td width="40%" valign="top">
40
23
 
41
- - **Session discovery** — polls local tmux windows and (optionally) remote hosts over SSH
42
- - **Status inference** — reads pane content and Claude/Codex JSONL logs to determine if each agent is *working*, *waiting for input*, or *asking for permission*
43
- - **Live terminal** — streams I/O through the server so you can interact with any session from any device
44
- - **Hibernating and History sessions** — keeps dormant agent sessions in the sidebar and wakes them on demand; startup does not auto-wake dormant sessions
24
+ ### Status and last prompt for every session
45
25
 
46
- ### Desktop
47
- | Terminal | Sessions | Hibernating |
48
- | :---: | :---: | :---: |
49
- | <img src="assets/desktop.png" alt="Terminal" height="400"/> | <img src="assets/sessions.png" alt="Sessions" height="400"/> | <img src="assets/pins.png" alt="Hibernating" height="400"/> |
26
+ Each session shows a status inferred from its terminal output: *working*, *waiting for input*, or *needs permission*. Sessions matched to an agent transcript also show the last prompt you sent. Optional sounds tell you when a session needs permission or goes idle.
50
27
 
51
- ### Mobile
52
- | Terminal | Controls |
53
- | :---: | :---: |
54
- | <img src="assets/mobile.jpeg" alt="Terminal" height="400"/> | <img src="assets/mobile-controls.jpeg" alt="Controls" height="400"/> |
28
+ </td>
29
+ <td width="60%">
30
+ <img src="assets/readme/status-loop.gif" width="520" alt="Animation: the sidebar lists sessions with their last prompts and ages. The selected session, orders-migration, shows a permission prompt to run a database migration; its status badge changes to a raised hand while the prompt is open, then back to now when the prompt is answered.">
31
+ </td>
32
+ </tr>
33
+ <tr>
34
+ <td width="40%" valign="top">
55
35
 
56
- ## Requirements
57
-
58
- - tmux (`brew install tmux` / `apt install tmux`)
59
- - [Tailscale](https://tailscale.com/download) (recommended) or any network path to your machine
60
-
61
- ## Install
62
-
63
- ### Homebrew
36
+ ### Subagent activity
64
37
 
65
- ```bash
66
- brew tap gbasin/tap
67
- brew install agentboard
68
- agentboard
69
- ```
38
+ For local Claude Code and Codex sessions, a counter on the session shows how many subagents are running. Click it to see the main session and each subagent with its current state and the time of its last activity signal.
70
39
 
71
- ### npm
40
+ </td>
41
+ <td width="60%">
42
+ <img src="assets/readme/subagents.webp" width="520" alt="The agent activity panel for the router-refactor session, opened from its subagent counter showing 3. The main session has an active model turn. Of four subagents, Migrate billing routes and Run e2e suite are waiting on Edit and Bash tool calls, Migrate invoice routes has an active model turn, and Audit auth middleware has finished.">
43
+ </td>
44
+ </tr>
45
+ <tr>
46
+ <td width="40%" valign="top">
72
47
 
73
- ```bash
74
- npm install -g @gbasin/agentboard
75
- agentboard
76
- ```
48
+ ### Pull requests with CI state
77
49
 
78
- Or run directly:
50
+ Pull requests that a session created with `gh pr create` or through the GitHub connector appear as chips on the session, colored by state: open, draft, merged, or closed. Claude Code sessions also show pull requests that Claude Code linked to the session, such as one it pushed to. Hover a chip to see its title and CI checks.
79
51
 
80
- ```bash
81
- npx @gbasin/agentboard
82
- ```
52
+ </td>
53
+ <td width="60%">
54
+ <img src="assets/readme/pull-requests.webp" width="520" alt="Four sidebar sessions with pull request chips: a draft (489), two open (482 and 1193) and a merged one (1187). A hover card for pull request 1193 shows its title and four CI checks, one of them failing.">
55
+ </td>
56
+ </tr>
57
+ <tr>
58
+ <td width="40%" valign="top">
83
59
 
84
- Then open `http://localhost:4040` (or `http://<your-machine>:4040` from another device).
60
+ ### Media from the transcript
85
61
 
86
- For persistent deployment, see [systemd/README.md](systemd/README.md) (Linux) or [launchd/README.md](launchd/README.md) (macOS).
62
+ A media rail collects the images, documents, and links from a session's transcript. Open any image in a viewer and step through the rest.
87
63
 
88
- ### From source
64
+ </td>
65
+ <td width="60%">
66
+ <img src="assets/readme/media-rail.webp" width="520" alt="The media rail open over a session's terminal: tabs for Media 5 and Links 1, then thumbnails for a PDF report, a search results screenshot, a CPU flame graph and two latency charts. Below it, the transcript lines where the agent read those files.">
67
+ </td>
68
+ </tr>
69
+ <tr>
70
+ <td width="40%" valign="top">
89
71
 
90
- Requires **Bun 1.3.14+** (see [Troubleshooting](#troubleshooting)).
72
+ ### History, Hibernate, and Wake
91
73
 
92
- ```bash
93
- bun install
94
- bun run dev
95
- ```
74
+ **Hibernate** closes an agent session's tmux window and keeps its conversation in the sidebar. It works for local sessions in the tmux session that Agentboard manages. **History** lists recent conversations: open one to preview its transcript, then **Wake** it to resume.
96
75
 
97
- Open `http://<your-machine>:5173` (Vite dev server). In production, UI is served from the backend port (default 4040).
76
+ </td>
77
+ <td width="60%">
78
+ <img src="assets/readme/history.webp" width="520" alt="The transcript preview of a past Claude Code conversation, admin-react-19, about upgrading an app to React 19, with Cancel and Wake buttons.">
79
+ </td>
80
+ </tr>
81
+ <tr>
82
+ <td colspan="2">
98
83
 
99
- Production:
84
+ ### On your phone
100
85
 
101
- ```bash
102
- bun run build
103
- bun run start
104
- ```
86
+ On a small screen the board switches to a touch layout: a session drawer, a quick-keys toolbar (Esc, Tab, Ctrl, arrow keys, numbers), and a paste dialog. Touch scrolling, tap-to-click, and long-press selection work in the terminal. Add the board to your home screen as a PWA.
105
87
 
106
- For persistent deployment, see [systemd/README.md](systemd/README.md) (Linux) or [launchd/README.md](launchd/README.md) (macOS).
88
+ <img src="assets/readme/phone.webp" width="880" alt="Three phone screens. Left: the session drawer listing sessions with status, last prompt and pull request chips. Middle: a session waiting on a permission prompt, with a row of numbered session tiles at the top and the quick-keys toolbar at the bottom. Right: the paste dialog with three lines of text ready to submit.">
107
89
 
108
- ## Dependency Risk Scanner
90
+ </td>
91
+ </tr>
92
+ <tr>
93
+ <td width="40%" valign="top">
109
94
 
110
- Use the built-in scanner to report security and maintenance risk for direct dependencies:
95
+ ### Sessions from other machines
111
96
 
112
- ```bash
113
- bun run deps:risk
114
- ```
97
+ Sessions from other machines appear on the same board over SSH, with a host badge on each one. Filter the board by host or by project. See [Remote hosts](docs/remote-hosts.md).
115
98
 
116
- Machine-readable output:
99
+ </td>
100
+ <td width="60%">
101
+ <img src="assets/readme/hosts.webp" width="520" alt="Five sidebar sessions from two machines: rows badged STUDIO run locally, rows badged BUILD-BOX run on a remote host. The remote Codex session nightly-e2e is selected.">
102
+ </td>
103
+ </tr>
104
+ </table>
117
105
 
118
- ```bash
119
- bun run deps:risk:json
120
- ```
106
+ ### Also
121
107
 
122
- Policy:
108
+ - A full terminal in the browser. Mouse scrolling, selection, and the clipboard work with Claude Code's fullscreen renderer.
109
+ - Paste or drop text, images, and files into the prompt.
110
+ - Keyboard shortcuts to switch, create, and close sessions.
111
+ - Sort by age or by what needs attention, filter by project or host, or drag sessions into your own order.
112
+ - Session recovery lists the sessions that a crash or reboot interrupted, so you can reopen them. Automatic reopening is opt-in. See [Session recovery](docs/session-recovery.md).
123
113
 
124
- - Security risk comes from `bun audit --json` findings and is aggregated by severity (`low`, `moderate`, `high`, `critical`).
125
- - Maintenance risk comes from `bun outdated` and classifies version lag as `major`, `minor`, or `patch` behind latest.
126
- - Local default threshold is `high` (`high` + `critical` fail).
127
- - CI enforces security threshold breaches at `critical` only (`bun run deps:risk:ci`) while existing upstream `high` advisories are tracked; maintenance findings are warnings for prioritization.
114
+ ## Supported agents
128
115
 
129
- You can override the security threshold with `--threshold` (or `DEPENDENCY_RISK_FAIL_ON`):
116
+ | Agent | Matching, last prompt, Wake | Pull requests | Media rail | Subagent activity |
117
+ | --- | :---: | :---: | :---: | :---: |
118
+ | Claude Code | Yes | Yes | Yes | Yes |
119
+ | Codex | Yes | Yes | Yes | Yes |
120
+ | Pi | Yes | Yes | Links | |
121
+ | oh-my-pi | Yes | Yes | Links | |
122
+ | Devin CLI | Yes | Yes | Links | |
123
+ | Grok CLI | Yes | Yes | Links | |
130
124
 
131
- ```bash
132
- bun run deps:risk -- --threshold moderate
133
- ```
125
+ The media rail shows images, documents, and links for Claude Code and Codex. For the other agents it shows links.
134
126
 
135
- ## Session recovery
127
+ Agentboard finds each agent's transcripts in its default location and matches them to tmux windows automatically. Any other program that runs in tmux also works as a plain terminal session, with status but no transcript features.
136
128
 
137
- **Session recovery** keeps session names, projects, launch details, and earlier runs across restarts. New sessions are saved before their terminal starts, including shells and agents that have not written a conversation log yet.
129
+ ## Requirements
138
130
 
139
- - Review interrupted sessions and reopen them from the recovery panel.
140
- - Hibernate or archive sessions without deleting their saved metadata.
131
+ - macOS (Apple Silicon or Intel) or Linux (x64 or arm64).
132
+ - tmux 3.2 or later: `brew install tmux` or `apt install tmux`.
133
+ - [ripgrep](https://github.com/BurntSushi/ripgrep) (`rg`): `brew install ripgrep` or `apt install ripgrep`. Agentboard uses it to match agent transcripts to tmux windows. The Homebrew and npm packages do not install it.
134
+ - [Tailscale](https://tailscale.com/download) (recommended) or another network path to your machine, for access from other devices.
141
135
 
142
- Automatic reopening is off by default. A reboot stops the underlying processes; reopening resumes supported conversations or launches a fresh shell. See the [recovery guide](docs/session-recovery.md) for defaults and limits.
136
+ Optional:
143
137
 
144
- ## Keyboard Shortcuts
138
+ - The [GitHub CLI](https://cli.github.com/) (`gh`), signed in, to show pull request state and CI checks.
139
+ - `ssh` with key-based access, to show sessions from [remote hosts](docs/remote-hosts.md).
145
140
 
146
- | Action | Mac | Windows/Linux |
147
- |--------|-----|---------------|
148
- | Previous session | `Ctrl+Option+[` | `Ctrl+Shift+[` |
149
- | Next session | `Ctrl+Option+]` | `Ctrl+Shift+]` |
150
- | Jump to session 1-9 | `Ctrl+Option+1..9` | `Ctrl+Shift+1..9` |
151
- | New session | `Ctrl+Option+N` | `Ctrl+Shift+N` |
152
- | Kill session | `Ctrl+Option+X` | `Ctrl+Shift+X` |
141
+ ## Install
153
142
 
154
- ## Environment
143
+ ### Homebrew
155
144
 
145
+ ```bash
146
+ brew tap gbasin/tap
147
+ brew install agentboard
148
+ agentboard
156
149
  ```
157
- PORT=4040
158
- HOSTNAME=127.0.0.1
159
- TMUX_SESSION=agentboard
160
- REFRESH_INTERVAL_MS=5000
161
- DISCOVER_PREFIXES=work,external
162
- ALLOW_KILL_EXTERNAL=false
163
- PRUNE_WS_SESSIONS=true
164
- AGENTBOARD_PREFER_WINDOW_NAME=false
165
- TERMINAL_MODE=pty
166
- AGENTBOARD_CLAUDE_NO_FLICKER=true
167
- AGENTBOARD_TMUX_SET_CLIPBOARD=true
168
- AGENTBOARD_TMUX_SYNC=true
169
- TERMINAL_MONITOR_TARGETS=true
170
- VITE_ALLOWED_HOSTS=nuc,myserver
171
- AGENTBOARD_DB_PATH=~/.agentboard/agentboard.db
172
- AGENTBOARD_INACTIVE_MAX_AGE_HOURS=24
173
- AGENTBOARD_EXCLUDE_PROJECTS=<empty>,/workspace
174
- AGENTBOARD_HOST=blade
175
- AGENTBOARD_REMOTE_HOSTS=mba,carbon,worm
176
- AGENTBOARD_REMOTE_POLL_MS=2000
177
- AGENTBOARD_REMOTE_TIMEOUT_MS=4000
178
- AGENTBOARD_REMOTE_STALE_MS=45000
179
- AGENTBOARD_REMOTE_SSH_OPTS=-o BatchMode=yes -o ConnectTimeout=3
180
- AGENTBOARD_REMOTE_ALLOW_ATTACH=false
181
- AGENTBOARD_REMOTE_ALLOW_CONTROL=false
182
- AGENTBOARD_LOG_WATCH_MODE=watch
183
- AGENTBOARD_PASTE_IMAGE_MAX_BYTES=41943040
184
- ```
185
-
186
- `HOSTNAME` controls which interfaces the server binds to (default `127.0.0.1` for localhost-only). With the default localhost binding, if Tailscale is detected the server also binds to your Tailscale IP automatically. Set to `0.0.0.0` to listen on all interfaces. A `HOSTNAME` that merely equals the machine hostname is treated as auto-exported by the environment (containers and some CI images do this) and ignored with a warning, keeping the localhost default.
187
-
188
- > **Security note:** Agentboard has no built-in authentication. Anyone who can reach the server has full access to your terminal sessions, including the ability to run commands as your user. The default localhost binding is safe. Tailscale provides network-level auth for remote access. Avoid setting `HOSTNAME=0.0.0.0` on untrusted networks (public WiFi, shared LANs) without an additional access control layer.
189
-
190
- `DISCOVER_PREFIXES` lets you discover and control windows from other tmux sessions. If unset, all sessions except the managed one are discovered. Windows named `__agentboard_root__` are always hidden — that name is reserved for the placeholder that keeps a base session alive.
191
-
192
- `ALLOW_KILL_EXTERNAL` (default `false`) controls whether externally-discovered sessions can be killed from the UI. Set to `true` to allow it.
193
-
194
- `PRUNE_WS_SESSIONS` removes orphaned `agentboard-ws-*` tmux sessions on startup (set to `false` to disable).
195
150
 
196
- `AGENTBOARD_PREFER_WINDOW_NAME` (default `false`) controls how externally-discovered sessions are labeled. When `false`, the tmux session name is used (more meaningful than auto-renamed window names that follow the running process under tmux `automatic-rename on`). Set to `true` to use the tmux window name when it is non-empty and distinct from the session name — useful when you keep one shared session (e.g. `dev`) with one explicitly-named window per project (`myapp`, `infra`, ...).
197
-
198
- `TERMINAL_MODE` selects terminal I/O strategy: `pty` (default, grouped session) or `pipe-pane` (PTY-less, works in daemon/systemd/docker without `-t`).
151
+ ### npm
199
152
 
200
- `AGENTBOARD_CLAUDE_NO_FLICKER` controls how Agentboard launches new Claude Code windows. By default, Agentboard sets `CLAUDE_CODE_NO_FLICKER=1` on newly-created panes so Claude uses its fullscreen renderer with mouse scrolling, click handling, in-app selection, and flat memory usage for long conversations. Set `AGENTBOARD_CLAUDE_NO_FLICKER=0` (or `false`) before starting Agentboard to launch Claude without that env var. Fullscreen rendering requires Claude Code v2.1.89 or later; older Claude Code versions should ignore the env var and use the classic renderer.
153
+ Requires Node.js 18 or later.
201
154
 
202
- Reasons to opt out: fullscreen rendering keeps the conversation in the alternate screen buffer instead of native terminal scrollback, so terminal-level search/copy workflows behave differently; Claude also captures mouse events unless you disable its mouse capture. Inside Claude Code, run `/tui default` to switch a session back to the classic renderer, or launch Claude with `CLAUDE_CODE_DISABLE_MOUSE=1` if you want fullscreen rendering but native mouse selection.
155
+ ```bash
156
+ npm install -g @gbasin/agentboard
157
+ agentboard
158
+ ```
203
159
 
204
- `AGENTBOARD_TMUX_SET_CLIPBOARD` controls whether Agentboard enables tmux's `set-clipboard on` when it attaches. By default it does, so copies made inside a session land in a tmux paste buffer that Agentboard can relay to the browser clipboard (important on iOS Safari, where the async OSC 52 path can't satisfy the user-gesture rule). Because `set-clipboard` is a server-global tmux option, this affects your whole tmux server and is not reverted on disconnect — set `AGENTBOARD_TMUX_SET_CLIPBOARD=0` (or `false`) to leave your tmux configuration untouched.
160
+ Or run it without installing:
205
161
 
206
- `AGENTBOARD_TMUX_SYNC` controls whether Agentboard's tmux client advertises synchronized-update support (`tmux -T sync`, tmux 3.2+). By default it does, so tmux wraps redraws in DEC 2026 frame markers and the browser terminal paints each frame atomically instead of tearing during fast fullscreen repaints (e.g. Claude Code's no-flicker renderer). The flag applies only to Agentboard's own client and does not change tmux server options. Set `AGENTBOARD_TMUX_SYNC=0` (or `false`) to disable.
162
+ ```bash
163
+ npx @gbasin/agentboard
164
+ ```
207
165
 
208
- When you open an externally-discovered tmux session, Agentboard attaches through a per-connection session grouped with it (`agentboard-ws-<connection>-x-<session>-<hash>`), so focus in the browser stays independent of your own tmux clients. Two side effects: these derived sessions appear in `tmux ls` while a viewer is attached (they are removed on switch-away and disconnect, and pruned at startup), and killing the raw session keeps its windows alive until the last grouped viewer switches away (tmux keeps a group's windows while any member session exists).
166
+ ### Open the board
209
167
 
210
- `TERMINAL_MONITOR_TARGETS` (pipe-pane only) polls tmux to detect closed targets (set to `false` to disable).
168
+ Open `http://localhost:4040` on the same machine.
211
169
 
212
- `VITE_ALLOWED_HOSTS` allows access to the Vite dev server from other hostnames. Useful with Tailscale MagicDNS - add your machine name (e.g., `nuc`) to access the dev server at `http://nuc:5173` from other devices on your tailnet.
170
+ If Tailscale is running, Agentboard also listens on your Tailscale address. Open `http://<your-machine>:4040` from any device on your tailnet. To install the board on your phone's home screen, see [PWA installation](docs/pwa-install.md).
213
171
 
214
- All persistent data is stored in `~/.agentboard/`: session database (`agentboard.db`) and logs (`agentboard.log`). Override paths with `AGENTBOARD_DB_PATH` and `LOG_FILE`.
172
+ Without Tailscale, Agentboard accepts connections from the same machine only. To change that, see [Network and security](docs/configuration.md#network-and-security).
215
173
 
216
- `AGENTBOARD_INACTIVE_MAX_AGE_HOURS` controls the sidebar lookback (default: 24 hours, up to 100 recent entries). The env var name is kept for compatibility.
174
+ ### Run it as a service
217
175
 
218
- `AGENTBOARD_EXCLUDE_PROJECTS` filters out sessions from specific project directories (comma-separated). Use `<empty>` to exclude sessions with no project path. Useful for hiding automated/spam sessions.
176
+ To start Agentboard at login and keep it running:
219
177
 
220
- `AGENTBOARD_SKIP_MATCHING_PATTERNS` controls which orphan sessions skip expensive window matching (comma-separated). Defaults: `<codex-exec>` (headless Codex exec sessions), `/private/tmp/*`, `/private/var/folders/*`, `/var/folders/*`, `/tmp/*`. Patterns support trailing `*` for prefix matching. Set to empty string to disable skip matching entirely.
178
+ - macOS: [launchd/README.md](launchd/README.md)
179
+ - Linux: [systemd/README.md](systemd/README.md)
221
180
 
222
- `AGENTBOARD_HOST` sets the host label for local sessions (default: `hostname`).
181
+ Both installers need a git checkout of this repository. They do not use a Homebrew or npm install.
223
182
 
224
- `AGENTBOARD_REMOTE_HOSTS` enables remote tmux polling over SSH. Provide a comma-separated list of hosts (e.g., `mba,carbon,worm`). Remote sessions show live status (working/waiting/permission) via pane content capture over SSH.
183
+ ### Upgrade
225
184
 
226
- `AGENTBOARD_REMOTE_POLL_MS`, `AGENTBOARD_REMOTE_TIMEOUT_MS`, and `AGENTBOARD_REMOTE_STALE_MS` control remote poll cadence, SSH timeout, and stale host cutoff.
185
+ Run `brew upgrade agentboard` or `npm install -g @gbasin/agentboard@latest`, then restart Agentboard. Your tmux sessions keep running across the restart, and your data stays in `~/.agentboard`.
227
186
 
228
- `AGENTBOARD_REMOTE_SSH_OPTS` appends extra SSH options (space-separated).
187
+ These commands do not upgrade a service installed with the launchd or systemd installer. Upgrade a service as its guide describes.
229
188
 
230
- `AGENTBOARD_REMOTE_ALLOW_ATTACH` enables interactive terminal attach to remote sessions (input, resize, copy-mode). When `false` (default), remote sessions are view-only.
189
+ ### Uninstall
231
190
 
232
- `AGENTBOARD_REMOTE_ALLOW_CONTROL` enables destructive remote session management (create, kill, rename) via the UI. Setting this to `true` implies `REMOTE_ALLOW_ATTACH=true`. Kill and rename are restricted to agentboard-managed sessions — externally-discovered remote sessions cannot be killed or renamed even with control enabled.
191
+ Stop Agentboard, then run `brew uninstall agentboard` or `npm uninstall -g @gbasin/agentboard`.
233
192
 
234
- `AGENTBOARD_LOG_WATCH_MODE` selects the log detection strategy: `watch` (default) uses `fs.watch` for instant file-change detection, `poll` falls back to periodic directory scanning. Use `poll` if you experience issues with filesystem notifications (e.g., on network-mounted home directories). On Linux, watch mode automatically includes a 15-second fallback poll since `fs.watch({ recursive: true })` has known platform bugs.
193
+ `brew uninstall` also removes tmux if no other formula needs it. To keep tmux, run `HOMEBREW_NO_AUTOREMOVE=1 brew uninstall agentboard`.
235
194
 
236
- `AGENTBOARD_OWNERSHIP_OBSERVER=true` enables read-only ownership diagnostics for local Claude and Codex sessions. It checks at startup and every 30 seconds. The diagnostics flag defaults to off. For read-only observation on macOS, also set `AGENTBOARD_OWNERSHIP_MATCHING=false`. Changed results appear as `ownership_observation` log events with `agree`, `unmatched`, `disagree`, or `unresolved` comparisons. Set `LOG_LEVEL=debug` to include per-cycle counts and duration.
195
+ If you installed a service, remove it first. For that, and for the data and settings that an uninstall leaves in place, see [Uninstall](docs/uninstall.md).
237
196
 
238
- Ownership-based matching is enabled by default on macOS. Set `AGENTBOARD_OWNERSHIP_MATCHING=false` to opt out. Matching also enables the observer. Confirmed ownership takes precedence over scrollback, name, and slug matching. It can match idle sessions and switch a window to a different known conversation atomically. It never steals a conversation from another window or changes a session with a pending stop/wake. Inspection failures preserve existing associations. Other agents keep the existing matching behavior.
197
+ ### From source
239
198
 
240
- A conversation must first enter the log database. Missing Codex transcripts are queued directly for discovery; Claude uses the normal transcript discovery pipeline. A later ownership check binds the discovered conversation (checks run every 30 seconds). The flag has no effect on Linux until live validation is complete. Set `AGENTBOARD_OWNERSHIP_MATCHING=false` and restart to return to the existing matcher; already matched sessions remain in the database. No agent configuration changes are required.
199
+ See [Development](docs/development.md).
241
200
 
242
- Claude identity comes from its local PID registry, checked against the running process. Codex identity comes from writable root transcripts and open writer-lock descriptors. Shared-daemon Codex sessions, ambiguous roots, and unsupported registry formats remain unresolved. These readers use internal agent formats. Live validation currently covers macOS; Linux needs live validation before enabling ownership writes.
201
+ ## Configuration
243
202
 
244
- To compare a running instance once from a source checkout, supply its socket and API address:
203
+ Agentboard is configured with environment variables. It has no command-line flags.
245
204
 
246
205
  ```bash
247
- bun scripts/observe-session-ownership.ts --socket /private/tmp/tmux-501/default --api http://127.0.0.1:4040
206
+ PORT=8080 TMUX_SESSION=work agentboard
248
207
  ```
249
208
 
250
- Replace the socket path with the instance's actual tmux socket. This command reads process metadata and session headers. It sends no terminal input and makes no API writes. Use `--claude-home` or `--codex-home` for nondefault agent directories. The observer requires `ps`, `tmux`, and, for Codex, `lsof`.
209
+ | Variable | Default | Effect |
210
+ | --- | --- | --- |
211
+ | `PORT` | `4040` | Port for the web UI. |
212
+ | `HOSTNAME` | `127.0.0.1` | Address to bind. Set `0.0.0.0` to listen on all interfaces. |
213
+ | `TMUX_SESSION` | `agentboard` | Name of the tmux session that Agentboard manages. |
214
+ | `DISCOVER_PREFIXES` | unset | Limits which of your other tmux sessions appear on the board. By default, all of them appear. |
215
+ | `AGENTBOARD_REMOTE_HOSTS` | unset | SSH hosts to show on the board. |
216
+ | `AGENTBOARD_DATA_DIR` | `~/.agentboard` | Directory for the database and logs. |
251
217
 
252
- Paste text or files directly into the terminal prompt. Desktop clipboard paste and file drops upload device files and insert their paths without pressing Enter. On mobile, **Paste** opens a dialog with a field for native clipboard paste and **Choose files** for selecting one or more files. File uploads accept any extension, up to 40 MB per file. Files are stored temporarily on the Agentboard host; uploads are unavailable for SSH sessions.
218
+ See [Configuration](docs/configuration.md) for every setting.
253
219
 
254
- The mobile dialog works the same over HTTP and HTTPS. Touch and hold in the field to paste, or select **Choose files**. Either action inserts directly into the existing terminal prompt without submitting it. Automatic clipboard reads elsewhere depend on browser support and permission and require HTTPS or localhost.
220
+ Appearance, notification sounds, command presets, session list options, and terminal options are in the **Settings** dialog in the UI.
255
221
 
256
- `AGENTBOARD_PASTE_IMAGE_MAX_BYTES` caps clipboard image uploads (default 40 MB, enough for full-resolution photos pasted as PNG). Image attachments support PNG, JPEG, GIF, and WebP.
222
+ > **Security note:** Agentboard has no authentication. Anyone who can reach the server can run commands as your user. By default it accepts connections from this machine and, if Tailscale is running, from your tailnet. Do not set `HOSTNAME=0.0.0.0` on a network that you do not trust (public Wi-Fi, a shared LAN) without another access control layer. See [SECURITY.md](SECURITY.md#threat-model) for the full threat model.
257
223
 
258
- **SSH multiplexing (recommended):** Each poll cycle opens SSH connections to every remote host. Enable SSH connection multiplexing to reuse connections and reduce overhead from ~200-500ms to ~5ms per poll. Add to your `~/.ssh/config`:
224
+ ## Keyboard shortcuts
259
225
 
260
- ```
261
- Host *
262
- ControlMaster auto
263
- ControlPath ~/.ssh/sockets/%r@%h-%p
264
- ControlPersist 600
265
- ```
226
+ | Action | Mac | Windows/Linux |
227
+ |--------|-----|---------------|
228
+ | Previous session | `Ctrl+Option+[` | `Ctrl+Shift+[` |
229
+ | Next session | `Ctrl+Option+]` | `Ctrl+Shift+]` |
230
+ | Jump to session 1-9 | `Ctrl+Option+1..9` | `Ctrl+Shift+1..9` |
231
+ | New session | `Ctrl+Option+N` | `Ctrl+Shift+N` |
232
+ | Kill session | `Ctrl+Option+X` | `Ctrl+Shift+X` |
233
+ | Settings | `Ctrl+Option+,` | `Ctrl+Shift+,` |
266
234
 
267
- Then create the sockets directory: `mkdir -p ~/.ssh/sockets && chmod 700 ~/.ssh/sockets`
235
+ To use a different modifier, open **Settings** > **Terminal**.
268
236
 
269
- ## Logging
237
+ ## How it works
270
238
 
271
239
  ```
272
- LOG_LEVEL=info # debug | info | warn | error (default: info)
273
- LOG_FILE=~/.agentboard/agentboard.log # default; set empty to disable file logging
274
- ```
275
-
276
- Console output is pretty-printed in development, JSON in production (`NODE_ENV=production`). File output is always JSON. Set `LOG_FILE=` (empty) to disable file logging.
277
-
278
- ## Troubleshooting
279
-
280
- ### "open terminal failed: not a terminal" errors
281
-
282
- If you see infinite `open terminal failed: not a terminal` errors, you need to upgrade Bun:
283
-
284
- ```bash
285
- bun upgrade
240
+ ┌─────────────┐ SSH ┌─────────────┐
241
+ │ Remote Host ├───────────►│ │ WebSocket ┌────────────┐
242
+ │ (tmux) │ │ Agentboard ├──────────────►│ Browser │
243
+ └─────────────┘ tmux │ Server │ │ (React + │
244
+ ┌─────────────┐ CLI │ │ │ xterm.js) │
245
+ │ Local tmux ├───────────►│ - discover │ └────────────┘
246
+ │ sessions │ │ sessions │
247
+ └─────────────┘ │ - parse │
248
+ ┌─────────────┐ read │ agent │
249
+ │ Agent logs ├───────────►│ logs │
250
+ │ │ └─────────────┘
251
+ └─────────────┘
286
252
  ```
287
253
 
288
- **Root cause**: Bun versions prior to 1.3.6 had a bug where the `terminal` option in `Bun.spawn()` incorrectly set stdin to `/dev/null` instead of the PTY. Since `tmux attach` requires stdin to be a terminal, it fails immediately. This was fixed in Bun 1.3.6.
254
+ - **Session discovery:** The server polls local tmux windows and, if you configure them, remote hosts over SSH.
255
+ - **Status inference:** The server reads pane content to tell if each agent is *working*, *waiting for input*, or *asking for permission*.
256
+ - **Log matching:** The server reads agent transcripts to match each session to its tmux window and to show its last prompt, pull requests, and media.
257
+ - **Live terminal:** The server streams terminal I/O to the browser, so you can use any session from any device.
258
+ - **Hibernating and History sessions:** The sidebar keeps dormant agent sessions, and you wake one when you need it. Startup does not wake hibernating or History sessions.
259
+
260
+ ## Documentation
261
+
262
+ - [Configuration](docs/configuration.md): every environment variable.
263
+ - [Remote hosts](docs/remote-hosts.md): sessions from other machines over SSH.
264
+ - [Session recovery](docs/session-recovery.md): reopen sessions after a crash or reboot.
265
+ - [PWA installation](docs/pwa-install.md): add the board to your phone's home screen.
266
+ - [Uninstall](docs/uninstall.md): remove Agentboard, and what stays behind.
267
+ - [macOS service](launchd/README.md) and [Linux service](systemd/README.md).
268
+ - [Development](docs/development.md): run from source and contribute.
269
+ - [Security policy](SECURITY.md).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gbasin/agentboard",
3
- "version": "0.38.0",
3
+ "version": "0.38.2",
4
4
  "type": "module",
5
5
  "description": "Web GUI for tmux optimized for AI agent TUIs",
6
6
  "author": "gbasin",
@@ -20,10 +20,10 @@
20
20
  "bun": ">=1.3.14"
21
21
  },
22
22
  "optionalDependencies": {
23
- "@gbasin/agentboard-darwin-arm64": "0.38.0",
24
- "@gbasin/agentboard-darwin-x64": "0.38.0",
25
- "@gbasin/agentboard-linux-x64": "0.38.0",
26
- "@gbasin/agentboard-linux-arm64": "0.38.0"
23
+ "@gbasin/agentboard-darwin-arm64": "0.38.2",
24
+ "@gbasin/agentboard-darwin-x64": "0.38.2",
25
+ "@gbasin/agentboard-linux-x64": "0.38.2",
26
+ "@gbasin/agentboard-linux-arm64": "0.38.2"
27
27
  },
28
28
  "scripts": {
29
29
  "dev": "concurrently -k \"bun run dev:server\" \"bun run dev:client\"",
@@ -42,6 +42,7 @@
42
42
  "coverage:all": "bun scripts/coverage-all.ts",
43
43
  "test:e2e": "playwright test",
44
44
  "test:e2e:headed": "playwright test --headed",
45
+ "readme:shots": "bun --no-env-file scripts/readme-shots/index.ts",
45
46
  "prepare": "git config core.hooksPath .githooks",
46
47
  "test:activity:coverage": "bun test --coverage --coverage-reporter=lcov --coverage-dir=coverage/activity src/server/__tests__/sessionActivity.test.ts src/server/__tests__/sessionActivityClient.test.ts && bun scripts/check-activity-coverage.ts"
47
48
  },