tabminal 1.3.7 → 1.3.9
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/AGENTS.md +312 -0
- package/README.md +31 -10
- package/config.sample.json +3 -1
- package/eslint.config.js +31 -0
- package/package.json +5 -2
- package/public/app.js +1471 -507
- package/public/index.html +43 -9
- package/public/modules/notifications.js +135 -0
- package/public/modules/session-meta.js +108 -0
- package/public/modules/url-auth.js +159 -0
- package/public/styles.css +208 -37
- package/public/sw.js +76 -23
- package/src/auth.mjs +6 -1
- package/src/config.mjs +75 -2
- package/src/fs-routes.mjs +2 -3
- package/src/persistence.mjs +47 -1
- package/src/server.mjs +62 -5
- package/src/terminal-manager.mjs +12 -23
- package/src/terminal-session.mjs +12 -21
package/AGENTS.md
ADDED
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
# Tabminal Agent Notes
|
|
2
|
+
|
|
3
|
+
Last updated: 2026-02-10
|
|
4
|
+
|
|
5
|
+
This file is for future AI/code agents working in this repo.
|
|
6
|
+
Goal: keep context accurate, avoid reintroducing old bugs, and preserve current UX
|
|
7
|
+
contracts after the multi-host refactor.
|
|
8
|
+
|
|
9
|
+
## 1) Project Snapshot
|
|
10
|
+
|
|
11
|
+
- Runtime: Node.js >= 22, ESM project.
|
|
12
|
+
- Backend entry: `src/server.mjs`.
|
|
13
|
+
- Frontend entry: `public/app.js` (plus modules in `public/modules/`).
|
|
14
|
+
- PWA shell: `public/index.html` + `public/sw.js`.
|
|
15
|
+
- Multi-host registry persistence: `~/.tabminal/cluster.json` via backend API.
|
|
16
|
+
|
|
17
|
+
Core idea now:
|
|
18
|
+
- One web app can connect to multiple Tabminal backends.
|
|
19
|
+
- Main host controls page-level auth modal/state.
|
|
20
|
+
- Sub-hosts are independent connection/auth units and can reconnect separately.
|
|
21
|
+
|
|
22
|
+
## 2) Non-Negotiable Behavior Contracts
|
|
23
|
+
|
|
24
|
+
### 2.1 Host model and state isolation
|
|
25
|
+
|
|
26
|
+
- UI term is `Host` (not `Server`) for user-facing labels.
|
|
27
|
+
- Every session belongs to exactly one host.
|
|
28
|
+
- Session/editor/file-tree/expanded-path state is host-isolated.
|
|
29
|
+
- Do not merge runtime state across hosts.
|
|
30
|
+
|
|
31
|
+
Relevant code:
|
|
32
|
+
- `public/app.js` (`state.servers`, `state.sessions`, `makeSessionKey` usage)
|
|
33
|
+
- `public/modules/session-meta.js`
|
|
34
|
+
|
|
35
|
+
### 2.2 Auth model
|
|
36
|
+
|
|
37
|
+
- Main host (`id = 'main'`) auth controls the app login modal.
|
|
38
|
+
- Only main host 401/403 should trigger global login modal.
|
|
39
|
+
- Sub-host 401/403 should mark that host as reconnect/login required, not global logout.
|
|
40
|
+
- Sub-host may require Cloudflare Access login without password change.
|
|
41
|
+
|
|
42
|
+
Relevant code:
|
|
43
|
+
- `public/app.js` `ServerClient.handleUnauthorized`
|
|
44
|
+
- `public/app.js` `ServerClient.handleAccessRedirect`
|
|
45
|
+
|
|
46
|
+
### 2.3 Token storage contract
|
|
47
|
+
|
|
48
|
+
- Main host token:
|
|
49
|
+
- persisted in browser `localStorage` key `tabminal_auth_token:main`.
|
|
50
|
+
- Sub-host tokens:
|
|
51
|
+
- persisted in backend registry `~/.tabminal/cluster.json`.
|
|
52
|
+
- should not persist in browser localStorage.
|
|
53
|
+
- Removing a host should remove any stale local token key for that host id.
|
|
54
|
+
|
|
55
|
+
Relevant code:
|
|
56
|
+
- `public/app.js` `ServerClient.constructor`, `ServerClient.setToken`
|
|
57
|
+
- `src/persistence.mjs` `loadCluster` / `saveCluster`
|
|
58
|
+
|
|
59
|
+
### 2.4 Host registry persistence contract
|
|
60
|
+
|
|
61
|
+
- Frontend does not own host list persistence anymore.
|
|
62
|
+
- Source of truth: backend `GET/PUT /api/cluster`.
|
|
63
|
+
- File format in `~/.tabminal/cluster.json`:
|
|
64
|
+
- `{ "servers": [{ id, baseUrl, host, token }, ...] }`
|
|
65
|
+
- On page load, host list is restored from backend after main host auth succeeds.
|
|
66
|
+
|
|
67
|
+
Relevant code:
|
|
68
|
+
- `public/app.js` `loadServerRegistryFromBackend`, `saveServerRegistryToBackend`
|
|
69
|
+
- `src/server.mjs` `/api/cluster`
|
|
70
|
+
- `src/persistence.mjs` cluster helpers
|
|
71
|
+
|
|
72
|
+
### 2.5 Deduplication and self-host skip
|
|
73
|
+
|
|
74
|
+
- Host uniqueness key is normalized `hostname[:port]` in lowercase.
|
|
75
|
+
- Path is not part of dedupe key.
|
|
76
|
+
- Registry hydration skips entries that resolve to current main node
|
|
77
|
+
(same endpoint key or same hostname) to prevent self-loop duplicates.
|
|
78
|
+
- This is intentional to support sharing one cluster config across nodes.
|
|
79
|
+
|
|
80
|
+
Relevant code:
|
|
81
|
+
- `public/modules/url-auth.js` `getServerEndpointKeyFromUrl`
|
|
82
|
+
- `public/app.js` `findServerByEndpointKey`, `hydrateServerRegistry`
|
|
83
|
+
|
|
84
|
+
Important implication:
|
|
85
|
+
- Path-based multi-host on one domain (like `/a/*`, `/b/*`) is not supported by current
|
|
86
|
+
client routing assumptions.
|
|
87
|
+
|
|
88
|
+
### 2.6 Session creation ownership
|
|
89
|
+
|
|
90
|
+
- Backend no longer auto-creates a default session/tab.
|
|
91
|
+
- Frontend ensures usability:
|
|
92
|
+
- if no sessions after init, create one on main host.
|
|
93
|
+
- if user closes last session, create one on main host.
|
|
94
|
+
|
|
95
|
+
Relevant code:
|
|
96
|
+
- `public/app.js` `initApp`, `closeSession`
|
|
97
|
+
- `src/server.mjs` (no auto-create fallback)
|
|
98
|
+
|
|
99
|
+
### 2.7 Polling / heartbeat behavior
|
|
100
|
+
|
|
101
|
+
- Online heartbeat sync interval: `1000ms` (frontend).
|
|
102
|
+
- Reconnect retry cadence when host is down: `5000ms` throttle per host.
|
|
103
|
+
- Do not remove strong polling; it is a UX requirement.
|
|
104
|
+
|
|
105
|
+
Relevant code:
|
|
106
|
+
- `public/app.js`
|
|
107
|
+
- `HEARTBEAT_INTERVAL_MS = 1000`
|
|
108
|
+
- `RECONNECT_RETRY_MS = 5000`
|
|
109
|
+
- `syncServer`, `ServerClient.startHeartbeat`
|
|
110
|
+
|
|
111
|
+
### 2.8 Cloudflare Access handling
|
|
112
|
+
|
|
113
|
+
Current behavior for sub-hosts:
|
|
114
|
+
- requests use `credentials: 'include'` so Access cookies can be sent.
|
|
115
|
+
- requests default to `redirect: 'manual'` on non-main hosts.
|
|
116
|
+
- Access redirect is treated as reconnect reason, not generic password failure.
|
|
117
|
+
- reconnect UI can trigger opening host root in a new tab for Access login.
|
|
118
|
+
|
|
119
|
+
Relevant code:
|
|
120
|
+
- `public/app.js`
|
|
121
|
+
- `ServerClient.fetch`
|
|
122
|
+
- `probeAccessLoginUrl`
|
|
123
|
+
- `openAccessLoginPage`
|
|
124
|
+
- `public/modules/url-auth.js`
|
|
125
|
+
- `isAccessRedirectResponse`
|
|
126
|
+
- `buildAccessLoginUrl` (root origin)
|
|
127
|
+
|
|
128
|
+
### 2.9 CORS policy in backend
|
|
129
|
+
|
|
130
|
+
- Backend currently allows cross-origin by reflecting request origin when present.
|
|
131
|
+
- For requests without origin, backend returns `Access-Control-Allow-Origin: *`.
|
|
132
|
+
- OPTIONS is handled with 204 directly.
|
|
133
|
+
- No per-origin `cors-origin` config is used now.
|
|
134
|
+
|
|
135
|
+
Relevant code:
|
|
136
|
+
- `src/server.mjs` top-level CORS middleware
|
|
137
|
+
|
|
138
|
+
### 2.10 Runtime version and PWA cache coherence
|
|
139
|
+
|
|
140
|
+
- Backend heartbeat returns runtime boot id.
|
|
141
|
+
- Frontend appends `?rt=<bootId>` to URL and reloads on server restart/version change.
|
|
142
|
+
- `index.html` loads `styles.css` and `app.js` using runtime key.
|
|
143
|
+
- SW is registered with `?rt=<bootId>`, cache key includes that runtime id.
|
|
144
|
+
- App shell (`/`, `/index.html`, `/app.js`, `/styles.css`, `/modules/*`) uses
|
|
145
|
+
network-first.
|
|
146
|
+
|
|
147
|
+
Relevant code:
|
|
148
|
+
- `src/server.mjs` `/api/heartbeat` -> `runtime.bootId`
|
|
149
|
+
- `public/app.js` `handlePrimaryRuntimeVersion`
|
|
150
|
+
- `public/index.html` runtime loader script
|
|
151
|
+
- `public/sw.js`
|
|
152
|
+
|
|
153
|
+
## 3) UX Contracts to Keep
|
|
154
|
+
|
|
155
|
+
### 3.1 Sidebar host controls
|
|
156
|
+
|
|
157
|
+
- Per-host row: primary action button + (non-main only) remove button.
|
|
158
|
+
- Remove button is overlay style (top-left), hidden by default, fades in on hover/focus.
|
|
159
|
+
- Main host has no remove button.
|
|
160
|
+
- Main button text:
|
|
161
|
+
- normal: `New Tab @ <Host>`
|
|
162
|
+
- reconnect: `Reconnect <Host>`
|
|
163
|
+
- access flow: `Cloudflare Login <Host>`
|
|
164
|
+
- Second line includes latency text + heartbeat dot + mini heartbeat canvas.
|
|
165
|
+
|
|
166
|
+
Relevant code:
|
|
167
|
+
- `public/app.js` `renderServerControls`
|
|
168
|
+
- `public/styles.css` `.server-row`, `.server-main-button`, `.server-delete-button`
|
|
169
|
+
|
|
170
|
+
### 3.2 Host naming display
|
|
171
|
+
|
|
172
|
+
Display priority for host name:
|
|
173
|
+
1. configured `host` alias
|
|
174
|
+
2. runtime hostname from host heartbeat
|
|
175
|
+
3. URL hostname
|
|
176
|
+
4. `'unknown'`
|
|
177
|
+
|
|
178
|
+
Session metadata line should stay:
|
|
179
|
+
- `HOST: user@<host>`
|
|
180
|
+
- host text uses `.host-emphasis` style.
|
|
181
|
+
|
|
182
|
+
Relevant code:
|
|
183
|
+
- `public/modules/session-meta.js`
|
|
184
|
+
|
|
185
|
+
### 3.3 Path display
|
|
186
|
+
|
|
187
|
+
- PWD display in tab meta uses fish-style compact path shortening.
|
|
188
|
+
- Keep this style unless a full UX redesign is explicitly requested.
|
|
189
|
+
|
|
190
|
+
Relevant code:
|
|
191
|
+
- `public/modules/session-meta.js` `shortenPathFishStyle`
|
|
192
|
+
|
|
193
|
+
### 3.4 Small-screen rule (< 600px height)
|
|
194
|
+
|
|
195
|
+
- `new-tab-item` region is capped to two-button area height and scrollable.
|
|
196
|
+
- This is intentional for small-height mobile/embedded layouts.
|
|
197
|
+
|
|
198
|
+
Relevant code:
|
|
199
|
+
- `public/styles.css` `@media (max-height: 600px)` on `.new-tab-item`
|
|
200
|
+
|
|
201
|
+
## 4) Known Pitfalls and Their Root Causes
|
|
202
|
+
|
|
203
|
+
### 4.1 `SecurityError: insecure WebSocket from HTTPS page`
|
|
204
|
+
|
|
205
|
+
Cause:
|
|
206
|
+
- trying `ws://` from HTTPS page.
|
|
207
|
+
Current mitigation:
|
|
208
|
+
- WS URL builder chooses `wss://` if page is HTTPS or host URL is HTTPS.
|
|
209
|
+
|
|
210
|
+
Check:
|
|
211
|
+
- `public/app.js` `ServerClient.resolveWsUrl`
|
|
212
|
+
- ensure host URL is HTTPS when used from secure origin.
|
|
213
|
+
|
|
214
|
+
### 4.2 `TypeError: Failed to fetch` during heartbeat
|
|
215
|
+
|
|
216
|
+
Usually means:
|
|
217
|
+
- host down, DNS issue, TLS failure, CORS block, or network unreachable.
|
|
218
|
+
Expected behavior:
|
|
219
|
+
- warning-level reconnect messaging, not noisy crash behavior.
|
|
220
|
+
|
|
221
|
+
Check:
|
|
222
|
+
- browser network tab
|
|
223
|
+
- host availability
|
|
224
|
+
- Access auth state for that host
|
|
225
|
+
|
|
226
|
+
### 4.3 Cloudflare Access 302/login loops
|
|
227
|
+
|
|
228
|
+
Important:
|
|
229
|
+
- CORS headers alone do not fix Access redirect login requirements.
|
|
230
|
+
- Main issue is Access auth challenge during API request.
|
|
231
|
+
- Current design handles this by detecting redirect and opening host root login page.
|
|
232
|
+
|
|
233
|
+
### 4.4 Host list not restoring after refresh
|
|
234
|
+
|
|
235
|
+
Check in order:
|
|
236
|
+
1. main host authenticated?
|
|
237
|
+
2. `/api/cluster` returns expected `servers` array?
|
|
238
|
+
3. entries include valid `id` and `baseUrl`?
|
|
239
|
+
4. entry skipped as self-host by dedupe/hostname rule?
|
|
240
|
+
|
|
241
|
+
### 4.5 Same domain with different path does not behave as separate hosts
|
|
242
|
+
|
|
243
|
+
Current architecture dedupes by `hostname[:port]` and uses absolute `/api/*`/`/ws/*`.
|
|
244
|
+
Do not assume path-prefix multiplexing works without deeper routing redesign.
|
|
245
|
+
|
|
246
|
+
## 5) File Map for Fast Onboarding
|
|
247
|
+
|
|
248
|
+
Backend:
|
|
249
|
+
- `src/server.mjs`: API routes, WS upgrade, CORS, runtime boot id, startup/shutdown.
|
|
250
|
+
- `src/config.mjs`: merged config parser (defaults/home/local/CLI/env), validation.
|
|
251
|
+
- `src/auth.mjs`: hash auth, lockout logic, API and WS auth checks.
|
|
252
|
+
- `src/persistence.mjs`: sessions, memory, cluster registry disk persistence.
|
|
253
|
+
- `src/terminal-manager.mjs`: PTY session lifecycle + persistence glue.
|
|
254
|
+
- `src/terminal-session.mjs`: terminal stream parsing, history, metadata, AI context.
|
|
255
|
+
|
|
256
|
+
Frontend:
|
|
257
|
+
- `public/app.js`: host/session state, sync loop, UI orchestration.
|
|
258
|
+
- `public/modules/url-auth.js`: URL normalization, dedupe key, auth helpers.
|
|
259
|
+
- `public/modules/session-meta.js`: host display and path shortening.
|
|
260
|
+
- `public/styles.css`: sidebar/tab/host control styling and responsive rules.
|
|
261
|
+
- `public/index.html`: shell DOM, runtime versioned loader, SW register.
|
|
262
|
+
- `public/sw.js`: runtime-versioned caching strategy.
|
|
263
|
+
|
|
264
|
+
## 6) Logs and Debug Guidance
|
|
265
|
+
|
|
266
|
+
Expected, low-noise warnings:
|
|
267
|
+
- host unreachable / reconnect transitions.
|
|
268
|
+
- invalid cluster entries skipped.
|
|
269
|
+
|
|
270
|
+
Avoid:
|
|
271
|
+
- spamming full stack traces for normal offline scenarios.
|
|
272
|
+
- debug-only console noise left enabled by default.
|
|
273
|
+
|
|
274
|
+
Note:
|
|
275
|
+
- old `cluster-debug` helper has been intentionally removed; do not reintroduce
|
|
276
|
+
unless there is a concrete observability requirement.
|
|
277
|
+
|
|
278
|
+
## 7) Security and Risk Notes
|
|
279
|
+
|
|
280
|
+
- Product is high-privilege by design (terminal + file write).
|
|
281
|
+
- AI features may send terminal context to model providers.
|
|
282
|
+
- Current policy is explicit risk acknowledgment (`--accept-terms` / config flag).
|
|
283
|
+
- Choose trusted model providers and least-privilege credentials.
|
|
284
|
+
|
|
285
|
+
## 8) Deployment and Ops Notes
|
|
286
|
+
|
|
287
|
+
- Local helper script: `reploy.sh` (intentionally ignored by git and npm package).
|
|
288
|
+
- It restarts one macOS launchctl node + several Linux pm2 nodes via SSH.
|
|
289
|
+
- Script contains aggressive cleanup on Linux nodes (reset/clean fallback);
|
|
290
|
+
use carefully in shared environments.
|
|
291
|
+
|
|
292
|
+
## 9) Quality Gates Before Release
|
|
293
|
+
|
|
294
|
+
Recommended checks:
|
|
295
|
+
1. `npm run lint`
|
|
296
|
+
2. `npm test`
|
|
297
|
+
3. `npm run build`
|
|
298
|
+
4. quick manual smoke:
|
|
299
|
+
- main host login
|
|
300
|
+
- add host (with and without password, inheritance path)
|
|
301
|
+
- reconnect flow (normal + Access login path)
|
|
302
|
+
- delete host
|
|
303
|
+
- restart backend and confirm runtime cache refresh (`rt` flow)
|
|
304
|
+
|
|
305
|
+
## 10) Change Safety Rules for Future Refactors
|
|
306
|
+
|
|
307
|
+
- Do not move host list back to localStorage.
|
|
308
|
+
- Do not make sub-host auth failures trigger global logout.
|
|
309
|
+
- Do not remove `credentials: 'include'` from host fetch wrapper.
|
|
310
|
+
- Do not remove reconnect backoff (`5s`) or online heartbeat cadence (`1s`).
|
|
311
|
+
- Do not reintroduce backend auto-create-session fallback.
|
|
312
|
+
- Do not add path-based host assumptions without redesigning URL/WS routing model.
|
package/README.md
CHANGED
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
|
|
7
7
|

|
|
8
8
|
|
|
9
|
-
## 🌟 Why Tabminal
|
|
9
|
+
## 🌟 Why `t> Tabminal`?
|
|
10
10
|
|
|
11
|
-
Tabminal bridges the gap between traditional CLI tools and modern AI capabilities, all while solving the UX challenges of coding on desktop and mobile devices.
|
|
11
|
+
`t> Tabminal` bridges the gap between traditional CLI tools and modern AI capabilities, all while solving the UX challenges of coding on desktop and mobile devices.
|
|
12
12
|
|
|
13
13
|

|
|
14
14
|
|
|
@@ -22,7 +22,7 @@ As a long-time terminal user who frequently needs to step away from my computer
|
|
|
22
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
23
|
- `Cloud-native design` enables access via Zero Trust or VPN, providing unprecedented convenience for managing cloud servers.
|
|
24
24
|
|
|
25
|
-
<img width="
|
|
25
|
+
<img width="1689" height="1386" alt="Screenshot 2026-02-10 at 1 10 01 AM" src="https://github.com/user-attachments/assets/608e21c3-bae2-4f16-85b7-4bd6520fd4f5" />
|
|
26
26
|
|
|
27
27
|
<details>
|
|
28
28
|
|
|
@@ -39,11 +39,12 @@ As a long-time terminal user who frequently needs to step away from my computer
|
|
|
39
39
|
</details>
|
|
40
40
|
|
|
41
41
|
### 🧠 AI-Native Intelligence
|
|
42
|
-
Powered by **modern AI models** (via OpenRouter or OpenAI), Tabminal understands your context.
|
|
42
|
+
Powered by **modern AI models** (via OpenRouter or OpenAI), `t> Tabminal` understands your context.
|
|
43
43
|
*(Defaults to **Gemini 3 Flash** for OpenRouter or **GPT-5.2** for OpenAI if not configured)*
|
|
44
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? Tabminal automatically analyzes the exit code and error output to suggest fixes. No copy-pasting required.
|
|
45
|
+
* **Auto-Fix**: Command failed? `t> Tabminal` automatically analyzes the exit code and error output to suggest fixes. No copy-pasting required.
|
|
46
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.
|
|
47
48
|
|
|
48
49
|
### 📱 Ultimate Mobile Experience
|
|
49
50
|
Built from the ground up for **iPadOS**, **iOS** and **Android**.
|
|
@@ -56,6 +57,15 @@ Built from the ground up for **iPadOS**, **iOS** and **Android**.
|
|
|
56
57
|
* **Built-in Editor**: Integrated **Monaco Editor** (VS Code core) allows you to edit files directly on the server.
|
|
57
58
|
* **Visual File Manager**: Sidebar file tree for easy navigation.
|
|
58
59
|
* **Network Heartbeat**: Real-time latency visualization.
|
|
60
|
+
* **Cluster Host Registry**: Multi-host entries are stored on the main server at `~/.tabminal/cluster.json` (including per-host auth hash). Entries that resolve to the current node are ignored at runtime to avoid self-loop duplicates. Non-main host tokens are restored from this server-side registry; main-host auth stays in browser local storage.
|
|
61
|
+
|
|
62
|
+
### 🌐 Multi-Server Support
|
|
63
|
+
`t> Tabminal` can manage multiple backend nodes from one UI.
|
|
64
|
+
* Register hosts from the sidebar using `+ Add Host`.
|
|
65
|
+
* Open sessions on a specific host with `New Tab @ Host`.
|
|
66
|
+
* Each host maintains its own heartbeat, session list, and file/editor state.
|
|
67
|
+
* Authentication is host-scoped: the main host controls page login, while sub-host login state is shown per-host in the sidebar.
|
|
68
|
+
* Host registry is saved on the main host at `~/.tabminal/cluster.json`, so added hosts can be restored after refresh and across browsers/devices.
|
|
59
69
|
|
|
60
70
|
## 🚀 Getting Started
|
|
61
71
|
|
|
@@ -65,8 +75,9 @@ Built from the ground up for **iPadOS**, **iOS** and **Android**.
|
|
|
65
75
|
* (Optional) A pair of Google API Key and Search Engine ID (CX) for web search capabilities.
|
|
66
76
|
|
|
67
77
|
### ⚠️ Security Warning
|
|
68
|
-
Tabminal provides **full read/write access** to the underlying file system.
|
|
78
|
+
`t> Tabminal` provides **full read/write access** to the underlying file system.
|
|
69
79
|
* **Do NOT expose this to the public internet** without proper protection (VPN, etc).
|
|
80
|
+
* If AI features are enabled, terminal history/environment/context may be sent to your configured model provider. You are responsible for this risk and provider selection.
|
|
70
81
|
* The `--accept-terms` flag is required to acknowledge that you understand these risks.
|
|
71
82
|
|
|
72
83
|
|
|
@@ -103,12 +114,12 @@ npm start -- --openrouter-key "YOUR_API_KEY" --accept-terms
|
|
|
103
114
|
|
|
104
115
|
### Configuration
|
|
105
116
|
|
|
106
|
-
You can configure Tabminal via command-line arguments, environment variables, or a `config.json` file.
|
|
117
|
+
You can configure `t> Tabminal` via command-line arguments, environment variables, or a `config.json` file.
|
|
107
118
|
|
|
108
119
|
| Argument | Env Variable | Description | Default |
|
|
109
120
|
| :--- | :--- | :--- | :--- |
|
|
110
|
-
| `-p`, `--port` | `
|
|
111
|
-
| `-h`, `--host` | `
|
|
121
|
+
| `-p`, `--port` | `TABMINAL_PORT` | Server port | `9846` |
|
|
122
|
+
| `-h`, `--host` | `TABMINAL_HOST` | Bind address | `127.0.0.1` |
|
|
112
123
|
| `-a`, `--password` | `TABMINAL_PASSWORD` | Access password | (Randomly Generated) |
|
|
113
124
|
| `-k`, `--openrouter-key` | `TABMINAL_OPENROUTER_KEY` | OpenRouter API Key (Mutually exclusive with OpenAI) | `null` |
|
|
114
125
|
| `-o`, `--openai-key` | `TABMINAL_OPENAI_KEY` | OpenAI API Key (Mutually exclusive with OpenRouter) | `null` |
|
|
@@ -118,7 +129,13 @@ You can configure Tabminal via command-line arguments, environment variables, or
|
|
|
118
129
|
| `-g`, `--google-key` | `TABMINAL_GOOGLE_KEY` | Google Search API Key | `null` |
|
|
119
130
|
| `-c`, `--google-cx` | `TABMINAL_GOOGLE_CX` | Google Search Engine ID (CX) | `null` |
|
|
120
131
|
| `-d`, `--debug` | `TABMINAL_DEBUG` | Enable debug logs | `false` |
|
|
121
|
-
|
|
|
132
|
+
| `--heartbeat` | `TABMINAL_HEARTBEAT` | WebSocket heartbeat interval (ms, minimum `1000`) | `10000` |
|
|
133
|
+
| `--history` | `TABMINAL_HISTORY` | Terminal history limit (characters) | `1048576` |
|
|
134
|
+
| `-y`, `--accept-terms` | `TABMINAL_ACCEPT` / `TABMINAL_ACCEPT_TERMS` | **Required**: Accept security risks (Full FS Access) | `false` |
|
|
135
|
+
|
|
136
|
+
`config.json` also supports:
|
|
137
|
+
- `heartbeatInterval` or `heartbeat-interval`
|
|
138
|
+
- `historyLimit` or `history-limit`
|
|
122
139
|
|
|
123
140
|
## ⌨️ Shortcuts & Gestures
|
|
124
141
|
|
|
@@ -139,5 +156,9 @@ You can configure Tabminal via command-line arguments, environment variables, or
|
|
|
139
156
|
* **Frontend**: [Vanilla JS](http://vanilla-js.com/) 😝, [xterm.js](https://github.com/xtermjs/xterm.js), [Monaco Editor](https://github.com/microsoft/monaco-editor).
|
|
140
157
|
* **AI**: Integration via [utilitas](https://github.com/leask/utilitas).
|
|
141
158
|
|
|
159
|
+
## 🐛 Troubleshooting
|
|
160
|
+
|
|
161
|
+
- On macOS, you may need to run `chmod +x node_modules/node-pty/prebuilds/darwin-*/spawn-helper` to fix permission issues.
|
|
162
|
+
|
|
142
163
|
## 📄 License
|
|
143
164
|
[MIT](LICENSE)
|
package/config.sample.json
CHANGED
|
@@ -4,8 +4,10 @@
|
|
|
4
4
|
"password": "YOUR_SECURE_PASSWORD",
|
|
5
5
|
"openrouter-key": "YOUR_OPENROUTER_API_KEY",
|
|
6
6
|
"model": "gemini-2.5-flash-preview-09-2025",
|
|
7
|
+
"heartbeat-interval": 10000,
|
|
8
|
+
"history-limit": 1048576,
|
|
7
9
|
"google-key": "YOUR_GOOGLE_SEARCH_API_KEY",
|
|
8
10
|
"google-cx": "YOUR_GOOGLE_SEARCH_ENGINE_ID",
|
|
9
11
|
"accept-terms": true,
|
|
10
12
|
"debug": false
|
|
11
|
-
}
|
|
13
|
+
}
|
package/eslint.config.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export default [
|
|
2
|
+
{
|
|
3
|
+
ignores: [
|
|
4
|
+
'node_modules/**',
|
|
5
|
+
'.history/**',
|
|
6
|
+
'coverage/**',
|
|
7
|
+
'public/icons/**'
|
|
8
|
+
]
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
files: ['**/*.{js,mjs,cjs}'],
|
|
12
|
+
languageOptions: {
|
|
13
|
+
ecmaVersion: 'latest',
|
|
14
|
+
sourceType: 'module'
|
|
15
|
+
},
|
|
16
|
+
rules: {
|
|
17
|
+
'no-unused-vars': ['error', {
|
|
18
|
+
vars: 'all',
|
|
19
|
+
args: 'after-used',
|
|
20
|
+
argsIgnorePattern: '^_',
|
|
21
|
+
varsIgnorePattern: '^_',
|
|
22
|
+
caughtErrors: 'all',
|
|
23
|
+
caughtErrorsIgnorePattern: '^_'
|
|
24
|
+
}],
|
|
25
|
+
'no-empty': ['error', {
|
|
26
|
+
allowEmptyCatch: true
|
|
27
|
+
}],
|
|
28
|
+
'no-redeclare': 'error'
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tabminal",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.9",
|
|
4
4
|
"description": "A modern, persistent web terminal with multi-tab support and real-time system monitoring.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -52,5 +52,8 @@
|
|
|
52
52
|
"bugs": {
|
|
53
53
|
"url": "https://github.com/leask/tabminal/issues"
|
|
54
54
|
},
|
|
55
|
-
"homepage": "https://github.com/leask/tabminal#readme"
|
|
55
|
+
"homepage": "https://github.com/leask/tabminal#readme",
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"eslint": "^9.39.2"
|
|
58
|
+
}
|
|
56
59
|
}
|