@camstack/system 1.2.29 → 1.2.30

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 (48) hide show
  1. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
  2. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
  3. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
  4. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
  5. package/dist/builtins/alerts/alerts.addon.js +1 -1
  6. package/dist/builtins/alerts/alerts.addon.mjs +1 -1
  7. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +1 -1
  8. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +1 -1
  9. package/dist/builtins/console-logging/index.js +1 -1
  10. package/dist/builtins/console-logging/index.mjs +1 -1
  11. package/dist/builtins/device-manager/device-manager.addon.js +1 -1
  12. package/dist/builtins/device-manager/device-manager.addon.mjs +1 -1
  13. package/dist/builtins/doorbell/virtual-doorbell.addon.js +1 -1
  14. package/dist/builtins/doorbell/virtual-doorbell.addon.mjs +1 -1
  15. package/dist/builtins/hub-forwarder/index.js +1 -1
  16. package/dist/builtins/hub-forwarder/index.mjs +1 -1
  17. package/dist/builtins/local-auth/local-auth.addon.js +1 -1
  18. package/dist/builtins/local-auth/local-auth.addon.mjs +1 -1
  19. package/dist/builtins/local-network/local-network.addon.js +1 -1
  20. package/dist/builtins/local-network/local-network.addon.mjs +1 -1
  21. package/dist/builtins/loki-logging/index.js +1 -1
  22. package/dist/builtins/loki-logging/index.mjs +1 -1
  23. package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
  24. package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
  25. package/dist/builtins/platform-probe/index.js +1 -1
  26. package/dist/builtins/platform-probe/index.mjs +1 -1
  27. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
  28. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
  29. package/dist/builtins/snapshot/index.js +1 -1
  30. package/dist/builtins/snapshot/index.mjs +1 -1
  31. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
  32. package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
  33. package/dist/builtins/sqlite-storage/filter-compiler.d.ts +61 -0
  34. package/dist/builtins/sqlite-storage/sqlite-settings-backend.d.ts +43 -0
  35. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +115 -61
  36. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +115 -61
  37. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +3 -1
  38. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +3 -1
  39. package/dist/builtins/system-config/system-config.addon.js +1 -1
  40. package/dist/builtins/system-config/system-config.addon.mjs +1 -1
  41. package/dist/builtins/winston-logging/index.js +1 -1
  42. package/dist/builtins/winston-logging/index.mjs +1 -1
  43. package/dist/{dist-B7hOpr5i.mjs → dist-Dr_P0DOB.mjs} +81 -0
  44. package/dist/{dist-CPmFYLqq.js → dist-VIwdvws5.js} +81 -0
  45. package/dist/index.js +45 -1
  46. package/dist/index.mjs +45 -1
  47. package/dist/kernel/addon-installer.d.ts +38 -0
  48. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { a as __toCommonJS, i as __require, n as __esmMin, o as __toESM$1, r as __exportAll, t as __commonJSMin$1 } from "./chunk-CNf5ZN-e.mjs";
2
- import { A as extractNestedAddonId, At as scopeKey, Dt as parseJsonUnknown$1, Et as parseJsonObject, F as isObjectInput, G as objectInputDeclaresAddonId, H as looseSchema, I as isVoidInput, J as procedureAuthKey, L as kebabToCamel, Mt as EventCategory$1, N as isArrayOutputSchema, Ot as readinessKey, P as isCollectionArrayMethod, R as lifecycleJobSchema, St as expandCapMethods, V as logLevelAtMost, _t as asNumber, at as errMsg$1, bt as emitDownForOwnedCaps, c as RUNTIME_DEFAULTS, ct as DEVICE_SETTINGS_CONTRIBUTION_METHODS, gt as asJsonObject$1, kt as resolveCapMount, lt as DEVICE_STATUS_METHOD, m as addonSettingsCapability, mt as ReadinessTimeoutError, pt as ReadinessRegistry, s as METHOD_ACCESS_MAP, st as DATAPLANE_SECRET_HEADER$1, t as ALL_CAPABILITY_DEFINITIONS, vt as asString$1, yt as createEvent } from "./dist-B7hOpr5i.mjs";
2
+ import { A as extractNestedAddonId, At as scopeKey, Dt as parseJsonUnknown$1, Et as parseJsonObject, F as isObjectInput, G as objectInputDeclaresAddonId, H as looseSchema, I as isVoidInput, J as procedureAuthKey, L as kebabToCamel, Mt as EventCategory$1, N as isArrayOutputSchema, Ot as readinessKey, P as isCollectionArrayMethod, R as lifecycleJobSchema, St as expandCapMethods, V as logLevelAtMost, _t as asNumber, at as errMsg$1, bt as emitDownForOwnedCaps, c as RUNTIME_DEFAULTS, ct as DEVICE_SETTINGS_CONTRIBUTION_METHODS, gt as asJsonObject$1, kt as resolveCapMount, lt as DEVICE_STATUS_METHOD, m as addonSettingsCapability, mt as ReadinessTimeoutError, pt as ReadinessRegistry, s as METHOD_ACCESS_MAP, st as DATAPLANE_SECRET_HEADER$1, t as ALL_CAPABILITY_DEFINITIONS, vt as asString$1, yt as createEvent } from "./dist-Dr_P0DOB.mjs";
3
3
  import { a as downloadModel, c as getModelFilePath, d as contentTypeFor, f as createAuthenticatedFileServer, h as resolveFilePath, i as downloadFile, l as isModelDownloaded, m as parseTokenizedUrl, n as collectModelFiles, o as ensureModel, p as parseRangeHeader, r as deleteModelFromDisk, s as fetchJson, t as ModelDownloadService, u as createFileDataPlaneHandler } from "./model-download-service-Cp9f4dk6.mjs";
4
4
  import { $ as buildNativeCapProxy, A as createHubCapForwardService, B as AGENT_CAP_FWD_ACTION, C as brokerTransportLink, Ct as resolveAddonClass, D as localProviderLink, E as ipcParentLink, F as createUdsLogger, G as callWithServiceDiscovery, H as CapRouteResolver, I as createUdsLoggerWithControl, J as UdsLocalTransportServer, K as createLocalTransport, L as LocalChildClient, M as createUdsEventBridge, N as createUdsEventBus, O as HUB_CAP_FWD_ACTION, P as udsChildLogToWorkerEntry, Q as encodeFrame, R as LocalChildRegistry, S as brokerCallForCap, St as runNpm, T as ipcChildLink, U as CapRouteError, V as AGENT_CAP_FWD_SERVICE, W as classifyCapRoute, X as localEndpointPath, Y as SocketChannel, Z as FrameDecoder, _ as createKernelHwAccel, _t as CapabilityHandle, a as getWorkerDeviceRegistry, b as __resetCapUsageRegistryForTests, bt as installManifestNativeDeps, c as setHubConnected, ct as NATIVE_PROVIDER_SERVICE_INFIX, d as getBrokerEventBus, dt as capBareAction, et as buildUdsNativeCapProxy, f as getMoleculerEventStats, ft as capServiceName, g as AddonDepsManager, gt as DeviceRegistry, h as subscribePassthrough, ht as serializeTypedArrays, i as createUdsAddonContext, it as mountNativeCapService, j as createParentUnownedCallHandler, k as HUB_CAP_FWD_SERVICE, l as EVENT_TOPIC_PREFIX, lt as capActionName, m as setNodeEventInterest, mt as deserializeTypedArrays, n as adaptBrokerToCluster, o as getOrInitReadinessRegistry, ot as createAddonService, p as registerEventBusService, pt as parseCapAction, q as UdsLocalTransportClient, r as createAddonContext, s as getOrInitReadinessRegistryForClient, st as validateProviderRegistrations, t as installManifestPythonDeps, tt as createBrokerDeviceManagerApi, u as clusterEventTopic, ut as capActionSuffix, v as resolveHwAccel, vt as CapabilityUnavailableError, w as buildLinkChain, wt as createAddonDataPlaneFacility, x as getCapUsageRegistry, xt as resolveNpmInvocation, y as CapUsageRegistry, yt as copyBundledNativeModules, z as UDS_NO_ROUTE_PREFIX } from "./manifest-python-deps-Ck4-9K9m.mjs";
5
5
  import { n as getSinglePidStats, t as getPidStats } from "./resource-monitor-BkP504Vq.mjs";
@@ -3566,6 +3566,25 @@ function readPackageJson(pkgJsonPath) {
3566
3566
  camstackAddons: Array.isArray(addonsField) ? addonsField : null
3567
3567
  };
3568
3568
  }
3569
+ /**
3570
+ * Should the bootstrap SKIP seeding `packageName` into /data/addons?
3571
+ *
3572
+ * True only for the package the closure provides, and only when it actually
3573
+ * resolves. Both halves are load-bearing:
3574
+ *
3575
+ * - seeding a copy the closure already provides creates one that WINS over
3576
+ * the closure and is never refreshed (bootstrap is seed-only, and
3577
+ * `camstack deploy` of a framework package is rejected on an image hub), so
3578
+ * the node runs first-boot builtins forever while reporting the new
3579
+ * version;
3580
+ * - skipping it when it does NOT resolve is how a fresh deployment was once
3581
+ * made unbootable ("No addon provides required infrastructure capability
3582
+ * storage-provider"). That is why the guard is resolvability rather than a
3583
+ * blanket removal from the bootstrap list.
3584
+ */
3585
+ function shouldSkipClosureProvidedSeed(packageName, isResolvable) {
3586
+ return packageName === "@camstack/system" && isResolvable;
3587
+ }
3569
3588
  /** Minimal no-op logger for default parameter */
3570
3589
  var noopLogger = {
3571
3590
  debug() {},
@@ -3585,6 +3604,7 @@ var AddonInstaller = class AddonInstaller {
3585
3604
  workspaceDir;
3586
3605
  installSource;
3587
3606
  logger;
3607
+ isPackageResolvable;
3588
3608
  /**
3589
3609
  * Central manifest of installed addons. Tracks version + source +
3590
3610
  * timestamps + last-backup pointer per package, written atomically
@@ -3600,6 +3620,7 @@ var AddonInstaller = class AddonInstaller {
3600
3620
  this.workspaceDir = config.workspacePackagesDir;
3601
3621
  this.logger = logger;
3602
3622
  this.manifest = new AddonManifest(config.addonsDir);
3623
+ this.isPackageResolvable = config.isPackageResolvable;
3603
3624
  if (config.installSource) this.installSource = config.installSource;
3604
3625
  else this.installSource = "npm";
3605
3626
  }
@@ -3628,6 +3649,25 @@ var AddonInstaller = class AddonInstaller {
3628
3649
  * hardcoded lists — see design spec
3629
3650
  * docs/superpowers/specs/2026-05-20-docker-install-from-npm-design.md.
3630
3651
  */
3652
+ /**
3653
+ * Is `packageName` reachable through normal resolution — i.e. does the
3654
+ * running closure already provide it?
3655
+ *
3656
+ * Overridable via `AddonInstallerConfig.isPackageResolvable` so a spec can
3657
+ * exercise BOTH sides. That matters more than it looks: the branch that
3658
+ * still seeds is the one protecting a fresh deployment from an unbootable
3659
+ * node, and it is unreachable in a test process where `@camstack/system`
3660
+ * always resolves.
3661
+ */
3662
+ isResolvableFromClosure(packageName) {
3663
+ if (this.isPackageResolvable) return this.isPackageResolvable(packageName);
3664
+ try {
3665
+ __require.resolve(`${packageName}/package.json`);
3666
+ return true;
3667
+ } catch {
3668
+ return false;
3669
+ }
3670
+ }
3631
3671
  static deriveBootstrapList(metaPackageName) {
3632
3672
  const pkgJsonId = `${metaPackageName}/package.json`;
3633
3673
  let pkgPath;
@@ -3710,6 +3750,10 @@ var AddonInstaller = class AddonInstaller {
3710
3750
  this.logger.debug(`${packageName} — already installed, skipping`);
3711
3751
  continue;
3712
3752
  }
3753
+ if (shouldSkipClosureProvidedSeed(packageName, this.isResolvableFromClosure(packageName))) {
3754
+ this.logger.info(`${packageName} — provided by the server closure, not seeding a copy that would shadow it`);
3755
+ continue;
3756
+ }
3713
3757
  try {
3714
3758
  if (isLocal) {
3715
3759
  const pkgDir = this.findLocalPackage(packageName);
@@ -22,6 +22,25 @@ import { AddonManifest } from './addon-manifest.js';
22
22
  * `addonsDir/<pkg>` → `packages/<pkg>`.
23
23
  */
24
24
  export type InstallSource = 'npm' | 'local' | 'symlink';
25
+ /** The one bootstrap package the server closure carries itself. */
26
+ export declare const CLOSURE_PROVIDED_PACKAGE = "@camstack/system";
27
+ /**
28
+ * Should the bootstrap SKIP seeding `packageName` into /data/addons?
29
+ *
30
+ * True only for the package the closure provides, and only when it actually
31
+ * resolves. Both halves are load-bearing:
32
+ *
33
+ * - seeding a copy the closure already provides creates one that WINS over
34
+ * the closure and is never refreshed (bootstrap is seed-only, and
35
+ * `camstack deploy` of a framework package is rejected on an image hub), so
36
+ * the node runs first-boot builtins forever while reporting the new
37
+ * version;
38
+ * - skipping it when it does NOT resolve is how a fresh deployment was once
39
+ * made unbootable ("No addon provides required infrastructure capability
40
+ * storage-provider"). That is why the guard is resolvability rather than a
41
+ * blanket removal from the bootstrap list.
42
+ */
43
+ export declare function shouldSkipClosureProvidedSeed(packageName: string, isResolvable: boolean): boolean;
25
44
  export interface AddonInstallerConfig {
26
45
  /** Directory where addons are stored (e.g., {dataDir}/addons) */
27
46
  readonly addonsDir: string;
@@ -31,6 +50,13 @@ export interface AddonInstallerConfig {
31
50
  readonly workspacePackagesDir?: string;
32
51
  /** Install source mode. Default: auto-detect */
33
52
  readonly installSource?: InstallSource;
53
+ /**
54
+ * Override for "does the running closure already provide this package?".
55
+ * Production leaves it unset (real `require.resolve`); a spec sets it to
56
+ * reach the branch that still seeds `@camstack/system`, which is otherwise
57
+ * unreachable in a process where that package always resolves.
58
+ */
59
+ readonly isPackageResolvable?: (packageName: string) => boolean;
34
60
  }
35
61
  export type { InstalledPackage };
36
62
  /** Outcome of {@link AddonInstaller.sweepBackups}. Absolute paths. */
@@ -46,6 +72,7 @@ export declare class AddonInstaller {
46
72
  readonly workspaceDir: string | undefined;
47
73
  readonly installSource: InstallSource;
48
74
  private readonly logger;
75
+ private readonly isPackageResolvable?;
49
76
  /**
50
77
  * Central manifest of installed addons. Tracks version + source +
51
78
  * timestamps + last-backup pointer per package, written atomically
@@ -71,6 +98,17 @@ export declare class AddonInstaller {
71
98
  * hardcoded lists — see design spec
72
99
  * docs/superpowers/specs/2026-05-20-docker-install-from-npm-design.md.
73
100
  */
101
+ /**
102
+ * Is `packageName` reachable through normal resolution — i.e. does the
103
+ * running closure already provide it?
104
+ *
105
+ * Overridable via `AddonInstallerConfig.isPackageResolvable` so a spec can
106
+ * exercise BOTH sides. That matters more than it looks: the branch that
107
+ * still seeds is the one protecting a fresh deployment from an unbootable
108
+ * node, and it is unreachable in a test process where `@camstack/system`
109
+ * always resolves.
110
+ */
111
+ private isResolvableFromClosure;
74
112
  private static deriveBootstrapList;
75
113
  /**
76
114
  * Bootstrap packages installed on first boot — derived from the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/system",
3
- "version": "1.2.29",
3
+ "version": "1.2.30",
4
4
  "description": "Core addon for CamStack — builtins, pipeline, process management, auth, logging, events",
5
5
  "keywords": [
6
6
  "camstack",