cmux-ssh-here 0.4.0 → 0.4.1

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.
Files changed (2) hide show
  1. package/bin.js +40 -17
  2. package/package.json +1 -1
package/bin.js CHANGED
@@ -322,42 +322,65 @@ server.listen(PORT, "0.0.0.0", function () {
322
322
  return `https://cmux.com/deeplink/ssh?${params}`;
323
323
  };
324
324
 
325
- // ponytail: in debug mode skip the screen-clearing UI so logs stay readable;
326
- // just print the link whenever it rotates.
325
+ // ponytail: in debug mode skip the dashboard so logs stay readable.
327
326
  const liveUI = !process.env.CMUX_SSH_DEBUG;
328
327
  const ago = (since) => `${Math.floor((Date.now() - since) / 1000)}s`;
329
328
 
330
- render = () => {
331
- if (!liveUI) return;
329
+ // ponytail: never clear the whole screen (that wipes the user's selection and
330
+ // makes the link impossible to copy). Repaint the static block only on real
331
+ // events (link rotation, session add/remove); the per-second countdown rewrites
332
+ // just its own line via "\r", leaving the link above untouched and selectable.
333
+ const countdownLine = () => ` ↻ Link regenerates in ${remaining}s — copy it above. Ctrl-C to stop.`;
334
+
335
+ // Collapse the raw SSH connections (cmux opens several from one machine:
336
+ // ControlMaster, the daemon channel, short-lived probes) into one row per IP.
337
+ const sessionRows = () => {
338
+ const byIp = new Map();
339
+ for (const s of sessions.values()) {
340
+ const e = byIp.get(s.ip);
341
+ if (e) { e.count++; e.since = Math.min(e.since, s.since); }
342
+ else byIp.set(s.ip, { count: 1, since: s.since });
343
+ }
344
+ return [...byIp.entries()].map(
345
+ ([ipAddr, e]) => ` • ${ipAddr} connected ${ago(e.since)} ago${e.count > 1 ? ` (${e.count} connections)` : ""}`
346
+ );
347
+ };
348
+
349
+ const block = () => {
332
350
  const lines = [
333
351
  "",
334
352
  ` cmux-ssh-here — shell as ${user} over the LAN`,
335
353
  "",
336
- ` Open in cmux (regenerates in ${remaining}s):`,
354
+ " Open in cmux:",
337
355
  ` ${buildLink()}`,
338
356
  "",
339
357
  ];
340
- if (sessions.size) {
341
- lines.push(` Connected sessions (${sessions.size}):`);
342
- for (const s of sessions.values()) lines.push(` • ${s.ip} connected ${ago(s.since)} ago`);
343
- } else {
344
- lines.push(" No active sessions yet.");
345
- }
346
- lines.push("", " Ctrl-C to stop.", "");
347
- // Clear screen + home, then redraw.
348
- process.stdout.write(`\x1b[2J\x1b[3J\x1b[H${lines.join("\n")}\n`);
358
+ const rows = sessionRows();
359
+ if (rows.length) lines.push(` Connected (${rows.length}):`, ...rows);
360
+ else lines.push(" No active sessions yet.");
361
+ lines.push("");
362
+ return lines.join("\n");
363
+ };
364
+
365
+ // Repaint the block, then leave the cursor parked on the countdown line.
366
+ render = () => {
367
+ if (!liveUI) return;
368
+ process.stdout.write(`\n${block()}\n${countdownLine()}`);
349
369
  };
350
370
 
351
371
  if (liveUI) render();
352
372
  else console.log(`\n Open in cmux (regenerates in ${remaining}s):\n ${buildLink()}\n`);
353
373
 
354
- // Tick once a second: count down, regenerate on expiry, refresh the UI.
355
374
  setInterval(() => {
356
375
  remaining--;
357
376
  if (remaining <= 0) {
358
377
  regenerateToken();
359
- if (!liveUI) console.log(`\n [link regenerated]\n ${buildLink()}\n`);
378
+ // Link changed: repaint the whole block (rare — once per TTL).
379
+ if (liveUI) render();
380
+ else console.log(`\n [link regenerated]\n ${buildLink()}\n`);
381
+ return;
360
382
  }
361
- render();
383
+ // Common case: rewrite only the countdown line in place — no screen churn.
384
+ if (liveUI) process.stdout.write(`\r\x1b[2K${countdownLine()}`);
362
385
  }, 1000);
363
386
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cmux-ssh-here",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "Spin up a token-auth SSH server and print a cmux deep link to connect over LAN",
5
5
  "type": "module",
6
6
  "bin": {