bloby-bot 0.17.6 → 0.17.7

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/bin/cli.js CHANGED
@@ -24,6 +24,11 @@ const subcommand = args[1];
24
24
  const flags = new Set(args.filter(a => a.startsWith('--')));
25
25
  const HOSTED = flags.has('--hosted');
26
26
 
27
+ // ── Terminal safety: always restore cursor on exit ──
28
+ process.on('exit', () => process.stdout.write('\x1b[?25h'));
29
+ process.on('SIGINT', () => { process.stdout.write('\x1b[?25h'); process.exit(0); });
30
+ process.on('SIGTERM', () => { process.stdout.write('\x1b[?25h'); process.exit(0); });
31
+
27
32
  // ── Daemon constants & helpers ──
28
33
 
29
34
  const PLATFORM = os.platform();
@@ -323,6 +328,7 @@ function chooseTunnelMode() {
323
328
  }
324
329
  }
325
330
 
331
+ process.stdout.write('\x1b[?25l'); // Hide cursor
326
332
  render();
327
333
 
328
334
  // Enable raw mode for arrow key input
@@ -338,12 +344,13 @@ function chooseTunnelMode() {
338
344
  selected = (selected + 1) % options.length;
339
345
  render();
340
346
  } else if (key === '\r' || key === '\n') { // Enter
347
+ process.stdout.write('\x1b[?25h'); // Show cursor
341
348
  process.stdin.setRawMode(false);
342
349
  process.stdin.pause();
343
350
  process.stdin.removeListener('data', onKey);
344
351
  resolve(options[selected].mode);
345
352
  } else if (key === '\x03') { // Ctrl+C
346
- process.stdout.write('\n');
353
+ process.stdout.write('\x1b[?25h\n');
347
354
  process.exit(0);
348
355
  }
349
356
  };
@@ -450,6 +457,21 @@ class Stepper {
450
457
 
451
458
  start() {
452
459
  console.log('');
460
+ // Hide cursor and suppress user input during animation
461
+ process.stdout.write('\x1b[?25l');
462
+ if (process.stdin.isTTY) {
463
+ process.stdin.setRawMode(true);
464
+ process.stdin.resume();
465
+ this._stdinHandler = (data) => {
466
+ // Allow Ctrl+C
467
+ if (data[0] === 0x03) {
468
+ this._restoreTerminal();
469
+ process.exit(0);
470
+ }
471
+ // Discard everything else
472
+ };
473
+ process.stdin.on('data', this._stdinHandler);
474
+ }
453
475
  this.interval = setInterval(() => {
454
476
  this.frame = (this.frame + 1) % SPINNER.length;
455
477
  this.render();
@@ -457,6 +479,18 @@ class Stepper {
457
479
  this.render();
458
480
  }
459
481
 
482
+ _restoreTerminal() {
483
+ process.stdout.write('\x1b[?25h');
484
+ if (process.stdin.isTTY) {
485
+ if (this._stdinHandler) {
486
+ process.stdin.removeListener('data', this._stdinHandler);
487
+ this._stdinHandler = null;
488
+ }
489
+ try { process.stdin.setRawMode(false); } catch {}
490
+ process.stdin.pause();
491
+ }
492
+ }
493
+
460
494
  setInfo(lines) {
461
495
  this.infoLines = lines || [];
462
496
  this.render();
@@ -505,6 +539,7 @@ class Stepper {
505
539
  finish() {
506
540
  this.done = true;
507
541
  if (this.interval) clearInterval(this.interval);
542
+ this._restoreTerminal();
508
543
 
509
544
  if (this._totalLines > 0) {
510
545
  process.stdout.write(`\x1b[${this._totalLines}A`);