termbeam 1.5.0 → 1.8.0
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/README.md +7 -32
- package/bin/termbeam.js +27 -12
- package/package.json +1 -1
- package/public/css/themes.css +217 -0
- package/public/index.html +42 -242
- package/public/js/keybar.js +180 -0
- package/public/js/search.js +95 -0
- package/public/js/shared.js +39 -0
- package/public/js/terminal-themes.js +291 -0
- package/public/js/themes.js +54 -0
- package/public/terminal.html +74 -873
- package/src/cli.js +6 -0
- package/src/git.js +125 -0
- package/src/interactive.js +269 -0
- package/src/prompts.js +146 -0
- package/src/service.js +13 -129
- package/src/sessions.js +86 -1
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
TermBeam lets you access your terminal from a phone, tablet, or any browser — no SSH, no port forwarding, no config files. Run one command and scan the QR code.
|
|
17
17
|
|
|
18
|
-
I built this because I kept needing to run quick commands on my dev machine while away from my desk, and SSH on a phone is painful. TermBeam gives you a real terminal with a touch-
|
|
18
|
+
I built this because I kept needing to run quick commands on my dev machine while away from my desk, and SSH on a phone is painful. TermBeam gives you a real terminal with a touch-optimized UI — key bar, swipe scroll, pinch zoom — that actually works on small screens. You get multi-session tabs with split view, terminal search, a command palette, 12 themes, and secure remote access out of the box.
|
|
19
19
|
|
|
20
20
|
[Full documentation](https://dorlugasigal.github.io/TermBeam/) · [Website](https://termbeam.pages.dev)
|
|
21
21
|
|
|
@@ -26,8 +26,8 @@ https://github.com/user-attachments/assets/9dd4f3d7-f017-4314-9b3a-f6a5688e3671
|
|
|
26
26
|
<table align="center">
|
|
27
27
|
<tr>
|
|
28
28
|
<td align="center"><img src="docs/assets/screenshots/mobile-session-hub.jpeg" alt="Session hub on mobile" width="250" /></td>
|
|
29
|
-
<td align="center"><img src="docs/assets/screenshots/mobile-session-preview.jpeg" alt="Session preview on mobile" width="250" /></td>
|
|
30
29
|
<td align="center"><img src="docs/assets/screenshots/mobile-terminal.jpeg" alt="Terminal on mobile" width="250" /></td>
|
|
30
|
+
<td align="center"><img src="docs/assets/screenshots/mobile-session-preview.jpeg" alt="Session preview on mobile" width="250" /></td>
|
|
31
31
|
</tr>
|
|
32
32
|
</table>
|
|
33
33
|
|
|
@@ -46,6 +46,8 @@ termbeam
|
|
|
46
46
|
|
|
47
47
|
Scan the QR code printed in your terminal, or open the URL on any device.
|
|
48
48
|
|
|
49
|
+
> **First time?** Run `termbeam -i` for a guided setup wizard that walks you through password, port, and access mode.
|
|
50
|
+
|
|
49
51
|
### Secure by default
|
|
50
52
|
|
|
51
53
|
TermBeam starts with a tunnel and auto-generated password out of the box — just run `termbeam` and scan the QR code.
|
|
@@ -55,38 +57,9 @@ termbeam # tunnel + auto-password (default)
|
|
|
55
57
|
termbeam --password mysecret # use a specific password
|
|
56
58
|
termbeam --no-tunnel # LAN-only (no tunnel)
|
|
57
59
|
termbeam --no-password # disable password protection
|
|
60
|
+
termbeam -i # interactive setup wizard
|
|
58
61
|
```
|
|
59
62
|
|
|
60
|
-
## Features
|
|
61
|
-
|
|
62
|
-
- **Mobile-first UI** with on-screen touch bar (arrow keys, Tab, Enter, Ctrl shortcuts, Esc) and touch-optimized controls
|
|
63
|
-
- **Copy/paste support** — Copy button opens text overlay for finger-selectable terminal content; Paste button with clipboard API + fallback modal
|
|
64
|
-
- **Image paste** — paste images from clipboard, uploaded to server
|
|
65
|
-
- **Tabbed multi-session terminal** — open, switch, and manage multiple sessions from a single tab bar with drag-to-reorder
|
|
66
|
-
- **Split view** — view two sessions side-by-side (horizontal on desktop, vertical on mobile)
|
|
67
|
-
- **Session colors** — assign a color to each session for quick identification
|
|
68
|
-
- **Activity indicators** — see how recently each session had output (e.g. "3s ago", "5m ago")
|
|
69
|
-
- **Tab previews** — hover (desktop) or long-press (mobile) a tab to preview the last few lines of output
|
|
70
|
-
- **Side panel** (mobile) — slide-out session list with output previews for quick switching
|
|
71
|
-
- **Create sessions anywhere** — new session modal available from both the hub page and the terminal page
|
|
72
|
-
- **Touch scrolling** — swipe to scroll through terminal history
|
|
73
|
-
- **Share button** — share the TermBeam URL via Web Share API, clipboard, or legacy copy fallback (works over HTTP); each share gets a fresh auto-login link with a 5-minute share token
|
|
74
|
-
- **QR code auto-login** — scan the QR code to log in automatically without typing the password (share token, 5-minute expiry)
|
|
75
|
-
- **Refresh button** — clear PWA/service worker cache and reload to get the latest version
|
|
76
|
-
- **iPhone PWA safe area** — full support for `viewport-fit=cover` and safe area insets on notched devices
|
|
77
|
-
- **Password auth** with token-based cookies and rate-limited login
|
|
78
|
-
- **Folder browser** to pick working directories without typing paths
|
|
79
|
-
- **Initial command** — optionally launch a session straight into `htop`, `vim`, or any command
|
|
80
|
-
- **Shell detection** — auto-detects your shell on all platforms (PowerShell, cmd, bash, zsh, Git Bash, WSL)
|
|
81
|
-
- **QR code on startup** for instant phone connection
|
|
82
|
-
- **Command completion notifications** — get browser notifications when a command finishes in a background tab; toggle with the bell icon in the toolbar (opt-in, requires browser permission)
|
|
83
|
-
- **Terminal search** — press <kbd>Ctrl+F</kbd> / <kbd>Cmd+F</kbd> to open a search overlay with regex support, powered by xterm.js SearchAddon
|
|
84
|
-
- **Command palette** — press <kbd>Ctrl+K</kbd> / <kbd>Cmd+K</kbd> (or tap the ⚙️ button) to open a slide-out tool panel with categorized actions: Session, Search, View, Share, Notifications, and System
|
|
85
|
-
- **Light/dark theme** with persistent preference
|
|
86
|
-
- **Adjustable font size** via status bar controls, saved across sessions
|
|
87
|
-
- **Port preview** — reverse-proxy a single local web server port and preview it in the browser (HTTP only; no WebSocket/HMR; best with server-rendered apps)
|
|
88
|
-
- **Remote access via [DevTunnel](#remote-access)** — ephemeral or persisted public URLs
|
|
89
|
-
|
|
90
63
|
## Remote Access
|
|
91
64
|
|
|
92
65
|
```bash
|
|
@@ -115,6 +88,7 @@ termbeam [shell] [args...] # start with a specific shell (default: auto-d
|
|
|
115
88
|
termbeam --port 8080 # custom port (default: 3456)
|
|
116
89
|
termbeam --host 0.0.0.0 # allow LAN access (default: 127.0.0.1)
|
|
117
90
|
termbeam --lan # shortcut for --host 0.0.0.0
|
|
91
|
+
termbeam -i # interactive setup wizard
|
|
118
92
|
termbeam service install # interactive PM2 service setup wizard
|
|
119
93
|
termbeam service uninstall # stop & remove PM2 service
|
|
120
94
|
termbeam service status # show PM2 service status
|
|
@@ -135,6 +109,7 @@ termbeam service restart # restart PM2 service
|
|
|
135
109
|
| `--host <addr>` | Bind address | `127.0.0.1` |
|
|
136
110
|
| `--lan` | Bind to all interfaces (LAN access) | Off |
|
|
137
111
|
| `--log-level <level>` | Log verbosity (error/warn/info/debug) | `info` |
|
|
112
|
+
| `-i, --interactive` | Interactive setup wizard (guided configuration) | Off |
|
|
138
113
|
| `-h, --help` | Show help | — |
|
|
139
114
|
| `-v, --version` | Show version | — |
|
|
140
115
|
|
package/bin/termbeam.js
CHANGED
|
@@ -10,18 +10,33 @@ if (subcommand === 'service') {
|
|
|
10
10
|
});
|
|
11
11
|
} else {
|
|
12
12
|
const { createTermBeamServer } = require('../src/server.js');
|
|
13
|
-
const
|
|
13
|
+
const { parseArgs } = require('../src/cli');
|
|
14
|
+
const { runInteractiveSetup } = require('../src/interactive');
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
16
|
+
async function main() {
|
|
17
|
+
const baseConfig = parseArgs();
|
|
18
|
+
let config;
|
|
19
|
+
if (baseConfig.interactive) {
|
|
20
|
+
config = await runInteractiveSetup(baseConfig);
|
|
21
|
+
}
|
|
22
|
+
const instance = createTermBeamServer(config ? { config } : undefined);
|
|
23
|
+
|
|
24
|
+
process.on('SIGINT', () => {
|
|
25
|
+
console.log('\n[termbeam] Shutting down...');
|
|
26
|
+
instance.shutdown();
|
|
27
|
+
setTimeout(() => process.exit(0), 500).unref();
|
|
28
|
+
});
|
|
29
|
+
process.on('SIGTERM', () => {
|
|
30
|
+
console.log('\n[termbeam] Shutting down...');
|
|
31
|
+
instance.shutdown();
|
|
32
|
+
setTimeout(() => process.exit(0), 500).unref();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
instance.start();
|
|
36
|
+
}
|
|
25
37
|
|
|
26
|
-
|
|
38
|
+
main().catch((err) => {
|
|
39
|
+
console.error(err.message);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
});
|
|
27
42
|
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/* TermBeam shared theme variables — imported by index.html and terminal.html */
|
|
2
|
+
|
|
3
|
+
:root {
|
|
4
|
+
--bg: #1e1e1e;
|
|
5
|
+
--surface: #252526;
|
|
6
|
+
--border: #3c3c3c;
|
|
7
|
+
--border-subtle: #474747;
|
|
8
|
+
--text: #d4d4d4;
|
|
9
|
+
--text-secondary: #858585;
|
|
10
|
+
--text-dim: #6e6e6e;
|
|
11
|
+
--text-muted: #555555;
|
|
12
|
+
--accent: #0078d4;
|
|
13
|
+
--accent-hover: #1a8ae8;
|
|
14
|
+
--accent-active: #005a9e;
|
|
15
|
+
--danger: #f14c4c;
|
|
16
|
+
--danger-hover: #d73a3a;
|
|
17
|
+
--success: #89d185;
|
|
18
|
+
--overlay-bg: rgba(0, 0, 0, 0.85);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
[data-theme='light'] {
|
|
22
|
+
--bg: #ffffff;
|
|
23
|
+
--surface: #f3f3f3;
|
|
24
|
+
--border: #e0e0e0;
|
|
25
|
+
--border-subtle: #d0d0d0;
|
|
26
|
+
--text: #1e1e1e;
|
|
27
|
+
--text-secondary: #616161;
|
|
28
|
+
--text-dim: #767676;
|
|
29
|
+
--text-muted: #a0a0a0;
|
|
30
|
+
--accent: #0078d4;
|
|
31
|
+
--accent-hover: #106ebe;
|
|
32
|
+
--accent-active: #005a9e;
|
|
33
|
+
--danger: #e51400;
|
|
34
|
+
--danger-hover: #c20000;
|
|
35
|
+
--success: #16825d;
|
|
36
|
+
--overlay-bg: rgba(0, 0, 0, 0.5);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
[data-theme='monokai'] {
|
|
40
|
+
--bg: #272822;
|
|
41
|
+
--surface: #1e1f1c;
|
|
42
|
+
--border: #49483e;
|
|
43
|
+
--border-subtle: #5c5c4f;
|
|
44
|
+
--text: #f8f8f2;
|
|
45
|
+
--text-secondary: #a59f85;
|
|
46
|
+
--text-dim: #75715e;
|
|
47
|
+
--text-muted: #5a5854;
|
|
48
|
+
--accent: #a6e22e;
|
|
49
|
+
--accent-hover: #b8f53c;
|
|
50
|
+
--accent-active: #8acc16;
|
|
51
|
+
--danger: #f92672;
|
|
52
|
+
--danger-hover: #e0155d;
|
|
53
|
+
--success: #a6e22e;
|
|
54
|
+
--overlay-bg: rgba(0, 0, 0, 0.75);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
[data-theme='solarized-dark'] {
|
|
58
|
+
--bg: #002b36;
|
|
59
|
+
--surface: #073642;
|
|
60
|
+
--border: #586e75;
|
|
61
|
+
--border-subtle: #657b83;
|
|
62
|
+
--text: #839496;
|
|
63
|
+
--text-secondary: #657b83;
|
|
64
|
+
--text-dim: #586e75;
|
|
65
|
+
--text-muted: #4a5a62;
|
|
66
|
+
--accent: #268bd2;
|
|
67
|
+
--accent-hover: #379ce3;
|
|
68
|
+
--accent-active: #1a7abf;
|
|
69
|
+
--danger: #dc322f;
|
|
70
|
+
--danger-hover: #c8221f;
|
|
71
|
+
--success: #859900;
|
|
72
|
+
--overlay-bg: rgba(0, 0, 0, 0.75);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
[data-theme='solarized-light'] {
|
|
76
|
+
--bg: #fdf6e3;
|
|
77
|
+
--surface: #eee8d5;
|
|
78
|
+
--border: #93a1a1;
|
|
79
|
+
--border-subtle: #839496;
|
|
80
|
+
--text: #657b83;
|
|
81
|
+
--text-secondary: #93a1a1;
|
|
82
|
+
--text-dim: #a0a0a0;
|
|
83
|
+
--text-muted: #b0b0b0;
|
|
84
|
+
--accent: #268bd2;
|
|
85
|
+
--accent-hover: #379ce3;
|
|
86
|
+
--accent-active: #1a7abf;
|
|
87
|
+
--danger: #dc322f;
|
|
88
|
+
--danger-hover: #c8221f;
|
|
89
|
+
--success: #859900;
|
|
90
|
+
--overlay-bg: rgba(0, 0, 0, 0.4);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
[data-theme='nord'] {
|
|
94
|
+
--bg: #2e3440;
|
|
95
|
+
--surface: #3b4252;
|
|
96
|
+
--border: #434c5e;
|
|
97
|
+
--border-subtle: #4c566a;
|
|
98
|
+
--text: #d8dee9;
|
|
99
|
+
--text-secondary: #b0bac9;
|
|
100
|
+
--text-dim: #7b88a1;
|
|
101
|
+
--text-muted: #5c6a85;
|
|
102
|
+
--accent: #88c0d0;
|
|
103
|
+
--accent-hover: #9fd4e4;
|
|
104
|
+
--accent-active: #6aafbf;
|
|
105
|
+
--danger: #bf616a;
|
|
106
|
+
--danger-hover: #a84d57;
|
|
107
|
+
--success: #a3be8c;
|
|
108
|
+
--overlay-bg: rgba(0, 0, 0, 0.75);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
[data-theme='dracula'] {
|
|
112
|
+
--bg: #282a36;
|
|
113
|
+
--surface: #343746;
|
|
114
|
+
--border: #44475a;
|
|
115
|
+
--border-subtle: #525568;
|
|
116
|
+
--text: #f8f8f2;
|
|
117
|
+
--text-secondary: #c1c4d2;
|
|
118
|
+
--text-dim: #8e92a4;
|
|
119
|
+
--text-muted: #6272a4;
|
|
120
|
+
--accent: #bd93f9;
|
|
121
|
+
--accent-hover: #d0b0ff;
|
|
122
|
+
--accent-active: #a77de7;
|
|
123
|
+
--danger: #ff5555;
|
|
124
|
+
--danger-hover: #e03d3d;
|
|
125
|
+
--success: #50fa7b;
|
|
126
|
+
--overlay-bg: rgba(0, 0, 0, 0.75);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
[data-theme='github-dark'] {
|
|
130
|
+
--bg: #0d1117;
|
|
131
|
+
--surface: #161b22;
|
|
132
|
+
--border: #30363d;
|
|
133
|
+
--border-subtle: #3d444d;
|
|
134
|
+
--text: #c9d1d9;
|
|
135
|
+
--text-secondary: #8b949e;
|
|
136
|
+
--text-dim: #6e7681;
|
|
137
|
+
--text-muted: #484f58;
|
|
138
|
+
--accent: #58a6ff;
|
|
139
|
+
--accent-hover: #79b8ff;
|
|
140
|
+
--accent-active: #388bfd;
|
|
141
|
+
--danger: #f85149;
|
|
142
|
+
--danger-hover: #da3633;
|
|
143
|
+
--success: #3fb950;
|
|
144
|
+
--overlay-bg: rgba(0, 0, 0, 0.75);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
[data-theme='one-dark'] {
|
|
148
|
+
--bg: #282c34;
|
|
149
|
+
--surface: #21252b;
|
|
150
|
+
--border: #3e4452;
|
|
151
|
+
--border-subtle: #4b5263;
|
|
152
|
+
--text: #abb2bf;
|
|
153
|
+
--text-secondary: #7f848e;
|
|
154
|
+
--text-dim: #5c6370;
|
|
155
|
+
--text-muted: #4b5263;
|
|
156
|
+
--accent: #61afef;
|
|
157
|
+
--accent-hover: #7dc0ff;
|
|
158
|
+
--accent-active: #4d9ede;
|
|
159
|
+
--danger: #e06c75;
|
|
160
|
+
--danger-hover: #c95c67;
|
|
161
|
+
--success: #98c379;
|
|
162
|
+
--overlay-bg: rgba(0, 0, 0, 0.75);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
[data-theme='catppuccin'] {
|
|
166
|
+
--bg: #1e1e2e;
|
|
167
|
+
--surface: #313244;
|
|
168
|
+
--border: #45475a;
|
|
169
|
+
--border-subtle: #585b70;
|
|
170
|
+
--text: #cdd6f4;
|
|
171
|
+
--text-secondary: #a6adc8;
|
|
172
|
+
--text-dim: #7f849c;
|
|
173
|
+
--text-muted: #585b70;
|
|
174
|
+
--accent: #89b4fa;
|
|
175
|
+
--accent-hover: #b4d0ff;
|
|
176
|
+
--accent-active: #5c9de3;
|
|
177
|
+
--danger: #f38ba8;
|
|
178
|
+
--danger-hover: #eb7c9d;
|
|
179
|
+
--success: #a6e3a1;
|
|
180
|
+
--overlay-bg: rgba(0, 0, 0, 0.75);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
[data-theme='gruvbox'] {
|
|
184
|
+
--bg: #282828;
|
|
185
|
+
--surface: #3c3836;
|
|
186
|
+
--border: #504945;
|
|
187
|
+
--border-subtle: #665c54;
|
|
188
|
+
--text: #ebdbb2;
|
|
189
|
+
--text-secondary: #d5c4a1;
|
|
190
|
+
--text-dim: #a89984;
|
|
191
|
+
--text-muted: #7c6f64;
|
|
192
|
+
--accent: #83a598;
|
|
193
|
+
--accent-hover: #9dbfb4;
|
|
194
|
+
--accent-active: #6a8f8a;
|
|
195
|
+
--danger: #fb4934;
|
|
196
|
+
--danger-hover: #e33826;
|
|
197
|
+
--success: #b8bb26;
|
|
198
|
+
--overlay-bg: rgba(0, 0, 0, 0.75);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
[data-theme='night-owl'] {
|
|
202
|
+
--bg: #011627;
|
|
203
|
+
--surface: #0d2a45;
|
|
204
|
+
--border: #1d3b53;
|
|
205
|
+
--border-subtle: #264863;
|
|
206
|
+
--text: #d6deeb;
|
|
207
|
+
--text-secondary: #8badc1;
|
|
208
|
+
--text-dim: #5f7e97;
|
|
209
|
+
--text-muted: #3f5f7d;
|
|
210
|
+
--accent: #7fdbca;
|
|
211
|
+
--accent-hover: #9ff0e0;
|
|
212
|
+
--accent-active: #62c5b5;
|
|
213
|
+
--danger: #ef5350;
|
|
214
|
+
--danger-hover: #d83130;
|
|
215
|
+
--success: #addb67;
|
|
216
|
+
--overlay-bg: rgba(0, 0, 0, 0.75);
|
|
217
|
+
}
|