@camstack/server 1.2.34 → 1.2.36

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.
@@ -2261,11 +2261,41 @@ class AddonRegistryService {
2261
2261
  if (!provider)
2262
2262
  return;
2263
2263
  this.activeSettingsBackend = provider;
2264
- if (isSettingsStore(provider)) {
2265
- this.configService.setSettingsStore(provider);
2264
+ // ConfigManager needs the SYNC legacy surface (`getAllAddon`,
2265
+ // `setAddonDevice`, …), which is not part of the cap. Since D44 the
2266
+ // `settings-store` provider is the storage-orchestrator's
2267
+ // DISPATCHER, and a dispatcher has none of those methods — so this
2268
+ // predicate started returning false and ConfigManager was left
2269
+ // without a store. Nothing said so: `readAddonStore()` then answered
2270
+ // `{}` for every addon, device-manager restored ZERO devices, and no
2271
+ // camera published a stream. Fall back to the ENGINE behind the door
2272
+ // (`data-store-provider` — the SQLite backend does implement both
2273
+ // surfaces), the same move `storage-orchestrator` makes for its
2274
+ // location store. And if neither can serve it, SAY SO: this is the
2275
+ // branch whose silence cost an evening.
2276
+ const syncStore = isSettingsStore(provider)
2277
+ ? provider
2278
+ : this.capabilityRegistry
2279
+ .getCollection('data-store-provider')
2280
+ .find((engine) => isSettingsStore(engine));
2281
+ if (syncStore) {
2282
+ this.configService.setSettingsStore(syncStore);
2283
+ }
2284
+ else {
2285
+ this.logger.error('settings-store provider does not implement the sync ConfigManager surface and no data-store-provider engine does either — every addon store reads empty, devices will NOT be restored', { meta: { addonId, phase: 'v2' } });
2266
2286
  }
2267
2287
  this.storageService.setSettingsBackend(provider);
2268
- this.integrationRegistry = new system_4.IntegrationRegistry(provider);
2288
+ // The registry needs the DOOR's own shape, not `ISettingsBackend`.
2289
+ // `CapabilityProviderMap` still types this cap as the hand-written
2290
+ // interface, which has drifted from the cap definition it is meant
2291
+ // to describe — it never grew `deleteWhere` / `updateWhere`. The
2292
+ // same provider object satisfies both; reconciling the two types is
2293
+ // its own change (it makes `query` / `insert` non-generic for every
2294
+ // `ISettingsBackend` consumer in the backend).
2295
+ const store = this.capabilityRegistry.getProviderByAddon('settings-store', addonId);
2296
+ if (!store)
2297
+ return;
2298
+ this.integrationRegistry = new system_4.IntegrationRegistry(store);
2269
2299
  void this.integrationRegistry.initialize().then(() => {
2270
2300
  this.logger.info('IntegrationRegistry initialized', { meta: { phase: 'v2' } });
2271
2301
  });
package/dist/launcher.js CHANGED
@@ -413,6 +413,28 @@ async function launch() {
413
413
  Module._initPaths();
414
414
  console.log(`[launcher] NODE_PATH extended with: ${extraNodePaths.join(sep)}`);
415
415
  }
416
+ // WHICH COPY did this node just commit to? ([D45](../../../docs/decisions/adr-0045.md))
417
+ //
418
+ // A node can hold several copies of a host-provided package — the image seed
419
+ // under /opt, a legacy /data/framework on NODE_PATH, the active closure, an
420
+ // installed copy under /data/addons. Which one wins is a resolution outcome,
421
+ // and on 2026-08-03 three consecutive deductions about it were each disproved
422
+ // by the next measurement, while every status surface reported the version of
423
+ // a copy nobody was running. Resolution happens HERE, right after NODE_PATH
424
+ // is final and before the runtime imports anything — so this is the one place
425
+ // that can answer it, and it costs a stat call per package.
426
+ //
427
+ // A version number without a path is not evidence. Log both.
428
+ for (const pkg of ['@camstack/system', '@camstack/types']) {
429
+ try {
430
+ const resolved = require.resolve(`${pkg}/package.json`);
431
+ const version = JSON.parse(fs.readFileSync(resolved, 'utf-8')).version;
432
+ console.log(`[launcher] resolved ${pkg}@${String(version)} from ${resolved}`);
433
+ }
434
+ catch (err) {
435
+ console.warn(`[launcher] could NOT resolve ${pkg}: ${err instanceof Error ? err.message : String(err)}`);
436
+ }
437
+ }
416
438
  // Now safe to load the role's runtime entry (both have static imports from
417
439
  // @camstack/system, resolved only after the framework dir + NODE_PATH setup
418
440
  // above). The agent boots from THIS same @camstack/server closure — there is
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/server",
3
- "version": "1.2.34",
3
+ "version": "1.2.36",
4
4
  "private": false,
5
5
  "files": [
6
6
  "dist",
@@ -40,11 +40,11 @@
40
40
  "@camstack/addon-notifiers": "1.2.11",
41
41
  "@camstack/addon-pipeline": "1.2.39",
42
42
  "@camstack/addon-pipeline-orchestrator": "1.2.19",
43
- "@camstack/addon-post-analysis": "1.2.23",
43
+ "@camstack/addon-post-analysis": "1.2.24",
44
44
  "@camstack/sdk": "1.2.9",
45
45
  "@camstack/shm-ring": "1.1.9",
46
- "@camstack/system": "1.2.30",
47
- "@camstack/types": "1.2.22",
46
+ "@camstack/system": "1.2.31",
47
+ "@camstack/types": "1.2.23",
48
48
  "@camstack/ui-library": "1.2.18",
49
49
  "@fastify/compress": "^9.0.0",
50
50
  "@fastify/cookie": "^11.0.2",