blun-king-cli 9.1.207 → 9.1.209
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/launcher-runtime.js +82 -7
- package/bin/running-update.cjs +122 -3
- package/blun.mjs +23 -1
- package/package.json +1 -1
package/bin/launcher-runtime.js
CHANGED
|
@@ -33,11 +33,15 @@ const {
|
|
|
33
33
|
RUNNING_UPDATE_HANDOFF_MESSAGE,
|
|
34
34
|
RUNNING_UPDATE_MODE_MESSAGE,
|
|
35
35
|
RUNNING_UPDATE_PREPARED_MESSAGE,
|
|
36
|
+
RUNTIME_EXIT_INTENT_MESSAGE,
|
|
36
37
|
activateRuntime,
|
|
37
38
|
handoffArgsForMode,
|
|
38
39
|
handoffRuntime,
|
|
39
40
|
prepareRunningUpdate,
|
|
41
|
+
pruneRunningUpdateReleases,
|
|
42
|
+
recordRunningUpdateEvent,
|
|
40
43
|
readActiveRuntime,
|
|
44
|
+
restoreActiveRuntime,
|
|
41
45
|
} = require('./running-update.cjs');
|
|
42
46
|
const {
|
|
43
47
|
RUNNING_UPDATE_MODES,
|
|
@@ -64,6 +68,7 @@ const RUNTIME_READY_TIMEOUT_MS = 60_000;
|
|
|
64
68
|
const RUNNING_UPDATE_RECHECK_MS = 60_000;
|
|
65
69
|
const RUNNING_UPDATE_RECHECK_JITTER_MS = 30_000;
|
|
66
70
|
const RUNNING_UPDATE_HANDOFF_NOTICE = 'Ein Update wird geladen. Die TUI wird anschließend neu gestartet.';
|
|
71
|
+
const RUNNING_UPDATE_STABILIZATION_MS = 2 * 60 * 1000;
|
|
67
72
|
|
|
68
73
|
function runningUpdateRecheckDelay(randomValue = Math.random()) {
|
|
69
74
|
const normalized = Number.isFinite(randomValue)
|
|
@@ -267,6 +272,14 @@ function resolveHandoffCwd(candidate, fallback) {
|
|
|
267
272
|
}
|
|
268
273
|
}
|
|
269
274
|
|
|
275
|
+
function shouldRecoverActivatedRuntime(result, recovery, options = {}) {
|
|
276
|
+
if (recovery === undefined || options.runtimeExitIntent === true) return false;
|
|
277
|
+
const signal = result?.signal;
|
|
278
|
+
if (signal === 'SIGINT' || signal === 'SIGTERM' || signal === 'SIGHUP') return false;
|
|
279
|
+
const now = options.now ?? Date.now();
|
|
280
|
+
return now - recovery.activatedAt <= RUNNING_UPDATE_STABILIZATION_MS;
|
|
281
|
+
}
|
|
282
|
+
|
|
270
283
|
async function superviseProtectedCore(args, env, cwd, releaseNotice, options = {}) {
|
|
271
284
|
const packageRoot = path.resolve(options.packageRoot || PKG);
|
|
272
285
|
let preparedTarget;
|
|
@@ -275,6 +288,7 @@ async function superviseProtectedCore(args, env, cwd, releaseNotice, options = {
|
|
|
275
288
|
let handoffCwd = cwd;
|
|
276
289
|
let updateStarted = false;
|
|
277
290
|
let runtimeReady = false;
|
|
291
|
+
let runtimeExitIntent = false;
|
|
278
292
|
let runningUpdatePollTimer;
|
|
279
293
|
let runningUpdateMode = readRunningUpdateMode(env.BLUN_HOME);
|
|
280
294
|
const automaticMode = () => runningUpdateMode === RUNNING_UPDATE_MODES.RESUME
|
|
@@ -305,11 +319,17 @@ async function superviseProtectedCore(args, env, cwd, releaseNotice, options = {
|
|
|
305
319
|
};
|
|
306
320
|
const announcePrepared = (child) => {
|
|
307
321
|
if (preparedTarget === undefined || !automaticMode() || child.connected !== true) return;
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
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
|
+
}
|
|
313
333
|
};
|
|
314
334
|
const startPreparation = (child) => {
|
|
315
335
|
if (updateStarted || options.runningUpdate === false || !automaticMode()) return;
|
|
@@ -340,6 +360,7 @@ async function superviseProtectedCore(args, env, cwd, releaseNotice, options = {
|
|
|
340
360
|
});
|
|
341
361
|
};
|
|
342
362
|
const handleCoreMessage = (message, child) => {
|
|
363
|
+
if (message?.type === RUNTIME_EXIT_INTENT_MESSAGE) runtimeExitIntent = true;
|
|
343
364
|
if (message?.type === RUNTIME_READY_MESSAGE) {
|
|
344
365
|
runtimeReady = true;
|
|
345
366
|
refreshRunningUpdateMode();
|
|
@@ -394,12 +415,13 @@ async function superviseProtectedCore(args, env, cwd, releaseNotice, options = {
|
|
|
394
415
|
const result = await core.completed;
|
|
395
416
|
clearRunningUpdatePoll();
|
|
396
417
|
if (existingMessageHandler) core.child.off('message', existingMessageHandler);
|
|
397
|
-
if (result.error) throw result.error;
|
|
398
418
|
if (result.code === RUNNING_UPDATE_HANDOFF_EXIT_CODE
|
|
399
419
|
&& preparedTarget !== undefined
|
|
400
420
|
&& handoffSessionId !== undefined
|
|
401
421
|
&& handoffMode !== undefined) {
|
|
402
422
|
writeRunningUpdateHandoffNotice(options.runningUpdateNoticeOutput || process.stdout);
|
|
423
|
+
const previousActiveRuntime = (options.readActiveRuntime || readActiveRuntime)(env.BLUN_SHARED_HOME);
|
|
424
|
+
const activatedAt = (options.nowImpl || Date.now)();
|
|
403
425
|
const handoff = await handoffRuntime({
|
|
404
426
|
target: preparedTarget,
|
|
405
427
|
previous: { packageRoot, version: readPackageVersionAt(packageRoot) },
|
|
@@ -418,7 +440,21 @@ async function superviseProtectedCore(args, env, cwd, releaseNotice, options = {
|
|
|
418
440
|
}
|
|
419
441
|
return { ...nextCore, ready };
|
|
420
442
|
},
|
|
421
|
-
activateTarget: (target) =>
|
|
443
|
+
activateTarget: async (target) => {
|
|
444
|
+
await (options.activateRuntime || activateRuntime)(env.BLUN_SHARED_HOME, target);
|
|
445
|
+
(options.recordRunningUpdateEvent || recordRunningUpdateEvent)(env.BLUN_SHARED_HOME, {
|
|
446
|
+
event: 'activated',
|
|
447
|
+
fromVersion: readPackageVersionAt(packageRoot),
|
|
448
|
+
toVersion: target.version,
|
|
449
|
+
}, { now: options.nowImpl });
|
|
450
|
+
try {
|
|
451
|
+
await (options.pruneRunningUpdateReleases || pruneRunningUpdateReleases)(env.BLUN_SHARED_HOME, {
|
|
452
|
+
activePackageRoot: target.packageRoot,
|
|
453
|
+
});
|
|
454
|
+
} catch (error) {
|
|
455
|
+
options.onRunningUpdateError?.(error);
|
|
456
|
+
}
|
|
457
|
+
},
|
|
422
458
|
});
|
|
423
459
|
const resumed = handoff.core;
|
|
424
460
|
if (resumed === undefined || resumed.ready !== true) return 1;
|
|
@@ -427,8 +463,45 @@ async function superviseProtectedCore(args, env, cwd, releaseNotice, options = {
|
|
|
427
463
|
...options,
|
|
428
464
|
existingCore: resumed,
|
|
429
465
|
packageRoot: handoff.runtime.packageRoot,
|
|
466
|
+
recoveryRuntime: handoff.kind === 'activated' ? {
|
|
467
|
+
activatedAt,
|
|
468
|
+
activeRuntime: previousActiveRuntime,
|
|
469
|
+
packageRoot,
|
|
470
|
+
version: readPackageVersionAt(packageRoot),
|
|
471
|
+
} : undefined,
|
|
430
472
|
});
|
|
431
473
|
}
|
|
474
|
+
const recovery = options.recoveryRuntime;
|
|
475
|
+
if (shouldRecoverActivatedRuntime(result, recovery, {
|
|
476
|
+
now: (options.nowImpl || Date.now)(),
|
|
477
|
+
runtimeExitIntent,
|
|
478
|
+
})) {
|
|
479
|
+
(options.recordRunningUpdateEvent || recordRunningUpdateEvent)(env.BLUN_SHARED_HOME, {
|
|
480
|
+
event: 'post-activation-exit',
|
|
481
|
+
activeVersion: readPackageVersionAt(packageRoot),
|
|
482
|
+
code: Number.isInteger(result.code) ? result.code : null,
|
|
483
|
+
error: result.error?.message || null,
|
|
484
|
+
signal: result.signal || null,
|
|
485
|
+
recoveryVersion: recovery.version,
|
|
486
|
+
}, { now: options.nowImpl });
|
|
487
|
+
await (options.restoreActiveRuntime || restoreActiveRuntime)(env.BLUN_SHARED_HOME, recovery.activeRuntime);
|
|
488
|
+
const fallback = spawnCore(args, env, cwd, { packageRoot: recovery.packageRoot });
|
|
489
|
+
const fallbackLoaded = await fallback.loaded;
|
|
490
|
+
const fallbackReady = fallbackLoaded && await waitForRuntimeReady(fallback, options.readyTimeoutMs);
|
|
491
|
+
(options.recordRunningUpdateEvent || recordRunningUpdateEvent)(env.BLUN_SHARED_HOME, {
|
|
492
|
+
event: fallbackReady ? 'recovery-ready' : 'recovery-failed',
|
|
493
|
+
version: recovery.version,
|
|
494
|
+
}, { now: options.nowImpl });
|
|
495
|
+
if (fallbackReady) {
|
|
496
|
+
return superviseProtectedCore(args, env, cwd, async () => {}, {
|
|
497
|
+
...options,
|
|
498
|
+
existingCore: fallback,
|
|
499
|
+
packageRoot: recovery.packageRoot,
|
|
500
|
+
recoveryRuntime: undefined,
|
|
501
|
+
});
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
if (result.error) throw result.error;
|
|
432
505
|
return exitCodeForChild(result, loaded);
|
|
433
506
|
}
|
|
434
507
|
|
|
@@ -758,12 +831,14 @@ async function runLauncher(options = {}) {
|
|
|
758
831
|
module.exports = {
|
|
759
832
|
RUNNING_UPDATE_RECHECK_JITTER_MS,
|
|
760
833
|
RUNNING_UPDATE_RECHECK_MS,
|
|
834
|
+
RUNNING_UPDATE_STABILIZATION_MS,
|
|
761
835
|
createManagedNodeEnvironment,
|
|
762
836
|
resolveLauncherPrivatePaths,
|
|
763
837
|
resolveHandoffCwd,
|
|
764
838
|
runningUpdateRecheckDelay,
|
|
765
839
|
runLauncher,
|
|
766
840
|
scheduleRunningUpdateRecheck,
|
|
841
|
+
shouldRecoverActivatedRuntime,
|
|
767
842
|
shouldDetachProtectedCore,
|
|
768
843
|
spawnManagedLauncher,
|
|
769
844
|
superviseProtectedCore,
|
package/bin/running-update.cjs
CHANGED
|
@@ -7,6 +7,7 @@ const path = require('node:path');
|
|
|
7
7
|
const { spawn } = require('node:child_process');
|
|
8
8
|
|
|
9
9
|
const { compareSemver, requestTrustedJson } = require('./update-notice');
|
|
10
|
+
const { tryAcquireUpdateLease } = require('./update-lease');
|
|
10
11
|
const { ensurePrivateDirectory, securePrivateFile, writePrivateFile } = require('./private-paths');
|
|
11
12
|
|
|
12
13
|
const PACKAGE_NAME = 'blun-king-cli';
|
|
@@ -18,7 +19,10 @@ const RUNNING_UPDATE_PREPARED_MESSAGE = 'blun-running-update-prepared';
|
|
|
18
19
|
const RUNNING_UPDATE_HANDOFF_MESSAGE = 'blun-running-update-handoff';
|
|
19
20
|
const RUNNING_UPDATE_MODE_MESSAGE = 'blun-running-update-mode';
|
|
20
21
|
const RUNTIME_READY_MESSAGE = 'blun-runtime-session-ready';
|
|
22
|
+
const RUNTIME_EXIT_INTENT_MESSAGE = 'blun-runtime-exit-intent';
|
|
21
23
|
const MAX_TARBALL_BYTES = 128 * 1024 * 1024;
|
|
24
|
+
const AUTO_UPDATE_SETTLE_MS = 30 * 60 * 1000;
|
|
25
|
+
const DEFAULT_RETAINED_RELEASE_VERSIONS = 3;
|
|
22
26
|
|
|
23
27
|
function ownData(value, key) {
|
|
24
28
|
if (typeof value !== 'object' || value === null || Array.isArray(value)) return undefined;
|
|
@@ -37,22 +41,110 @@ function validIntegrity(value) {
|
|
|
37
41
|
}
|
|
38
42
|
}
|
|
39
43
|
|
|
40
|
-
function selectRunningUpdateTarget(currentVersion, manifest) {
|
|
44
|
+
function selectRunningUpdateTarget(currentVersion, manifest, options = {}) {
|
|
41
45
|
const name = ownData(manifest, 'name');
|
|
42
46
|
const version = ownData(manifest, 'latest');
|
|
43
47
|
const integrity = ownData(manifest, 'integrity');
|
|
44
48
|
const releasedAt = ownData(manifest, 'releasedAt');
|
|
49
|
+
const releasedAtMs = Date.parse(releasedAt);
|
|
50
|
+
const now = options.now || Date.now;
|
|
45
51
|
if (name !== PACKAGE_NAME
|
|
46
52
|
|| typeof version !== 'string'
|
|
47
53
|
|| compareSemver(currentVersion, version) !== -1
|
|
48
54
|
|| !validIntegrity(integrity)
|
|
49
55
|
|| typeof releasedAt !== 'string'
|
|
50
|
-
|| !Number.isFinite(
|
|
56
|
+
|| !Number.isFinite(releasedAtMs)
|
|
57
|
+
|| now() - releasedAtMs < AUTO_UPDATE_SETTLE_MS) {
|
|
51
58
|
return null;
|
|
52
59
|
}
|
|
53
60
|
return Object.freeze({ version, integrity });
|
|
54
61
|
}
|
|
55
62
|
|
|
63
|
+
function releaseVersionEntries(sharedHome) {
|
|
64
|
+
const root = releasesRoot(sharedHome);
|
|
65
|
+
let entries;
|
|
66
|
+
try {
|
|
67
|
+
entries = fs.readdirSync(root, { withFileTypes: true });
|
|
68
|
+
} catch {
|
|
69
|
+
return [];
|
|
70
|
+
}
|
|
71
|
+
const releases = [];
|
|
72
|
+
for (const entry of entries) {
|
|
73
|
+
if (!entry.isDirectory() || entry.isSymbolicLink()) continue;
|
|
74
|
+
const version = entry.name;
|
|
75
|
+
try {
|
|
76
|
+
if (compareSemver('0.0.0', version) !== -1) continue;
|
|
77
|
+
} catch {
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
const versionRoot = path.join(root, version);
|
|
81
|
+
const digestEntries = fs.readdirSync(versionRoot, { withFileTypes: true });
|
|
82
|
+
const packageRoots = [];
|
|
83
|
+
let valid = digestEntries.length > 0;
|
|
84
|
+
for (const digestEntry of digestEntries) {
|
|
85
|
+
if (!digestEntry.isDirectory() || digestEntry.isSymbolicLink()) {
|
|
86
|
+
valid = false;
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
const packageRoot = path.join(versionRoot, digestEntry.name, 'node_modules', PACKAGE_NAME);
|
|
90
|
+
if (!verifyRuntimePackage(packageRoot, version, { allowedRoot: versionRoot })) {
|
|
91
|
+
valid = false;
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
packageRoots.push(path.resolve(packageRoot));
|
|
95
|
+
}
|
|
96
|
+
if (valid && packageRoots.length > 0) releases.push({ packageRoots, version, versionRoot });
|
|
97
|
+
}
|
|
98
|
+
releases.sort((left, right) => compareSemver(right.version, left.version));
|
|
99
|
+
return releases;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
async function pruneRunningUpdateReleases(sharedHome, options = {}) {
|
|
103
|
+
const keepVersions = Number.isInteger(options.keepVersions) && options.keepVersions >= 1
|
|
104
|
+
? options.keepVersions
|
|
105
|
+
: DEFAULT_RETAINED_RELEASE_VERSIONS;
|
|
106
|
+
const activePackageRoot = typeof options.activePackageRoot === 'string'
|
|
107
|
+
? path.resolve(options.activePackageRoot)
|
|
108
|
+
: readActiveRuntime(sharedHome)?.packageRoot;
|
|
109
|
+
const acquire = options.tryAcquireLease
|
|
110
|
+
|| (({ packageRoot }) => tryAcquireUpdateLease({ packageRoot, role: 'install' }));
|
|
111
|
+
const releases = releaseVersionEntries(sharedHome);
|
|
112
|
+
const kept = new Set(releases.slice(0, keepVersions).map((release) => release.version));
|
|
113
|
+
for (const release of releases) {
|
|
114
|
+
if (release.packageRoots.includes(activePackageRoot)) kept.add(release.version);
|
|
115
|
+
}
|
|
116
|
+
const removedVersions = [];
|
|
117
|
+
const busyVersions = [];
|
|
118
|
+
for (const release of releases) {
|
|
119
|
+
if (kept.has(release.version)) continue;
|
|
120
|
+
const leases = [];
|
|
121
|
+
let blocked = false;
|
|
122
|
+
try {
|
|
123
|
+
for (const packageRoot of release.packageRoots) {
|
|
124
|
+
const result = await acquire({ packageRoot });
|
|
125
|
+
if (!result?.acquired || !result.lease) {
|
|
126
|
+
blocked = true;
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
leases.push(result.lease);
|
|
130
|
+
}
|
|
131
|
+
if (blocked) {
|
|
132
|
+
busyVersions.push(release.version);
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
for (const lease of leases) lease.assertOwned();
|
|
136
|
+
fs.rmSync(release.versionRoot, { recursive: true, force: true });
|
|
137
|
+
removedVersions.push(release.version);
|
|
138
|
+
} finally {
|
|
139
|
+
await Promise.allSettled(leases.map((lease) => lease.release()));
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return Object.freeze({
|
|
143
|
+
busyVersions: Object.freeze(busyVersions),
|
|
144
|
+
removedVersions: Object.freeze(removedVersions),
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
|
|
56
148
|
function isSafeRuntimeBoundary(state) {
|
|
57
149
|
return state?.isShuttingDown === false
|
|
58
150
|
&& state.streamingPhase === 'idle'
|
|
@@ -185,6 +277,28 @@ function activateRuntime(sharedHome, target) {
|
|
|
185
277
|
}
|
|
186
278
|
}
|
|
187
279
|
|
|
280
|
+
function restoreActiveRuntime(sharedHome, runtime) {
|
|
281
|
+
if (runtime === null || runtime === undefined) {
|
|
282
|
+
fs.rmSync(activeRuntimePath(sharedHome), { force: true });
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
activateRuntime(sharedHome, runtime);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
function recordRunningUpdateEvent(sharedHome, event, options = {}) {
|
|
289
|
+
if (typeof sharedHome !== 'string' || !path.isAbsolute(sharedHome)) return false;
|
|
290
|
+
const updateRoot = path.join(path.resolve(sharedHome), 'updates');
|
|
291
|
+
ensurePrivateDirectory(path.resolve(sharedHome));
|
|
292
|
+
ensurePrivateDirectory(updateRoot);
|
|
293
|
+
const filePath = path.join(updateRoot, 'handoff.jsonl');
|
|
294
|
+
fs.appendFileSync(filePath, `${JSON.stringify({
|
|
295
|
+
at: new Date((options.now || Date.now)()).toISOString(),
|
|
296
|
+
...event,
|
|
297
|
+
})}\n`, { encoding: 'utf8', mode: 0o600 });
|
|
298
|
+
securePrivateFile(filePath);
|
|
299
|
+
return true;
|
|
300
|
+
}
|
|
301
|
+
|
|
188
302
|
function registryRelease(registry, version) {
|
|
189
303
|
const versions = ownData(registry, 'versions');
|
|
190
304
|
const entry = ownData(versions, version);
|
|
@@ -325,7 +439,7 @@ async function prepareRunningUpdate(options) {
|
|
|
325
439
|
const manifest = await (options.loadManifest
|
|
326
440
|
? options.loadManifest()
|
|
327
441
|
: requestTrustedJson(MANIFEST_URL));
|
|
328
|
-
const target = selectRunningUpdateTarget(options.currentVersion, manifest);
|
|
442
|
+
const target = selectRunningUpdateTarget(options.currentVersion, manifest, { now: options.now });
|
|
329
443
|
if (target === null) return null;
|
|
330
444
|
const registry = await (options.loadRegistry
|
|
331
445
|
? options.loadRegistry()
|
|
@@ -378,10 +492,12 @@ async function prepareRunningUpdate(options) {
|
|
|
378
492
|
|
|
379
493
|
module.exports = {
|
|
380
494
|
ACTIVE_RUNTIME_FILE,
|
|
495
|
+
AUTO_UPDATE_SETTLE_MS,
|
|
381
496
|
RUNNING_UPDATE_HANDOFF_EXIT_CODE,
|
|
382
497
|
RUNNING_UPDATE_HANDOFF_MESSAGE,
|
|
383
498
|
RUNNING_UPDATE_MODE_MESSAGE,
|
|
384
499
|
RUNNING_UPDATE_PREPARED_MESSAGE,
|
|
500
|
+
RUNTIME_EXIT_INTENT_MESSAGE,
|
|
385
501
|
RUNTIME_READY_MESSAGE,
|
|
386
502
|
activateRuntime,
|
|
387
503
|
activeRuntimePath,
|
|
@@ -390,7 +506,10 @@ module.exports = {
|
|
|
390
506
|
handoffRuntime,
|
|
391
507
|
isSafeRuntimeBoundary,
|
|
392
508
|
prepareRunningUpdate,
|
|
509
|
+
pruneRunningUpdateReleases,
|
|
510
|
+
recordRunningUpdateEvent,
|
|
393
511
|
readActiveRuntime,
|
|
512
|
+
restoreActiveRuntime,
|
|
394
513
|
resumeArgsForHandoff,
|
|
395
514
|
selectRunningUpdateTarget,
|
|
396
515
|
verifyRuntimePackage,
|
package/blun.mjs
CHANGED
|
@@ -515036,12 +515036,15 @@ function turnsToTrim(turns, maxTurns, hysteresis) {
|
|
|
515036
515036
|
//#endregion
|
|
515037
515037
|
//#region src/tui/blun-tui.ts
|
|
515038
515038
|
const {
|
|
515039
|
+
AUTO_UPDATE_SETTLE_MS,
|
|
515039
515040
|
RUNNING_UPDATE_HANDOFF_EXIT_CODE,
|
|
515040
515041
|
RUNNING_UPDATE_HANDOFF_MESSAGE,
|
|
515041
515042
|
RUNNING_UPDATE_MODE_MESSAGE,
|
|
515042
515043
|
RUNNING_UPDATE_PREPARED_MESSAGE,
|
|
515044
|
+
RUNTIME_EXIT_INTENT_MESSAGE,
|
|
515043
515045
|
RUNTIME_READY_MESSAGE,
|
|
515044
|
-
isSafeRuntimeBoundary
|
|
515046
|
+
isSafeRuntimeBoundary,
|
|
515047
|
+
pruneRunningUpdateReleases
|
|
515045
515048
|
} = __require("./bin/running-update.cjs");
|
|
515046
515049
|
const {
|
|
515047
515050
|
RUNNING_UPDATE_MODES,
|
|
@@ -515049,6 +515052,9 @@ const {
|
|
|
515049
515052
|
writeRunningUpdateMode
|
|
515050
515053
|
} = __require("./bin/running-update-preference.cjs");
|
|
515051
515054
|
function notifyRunningRuntimeReady(tui) {
|
|
515055
|
+
if (typeof process.env["BLUN_SHARED_HOME"] === "string" && process.env["BLUN_SHARED_HOME"].length > 0) void pruneRunningUpdateReleases(process.env["BLUN_SHARED_HOME"], {
|
|
515056
|
+
activePackageRoot: __dirname
|
|
515057
|
+
}).catch(() => {});
|
|
515052
515058
|
if (!process.connected) return;
|
|
515053
515059
|
const sessionId = tui.getCurrentSessionId();
|
|
515054
515060
|
if (sessionId.length === 0) return;
|
|
@@ -515061,6 +515067,17 @@ function notifyRunningRuntimeReady(tui) {
|
|
|
515061
515067
|
}
|
|
515062
515068
|
function requestRunningUpdateAtSafeBoundary(tui) {
|
|
515063
515069
|
if (tui.runningUpdatePreparedVersion === void 0 || tui.runningUpdatePreparedMode === void 0 || tui.runningUpdateHandoffStarted || !process.connected) return false;
|
|
515070
|
+
const waitMs = tui.runningUpdateNotBeforeMs - Date.now();
|
|
515071
|
+
if (Number.isFinite(waitMs) && waitMs > 0) {
|
|
515072
|
+
if (tui.runningUpdateDelayTimer === void 0) {
|
|
515073
|
+
tui.runningUpdateDelayTimer = setTimeout(() => {
|
|
515074
|
+
tui.runningUpdateDelayTimer = void 0;
|
|
515075
|
+
requestRunningUpdateAtSafeBoundary(tui);
|
|
515076
|
+
}, waitMs);
|
|
515077
|
+
tui.runningUpdateDelayTimer.unref?.();
|
|
515078
|
+
}
|
|
515079
|
+
return false;
|
|
515080
|
+
}
|
|
515064
515081
|
const boundaryState = () => ({
|
|
515065
515082
|
isShuttingDown: tui.isShuttingDown,
|
|
515066
515083
|
streamingPhase: tui.state.appState.streamingPhase,
|
|
@@ -515191,6 +515208,8 @@ var BlunTUI = class {
|
|
|
515191
515208
|
runningUpdatePreparedVersion;
|
|
515192
515209
|
runningUpdatePreparedMode;
|
|
515193
515210
|
runningUpdateHandoffStarted = false;
|
|
515211
|
+
runningUpdateNotBeforeMs = Date.now() + AUTO_UPDATE_SETTLE_MS;
|
|
515212
|
+
runningUpdateDelayTimer;
|
|
515194
515213
|
runningUpdateMessageDispose;
|
|
515195
515214
|
startupPhaseMs = {};
|
|
515196
515215
|
lastActivityMode;
|
|
@@ -515716,6 +515735,9 @@ var BlunTUI = class {
|
|
|
515716
515735
|
async stop(exitCode) {
|
|
515717
515736
|
if (this.isShuttingDown) return;
|
|
515718
515737
|
this.isShuttingDown = true;
|
|
515738
|
+
if (exitCode === 0 && process.connected) try {
|
|
515739
|
+
process.send({ type: RUNTIME_EXIT_INTENT_MESSAGE });
|
|
515740
|
+
} catch {}
|
|
515719
515741
|
this.unregisterSignalHandlers();
|
|
515720
515742
|
this.aborted = true;
|
|
515721
515743
|
this.channelQueueDeadline?.dispose();
|