@camstack/server 1.0.2 → 1.0.3

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 (39) hide show
  1. package/dist/api/addon-upload.js +17 -3
  2. package/dist/api/bridge-addons.router.js +1 -1
  3. package/dist/api/capabilities.router.js +3 -3
  4. package/dist/api/core/cap-providers.js +3 -3
  5. package/dist/api/core/logs.router.js +1 -1
  6. package/dist/api/core/notifications.router.js +1 -1
  7. package/dist/api/core/repl.router.js +1 -1
  8. package/dist/api/health/health.routes.js +7 -2
  9. package/dist/api/trpc/cap-route-error-formatter.js +3 -3
  10. package/dist/api/trpc/core-cap-bridge.js +2 -2
  11. package/dist/api/trpc/generated-cap-routers.js +4 -4
  12. package/dist/boot/boot-config.js +2 -2
  13. package/dist/boot/post-boot.service.js +2 -2
  14. package/dist/core/addon/addon-call-gateway.js +1 -1
  15. package/dist/core/addon/addon-package.service.js +37 -43
  16. package/dist/core/addon/addon-registry.service.js +61 -51
  17. package/dist/core/addon-bridge/addon-bridge.service.js +6 -6
  18. package/dist/core/addon-pages/addon-pages.service.js +1 -1
  19. package/dist/core/auth/auth.service.js +2 -2
  20. package/dist/core/config/config.schema.js +4 -4
  21. package/dist/core/config/config.service.js +2 -2
  22. package/dist/core/events/event-bus.service.js +2 -2
  23. package/dist/core/feature/feature.service.js +2 -2
  24. package/dist/core/lifecycle/lifecycle-state-machine.js +3 -3
  25. package/dist/core/logging/log-ring-buffer.js +3 -3
  26. package/dist/core/logging/logging.service.js +3 -3
  27. package/dist/core/logging/scoped-logger.js +3 -3
  28. package/dist/core/moleculer/cap-route-authority.js +2 -2
  29. package/dist/core/moleculer/moleculer.service.js +22 -22
  30. package/dist/core/network/network-quality.service.js +2 -2
  31. package/dist/core/notification/notification-wrapper.service.js +2 -2
  32. package/dist/core/notification/toast-wrapper.service.js +2 -2
  33. package/dist/core/repl/repl-engine.service.js +2 -2
  34. package/dist/core/storage/fs-storage-backend.js +3 -3
  35. package/dist/core/storage/storage-location-manager.js +3 -3
  36. package/dist/core/storage/storage.service.js +2 -2
  37. package/dist/launcher.js +18 -12
  38. package/dist/main.js +7 -4
  39. package/package.json +2 -3
@@ -38,11 +38,11 @@ exports.AddonRegistryService = void 0;
38
38
  const os = __importStar(require("node:os"));
39
39
  const addon_row_manifest_1 = require("./addon-row-manifest");
40
40
  const types_1 = require("@camstack/types");
41
- const kernel_1 = require("@camstack/kernel");
42
- const kernel_2 = require("@camstack/kernel");
41
+ const system_1 = require("@camstack/system");
42
+ const system_2 = require("@camstack/system");
43
43
  const client_1 = require("@trpc/client");
44
- const kernel_3 = require("@camstack/kernel");
45
- const core_1 = require("@camstack/core");
44
+ const system_3 = require("@camstack/system");
45
+ const system_4 = require("@camstack/system");
46
46
  const node_crypto_1 = require("node:crypto");
47
47
  const path = __importStar(require("node:path"));
48
48
  const fs = __importStar(require("node:fs"));
@@ -55,7 +55,7 @@ const types_3 = require("@camstack/types");
55
55
  * Type predicate: true when an `ISettingsBackend` also satisfies the
56
56
  * sync `ISettingsStore` contract (system/addon/device key-value ops)
57
57
  * that ConfigManager expects. The default `SqliteSettingsBackend` in
58
- * `@camstack/core` implements both surfaces; forked addon backends may
58
+ * `@camstack/system` implements both surfaces; forked addon backends may
59
59
  * not, in which case we skip the ConfigService wiring.
60
60
  */
61
61
  function isSettingsStore(backend) {
@@ -174,7 +174,7 @@ class AddonRegistryService {
174
174
  // Task 7.1: hub-wide registry of addon custom actions. Populated on
175
175
  // each addon's initialize() (in-process path); Task 7.2 will dispatch
176
176
  // through this from the `api.addons.custom` tRPC procedure.
177
- customActionRegistry = new kernel_1.CustomActionRegistry();
177
+ customActionRegistry = new system_1.CustomActionRegistry();
178
178
  /**
179
179
  * AddonIds whose group-runner disconnect is operator-initiated (update /
180
180
  * restart / uninstall). The Moleculer `$node.disconnected` handler skips
@@ -209,7 +209,7 @@ class AddonRegistryService {
209
209
  getByName: (capName) => reg.getSingleton(capName) ?? reg.getAllProviders(capName)[0] ?? null,
210
210
  };
211
211
  const client = (0, client_1.createTRPCClient)({
212
- links: [(0, kernel_2.localProviderLink)(resolver), (0, kernel_2.brokerTransportLink)(this.moleculer.broker)],
212
+ links: [(0, system_2.localProviderLink)(resolver), (0, system_2.brokerTransportLink)(this.moleculer.broker)],
213
213
  });
214
214
  this.brokerApi = client;
215
215
  }
@@ -225,7 +225,7 @@ class AddonRegistryService {
225
225
  integrationRegistry = null;
226
226
  // Device architecture — in-memory registry of live IDevice instances.
227
227
  // Persistence is owned by the `device-manager` capability addon.
228
- deviceRegistry = new kernel_1.DeviceRegistry();
228
+ deviceRegistry = new system_1.DeviceRegistry();
229
229
  /**
230
230
  * Typed accessor for the Moleculer broker. The Moleculer `index.d.ts`
231
231
  * chains through `eventemitter2`, whose package.json has no `types`
@@ -249,7 +249,7 @@ class AddonRegistryService {
249
249
  this.moleculer = moleculer;
250
250
  this.streamProbe = streamProbe;
251
251
  this.logger = this.loggingService.createLogger('AddonRegistry');
252
- this.addonLoader = new kernel_1.AddonLoader(this.loggingService.createLogger('AddonLoader'));
252
+ this.addonLoader = new system_1.AddonLoader(this.loggingService.createLogger('AddonLoader'));
253
253
  // Kernel-level addon health monitor — drives the 5-min boot grace
254
254
  // window + aggressive auto-retry loop (60s/120s/300s, never gives
255
255
  // up). Failures and recoveries are recorded by the load + init
@@ -257,13 +257,13 @@ class AddonRegistryService {
257
257
  // reattempt failed addons. Operator visibility comes through
258
258
  // AddonLoadFailed / AddonLoadRecovered events consumed by
259
259
  // AlertCenter (see addon-health-monitor.ts spec).
260
- this.healthMonitor = new kernel_1.AddonHealthMonitor({
260
+ this.healthMonitor = new system_1.AddonHealthMonitor({
261
261
  eventBus: this.eventBusService,
262
262
  logger: this.loggingService.createLogger('AddonHealthMonitor'),
263
263
  retryFn: (packageName) => this.tryReloadPackage(packageName),
264
264
  });
265
265
  // Create capability registry with config reader for singleton preferences
266
- this.capabilityRegistry = new kernel_1.CapabilityRegistry(this.loggingService.createLogger('CapabilityRegistry'), this.eventBusService);
266
+ this.capabilityRegistry = new system_1.CapabilityRegistry(this.loggingService.createLogger('CapabilityRegistry'), this.eventBusService);
267
267
  this.capabilityRegistry.setConfigReader((capability) => {
268
268
  try {
269
269
  return this.configService.get(`capabilities.singleton.${capability}`) ?? undefined;
@@ -386,9 +386,12 @@ class AddonRegistryService {
386
386
  return;
387
387
  this.capabilityRegistry.setSingletonActiveAddon(data.capName, data.addonId ?? null);
388
388
  });
389
- // 2. Load all addons from data/addons/ directory (including core builtins)
389
+ // 2. Load all addons from the addons directory (including core builtins).
390
+ // Honors CAMSTACK_ADDONS_DIR (a `node_modules`-shaped dir on Docker/Electron
391
+ // so forked ESM addon runners resolve @camstack/* via walk-up — see the
392
+ // launcher). Defaults to `<dataDir>/addons` for dev.
390
393
  const dataDir = path.resolve(process.env.CAMSTACK_DATA ?? 'camstack-data');
391
- const addonsDir = path.resolve(dataDir, 'addons');
394
+ const addonsDir = process.env.CAMSTACK_ADDONS_DIR ?? path.resolve(dataDir, 'addons');
392
395
  await this.addonLoader.loadFromDirectory(addonsDir);
393
396
  // Hand pre-init load failures (broken package.json, missing
394
397
  // dist, import-time errors) to the health monitor so its retry
@@ -447,7 +450,7 @@ class AddonRegistryService {
447
450
  });
448
451
  // Platform probing is no longer orchestrated by the backend. The
449
452
  // `platform-probe` capability (shipped as a core builtin under
450
- // `@camstack/core/dist/builtins/platform-probe/` since Phase B of
453
+ // `@camstack/system/dist/builtins/platform-probe/` since Phase B of
451
454
  // the bundles refactor) exposes hardware + scored backends via
452
455
  // `ctx.api.platformProbe.*`; inference addons auto-configure
453
456
  // inside their own `onInitialize`.
@@ -481,7 +484,7 @@ class AddonRegistryService {
481
484
  // genuinely has no cross-process provider and the fallback returns null — wrappers
482
485
  // cleanly fall through to their own secondary strategy.
483
486
  {
484
- const { buildNativeCapProxy } = await Promise.resolve().then(() => __importStar(require('@camstack/kernel')));
487
+ const { buildNativeCapProxy } = await Promise.resolve().then(() => __importStar(require('@camstack/system')));
485
488
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- moleculer types unresolvable; see `broker` getter docstring
486
489
  const broker = this.moleculer.broker;
487
490
  this.capabilityRegistry.setNativeFallback((capName, deviceId) => {
@@ -561,7 +564,7 @@ class AddonRegistryService {
561
564
  // one were declared — the mechanism stays available as an explicit
562
565
  // opt-in for future co-location needs.
563
566
  //
564
- // `@camstack/core` builtins and `placement: 'agent-only'` addons are
567
+ // `@camstack/system` builtins and `placement: 'agent-only'` addons are
565
568
  // excluded from the plan (filtered inside `buildAddonGroupPlan`).
566
569
  // A failed runner spawn is logged and the addon surfaces as
567
570
  // `addon.error` — there is NO in-process-on-the-hub fallback (it
@@ -590,7 +593,7 @@ class AddonRegistryService {
590
593
  }
591
594
  }
592
595
  }
593
- // In-process boot for `@camstack/core` builtins. Core builtins stay
596
+ // In-process boot for `@camstack/system` builtins. Core builtins stay
594
597
  // resident on the hub process — they provide the storage / settings
595
598
  // / logging infrastructure every forked runner depends on, reachable
596
599
  // via the hub broker, so `buildAddonGroupPlan` excludes them from
@@ -599,14 +602,14 @@ class AddonRegistryService {
599
602
  // storage→settings→logging), then the remaining builtins in
600
603
  // capability-dependency order.
601
604
  //
602
- // A core builtin is identified by `packageName === "@camstack/core"`,
605
+ // A core builtin is identified by `packageName === "@camstack/system"`,
603
606
  // NOT by the absence of an `execution` declaration — a builtin may
604
607
  // still declare `execution` (e.g. `platform-probe`); the package
605
608
  // boundary is the selection criterion.
606
- const isCoreBuiltin = (id) => this.addonEntries.get(id)?.packageName === '@camstack/core';
609
+ const isCoreBuiltin = (id) => this.addonEntries.get(id)?.packageName === '@camstack/system';
607
610
  // Pass 1 — infrastructure builtins. A failed REQUIRED infra cap
608
611
  // aborts boot: nothing downstream can run without storage/settings.
609
- for (const infra of kernel_1.INFRA_CAPABILITIES) {
612
+ for (const infra of system_1.INFRA_CAPABILITIES) {
610
613
  const addonId = this.findAddonForCapability(infra.name, allIds);
611
614
  if (addonId) {
612
615
  const entry = this.addonEntries.get(addonId);
@@ -642,7 +645,7 @@ class AddonRegistryService {
642
645
  }
643
646
  // Pass 2 — remaining core builtins, in capability-dependency order.
644
647
  const bootOrder = this.capabilityRegistry.getBootOrder();
645
- const infraNames = new Set(kernel_1.INFRA_CAPABILITIES.map((c) => c.name));
648
+ const infraNames = new Set(system_1.INFRA_CAPABILITIES.map((c) => c.name));
646
649
  for (const capName of bootOrder) {
647
650
  if (infraNames.has(capName))
648
651
  continue; // Handled in pass 1
@@ -783,7 +786,7 @@ class AddonRegistryService {
783
786
  */
784
787
  async tryReloadPackage(packageName) {
785
788
  const dataDir = path.resolve(process.env.CAMSTACK_DATA ?? 'camstack-data');
786
- const addonsDir = path.resolve(dataDir, 'addons');
789
+ const addonsDir = process.env.CAMSTACK_ADDONS_DIR ?? path.resolve(dataDir, 'addons');
787
790
  const addonDir = path.join(addonsDir, packageName);
788
791
  if (!fs.existsSync(addonDir)) {
789
792
  throw new Error(`Package directory missing: ${addonDir}`);
@@ -1055,10 +1058,10 @@ class AddonRegistryService {
1055
1058
  // subprocess. The runner-spawn pass during initial boot already
1056
1059
  // spawned every eligible addon; `initializeAddon` is the per-addon
1057
1060
  // entry point reached by the hot-load / restart flows (and by the
1058
- // Pass 1/2/3 in-process boot for `@camstack/core` builtins). Fork
1061
+ // Pass 1/2/3 in-process boot for `@camstack/system` builtins). Fork
1059
1062
  // only when the addon declares an `execution` block, ships an
1060
1063
  // on-disk `addonDir`, and is not `agent-only`; otherwise (only
1061
- // `@camstack/core` builtins reach the in-process path below) it
1064
+ // `@camstack/system` builtins reach the in-process path below) it
1062
1065
  // boots in-process on the hub.
1063
1066
  if (this.isForkedAddonEntry(entry)) {
1064
1067
  // D5: one-addon-one-process. A forked addon ALWAYS boots in its
@@ -1129,7 +1132,7 @@ class AddonRegistryService {
1129
1132
  // D4: wrapper behaviour is read from the cap DEFINITION. The runtime
1130
1133
  // ProviderRegistration.kind/defaultActive are deprecated hints — if an
1131
1134
  // addon still sets them and they disagree, warn (the cap def wins).
1132
- const kindDrift = (0, kernel_1.describeProviderKindDrift)(capName, reg.capability, {
1135
+ const kindDrift = (0, system_1.describeProviderKindDrift)(capName, reg.capability, {
1133
1136
  // eslint-disable-next-line @typescript-eslint/no-deprecated -- this IS the drift detector; it reads the deprecated hint on purpose
1134
1137
  kind: reg.kind,
1135
1138
  // eslint-disable-next-line @typescript-eslint/no-deprecated -- this IS the drift detector; it reads the deprecated hint on purpose
@@ -1181,7 +1184,7 @@ class AddonRegistryService {
1181
1184
  if (provider)
1182
1185
  capturedProviders.set(capName, provider);
1183
1186
  }
1184
- (0, kernel_1.validateProviderRegistrations)(id, entry.declaration, capturedProviders, this.logger);
1187
+ (0, system_1.validateProviderRegistrations)(id, entry.declaration, capturedProviders, this.logger);
1185
1188
  }
1186
1189
  await this.restoreAddonDevices(id, entry.addon);
1187
1190
  entry.initialized = true;
@@ -1196,7 +1199,7 @@ class AddonRegistryService {
1196
1199
  return Object.keys(def.methods);
1197
1200
  };
1198
1201
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- createAddonService return type unresolvable due to upstream eventemitter2/moleculer type chain
1199
- const schema = (0, kernel_1.createAddonService)(entry.addon, entry.declaration, {
1202
+ const schema = (0, system_1.createAddonService)(entry.addon, entry.declaration, {
1200
1203
  methodResolver,
1201
1204
  providers: capturedProviders,
1202
1205
  });
@@ -1380,7 +1383,7 @@ class AddonRegistryService {
1380
1383
  }
1381
1384
  // D5: a forked addon ALWAYS restarts via `$process.restart` above
1382
1385
  // (process restart — no in-process hot-reload of a live forked
1383
- // addon). This branch is reached only by `@camstack/core` builtins
1386
+ // addon). This branch is reached only by `@camstack/system` builtins
1384
1387
  // — they have no runner and legitimately reload in-process:
1385
1388
  // shutdown, unregister, re-initialize, re-wire.
1386
1389
  if (entry.initialized && entry.addon.shutdown) {
@@ -1469,7 +1472,7 @@ class AddonRegistryService {
1469
1472
  }
1470
1473
  findAddonDirOnDisk(addonId) {
1471
1474
  const dataDir = path.resolve(process.env.CAMSTACK_DATA ?? 'camstack-data');
1472
- const addonsDir = path.resolve(dataDir, 'addons');
1475
+ const addonsDir = process.env.CAMSTACK_ADDONS_DIR ?? path.resolve(dataDir, 'addons');
1473
1476
  if (!fs.existsSync(addonsDir))
1474
1477
  return null;
1475
1478
  const visit = (pkgDir) => {
@@ -1570,7 +1573,7 @@ class AddonRegistryService {
1570
1573
  * True when the entry boots in its own forked runner. This MUST mirror
1571
1574
  * the fork authority `buildAddonGroupPlan`, which spawns a runner for
1572
1575
  * every addon that ships an on-disk `addonDir` + a manifest
1573
- * `declaration`, is NOT a `@camstack/core` builtin, and is NOT
1576
+ * `declaration`, is NOT a `@camstack/system` builtin, and is NOT
1574
1577
  * `agent-only`. The `execution` block is OPTIONAL — an addon with no
1575
1578
  * `execution` declaration still forks on its own dedicated runner
1576
1579
  * (`resolveRunnerId` falls back to the addon id). Requiring `execution`
@@ -1579,13 +1582,13 @@ class AddonRegistryService {
1579
1582
  * in-process by this predicate, so its route-mount took the co-located
1580
1583
  * path and received the async UDS cap proxy whose `getRoutes()` returns
1581
1584
  * a Promise (→ `getRoutes(...).map is not a function`). Only
1582
- * `@camstack/core` builtins boot in-process on the hub. The type
1585
+ * `@camstack/system` builtins boot in-process on the hub. The type
1583
1586
  * predicate narrows both `addonDir` and `declaration` for callers.
1584
1587
  */
1585
1588
  isForkedAddonEntry(entry) {
1586
1589
  return !!(entry.declaration &&
1587
1590
  entry.addonDir &&
1588
- entry.packageName !== '@camstack/core' &&
1591
+ entry.packageName !== '@camstack/system' &&
1589
1592
  (0, types_1.resolveAddonPlacement)(entry.declaration) !== 'agent-only');
1590
1593
  }
1591
1594
  /** Per-entry helper used by `listAddons()` to mark a row removable / not. */
@@ -1675,7 +1678,7 @@ class AddonRegistryService {
1675
1678
  */
1676
1679
  scanFailedToLoadPackages(seenPackages) {
1677
1680
  const dataDir = path.resolve(process.env.CAMSTACK_DATA ?? 'camstack-data');
1678
- const addonsDir = path.resolve(dataDir, 'addons');
1681
+ const addonsDir = process.env.CAMSTACK_ADDONS_DIR ?? path.resolve(dataDir, 'addons');
1679
1682
  if (!fs.existsSync(addonsDir))
1680
1683
  return [];
1681
1684
  const out = [];
@@ -1791,7 +1794,7 @@ class AddonRegistryService {
1791
1794
  async listAddonProcesses() {
1792
1795
  const result = [];
1793
1796
  // Collect hub PID and fetch stats
1794
- const { getPidStats } = await Promise.resolve().then(() => __importStar(require('@camstack/core')));
1797
+ const { getPidStats } = await Promise.resolve().then(() => __importStar(require('@camstack/system')));
1795
1798
  const pidStats = await getPidStats([process.pid]);
1796
1799
  // In-process addons
1797
1800
  const hubStats = pidStats.get(process.pid);
@@ -1832,9 +1835,9 @@ class AddonRegistryService {
1832
1835
  */
1833
1836
  async loadNewAddons() {
1834
1837
  const dataDir = path.resolve(process.env.CAMSTACK_DATA ?? 'camstack-data');
1835
- const addonsDir = path.resolve(dataDir, 'addons');
1838
+ const addonsDir = process.env.CAMSTACK_ADDONS_DIR ?? path.resolve(dataDir, 'addons');
1836
1839
  // Create a fresh loader to discover what's on disk (for diffing against existing)
1837
- const freshLoader = new kernel_1.AddonLoader(this.loggingService.createLogger('AddonLoader'));
1840
+ const freshLoader = new system_1.AddonLoader(this.loggingService.createLogger('AddonLoader'));
1838
1841
  await freshLoader.loadFromDirectory(addonsDir);
1839
1842
  const loaded = [];
1840
1843
  const failed = [];
@@ -1916,7 +1919,7 @@ class AddonRegistryService {
1916
1919
  // D5: every non-core addon lives in its own runner subprocess. The
1917
1920
  // uninstall consolidation is "stop the runner"; the runner exits and
1918
1921
  // re-handshakes the hub WITHOUT the removed addon (D3 machinery).
1919
- // Only `@camstack/core` builtins — which have no runner — take the
1922
+ // Only `@camstack/system` builtins — which have no runner — take the
1920
1923
  // in-process `shutdown()` + disposer-drain path.
1921
1924
  const onDiskIds = new Set(freshLoader.listAddons().map((a) => a.declaration.id));
1922
1925
  for (const [id, entry] of this.addonEntries) {
@@ -1948,7 +1951,7 @@ class AddonRegistryService {
1948
1951
  }
1949
1952
  }
1950
1953
  else if (entry.initialized) {
1951
- // `@camstack/core` builtin — reload model is in-process.
1954
+ // `@camstack/system` builtin — reload model is in-process.
1952
1955
  try {
1953
1956
  await entry.addon.shutdown();
1954
1957
  }
@@ -2047,7 +2050,7 @@ class AddonRegistryService {
2047
2050
  this.configService.setSettingsStore(provider);
2048
2051
  }
2049
2052
  this.storageService.setSettingsBackend(provider);
2050
- this.integrationRegistry = new core_1.IntegrationRegistry(provider);
2053
+ this.integrationRegistry = new system_4.IntegrationRegistry(provider);
2051
2054
  void this.integrationRegistry.initialize().then(() => {
2052
2055
  this.logger.info('IntegrationRegistry initialized', { meta: { phase: 'v2' } });
2053
2056
  });
@@ -2129,7 +2132,7 @@ class AddonRegistryService {
2129
2132
  if (!routeProvider)
2130
2133
  return;
2131
2134
  // ── Forked addon: fetch handler-stripped routes over UDS (F3) ──────
2132
- // EVERY non-`@camstack/core` addon forks (the fork authority is
2135
+ // EVERY non-`@camstack/system` addon forks (the fork authority is
2133
2136
  // `buildAddonGroupPlan`, which does NOT require an `execution` block — an
2134
2137
  // addon like `auth-oidc` with no `execution` still runs in its own
2135
2138
  // runner). `isForkedAddonEntry` now mirrors that rule. For a forked addon
@@ -2163,7 +2166,7 @@ class AddonRegistryService {
2163
2166
  });
2164
2167
  return;
2165
2168
  }
2166
- // ── Co-located addon (`@camstack/core` builtin): live handlers, register
2169
+ // ── Co-located addon (`@camstack/system` builtin): live handlers, register
2167
2170
  // the provider directly. The route handlers run in-process against the
2168
2171
  // real Fastify reply, so no wire bridge is needed.
2169
2172
  addonRouteRegistry.registerRoutes(routeProvider.id, routeProvider);
@@ -2404,7 +2407,7 @@ class AddonRegistryService {
2404
2407
  probe: (url, options) => this.streamProbe.probe(url, options),
2405
2408
  probeField: (key, value) => this.streamProbe.probeField(key, value),
2406
2409
  };
2407
- const deviceManagerApi = (0, kernel_1.createBrokerDeviceManagerApi)({
2410
+ const deviceManagerApi = (0, system_1.createBrokerDeviceManagerApi)({
2408
2411
  api: this.getBrokerApi(),
2409
2412
  addonId,
2410
2413
  nodeId: this.broker.nodeID,
@@ -2418,11 +2421,11 @@ class AddonRegistryService {
2418
2421
  const rr = this.moleculer.readinessRegistry;
2419
2422
  const capHandleCache = new Map();
2420
2423
  function getOrCreateHandle(capName, scope, timeoutMs) {
2421
- const key = `${capName}::${(0, kernel_1.scopeKey)(scope)}`;
2424
+ const key = `${capName}::${(0, system_1.scopeKey)(scope)}`;
2422
2425
  const existing = capHandleCache.get(key);
2423
2426
  if (existing)
2424
2427
  return existing;
2425
- const handle = new kernel_1.CapabilityHandle(capName, scope, rr, timeoutMs);
2428
+ const handle = new system_1.CapabilityHandle(capName, scope, rr, timeoutMs);
2426
2429
  capHandleCache.set(key, handle);
2427
2430
  return handle;
2428
2431
  }
@@ -2455,15 +2458,15 @@ class AddonRegistryService {
2455
2458
  return registry.capabilityRegistry.getSingleton(capName) ?? undefined;
2456
2459
  },
2457
2460
  },
2458
- deps: new kernel_3.AddonDepsManager(dataDir, logger),
2461
+ deps: new system_3.AddonDepsManager(dataDir, logger),
2459
2462
  kernel: {
2460
2463
  localNodeId: this.broker.nodeID,
2461
2464
  storage: storageProvider ?? undefined,
2462
2465
  deviceRegistry: this.deviceRegistry ?? undefined,
2463
2466
  devices: deviceManagerApi,
2464
- cluster: { broker: (0, kernel_1.adaptBrokerToCluster)(this.moleculer.broker) },
2467
+ cluster: { broker: (0, system_1.adaptBrokerToCluster)(this.moleculer.broker) },
2465
2468
  streamProbe: kernelStreamProbe,
2466
- hwaccel: (0, kernel_1.createKernelHwAccel)(),
2469
+ hwaccel: (0, system_1.createKernelHwAccel)(),
2467
2470
  capabilityRegistry: this.capabilityRegistry,
2468
2471
  // Per-addon storage-location declarations across every installed
2469
2472
  // addon — surfaced from the kernel's AddonLoader so the
@@ -2567,7 +2570,7 @@ class AddonRegistryService {
2567
2570
  * passes a live JS reference across a process boundary any more.
2568
2571
  *
2569
2572
  * Addons with `placement: 'agent-only'` are dropped (they don't run on
2570
- * the hub). `@camstack/core` builtins are dropped too — they stay
2573
+ * the hub). `@camstack/system` builtins are dropped too — they stay
2571
2574
  * in-process on the hub (every forked runner connects to the hub
2572
2575
  * broker via static-URL TCP transit, so cap providers hosted on the
2573
2576
  * hub broker are reachable from any runner with one hop; moving them
@@ -2583,7 +2586,7 @@ class AddonRegistryService {
2583
2586
  const entry = this.addonEntries.get(id);
2584
2587
  if (!entry?.declaration || !entry.addonDir)
2585
2588
  continue;
2586
- if (entry.packageName === '@camstack/core')
2589
+ if (entry.packageName === '@camstack/system')
2587
2590
  continue;
2588
2591
  const placement = (0, types_1.resolveAddonPlacement)(entry.declaration);
2589
2592
  if (placement === 'agent-only')
@@ -2631,7 +2634,7 @@ class AddonRegistryService {
2631
2634
  for (const { addonId } of addons) {
2632
2635
  await this.registerForkedAddonCustomActions(addonId, runnerId);
2633
2636
  // Mark the entry initialized so the in-process core-builtin boot
2634
- // passes skip it (those passes only touch `@camstack/core`).
2637
+ // passes skip it (those passes only touch `@camstack/system`).
2635
2638
  const entry = this.addonEntries.get(addonId);
2636
2639
  if (entry) {
2637
2640
  entry.initialized = true;
@@ -2701,7 +2704,14 @@ class AddonRegistryService {
2701
2704
  // Cache-bust so a hot-updated bundle is re-read instead of served
2702
2705
  // from Node's ESM module cache.
2703
2706
  const cacheBustedUrl = `${(0, node_url_1.pathToFileURL)(entryPath).href}?t=${Date.now()}`;
2704
- const modUnknown = await Promise.resolve(`${cacheBustedUrl}`).then(s => __importStar(require(s)));
2707
+ // A plain `await import()` here is downleveled by tsc (the backend builds
2708
+ // with `module: CommonJS`) into a `require()`-based shim. `require()` then
2709
+ // treats the `?t=…` cache-bust query as part of the literal filename and
2710
+ // throws MODULE_NOT_FOUND for EVERY forked addon — so no forked addon's
2711
+ // custom-action catalog ever loaded. Use a native dynamic import the
2712
+ // compiler won't rewrite, so Node's ESM loader handles the query string.
2713
+ const nativeImport = new Function('specifier', 'return import(specifier)');
2714
+ const modUnknown = await nativeImport(cacheBustedUrl);
2705
2715
  catalog =
2706
2716
  modUnknown && typeof modUnknown === 'object'
2707
2717
  ? modUnknown['customActions']
@@ -69,9 +69,9 @@ class AddonBridgeService {
69
69
  // Initialize installer eagerly in constructor (no async needed).
70
70
  // This ensures install/uninstall works even before onModuleInit completes.
71
71
  try {
72
- const kernel = require('@camstack/kernel');
72
+ const kernel = require('@camstack/system');
73
73
  const dataDir = process.env.CAMSTACK_DATA ?? 'camstack-data';
74
- const addonsDir = path.resolve(dataDir, 'addons');
74
+ const addonsDir = process.env.CAMSTACK_ADDONS_DIR ?? path.resolve(dataDir, 'addons');
75
75
  const workspacePackagesDir = kernel.detectWorkspacePackagesDir(__dirname);
76
76
  this.installer = new kernel.AddonInstaller({
77
77
  addonsDir,
@@ -87,10 +87,10 @@ class AddonBridgeService {
87
87
  async onModuleInit() {
88
88
  this.logger.info('Initializing addon bridge (package management only)...');
89
89
  try {
90
- const kernel = await Promise.resolve().then(() => __importStar(require('@camstack/kernel')));
90
+ const kernel = await Promise.resolve().then(() => __importStar(require('@camstack/system')));
91
91
  this.loader = new kernel.AddonLoader(this.logger.child('AddonLoader'));
92
92
  const dataDir = process.env.CAMSTACK_DATA ?? 'camstack-data';
93
- const addonsDir = path.resolve(dataDir, 'addons');
93
+ const addonsDir = process.env.CAMSTACK_ADDONS_DIR ?? path.resolve(dataDir, 'addons');
94
94
  await this.loader.loadFromDirectory(addonsDir);
95
95
  this.available = true;
96
96
  this.logger.info('Addon bridge initialized', {
@@ -134,10 +134,10 @@ class AddonBridgeService {
134
134
  this.logger.warn('reloadPackages called but bridge is unavailable — skipping');
135
135
  return;
136
136
  }
137
- const kernel = await Promise.resolve().then(() => __importStar(require('@camstack/kernel')));
137
+ const kernel = await Promise.resolve().then(() => __importStar(require('@camstack/system')));
138
138
  this.loader = new kernel.AddonLoader(this.logger.child('AddonLoader'));
139
139
  const dataDir = process.env.CAMSTACK_DATA ?? 'camstack-data';
140
- const addonsDir = path.resolve(dataDir, 'addons');
140
+ const addonsDir = process.env.CAMSTACK_ADDONS_DIR ?? path.resolve(dataDir, 'addons');
141
141
  await this.loader.loadFromDirectory(addonsDir);
142
142
  this.logger.info('Reloaded', { meta: { count: this.loader.listAddons().length } });
143
143
  }
@@ -42,7 +42,7 @@ const fs = __importStar(require("node:fs"));
42
42
  *
43
43
  * The public listing surface (`addonPages.listPages` on the AppRouter)
44
44
  * has been split out of this class — it now lives in the
45
- * `addon-pages-aggregator` builtin (`@camstack/core/builtins/...`)
45
+ * `addon-pages-aggregator` builtin (`@camstack/system/builtins/...`)
46
46
  * which walks every `addon-pages-source` collection provider and
47
47
  * stamps versioned `bundleUrl`s. The split lets both ends flow through
48
48
  * codegen instead of relying on a hand-written wrapper.
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.AuthService = void 0;
4
- const core_1 = require("@camstack/core");
5
- class AuthService extends core_1.AuthManager {
4
+ const system_1 = require("@camstack/system");
5
+ class AuthService extends system_1.AuthManager {
6
6
  constructor(config) {
7
7
  super(config);
8
8
  }
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RUNTIME_DEFAULTS = exports.bootstrapSchema = void 0;
4
- // Re-export from @camstack/kernel
5
- var kernel_1 = require("@camstack/kernel");
6
- Object.defineProperty(exports, "bootstrapSchema", { enumerable: true, get: function () { return kernel_1.bootstrapSchema; } });
7
- Object.defineProperty(exports, "RUNTIME_DEFAULTS", { enumerable: true, get: function () { return kernel_1.RUNTIME_DEFAULTS; } });
4
+ // Re-export from @camstack/system
5
+ var system_1 = require("@camstack/system");
6
+ Object.defineProperty(exports, "bootstrapSchema", { enumerable: true, get: function () { return system_1.bootstrapSchema; } });
7
+ Object.defineProperty(exports, "RUNTIME_DEFAULTS", { enumerable: true, get: function () { return system_1.RUNTIME_DEFAULTS; } });
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ConfigService = void 0;
4
- const kernel_1 = require("@camstack/kernel");
5
- class ConfigService extends kernel_1.ConfigManager {
4
+ const system_1 = require("@camstack/system");
5
+ class ConfigService extends system_1.ConfigManager {
6
6
  constructor(configPath) {
7
7
  super(configPath);
8
8
  }
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.EventBusService = void 0;
4
- const kernel_1 = require("@camstack/kernel");
4
+ const system_1 = require("@camstack/system");
5
5
  /**
6
6
  * Hub-side event bus. Pre-broker boot the service buffers nothing —
7
7
  * subscribers / emits are no-ops until `attachBroker` lands the
@@ -36,7 +36,7 @@ class EventBusService {
36
36
  if (this.broker === broker)
37
37
  return;
38
38
  this.broker = broker;
39
- const inner = (0, kernel_1.getBrokerEventBus)(broker);
39
+ const inner = (0, system_1.getBrokerEventBus)(broker);
40
40
  this.inner = inner;
41
41
  // Replay deferred subscriptions onto the real bus.
42
42
  for (const sub of this.deferredSubs) {
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.FeatureService = void 0;
4
- const core_1 = require("@camstack/core");
5
- class FeatureService extends core_1.FeatureManager {
4
+ const system_1 = require("@camstack/system");
5
+ class FeatureService extends system_1.FeatureManager {
6
6
  constructor(configService) {
7
7
  super(configService);
8
8
  }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.LifecycleStateMachine = void 0;
4
- // Re-export from @camstack/core — LifecycleStateMachine is already a plain class
5
- var core_1 = require("@camstack/core");
6
- Object.defineProperty(exports, "LifecycleStateMachine", { enumerable: true, get: function () { return core_1.LifecycleStateMachine; } });
4
+ // Re-export from @camstack/system — LifecycleStateMachine is already a plain class
5
+ var system_1 = require("@camstack/system");
6
+ Object.defineProperty(exports, "LifecycleStateMachine", { enumerable: true, get: function () { return system_1.LifecycleStateMachine; } });
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.LogRingBuffer = void 0;
4
- // Re-export from @camstack/core
5
- var core_1 = require("@camstack/core");
6
- Object.defineProperty(exports, "LogRingBuffer", { enumerable: true, get: function () { return core_1.LogRingBuffer; } });
4
+ // Re-export from @camstack/system
5
+ var system_1 = require("@camstack/system");
6
+ Object.defineProperty(exports, "LogRingBuffer", { enumerable: true, get: function () { return system_1.LogRingBuffer; } });
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.LoggingService = void 0;
4
- const core_1 = require("@camstack/core");
4
+ const system_1 = require("@camstack/system");
5
5
  const types_1 = require("@camstack/types");
6
6
  /** Baseline tags every hub-local logger gets, so console output never
7
7
  * falls back to `?` for the agent slot. Hub-local addons already
@@ -13,7 +13,7 @@ const types_1 = require("@camstack/types");
13
13
  * forked workers via `$hub.log` carry their own `tags.pid` which
14
14
  * wins over this baseline (right-biased merge in `writeFromWorker`). */
15
15
  const HUB_BASELINE_TAGS = { agentId: 'hub', nodeId: 'hub', pid: process.pid };
16
- class LoggingService extends core_1.LogManager {
16
+ class LoggingService extends system_1.LogManager {
17
17
  /**
18
18
  * Device-name cache consulted by the formatter when a log line
19
19
  * carries `tags.deviceId` but no explicit `deviceName`. Populated
@@ -31,7 +31,7 @@ class LoggingService extends core_1.LogManager {
31
31
  super(perAddonCapacity);
32
32
  // Enriches every emitted LogEntry with `tags.deviceName` before
33
33
  // destinations / subscribers see it — works across bundled copies
34
- // of `@camstack/core` (addon packages) because the mutation
34
+ // of `@camstack/system` (addon packages) because the mutation
35
35
  // happens upstream of their formatters.
36
36
  this.setDeviceNameLookup((id) => this.deviceNames.get(id) ?? null);
37
37
  }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ScopedLogger = void 0;
4
- // Re-export from @camstack/core
5
- var core_1 = require("@camstack/core");
6
- Object.defineProperty(exports, "ScopedLogger", { enumerable: true, get: function () { return core_1.ScopedLogger; } });
4
+ // Re-export from @camstack/system
5
+ var system_1 = require("@camstack/system");
6
+ Object.defineProperty(exports, "ScopedLogger", { enumerable: true, get: function () { return system_1.ScopedLogger; } });
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
2
  /**
3
3
  * Adapter factories that bridge the server-side registry/service state into the
4
- * narrow interfaces that CapRouteResolver (in @camstack/kernel) requires.
4
+ * narrow interfaces that CapRouteResolver (in @camstack/system) requires.
5
5
  *
6
6
  * Layer note: this file is in server/backend and may import server-side types.
7
- * The resolver itself (in @camstack/kernel) must NOT import from here —
7
+ * The resolver itself (in @camstack/system) must NOT import from here —
8
8
  * it depends only on the narrow interfaces (NodeCapAuthority, InProcessProviderLookup)
9
9
  * defined in the kernel. These factories are the wiring adapters.
10
10
  *