Tab(ter)minal, a Cloud-Native terminal and ACP agent workspace for desktop, tablet, and phone.
Tabminal combines persistent server-side terminal sessions, a built-in
workspace, multi-host access, and Agent Client Protocol (ACP) integrations in
one UI. It is designed for people who want a real terminal, real files, and
real agent tooling without being tied to a desktop-only client let you code from
your desktop, tablet, or phone with an intelligent, persistent, and rich
experience.
- Persistent terminal sessions that survive refreshes, reconnects, and device switches.
- Built-in workspace tabs for files, images, agents, and pinned terminals.
- ACP agent support with managed terminals, live tool calls, diffs, code viewers, permission requests, plans, and usage HUDs.
- Multi-host cluster support from a single UI, with per-host auth and heartbeat state.
- Browser-first mobile and tablet UX, including compact workspace mode and PWA install support.
- Terminal-native AI assistance for shell history and auto-fix flows when OpenAI or OpenRouter is configured.
Tabminal now has a full ACP agent surface, not just an AI chat box.
- Agent tabs live beside files and terminal tabs in the same workspace bar.
- Tool calls can render live terminal output, diffs, code/resource payloads, and file paths inline.
Jump inmoves you into the managed terminal session while it is still running.- Agent plans, running-terminal summaries, slash-command menus, permissions, and usage data are first-class UI elements.
- The agent composer supports provider-defined slash commands and keyboard navigation.
- Agent state restores across refreshes, including transcript history and managed terminal relationships.
Built-in agent definitions currently include:
- Gemini CLI
- Codex CLI
- Claude Agent
- GitHub Copilot CLI
- ACP Test Agent (
TABMINAL_ENABLE_TEST_AGENT=1)
Each definition is detected per host. Availability depends on the runtime environment of that host and any required local auth or API keys.
Tabminal still includes the original terminal-native assistant path.
- Prefix a shell prompt with
#to ask the built-in assistant about your current terminal context. - Failed commands can trigger an automatic AI follow-up using recent history and error output.
- This path uses your configured OpenAI or OpenRouter key and is separate from ACP agent integrations.
One UI can manage multiple Tabminal backends.
- Add hosts from the sidebar.
- Open sessions on any connected host.
- Auth is host-scoped.
- The main host controls the global login modal.
- Sub-host auth failures stay local to that host.
- Host registry is persisted on the main host and restored after refresh.
- Monaco-based file editor
- File tree and image preview
- Terminal, file, and agent tabs in one shared workspace bar
- Managed terminal previews in the sidebar
- Restore-aware terminal pinning and workspace switching
- PWA install support
- Safe-area aware responsive layout
- Compact workspace mode for small or short screens
- Touch-friendly controls and virtual keyboard support
- Small-screen agent config controls collapse into icon-only selectors to keep the composer usable on tablets and phones
- Node.js
>= 22 - A secure environment. Tabminal is a high-privilege app by design.
- Optional provider credentials:
- OpenAI or OpenRouter for the built-in terminal-native assistant
- Google Search API key and CX for web search augmentation
- Local CLI/auth for ACP agents such as Codex, Gemini, Claude, or Copilot
Tabminal provides direct read/write access to the host file system and can run commands on that host.
- Do not expose it directly to the public internet.
- Use a VPN, Tailscale, or a Zero Trust layer such as Cloudflare Access.
- If AI features are enabled, terminal history, paths, env hints, or recent command context may be sent to your configured provider.
--accept-termsis required to start the server.
Terminal only:
npx tabminal --accept-termsWith OpenAI:
npx tabminal --openai-key "YOUR_API_KEY" --accept-termsWith OpenRouter:
npx tabminal --openrouter-key "YOUR_API_KEY" --accept-termsdocker run --rm -it -p 9846:9846 \
leask/tabminal \
--accept-termsWith AI enabled:
docker run --rm -it -p 9846:9846 \
leask/tabminal \
--openai-key "YOUR_API_KEY" \
--accept-termsgit clone https://github.com/leask/tabminal.git
cd tabminal
npm install
npm start -- --accept-termsConfiguration precedence is:
- built-in defaults
~/.tabminal/config.json./config.json- CLI flags
- environment variables
If no password is provided, Tabminal generates a temporary password at startup and prints it to the terminal.
| Argument | Env Variable | Description | Default |
|---|---|---|---|
-p, --port |
TABMINAL_PORT |
Server port | 9846 |
-h, --host |
TABMINAL_HOST |
Bind address | 127.0.0.1 |
-a, --password |
TABMINAL_PASSWORD |
Access password | generated at startup |
-s, --shell |
TABMINAL_SHELL |
Default shell executable | system default |
-k, --openrouter-key |
TABMINAL_OPENROUTER_KEY |
OpenRouter API key | null |
-o, --openai-key |
TABMINAL_OPENAI_KEY |
OpenAI API key | null |
-u, --openai-api |
TABMINAL_OPENAI_API |
OpenAI-compatible base URL | null |
-m, --model |
TABMINAL_MODEL |
Built-in assistant model ID | gpt-5.2 with OpenAI, gemini-3-flash-preview with OpenRouter |
-f, --cloudflare-key |
TABMINAL_CLOUDFLARE_KEY |
Cloudflare Tunnel token | null |
-g, --google-key |
TABMINAL_GOOGLE_KEY |
Google Search API key | null |
-c, --google-cx |
TABMINAL_GOOGLE_CX |
Google Search Engine ID | null |
-d, --debug |
TABMINAL_DEBUG |
Enable debug logs | false |
--heartbeat |
TABMINAL_HEARTBEAT |
WebSocket heartbeat interval in ms, minimum 1000 |
10000 |
--history |
TABMINAL_HISTORY |
Terminal history limit in characters | 1048576 |
-y, --accept-terms |
TABMINAL_ACCEPT / TABMINAL_ACCEPT_TERMS |
Required risk acknowledgement | false |
Notes:
--openrouter-keyand--openai-keyare mutually exclusive.config.jsonalso supportsheartbeatInterval/heartbeat-intervalandhistoryLimit/history-limit.
Tabminal stores runtime state under ~/.tabminal/:
config.json: optional home-level configcluster.json: multi-host registryagent-tabs.json: ACP agent tab restore stateagent-config.json: saved per-agent setup/config values
For multi-host:
- The main host token stays in browser local storage.
- Sub-host tokens are persisted in the main host's
cluster.json.
ACP availability is discovered per host. A backend may show different results if its runtime environment differs from your interactive shell.
Typical requirements:
- Codex:
codex login - Gemini:
gemini --acpornpx @google/gemini-cli@latest --acp - Claude:
npx @zed-industries/claude-code-acp@latestplus required Anthropic or Vertex configuration - Copilot:
copilot --acp --stdioorgh copilot -- --acp --stdio
On hosts where the CLI lives in a user-local bin directory such as
~/.local/bin, Tabminal augments the agent runtime PATH so discovery is more
reliable.
Ctrl + Shift + T: New terminalCtrl + Shift + W: Close terminalCtrl + Shift + E: Toggle file workspace paneCtrl + Shift + A: Open agent menuCtrl + Up / Down: Move focus between workspace and terminalCtrl + Shift + [ / ]: Switch sessionCtrl + Alt + [ / ]: Switch workspace tabCtrl + Shift + ?: Show shortcuts helpCtrl/Cmd+F: Find in terminalEsc: Stops a running ACP prompt when supported, or closes transient agent UI such as menus
- The virtual keyboard exposes terminal-friendly modifier keys.
- Workspace and agent controls are optimized for touch and compact screens.
- Backend:
Node.js,utilitas,Koa,node-pty,WebSocket,ACP SDK - Frontend:
Vanilla JS 😝,xterm.js,Monaco Editor - Persistence: host-local files under
~/.tabminal - Native clients and packaging work live under:
apps/Appleapps/ghostty-vendor
-
On macOS,
node-ptymay need:chmod +x node_modules/node-pty/prebuilds/darwin-*/spawn-helper -
If a sub-host keeps asking for login, check whether Cloudflare Access or another auth layer requires an interactive browser login for that host.
-
If an ACP agent is missing, verify the CLI is installed on the backend host and available in that host's runtime environment.
Recommended before shipping changes:
npm run lint
npm test
npm run build











