A development workbench for managing multiple AI coding agent and terminal sessions across projects. Think of it as a dashboard that organizes your Claude Code, Pi, Codex, and plain terminal sessions β all backed by tmux for persistence.
- Register projects by name and filesystem path
- Optional browser URL per project for live-previewing web apps
- Full CRUD β create, edit, and delete projects from the sidebar
- Drag-and-drop reordering for projects and sessions in the sidebar
- Terminal β plain shell session
- Claude Code β launches
claude --dangerously-skip-permissions - Pi β launches the
picoding agent - Codex β launches
codex
Each session runs inside a detached tmux session, so they survive page reloads, reconnects, and server restarts.
- Attach a source URL when creating or editing a session (Jira ticket, Linear issue, Sentry error, GitHub/GitLab issue, Slack thread)
- Auto-detects source type and displays a labelled badge (e.g.
PROJ-123for Jira) - Issue and MR/PR links shown in the terminal header for quick access on any device
- Edit session popup (
Ctrl+Shift+Eor via session context menu) to update source URL and manage MR/PR links
- Full terminal emulation in the browser via xterm.js
- WebSocket connection streams I/O between the browser and tmux (via
node-pty) - Resize support β terminal dimensions sync automatically
- Sessions that exit from inside (e.g.
exit,Ctrl+D) are detected and archived
Sessions start with a generic name like "Claude Code 1". Once meaningful activity is detected in the terminal, Devbench uses Claude Haiku to generate a short, descriptive kebab-case name based on the terminal content β so your sidebar stays readable even with many sessions.
- Agent sessions (Claude Code, Pi, Codex) are monitored for activity
- Status shows working (spinner) or waiting (idle) based on terminal content changes
- Only the conversation/output area is tracked β input area keystrokes are ignored to avoid false positives
Terminal output is periodically scanned for merge request and pull request URLs from:
- GitLab β
/-/merge_requests/<id>and/merge_requests/new - GitHub β
/pull/<id>and/pull/new/ - Bitbucket β
/pull-requests/<id>
Detected links appear as rich status badges on sessions in the sidebar:
- API polling fetches live status from GitLab/GitHub (open, merged, closed, draft, approved, changes requested, pipeline status)
- Badges are color-coded by state (green = approved, purple = merged, red = failed pipeline, etc.)
- Configure API tokens in Settings (
βοΈbutton) to enable status polling
- Side-by-side browser panel for previewing your web app alongside the terminal
- Electron mode: native
WebContentsViewwith a real browser toolbar, tab bar (project URL + MR tabs), and URL navigation - Web mode: inline
<iframe>with address bar, back/forward, reload, and a draggable split resizer - Reverse proxy β proxies HTTP dev server targets through the Devbench server to fix HTTPS mixed-content issues
- Visual branch dashboard showing stacks, branches, commits, and uncommitted changes per project
- MR/PR status badges on branches with linked reviews
- Pull from upstream with one click (per-project or all projects at once)
- Merge MRs/PRs directly from the dashboard via
glab/ghCLIs with auto-merge support - Session linking β branches are matched to active sessions, with quick navigation
- DB-backed cache with per-project background refresh for instant load times
- Open per-project (
Ctrl+Shift+D) or across all projects (Ctrl+Shift+F)
- Installable as a PWA β add to home screen on mobile for a native app experience
- Mobile keyboard bar with Esc, Tab, Ctrl, Alt, arrow keys, and a git-commit-and-push button
- Swipe gestures β swipe left/right to navigate between sessions
- Touch scrolling for terminal content
- Long-press to rename sessions on touch devices
- Sidebar auto-closes on session creation for more screen space
- Optimized terminal font size for mobile viewports
- Native input with dictation and autofill support
| Shortcut | Action |
|---|---|
Ctrl+Shift+J |
Next session |
Ctrl+Shift+K |
Previous session |
Ctrl+Shift+N |
New session |
Ctrl+Shift+R |
Rename session |
Ctrl+Shift+X |
Kill session |
Ctrl+Shift+A |
Archived sessions |
Ctrl+Shift+B |
Toggle browser pane |
Ctrl+Shift+T |
Toggle terminal session |
Ctrl+Shift+G |
Git commit & push |
Ctrl+Shift+D |
GitButler dashboard (project) |
Ctrl+Shift+F |
GitButler dashboard (all projects) |
Ctrl+Shift+L |
GitButler pull (in dashboard) |
Ctrl+Shift+? |
Show shortcuts help |
- Orphaned session detection β If the server restarts after a crash or power failure, sessions whose tmux died are marked orphaned (not archived), preserving them for revival
- Agent session tracking β Claude Code and Pi sessions store their agent session IDs so conversations can be resumed after a crash
- Claude: launched with
--session-id <uuid>for deterministic resume - Pi: launched with
--session <path>to persist conversation state
- Claude: launched with
- Revive orphaned sessions β Orphaned sessions appear dimmed in the sidebar with a π button; reviving creates a new tmux and resumes the agent conversation
- Revive archived sessions β Open the archived sessions popup (
Ctrl+Shift+Aor the π button on a project header) to browse and revive previously closed sessions - Keyboard navigation β The archived sessions popup supports
j/kto navigate,Enterto revive,Escto close - Archive on kill β Killing a session archives it instead of deleting, so it can be recovered later; permanent delete is only available from the archived list
- Terminal WebSocket connections automatically reconnect on disconnect
- Active session is persisted in the URL, so refreshes and server restarts return you to the same session
- On startup, sessions whose tmux died are kept as orphaned (revivable), not silently discarded
- A periodic health check (every 10s) archives any sessions whose tmux process has disappeared (skips orphaned sessions)
- Auto-rename and MR monitoring are restarted for surviving sessions on server boot
devbench/
βββ shared/ # TypeScript types shared between client & server
β βββ types.ts # Core types (Session, Project, MrStatus, AgentStatus)
β βββ session-config.ts # Session type definitions & icons
β βββ gitbutler-types.ts # GitButler CLI output types & dashboard models
β βββ mr-labels.ts # MR badge status labels & formatting
β βββ source-utils.ts # Source URL detection (Jira, Linear, Sentry, etc.)
βββ server/ # Node.js backend (HTTP + WebSocket)
β βββ index.ts # Entry point & startup routines
β βββ server.ts # HTTP server factory
β βββ router.ts # Lightweight HTTP router
β βββ websocket.ts # WebSocket terminal I/O
β βββ db.ts # SQLite database (better-sqlite3) with migrations
β βββ terminal.ts # tmux + node-pty session management
β βββ auto-rename.ts # LLM-powered session naming
β βββ agent-status.ts # Agent working/waiting status monitor
β βββ mr-links.ts # MR/PR URL extraction from terminal output
β βββ mr-status.ts # MR/PR API status polling (GitLab, GitHub)
β βββ mr-merge.ts # MR/PR merge via glab/gh CLIs
β βββ proxy.ts # Reverse proxy for browser-pane HTTP targets
β βββ gitbutler.ts # GitButler CLI integration
β βββ gitbutler-cache.ts # DB-backed dashboard cache with background refresh
β βββ monitor-manager.ts # Centralized session monitor lifecycle
β βββ agent-session-tracker.ts # Agent session ID generation & resume
βββ client/ # React + Vite frontend
β βββ src/
β βββ App.tsx # Main app shell
β βββ api.ts # REST API client
β βββ components/ # UI components
β βββ Sidebar.tsx # Project & session sidebar
β βββ TerminalPane.tsx # xterm.js terminal emulator
β βββ BrowserPane.tsx # Side-by-side browser panel
β βββ GitButlerDashboard.tsx # Branch visualization dashboard
β βββ MobileKeyboardBar.tsx # Touch keyboard bar
β βββ EditSessionPopup.tsx # Source URL & MR link editor
β βββ SettingsModal.tsx # API token configuration
β βββ ... # Popups, modals, shared components
βββ electron/ # Optional Electron desktop wrapper
β βββ main.ts # Electron main process
β βββ view-manager.ts # WebContentsView management
β βββ layout.ts # Window layout & resizing
β βββ shortcuts.ts # Electron keyboard shortcuts
β βββ preload.ts # Context bridge for renderer
βββ package.json # Workspace root
Tech stack: Node.js Β· TypeScript (native --experimental-strip-types) Β· React 18 Β· Vite Β· xterm.js Β· WebSocket (ws) Β· better-sqlite3 Β· node-pty Β· tmux Β· Electron (optional) Β· Vitest
- Node.js β₯ 22.6 (for native TypeScript stripping)
- tmux installed and on
PATH - claude CLI on
PATH(for Claude Code sessions and auto-rename) - pi CLI on
PATH(for Pi sessions, optional) - codex CLI on
PATH(for Codex sessions, optional) - but (GitButler CLI) on
PATH(for GitButler dashboard, optional) - glab / gh on
PATH(for MR/PR merging from the dashboard, optional)
npm installThis installs all three workspaces (shared, server, client) via npm workspaces.
npm run devThis runs concurrently:
- The server on
http://localhost:3001(with--watchfor auto-reload) - The Vite dev server on
http://localhost:5173(with HMR)
Open http://localhost:5173 in your browser.
# Build the client
npm run build
# Start the production server (serves the built client)
npm startThe production server runs on port 3001 by default. Override with the PORT environment variable:
PORT=8080 npm startTo run as a native desktop app:
# From the repo root β start the backend first
npm run dev:server
# In another terminal β build and launch Electron
cd electron
npm install
npm run devFor standalone Electron (connecting to a running server):
cd electron
npm run startSet DEVBOX_URL to point at a remote server if needed:
DEVBOX_URL=http://my-server:3001 npm run start- Add a project β Click the
+button in the sidebar. Enter a name, the absolute filesystem path, and optionally a browser URL. - Create a session β Expand a project and click the
+icon, or pressCtrl+Shift+N. Pick Terminal, Claude Code, Pi, or Codex. Optionally attach a source URL (Jira, Linear, etc.). - Switch sessions β Click in the sidebar, use
Ctrl+Shift+J/Ctrl+Shift+K, or swipe left/right on mobile. - Browser pane β If a project has a browser URL configured, press
Ctrl+Shift+Bto open a side-by-side browser. - MR links β When a
git pushprints a merge request URL, it appears as a status badge on the session. Configure GitLab/GitHub tokens in Settings to enable live status polling. - GitButler dashboard β Press
Ctrl+Shift+Dfor the current project orCtrl+Shift+Ffor all projects. View branches, pull upstream changes, and merge MRs/PRs. - Git commit & push β Press
Ctrl+Shift+Gto send/git-commit-and-pushto an agent session. - Revive sessions β Press
Ctrl+Shift+Ato open the archived sessions list for the current project. Usej/kto browse,Enterto revive. Orphaned sessions (from a crash) also show a revive button directly in the sidebar. - Mobile β Install as a PWA from your browser. Use the floating keyboard bar for special keys, swipe to switch sessions, and long-press to rename.
Private β not yet published.