blun-king-cli 9.0.0 → 9.0.1
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/LIESMICH.txt +1 -7
- package/README.md +4 -16
- package/bin/blun.js +248 -160
- package/bin/core-bootstrap.js +47 -0
- package/bin/king.js +277 -1
- package/bin/launcher-mode.js +2 -1
- package/bin/launcher-runtime.js +221 -0
- package/bin/plugin-bootstrap.js +0 -0
- package/bin/private-paths.js +0 -0
- package/bin/update-lease.js +399 -0
- package/bin/update-notice.js +1094 -0
- package/blun.mjs +4060 -6667
- package/package.json +3 -10
- package/skills/screenshot-lesen/SKILL.md +0 -1
- package/skills/web-lesen/SKILL.md +0 -1
- package/telegram-plugin/dist/bridge.mjs +1 -21
- package/mnemo/access_routes.js +0 -692
- package/mnemo/agent_governance.js +0 -4242
- package/mnemo/agent_mail.js +0 -901
- package/mnemo/bootstrap_auto.js +0 -137
- package/mnemo/brief_coordination.js +0 -226
- package/mnemo/code_read_tools.js +0 -375
- package/mnemo/context_preview_tools.js +0 -603
- package/mnemo/embeddings.js +0 -66
- package/mnemo/external_repo_ops.js +0 -575
- package/mnemo/facts/example-project-rules.json +0 -90
- package/mnemo/facts/example.json +0 -34
- package/mnemo/identity_schema.sql +0 -139
- package/mnemo/journal_schema.js +0 -561
- package/mnemo/loop_doctor_tools.js +0 -661
- package/mnemo/mail_secret_refs.js +0 -150
- package/mnemo/mcp.js +0 -9309
- package/mnemo/memory_consolidation.js +0 -1914
- package/mnemo/memory_health_tools.js +0 -165
- package/mnemo/package.json +0 -79
- package/mnemo/protected_scope_gate.js +0 -627
- package/mnemo/resource_access_control.js +0 -684
- package/mnemo/runtime_governance.js +0 -1256
- package/mnemo/runtime_turn_gate.js +0 -862
- package/mnemo/sandbox.js +0 -143
- package/mnemo/schema.sql +0 -389
- package/mnemo/shared_utils.js +0 -763
- package/mnemo/skills/agent-auto-resume/SKILL.md +0 -56
- package/mnemo/skills/agent_hand/SKILL.md +0 -43
- package/mnemo/skills/agent_hand/run.js +0 -63
- package/mnemo/skills/book_flight/SKILL.md +0 -34
- package/mnemo/skills/external_repo_review/SKILL.md +0 -43
- package/mnemo/skills/external_repo_review/run.js +0 -73
- package/mnemo/skills/pay_invoice/SKILL.md +0 -34
- package/mnemo/team_quality_ops.js +0 -944
- package/mnemo/timeline_report_tools.js +0 -810
- package/mnemo/write_gate_risk.js +0 -80
- package/mnemo/writer_health.js +0 -152
- package/skills/doku-ingestion/SKILL.md +0 -48
- package/skills/doku-ingestion/ingest_docs.py +0 -133
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { createHash } = require('node:crypto');
|
|
4
|
+
const fs = require('node:fs');
|
|
5
|
+
const net = require('node:net');
|
|
6
|
+
const os = require('node:os');
|
|
7
|
+
const path = require('node:path');
|
|
8
|
+
|
|
9
|
+
const LEASE_ADOPT_MESSAGE = 'blun-update-lease-adopted';
|
|
10
|
+
const LEASE_CANCEL_MESSAGE = 'blun-update-lease-cancel';
|
|
11
|
+
const LEASE_COMMIT_MESSAGE = 'blun-update-lease-commit';
|
|
12
|
+
const LEASE_HANDOFF_MESSAGE = 'blun-update-lease-handoff';
|
|
13
|
+
const LEASE_BUSY_MESSAGE = 'blun-update-lease-busy';
|
|
14
|
+
const LEASE_UNAVAILABLE_MESSAGE = 'blun-update-lease-unavailable';
|
|
15
|
+
const LEASE_PROTOCOL_VERSION = 'BLUN_UPDATE_LEASE_V3';
|
|
16
|
+
const LEASE_PROBE_TIMEOUT_MS = 500;
|
|
17
|
+
const MAX_POSIX_SOCKET_PATH_BYTES = 96;
|
|
18
|
+
|
|
19
|
+
function canonicalPackageIdentity(packageRoot, options = {}) {
|
|
20
|
+
if (typeof packageRoot !== 'string' || packageRoot.trim().length === 0) {
|
|
21
|
+
throw new Error('UPDATE_PACKAGE_ROOT_REQUIRED');
|
|
22
|
+
}
|
|
23
|
+
const fsImpl = options.fsImpl || fs;
|
|
24
|
+
const platform = options.platform || process.platform;
|
|
25
|
+
const realpath = fsImpl.realpathSync.native || fsImpl.realpathSync;
|
|
26
|
+
let canonical = realpath(path.resolve(packageRoot));
|
|
27
|
+
if (!fsImpl.statSync(canonical).isDirectory()) throw new Error('INVALID_UPDATE_PACKAGE_ROOT');
|
|
28
|
+
canonical = canonical.replaceAll('\\', '/');
|
|
29
|
+
if (platform === 'win32') canonical = canonical.toLowerCase();
|
|
30
|
+
return canonical;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function deriveUpdateLeaseEndpoint(packageRoot, options = {}) {
|
|
34
|
+
const platform = options.platform || process.platform;
|
|
35
|
+
const role = options.role === 'install' ? 'install' : 'notice';
|
|
36
|
+
const identity = canonicalPackageIdentity(packageRoot, options);
|
|
37
|
+
const digest = createHash('sha256')
|
|
38
|
+
.update(`blun-update-v3\0${role}\0${identity}`)
|
|
39
|
+
.digest('hex');
|
|
40
|
+
const magic = `${LEASE_PROTOCOL_VERSION} ${digest}\n`;
|
|
41
|
+
if (platform === 'win32') {
|
|
42
|
+
return Object.freeze({
|
|
43
|
+
magic,
|
|
44
|
+
path: `\\\\.\\pipe\\blun-update-v3-${digest.slice(0, 32)}`,
|
|
45
|
+
platform,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const uid = options.uid ?? (typeof process.getuid === 'function' ? process.getuid() : undefined);
|
|
50
|
+
const directoryName = `blun-update-${uid ?? digest.slice(0, 12)}`;
|
|
51
|
+
const requestedRoot = String(options.socketDirectory || options.tempDir || os.tmpdir())
|
|
52
|
+
.replaceAll('\\', '/');
|
|
53
|
+
let directory = options.socketDirectory
|
|
54
|
+
? requestedRoot
|
|
55
|
+
: path.posix.join(requestedRoot, directoryName);
|
|
56
|
+
let socketPath = path.posix.join(directory, `lease-${digest.slice(0, 24)}.sock`);
|
|
57
|
+
if (Buffer.byteLength(socketPath, 'utf8') > MAX_POSIX_SOCKET_PATH_BYTES) {
|
|
58
|
+
directory = path.posix.join('/tmp', directoryName);
|
|
59
|
+
socketPath = path.posix.join(directory, `lease-${digest.slice(0, 24)}.sock`);
|
|
60
|
+
}
|
|
61
|
+
if (Buffer.byteLength(socketPath, 'utf8') > MAX_POSIX_SOCKET_PATH_BYTES) {
|
|
62
|
+
throw new Error('UPDATE_LEASE_SOCKET_PATH_TOO_LONG');
|
|
63
|
+
}
|
|
64
|
+
return Object.freeze({ directory, magic, path: socketPath, platform });
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function closeServer(server) {
|
|
68
|
+
return new Promise((resolve) => {
|
|
69
|
+
if (!server.listening) {
|
|
70
|
+
resolve();
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
try {
|
|
74
|
+
server.close(() => resolve());
|
|
75
|
+
} catch {
|
|
76
|
+
resolve();
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function ensurePrivateSocketDirectory(endpoint, options = {}) {
|
|
82
|
+
if (endpoint.platform === 'win32') return;
|
|
83
|
+
const fsImpl = options.fsImpl || fs;
|
|
84
|
+
fsImpl.mkdirSync(endpoint.directory, { recursive: true, mode: 0o700 });
|
|
85
|
+
const stat = fsImpl.lstatSync(endpoint.directory);
|
|
86
|
+
if (!stat.isDirectory() || stat.isSymbolicLink()) {
|
|
87
|
+
throw new Error('INVALID_UPDATE_LEASE_DIRECTORY');
|
|
88
|
+
}
|
|
89
|
+
if (typeof process.getuid === 'function'
|
|
90
|
+
&& Number.isInteger(stat.uid)
|
|
91
|
+
&& stat.uid !== process.getuid()) {
|
|
92
|
+
throw new Error('INVALID_UPDATE_LEASE_DIRECTORY_OWNER');
|
|
93
|
+
}
|
|
94
|
+
fsImpl.chmodSync(endpoint.directory, 0o700);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function listenForLease(endpoint, options = {}) {
|
|
98
|
+
const netImpl = options.netImpl || net;
|
|
99
|
+
return new Promise((resolve, reject) => {
|
|
100
|
+
const server = netImpl.createServer((socket) => {
|
|
101
|
+
socket.on('error', () => {});
|
|
102
|
+
socket.end(endpoint.magic);
|
|
103
|
+
});
|
|
104
|
+
const onError = (error) => {
|
|
105
|
+
server.removeListener('error', onError);
|
|
106
|
+
reject(error);
|
|
107
|
+
};
|
|
108
|
+
server.once('error', onError);
|
|
109
|
+
server.listen({ path: endpoint.path, exclusive: true }, () => {
|
|
110
|
+
server.removeListener('error', onError);
|
|
111
|
+
resolve(server);
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function probeExistingLease(endpoint, options = {}) {
|
|
117
|
+
const netImpl = options.netImpl || net;
|
|
118
|
+
const timeoutMs = options.probeTimeoutMs || LEASE_PROBE_TIMEOUT_MS;
|
|
119
|
+
return new Promise((resolve) => {
|
|
120
|
+
let settled = false;
|
|
121
|
+
let received = '';
|
|
122
|
+
let socket;
|
|
123
|
+
const finish = (state, error) => {
|
|
124
|
+
if (settled) return;
|
|
125
|
+
settled = true;
|
|
126
|
+
clearTimeout(timer);
|
|
127
|
+
try {
|
|
128
|
+
socket?.destroy();
|
|
129
|
+
} catch {}
|
|
130
|
+
// oxlint-disable-next-line promise/no-multiple-resolved -- settled is the idempotence guard.
|
|
131
|
+
resolve({ error, state });
|
|
132
|
+
};
|
|
133
|
+
const timer = setTimeout(() => finish('foreign'), timeoutMs);
|
|
134
|
+
timer.unref?.();
|
|
135
|
+
try {
|
|
136
|
+
socket = netImpl.createConnection({ path: endpoint.path });
|
|
137
|
+
socket.setEncoding?.('utf8');
|
|
138
|
+
socket.on('data', (chunk) => {
|
|
139
|
+
received += String(chunk);
|
|
140
|
+
if (Buffer.byteLength(received, 'utf8') > Buffer.byteLength(endpoint.magic, 'utf8')) {
|
|
141
|
+
finish('foreign');
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
socket.once('end', () => finish(received === endpoint.magic ? 'owner' : 'foreign'));
|
|
145
|
+
socket.once('error', (error) => {
|
|
146
|
+
const stale = error?.code === 'ECONNREFUSED' || error?.code === 'ENOENT';
|
|
147
|
+
finish(stale ? 'stale' : 'foreign', error);
|
|
148
|
+
});
|
|
149
|
+
socket.once('close', () => {
|
|
150
|
+
if (!settled) finish(received === endpoint.magic ? 'owner' : 'foreign');
|
|
151
|
+
});
|
|
152
|
+
} catch (error) {
|
|
153
|
+
const stale = error?.code === 'ECONNREFUSED' || error?.code === 'ENOENT';
|
|
154
|
+
finish(stale ? 'stale' : 'foreign', error);
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function observeSocketPath(endpoint, options = {}) {
|
|
160
|
+
if (endpoint.platform === 'win32') return { state: 'not_applicable' };
|
|
161
|
+
const fsImpl = options.fsImpl || fs;
|
|
162
|
+
try {
|
|
163
|
+
const stat = fsImpl.lstatSync(endpoint.path);
|
|
164
|
+
if (!stat.isSocket() || stat.isSymbolicLink()) return { state: 'unsafe' };
|
|
165
|
+
return { dev: stat.dev, ino: stat.ino, state: 'socket' };
|
|
166
|
+
} catch (error) {
|
|
167
|
+
return error?.code === 'ENOENT' ? { state: 'missing' } : { state: 'unsafe' };
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function removeObservedStaleSocket(endpoint, observed, options = {}) {
|
|
172
|
+
if (endpoint.platform === 'win32') return false;
|
|
173
|
+
const fsImpl = options.fsImpl || fs;
|
|
174
|
+
try {
|
|
175
|
+
const stat = fsImpl.lstatSync(endpoint.path);
|
|
176
|
+
if (observed.state !== 'socket'
|
|
177
|
+
|| !stat.isSocket()
|
|
178
|
+
|| stat.isSymbolicLink()
|
|
179
|
+
|| stat.dev !== observed.dev
|
|
180
|
+
|| stat.ino !== observed.ino) {
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
fsImpl.unlinkSync(endpoint.path);
|
|
184
|
+
return true;
|
|
185
|
+
} catch (error) {
|
|
186
|
+
return error?.code === 'ENOENT' && observed.state === 'missing';
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function recordSocketIdentity(endpoint, options = {}) {
|
|
191
|
+
if (endpoint.platform === 'win32') return undefined;
|
|
192
|
+
const fsImpl = options.fsImpl || fs;
|
|
193
|
+
const stat = fsImpl.lstatSync(endpoint.path);
|
|
194
|
+
if (!stat.isSocket() || stat.isSymbolicLink()) throw new Error('INVALID_UPDATE_LEASE_SOCKET');
|
|
195
|
+
fsImpl.chmodSync(endpoint.path, 0o600);
|
|
196
|
+
return { dev: stat.dev, ino: stat.ino };
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function removeOwnedSocket(endpoint, identity, options = {}) {
|
|
200
|
+
if (endpoint.platform === 'win32' || !identity) return;
|
|
201
|
+
const fsImpl = options.fsImpl || fs;
|
|
202
|
+
try {
|
|
203
|
+
const stat = fsImpl.lstatSync(endpoint.path);
|
|
204
|
+
if (stat.isSocket()
|
|
205
|
+
&& !stat.isSymbolicLink()
|
|
206
|
+
&& stat.dev === identity.dev
|
|
207
|
+
&& stat.ino === identity.ino) {
|
|
208
|
+
fsImpl.unlinkSync(endpoint.path);
|
|
209
|
+
}
|
|
210
|
+
} catch {}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
async function tryAcquireUpdateLease(options = {}) {
|
|
214
|
+
let endpoint;
|
|
215
|
+
try {
|
|
216
|
+
endpoint = deriveUpdateLeaseEndpoint(options.packageRoot, options);
|
|
217
|
+
ensurePrivateSocketDirectory(endpoint, options);
|
|
218
|
+
} catch {
|
|
219
|
+
return { acquired: false, reason: 'unavailable' };
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
let server;
|
|
223
|
+
for (let attempt = 0; attempt < 2; attempt += 1) {
|
|
224
|
+
try {
|
|
225
|
+
server = await listenForLease(endpoint, options);
|
|
226
|
+
break;
|
|
227
|
+
} catch (error) {
|
|
228
|
+
if (error?.code !== 'EADDRINUSE') {
|
|
229
|
+
return { acquired: false, reason: 'unavailable' };
|
|
230
|
+
}
|
|
231
|
+
const observed = observeSocketPath(endpoint, options);
|
|
232
|
+
const probe = await probeExistingLease(endpoint, options);
|
|
233
|
+
if (probe.state === 'owner') return { acquired: false, reason: 'busy' };
|
|
234
|
+
if (probe.state !== 'stale' || attempt > 0) {
|
|
235
|
+
return { acquired: false, reason: 'unavailable' };
|
|
236
|
+
}
|
|
237
|
+
if (endpoint.platform === 'win32') continue;
|
|
238
|
+
if (!removeObservedStaleSocket(endpoint, observed, options)) {
|
|
239
|
+
return { acquired: false, reason: 'unavailable' };
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
if (!server) return { acquired: false, reason: 'unavailable' };
|
|
244
|
+
|
|
245
|
+
let identity;
|
|
246
|
+
try {
|
|
247
|
+
identity = recordSocketIdentity(endpoint, options);
|
|
248
|
+
} catch {
|
|
249
|
+
await closeServer(server);
|
|
250
|
+
removeOwnedSocket(endpoint, identity, options);
|
|
251
|
+
return { acquired: false, reason: 'unavailable' };
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
let owned = true;
|
|
255
|
+
let released = false;
|
|
256
|
+
server.on('error', () => {
|
|
257
|
+
owned = false;
|
|
258
|
+
});
|
|
259
|
+
server.on('close', () => {
|
|
260
|
+
owned = false;
|
|
261
|
+
});
|
|
262
|
+
const lease = Object.freeze({
|
|
263
|
+
assertOwned() {
|
|
264
|
+
if (!owned || !server.listening) throw new Error('UPDATE_LEASE_LOST');
|
|
265
|
+
},
|
|
266
|
+
async release() {
|
|
267
|
+
if (released) return;
|
|
268
|
+
released = true;
|
|
269
|
+
owned = false;
|
|
270
|
+
await closeServer(server);
|
|
271
|
+
removeOwnedSocket(endpoint, identity, options);
|
|
272
|
+
},
|
|
273
|
+
unref() {
|
|
274
|
+
server.unref?.();
|
|
275
|
+
},
|
|
276
|
+
});
|
|
277
|
+
return { acquired: true, lease };
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
function isInstallerMessage(message) {
|
|
281
|
+
if (!message || message.type !== LEASE_HANDOFF_MESSAGE) return false;
|
|
282
|
+
const installer = message.installer;
|
|
283
|
+
return installer
|
|
284
|
+
&& typeof installer === 'object'
|
|
285
|
+
&& typeof message.packageRoot === 'string'
|
|
286
|
+
&& path.isAbsolute(message.packageRoot)
|
|
287
|
+
&& typeof installer.npmCliPath === 'string'
|
|
288
|
+
&& path.isAbsolute(installer.npmCliPath)
|
|
289
|
+
&& Array.isArray(installer.npmArgs)
|
|
290
|
+
&& installer.npmArgs.every((entry) => typeof entry === 'string')
|
|
291
|
+
&& typeof installer.installCwd === 'string'
|
|
292
|
+
&& path.isAbsolute(installer.installCwd);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
function runInstallerWorker() {
|
|
296
|
+
let state = 'BOOT';
|
|
297
|
+
let started = false;
|
|
298
|
+
let installLease;
|
|
299
|
+
let installCwd;
|
|
300
|
+
const isControlMessage = (message, type) => message
|
|
301
|
+
&& typeof message === 'object'
|
|
302
|
+
&& Object.getPrototypeOf(message) === Object.prototype
|
|
303
|
+
&& Reflect.ownKeys(message).length === 1
|
|
304
|
+
&& message.type === type;
|
|
305
|
+
const exitWithoutInstall = async (code = 0) => {
|
|
306
|
+
if (state === 'DONE') return;
|
|
307
|
+
state = 'DONE';
|
|
308
|
+
try {
|
|
309
|
+
await installLease?.release();
|
|
310
|
+
} catch {}
|
|
311
|
+
process.exit(code);
|
|
312
|
+
};
|
|
313
|
+
const startInstaller = (installer) => {
|
|
314
|
+
if (started || state !== 'COMMITTED') return;
|
|
315
|
+
started = true;
|
|
316
|
+
try {
|
|
317
|
+
installLease.assertOwned();
|
|
318
|
+
process.chdir(installer.installCwd);
|
|
319
|
+
process.argv = [process.execPath, installer.npmCliPath, ...installer.npmArgs];
|
|
320
|
+
require(installer.npmCliPath);
|
|
321
|
+
} catch {
|
|
322
|
+
process.exit(1);
|
|
323
|
+
}
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
process.once('message', async (message) => {
|
|
327
|
+
if (state !== 'BOOT' || !isInstallerMessage(message)) {
|
|
328
|
+
process.exit(1);
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
state = 'PREPARED';
|
|
332
|
+
installCwd = message.installer.installCwd;
|
|
333
|
+
process.once('exit', () => {
|
|
334
|
+
if (!installCwd) return;
|
|
335
|
+
try {
|
|
336
|
+
process.chdir(path.dirname(installCwd));
|
|
337
|
+
fs.rmSync(installCwd, { recursive: true, force: true });
|
|
338
|
+
} catch {}
|
|
339
|
+
});
|
|
340
|
+
const leaseResult = await tryAcquireUpdateLease({
|
|
341
|
+
packageRoot: message.packageRoot,
|
|
342
|
+
role: 'install',
|
|
343
|
+
});
|
|
344
|
+
if (!leaseResult.acquired) {
|
|
345
|
+
const type = leaseResult.reason === 'busy'
|
|
346
|
+
? LEASE_BUSY_MESSAGE
|
|
347
|
+
: LEASE_UNAVAILABLE_MESSAGE;
|
|
348
|
+
if (process.connected) {
|
|
349
|
+
try {
|
|
350
|
+
process.send({ type }, () => process.exit(75));
|
|
351
|
+
return;
|
|
352
|
+
} catch {}
|
|
353
|
+
}
|
|
354
|
+
process.exit(75);
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
installLease = leaseResult.lease;
|
|
358
|
+
state = 'LEASED';
|
|
359
|
+
if (!process.connected) {
|
|
360
|
+
await exitWithoutInstall();
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
const onControl = (control) => {
|
|
364
|
+
if (state !== 'LEASED') {
|
|
365
|
+
void exitWithoutInstall(1);
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
if (isControlMessage(control, LEASE_CANCEL_MESSAGE)) {
|
|
369
|
+
void exitWithoutInstall();
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
if (!isControlMessage(control, LEASE_COMMIT_MESSAGE)) {
|
|
373
|
+
void exitWithoutInstall(1);
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
state = 'COMMITTED';
|
|
377
|
+
setImmediate(() => startInstaller(message.installer));
|
|
378
|
+
};
|
|
379
|
+
process.once('message', onControl);
|
|
380
|
+
try {
|
|
381
|
+
process.send({ type: LEASE_ADOPT_MESSAGE });
|
|
382
|
+
} catch {
|
|
383
|
+
process.removeListener('message', onControl);
|
|
384
|
+
await exitWithoutInstall();
|
|
385
|
+
}
|
|
386
|
+
});
|
|
387
|
+
process.once('disconnect', () => {
|
|
388
|
+
if (state !== 'COMMITTED' && state !== 'DONE') void exitWithoutInstall();
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
if (require.main === module && process.argv[2] === '--installer-worker') {
|
|
393
|
+
runInstallerWorker();
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
module.exports = {
|
|
397
|
+
deriveUpdateLeaseEndpoint,
|
|
398
|
+
tryAcquireUpdateLease,
|
|
399
|
+
};
|