blun-king-cli 9.1.392 → 9.1.394

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 CHANGED
@@ -20,6 +20,17 @@ Start
20
20
  Beide Startbefehle verwenden dieselbe Version, dasselbe Konto, dasselbe Modell
21
21
  und dieselben Befehle.
22
22
 
23
+ king und king -c prüfen beim interaktiven Start auf eine neuere Version. Ist
24
+ eine vorhanden, erscheint der sichtbare Dialog:
25
+
26
+ 1. Jetzt aktualisieren
27
+ 2. Überspringen
28
+ 3. Auf den nächsten Release warten
29
+
30
+ Es gibt keinen Download und keine Installation im Hintergrund. Nach einer
31
+ gewählten Installation endet king; king -c setzt die letzte Sitzung mit der
32
+ neuen Version fort.
33
+
23
34
  Standard-MCPs und Eingabesteuerung
24
35
  ---------------------------------
25
36
  Beim Start richtet BLUN King `agent-browser`, `blun-language-guard` und unter
@@ -315,6 +326,25 @@ Nachweisbare Arbeitsabläufe
315
326
 
316
327
  Alle Befehle funktionieren identisch mit `king`.
317
328
 
329
+ Gemeinsamer kognitiver Speicherkern (optional)
330
+ ------------------------------------------------
331
+
332
+ Ohne zusätzliche Konfiguration bleibt der bisherige lokale SQLite-Speicher
333
+ aktiv. Betreiber können einen gemeinsamen, portalneutralen Speicherkern
334
+ ausdrücklich über BLUN_COGNITIVE_MEMORY_ADAPTER_MODULE wählen. Der Wert muss
335
+ auf eine absolute, kanonische CommonJS-Datei zeigen.
336
+
337
+ Das Modul exportiert synchron createCognitiveMemoryAdapter(context) und liefert
338
+ einen Adapter mit Vertragsversion 6. Relative Pfade, symbolische Verknüpfungen,
339
+ asynchrone Fabriken und abweichende Vertragsversionen werden geschlossen
340
+ abgewiesen. Der Adapter erhält nur die Vertragsversion, das Profilverzeichnis
341
+ sowie Mandanten-, Agenten- und Anzeigenamen. Zugangsdaten werden nicht
342
+ übergeben.
343
+
344
+ Damit kann derselbe geprüfte Ereignisstrom über CLI und Portale hinweg gelesen,
345
+ korrigiert und zurückgezogen werden. Ohne den optionalen Anbieter entstehen
346
+ keine neuen Netzwerkzugriffe und keine Verhaltensänderung.
347
+
318
348
  Medienerzeugung
319
349
  ---------------
320
350
  Für Medienaufträge bleiben GenerateImage, GenerateVideo, GenerateSpeech und
@@ -414,15 +444,6 @@ zurückzufallen. Die globale Node-Installation des Systems wird nicht verändert
414
444
  OAuth, gespeicherte Anmeldedaten, Sitzungen und der Updatestatus bleiben
415
445
  unverändert.
416
446
 
417
- Aktualisieren
418
- -------------
419
-
420
- blun update
421
-
422
- `king update` und `upgrade` sind gleichwertig. Der Updater bleibt im installierten
423
- Stable- oder Next-Kanal, verhindert Rückstufungen und installiert nur eine zuvor
424
- aufgelöste exakte Paketversion.
425
-
426
447
  Beim ersten Start in der Konsole /login eingeben. Der Browser öffnet den
427
448
  BLUN-OAuth-Login.
428
449
  Ein API-Schlüssel wird weder abgefragt noch in die Konfiguration geschrieben.
package/README.md CHANGED
@@ -35,6 +35,13 @@ an. Version, Konto, Modell und Befehle sind ansonsten identisch. Der Unterschied
35
35
  gilt nur für den laufenden Prozess; die gespeicherte
36
36
  Plugin-Konfiguration wird nicht umgeschrieben.
37
37
 
38
+ `king` und `king -c` prüfen beim interaktiven Start, ob eine neuere Version
39
+ vorliegt. Dann erscheint der sichtbare Dialog mit den Optionen jetzt
40
+ aktualisieren, überspringen oder auf den nächsten Release warten. Im Hintergrund
41
+ wird nichts heruntergeladen oder installiert. Nach einer gewählten Installation
42
+ endet `king`; `king -c` setzt dagegen die letzte Sitzung mit der neuen Version
43
+ fort.
44
+
38
45
  Telegram-Chats werden ohne manuell eingegebene IDs verbunden. In der Konsole
39
46
  erzeugt `/telegram:access connect` einen einmaligen Code. `/connect CODE` im
40
47
  gewünschten privaten Chat oder in einer Gruppe speichert Chat und Absender
@@ -331,6 +338,24 @@ Version 9.1.0 enthält sieben zusätzliche, getrennt nutzbare Befehlsgruppen:
331
338
 
332
339
  Sie stehen unter `blun` und `king` identisch zur Verfügung.
333
340
 
341
+ ## Gemeinsamer kognitiver Speicherkern (optional)
342
+
343
+ Ohne zusätzliche Konfiguration bleibt der bisherige lokale SQLite-Speicher
344
+ aktiv. Betreiber können einen gemeinsamen, portalneutralen Speicherkern
345
+ ausdrücklich über `BLUN_COGNITIVE_MEMORY_ADAPTER_MODULE` wählen. Der Wert muss
346
+ auf eine absolute, kanonische CommonJS-Datei zeigen.
347
+
348
+ Das Modul exportiert synchron `createCognitiveMemoryAdapter(context)` und
349
+ liefert einen Adapter mit Vertragsversion 6. Relative Pfade, symbolische
350
+ Verknüpfungen, asynchrone Fabriken und abweichende Vertragsversionen werden
351
+ geschlossen abgewiesen. Der Adapter erhält nur die Vertragsversion, das
352
+ Profilverzeichnis sowie Mandanten-, Agenten- und Anzeigenamen. Zugangsdaten
353
+ werden nicht übergeben.
354
+
355
+ Damit kann derselbe geprüfte Ereignisstrom über CLI und Portale hinweg gelesen,
356
+ korrigiert und zurückgezogen werden. Ohne den optionalen Anbieter entstehen
357
+ keine neuen Netzwerkzugriffe und keine Verhaltensänderung.
358
+
334
359
  ## Medienerzeugung
335
360
 
336
361
  Für Medienaufträge bleiben `GenerateImage`, `GenerateVideo`, `GenerateSpeech` und
@@ -416,10 +441,3 @@ unterstützte Laufzeit wie die TUI, statt auf eine ältere Systeminstallation
416
441
  zurückzufallen. Die globale Node-Installation des Systems wird nicht verändert.
417
442
  OAuth, gespeicherte Anmeldedaten, Sitzungen und der Updatestatus bleiben
418
443
  unverändert.
419
-
420
- ## Aktualisieren
421
-
422
- `blun update`, `king update` und die jeweilige Variante `upgrade` verwenden
423
- denselben abgesicherten Updater. Er bleibt im installierten Stable- oder
424
- Next-Kanal, verhindert Rückstufungen und übergibt npm ausschließlich eine zuvor
425
- aufgelöste exakte Paketversion.
package/bin/blun.js CHANGED
@@ -325,55 +325,40 @@ async function connectExistingRuntimeLease(timeoutMs = 3_000) {
325
325
  }
326
326
 
327
327
  async function main() {
328
- const explicitUpdateRequest = process.argv.length === 3
329
- && /^(?:update|upgrade)$/iu.test(process.argv[2] || '');
330
- let noticeResult = await acquireNoticeLease();
331
- let runtimeResult;
332
- try {
333
- if (explicitUpdateRequest) {
334
- runtimeResult = await connectExistingRuntimeLease(750);
335
- if (!runtimeResult.acquired) {
336
- runtimeResult = undefined;
337
- if (!noticeResult.acquired || !await installLeaseIsClear()) {
338
- process.stderr.write('Der geschuetzte BLUN-Start ist gerade nicht verfuegbar.\n');
339
- process.exitCode = 1;
340
- return;
341
- }
342
- }
343
- } else {
344
- const installClear = await installLeaseIsClear();
345
- if (!installClear || !noticeResult.acquired) {
346
- runtimeResult = await connectExistingRuntimeLease();
347
- if (!runtimeResult.acquired && !installClear) {
348
- if (!await installLeaseIsClear()) {
349
- process.stderr.write('Der geschuetzte BLUN-Start ist gerade nicht verfuegbar.\n');
350
- process.exitCode = 1;
351
- return;
352
- }
353
- runtimeResult = undefined;
354
- }
355
- if (!runtimeResult?.acquired && !noticeResult.acquired) {
356
- noticeResult = await acquireNoticeLease();
357
- if (!noticeResult.acquired) {
358
- process.stderr.write('Der geschuetzte BLUN-Start ist gerade nicht verfuegbar.\n');
359
- process.exitCode = 1;
360
- return;
361
- }
362
- }
363
- }
364
- }
328
+ let noticeResult = await acquireNoticeLease();
329
+ let runtimeResult;
330
+ try {
331
+ const installClear = await installLeaseIsClear();
332
+ if (!installClear || !noticeResult.acquired) {
333
+ runtimeResult = await connectExistingRuntimeLease();
334
+ if (!runtimeResult.acquired && !installClear) {
335
+ if (!await installLeaseIsClear()) {
336
+ process.stderr.write('Der geschuetzte BLUN-Start ist gerade nicht verfuegbar.\n');
337
+ process.exitCode = 1;
338
+ return;
339
+ }
340
+ runtimeResult = undefined;
341
+ }
342
+ if (!runtimeResult?.acquired && !noticeResult.acquired) {
343
+ noticeResult = await acquireNoticeLease();
344
+ if (!noticeResult.acquired) {
345
+ process.stderr.write('Der geschuetzte BLUN-Start ist gerade nicht verfuegbar.\n');
346
+ process.exitCode = 1;
347
+ return;
348
+ }
349
+ }
350
+ }
365
351
  noticeResult.lease?.assertOwned();
366
352
  runtimeResult?.lease?.assertOwned();
367
353
  const { runLauncher } = require('./launcher-runtime');
368
354
  noticeResult.lease?.assertOwned();
369
355
  runtimeResult?.lease?.assertOwned();
370
356
  const filename = path.basename(__filename).toLowerCase();
371
- await runLauncher({
372
- mode: filename.startsWith('king') ? 'king' : 'blun',
373
- noticeLease: noticeResult.lease,
374
- runtimeLease: runtimeResult?.lease,
375
- skipUpdateNotice: runtimeResult?.acquired === true || !noticeResult.acquired,
376
- });
357
+ await runLauncher({
358
+ mode: filename.startsWith('king') ? 'king' : 'blun',
359
+ noticeLease: noticeResult.lease,
360
+ runtimeLease: runtimeResult?.lease,
361
+ });
377
362
  } finally {
378
363
  await runtimeResult?.lease?.release();
379
364
  await noticeResult.lease?.release();
@@ -0,0 +1,92 @@
1
+ 'use strict';
2
+
3
+ const fs = require('node:fs');
4
+ const path = require('node:path');
5
+ const {
6
+ COGNITIVE_MEMORY_ADAPTER_VERSION,
7
+ assertCognitiveMemoryAdapter,
8
+ } = require('./cognitive-memory-adapter.cjs');
9
+
10
+ const PROVIDER_ENV = 'BLUN_COGNITIVE_MEMORY_ADAPTER_MODULE';
11
+ const SAFE_ID_RE = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u;
12
+
13
+ function fail(code) {
14
+ const error = new Error(code);
15
+ error.code = code;
16
+ throw error;
17
+ }
18
+
19
+ function canonicalFile(input) {
20
+ const configured = String(input ?? '').trim();
21
+ if (!configured || !path.isAbsolute(configured)) fail('COGNITIVE_MEMORY_PROVIDER_PATH_INVALID');
22
+ const resolved = path.resolve(configured);
23
+ let stat;
24
+ let canonical;
25
+ try {
26
+ stat = fs.lstatSync(resolved);
27
+ canonical = fs.realpathSync(resolved);
28
+ } catch {
29
+ fail('COGNITIVE_MEMORY_PROVIDER_PATH_INVALID');
30
+ }
31
+ if (!stat.isFile() || stat.isSymbolicLink()
32
+ || path.normalize(canonical).toLowerCase() !== path.normalize(resolved).toLowerCase()) {
33
+ fail('COGNITIVE_MEMORY_PROVIDER_PATH_INVALID');
34
+ }
35
+ return canonical;
36
+ }
37
+
38
+ function boundedContext({ home, tenantId, agentId, agentName }) {
39
+ const tenant = String(tenantId ?? '').trim();
40
+ const agent = String(agentId ?? '').trim();
41
+ const name = String(agentName ?? '').trim();
42
+ let canonicalHome;
43
+ try {
44
+ const stat = fs.lstatSync(path.resolve(String(home ?? '')));
45
+ canonicalHome = fs.realpathSync(path.resolve(String(home ?? '')));
46
+ if (!stat.isDirectory() || stat.isSymbolicLink()) fail('COGNITIVE_MEMORY_PROVIDER_CONTEXT_INVALID');
47
+ } catch (error) {
48
+ if (error?.code === 'COGNITIVE_MEMORY_PROVIDER_CONTEXT_INVALID') throw error;
49
+ fail('COGNITIVE_MEMORY_PROVIDER_CONTEXT_INVALID');
50
+ }
51
+ if (!SAFE_ID_RE.test(tenant) || !SAFE_ID_RE.test(agent) || !name || name.length > 128
52
+ || /[\u0000-\u001f\u007f]/u.test(name)) {
53
+ fail('COGNITIVE_MEMORY_PROVIDER_CONTEXT_INVALID');
54
+ }
55
+ return Object.freeze({
56
+ contractVersion: COGNITIVE_MEMORY_ADAPTER_VERSION,
57
+ home: canonicalHome,
58
+ tenantId: tenant,
59
+ agentId: agent,
60
+ agentName: name,
61
+ });
62
+ }
63
+
64
+ function loadConfiguredCognitiveMemoryAdapter({
65
+ modulePath,
66
+ env = process.env,
67
+ home,
68
+ tenantId,
69
+ agentId,
70
+ agentName,
71
+ } = {}) {
72
+ const configured = modulePath === undefined ? env?.[PROVIDER_ENV] : modulePath;
73
+ if (!String(configured ?? '').trim()) return undefined;
74
+ const providerPath = canonicalFile(configured);
75
+ const provider = require(providerPath);
76
+ if (!provider || typeof provider.createCognitiveMemoryAdapter !== 'function') {
77
+ fail('COGNITIVE_MEMORY_PROVIDER_FACTORY_REQUIRED');
78
+ }
79
+ const adapter = provider.createCognitiveMemoryAdapter(boundedContext({
80
+ home,
81
+ tenantId,
82
+ agentId,
83
+ agentName,
84
+ }));
85
+ if (adapter && typeof adapter.then === 'function') fail('COGNITIVE_MEMORY_PROVIDER_ASYNC_UNSUPPORTED');
86
+ return assertCognitiveMemoryAdapter(adapter);
87
+ }
88
+
89
+ module.exports = {
90
+ PROVIDER_ENV,
91
+ loadConfiguredCognitiveMemoryAdapter,
92
+ };
@@ -4,6 +4,7 @@ const crypto = require('node:crypto');
4
4
  const fs = require('node:fs');
5
5
  const path = require('node:path');
6
6
  const { openCognitiveMemoryAdapter } = require('./cognitive-memory-adapter.cjs');
7
+ const { loadConfiguredCognitiveMemoryAdapter } = require('./cognitive-memory-provider.cjs');
7
8
  const { buildCognitiveContextProjection } = require('./cognitive-context-projection.cjs');
8
9
  const { buildCognitiveFocusProjection } = require('./cognitive-focus-projection.cjs');
9
10
  const { authorizeAttentionCandidate } = require('./cognitive-attention-runtime.cjs');
@@ -521,6 +522,7 @@ function createRuntimeCognitiveTurnLifecycle({
521
522
  agentId,
522
523
  runtimeId,
523
524
  memoryAdapter,
525
+ memoryAdapterModule,
524
526
  now,
525
527
  } = {}) {
526
528
  const resolvedHome = String(home ?? '').trim();
@@ -537,12 +539,25 @@ function createRuntimeCognitiveTurnLifecycle({
537
539
  agentId: explicitAgent || manifestIdentity?.agentId || '',
538
540
  };
539
541
  const hasSharedIdentity = Boolean(identity.tenantId && identity.agentId);
542
+ const resolvedTenantId = hasSharedIdentity
543
+ ? identity.tenantId : digestId('home', [resolvedHome.toLowerCase()]);
544
+ const resolvedAgentId = hasSharedIdentity
545
+ ? identity.agentId : digestId('agent', [resolvedAgent.toLowerCase()]);
546
+ const resolvedMemoryAdapter = memoryAdapter === undefined
547
+ ? loadConfiguredCognitiveMemoryAdapter({
548
+ modulePath: memoryAdapterModule,
549
+ home: resolvedHome,
550
+ tenantId: resolvedTenantId,
551
+ agentId: resolvedAgentId,
552
+ agentName: resolvedAgent,
553
+ })
554
+ : memoryAdapter;
540
555
  return createCognitiveTurnLifecycle({
541
556
  home: resolvedHome,
542
- tenantId: hasSharedIdentity ? identity.tenantId : digestId('home', [resolvedHome.toLowerCase()]),
543
- agentId: hasSharedIdentity ? identity.agentId : digestId('agent', [resolvedAgent.toLowerCase()]),
557
+ tenantId: resolvedTenantId,
558
+ agentId: resolvedAgentId,
544
559
  runtimeId,
545
- memoryAdapter,
560
+ memoryAdapter: resolvedMemoryAdapter,
546
561
  now,
547
562
  });
548
563
  }
@@ -5,7 +5,6 @@ const path = require('node:path');
5
5
  const { pathToFileURL } = require('node:url');
6
6
 
7
7
  const { acquireSharedRuntimeLease } = require('./update-lease');
8
- const { RUNTIME_READY_MESSAGE } = require('./running-update.cjs');
9
8
 
10
9
  const CORE_LOADED_MESSAGE = 'blun-core-bootstrap-loaded';
11
10
 
@@ -46,4 +45,4 @@ if (require.main === module) {
46
45
  });
47
46
  }
48
47
 
49
- module.exports = { CORE_LOADED_MESSAGE, RUNTIME_READY_MESSAGE, runCoreBootstrap };
48
+ module.exports = { CORE_LOADED_MESSAGE, runCoreBootstrap };
package/bin/king.js CHANGED
@@ -325,55 +325,40 @@ async function connectExistingRuntimeLease(timeoutMs = 3_000) {
325
325
  }
326
326
 
327
327
  async function main() {
328
- const explicitUpdateRequest = process.argv.length === 3
329
- && /^(?:update|upgrade)$/iu.test(process.argv[2] || '');
330
- let noticeResult = await acquireNoticeLease();
331
- let runtimeResult;
332
- try {
333
- if (explicitUpdateRequest) {
334
- runtimeResult = await connectExistingRuntimeLease(750);
335
- if (!runtimeResult.acquired) {
336
- runtimeResult = undefined;
337
- if (!noticeResult.acquired || !await installLeaseIsClear()) {
338
- process.stderr.write('Der geschuetzte BLUN-Start ist gerade nicht verfuegbar.\n');
339
- process.exitCode = 1;
340
- return;
341
- }
342
- }
343
- } else {
344
- const installClear = await installLeaseIsClear();
345
- if (!installClear || !noticeResult.acquired) {
346
- runtimeResult = await connectExistingRuntimeLease();
347
- if (!runtimeResult.acquired && !installClear) {
348
- if (!await installLeaseIsClear()) {
349
- process.stderr.write('Der geschuetzte BLUN-Start ist gerade nicht verfuegbar.\n');
350
- process.exitCode = 1;
351
- return;
352
- }
353
- runtimeResult = undefined;
354
- }
355
- if (!runtimeResult?.acquired && !noticeResult.acquired) {
356
- noticeResult = await acquireNoticeLease();
357
- if (!noticeResult.acquired) {
358
- process.stderr.write('Der geschuetzte BLUN-Start ist gerade nicht verfuegbar.\n');
359
- process.exitCode = 1;
360
- return;
361
- }
362
- }
363
- }
364
- }
328
+ let noticeResult = await acquireNoticeLease();
329
+ let runtimeResult;
330
+ try {
331
+ const installClear = await installLeaseIsClear();
332
+ if (!installClear || !noticeResult.acquired) {
333
+ runtimeResult = await connectExistingRuntimeLease();
334
+ if (!runtimeResult.acquired && !installClear) {
335
+ if (!await installLeaseIsClear()) {
336
+ process.stderr.write('Der geschuetzte BLUN-Start ist gerade nicht verfuegbar.\n');
337
+ process.exitCode = 1;
338
+ return;
339
+ }
340
+ runtimeResult = undefined;
341
+ }
342
+ if (!runtimeResult?.acquired && !noticeResult.acquired) {
343
+ noticeResult = await acquireNoticeLease();
344
+ if (!noticeResult.acquired) {
345
+ process.stderr.write('Der geschuetzte BLUN-Start ist gerade nicht verfuegbar.\n');
346
+ process.exitCode = 1;
347
+ return;
348
+ }
349
+ }
350
+ }
365
351
  noticeResult.lease?.assertOwned();
366
352
  runtimeResult?.lease?.assertOwned();
367
353
  const { runLauncher } = require('./launcher-runtime');
368
354
  noticeResult.lease?.assertOwned();
369
355
  runtimeResult?.lease?.assertOwned();
370
356
  const filename = path.basename(__filename).toLowerCase();
371
- await runLauncher({
372
- mode: filename.startsWith('king') ? 'king' : 'blun',
373
- noticeLease: noticeResult.lease,
374
- runtimeLease: runtimeResult?.lease,
375
- skipUpdateNotice: runtimeResult?.acquired === true || !noticeResult.acquired,
376
- });
357
+ await runLauncher({
358
+ mode: filename.startsWith('king') ? 'king' : 'blun',
359
+ noticeLease: noticeResult.lease,
360
+ runtimeLease: runtimeResult?.lease,
361
+ });
377
362
  } finally {
378
363
  await runtimeResult?.lease?.release();
379
364
  await noticeResult.lease?.release();