blun-king-cli 9.1.20 → 9.1.22

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.
@@ -31,6 +31,13 @@ const UPDATE_SIGNAL_EXIT_CODES = Object.freeze({
31
31
  SIGINT: 130,
32
32
  SIGTERM: 143,
33
33
  });
34
+ const INTERACTIVE_START_MODE_FLAGS = new Set([
35
+ '-y',
36
+ '--auto',
37
+ '--auto-approve',
38
+ '--plan',
39
+ '--yolo',
40
+ ]);
34
41
  const SEMVER_IDENTIFIER = '(?:0|[1-9]\\d*|\\d*[A-Za-z-][0-9A-Za-z-]*)';
35
42
  const SEMVER_PATTERN = new RegExp(
36
43
  `^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)`
@@ -435,8 +442,10 @@ function writeSkippedVersion(blunDir, skippedVersion) {
435
442
  }
436
443
 
437
444
  function isInteractiveUpdateStart({ argv, env, stdin, stdout }) {
438
- return Array.isArray(argv)
439
- && argv.length === 0
445
+ const isOrdinaryStartup = Array.isArray(argv)
446
+ && (argv.length === 0
447
+ || (argv.length === 1 && INTERACTIVE_START_MODE_FLAGS.has(argv[0])));
448
+ return isOrdinaryStartup
440
449
  && (!env || env.BLUN_NO_AUTO_UPDATE !== '1')
441
450
  && stdin?.isTTY === true
442
451
  && stdout?.isTTY === true;
@@ -449,48 +458,65 @@ function installCommandText(version) {
449
458
  function createUpdateProgress(output) {
450
459
  const enabled = output?.isTTY === true;
451
460
  const phaseCount = 4;
452
- const width = 20;
453
- return (phase, label) => {
461
+ const width = 24;
462
+ const cyan = '\u001B[36m';
463
+ const dim = '\u001B[2m';
464
+ const reset = '\u001B[0m';
465
+ let active = false;
466
+ const update = (phase, label) => {
454
467
  if (!enabled) return;
455
468
  const completed = Math.max(0, Math.min(phaseCount, phase));
456
469
  const filled = Math.round((completed / phaseCount) * width);
457
- const bar = `${'#'.repeat(filled)}${'-'.repeat(width - filled)}`;
458
- output.write(`Update [${bar}] ${completed}/${phaseCount} ${label}\n`);
470
+ const bar = `${''.repeat(filled)}${''.repeat(width - filled)}`;
471
+ output.write(`\r\u001B[2K${cyan}${bar}${reset} ${dim}${completed}/${phaseCount}${reset} ${label}`);
472
+ active = completed < phaseCount;
473
+ if (!active) output.write('\n');
474
+ };
475
+ update.finish = () => {
476
+ if (!enabled || !active) return;
477
+ active = false;
478
+ output.write('\n');
459
479
  };
480
+ return update;
460
481
  }
461
482
 
462
483
  function promptUpdateAction({ currentVersion, release, input, output, processRef = process }) {
463
484
  return new Promise((resolve, reject) => {
464
- let selected = 1;
485
+ let selected = 0;
465
486
  let settled = false;
466
487
  let cursorHidden = false;
467
488
  let escapeTimer;
468
489
  let pendingInput = '';
469
490
  const decoder = new StringDecoder('utf8');
470
491
  const wasRaw = input.isRaw === true;
492
+ const cyan = '\u001B[36m';
493
+ const dim = '\u001B[2m';
494
+ const underline = '\u001B[4m';
495
+ const reset = '\u001B[0m';
471
496
  const actions = [
472
497
  {
473
498
  choice: 'install',
474
499
  label: `Jetzt aktualisieren (führt \`${installCommandText(release.version)}\` aus)`,
475
500
  },
476
- { choice: 'postpone', label: 'In sieben Tagen erneut fragen' },
477
- { choice: 'skip-version', label: 'Diese Version überspringen' },
501
+ { choice: 'skip-once', label: 'Überspringen' },
502
+ { choice: 'skip-version', label: 'Auf den nächsten Release warten' },
478
503
  ];
479
504
  const signalHandlers = new Map();
480
505
 
481
506
  const renderActions = (refresh) => {
482
507
  if (refresh) output.write(`\u001B[${actions.length + 1}F`);
483
508
  for (let index = 0; index < actions.length; index += 1) {
484
- output.write(`\r\u001B[2K ${selected === index ? '>' : ' '} ${index + 1}. ${actions[index].label}\n`);
509
+ const line = `${selected === index ? '' : ' '} ${index + 1}. ${actions[index].label}`;
510
+ output.write(`\r\u001B[2K${selected === index ? cyan : ''}${line}${selected === index ? reset : ''}\n`);
485
511
  }
486
- output.write('\r\u001B[2KEnter drücken, um fortzufahren\n');
512
+ output.write(`\r\u001B[2K${dim}Enter drücken, um fortzufahren${reset}\n`);
487
513
  };
488
514
  const cleanup = () => {
489
515
  if (escapeTimer !== undefined) clearTimeout(escapeTimer);
490
516
  input.removeListener('data', onData);
491
- input.removeListener('end', postpone);
492
- input.removeListener('close', postpone);
493
- input.removeListener('error', postpone);
517
+ input.removeListener('end', skipOnce);
518
+ input.removeListener('close', skipOnce);
519
+ input.removeListener('error', skipOnce);
494
520
  for (const [signal, handler] of signalHandlers) {
495
521
  processRef.removeListener(signal, handler);
496
522
  }
@@ -537,14 +563,14 @@ function promptUpdateAction({ currentVersion, release, input, output, processRef
537
563
  if (typeof processRef.exit === 'function') processRef.exit(exitCode);
538
564
  reject(error);
539
565
  };
540
- function postpone() {
541
- finish('postpone');
566
+ function skipOnce() {
567
+ finish('skip-once');
542
568
  }
543
569
  const waitForEscapeSuffix = () => {
544
570
  if (escapeTimer !== undefined) return;
545
571
  escapeTimer = setTimeout(() => {
546
572
  escapeTimer = undefined;
547
- postpone();
573
+ skipOnce();
548
574
  }, UPDATE_KEY_ESCAPE_TIMEOUT_MS);
549
575
  };
550
576
  const clearEscapeTimer = () => {
@@ -573,7 +599,7 @@ function promptUpdateAction({ currentVersion, release, input, output, processRef
573
599
  while (pendingInput.length > 0) {
574
600
  const first = pendingInput[0];
575
601
  if (first === '\u0003') {
576
- postpone();
602
+ skipOnce();
577
603
  return;
578
604
  }
579
605
  if (first === '\r' || first === '\n') {
@@ -596,7 +622,7 @@ function promptUpdateAction({ currentVersion, release, input, output, processRef
596
622
  && (pendingInput[1] === '\r'
597
623
  || pendingInput[1] === '\n'
598
624
  || pendingInput[1] === '\u0003')) {
599
- postpone();
625
+ skipOnce();
600
626
  return;
601
627
  }
602
628
  const sequence = readEscapeSequence();
@@ -638,16 +664,18 @@ function promptUpdateAction({ currentVersion, release, input, output, processRef
638
664
  signalHandlers.set(signal, handler);
639
665
  processRef.once(signal, handler);
640
666
  }
641
- output.write(`\nNeues Update verfügbar (${currentVersion} -> ${release.version})\n`);
642
- if (release.notesUrl) output.write(`Versionshinweise: ${release.notesUrl}\n`);
667
+ output.write(`\nBLUN Code-Update verfügbar: ${currentVersion} -> ${release.version}\n`);
668
+ if (release.notesUrl) {
669
+ output.write(`${dim}Versionshinweise:${reset} ${underline}${release.notesUrl}${reset}\n`);
670
+ }
643
671
  output.write('\n');
644
672
  cursorHidden = true;
645
673
  output.write('\u001B[?25l');
646
674
  renderActions(false);
647
675
  input.on('data', onData);
648
- input.once('end', postpone);
649
- input.once('close', postpone);
650
- input.once('error', postpone);
676
+ input.once('end', skipOnce);
677
+ input.once('close', skipOnce);
678
+ input.once('error', skipOnce);
651
679
  if (typeof input.setRawMode === 'function') input.setRawMode(true);
652
680
  if (typeof input.resume === 'function') input.resume();
653
681
  } catch (error) {
@@ -1260,6 +1288,9 @@ async function runUpdateFlow(options, explicitUpdate) {
1260
1288
  }
1261
1289
  if (action !== 'install') {
1262
1290
  if (installerSession?.ready) await installerSession.cancel();
1291
+ if (action === 'skip-once') {
1292
+ return { kind: 'continue', reason: 'skipped_once' };
1293
+ }
1263
1294
  if (action === 'skip-version') {
1264
1295
  try {
1265
1296
  writeSkippedVersion(blunDir, release.version);
@@ -1299,6 +1330,7 @@ async function runUpdateFlow(options, explicitUpdate) {
1299
1330
  if (installResult?.leaseBusy === true
1300
1331
  || installResult?.leaseUnavailable === true
1301
1332
  || installResult?.unknownState === true) {
1333
+ updateProgress.finish();
1302
1334
  return explicitUpdate
1303
1335
  ? explicitFailure(stderr, 'update_in_progress')
1304
1336
  : { kind: 'update_in_progress' };
@@ -1310,12 +1342,14 @@ async function runUpdateFlow(options, explicitUpdate) {
1310
1342
  }
1311
1343
 
1312
1344
  if (Number.isInteger(installResult?.code) && installResult.code !== 0) {
1345
+ updateProgress.finish();
1313
1346
  if (explicitUpdate) {
1314
1347
  return explicitFailure(stderr, 'install_failed', installResult.code);
1315
1348
  }
1316
1349
  stderr.write(`Update fehlgeschlagen (Code ${installResult.code}). Die vorhandene Version wird gestartet.\n`);
1317
1350
  return { kind: 'continue', reason: 'install_failed', exitCode: installResult.code };
1318
1351
  }
1352
+ updateProgress.finish();
1319
1353
  if (explicitUpdate) return explicitFailure(stderr, 'verification_failed');
1320
1354
  stderr.write('Update konnte nicht verifiziert werden. Starte BLUN Code neu.\n');
1321
1355
  return { kind: 'update_in_progress' };