@bramblex/codex-workbench
v0.2.20
Published
Terminal workbench for browsing and managing local and SSH Codex sessions.
Maintainers
Readme
codex-workbench
A keyboard-driven terminal UI for browsing, organizing, and resuming coding-agent sessions — locally and across SSH remotes.

What is it?
codex-workbench is an interactive terminal UI for coding-agent sessions. Instead of digging through backend-specific session directories by hand, you get a fast, keyboard-driven interface to browse, search, rename, and delete sessions — all without leaving the terminal.
It also connects to remote machines over SSH, so you can manage sessions across all your servers from a single pane of glass.
Built-in backends currently include Codex, Claude Code, pi, and opencode. The backend layer is intentionally provider-based so additional agents can be added without changing the TUI workflow.
A handful of CLI subcommands are available for scripting, but the TUI is the product.
Quick start
npm install -g @bramblex/codex-workbenchVerify your backends are reachable, then open the workbench:
codex-workbench doctor
cwbThat's it. cwb with no arguments opens the TUI.
Interactive TUI
The TUI has two columns: a machine/project/session tree on the left, and the selected details or agent terminal on the right. Local sessions load instantly; remote SSH sources stream in asynchronously.
When you resume or start a session from the TUI, it opens in the right-hand agent pane so multiple sessions can keep running inside one workbench. F2 opens or focuses a smaller shell pane for the current session or project; that shell stays visible until it exits.
Sessions are grouped by machine, then project. On macOS, Codex scratch conversations whose cwd looks like ~/Documents/Codex/YYYY-MM-DD/... are grouped under a virtual Codex Scratch project and sorted after regular projects, so date-based scratch folders do not take over the tree.
For Codex sessions, workbench also reads generated thread names from $CODEX_HOME/session_index.jsonl when available. A manual workbench rename still wins, but generated Codex names are used before falling back to the first prompt.
When a newer codex-workbench package is available, the TUI shows an update hint in the header. Press u to confirm, install that exact version globally, and exit the old cwb process.
Keyboard shortcuts
| Key | Action |
|-----|--------|
| Enter | Open or focus selected session in the right agent pane |
| F2 | Open/focus the shell pane, or return from shell focus to the agent/detail pane |
| Ctrl+] | Return from a terminal pane to the session tree |
| Tab / S-Tab | Switch focus between panes |
| ← / h | Fold or move to the parent tree item |
| → / l | Expand or move focus to the details/terminal pane |
| ↑ ↓ / j k | Move selection up/down |
| Ctrl+u / Ctrl+d | Move a half page up/down |
| Ctrl+b / Ctrl+f | Move a full page up/down |
| g / G | Move to the first/last item |
| Shift+h / Shift+m / Shift+l | Move to the top/middle/bottom visible item |
| [ ] | Previous / next project in the tree |
| { } | Previous / next machine in the tree |
| / | Search the session tree |
| R | Refresh local and remote sessions |
| n | New session in the selected project; on a machine, choose a project first |
| N | Choose a project and start a new session there |
| u | Update codex-workbench when an update is available |
| c | Close selected open session |
| r | Rename selected session |
| d | Delete selected session |
| q | Quit |
Search picker
Press / from the session tree to open the search picker. Search matches session titles, generated Codex names, prompts, cwd, project labels, source labels, backend names, and session ids. Multiple words are matched as tokens, and results are sorted by most recently updated session first.
| Key | Action |
|-----|--------|
| Text input | Update the query |
| ↑ / Ctrl+p | Move to the previous result |
| ↓ / Ctrl+n | Move to the next result |
| Ctrl+u | Clear the query |
| Ctrl+w | Delete the previous word |
| Enter | Open selected session in the right agent pane |
| Esc | Cancel |
Directory picker
| Key | Action |
|-----|--------|
| ↑ ↓ / j k | Move selection |
| ← / h | Go to parent directory |
| → / l | Enter child directory |
| n | Create a new subdirectory |
| Enter | Choose selected directory |
| q / Esc | Cancel |
Remote SSH sources
codex-workbench can show sessions from remote machines by running cwb over SSH. Remote sources appear alongside Local in the TUI and load asynchronously.
Tree-level shortcuts such as [], {}, n, N, and / only apply while the tree is focused; the details pane keeps its own simpler controls.
Requirements
The remote must have codex-workbench installed and cwb available from the remote user's default login shell. Test it:
ssh user@host 'exec "${SHELL:-/bin/sh}" -lic "cwb list --json --compact"'Configuration
The TUI creates ~/.cwb/config.json on first run and asks whether anonymous update-check stats may be sent. You can also edit it manually:
{
"cwb": {
"installId": "cwb-00000000-0000-4000-8000-000000000000",
"updates": {
"enabled": true
},
"telemetry": {
"prompted": true,
"enabled": false
}
},
"servers": [
{
"id": "devbox",
"label": "SSH · Dev Box",
"target": "[email protected]"
},
{
"id": "gpu",
"label": "SSH · GPU Server",
"target": "gpu-host",
"command": "/usr/local/bin/cwb",
"sshArgs": ["-p", "2222"]
},
{
"id": "winbox",
"label": "SSH · Windows Box",
"target": "alice@windows-host",
"shell": "powershell",
"command": "cwb"
}
]
}If cwb.telemetry.enabled is true, update checks use the built-in cwb stats endpoint (https://brambles.top/cwb/latest) and append install_id and version query parameters. The response is parsed like npm's /latest response and must include a version field. If telemetry is disabled, update checks use npm directly and do not send the install id.
| Field | Required | Description |
|-------|----------|-------------|
| target | Yes | SSH destination (user@host or hostname) |
| label | No | Display name in the TUI |
| id | No | Short identifier (defaults to sanitized target) |
| command | No | Path to cwb on the remote (default: cwb) |
| shell | No | Remote command shell: posix (default) or powershell |
| sshArgs | No | Extra SSH flags, e.g. ["-p", "2222"] |
Operations like rename, new, resume, and delete are forwarded to the remote cwb transparently.
Remote backends are supported as long as the remote cwb can read them.
For Windows OpenSSH targets, configure the remote SSH default shell as
PowerShell and set "shell": "powershell". Windows-native npm shims such as
cwb.cmd, codex.cmd, claude.cmd, and npm.cmd are discovered through
PATHEXT and launched through PowerShell.
Backends
codex-workbench auto-detects installed backends by checking each backend's session storage.
| Backend | Sessions | Binary override | Notes |
|---------|----------|-----------------|-------|
| codex | $CODEX_SESSIONS_DIR or ~/.codex/sessions | CODEX_BIN | Uses the Codex CLI for new, resume, and delete. |
| claude | $CLAUDE_PROJECTS_DIR or ~/.claude/projects | CLAUDE_BIN | Uses the Claude Code CLI for new and resume; delete removes the session file. |
| pi | $PI_CODING_AGENT_SESSION_DIR or $PI_CODING_AGENT_DIR/sessions | PI_BIN | Uses the pi CLI for new and resume; delete removes the session file. |
| opencode | $OPENCODE_DB, $OPENCODE_DATA_DIR/opencode.db, or ~/.local/share/opencode/opencode.db | OPENCODE_BIN | Uses the opencode CLI and database for list, new, resume, and delete. |
Session metadata such as custom names is stored in workbench's own metadata file, not inside backend session files.
Codex approval-assessment helper sessions are treated as internal noise and hidden from session lists, including compact local and remote listings.
Every provider owns the full workbench command surface it advertises: new, resume, and delete. A provider can implement an operation through its native CLI, workbench metadata, or file operations, but callers should not need provider-specific fallback logic.
CLI commands
The TUI is the primary interface, but every action is also available as a CLI subcommand for scripting and automation.
cwb list # human-readable, grouped by source + project
cwb list --json --compact # machine-readable, omits message history
cwb list --cwd ~/projects/foo # filter to one working directory
cwb backends --json # list detected local backends
cwb show <session> # full session details
cwb rename <session> "fix auth" # give a session a memorable name
cwb close <session> # close an open resume process
cwb delete <session> --force
cwb new --cwd ~/projects/foo --backend codex "Summarize this repo"
cwb new --cwd ~/projects/foo --backend claude "Summarize this repo"
cwb new --cwd ~/projects/foo --backend pi "Summarize this repo"
cwb new --cwd ~/projects/foo --backend opencode "Summarize this repo"
cwb resume <session> "what was the conclusion about the rate limiter?"
cwb dirs --cwd ~/projects
cwb mkdir --cwd ~/projects my-new-feature
cwb update --check # check for a codex-workbench update
cwb update # self-update with npm install -g <exact version>
cwb doctor # check available backends and binaries
cwb delete <session> --file # force-delete broken session file<session> can be a full session id, a unique prefix, a saved custom name, or a session filename.
From the CLI, new and resume let the selected backend take over the terminal until it exits. In the TUI, Enter resumes a session in the right-hand agent pane, while n creates a temporary session row and starts the selected backend in that same pane. When the new session exits, the list refreshes and the temporary row is replaced by the backend's real session record. The n flow scans the current source for available backends; local sources are scanned directly and remote sources are scanned with cwb backends --json over SSH.
Environment variables
| Variable | Default | Description |
|----------|---------|-------------|
| CWB_HOME | ~/.cwb | codex-workbench data directory |
| CWB_META | $CWB_HOME/metadata.json | Workbench metadata, such as custom names |
| CWB_CONFIG | $CWB_HOME/config.json | Workbench config, remote sources, and update preferences |
| CODEX_HOME | ~/.codex | Codex data directory |
| CODEX_SESSIONS_DIR | $CODEX_HOME/sessions | Session JSONL files |
| CODEX_SESSION_INDEX_FILE | $CODEX_HOME/session_index.jsonl | Codex generated thread-name index |
| CLAUDE_HOME | ~/.claude | Claude Code data directory |
| CLAUDE_PROJECTS_DIR | $CLAUDE_HOME/projects | Claude Code project session JSONL files |
| PI_CODING_AGENT_DIR | ~/.pi/agent | pi coding agent data directory |
| PI_CODING_AGENT_SESSION_DIR | $PI_CODING_AGENT_DIR/sessions | pi session JSONL files |
| OPENCODE_DATA_DIR | ~/.local/share/opencode | opencode data directory |
| OPENCODE_DB | $OPENCODE_DATA_DIR/opencode.db | opencode SQLite database |
| CODEX_WORKBENCH_META | unset | Legacy override for CWB_META |
| CODEX_WORKBENCH_CONFIG | unset | Legacy override for CWB_CONFIG |
| CODEX_BIN | auto-detected | Force a specific Codex executable |
| CLAUDE_BIN | auto-detected | Force a specific Claude Code executable |
| PI_BIN | auto-detected | Force a specific pi executable |
| OPENCODE_BIN | auto-detected | Force a specific opencode executable |
By default, codex-workbench discovers the codex binary through your login shell's PATH. Set CODEX_BIN to override.
cwb doctor reports every backend it can see.
On first run, workbench moves legacy config files from ~/.codex/ into ~/.cwb/ if the new files do not exist yet.
Troubleshooting
"Could not find the codex executable"
Run codex-workbench doctor to see where codex-workbench is looking. Common fixes:
- Run
npm install -g @openai/codexto install Codex globally - Set
CODEX_BIN=/path/to/codexto point directly at the executable - Make sure your shell profile (
~/.zshrc,~/.bashrc) adds Codex toPATH
No Codex sessions appear
Make sure you've run Codex at least once. Sessions are stored as .jsonl files under $CODEX_SESSIONS_DIR. Run ls ~/.codex/sessions/ to verify.
No Claude Code sessions appear
Make sure you've run Claude Code at least once. Sessions are stored as .jsonl files under $CLAUDE_PROJECTS_DIR. Run find ~/.claude/projects -name '*.jsonl' to verify.
No pi sessions appear
Make sure you've run the pi coding agent at least once. Sessions are stored as .jsonl files under $PI_CODING_AGENT_SESSION_DIR or $PI_CODING_AGENT_DIR/sessions. Run ls ~/.pi/agent/sessions/ to verify.
No opencode sessions found
Make sure you've run opencode at least once. Sessions are stored in the SQLite database at $OPENCODE_DB or $OPENCODE_DATA_DIR/opencode.db. Run opencode session list --format json or opencode db path to verify.
A backend is missing from doctor
Backends appear only when their session directory exists. For a new backend integration, add a provider under src/providers/ with session discovery, parsing, binary discovery, and command routing.
Remote source shows an error
Verify the remote is reachable and has cwb in its non-interactive PATH:
ssh user@host 'cwb list --json --compact'If that fails, set the command field in your config to the full path:
{ "command": "/home/user/.nvm/versions/node/v20/bin/cwb" }TUI rendering issues
codex-workbench uses blessed for terminal rendering and forces Unicode line drawing instead of alternate-character-set border sequences. Use a UTF-8 terminal emulator such as iTerm2, Kitty, WezTerm, or the built-in macOS Terminal.
Development
git clone https://github.com/bramblex/codex-workbench.git
cd codex-workbench
npm installRun the CLI directly:
node bin/codex-workbench --helpOr link it locally:
npm link
cwb listProject layout
bin/codex-workbench # executable entry point
src/
cli.js # CLI argument parsing and command dispatch
cli-output.js # terminal output formatters
codex-bin.js # legacy Codex binary discovery wrapper
config.js # environment-derived path constants
model/
backend-labels.js # backend display names
metadata.js # workbench-owned metadata persistence
session-classification.js # project grouping helpers, including Codex Scratch
session-store.js # provider session aggregation and metadata merge
format.js # id/time/text formatting helpers
directories.js # filesystem directory listing and creation
workbench-config.js # SSH remote source config loader
providers/
codex.js # Codex provider
claude.js # Claude Code provider
pi.js # pi provider
opencode.js # opencode provider
index.js # provider registry
services/
codex-runner.js # backward-compatible provider runner wrapper
session-sources.js # aggregates local + remote session lists
ssh-runner.js # runs cwb commands over SSH (sync + async)
ui/
blessed-compat.js # blessed terminfo compatibility patch
purple-terminal.js # reusable node-pty + @xterm/headless blessed terminal
workbench.js # interactive TUI orchestration
workbench-renderers.js # TUI text rendering helpers
workbench-terminal-manager.js # embedded agent and shell terminals
workbench-search-picker.js # modal session search UI
workbench-tree.js # session tree modeling
workbench-theme.js # shared TUI palette
list-keymap.js # shared blessed.list key bindings
list-scroll.js # stable list scroll math
directory-picker.js # TUI filesystem directory picker
test/
smoke.js # end-to-end CLI smoke test
codex-bin.test.js # binary discovery unit tests
codex-session-index.test.js # Codex generated-title lookup tests
directory-picker.test.js # directory picker key binding tests
list-keymap.test.js # shared list key binding tests
session-sources.test.js # session source aggregation tests
session-classification.test.js # project grouping and Codex Scratch tests
list-scroll.test.js # list scroll math tests
metadata.test.js # metadata persistence tests
workbench-backend-picker.test.js # backend picker key binding tests
workbench-keymap.test.js # tree key binding regression tests
workbench-new-session-pane.test.js # TUI new-session pane flow tests
workbench-search-picker.test.js # search picker filtering and rendering tests
workbench-tree.test.js # session tree expansion tests
blessed-compat.test.js # terminfo patch verification
purple-terminal.test.js # purple terminal env and color bridge tests
scripts/
pty-codex.js # PTY-based Codex runner prototype
open-codex-pty.js # purple terminal Codex runner prototype
tui-pty-codex.js # PTY + blessed integration prototypesrc/ui/purple-terminal.js is the reusable terminal component behind the embedded agent and shell panes. It keeps the terminal surface's default background intact while giving the surrounding blessed chrome a purple theme, and it answers the terminal capability probes Codex relies on for truecolor diff backgrounds.
Tests
npm testPublishing
npm pack --dry-run
npm publish --access public