blun-king-cli 9.1.41 → 9.1.42

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.
@@ -26,6 +26,7 @@ const STATE_FILE = 'update-notice.json';
26
26
  const UPDATE_SKIP_FILE = 'update-skip-version.json';
27
27
  const PENDING_UPDATE_FILE = 'update-pending.json';
28
28
  const UPDATE_DIRECTORY = 'updates';
29
+ const CORE_INSTALL_STATE_FILE = 'install.json';
29
30
  const UPDATE_KEY_ESCAPE_TIMEOUT_MS = 500;
30
31
  const UPDATE_SIGNAL_EXIT_CODES = Object.freeze({
31
32
  SIGHUP: 129,
@@ -495,6 +496,43 @@ function clearPendingUpdate(blunDir) {
495
496
  fs.rmSync(pendingUpdatePath(blunDir), { force: true });
496
497
  }
497
498
 
499
+ function writeCoreInstallSuccess(blunDir, fromVersion, version, now = Date.now()) {
500
+ if (!parseSemver(fromVersion) || !parseSemver(version)) {
501
+ throw new Error('INVALID_UPDATE_VERSION');
502
+ }
503
+ const updateDirectory = path.join(blunDir, UPDATE_DIRECTORY);
504
+ ensurePrivateDirectory(blunDir);
505
+ ensurePrivateDirectory(updateDirectory);
506
+ const filePath = path.join(updateDirectory, CORE_INSTALL_STATE_FILE);
507
+ const temporaryPath = path.join(
508
+ updateDirectory,
509
+ `.${CORE_INSTALL_STATE_FILE}.${process.pid}.${randomUUID()}.tmp`,
510
+ );
511
+ try {
512
+ writePrivateFile(temporaryPath, `${JSON.stringify({
513
+ active: null,
514
+ lastFailure: null,
515
+ lastSuccess: {
516
+ version,
517
+ fromVersion,
518
+ installedAt: new Date(now).toISOString(),
519
+ notifiedAt: null,
520
+ },
521
+ })}\n`);
522
+ const handle = fs.openSync(temporaryPath, 'r+');
523
+ try {
524
+ fs.fsyncSync(handle);
525
+ } finally {
526
+ fs.closeSync(handle);
527
+ }
528
+ fs.renameSync(temporaryPath, filePath);
529
+ securePrivateFile(filePath);
530
+ } catch (error) {
531
+ fs.rmSync(temporaryPath, { force: true });
532
+ throw error;
533
+ }
534
+ }
535
+
498
536
  function isInteractiveUpdateStart({ argv, env, stdin, stdout }) {
499
537
  const isOrdinaryStartup = Array.isArray(argv)
500
538
  && (argv.length === 0
@@ -1178,10 +1216,10 @@ function noReleaseReason(currentVersion, registryTags, fallbackManifest) {
1178
1216
  return parseSemver(latest) || fallbackManifest ? 'current' : 'unavailable';
1179
1217
  }
1180
1218
 
1181
- function explicitNoTarget(stdout, reason) {
1219
+ function explicitNoTarget(stdout, reason, currentVersion) {
1182
1220
  stdout.write(reason === 'current'
1183
- ? 'Kein Update verfügbar. BLUN Code ist auf dem aktuellen Updatekanal.\n'
1184
- : 'Kein sicherer Update-Zielstand verfügbar.\n');
1221
+ ? `Kein Update verfügbar. Installiert: ${currentVersion} · Aktuell: ${currentVersion}.\n`
1222
+ : `Kein sicherer Update-Zielstand verfügbar. Installiert: ${currentVersion}.\n`);
1185
1223
  return { kind: 'current', reason };
1186
1224
  }
1187
1225
 
@@ -1280,7 +1318,7 @@ async function runUpdateFlow(options, explicitUpdate) {
1280
1318
  sources = await (options.loadReleaseSources || loadReleaseSources)();
1281
1319
  } catch {
1282
1320
  return explicitUpdate
1283
- ? explicitNoTarget(stdout, 'unavailable')
1321
+ ? explicitNoTarget(stdout, 'unavailable', currentVersion)
1284
1322
  : { kind: 'continue', reason: 'unavailable' };
1285
1323
  }
1286
1324
  const registryTags = parseRegistryDocument(sources?.registryDocument);
@@ -1289,7 +1327,7 @@ async function runUpdateFlow(options, explicitUpdate) {
1289
1327
  if (!release) {
1290
1328
  const reason = noReleaseReason(currentVersion, registryTags, fallbackManifest);
1291
1329
  return explicitUpdate
1292
- ? explicitNoTarget(stdout, reason)
1330
+ ? explicitNoTarget(stdout, reason, currentVersion)
1293
1331
  : { kind: 'continue', reason };
1294
1332
  }
1295
1333
  const queuedForRelease = pendingVersion === release.version;
@@ -1413,7 +1451,22 @@ async function runUpdateFlow(options, explicitUpdate) {
1413
1451
  if (installResult?.code === 0 && installResult?.verified === true) {
1414
1452
  updateProgress(4, 'Installation geprüft');
1415
1453
  clearPendingUpdate(blunDir);
1416
- stdout.write('Update erfolgreich installiert. Starte BLUN Code neu, um die neue Version zu verwenden.\n');
1454
+ try {
1455
+ writeCoreInstallSuccess(
1456
+ blunDir,
1457
+ currentVersion,
1458
+ release.version,
1459
+ (options.now || Date.now)(),
1460
+ );
1461
+ } catch {
1462
+ stderr.write(
1463
+ `Update ${release.version} wurde installiert, aber die Startmeldung konnte nicht gespeichert werden.\n`,
1464
+ );
1465
+ }
1466
+ stdout.write(
1467
+ `Update ${currentVersion} -> ${release.version} erfolgreich installiert. Starte BLUN Code neu, um die neue Version zu verwenden.\n`,
1468
+ );
1469
+ if (release.notesUrl) stdout.write(`Versionshinweise: ${release.notesUrl}\n`);
1417
1470
  return { kind: 'installed', version: release.version };
1418
1471
  }
1419
1472
 
package/blun.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- // BLUN_BUILD_INPUT_SHA256:6009b58ca14a14c742deab1a33fcd60086908033898c436965fbdad7c20c9073
2
+ // BLUN_BUILD_INPUT_SHA256:e742852861871f37f8395d93073c267847862c7dc263b88fef831cbe36a70bb9
3
3
  import { fileURLToPath as __cjsShimFileURLToPath } from 'node:url';
4
4
  import { dirname as __cjsShimDirname } from 'node:path';
5
5
  const __filename = __cjsShimFileURLToPath(import.meta.url);
@@ -515539,11 +515539,8 @@ async function runUpdatePreflight(currentVersion, options = {}) {
515539
515539
  const stderr = options.stderr ?? process.stderr;
515540
515540
  const logger = options.logger ?? log;
515541
515541
  const platform = process.platform;
515542
- if (isAutoUpdateDisabledByEnv()) return "continue";
515543
515542
  try {
515544
515543
  const isInteractive = options.isTTY ?? (process.stdin.isTTY && process.stdout.isTTY);
515545
- const deviceId = resolveUpdateDeviceId();
515546
- const bypassRollout = isRolloutBypassedByExperimentalEnv();
515547
515544
  const installState = await readUpdateInstallState().catch(() => emptyUpdateInstallState());
515548
515545
  if (isInteractive) {
515549
515546
  const startupNotice = pendingBackgroundInstallNotice(installState, currentVersion, options.track, logger);
@@ -515552,6 +515549,9 @@ async function runUpdatePreflight(currentVersion, options = {}) {
515552
515549
  startupNotice
515553
515550
  };
515554
515551
  }
515552
+ if (isAutoUpdateDisabledByEnv()) return "continue";
515553
+ const deviceId = resolveUpdateDeviceId();
515554
+ const bypassRollout = isRolloutBypassedByExperimentalEnv();
515555
515555
  const cache = await readUpdateCache().catch(() => null);
515556
515556
  const cachedManifest = cache?.manifest ?? null;
515557
515557
  const cachedDecision = decidePassiveUpdateTarget(currentVersion, cache?.latest ?? null, cachedManifest, deviceId, /* @__PURE__ */ new Date(), bypassRollout);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blun-king-cli",
3
- "version": "9.1.41",
3
+ "version": "9.1.42",
4
4
  "description": "BLUN CLI - your own AI agent with a Telegram channel. Get it done. With BLUN.",
5
5
  "license": "MIT",
6
6
  "bin": {