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 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-friendly UI that actually works on small screens.
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 instance = createTermBeamServer();
13
+ const { parseArgs } = require('../src/cli');
14
+ const { runInteractiveSetup } = require('../src/interactive');
14
15
 
15
- process.on('SIGINT', () => {
16
- console.log('\n[termbeam] Shutting down...');
17
- instance.shutdown();
18
- setTimeout(() => process.exit(0), 500).unref();
19
- });
20
- process.on('SIGTERM', () => {
21
- console.log('\n[termbeam] Shutting down...');
22
- instance.shutdown();
23
- setTimeout(() => process.exit(0), 500).unref();
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
- instance.start();
38
+ main().catch((err) => {
39
+ console.error(err.message);
40
+ process.exit(1);
41
+ });
27
42
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "termbeam",
3
- "version": "1.5.0",
3
+ "version": "1.8.0",
4
4
  "description": "Beam your terminal to any device — mobile-optimized web terminal with multi-session support",
5
5
  "main": "src/server.js",
6
6
  "bin": {
@@ -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
+ }