blun-king-cli 9.1.221 → 9.1.222

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.
@@ -29,16 +29,11 @@ const { repairConfiguredNativeModules } = require('./native-module-repair');
29
29
  const { acquireSharedRuntimeLease, tryAcquireUpdateLease } = require('./update-lease');
30
30
  const { compareSemver, runExplicitUpdate, runUpdateNotice } = require('./update-notice');
31
31
  const {
32
- RUNNING_UPDATE_HANDOFF_EXIT_CODE,
33
- RUNNING_UPDATE_HANDOFF_ACK_MESSAGE,
34
- RUNNING_UPDATE_HANDOFF_MESSAGE,
35
32
  RUNNING_UPDATE_MODE_MESSAGE,
36
- RUNNING_UPDATE_PREPARED_MESSAGE,
37
33
  RUNTIME_EXIT_INTENT_MESSAGE,
38
34
  activateRuntime,
39
35
  clearActiveRuntime,
40
36
  handoffArgsForMode,
41
- handoffRuntime,
42
37
  prepareRunningUpdate,
43
38
  pruneRunningUpdateReleases,
44
39
  recordRunningUpdateEvent,
@@ -283,9 +278,6 @@ function shouldRecoverActivatedRuntime(result, recovery, options = {}) {
283
278
  async function superviseProtectedCore(args, env, cwd, releaseNotice, options = {}) {
284
279
  const packageRoot = path.resolve(options.packageRoot || PKG);
285
280
  let preparedTarget;
286
- let handoffSessionId;
287
- let handoffMode;
288
- let handoffCwd = cwd;
289
281
  let updateStarted = false;
290
282
  let runtimeReady = false;
291
283
  let runtimeExitIntent = false;
@@ -297,9 +289,6 @@ async function superviseProtectedCore(args, env, cwd, releaseNotice, options = {
297
289
  const persistedMode = readRunningUpdateMode(env.BLUN_HOME);
298
290
  if (persistedMode !== runningUpdateMode) {
299
291
  runningUpdateMode = persistedMode;
300
- handoffSessionId = undefined;
301
- handoffMode = undefined;
302
- handoffCwd = cwd;
303
292
  }
304
293
  };
305
294
  const clearRunningUpdatePoll = () => {
@@ -317,20 +306,6 @@ async function superviseProtectedCore(args, env, cwd, releaseNotice, options = {
317
306
  else scheduleNextPreparation(child);
318
307
  });
319
308
  };
320
- const announcePrepared = (child) => {
321
- if (preparedTarget === undefined || !automaticMode() || child.connected !== true) return;
322
- try {
323
- child.send({
324
- type: RUNNING_UPDATE_PREPARED_MESSAGE,
325
- version: preparedTarget.version,
326
- mode: runningUpdateMode,
327
- }, (error) => {
328
- if (error) options.onRunningUpdateError?.(error);
329
- });
330
- } catch (error) {
331
- options.onRunningUpdateError?.(error);
332
- }
333
- };
334
309
  const startPreparation = (child) => {
335
310
  if (updateStarted || options.runningUpdate === false || !automaticMode()) return;
336
311
  updateStarted = true;
@@ -361,7 +336,6 @@ async function superviseProtectedCore(args, env, cwd, releaseNotice, options = {
361
336
  activePackageRoot: packageRoot,
362
337
  })).catch((error) => options.onRunningUpdateError?.(error));
363
338
  clearRunningUpdatePoll();
364
- announcePrepared(child);
365
339
  }).catch((error) => {
366
340
  updateStarted = false;
367
341
  options.onRunningUpdateError?.(error);
@@ -378,48 +352,14 @@ async function superviseProtectedCore(args, env, cwd, releaseNotice, options = {
378
352
  }
379
353
  if (message?.type === RUNNING_UPDATE_MODE_MESSAGE && typeof message.mode === 'string') {
380
354
  runningUpdateMode = normalizeRunningUpdateMode(message.mode);
381
- handoffSessionId = undefined;
382
- handoffMode = undefined;
383
- handoffCwd = cwd;
384
355
  clearRunningUpdatePoll();
385
356
  if (automaticMode()) {
386
- if (preparedTarget !== undefined) announcePrepared(child);
387
- else if (runtimeReady) {
357
+ if (preparedTarget === undefined && runtimeReady) {
388
358
  updateStarted = false;
389
359
  startPreparation(child);
390
360
  }
391
361
  } else if (runtimeReady) scheduleNextPreparation(child);
392
362
  }
393
- if (message?.type === RUNNING_UPDATE_HANDOFF_MESSAGE
394
- && typeof message.sessionId === 'string'
395
- && message.sessionId.length > 0
396
- && message.mode === runningUpdateMode
397
- && automaticMode()) {
398
- handoffSessionId = message.sessionId;
399
- handoffMode = runningUpdateMode;
400
- handoffCwd = resolveHandoffCwd(message.cwd, cwd);
401
- if (preparedTarget !== undefined && message.version === preparedTarget.version) {
402
- try {
403
- (options.stageRuntime || stageRuntime)(env.BLUN_SHARED_HOME, preparedTarget, {
404
- mode: handoffMode,
405
- sessionId: handoffSessionId,
406
- cwd: handoffCwd,
407
- });
408
- child.send({
409
- type: RUNNING_UPDATE_HANDOFF_ACK_MESSAGE,
410
- version: preparedTarget.version,
411
- mode: handoffMode,
412
- sessionId: handoffSessionId,
413
- }, (error) => {
414
- if (error) options.onRunningUpdateError?.(error);
415
- });
416
- } catch (error) {
417
- handoffSessionId = undefined;
418
- handoffMode = undefined;
419
- options.onRunningUpdateError?.(error);
420
- }
421
- }
422
- }
423
363
  };
424
364
  const spawnCore = options.spawnProtectedCore || spawnProtectedCore;
425
365
  const core = options.existingCore || spawnCore(args, env, cwd, {
@@ -460,67 +400,6 @@ async function superviseProtectedCore(args, env, cwd, releaseNotice, options = {
460
400
  const result = await core.completed;
461
401
  clearRunningUpdatePoll();
462
402
  if (existingMessageHandler) core.child.off('message', existingMessageHandler);
463
- if (result.code === RUNNING_UPDATE_HANDOFF_EXIT_CODE
464
- && preparedTarget !== undefined
465
- && handoffSessionId !== undefined
466
- && handoffMode !== undefined) {
467
- const previousActiveRuntime = (options.readActiveRuntime || readActiveRuntime)(env.BLUN_SHARED_HOME);
468
- const activatedAt = (options.nowImpl || Date.now)();
469
- const handoff = await handoffRuntime({
470
- target: preparedTarget,
471
- previous: { packageRoot, version: readPackageVersionAt(packageRoot) },
472
- sessionId: handoffSessionId,
473
- mode: handoffMode,
474
- args,
475
- probeTarget: options.probeRunningUpdate || (() => true),
476
- stopOld: async () => {},
477
- startCore: async ({ packageRoot: nextRoot, args: nextArgs }) => {
478
- const nextCore = spawnCore(nextArgs, env, handoffCwd, { packageRoot: nextRoot });
479
- const nextLoaded = await nextCore.loaded;
480
- const ready = nextLoaded && await waitForRuntimeReady(nextCore, options.readyTimeoutMs);
481
- if (!ready) {
482
- try { nextCore.child.kill(); } catch {}
483
- await nextCore.completed;
484
- }
485
- return { ...nextCore, ready };
486
- },
487
- activateTarget: async (target) => {
488
- await (options.activateRuntime || activateRuntime)(env.BLUN_SHARED_HOME, target);
489
- (options.clearPendingRuntime || clearPendingRuntime)(env.BLUN_SHARED_HOME, target);
490
- (options.recordRunningUpdateEvent || recordRunningUpdateEvent)(env.BLUN_SHARED_HOME, {
491
- event: 'activated',
492
- fromVersion: readPackageVersionAt(packageRoot),
493
- toVersion: target.version,
494
- }, { now: options.nowImpl });
495
- try {
496
- await (options.pruneRunningUpdateReleases || pruneRunningUpdateReleases)(env.BLUN_SHARED_HOME, {
497
- activePackageRoot: target.packageRoot,
498
- });
499
- } catch (error) {
500
- options.onRunningUpdateError?.(error);
501
- }
502
- },
503
- });
504
- if (handoff.kind !== 'activated') {
505
- (options.clearPendingRuntime || clearPendingRuntime)(env.BLUN_SHARED_HOME, preparedTarget);
506
- }
507
- const resumed = handoff.core;
508
- if (resumed === undefined || resumed.ready !== true) return 1;
509
- const resumedArgs = handoffArgsForMode(args, handoffMode, handoffSessionId);
510
- return superviseProtectedCore(resumedArgs, env, handoffCwd, async () => {}, {
511
- ...options,
512
- existingCore: resumed,
513
- packageRoot: handoff.runtime.packageRoot,
514
- startupPendingRuntime: undefined,
515
- staleActiveRuntime: undefined,
516
- recoveryRuntime: handoff.kind === 'activated' ? {
517
- activatedAt,
518
- activeRuntime: previousActiveRuntime,
519
- packageRoot,
520
- version: readPackageVersionAt(packageRoot),
521
- } : undefined,
522
- });
523
- }
524
403
  const recovery = options.recoveryRuntime;
525
404
  if (shouldRecoverActivatedRuntime(result, recovery, {
526
405
  now: (options.nowImpl || Date.now)(),
@@ -651,6 +530,7 @@ function spawnActiveLauncher(packageRoot, cwd, args = RAW_ARGS) {
651
530
  async function runLauncher(options = {}) {
652
531
  const callerCwd = process.cwd();
653
532
  let startupPendingRuntime;
533
+ let deferredPendingRuntime;
654
534
  let staleActiveRuntime;
655
535
  if (options.skipActiveRuntime !== true) {
656
536
  const activeHome = resolveLauncherPrivatePaths().sharedHome;
@@ -660,20 +540,12 @@ async function runLauncher(options = {}) {
660
540
  if (pendingRuntime !== null
661
541
  && path.resolve(pendingRuntime.packageRoot) !== PKG
662
542
  && compareSemver(currentVersion, pendingRuntime.version) === -1) {
663
- const pendingArgs = pendingRuntime.mode !== undefined && pendingRuntime.sessionId !== undefined
664
- ? handoffArgsForMode(RAW_ARGS, pendingRuntime.mode, pendingRuntime.sessionId)
665
- : RAW_ARGS;
666
- process.exitCode = await spawnActiveLauncher(
667
- pendingRuntime.packageRoot,
668
- pendingRuntime.cwd || callerCwd,
669
- pendingArgs,
670
- );
671
- return;
543
+ deferredPendingRuntime = pendingRuntime;
672
544
  }
673
545
  if (pendingRuntime !== null && path.resolve(pendingRuntime.packageRoot) === PKG) {
674
546
  startupPendingRuntime = pendingRuntime;
675
547
  }
676
- if (startupPendingRuntime === undefined && activeRuntime !== null
548
+ if (startupPendingRuntime === undefined && deferredPendingRuntime === undefined && activeRuntime !== null
677
549
  && path.resolve(activeRuntime.packageRoot) !== PKG
678
550
  && compareSemver(currentVersion, activeRuntime.version) === -1) {
679
551
  process.exitCode = await spawnActiveLauncher(activeRuntime.packageRoot, callerCwd);
@@ -837,8 +709,24 @@ async function runLauncher(options = {}) {
837
709
  stderr: process.stderr,
838
710
  blunDir: privatePaths.sharedHome,
839
711
  packageRoot: PKG,
712
+ preparedRuntime: deferredPendingRuntime,
840
713
  noticeLease,
841
714
  });
715
+ if (updateResult.kind === 'installed'
716
+ && updateResult.source === 'prepared_runtime'
717
+ && deferredPendingRuntime !== undefined) {
718
+ const pendingArgs = deferredPendingRuntime.mode !== undefined
719
+ && deferredPendingRuntime.sessionId !== undefined
720
+ ? handoffArgsForMode(RAW_ARGS, deferredPendingRuntime.mode, deferredPendingRuntime.sessionId)
721
+ : RAW_ARGS;
722
+ await releaseNotice();
723
+ process.exitCode = await spawnActiveLauncher(
724
+ deferredPendingRuntime.packageRoot,
725
+ deferredPendingRuntime.cwd || callerCwd,
726
+ pendingArgs,
727
+ );
728
+ return;
729
+ }
842
730
  if (updateResult.kind === 'installed' || updateResult.kind === 'update_in_progress') return;
843
731
 
844
732
  if (!runtimeLease) {
@@ -1393,6 +1393,13 @@ async function runUpdateFlow(options, explicitUpdate) {
1393
1393
  ? explicitNoTarget(stdout, reason, currentVersion)
1394
1394
  : { kind: 'continue', reason };
1395
1395
  }
1396
+ const preparedRuntime = options.preparedRuntime;
1397
+ const preparedRuntimeReady = preparedRuntime !== null
1398
+ && typeof preparedRuntime === 'object'
1399
+ && preparedRuntime.version === release.version
1400
+ && typeof preparedRuntime.packageRoot === 'string'
1401
+ && path.isAbsolute(preparedRuntime.packageRoot)
1402
+ && verifyInstalledPackageVersion(preparedRuntime.packageRoot, release.version);
1396
1403
  if (!explicitUpdate
1397
1404
  && pendingVersion === undefined
1398
1405
  && readSnoozeState(blunDir, release.version, now)) {
@@ -1438,7 +1445,7 @@ async function runUpdateFlow(options, explicitUpdate) {
1438
1445
  ? explicitFailure(stderr, 'lease_unavailable')
1439
1446
  : { kind: 'continue', reason: 'lease_unavailable' };
1440
1447
  }
1441
- if (!options.installVersion) {
1448
+ if (!options.installVersion && !preparedRuntimeReady) {
1442
1449
  installerSession = await (options.prepareInstaller || preparePinnedInstaller)(
1443
1450
  release.version,
1444
1451
  { blunDir, packageRoot },
@@ -1502,9 +1509,11 @@ async function runUpdateFlow(options, explicitUpdate) {
1502
1509
  let installResult;
1503
1510
  updateProgress(3, 'Paket wird installiert');
1504
1511
  try {
1505
- installResult = options.installVersion
1506
- ? await options.installVersion(release.version)
1507
- : await installerSession.commit();
1512
+ installResult = preparedRuntimeReady
1513
+ ? { code: 0, verified: true, preparedRuntime: true }
1514
+ : options.installVersion
1515
+ ? await options.installVersion(release.version)
1516
+ : await installerSession.commit();
1508
1517
  } catch {
1509
1518
  installResult = { code: undefined };
1510
1519
  }
@@ -1536,7 +1545,11 @@ async function runUpdateFlow(options, explicitUpdate) {
1536
1545
  `Update ${currentVersion} -> ${release.version} erfolgreich installiert. Starte BLUN Code neu, um die neue Version zu verwenden.\n`,
1537
1546
  );
1538
1547
  if (release.notesUrl) stdout.write(`Versionshinweise: ${release.notesUrl}\n`);
1539
- return { kind: 'installed', version: release.version };
1548
+ return {
1549
+ kind: 'installed',
1550
+ version: release.version,
1551
+ ...(installResult.preparedRuntime === true ? { source: 'prepared_runtime' } : {}),
1552
+ };
1540
1553
  }
1541
1554
 
1542
1555
  if (Number.isInteger(installResult?.code) && installResult.code !== 0) {
package/blun.mjs CHANGED
@@ -515119,8 +515119,6 @@ function turnsToTrim(turns, maxTurns, hysteresis) {
515119
515119
  const {
515120
515120
  AUTO_UPDATE_SETTLE_MS,
515121
515121
  RUNNING_UPDATE_HANDOFF_EXIT_CODE,
515122
- RUNNING_UPDATE_HANDOFF_ACK_MESSAGE,
515123
- RUNNING_UPDATE_HANDOFF_MESSAGE,
515124
515122
  RUNNING_UPDATE_MODE_MESSAGE,
515125
515123
  RUNNING_UPDATE_PREPARED_MESSAGE,
515126
515124
  RUNTIME_EXIT_INTENT_MESSAGE,
@@ -515148,64 +515146,14 @@ function notifyRunningRuntimeReady(tui) {
515148
515146
  } catch {}
515149
515147
  }
515150
515148
  function requestRunningUpdateAtSafeBoundary(tui) {
515151
- if (tui.runningUpdatePreparedVersion === void 0 || tui.runningUpdatePreparedMode === void 0 || tui.runningUpdateHandoffStarted || !process.connected) return false;
515152
- const boundaryState = () => ({
515153
- isShuttingDown: tui.isShuttingDown,
515154
- streamingPhase: tui.state.appState.streamingPhase,
515155
- isCompacting: tui.state.appState.isCompacting,
515156
- queuedMessages: tui.state.queuedMessages.length,
515157
- activeToolCalls: tui.streamingUI.hasActiveToolCalls() ? 1 : 0,
515158
- shellCommands: tui.shellOutputStreams.size,
515159
- queueCommandRunning: tui.queueCommandRunning
515160
- });
515161
- if (!isSafeRuntimeBoundary(boundaryState())) return false;
515162
- const sessionId = tui.getCurrentSessionId();
515163
- if (sessionId.length === 0) return false;
515164
- tui.runningUpdateHandoffStarted = true;
515165
- try {
515166
- process.send({
515167
- type: RUNNING_UPDATE_HANDOFF_MESSAGE,
515168
- sessionId,
515169
- version: tui.runningUpdatePreparedVersion,
515170
- mode: tui.runningUpdatePreparedMode,
515171
- cwd: tui.state.appState.workDir
515172
- }, (error) => {
515173
- if (error || !isSafeRuntimeBoundary(boundaryState())) {
515174
- tui.runningUpdateHandoffStarted = false;
515175
- }
515176
- });
515177
- } catch {
515178
- tui.runningUpdateHandoffStarted = false;
515179
- return false;
515180
- }
515181
- return true;
515149
+ return false;
515182
515150
  }
515183
515151
  function installRunningUpdateListener(tui) {
515184
515152
  const handler = (message) => {
515185
- if (message?.type === RUNNING_UPDATE_HANDOFF_ACK_MESSAGE) {
515186
- if (!tui.runningUpdateHandoffStarted || message.version !== tui.runningUpdatePreparedVersion || message.mode !== tui.runningUpdatePreparedMode || message.sessionId !== tui.getCurrentSessionId()) return;
515187
- if (!isSafeRuntimeBoundary({
515188
- isShuttingDown: tui.isShuttingDown,
515189
- streamingPhase: tui.state.appState.streamingPhase,
515190
- isCompacting: tui.state.appState.isCompacting,
515191
- queuedMessages: tui.state.queuedMessages.length,
515192
- activeToolCalls: tui.streamingUI.hasActiveToolCalls() ? 1 : 0,
515193
- shellCommands: tui.shellOutputStreams.size,
515194
- queueCommandRunning: tui.queueCommandRunning
515195
- })) {
515196
- tui.runningUpdateHandoffStarted = false;
515197
- return;
515198
- }
515199
- tui.showStatus("Ein Update wird geladen und die TUI wird neu gestartet.", "success");
515200
- void tui.stop(RUNNING_UPDATE_HANDOFF_EXIT_CODE).catch(() => {
515201
- tui.runningUpdateHandoffStarted = false;
515202
- });
515203
- return;
515204
- }
515205
515153
  if (message?.type !== RUNNING_UPDATE_PREPARED_MESSAGE || typeof message.version !== "string" || message.mode !== RUNNING_UPDATE_MODES.RESUME && message.mode !== RUNNING_UPDATE_MODES.NEW) return;
515206
515154
  tui.runningUpdatePreparedVersion = message.version;
515207
515155
  tui.runningUpdatePreparedMode = message.mode;
515208
- requestRunningUpdateAtSafeBoundary(tui);
515156
+ tui.showStatus(`Update ${message.version} ist bereit und wird beim naechsten Start aktiviert.`, "success");
515209
515157
  };
515210
515158
  process.on("message", handler);
515211
515159
  return () => process.off("message", handler);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blun-king-cli",
3
- "version": "9.1.221",
3
+ "version": "9.1.222",
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": {