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.
Files changed (55) hide show
  1. package/LIESMICH.txt +1 -7
  2. package/README.md +4 -16
  3. package/bin/blun.js +248 -160
  4. package/bin/core-bootstrap.js +47 -0
  5. package/bin/king.js +277 -1
  6. package/bin/launcher-mode.js +2 -1
  7. package/bin/launcher-runtime.js +221 -0
  8. package/bin/plugin-bootstrap.js +0 -0
  9. package/bin/private-paths.js +0 -0
  10. package/bin/update-lease.js +399 -0
  11. package/bin/update-notice.js +1094 -0
  12. package/blun.mjs +4060 -6667
  13. package/package.json +3 -10
  14. package/skills/screenshot-lesen/SKILL.md +0 -1
  15. package/skills/web-lesen/SKILL.md +0 -1
  16. package/telegram-plugin/dist/bridge.mjs +1 -21
  17. package/mnemo/access_routes.js +0 -692
  18. package/mnemo/agent_governance.js +0 -4242
  19. package/mnemo/agent_mail.js +0 -901
  20. package/mnemo/bootstrap_auto.js +0 -137
  21. package/mnemo/brief_coordination.js +0 -226
  22. package/mnemo/code_read_tools.js +0 -375
  23. package/mnemo/context_preview_tools.js +0 -603
  24. package/mnemo/embeddings.js +0 -66
  25. package/mnemo/external_repo_ops.js +0 -575
  26. package/mnemo/facts/example-project-rules.json +0 -90
  27. package/mnemo/facts/example.json +0 -34
  28. package/mnemo/identity_schema.sql +0 -139
  29. package/mnemo/journal_schema.js +0 -561
  30. package/mnemo/loop_doctor_tools.js +0 -661
  31. package/mnemo/mail_secret_refs.js +0 -150
  32. package/mnemo/mcp.js +0 -9309
  33. package/mnemo/memory_consolidation.js +0 -1914
  34. package/mnemo/memory_health_tools.js +0 -165
  35. package/mnemo/package.json +0 -79
  36. package/mnemo/protected_scope_gate.js +0 -627
  37. package/mnemo/resource_access_control.js +0 -684
  38. package/mnemo/runtime_governance.js +0 -1256
  39. package/mnemo/runtime_turn_gate.js +0 -862
  40. package/mnemo/sandbox.js +0 -143
  41. package/mnemo/schema.sql +0 -389
  42. package/mnemo/shared_utils.js +0 -763
  43. package/mnemo/skills/agent-auto-resume/SKILL.md +0 -56
  44. package/mnemo/skills/agent_hand/SKILL.md +0 -43
  45. package/mnemo/skills/agent_hand/run.js +0 -63
  46. package/mnemo/skills/book_flight/SKILL.md +0 -34
  47. package/mnemo/skills/external_repo_review/SKILL.md +0 -43
  48. package/mnemo/skills/external_repo_review/run.js +0 -73
  49. package/mnemo/skills/pay_invoice/SKILL.md +0 -34
  50. package/mnemo/team_quality_ops.js +0 -944
  51. package/mnemo/timeline_report_tools.js +0 -810
  52. package/mnemo/write_gate_risk.js +0 -80
  53. package/mnemo/writer_health.js +0 -152
  54. package/skills/doku-ingestion/SKILL.md +0 -48
  55. 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
+ };