tabminal 2.0.13 → 2.0.15
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.
- package/ACP_PLANING.md +184 -0
- package/README.md +238 -105
- package/package.json +6 -4
- package/public/app.js +8481 -553
- package/public/index.html +150 -2
- package/public/styles.css +1977 -84
- package/shell/tabminal-hooks.bash +10 -0
- package/src/acp-manager.mjs +3469 -0
- package/src/acp-test-agent.mjs +691 -0
- package/src/persistence.mjs +153 -0
- package/src/server.mjs +300 -12
- package/src/terminal-manager.mjs +184 -73
- package/src/terminal-session.mjs +233 -15
package/ACP_PLANING.md
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# ACP Planing
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Integrate ACP-based coding agents into Tabminal without implementing agents
|
|
6
|
+
ourselves. Agents run on the Tabminal host, managed by the Tabminal backend.
|
|
7
|
+
The web UI adds an Agent panel integrated into the existing workspace/editor
|
|
8
|
+
area and supports multiple concurrent agent tabs per host.
|
|
9
|
+
|
|
10
|
+
## Constraints
|
|
11
|
+
|
|
12
|
+
- Do not break existing terminal, file editor, multi-host, or AI-assist flows.
|
|
13
|
+
- Reuse community-maintained protocol and agent ecosystem pieces where
|
|
14
|
+
practical.
|
|
15
|
+
- Keep lifecycle bounded: lazy start, reusable while tabs are open, and
|
|
16
|
+
cleaned up after inactivity.
|
|
17
|
+
- Host isolation remains strict: each agent runtime and tab belongs to one
|
|
18
|
+
host.
|
|
19
|
+
- MVP should be usable before advanced ACP capabilities are added.
|
|
20
|
+
|
|
21
|
+
## Selected Architecture
|
|
22
|
+
|
|
23
|
+
### Backend
|
|
24
|
+
|
|
25
|
+
Add an ACP supervisor inside the Tabminal backend.
|
|
26
|
+
|
|
27
|
+
Responsibilities:
|
|
28
|
+
- List supported agent definitions available on the host.
|
|
29
|
+
- Start ACP runtimes on demand.
|
|
30
|
+
- Reuse ACP runtime processes while tabs/sessions are active.
|
|
31
|
+
- Create ACP sessions within a runtime.
|
|
32
|
+
- Bridge ACP events to browser clients over a dedicated WebSocket.
|
|
33
|
+
- Expose minimal approval surfaces later; MVP focuses on prompt/stream/cancel.
|
|
34
|
+
|
|
35
|
+
Transport strategy:
|
|
36
|
+
- Primary: stdio-launched ACP agents.
|
|
37
|
+
- Future: attach to TCP ACP servers for tools like GitHub Copilot CLI.
|
|
38
|
+
|
|
39
|
+
Lifecycle:
|
|
40
|
+
- Lazy runtime start on first use.
|
|
41
|
+
- Keep alive while any agent tab is attached.
|
|
42
|
+
- Idle timeout after last tab closes.
|
|
43
|
+
- Destroy all runtimes on backend shutdown.
|
|
44
|
+
|
|
45
|
+
### Frontend
|
|
46
|
+
|
|
47
|
+
Add a host-scoped Agent button beside the file editor toggle area.
|
|
48
|
+
|
|
49
|
+
Behavior:
|
|
50
|
+
- Clicking Agent opens a dropdown of available agents for the active host.
|
|
51
|
+
- Choosing an agent opens a new Agent tab inside the existing editor pane tab
|
|
52
|
+
strip.
|
|
53
|
+
- Agent tabs coexist with file tabs.
|
|
54
|
+
- Each agent tab streams conversation updates and supports prompt send/cancel.
|
|
55
|
+
|
|
56
|
+
MVP UI:
|
|
57
|
+
- Agent tabs render in the editor workspace.
|
|
58
|
+
- Transcript area with coalesced message stream.
|
|
59
|
+
- Prompt textarea + single send/stop button.
|
|
60
|
+
- Mode picker, new chat action, and slash-command chips when available.
|
|
61
|
+
- Status row with host, cwd, mode, and runtime/session status.
|
|
62
|
+
|
|
63
|
+
## Reuse Strategy
|
|
64
|
+
|
|
65
|
+
Use:
|
|
66
|
+
- `@agentclientprotocol/sdk` for protocol/client implementation.
|
|
67
|
+
- ACP Registry later for agent metadata discovery.
|
|
68
|
+
|
|
69
|
+
Do not directly embed:
|
|
70
|
+
- Chrome ACP web client.
|
|
71
|
+
- ACP UI desktop frontend.
|
|
72
|
+
|
|
73
|
+
Reason:
|
|
74
|
+
- They are standalone apps, not embeddable widgets.
|
|
75
|
+
- Tabminal needs native integration with existing host/session/workspace state.
|
|
76
|
+
|
|
77
|
+
## MVP Scope
|
|
78
|
+
|
|
79
|
+
### Phase 1
|
|
80
|
+
|
|
81
|
+
Status:
|
|
82
|
+
- Implemented on `acp` branch and usable with real browser smoke.
|
|
83
|
+
- Backend ACP supervisor, API, and WS fan-out are live.
|
|
84
|
+
- Frontend agent tabs, transcript rendering, prompt send/cancel, and
|
|
85
|
+
permission resolution are live.
|
|
86
|
+
- Agent tab metadata now persists on the backend and restores across backend
|
|
87
|
+
restart for ACP runtimes that support `loadSession`.
|
|
88
|
+
- Agent panel interaction polish is live:
|
|
89
|
+
- duplicate agent tabs auto-number as `#1`, `#2`, ...
|
|
90
|
+
- `Enter` sends
|
|
91
|
+
- `Esc` stops active runs
|
|
92
|
+
- `Ctrl+J` and `Shift+Enter` insert newlines
|
|
93
|
+
- mode switching and new-chat flows are available in-panel
|
|
94
|
+
- tool calls and permission requests render as structured cards
|
|
95
|
+
- Verified with:
|
|
96
|
+
- `npm run lint`
|
|
97
|
+
- `npm test`
|
|
98
|
+
- browser smoke against isolated local ACP test agent
|
|
99
|
+
- browser restart-restore validation against backend-persisted ACP tabs
|
|
100
|
+
- Current polish fixes already applied:
|
|
101
|
+
- Codex token stream is coalesced into a single assistant message instead of
|
|
102
|
+
one message per chunk.
|
|
103
|
+
- User prompts are no longer duplicated when an ACP runtime echoes
|
|
104
|
+
`user_message_chunk` updates after local optimistic insertion.
|
|
105
|
+
- Gemini definition availability is disabled with reason
|
|
106
|
+
`API key missing` when no key is configured.
|
|
107
|
+
- Agent panel typography has been reduced to align with the existing
|
|
108
|
+
workspace/editor density.
|
|
109
|
+
|
|
110
|
+
Backend:
|
|
111
|
+
- ACP supervisor module.
|
|
112
|
+
- Built-in agent definitions for Gemini CLI, Codex CLI adapter, Claude adapter,
|
|
113
|
+
and Copilot CLI ACP server descriptor.
|
|
114
|
+
- REST endpoints:
|
|
115
|
+
- `GET /api/agents`
|
|
116
|
+
- `POST /api/agents/tabs`
|
|
117
|
+
- `POST /api/agents/tabs/:tabId/prompt`
|
|
118
|
+
- `POST /api/agents/tabs/:tabId/cancel`
|
|
119
|
+
- `POST /api/agents/tabs/:tabId/mode`
|
|
120
|
+
- `POST /api/agents/tabs/:tabId/permissions/:permissionId`
|
|
121
|
+
- `DELETE /api/agents/tabs/:tabId`
|
|
122
|
+
- WebSocket endpoint for live event fan-out.
|
|
123
|
+
|
|
124
|
+
Frontend:
|
|
125
|
+
- Agent dropdown button.
|
|
126
|
+
- Agent tab state model.
|
|
127
|
+
- Agent transcript rendering.
|
|
128
|
+
- Prompt send/stop.
|
|
129
|
+
- Mode picker.
|
|
130
|
+
- New chat action.
|
|
131
|
+
- Slash-command starter chips.
|
|
132
|
+
- Structured tool call / permission cards.
|
|
133
|
+
- Host-scoped tabs in editor pane.
|
|
134
|
+
|
|
135
|
+
### Deferred
|
|
136
|
+
|
|
137
|
+
- File attachments.
|
|
138
|
+
- Rich diff/resource rendering in tool outputs.
|
|
139
|
+
- Terminal execution transcript UI for ACP tool calls.
|
|
140
|
+
- Registry-driven install UX.
|
|
141
|
+
- TCP ACP runtime support in UI.
|
|
142
|
+
- Dedicated conversation history browser independent of terminal sessions.
|
|
143
|
+
|
|
144
|
+
## Safety and Isolation
|
|
145
|
+
|
|
146
|
+
- Agent runtimes inherit the host filesystem context, not browser-local state.
|
|
147
|
+
- Prompt and transcript data stay isolated per host.
|
|
148
|
+
- Closing an agent tab detaches from its ACP session.
|
|
149
|
+
- When the last ACP session on a runtime closes, runtime enters idle cleanup.
|
|
150
|
+
|
|
151
|
+
## Test Plan
|
|
152
|
+
|
|
153
|
+
Backend:
|
|
154
|
+
- Unit tests for supervisor lifecycle.
|
|
155
|
+
- Mock ACP runtime process to test stream/cancel behavior.
|
|
156
|
+
- API tests for create/send/cancel/close.
|
|
157
|
+
|
|
158
|
+
Frontend:
|
|
159
|
+
- State/unit tests are minimal in current stack; use integration smoke.
|
|
160
|
+
- Manual flow:
|
|
161
|
+
- open agent dropdown
|
|
162
|
+
- create Gemini/Codex tab
|
|
163
|
+
- send prompt
|
|
164
|
+
- receive stream
|
|
165
|
+
- cancel
|
|
166
|
+
- open second agent tab
|
|
167
|
+
- verify file editor tabs still work
|
|
168
|
+
- verify terminal tabs still work
|
|
169
|
+
|
|
170
|
+
Regression checks:
|
|
171
|
+
- `npm run lint`
|
|
172
|
+
- `npm test`
|
|
173
|
+
- existing multi-host session behavior
|
|
174
|
+
- editor pane switching between file tabs and agent tabs
|
|
175
|
+
|
|
176
|
+
## Implementation Order
|
|
177
|
+
|
|
178
|
+
1. Add ACP dependency and inspect exact SDK client API.
|
|
179
|
+
2. Implement backend supervisor with a mockable adapter layer.
|
|
180
|
+
3. Expose API/WS endpoints with no frontend integration yet.
|
|
181
|
+
4. Add frontend Agent button and agent tab model.
|
|
182
|
+
5. Wire prompt streaming and cancellation.
|
|
183
|
+
6. Run tests and manual smoke.
|
|
184
|
+
7. Iterate on lifecycle and UI fit.
|
package/README.md
CHANGED
|
@@ -1,169 +1,302 @@
|
|
|
1
1
|
# `t>` Tabminal
|
|
2
2
|
|
|
3
|
-
> **Tab(ter)minal,
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
> **Tab(ter)minal, a Cloud-Native terminal and ACP agent workspace for desktop, tablet, and phone.
|
|
4
|
+
|
|
5
|
+
`Tabminal` combines persistent server-side terminal sessions, a built-in
|
|
6
|
+
workspace, multi-host access, and Agent Client Protocol (ACP) integrations in
|
|
7
|
+
one UI. It is designed for people who want a real terminal, real files, and
|
|
8
|
+
real agent tooling without being tied to a desktop-only client let you code from
|
|
9
|
+
your desktop, tablet, or phone with an intelligent, persistent, and rich
|
|
10
|
+
experience.
|
|
6
11
|
|
|
7
12
|

|
|
8
13
|
|
|
9
|
-
##
|
|
14
|
+
## What It Does
|
|
15
|
+
|
|
16
|
+
- Persistent terminal sessions that survive refreshes, reconnects, and device
|
|
17
|
+
switches.
|
|
18
|
+
- Built-in workspace tabs for files, images, agents, and pinned terminals.
|
|
19
|
+
- ACP agent support with managed terminals, live tool calls, diffs, code
|
|
20
|
+
viewers, permission requests, plans, and usage HUDs.
|
|
21
|
+
- Multi-host cluster support from a single UI, with per-host auth and heartbeat
|
|
22
|
+
state.
|
|
23
|
+
- Browser-first mobile and tablet UX, including compact workspace mode and PWA
|
|
24
|
+
install support.
|
|
25
|
+
- Terminal-native AI assistance for shell history and auto-fix flows when
|
|
26
|
+
OpenAI or OpenRouter is configured.
|
|
10
27
|
|
|
11
|
-
|
|
28
|
+

|
|
12
29
|
|
|
13
|
-
|
|
30
|
+
<details>
|
|
31
|
+
<summary>More screenshots</summary>
|
|
14
32
|
|
|
15
|
-
|
|
33
|
+
<img width="2016" height="1170" alt="Screenshot 2025-11-24 at 3 03 03 PM" src="https://github.com/user-attachments/assets/a74490be-fe97-41c6-9026-44bbf3be79f9" />
|
|
16
34
|
|
|
17
|
-
|
|
35
|
+
<img width="2012" height="1439" alt="Screenshot 2025-11-24 at 3 02 12 PM" src="https://github.com/user-attachments/assets/80fed651-48ce-482a-80a3-03d9dd2767b0" />
|
|
18
36
|
|
|
19
|
-
|
|
20
|
-
- `Fast and stable connection management` delivers a seamless, agile experience across platforms and devices, with native support for network roaming.
|
|
21
|
-
- Enjoy a comprehensive `Progressive Web App (PWA) experience` anytime, anywhere; all you need is a modern browser to start working.
|
|
22
|
-
- `Proactive AI integration` means your terminal becomes your work context. You can ask questions about your current session at any time, and the AI will automatically retrieve the context to accurately solve problems, even proactively offering assistance when commands fail.
|
|
23
|
-
- `Cloud-native design` enables access via Zero Trust or VPN, providing unprecedented convenience for managing cloud servers.
|
|
37
|
+
<img width="1816" height="1186" alt="Screenshot 2025-11-24 at 3 01 46 PM" src="https://github.com/user-attachments/assets/509f7e99-1d70-46be-bc18-a202c0fe11a4" />
|
|
24
38
|
|
|
25
|
-
<img width="
|
|
39
|
+
<img width="1815" height="826" alt="Screenshot 2025-11-24 at 2 57 39 PM" src="https://github.com/user-attachments/assets/c503c236-dc38-470e-9a0d-6b824e0dd624" />
|
|
26
40
|
|
|
27
|
-
|
|
41
|
+
</details>
|
|
28
42
|
|
|
29
|
-
|
|
43
|
+
## Current Highlights
|
|
30
44
|
|
|
31
|
-
|
|
45
|
+
### ACP Agent Workspace
|
|
32
46
|
|
|
33
|
-
|
|
47
|
+
Tabminal now has a full ACP agent surface, not just an AI chat box.
|
|
34
48
|
|
|
35
|
-
|
|
49
|
+
- Agent tabs live beside files and terminal tabs in the same workspace bar.
|
|
50
|
+
- Tool calls can render live terminal output, diffs, code/resource payloads,
|
|
51
|
+
and file paths inline.
|
|
52
|
+
- `Jump in` moves you into the managed terminal session while it is still
|
|
53
|
+
running.
|
|
54
|
+
- Agent plans, running-terminal summaries, slash-command menus, permissions,
|
|
55
|
+
and usage data are first-class UI elements.
|
|
56
|
+
- The agent composer supports provider-defined slash commands and keyboard
|
|
57
|
+
navigation.
|
|
58
|
+
- Agent state restores across refreshes, including transcript history and
|
|
59
|
+
managed terminal relationships.
|
|
36
60
|
|
|
37
|
-
|
|
61
|
+
Built-in agent definitions currently include:
|
|
38
62
|
|
|
39
|
-
|
|
63
|
+
- Gemini CLI
|
|
64
|
+
- Codex CLI
|
|
65
|
+
- Claude Agent
|
|
66
|
+
- GitHub Copilot CLI
|
|
67
|
+
- ACP Test Agent (`TABMINAL_ENABLE_TEST_AGENT=1`)
|
|
68
|
+
|
|
69
|
+
Each definition is detected per host. Availability depends on the runtime
|
|
70
|
+
environment of that host and any required local auth or API keys.
|
|
71
|
+
|
|
72
|
+
### Terminal-Native AI Assistant
|
|
40
73
|
|
|
41
|
-
|
|
42
|
-
Powered by **modern AI models** (via OpenRouter or OpenAI), `t> Tabminal` understands your context.
|
|
43
|
-
*(Defaults to **Gemini 3 Flash** for OpenRouter or **GPT-5.4** for OpenAI if not configured)*
|
|
44
|
-
* **Context-Aware Chat**: Type `# how do I...` to ask questions. The AI knows your **CWD**, **Environment**, and **Recent History**.
|
|
45
|
-
* **Auto-Fix**: Command failed? `t> Tabminal` automatically analyzes the exit code and error output to suggest fixes. No copy-pasting required.
|
|
46
|
-
* **Web Search**: Enable Google Search integration to let the AI fetch real-time answers from the web.
|
|
47
|
-
* **Provider Risk Notice**: AI features may send terminal context to your selected model provider. You are responsible for choosing trusted providers/models and acceptable data boundaries.
|
|
74
|
+
Tabminal still includes the original terminal-native assistant path.
|
|
48
75
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
76
|
+
- Prefix a shell prompt with `#` to ask the built-in assistant about your
|
|
77
|
+
current terminal context.
|
|
78
|
+
- Failed commands can trigger an automatic AI follow-up using recent history and
|
|
79
|
+
error output.
|
|
80
|
+
- This path uses your configured OpenAI or OpenRouter key and is separate from
|
|
81
|
+
ACP agent integrations.
|
|
54
82
|
|
|
55
|
-
|
|
83
|
+
### Multi-Host Cluster
|
|
56
84
|
|
|
57
|
-
|
|
58
|
-
- `apps/ghostty-vendor`: Ghostty xcframework vendor/build tooling
|
|
85
|
+
One UI can manage multiple Tabminal backends.
|
|
59
86
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
87
|
+
- Add hosts from the sidebar.
|
|
88
|
+
- Open sessions on any connected host.
|
|
89
|
+
- Auth is host-scoped.
|
|
90
|
+
- The main host controls the global login modal.
|
|
91
|
+
- Sub-host auth failures stay local to that host.
|
|
92
|
+
- Host registry is persisted on the main host and restored after refresh.
|
|
66
93
|
|
|
67
|
-
###
|
|
68
|
-
`t> Tabminal` can manage multiple backend nodes from one UI.
|
|
69
|
-
* Register hosts from the sidebar using `+ Add Host`.
|
|
70
|
-
* Open sessions on a specific host with `New Tab @ Host`.
|
|
71
|
-
* Each host maintains its own heartbeat, session list, and file/editor state.
|
|
72
|
-
* Authentication is host-scoped: the main host controls page login, while sub-host login state is shown per-host in the sidebar.
|
|
73
|
-
* Host registry is saved on the main host at `~/.tabminal/cluster.json`, so added hosts can be restored after refresh and across browsers/devices.
|
|
94
|
+
### Built-In Workspace
|
|
74
95
|
|
|
75
|
-
|
|
96
|
+
- Monaco-based file editor
|
|
97
|
+
- File tree and image preview
|
|
98
|
+
- Terminal, file, and agent tabs in one shared workspace bar
|
|
99
|
+
- Managed terminal previews in the sidebar
|
|
100
|
+
- Restore-aware terminal pinning and workspace switching
|
|
76
101
|
|
|
77
|
-
###
|
|
78
|
-
* Node.js >= 22
|
|
79
|
-
* (Optional) An [OpenRouter](https://openrouter.ai/) API Key or [OpenAI](https://openai.com/) API Key for AI features.
|
|
80
|
-
* (Optional) A pair of Google API Key and Search Engine ID (CX) for web search capabilities.
|
|
102
|
+
### Mobile and Tablet UX
|
|
81
103
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
104
|
+
- PWA install support
|
|
105
|
+
- Safe-area aware responsive layout
|
|
106
|
+
- Compact workspace mode for small or short screens
|
|
107
|
+
- Touch-friendly controls and virtual keyboard support
|
|
108
|
+
- Small-screen agent config controls collapse into icon-only selectors to keep
|
|
109
|
+
the composer usable on tablets and phones
|
|
87
110
|
|
|
111
|
+
## Getting Started
|
|
88
112
|
|
|
89
|
-
###
|
|
113
|
+
### Requirements
|
|
114
|
+
|
|
115
|
+
- Node.js `>= 22`
|
|
116
|
+
- A secure environment. Tabminal is a high-privilege app by design.
|
|
117
|
+
- Optional provider credentials:
|
|
118
|
+
- OpenAI or OpenRouter for the built-in terminal-native assistant
|
|
119
|
+
- Google Search API key and CX for web search augmentation
|
|
120
|
+
- Local CLI/auth for ACP agents such as Codex, Gemini, Claude, or Copilot
|
|
121
|
+
|
|
122
|
+
### Security Warning
|
|
123
|
+
|
|
124
|
+
Tabminal provides direct read/write access to the host file system and can run
|
|
125
|
+
commands on that host.
|
|
126
|
+
|
|
127
|
+
- Do not expose it directly to the public internet.
|
|
128
|
+
- Use a VPN, Tailscale, or a Zero Trust layer such as Cloudflare Access.
|
|
129
|
+
- If AI features are enabled, terminal history, paths, env hints, or recent
|
|
130
|
+
command context may be sent to your configured provider.
|
|
131
|
+
- `--accept-terms` is required to start the server.
|
|
132
|
+
|
|
133
|
+
### Quick Start
|
|
134
|
+
|
|
135
|
+
Terminal only:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
npx tabminal --accept-terms
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
With OpenAI:
|
|
90
142
|
|
|
91
143
|
```bash
|
|
92
|
-
npx tabminal --openrouter-key "YOUR_API_KEY" --accept-terms
|
|
93
|
-
# Or use OpenAI:
|
|
94
144
|
npx tabminal --openai-key "YOUR_API_KEY" --accept-terms
|
|
95
145
|
```
|
|
96
146
|
|
|
97
|
-
|
|
147
|
+
With OpenRouter:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
npx tabminal --openrouter-key "YOUR_API_KEY" --accept-terms
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Docker
|
|
98
154
|
|
|
99
155
|
```bash
|
|
100
156
|
docker run --rm -it -p 9846:9846 \
|
|
101
157
|
leask/tabminal \
|
|
102
|
-
--openrouter-key "YOUR_API_KEY" \
|
|
103
158
|
--accept-terms
|
|
104
159
|
```
|
|
105
160
|
|
|
106
|
-
|
|
161
|
+
With AI enabled:
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
docker run --rm -it -p 9846:9846 \
|
|
165
|
+
leask/tabminal \
|
|
166
|
+
--openai-key "YOUR_API_KEY" \
|
|
167
|
+
--accept-terms
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Local Development
|
|
107
171
|
|
|
108
172
|
```bash
|
|
109
|
-
# Clone the repository
|
|
110
173
|
git clone https://github.com/leask/tabminal.git
|
|
111
174
|
cd tabminal
|
|
112
|
-
|
|
113
|
-
# Install dependencies
|
|
114
175
|
npm install
|
|
115
|
-
|
|
116
|
-
# Start the server
|
|
117
|
-
npm start -- --openrouter-key "YOUR_API_KEY" --accept-terms
|
|
176
|
+
npm start -- --accept-terms
|
|
118
177
|
```
|
|
119
178
|
|
|
120
|
-
|
|
179
|
+
## Configuration
|
|
180
|
+
|
|
181
|
+
Configuration precedence is:
|
|
182
|
+
|
|
183
|
+
1. built-in defaults
|
|
184
|
+
2. `~/.tabminal/config.json`
|
|
185
|
+
3. `./config.json`
|
|
186
|
+
4. CLI flags
|
|
187
|
+
5. environment variables
|
|
188
|
+
|
|
189
|
+
If no password is provided, Tabminal generates a temporary password at startup
|
|
190
|
+
and prints it to the terminal.
|
|
121
191
|
|
|
122
|
-
|
|
192
|
+
### CLI Flags and Environment Variables
|
|
123
193
|
|
|
124
194
|
| Argument | Env Variable | Description | Default |
|
|
125
195
|
| :--- | :--- | :--- | :--- |
|
|
126
196
|
| `-p`, `--port` | `TABMINAL_PORT` | Server port | `9846` |
|
|
127
197
|
| `-h`, `--host` | `TABMINAL_HOST` | Bind address | `127.0.0.1` |
|
|
128
|
-
| `-a`, `--password` | `TABMINAL_PASSWORD` | Access password |
|
|
129
|
-
| `-
|
|
130
|
-
| `-
|
|
131
|
-
| `-
|
|
132
|
-
| `-
|
|
133
|
-
| `-
|
|
134
|
-
| `-
|
|
135
|
-
| `-
|
|
198
|
+
| `-a`, `--password` | `TABMINAL_PASSWORD` | Access password | generated at startup |
|
|
199
|
+
| `-s`, `--shell` | `TABMINAL_SHELL` | Default shell executable | system default |
|
|
200
|
+
| `-k`, `--openrouter-key` | `TABMINAL_OPENROUTER_KEY` | OpenRouter API key | `null` |
|
|
201
|
+
| `-o`, `--openai-key` | `TABMINAL_OPENAI_KEY` | OpenAI API key | `null` |
|
|
202
|
+
| `-u`, `--openai-api` | `TABMINAL_OPENAI_API` | OpenAI-compatible base URL | `null` |
|
|
203
|
+
| `-m`, `--model` | `TABMINAL_MODEL` | Built-in assistant model ID | `gpt-5.2` with OpenAI, `gemini-3-flash-preview` with OpenRouter |
|
|
204
|
+
| `-f`, `--cloudflare-key` | `TABMINAL_CLOUDFLARE_KEY` | Cloudflare Tunnel token | `null` |
|
|
205
|
+
| `-g`, `--google-key` | `TABMINAL_GOOGLE_KEY` | Google Search API key | `null` |
|
|
206
|
+
| `-c`, `--google-cx` | `TABMINAL_GOOGLE_CX` | Google Search Engine ID | `null` |
|
|
136
207
|
| `-d`, `--debug` | `TABMINAL_DEBUG` | Enable debug logs | `false` |
|
|
137
|
-
| `--heartbeat` | `TABMINAL_HEARTBEAT` | WebSocket heartbeat interval
|
|
138
|
-
| `--history` | `TABMINAL_HISTORY` | Terminal history limit
|
|
139
|
-
| `-y`, `--accept-terms` | `TABMINAL_ACCEPT` / `TABMINAL_ACCEPT_TERMS` |
|
|
208
|
+
| `--heartbeat` | `TABMINAL_HEARTBEAT` | WebSocket heartbeat interval in ms, minimum `1000` | `10000` |
|
|
209
|
+
| `--history` | `TABMINAL_HISTORY` | Terminal history limit in characters | `1048576` |
|
|
210
|
+
| `-y`, `--accept-terms` | `TABMINAL_ACCEPT` / `TABMINAL_ACCEPT_TERMS` | Required risk acknowledgement | `false` |
|
|
211
|
+
|
|
212
|
+
Notes:
|
|
213
|
+
|
|
214
|
+
- `--openrouter-key` and `--openai-key` are mutually exclusive.
|
|
215
|
+
- `config.json` also supports `heartbeatInterval` / `heartbeat-interval` and
|
|
216
|
+
`historyLimit` / `history-limit`.
|
|
217
|
+
|
|
218
|
+
### Persistence Files
|
|
219
|
+
|
|
220
|
+
Tabminal stores runtime state under `~/.tabminal/`:
|
|
221
|
+
|
|
222
|
+
- `config.json`: optional home-level config
|
|
223
|
+
- `cluster.json`: multi-host registry
|
|
224
|
+
- `agent-tabs.json`: ACP agent tab restore state
|
|
225
|
+
- `agent-config.json`: saved per-agent setup/config values
|
|
226
|
+
|
|
227
|
+
For multi-host:
|
|
228
|
+
|
|
229
|
+
- The main host token stays in browser local storage.
|
|
230
|
+
- Sub-host tokens are persisted in the main host's `cluster.json`.
|
|
140
231
|
|
|
141
|
-
|
|
142
|
-
- `heartbeatInterval` or `heartbeat-interval`
|
|
143
|
-
- `historyLimit` or `history-limit`
|
|
232
|
+
## ACP Agent Notes
|
|
144
233
|
|
|
145
|
-
|
|
234
|
+
ACP availability is discovered per host. A backend may show different results if
|
|
235
|
+
its runtime environment differs from your interactive shell.
|
|
146
236
|
|
|
147
|
-
|
|
148
|
-
* **`Ctrl + Shift + W`**: Close Terminal
|
|
149
|
-
* **`Ctrl + Shift + E`**: Toggle Editor Pane
|
|
150
|
-
* **`Ctrl + Up` / `Down`**: Focus Editor / Terminal
|
|
151
|
-
* **`Ctrl + Shift + [` / `]`**: Switch Terminal
|
|
152
|
-
* **`Ctrl + Alt + [` / `]`**: Switch Open File in Editor
|
|
153
|
-
* **`Ctrl + Shift + ?`**: Show Shortcuts Help
|
|
154
|
-
* **`Ctrl` / `Cmd` + `F`**: Find in Terminal
|
|
237
|
+
Typical requirements:
|
|
155
238
|
|
|
156
|
-
|
|
157
|
-
|
|
239
|
+
- Codex: `codex login`
|
|
240
|
+
- Gemini: `gemini --acp` or `npx @google/gemini-cli@latest --acp`
|
|
241
|
+
- Claude: `npx @zed-industries/claude-code-acp@latest` plus required Anthropic
|
|
242
|
+
or Vertex configuration
|
|
243
|
+
- Copilot: `copilot --acp --stdio` or `gh copilot -- --acp --stdio`
|
|
158
244
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
* **AI**: Integration via [utilitas](https://github.com/leask/utilitas).
|
|
245
|
+
On hosts where the CLI lives in a user-local bin directory such as
|
|
246
|
+
`~/.local/bin`, Tabminal augments the agent runtime `PATH` so discovery is more
|
|
247
|
+
reliable.
|
|
163
248
|
|
|
164
|
-
##
|
|
249
|
+
## Keyboard Shortcuts
|
|
250
|
+
|
|
251
|
+
- `Ctrl + Shift + T`: New terminal
|
|
252
|
+
- `Ctrl + Shift + W`: Close terminal
|
|
253
|
+
- `Ctrl + Shift + E`: Toggle file workspace pane
|
|
254
|
+
- `Ctrl + Shift + A`: Open agent menu
|
|
255
|
+
- `Ctrl + Up / Down`: Move focus between workspace and terminal
|
|
256
|
+
- `Ctrl + Shift + [ / ]`: Switch session
|
|
257
|
+
- `Ctrl + Alt + [ / ]`: Switch workspace tab
|
|
258
|
+
- `Ctrl + Shift + ?`: Show shortcuts help
|
|
259
|
+
- `Ctrl` / `Cmd` + `F`: Find in terminal
|
|
260
|
+
- `Esc`: Stops a running ACP prompt when supported, or closes transient agent UI
|
|
261
|
+
such as menus
|
|
262
|
+
|
|
263
|
+
### Touch
|
|
264
|
+
|
|
265
|
+
- The virtual keyboard exposes terminal-friendly modifier keys.
|
|
266
|
+
- Workspace and agent controls are optimized for touch and compact screens.
|
|
267
|
+
|
|
268
|
+
## Architecture Snapshot
|
|
269
|
+
|
|
270
|
+
- Backend: Node.js, Koa, `node-pty`, WebSocket, ACP SDK
|
|
271
|
+
- Frontend: vanilla JS, `xterm.js`, Monaco Editor
|
|
272
|
+
- Persistence: host-local files under `~/.tabminal`
|
|
273
|
+
- Native clients and packaging work live under:
|
|
274
|
+
- `apps/Apple`
|
|
275
|
+
- `apps/ghostty-vendor`
|
|
276
|
+
|
|
277
|
+
## Troubleshooting
|
|
278
|
+
|
|
279
|
+
- On macOS, `node-pty` may need:
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
chmod +x node_modules/node-pty/prebuilds/darwin-*/spawn-helper
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
- If a sub-host keeps asking for login, check whether Cloudflare Access or
|
|
286
|
+
another auth layer requires an interactive browser login for that host.
|
|
287
|
+
- If an ACP agent is missing, verify the CLI is installed on the backend host
|
|
288
|
+
and available in that host's runtime environment.
|
|
289
|
+
|
|
290
|
+
## Quality Checks
|
|
291
|
+
|
|
292
|
+
Recommended before shipping changes:
|
|
293
|
+
|
|
294
|
+
```bash
|
|
295
|
+
npm run lint
|
|
296
|
+
npm test
|
|
297
|
+
npm run build
|
|
298
|
+
```
|
|
165
299
|
|
|
166
|
-
|
|
300
|
+
## License
|
|
167
301
|
|
|
168
|
-
## 📄 License
|
|
169
302
|
[MIT](LICENSE)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tabminal",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.15",
|
|
4
4
|
"description": "A modern, persistent web terminal with multi-tab support and real-time system monitoring.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -32,10 +32,12 @@
|
|
|
32
32
|
"node": ">=22.0.0"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
+
"@agentclientprotocol/sdk": "^0.16.1",
|
|
35
36
|
"@fontsource/monaspace-neon": "^5.2.5",
|
|
36
37
|
"@koa/router": "^15.4.0",
|
|
37
38
|
"@mozilla/readability": "^0.6.0",
|
|
38
|
-
"
|
|
39
|
+
"formidable": "^3.5.4",
|
|
40
|
+
"jsdom": "^29.0.1",
|
|
39
41
|
"koa": "^3.1.2",
|
|
40
42
|
"koa-bodyparser": "^4.4.1",
|
|
41
43
|
"koa-static": "^5.0.0",
|
|
@@ -43,7 +45,7 @@
|
|
|
43
45
|
"node-pty": "^1.1.0",
|
|
44
46
|
"openai": "^6.32.0",
|
|
45
47
|
"utilitas": "^2001.1.135",
|
|
46
|
-
"ws": "^8.
|
|
48
|
+
"ws": "^8.20.0",
|
|
47
49
|
"xterm-addon-serialize": "^0.11.0",
|
|
48
50
|
"xterm-headless": "^5.3.0"
|
|
49
51
|
},
|
|
@@ -56,6 +58,6 @@
|
|
|
56
58
|
},
|
|
57
59
|
"homepage": "https://github.com/leask/tabminal#readme",
|
|
58
60
|
"devDependencies": {
|
|
59
|
-
"eslint": "^10.0
|
|
61
|
+
"eslint": "^10.1.0"
|
|
60
62
|
}
|
|
61
63
|
}
|