Skip to content

Commit 13713a3

Browse files
feat(cli): add attach alias, improve empty-session messages, add startup hints (#119)
Improves the CLI experience for session management. Adds `termbeam attach` as a non-breaking alias for `termbeam resume` to match tmux/docker conventions. Shows the server URL in empty-session messages so users can tell the server is reachable. Adds next-step hints after server and service startup showing available commands. Closes #118 --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 2ed1b6e commit 13713a3

9 files changed

Lines changed: 34 additions & 20 deletions

File tree

bin/termbeam.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ if (subcommand === 'service') {
88
console.error(err.message);
99
process.exit(1);
1010
});
11-
} else if (subcommand === 'resume') {
11+
} else if (subcommand === 'resume' || subcommand === 'attach') {
1212
const { resume } = require('../src/resume');
1313
resume(process.argv.slice(3)).catch((err) => {
1414
console.error(err.message);
@@ -129,7 +129,7 @@ if (subcommand === 'service') {
129129
const displayHost = existing.host === '127.0.0.1' ? 'localhost' : existing.host;
130130
console.error(
131131
`TermBeam is already running on http://${displayHost}:${existing.port}\n` +
132-
'Use "termbeam resume" to reconnect, "termbeam list" to list sessions,\n' +
132+
'Use "termbeam resume" (or "termbeam attach") to reconnect, "termbeam list" to list sessions,\n' +
133133
'or "termbeam --force" to stop the existing server and start a new one.',
134134
);
135135
process.exit(1);

docs/architecture.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ WebSocket terminal client used by the `resume` command. Handles raw-mode stdin/s
161161

162162
### `resume.js` — Resume & List Subcommands
163163

164-
Implements the `termbeam resume [name]` and `termbeam list` CLI subcommands. Auto-discovers running servers via `~/.termbeam/connection.json`, lists sessions, provides an interactive arrow-key chooser when multiple sessions exist, and delegates terminal attachment to `client.js`.
164+
Implements the `termbeam resume [name]` (alias: `termbeam attach`) and `termbeam list` CLI subcommands. Auto-discovers running servers via `~/.termbeam/connection.json`, lists sessions, provides an interactive arrow-key chooser when multiple sessions exist, and delegates terminal attachment to `client.js`.
165165

166166
---
167167

docs/resume.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ termbeam list
1010

1111
# Reconnect to a running session (interactive chooser if multiple)
1212
termbeam resume
13+
# or equivalently:
14+
termbeam attach
1315

1416
# Reconnect by session name
1517
termbeam resume my-project
@@ -18,14 +20,15 @@ termbeam resume my-project
1820
# Press Ctrl+B
1921
```
2022

21-
## `termbeam resume`
23+
## `termbeam resume` (alias: `termbeam attach`)
2224

2325
Connects to a running TermBeam server and attaches to a session via WebSocket, piping your terminal's stdin/stdout directly. The experience is identical to working in the original terminal.
2426

2527
### Usage
2628

2729
```
2830
termbeam resume [name] [options]
31+
termbeam attach [name] [options] # alias
2932
```
3033

3134
### Arguments
@@ -97,7 +100,7 @@ When a TermBeam server starts, it saves connection details to `~/.termbeam/conne
97100
}
98101
```
99102

100-
The `resume` and `list` commands read this file automatically, so you don't need to remember or type the port and password. The file is removed when the server shuts down.
103+
The `resume` (or `attach`) and `list` commands read this file automatically, so you don't need to remember or type the port and password. The file is removed when the server shuts down.
101104

102105
<!-- prettier-ignore -->
103106
!!! note "Multiple servers"

package-lock.json

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/cli.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ termbeam — Beam your terminal to any device
1010
1111
Usage:
1212
termbeam [options] [shell] [args...]
13-
termbeam resume [name] [options] Reconnect to a running session
13+
termbeam resume [name] [options] Reconnect to a running session (alias: attach)
1414
termbeam list List running sessions
1515
termbeam service <action> Manage as a background service (PM2)
1616
@@ -54,6 +54,7 @@ Examples:
5454
termbeam --interactive Guided setup wizard
5555
termbeam service install Set up as background service (PM2)
5656
termbeam resume Reconnect to an active session
57+
termbeam attach my-session Attach to a named session (alias for resume)
5758
termbeam list List all active sessions
5859
5960
Environment:

src/resume.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ function detachKeyLabel(key) {
155155

156156
function printResumeHelp() {
157157
console.log(`
158-
${bold('termbeam resume')} — Reconnect to a running session
158+
${bold('termbeam resume')} (alias: ${bold('attach')}) — Reconnect to a running session
159159
160160
${bold('Usage:')}
161161
termbeam resume [name] [options]
@@ -243,7 +243,7 @@ async function resume(args) {
243243
const { host, port, password, sessions, opts } = conn;
244244

245245
if (sessions.length === 0) {
246-
console.error(red(' No active sessions on the server.'));
246+
console.error(red(` Connected to server on ${conn.displayUrl} — no active sessions.`));
247247
process.exit(1);
248248
}
249249

@@ -345,7 +345,7 @@ async function list() {
345345
}
346346

347347
if (sessions.length === 0) {
348-
console.log(dim(' No active sessions.'));
348+
console.log(dim(` Connected to server on ${displayUrl} — no active sessions.`));
349349
return;
350350
}
351351

src/server.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,12 @@ function createTermBeamServer(overrides = {}) {
266266
console.log(` Scan the QR code or open: ${bl}${qrDisplayUrl}${rs}`);
267267
if (config.password) process.stdout.write(` Password: ${gn}${config.password}${rs}\n`);
268268
console.log('');
269+
console.log(`${_dm} From another terminal:${rs}`);
270+
console.log(`${_dm} termbeam list List active sessions${rs}`);
271+
console.log(
272+
`${_dm} termbeam resume Attach to a session (or: termbeam attach)${rs}`,
273+
);
274+
console.log('');
269275

270276
resolve({ url: `http://localhost:${actualPort}`, defaultId });
271277
});

src/service.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -460,9 +460,13 @@ async function actionInstall() {
460460
}
461461

462462
console.log(dim('\nUseful commands:'));
463-
console.log(` ${cyan('termbeam service status')} — Check service status`);
464-
console.log(` ${cyan('termbeam service logs')} — View logs`);
465-
console.log(` ${cyan('termbeam service restart')} — Restart service`);
463+
console.log(` ${cyan('termbeam list')} — List active sessions`);
464+
console.log(
465+
` ${cyan('termbeam resume')} — Attach to a session (or: termbeam attach)`,
466+
);
467+
console.log(` ${cyan('termbeam service status')} — Check service status`);
468+
console.log(` ${cyan('termbeam service logs')} — View logs`);
469+
console.log(` ${cyan('termbeam service restart')} — Restart service`);
466470
console.log(` ${cyan('termbeam service uninstall')} — Remove service\n`);
467471
}
468472

test/resume.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -873,7 +873,7 @@ describe('resume', () => {
873873
reloadResume();
874874

875875
await resume.list();
876-
// Should print "No active sessions." and return
876+
// Should print "Connected to server on ... — no active sessions." and return
877877
});
878878

879879
it('should display singular "session" when count is 1', async () => {

0 commit comments

Comments
 (0)