blun-king-cli 9.1.307 → 9.1.308

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.
@@ -68,6 +68,7 @@ const RAW_ARGS = process.argv.slice(2);
68
68
  const PROFILE = parseProfileLaunchArgs(RAW_ARGS, launcherModeFromArgv(process.argv));
69
69
  const ARGS = PROFILE.args;
70
70
  const CORE_LOAD_TIMEOUT_MS = 30_000;
71
+ const RUNNING_UPDATE_RESUME_SESSION_ENV = 'BLUN_RUNNING_UPDATE_RESUME_SESSION_ID';
71
72
  const RUNTIME_READY_TIMEOUT_MS = 60_000;
72
73
  const RUNNING_UPDATE_RECHECK_MS = 5 * 60_000;
73
74
  const RUNNING_UPDATE_RECHECK_JITTER_MS = 2 * 60_000;
@@ -312,6 +313,7 @@ async function superviseProtectedCore(args, env, cwd, releaseNotice, options = {
312
313
  let pendingHandoff;
313
314
  let updateStarted = false;
314
315
  let runtimeReady = false;
316
+ let activeSession;
315
317
  let runtimeExitIntent = false;
316
318
  let supervisionCompleted = false;
317
319
  let runningUpdatePollTimer;
@@ -329,6 +331,23 @@ async function superviseProtectedCore(args, env, cwd, releaseNotice, options = {
329
331
  (options.clearTimeoutImpl || clearTimeout)(runningUpdatePollTimer);
330
332
  runningUpdatePollTimer = undefined;
331
333
  };
334
+ const validSessionMessage = (message) => typeof message?.sessionId === 'string'
335
+ && message.sessionId.length > 0
336
+ && message.sessionId.length <= 256
337
+ && !/[\u0000-\u001f\u007f]/u.test(message.sessionId)
338
+ && resolveHandoffCwd(message.cwd, '') !== '';
339
+ const stagedRuntimeOptions = () => ({
340
+ mode: runningUpdateMode,
341
+ ...(runningUpdateMode === RUNNING_UPDATE_MODES.RESUME && activeSession !== undefined
342
+ ? { cwd: activeSession.cwd, sessionId: activeSession.sessionId }
343
+ : {}),
344
+ });
345
+ const persistPreparedRuntime = () => {
346
+ if (preparedTarget === undefined) return;
347
+ const sharedHome = env.BLUN_SHARED_HOME;
348
+ if (typeof sharedHome !== 'string' || sharedHome.length === 0) return;
349
+ (options.stageRuntime || stageRuntime)(sharedHome, preparedTarget, stagedRuntimeOptions());
350
+ };
332
351
  const scheduleNextPreparation = (child) => {
333
352
  clearRunningUpdatePoll();
334
353
  if (supervisionCompleted || pendingHandoff !== undefined || updateStarted) return;
@@ -367,7 +386,7 @@ async function superviseProtectedCore(args, env, cwd, releaseNotice, options = {
367
386
  return;
368
387
  }
369
388
  preparedTarget = target;
370
- (options.stageRuntime || stageRuntime)(sharedHome, target, { mode: runningUpdateMode });
389
+ persistPreparedRuntime();
371
390
  const runningVersion = readPackageVersionAt(packageRoot);
372
391
  (options.recordRunningUpdateEvent || recordRunningUpdateEvent)(sharedHome, previousTarget === undefined ? {
373
392
  event: 'prepared-for-next-start',
@@ -396,13 +415,20 @@ async function superviseProtectedCore(args, env, cwd, releaseNotice, options = {
396
415
  && preparedTarget !== undefined
397
416
  && message.version === preparedTarget.version
398
417
  && message.mode === runningUpdateMode
399
- && typeof message.sessionId === 'string'
400
- && message.sessionId.length > 0
401
- && message.sessionId.length <= 256
402
- && !/[\u0000-\u001f\u007f]/u.test(message.sessionId)
403
- && resolveHandoffCwd(message.cwd, '') !== '') {
404
- pendingHandoff = Object.freeze({
418
+ && validSessionMessage(message)) {
419
+ activeSession = Object.freeze({
405
420
  cwd: resolveHandoffCwd(message.cwd, cwd),
421
+ sessionId: message.sessionId,
422
+ });
423
+ try {
424
+ persistPreparedRuntime();
425
+ } catch (error) {
426
+ options.onRunningUpdateError?.(error);
427
+ scheduleNextPreparation(child);
428
+ return;
429
+ }
430
+ pendingHandoff = Object.freeze({
431
+ cwd: activeSession.cwd,
406
432
  mode: message.mode,
407
433
  sessionId: message.sessionId,
408
434
  target: preparedTarget,
@@ -423,6 +449,17 @@ async function superviseProtectedCore(args, env, cwd, releaseNotice, options = {
423
449
  }
424
450
  }
425
451
  if (message?.type === RUNTIME_READY_MESSAGE) {
452
+ if (validSessionMessage(message)) {
453
+ activeSession = Object.freeze({
454
+ cwd: resolveHandoffCwd(message.cwd, cwd),
455
+ sessionId: message.sessionId,
456
+ });
457
+ try {
458
+ persistPreparedRuntime();
459
+ } catch (error) {
460
+ options.onRunningUpdateError?.(error);
461
+ }
462
+ }
426
463
  runtimeReady = true;
427
464
  refreshRunningUpdateMode();
428
465
  if (automaticMode()) startPreparation(child);
@@ -482,7 +519,11 @@ async function superviseProtectedCore(args, env, cwd, releaseNotice, options = {
482
519
  const handoffArgs = handoffArgsForMode(args, pendingHandoff.mode, pendingHandoff.sessionId);
483
520
  const handoffCwd = pendingHandoff.cwd;
484
521
  const previousActive = (options.readActiveRuntime || readActiveRuntime)(sharedHome);
485
- const nextCore = spawnCore(handoffArgs, env, handoffCwd, { packageRoot: target.packageRoot });
522
+ const resumeEnv = {
523
+ ...env,
524
+ [RUNNING_UPDATE_RESUME_SESSION_ENV]: pendingHandoff.sessionId,
525
+ };
526
+ const nextCore = spawnCore(handoffArgs, resumeEnv, handoffCwd, { packageRoot: target.packageRoot });
486
527
  const nextLoaded = await nextCore.loaded;
487
528
  const nextReady = nextLoaded && await (options.waitForRuntimeReady || waitForRuntimeReady)(
488
529
  nextCore,
@@ -498,7 +539,7 @@ async function superviseProtectedCore(args, env, cwd, releaseNotice, options = {
498
539
  toVersion: target.version,
499
540
  mode: pendingHandoff.mode,
500
541
  }, { now: options.nowImpl });
501
- return superviseProtectedCore(handoffArgs, env, handoffCwd, async () => {}, {
542
+ return superviseProtectedCore(handoffArgs, resumeEnv, handoffCwd, async () => {}, {
502
543
  ...options,
503
544
  existingCore: nextCore,
504
545
  packageRoot: target.packageRoot,
@@ -519,14 +560,14 @@ async function superviseProtectedCore(args, env, cwd, releaseNotice, options = {
519
560
  fromVersion: readPackageVersionAt(packageRoot),
520
561
  toVersion: target.version,
521
562
  }, { now: options.nowImpl });
522
- const fallback = spawnCore(handoffArgs, env, handoffCwd, { packageRoot });
563
+ const fallback = spawnCore(handoffArgs, resumeEnv, handoffCwd, { packageRoot });
523
564
  const fallbackLoaded = await fallback.loaded;
524
565
  const fallbackReady = fallbackLoaded && await (options.waitForRuntimeReady || waitForRuntimeReady)(
525
566
  fallback,
526
567
  options.readyTimeoutMs,
527
568
  );
528
569
  if (!fallbackReady) return 1;
529
- return superviseProtectedCore(handoffArgs, env, handoffCwd, async () => {}, {
570
+ return superviseProtectedCore(handoffArgs, resumeEnv, handoffCwd, async () => {}, {
530
571
  ...options,
531
572
  existingCore: fallback,
532
573
  packageRoot,
@@ -641,14 +682,20 @@ function spawnManagedLauncher(binary, cwd) {
641
682
  });
642
683
  }
643
684
 
644
- function spawnActiveLauncher(packageRoot, cwd, args = RAW_ARGS) {
685
+ function spawnActiveLauncher(packageRoot, cwd, args = RAW_ARGS, options = {}) {
645
686
  const entryName = path.basename(process.argv[1] || 'king.js').toLowerCase() === 'blun.js'
646
687
  ? 'blun.js'
647
688
  : 'king.js';
648
689
  return new Promise((resolve, reject) => {
649
690
  const child = spawn(process.execPath, [path.join(packageRoot, 'bin', entryName), ...args], {
650
691
  cwd,
651
- env: { ...process.env, BLUN_ACTIVE_RUNTIME_ROOT: packageRoot },
692
+ env: {
693
+ ...process.env,
694
+ BLUN_ACTIVE_RUNTIME_ROOT: packageRoot,
695
+ ...(typeof options.resumeSessionId === 'string' && options.resumeSessionId.length > 0
696
+ ? { [RUNNING_UPDATE_RESUME_SESSION_ENV]: options.resumeSessionId }
697
+ : {}),
698
+ },
652
699
  stdio: 'inherit',
653
700
  windowsHide: true,
654
701
  });
@@ -873,6 +920,9 @@ async function runLauncher(options = {}) {
873
920
  deferredPendingRuntime.packageRoot,
874
921
  deferredPendingRuntime.cwd || callerCwd,
875
922
  pendingArgs,
923
+ deferredPendingRuntime.mode === RUNNING_UPDATE_MODES.RESUME
924
+ ? { resumeSessionId: deferredPendingRuntime.sessionId }
925
+ : {},
876
926
  );
877
927
  return;
878
928
  }
package/blun.mjs CHANGED
@@ -515728,20 +515728,28 @@ const {
515728
515728
  readRunningUpdateMode,
515729
515729
  writeRunningUpdateMode
515730
515730
  } = __require("./bin/running-update-preference.cjs");
515731
- function notifyRunningRuntimeReady(tui) {
515732
- if (typeof process.env["BLUN_SHARED_HOME"] === "string" && process.env["BLUN_SHARED_HOME"].length > 0) void pruneRunningUpdateReleases(process.env["BLUN_SHARED_HOME"], {
515733
- activePackageRoot: __dirname
515734
- }).catch(() => {});
515731
+ const RUNNING_UPDATE_RESUME_SESSION_ENV = "BLUN_RUNNING_UPDATE_RESUME_SESSION_ID";
515732
+ function shouldContinueActiveGoalAfterRunningUpdate(expectedSessionId, currentSessionId, goalStatus) {
515733
+ return typeof expectedSessionId === "string" && expectedSessionId.length > 0 && currentSessionId === expectedSessionId && goalStatus === "active";
515734
+ }
515735
+ function sendRunningRuntimeSession(tui) {
515735
515736
  if (!process.connected) return;
515736
515737
  const sessionId = tui.getCurrentSessionId();
515737
515738
  if (sessionId.length === 0) return;
515738
515739
  try {
515739
515740
  process.send({
515740
515741
  type: RUNTIME_READY_MESSAGE,
515741
- sessionId
515742
+ sessionId,
515743
+ cwd: tui.state.appState.workDir
515742
515744
  });
515743
515745
  } catch {}
515744
515746
  }
515747
+ function notifyRunningRuntimeReady(tui) {
515748
+ if (typeof process.env["BLUN_SHARED_HOME"] === "string" && process.env["BLUN_SHARED_HOME"].length > 0) void pruneRunningUpdateReleases(process.env["BLUN_SHARED_HOME"], {
515749
+ activePackageRoot: __dirname
515750
+ }).catch(() => {});
515751
+ sendRunningRuntimeSession(tui);
515752
+ }
515745
515753
  function requestRunningUpdateAtSafeBoundary(tui) {
515746
515754
  if (tui.runningUpdateHandoffStarted || tui.isShuttingDown || !process.connected) return false;
515747
515755
  const version = tui.runningUpdatePreparedVersion;
@@ -516268,7 +516276,8 @@ var BlunTUI = class {
516268
516276
  if (this.session !== void 0) {
516269
516277
  this.sessionEventHandler.startSubscription();
516270
516278
  if (shouldReplayHistory) {
516271
- await this.promptStartupResumeGoalIfNeeded();
516279
+ const continuedAfterUpdate = this.continueActiveGoalAfterRunningUpdateIfNeeded();
516280
+ if (!continuedAfterUpdate) await this.promptStartupResumeGoalIfNeeded();
516272
516281
  if (this.aborted) return;
516273
516282
  }
516274
516283
  this.showSessionWarnings(this.session);
@@ -516418,6 +516427,13 @@ var BlunTUI = class {
516418
516427
  }
516419
516428
  if (choice === "resume") await handleGoalCommand(this, "resume");
516420
516429
  }
516430
+ continueActiveGoalAfterRunningUpdateIfNeeded() {
516431
+ const expectedSessionId = process.env[RUNNING_UPDATE_RESUME_SESSION_ENV];
516432
+ delete process.env[RUNNING_UPDATE_RESUME_SESSION_ENV];
516433
+ if (!shouldContinueActiveGoalAfterRunningUpdate(expectedSessionId, this.session?.id, this.state.appState.goal?.status)) return false;
516434
+ this.sendNormalUserInput(RESUME_GOAL_INPUT);
516435
+ return true;
516436
+ }
516421
516437
  async stop(exitCode) {
516422
516438
  if (this.isShuttingDown) return;
516423
516439
  this.isShuttingDown = true;
@@ -517913,6 +517929,7 @@ var BlunTUI = class {
517913
517929
  if (resumeState?.warning !== void 0) this.showStatus(uiText("blunTui.warning", { warning: resumeState.warning }), "warning");
517914
517930
  this.showStatus(statusMessage);
517915
517931
  this.showSessionWarnings(session);
517932
+ sendRunningRuntimeSession(this);
517916
517933
  }
517917
517934
  async reloadCurrentSessionView(session, statusMessage) {
517918
517935
  await this.personalMemoryController.clear(session);
@@ -517976,6 +517993,7 @@ var BlunTUI = class {
517976
517993
  this.showStatus(uiText("blunTui.session.started", { sessionId: session.id }));
517977
517994
  this.showSessionWarnings(session);
517978
517995
  this.showConfigWarningsIfAny();
517996
+ sendRunningRuntimeSession(this);
517979
517997
  }
517980
517998
  /** Surface config.toml load warnings (degraded or kept-previous config) in the status bar. */
517981
517999
  async showConfigWarningsIfAny() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blun-king-cli",
3
- "version": "9.1.307",
3
+ "version": "9.1.308",
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": {