@camstack/system 1.2.480 → 1.2.482

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 (84) hide show
  1. package/dist/{agent-https-6j9JDvjh.mjs → agent-https-doVPSeiy.mjs} +1 -1
  2. package/dist/{agent-https-DDnP9ywM.js → agent-https-o3X-jkS7.js} +1 -1
  3. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
  4. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
  5. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
  6. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
  7. package/dist/builtins/alerts/alerts.addon.js +1 -1
  8. package/dist/builtins/alerts/alerts.addon.mjs +1 -1
  9. package/dist/builtins/autotrack/index.js +1 -1
  10. package/dist/builtins/autotrack/index.mjs +1 -1
  11. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +2 -2
  12. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +2 -2
  13. package/dist/builtins/calendars/calendars.addon.js +1 -1
  14. package/dist/builtins/calendars/calendars.addon.mjs +1 -1
  15. package/dist/builtins/camera-grid/index.js +1 -1
  16. package/dist/builtins/camera-grid/index.mjs +1 -1
  17. package/dist/builtins/composer/composer.addon.js +11 -3
  18. package/dist/builtins/composer/composer.addon.mjs +11 -3
  19. package/dist/builtins/console-logging/index.js +1 -1
  20. package/dist/builtins/console-logging/index.mjs +1 -1
  21. package/dist/builtins/core-blocks/core-blocks.addon.js +4 -4
  22. package/dist/builtins/core-blocks/core-blocks.addon.mjs +4 -4
  23. package/dist/builtins/device-history/device-history.addon.js +2 -2
  24. package/dist/builtins/device-history/device-history.addon.mjs +2 -2
  25. package/dist/builtins/device-manager/device-manager.addon.js +1 -1
  26. package/dist/builtins/device-manager/device-manager.addon.mjs +1 -1
  27. package/dist/builtins/hub-forwarder/index.js +1 -1
  28. package/dist/builtins/hub-forwarder/index.mjs +1 -1
  29. package/dist/builtins/keychain/index.js +3 -3
  30. package/dist/builtins/keychain/index.mjs +3 -3
  31. package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
  32. package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
  33. package/dist/builtins/local-auth/local-auth.addon.js +2 -2
  34. package/dist/builtins/local-auth/local-auth.addon.mjs +2 -2
  35. package/dist/builtins/local-network/local-network.addon.js +2 -2
  36. package/dist/builtins/local-network/local-network.addon.mjs +2 -2
  37. package/dist/builtins/loki-logging/index.js +1 -1
  38. package/dist/builtins/loki-logging/index.mjs +1 -1
  39. package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
  40. package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
  41. package/dist/builtins/platform-probe/index.js +1 -1
  42. package/dist/builtins/platform-probe/index.mjs +1 -1
  43. package/dist/builtins/record-entries/index.js +1 -1
  44. package/dist/builtins/record-entries/index.mjs +1 -1
  45. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
  46. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
  47. package/dist/builtins/snapshot/index.js +1 -1
  48. package/dist/builtins/snapshot/index.mjs +1 -1
  49. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
  50. package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
  51. package/dist/builtins/sqlite-storage/index.js +1 -1
  52. package/dist/builtins/sqlite-storage/index.mjs +1 -1
  53. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +2 -2
  54. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +2 -2
  55. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
  56. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
  57. package/dist/builtins/system-config/system-config.addon.js +3 -3
  58. package/dist/builtins/system-config/system-config.addon.mjs +3 -3
  59. package/dist/builtins/winston-logging/index.js +1 -1
  60. package/dist/builtins/winston-logging/index.mjs +1 -1
  61. package/dist/{composition-sources-DTchGK8d.js → composition-sources-BmhhDWIc.js} +1 -1
  62. package/dist/{composition-sources-CcxoCFH6.mjs → composition-sources-BrDtOpfE.mjs} +1 -1
  63. package/dist/{constants-Bc-5tr1I.js → constants-BVJrLycr.js} +1 -1
  64. package/dist/{constants-BUf0tYhG.mjs → constants-xuLNi4a2.mjs} +1 -1
  65. package/dist/{device-ca-Bxjub9X-.mjs → device-ca-DKOZSFED.mjs} +1 -1
  66. package/dist/{device-ca-CVO0N_Oz.js → device-ca-DgLZPn5R.js} +1 -1
  67. package/dist/{dist-DDVtA047.js → dist--v3KMKa1.js} +280 -213
  68. package/dist/{dist-DfZKKnMP.mjs → dist-BIJXQo_j.mjs} +275 -214
  69. package/dist/file-host-worker.js +1 -1
  70. package/dist/file-host-worker.mjs +1 -1
  71. package/dist/{hub-mdns-ciao-C49WPQfd.js → hub-mdns-ciao-C3NJsOvK.js} +2 -2
  72. package/dist/{hub-mdns-ciao-KIDDBuDn.mjs → hub-mdns-ciao-DMFXIlMY.mjs} +2 -2
  73. package/dist/index.js +126 -12
  74. package/dist/index.mjs +124 -13
  75. package/dist/kernel/addon-installer.d.ts +24 -4
  76. package/dist/kernel/addon-version-policy.d.ts +26 -0
  77. package/dist/kernel/index.d.ts +2 -0
  78. package/dist/{restore-archive-NvTeD4tg.mjs → restore-archive-DAEsvFY6.mjs} +1 -1
  79. package/dist/{restore-archive-BXORpvel.js → restore-archive-DpkdAuFf.js} +1 -1
  80. package/dist/{retention-CAGXAgiQ.js → retention-C71dNCIh.js} +1 -1
  81. package/dist/{retention-Dn74ba1y.mjs → retention-DbunrLR4.mjs} +1 -1
  82. package/dist/{wal-maintenance-ByIgd_g9.js → wal-maintenance-CsGk4kYn.js} +0 -0
  83. package/dist/{wal-maintenance-DkkPbYwt.mjs → wal-maintenance-DYAJwPWu.mjs} +0 -0
  84. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  require("./chunk-Cek0wNdY.js");
2
- const require_wal_maintenance = require("./wal-maintenance-ByIgd_g9.js");
2
+ const require_wal_maintenance = require("./wal-maintenance-CsGk4kYn.js");
3
3
  let node_worker_threads = require("node:worker_threads");
4
4
  //#region src/builtins/sqlite-storage/file-host-worker.ts
5
5
  /**
@@ -1,4 +1,4 @@
1
- import { C as RecordsEngine, D as callVector, E as callRecords, O as controlTargetOf, T as callData, _ as collectTransferables, a as WalMaintenance, b as isFileHostWorkerData, h as serializeError, l as SqliteSettingsBackend, o as createVectorIndex, s as vectorProviderOf, w as callControl, x as trustInput, y as isFileHostRequest } from "./wal-maintenance-DkkPbYwt.mjs";
1
+ import { C as RecordsEngine, D as callVector, E as callRecords, O as controlTargetOf, T as callData, _ as collectTransferables, a as WalMaintenance, b as isFileHostWorkerData, h as serializeError, l as SqliteSettingsBackend, o as createVectorIndex, s as vectorProviderOf, w as callControl, x as trustInput, y as isFileHostRequest } from "./wal-maintenance-DYAJwPWu.mjs";
2
2
  import { parentPort, threadId, workerData } from "node:worker_threads";
3
3
  //#region src/builtins/sqlite-storage/file-host-worker.ts
4
4
  /**
@@ -1,7 +1,7 @@
1
1
  const require_chunk = require("./chunk-Cek0wNdY.js");
2
- const require_dist = require("./dist-DDVtA047.js");
2
+ const require_dist = require("./dist--v3KMKa1.js");
3
3
  const require_x509_es = require("./x509.es-WtnRNyYS.js");
4
- const require_agent_https = require("./agent-https-DDnP9ywM.js");
4
+ const require_agent_https = require("./agent-https-o3X-jkS7.js");
5
5
  let node_crypto = require("node:crypto");
6
6
  let _camstack_types_node = require("@camstack/types/node");
7
7
  let node_fs_promises = require("node:fs/promises");
@@ -1,7 +1,7 @@
1
1
  import { o as __toESM } from "./chunk-CNf5ZN-e.mjs";
2
- import { Ea as userError } from "./dist-DfZKKnMP.mjs";
2
+ import { Da as userError } from "./dist-BIJXQo_j.mjs";
3
3
  import { f as X509Certificate$1 } from "./x509.es-BRiJgOvu.mjs";
4
- import { D as reasonRequiresNewCa, E as evaluateExistingCert, F as readNameConstraints, N as permitsIdentity, _ as issueLeaf, b as collectCertIdentity, g as generateCa, j as isConstrainedCa, v as loadCa, y as localCaCommonName } from "./agent-https-6j9JDvjh.mjs";
4
+ import { D as reasonRequiresNewCa, E as evaluateExistingCert, F as readNameConstraints, N as permitsIdentity, _ as issueLeaf, b as collectCertIdentity, g as generateCa, j as isConstrainedCa, v as loadCa, y as localCaCommonName } from "./agent-https-doVPSeiy.mjs";
5
5
  import { X509Certificate, createPrivateKey } from "node:crypto";
6
6
  import { writeOwnerOnlyFileSync } from "@camstack/types/node";
7
7
  import { mkdir, writeFile } from "node:fs/promises";
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_chunk = require("./chunk-Cek0wNdY.js");
3
- const require_dist = require("./dist-DDVtA047.js");
4
- const require_device_ca = require("./device-ca-CVO0N_Oz.js");
3
+ const require_dist = require("./dist--v3KMKa1.js");
4
+ const require_device_ca = require("./device-ca-DgLZPn5R.js");
5
5
  const require_read_all_rows$1 = require("./read-all-rows-CVoO1ONM.js");
6
6
  const require_builtins_alerts_alerts_addon = require("./builtins/alerts/alerts.addon.js");
7
7
  require("./builtins/alerts/index.js");
@@ -26,21 +26,21 @@ const require_builtins_loki_logging_index = require("./builtins/loki-logging/ind
26
26
  const require_builtins_native_metrics_native_metrics_addon = require("./builtins/native-metrics/native-metrics.addon.js");
27
27
  const require_builtins_device_history_device_history_addon = require("./builtins/device-history/device-history.addon.js");
28
28
  const require_builtins_sqlite_storage_filesystem_storage_addon = require("./builtins/sqlite-storage/filesystem-storage.addon.js");
29
- const require_wal_maintenance = require("./wal-maintenance-ByIgd_g9.js");
29
+ const require_wal_maintenance = require("./wal-maintenance-CsGk4kYn.js");
30
30
  const require_builtins_sqlite_storage_sqlite_settings_addon = require("./builtins/sqlite-storage/sqlite-settings.addon.js");
31
31
  const require_builtins_sqlite_storage_index = require("./builtins/sqlite-storage/index.js");
32
32
  const require_builtins_storage_orchestrator_storage_orchestrator_addon = require("./builtins/storage-orchestrator/storage-orchestrator.addon.js");
33
33
  require("./builtins/storage-orchestrator/index.js");
34
- const require_agent_https = require("./agent-https-DDnP9ywM.js");
35
- const require_constants = require("./constants-Bc-5tr1I.js");
34
+ const require_agent_https = require("./agent-https-o3X-jkS7.js");
35
+ const require_constants = require("./constants-BVJrLycr.js");
36
36
  const require_builtins_system_config_system_config_addon = require("./builtins/system-config/system-config.addon.js");
37
37
  require("./builtins/system-config/index.js");
38
38
  const require_builtins_winston_logging_index = require("./builtins/winston-logging/index.js");
39
39
  const require_custom_action_registry = require("./custom-action-registry-MRyes5j0.js");
40
- const require_hub_mdns_ciao = require("./hub-mdns-ciao-C49WPQfd.js");
40
+ const require_hub_mdns_ciao = require("./hub-mdns-ciao-C3NJsOvK.js");
41
41
  const require_platform_key_source = require("./platform-key-source-Di7HrlGR.js");
42
42
  const require_resource_monitor = require("./resource-monitor-mio9dSCT.js");
43
- const require_restore_archive = require("./restore-archive-BXORpvel.js");
43
+ const require_restore_archive = require("./restore-archive-DpkdAuFf.js");
44
44
  const require_coral_accelerators = require("./coral-accelerators-BSVsBVzt.js");
45
45
  let zod = require("zod");
46
46
  let node_crypto = require("node:crypto");
@@ -7528,6 +7528,34 @@ var AddonManifest = class {
7528
7528
  }
7529
7529
  };
7530
7530
  //#endregion
7531
+ //#region src/kernel/addon-version-policy.ts
7532
+ /**
7533
+ * Which version an installed addon should be running (D942).
7534
+ *
7535
+ * The hub's target is the registry dist-tag `latest`. An agent's target is
7536
+ * the hub's installed version — never the registry, and never "strictly
7537
+ * newer". A missing target is an unreadable authority: a failed read changes
7538
+ * nothing (D49), including never a move downward because the registry or the
7539
+ * hub could not be asked.
7540
+ */
7541
+ var ADDON_VERSION_REASON_REGISTRY_LATEST = "installed version differs from registry latest";
7542
+ var ADDON_VERSION_REASON_HUB = "agent follows the hub installed version";
7543
+ /**
7544
+ * Move when `installed` is not `target`. `target === null` (or empty) means
7545
+ * the authority could not be read — keep whatever is installed.
7546
+ * `installed === null` with a known target is a first install of that target.
7547
+ */
7548
+ function decideAddonVersionMove(installed, target, reason) {
7549
+ if (target === null || target.length === 0) return { move: false };
7550
+ if (installed !== null && installed === target) return { move: false };
7551
+ return {
7552
+ move: true,
7553
+ from: installed ?? "absent",
7554
+ to: target,
7555
+ reason
7556
+ };
7557
+ }
7558
+ //#endregion
7531
7559
  //#region src/kernel/deps/closure-dedupe.ts
7532
7560
  /**
7533
7561
  * Closure dedupe — stop copying into every addon the libraries the server
@@ -8282,6 +8310,25 @@ function readPackageJson(pkgJsonPath) {
8282
8310
  function shouldSkipClosureProvidedSeed(packageName, isResolvable) {
8283
8311
  return packageName === "@camstack/system" && isResolvable;
8284
8312
  }
8313
+ /** How long a boot-time `dist-tags.latest` read may take before it is "unreadable". */
8314
+ var REGISTRY_LATEST_TIMEOUT_MS = 15e3;
8315
+ function readInstalledPackageVersion(addonDir) {
8316
+ try {
8317
+ const raw = JSON.parse(node_fs.readFileSync(node_path.join(addonDir, "package.json"), "utf-8"));
8318
+ if (raw === null || typeof raw !== "object") return null;
8319
+ const version = Reflect.get(raw, "version");
8320
+ return typeof version === "string" && version.length > 0 ? version : null;
8321
+ } catch {
8322
+ return null;
8323
+ }
8324
+ }
8325
+ function distTagLatest(body) {
8326
+ if (body === null || typeof body !== "object") return null;
8327
+ const tags = Reflect.get(body, "dist-tags");
8328
+ if (tags === null || typeof tags !== "object") return null;
8329
+ const latest = Reflect.get(tags, "latest");
8330
+ return typeof latest === "string" && latest.length > 0 ? latest : null;
8331
+ }
8285
8332
  /** Minimal no-op logger for default parameter */
8286
8333
  var noopLogger = {
8287
8334
  debug() {},
@@ -8332,6 +8379,7 @@ var AddonInstaller = class AddonInstaller {
8332
8379
  isPackageResolvable;
8333
8380
  /** Test seam — production resolves via `CAMSTACK_FRAMEWORK_DIR`. */
8334
8381
  closureNodeModulesDir;
8382
+ resolveLatestVersionOverride;
8335
8383
  /**
8336
8384
  * Central manifest of installed addons. Tracks version + source +
8337
8385
  * timestamps + last-backup pointer per package, written atomically
@@ -8354,6 +8402,7 @@ var AddonInstaller = class AddonInstaller {
8354
8402
  this.manifest = new AddonManifest(config.addonsDir);
8355
8403
  this.isPackageResolvable = config.isPackageResolvable;
8356
8404
  this.closureNodeModulesDir = config.closureNodeModulesDir;
8405
+ this.resolveLatestVersionOverride = config.resolveLatestVersion;
8357
8406
  if (config.installSource) this.installSource = config.installSource;
8358
8407
  else this.installSource = "npm";
8359
8408
  }
@@ -8467,10 +8516,13 @@ var AddonInstaller = class AddonInstaller {
8467
8516
  * defaults to npm in production.
8468
8517
  *
8469
8518
  * There is no version argument and there is deliberately no pin: the system is
8470
- * addons-agnostic and `latest` is the whole contract at first boot (operator,
8471
- * 2026-08-13). A copy already under the addon root is never replaced either —
8472
- * bootstrap is seed-only, and overwriting a deployed bundle would be an
8473
- * un-deploy ([D90](../../../../docs/decisions/adr-0090.md)).
8519
+ * addons-agnostic and `latest` is the whole contract (operator, 2026-08-13,
8520
+ * restated 2026-10-25 — D942). A copy already under the addon root is left
8521
+ * alone when this installer is not on the npm source (a workspace or a
8522
+ * bundled desktop seed) and when the package is the closure-provided
8523
+ * `@camstack/system` (a copy there would shadow the closure). Every other
8524
+ * required addon already on disk is moved to registry `latest` when that
8525
+ * tag differs, higher or lower. An unreadable registry changes nothing.
8474
8526
  *
8475
8527
  * @param packages — optional custom package list (default: REQUIRED_PACKAGES)
8476
8528
  */
@@ -8486,7 +8538,16 @@ var AddonInstaller = class AddonInstaller {
8486
8538
  for (const packageName of pkgList) {
8487
8539
  const addonDir = node_path.join(this.addonsDir, packageName);
8488
8540
  if (node_fs.existsSync(node_path.join(addonDir, "package.json"))) {
8489
- this.logger.debug(`${packageName} — already installed, skipping`);
8541
+ if (this.installSource !== "npm" || shouldSkipClosureProvidedSeed(packageName, this.isResolvableFromClosure(packageName))) {
8542
+ this.logger.debug(`${packageName} — already installed, skipping`);
8543
+ continue;
8544
+ }
8545
+ try {
8546
+ await this.followInstalledAddonToLatest(packageName, addonDir);
8547
+ } catch (err) {
8548
+ const msg = require_dist.errMsg(err);
8549
+ this.logger.error(`Failed to move ${packageName} to registry latest`, { meta: { error: msg } });
8550
+ }
8490
8551
  continue;
8491
8552
  }
8492
8553
  if (shouldSkipClosureProvidedSeed(packageName, this.isResolvableFromClosure(packageName))) {
@@ -8511,6 +8572,56 @@ var AddonInstaller = class AddonInstaller {
8511
8572
  }
8512
8573
  }
8513
8574
  /**
8575
+ * Move an already-installed required addon to registry `latest` when the
8576
+ * installed version differs. `applyUpdate` keeps the previous tree as a
8577
+ * backup and restores it if the install throws. A null latest (registry
8578
+ * down, or no tag) leaves the copy where it is.
8579
+ */
8580
+ async followInstalledAddonToLatest(packageName, addonDir) {
8581
+ const installedVersion = readInstalledPackageVersion(addonDir);
8582
+ const decision = decideAddonVersionMove(installedVersion, await this.readRegistryLatest(packageName), ADDON_VERSION_REASON_REGISTRY_LATEST);
8583
+ if (!decision.move) {
8584
+ this.logger.debug(`${packageName} — installed copy matches registry latest, or the registry could not be read`);
8585
+ return;
8586
+ }
8587
+ this.logger.info(`${packageName} — moving ${decision.from} → ${decision.to}: ${decision.reason}`, { meta: {
8588
+ from: decision.from,
8589
+ to: decision.to,
8590
+ reason: decision.reason
8591
+ } });
8592
+ if (this.manifest.get(packageName) == null) this.manifest.upsert(packageName, {
8593
+ version: installedVersion ?? "0.0.0",
8594
+ source: "npm"
8595
+ });
8596
+ await this.applyUpdate(packageName, decision.to);
8597
+ }
8598
+ /** `dist-tags.latest`, or `null` when the registry cannot be read. */
8599
+ async readRegistryLatest(packageName) {
8600
+ if (this.resolveLatestVersionOverride) try {
8601
+ return await this.resolveLatestVersionOverride(packageName);
8602
+ } catch (err) {
8603
+ this.logger.warn(`${packageName} — registry unreadable, leaving the installed copy`, { meta: { error: require_dist.errMsg(err) } });
8604
+ return null;
8605
+ }
8606
+ return this.fetchRegistryLatest(packageName);
8607
+ }
8608
+ async fetchRegistryLatest(packageName) {
8609
+ const metadataUrl = `${(this.registry ?? "https://registry.npmjs.org").replace(/\/+$/, "")}/${encodeURIComponent(packageName).replace(/^%40/, "@")}`;
8610
+ try {
8611
+ const metadataRes = await fetch(metadataUrl, { signal: AbortSignal.timeout(REGISTRY_LATEST_TIMEOUT_MS) });
8612
+ if (!metadataRes.ok) {
8613
+ this.logger.warn(`${packageName} — registry answered ${metadataRes.status}, leaving the installed copy`);
8614
+ return null;
8615
+ }
8616
+ const latest = distTagLatest(await metadataRes.json());
8617
+ if (latest === null) this.logger.warn(`${packageName} — registry returned no dist-tags.latest, leaving the installed copy`);
8618
+ return latest;
8619
+ } catch (err) {
8620
+ this.logger.warn(`${packageName} — registry unreadable, leaving the installed copy`, { meta: { error: require_dist.errMsg(err) } });
8621
+ return null;
8622
+ }
8623
+ }
8624
+ /**
8514
8625
  * Reconcile the install manifest against the addons actually present on
8515
8626
  * disk: register seeded addons, correct a version that disagrees with the
8516
8627
  * installed `package.json`, and drop entries naming a directory that does
@@ -27769,6 +27880,8 @@ function resetCatalogRegistryForTests() {
27769
27880
  shared = null;
27770
27881
  }
27771
27882
  //#endregion
27883
+ exports.ADDON_VERSION_REASON_HUB = ADDON_VERSION_REASON_HUB;
27884
+ exports.ADDON_VERSION_REASON_REGISTRY_LATEST = ADDON_VERSION_REASON_REGISTRY_LATEST;
27772
27885
  exports.AGENT_CAP_FWD_ACTION = AGENT_CAP_FWD_ACTION;
27773
27886
  exports.AGENT_CAP_FWD_SERVICE = AGENT_CAP_FWD_SERVICE;
27774
27887
  exports.AGENT_DASHBOARD_ORIGINS_FIELD = require_builtins_system_config_system_config_addon.AGENT_DASHBOARD_ORIGINS_FIELD;
@@ -28115,6 +28228,7 @@ exports.createUdsLogger = createUdsLogger;
28115
28228
  exports.createUdsLoggerWithControl = createUdsLoggerWithControl;
28116
28229
  exports.createV8Reclaimer = createV8Reclaimer;
28117
28230
  exports.currentBrokerTransporter = currentBrokerTransporter;
28231
+ exports.decideAddonVersionMove = decideAddonVersionMove;
28118
28232
  exports.deleteModelFromDisk = require_custom_action_registry.deleteModelFromDisk;
28119
28233
  exports.deriveAgentListenPort = deriveAgentListenPort;
28120
28234
  exports.describeCsr = require_builtins_system_config_system_config_addon.describeCsr;
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { i as __require } from "./chunk-CNf5ZN-e.mjs";
2
- import { Cn as isCollectionArrayMethod, Cr as splitTranslationRef, Da as withoutCallerStamp, Dn as isObjectInput, Ea as userError, Fi as asNumber, Ii as asString$1, J as METHOD_ACCESS_MAP, Ji as emitDownForOwnedCaps, Jn as objectInputDeclaresAddonId, K as LOG_LEVEL_RANK, Oa as EventCategory$1, On as isVoidInput, Pi as asJsonObject$1, Pn as lifecycleJobSchema, Rn as logLevelAtMost, Si as ReadinessTimeoutError, Sn as isArrayOutputSchema, Wi as createEvent$1, Xi as expandCapMethods, Yn as objectInputDeclaresRequiredDeviceId, _ as CatalogFileSchema, _a as resolveCapMount, _r as scopesAllowDeviceCap, ai as DEVICE_SETTINGS_CONTRIBUTION_METHODS, bi as RUNTIME_DEFAULTS, ei as errMsg$1, fa as parseJsonObject, fn as extractNestedAddonId, gr as scopesAllowAddon, ha as readinessKey, ii as DATAPLANE_SECRET_HEADER$1, jr as supportedRuntimes, kn as kebabToCamel$1, n as AGENT_MDNS_TXT_KEYS, oi as DEVICE_STATUS_METHOD, pa as parseJsonUnknown, pr as resolveMethodAuth, qi as defineRecordKinds, r as ALL_CAPABILITY_DEFINITIONS, ri as CALLER_STAMPED_CAPABILITIES$1, t as AGENT_MDNS_SERVICE_TYPE, tr as procedureAuthKey, u as CATALOG_LANGS, vn as interpolate, vt as addonSettingsCapability, xi as ReadinessRegistry, ya as scopeKey, zn as looseSchema } from "./dist-DfZKKnMP.mjs";
3
- import { d as JWT_SIGNING_KEY_REF, f as JwtSigningKeyUnavailableError, g as processJwtSigningKey, i as generateDeviceCa, l as verifyDeviceLeaf, m as getProcessJwtSigningKeyState, n as DEVICE_CA_KEY_REF, o as issueDeviceLeaf, p as SYSTEM_SECRET_OWNER, s as loadDeviceCa, u as verifyDeviceSignature, v as staticJwtSigningKey } from "./device-ca-Bxjub9X-.mjs";
2
+ import { Ci as ReadinessTimeoutError, Cn as isCollectionArrayMethod, Da as userError, Dn as isObjectInput, Fi as asJsonObject$1, Gi as createEvent$1, Ii as asNumber, J as METHOD_ACCESS_MAP, Ji as defineRecordKinds, Jn as objectInputDeclaresAddonId, K as LOG_LEVEL_RANK, Li as asString$1, Mr as supportedRuntimes, Oa as withoutCallerStamp, On as isVoidInput, Pn as lifecycleJobSchema, Rn as logLevelAtMost, Si as ReadinessRegistry, Sn as isArrayOutputSchema, Yi as emitDownForOwnedCaps, Yn as objectInputDeclaresRequiredDeviceId, Zi as expandCapMethods, _ as CatalogFileSchema, _r as scopesAllowAddon, ai as DATAPLANE_SECRET_HEADER$1, ba as scopeKey, fn as extractNestedAddonId, ga as readinessKey, ii as CALLER_STAMPED_CAPABILITIES$1, ka as EventCategory$1, kn as kebabToCamel$1, ma as parseJsonUnknown, mr as resolveMethodAuth, n as AGENT_MDNS_TXT_KEYS, nr as procedureAuthKey, oi as DEVICE_SETTINGS_CONTRIBUTION_METHODS, pa as parseJsonObject, r as ALL_CAPABILITY_DEFINITIONS, si as DEVICE_STATUS_METHOD, t as AGENT_MDNS_SERVICE_TYPE, ti as errMsg$1, u as CATALOG_LANGS, va as resolveCapMount, vn as interpolate, vr as scopesAllowDeviceCap, vt as addonSettingsCapability, wr as splitTranslationRef, xi as RUNTIME_DEFAULTS, zn as looseSchema } from "./dist-BIJXQo_j.mjs";
3
+ import { d as JWT_SIGNING_KEY_REF, f as JwtSigningKeyUnavailableError, g as processJwtSigningKey, i as generateDeviceCa, l as verifyDeviceLeaf, m as getProcessJwtSigningKeyState, n as DEVICE_CA_KEY_REF, o as issueDeviceLeaf, p as SYSTEM_SECRET_OWNER, s as loadDeviceCa, u as verifyDeviceSignature, v as staticJwtSigningKey } from "./device-ca-DKOZSFED.mjs";
4
4
  import { t as require_read_all_rows } from "./read-all-rows-TaPqdWNF.mjs";
5
5
  import { AlertCenterAddon } from "./builtins/alerts/alerts.addon.mjs";
6
6
  import "./builtins/alerts/index.mjs";
@@ -25,21 +25,21 @@ import { LokiDestination, LokiLoggingAddon } from "./builtins/loki-logging/index
25
25
  import NativeMetricsAddon, { a as NativeMetricsProvider, n as nodeProcReader, r as parseProcStat } from "./builtins/native-metrics/native-metrics.addon.mjs";
26
26
  import { DeviceHistoryAddon } from "./builtins/device-history/device-history.addon.mjs";
27
27
  import { FilesystemStorageAddon, t as FilesystemStorageProvider } from "./builtins/sqlite-storage/filesystem-storage.addon.mjs";
28
- import { C as RecordsEngine, l as SqliteSettingsBackend } from "./wal-maintenance-DkkPbYwt.mjs";
28
+ import { C as RecordsEngine, l as SqliteSettingsBackend } from "./wal-maintenance-DYAJwPWu.mjs";
29
29
  import { SqliteSettingsAddon } from "./builtins/sqlite-storage/sqlite-settings.addon.mjs";
30
30
  import { ConfigStore, DeviceStore } from "./builtins/sqlite-storage/index.mjs";
31
31
  import { StorageOrchestratorAddon, a as stripForwardedCaller, i as createHubCapForwardService, l as STORAGE_DRAIN_STATE_LEGACY, n as HUB_CAP_FWD_ACTION, o as buildStorageLocationRegistry, r as HUB_CAP_FWD_SERVICE, t as StorageOrchestratorService, u as storageOrchestratorRecordKinds } from "./builtins/storage-orchestrator/storage-orchestrator.addon.mjs";
32
32
  import "./builtins/storage-orchestrator/index.mjs";
33
- import { A as buildNameConstraintSet, B as setProcessAgentHttpsNames, C as LEAF_RENEWAL_WINDOW_DAYS, E as evaluateExistingCert, F as readNameConstraints, I as AGENT_HTTPS_NAMES_COLLECTION, L as AGENT_HTTPS_NAMES_COLUMNS, M as isLocalOnlyHostname, N as permitsIdentity, O as PERMITTED_DNS_SUFFIXES, P as permitsName, R as AgentHttpsNames, S as CA_VALIDITY_DAYS, T as SERVER_AUTH_OID, a as collectAgentNames, b as collectCertIdentity, c as installAgentHttps, d as issueAgentHttpsLeaf, f as loadAgentHttps, h as CA_COMMON_NAME, i as certificateNames, j as isConstrainedCa, k as PERMITTED_IP_RANGES, l as isContainerBridgeAddress, m as pinnedHttpsCaFingerprint, n as acceptAgentSans, o as createAgentHttpsRequest, p as pemDigest, r as agentHttpsPaths, s as describeHttpsLeaf, t as AgentHttpsInstallError, u as isPrivateAddress, w as MAX_LEAF_VALIDITY_DAYS, x as systemHostFacts, y as localCaCommonName, z as getProcessAgentHttpsNames } from "./agent-https-6j9JDvjh.mjs";
34
- import { a as MESH_CA_KEY_REF, i as MESH_CA_FIELD, n as DEFAULT_HUB_TLS_TCP_PORT, o as MESH_CA_SETTINGS_KEY } from "./constants-BUf0tYhG.mjs";
33
+ import { A as buildNameConstraintSet, B as setProcessAgentHttpsNames, C as LEAF_RENEWAL_WINDOW_DAYS, E as evaluateExistingCert, F as readNameConstraints, I as AGENT_HTTPS_NAMES_COLLECTION, L as AGENT_HTTPS_NAMES_COLUMNS, M as isLocalOnlyHostname, N as permitsIdentity, O as PERMITTED_DNS_SUFFIXES, P as permitsName, R as AgentHttpsNames, S as CA_VALIDITY_DAYS, T as SERVER_AUTH_OID, a as collectAgentNames, b as collectCertIdentity, c as installAgentHttps, d as issueAgentHttpsLeaf, f as loadAgentHttps, h as CA_COMMON_NAME, i as certificateNames, j as isConstrainedCa, k as PERMITTED_IP_RANGES, l as isContainerBridgeAddress, m as pinnedHttpsCaFingerprint, n as acceptAgentSans, o as createAgentHttpsRequest, p as pemDigest, r as agentHttpsPaths, s as describeHttpsLeaf, t as AgentHttpsInstallError, u as isPrivateAddress, w as MAX_LEAF_VALIDITY_DAYS, x as systemHostFacts, y as localCaCommonName, z as getProcessAgentHttpsNames } from "./agent-https-doVPSeiy.mjs";
34
+ import { a as MESH_CA_KEY_REF, i as MESH_CA_FIELD, n as DEFAULT_HUB_TLS_TCP_PORT, o as MESH_CA_SETTINGS_KEY } from "./constants-xuLNi4a2.mjs";
35
35
  import { $ as generateMeshKeyPair, A as setProcessMeshPeerTransportLookup, B as describeMeshLeaf, C as setProcessMeshTlsEnabler, D as getProcessPeerLeaf, E as getProcessNodeMeshTransport, F as setProcessMeshTlsListenerState, G as MeshCaKeeper, H as setProcessMeshCertificateRegistry, I as MESH_NODE_CERTIFICATES_COLLECTION, J as caFingerprint, K as getProcessMeshCaState, L as MESH_NODE_CERTIFICATES_COLUMNS, M as revokeMeshCertificate, N as getProcessMeshTlsListenerState, O as isProcessVerifiedMeshPeer, P as openMeshTlsWhenRevocationsLoaded, Q as generateMeshCa, R as MeshCertificateRegistry, S as ServiceBroker, SystemConfigAddon, T as emitProcessNodeRegistered, U as MeshCrl, V as getProcessMeshCertificateRegistry, W as processMeshCrl, X as createMeshCsrPem, Y as caFingerprintCompact, Z as exportMeshPrivateKeyPem, _ as signPairingProof, _t as readCidrSetting, a as hubHostFromMeshAddress, at as AGENT_UI_UNLOCK_TTL_MS, b as TlsTcpTransporter, c as PAIRING_MAX_SESSIONS, ct as AGENT_UI_UNLOCK_VERSION, d as PAIRING_PROTOCOL, dt as mintAgentUiUnlockTicket, et as isValidAgentNodeId, f as PAIRING_TTL_MS, ft as parseAgentDashboardOrigins, g as keyFingerprintShort, gt as parseCidrList, h as describeCsr, ht as normalizeIp, i as AgentPairing, it as AGENT_DASHBOARD_ORIGINS_FIELD, j as renewMeshCertificate, k as onProcessNodeRegistered, l as PAIRING_PATHS, lt as UnlockTicketJtiStore, m as computePairingSas, mt as createCidrMatcher, n as HubPairing, nt as issueMeshLeafFromCsr, o as PAIRING_CODE_DIGITS, ot as AGENT_UI_UNLOCK_TYP, p as computePairingCommitment, pt as verifyAgentUiUnlockTicket, q as requireProcessMeshCa, r as PairingHttpError, rt as loadMeshCa, s as PAIRING_MAX_CODE_ATTEMPTS, st as AGENT_UI_UNLOCK_USE, tt as issueMeshLeafForNode, u as PAIRING_PIN_DIGITS, ut as isAllowedAgentDashboardReturnTo, v as verifyPairingProof, w as dropProcessPeer, x as Errors, y as MESH_TLS_PORT_HELLO_FIELD, z as RENEWAL_ABANDONED } from "./builtins/system-config/system-config.addon.mjs";
36
36
  import "./builtins/system-config/index.mjs";
37
37
  import { WinstonDestination, WinstonLoggingAddon } from "./builtins/winston-logging/index.mjs";
38
38
  import { C as isModelDownloaded, T as revisionWeightUrl, _ as downloadFile, a as startEventLoopStallMonitor, b as fetchJson, c as createAuthenticatedFileServer, d as resolveFilePath, f as ModelDownloadService, g as deleteModelFromDisk, h as collectModelFiles, i as attributeStall, l as parseRangeHeader, m as adoptModelRevisions, n as STALL_REPORT_MS, o as createFileDataPlaneHandler, r as STALL_TICK_MS, s as contentTypeFor, t as CustomActionRegistry, u as parseTokenizedUrl, v as downloadModel, w as resolveFormatRevision, x as getModelFilePath, y as ensureModel } from "./custom-action-registry-DZSCLBuT.mjs";
39
- import { A as allFamiliesListenHost, C as caReplacementMarkerFile, D as replaceUnconstrainedLocalCa, E as reissueTlsLeaf, F as registerLanHttpHandler, M as bindPendingLanHttp, N as closeLanHttp, O as retirePreviousLocalCa, P as readLanHttpState, S as validateUploadedTls, T as loadTlsCert, _ as splitPemCertificates, a as storeUploadedCertificate, b as chainsToPublicRoot, c as leafFingerprintOf, d as servedHttpsLeafFingerprint, f as prepareBootTls, g as readTlsMode, h as readTlsAccessStatus, i as revertToGeneratedCertificate, j as applyLanHttp, k as DEFAULT_LAN_HTTP_PORT, l as registerHttpsListener, m as readExtraSans, n as applyCertificateToListener, o as useStoredUploadedCertificate, p as UPLOADED_CA_FILE, r as regenerateCertificate, s as clearHttpsListener, t as createCiaoPublisher, u as reloadHttpsListener, v as writeExtraSans, w as ensureTlsCert, x as checkUploadedCa, y as writeTlsMode } from "./hub-mdns-ciao-KIDDBuDn.mjs";
39
+ import { A as allFamiliesListenHost, C as caReplacementMarkerFile, D as replaceUnconstrainedLocalCa, E as reissueTlsLeaf, F as registerLanHttpHandler, M as bindPendingLanHttp, N as closeLanHttp, O as retirePreviousLocalCa, P as readLanHttpState, S as validateUploadedTls, T as loadTlsCert, _ as splitPemCertificates, a as storeUploadedCertificate, b as chainsToPublicRoot, c as leafFingerprintOf, d as servedHttpsLeafFingerprint, f as prepareBootTls, g as readTlsMode, h as readTlsAccessStatus, i as revertToGeneratedCertificate, j as applyLanHttp, k as DEFAULT_LAN_HTTP_PORT, l as registerHttpsListener, m as readExtraSans, n as applyCertificateToListener, o as useStoredUploadedCertificate, p as UPLOADED_CA_FILE, r as regenerateCertificate, s as clearHttpsListener, t as createCiaoPublisher, u as reloadHttpsListener, v as writeExtraSans, w as ensureTlsCert, x as checkUploadedCa, y as writeTlsMode } from "./hub-mdns-ciao-DMFXIlMY.mjs";
40
40
  import { n as getPlatformKeychainKey, r as setPlatformKeychainKey, t as clearPlatformKeychainKey } from "./platform-key-source-BWlq0jjn.mjs";
41
41
  import { n as getSinglePidStats, t as getPidStats } from "./resource-monitor-Di9daRwI.mjs";
42
- import { _ as backupRecordStoresOf, c as BackupDecryptError, f as generateBackupKeyPair, g as backupOrchestratorRecordKinds, h as readBackupEncryptionHeader, l as BackupKeyFormatError, r as prepareRestoreArchive, s as SystemBackupService, t as BackupKeyRequiredError, u as BackupKeyMismatchError } from "./restore-archive-NvTeD4tg.mjs";
42
+ import { _ as backupRecordStoresOf, c as BackupDecryptError, f as generateBackupKeyPair, g as backupOrchestratorRecordKinds, h as readBackupEncryptionHeader, l as BackupKeyFormatError, r as prepareRestoreArchive, s as SystemBackupService, t as BackupKeyRequiredError, u as BackupKeyMismatchError } from "./restore-archive-DAEsvFY6.mjs";
43
43
  import { r as nodeCoralFs, t as classifyCoralAccelerator } from "./coral-accelerators-DBlgWB8k.mjs";
44
44
  import { z } from "zod";
45
45
  import * as crypto$1 from "node:crypto";
@@ -7525,6 +7525,34 @@ var AddonManifest = class {
7525
7525
  }
7526
7526
  };
7527
7527
  //#endregion
7528
+ //#region src/kernel/addon-version-policy.ts
7529
+ /**
7530
+ * Which version an installed addon should be running (D942).
7531
+ *
7532
+ * The hub's target is the registry dist-tag `latest`. An agent's target is
7533
+ * the hub's installed version — never the registry, and never "strictly
7534
+ * newer". A missing target is an unreadable authority: a failed read changes
7535
+ * nothing (D49), including never a move downward because the registry or the
7536
+ * hub could not be asked.
7537
+ */
7538
+ var ADDON_VERSION_REASON_REGISTRY_LATEST = "installed version differs from registry latest";
7539
+ var ADDON_VERSION_REASON_HUB = "agent follows the hub installed version";
7540
+ /**
7541
+ * Move when `installed` is not `target`. `target === null` (or empty) means
7542
+ * the authority could not be read — keep whatever is installed.
7543
+ * `installed === null` with a known target is a first install of that target.
7544
+ */
7545
+ function decideAddonVersionMove(installed, target, reason) {
7546
+ if (target === null || target.length === 0) return { move: false };
7547
+ if (installed !== null && installed === target) return { move: false };
7548
+ return {
7549
+ move: true,
7550
+ from: installed ?? "absent",
7551
+ to: target,
7552
+ reason
7553
+ };
7554
+ }
7555
+ //#endregion
7528
7556
  //#region src/kernel/deps/closure-dedupe.ts
7529
7557
  /**
7530
7558
  * Closure dedupe — stop copying into every addon the libraries the server
@@ -8279,6 +8307,25 @@ function readPackageJson(pkgJsonPath) {
8279
8307
  function shouldSkipClosureProvidedSeed(packageName, isResolvable) {
8280
8308
  return packageName === "@camstack/system" && isResolvable;
8281
8309
  }
8310
+ /** How long a boot-time `dist-tags.latest` read may take before it is "unreadable". */
8311
+ var REGISTRY_LATEST_TIMEOUT_MS = 15e3;
8312
+ function readInstalledPackageVersion(addonDir) {
8313
+ try {
8314
+ const raw = JSON.parse(fs$1.readFileSync(path$1.join(addonDir, "package.json"), "utf-8"));
8315
+ if (raw === null || typeof raw !== "object") return null;
8316
+ const version = Reflect.get(raw, "version");
8317
+ return typeof version === "string" && version.length > 0 ? version : null;
8318
+ } catch {
8319
+ return null;
8320
+ }
8321
+ }
8322
+ function distTagLatest(body) {
8323
+ if (body === null || typeof body !== "object") return null;
8324
+ const tags = Reflect.get(body, "dist-tags");
8325
+ if (tags === null || typeof tags !== "object") return null;
8326
+ const latest = Reflect.get(tags, "latest");
8327
+ return typeof latest === "string" && latest.length > 0 ? latest : null;
8328
+ }
8282
8329
  /** Minimal no-op logger for default parameter */
8283
8330
  var noopLogger = {
8284
8331
  debug() {},
@@ -8329,6 +8376,7 @@ var AddonInstaller = class AddonInstaller {
8329
8376
  isPackageResolvable;
8330
8377
  /** Test seam — production resolves via `CAMSTACK_FRAMEWORK_DIR`. */
8331
8378
  closureNodeModulesDir;
8379
+ resolveLatestVersionOverride;
8332
8380
  /**
8333
8381
  * Central manifest of installed addons. Tracks version + source +
8334
8382
  * timestamps + last-backup pointer per package, written atomically
@@ -8351,6 +8399,7 @@ var AddonInstaller = class AddonInstaller {
8351
8399
  this.manifest = new AddonManifest(config.addonsDir);
8352
8400
  this.isPackageResolvable = config.isPackageResolvable;
8353
8401
  this.closureNodeModulesDir = config.closureNodeModulesDir;
8402
+ this.resolveLatestVersionOverride = config.resolveLatestVersion;
8354
8403
  if (config.installSource) this.installSource = config.installSource;
8355
8404
  else this.installSource = "npm";
8356
8405
  }
@@ -8464,10 +8513,13 @@ var AddonInstaller = class AddonInstaller {
8464
8513
  * defaults to npm in production.
8465
8514
  *
8466
8515
  * There is no version argument and there is deliberately no pin: the system is
8467
- * addons-agnostic and `latest` is the whole contract at first boot (operator,
8468
- * 2026-08-13). A copy already under the addon root is never replaced either —
8469
- * bootstrap is seed-only, and overwriting a deployed bundle would be an
8470
- * un-deploy ([D90](../../../../docs/decisions/adr-0090.md)).
8516
+ * addons-agnostic and `latest` is the whole contract (operator, 2026-08-13,
8517
+ * restated 2026-10-25 — D942). A copy already under the addon root is left
8518
+ * alone when this installer is not on the npm source (a workspace or a
8519
+ * bundled desktop seed) and when the package is the closure-provided
8520
+ * `@camstack/system` (a copy there would shadow the closure). Every other
8521
+ * required addon already on disk is moved to registry `latest` when that
8522
+ * tag differs, higher or lower. An unreadable registry changes nothing.
8471
8523
  *
8472
8524
  * @param packages — optional custom package list (default: REQUIRED_PACKAGES)
8473
8525
  */
@@ -8483,7 +8535,16 @@ var AddonInstaller = class AddonInstaller {
8483
8535
  for (const packageName of pkgList) {
8484
8536
  const addonDir = path$1.join(this.addonsDir, packageName);
8485
8537
  if (fs$1.existsSync(path$1.join(addonDir, "package.json"))) {
8486
- this.logger.debug(`${packageName} — already installed, skipping`);
8538
+ if (this.installSource !== "npm" || shouldSkipClosureProvidedSeed(packageName, this.isResolvableFromClosure(packageName))) {
8539
+ this.logger.debug(`${packageName} — already installed, skipping`);
8540
+ continue;
8541
+ }
8542
+ try {
8543
+ await this.followInstalledAddonToLatest(packageName, addonDir);
8544
+ } catch (err) {
8545
+ const msg = errMsg$1(err);
8546
+ this.logger.error(`Failed to move ${packageName} to registry latest`, { meta: { error: msg } });
8547
+ }
8487
8548
  continue;
8488
8549
  }
8489
8550
  if (shouldSkipClosureProvidedSeed(packageName, this.isResolvableFromClosure(packageName))) {
@@ -8508,6 +8569,56 @@ var AddonInstaller = class AddonInstaller {
8508
8569
  }
8509
8570
  }
8510
8571
  /**
8572
+ * Move an already-installed required addon to registry `latest` when the
8573
+ * installed version differs. `applyUpdate` keeps the previous tree as a
8574
+ * backup and restores it if the install throws. A null latest (registry
8575
+ * down, or no tag) leaves the copy where it is.
8576
+ */
8577
+ async followInstalledAddonToLatest(packageName, addonDir) {
8578
+ const installedVersion = readInstalledPackageVersion(addonDir);
8579
+ const decision = decideAddonVersionMove(installedVersion, await this.readRegistryLatest(packageName), ADDON_VERSION_REASON_REGISTRY_LATEST);
8580
+ if (!decision.move) {
8581
+ this.logger.debug(`${packageName} — installed copy matches registry latest, or the registry could not be read`);
8582
+ return;
8583
+ }
8584
+ this.logger.info(`${packageName} — moving ${decision.from} → ${decision.to}: ${decision.reason}`, { meta: {
8585
+ from: decision.from,
8586
+ to: decision.to,
8587
+ reason: decision.reason
8588
+ } });
8589
+ if (this.manifest.get(packageName) == null) this.manifest.upsert(packageName, {
8590
+ version: installedVersion ?? "0.0.0",
8591
+ source: "npm"
8592
+ });
8593
+ await this.applyUpdate(packageName, decision.to);
8594
+ }
8595
+ /** `dist-tags.latest`, or `null` when the registry cannot be read. */
8596
+ async readRegistryLatest(packageName) {
8597
+ if (this.resolveLatestVersionOverride) try {
8598
+ return await this.resolveLatestVersionOverride(packageName);
8599
+ } catch (err) {
8600
+ this.logger.warn(`${packageName} — registry unreadable, leaving the installed copy`, { meta: { error: errMsg$1(err) } });
8601
+ return null;
8602
+ }
8603
+ return this.fetchRegistryLatest(packageName);
8604
+ }
8605
+ async fetchRegistryLatest(packageName) {
8606
+ const metadataUrl = `${(this.registry ?? "https://registry.npmjs.org").replace(/\/+$/, "")}/${encodeURIComponent(packageName).replace(/^%40/, "@")}`;
8607
+ try {
8608
+ const metadataRes = await fetch(metadataUrl, { signal: AbortSignal.timeout(REGISTRY_LATEST_TIMEOUT_MS) });
8609
+ if (!metadataRes.ok) {
8610
+ this.logger.warn(`${packageName} — registry answered ${metadataRes.status}, leaving the installed copy`);
8611
+ return null;
8612
+ }
8613
+ const latest = distTagLatest(await metadataRes.json());
8614
+ if (latest === null) this.logger.warn(`${packageName} — registry returned no dist-tags.latest, leaving the installed copy`);
8615
+ return latest;
8616
+ } catch (err) {
8617
+ this.logger.warn(`${packageName} — registry unreadable, leaving the installed copy`, { meta: { error: errMsg$1(err) } });
8618
+ return null;
8619
+ }
8620
+ }
8621
+ /**
8511
8622
  * Reconcile the install manifest against the addons actually present on
8512
8623
  * disk: register seeded addons, correct a version that disagrees with the
8513
8624
  * installed `package.json`, and drop entries naming a directory that does
@@ -27767,4 +27878,4 @@ function resetCatalogRegistryForTests() {
27767
27878
  }
27768
27879
  //#endregion
27769
27880
  var readAllRows = import_read_all_rows.readAllRows;
27770
- export { AGENT_CAP_FWD_ACTION, AGENT_CAP_FWD_SERVICE, AGENT_DASHBOARD_ORIGINS_FIELD, AGENT_HTTPS_NAMES_COLLECTION, AGENT_HTTPS_NAMES_COLUMNS, AGENT_READINESS_SERVICE_NAME, AGENT_UI_UNLOCK_TTL_MS, AGENT_UI_UNLOCK_TYP, AGENT_UI_UNLOCK_USE, AGENT_UI_UNLOCK_VERSION, ALL_CAPABILITY_DEFINITIONS, ARRAY_BUFFER_CENSUS_COOLDOWN_MS, ARRAY_BUFFER_CENSUS_SUSTAIN_MS, ARRAY_BUFFER_CENSUS_THRESHOLD_MB, ARRAY_BUFFER_RELEASE_MIN_DROP_RATIO, AddonApiFactory, AddonDepsManager, AddonEngineManager, AddonHealthMonitor, AddonInstaller, AddonLoader, AddonManifest, AddonRefusedError, AddonRouteRegistry, AgentHttpsInstallError, AgentHttpsNames, AgentMdnsAdvertiser, AgentMeshIdentityGate, AgentPairing, AlertCenterAddon, AuthAuditLog, AuthManager, BackupDecryptError, BackupKeyFormatError, BackupKeyMismatchError, BackupKeyRequiredError, CAP_ACTION_OVERFLOW_LABEL, CAP_ACTION_UNLABELLED, CAP_METHOD_NOT_IMPLEMENTED, CA_COMMON_NAME, CA_VALIDITY_DAYS, CORE_CAP_SERVICE_NAME, CalendarsAddon, CapRouteError, CapRouteResolver, CapUsageRegistry, CapabilityHandle, CapabilityRegistry, CapabilityUnavailableError, CatalogRegistry, ClusterNodeHistoryBodySchema, ComposerAddon, ConfigManager, ConfigStore, ConsoleDestination, ConsoleLoggingAddon, CoreBlocksAddon, CustomActionRegistry, DECISIVE_HEAP_SPACES, DEFAULT_DATA_PATH, DEFAULT_HUB_TLS_TCP_PORT, DEFAULT_LAN_HTTP_PORT, DEFAULT_LOG_LEVEL, DEVICE_CA_KEY_REF, DEVICE_SETTINGS_CONTRIBUTION_METHODS, DEVICE_STATUS_METHOD, DataPlaneRegistry, DeviceCaStore, DeviceCredentialManager, DeviceHistoryAddon, DeviceManagerAddon, DeviceRegistry, DeviceStore, EMPTY_CAP_ACTION_READING, EMPTY_SOCKET_DIRECTION, EMPTY_SOCKET_PLANE_BASELINE, EVENT_PLANE_TOP_N, EVENT_TOPIC_PREFIX, EngineManagerResolver, EventBus, FIRST_BOOT_ADMIN_PASSWORD, FIRST_BOOT_ADMIN_USERNAME, FeatureManager, FilesystemStorageAddon, FilesystemStorageProvider, FrameDecoder, FsStorageBackend, GET_STATUS_METHOD, HEALTH_MONITOR_GRACE_PERIOD_MS, HEALTH_MONITOR_RETRY_INTERVALS_MS, HEALTH_MONITOR_TICK_MS, HEAP_RECLAIM_MIN_INTERVAL_MS, HEAP_RECLAIM_STEADY_STATE_INTERVAL_MS, HEAP_RECLAIM_TRIGGER_MB, HEAP_SPACE_REPORT_MIN_MB, HEAP_WATCH_INTERVAL_MS, HEAP_WATCH_WARN_RATIO, HUB_CAP_FWD_ACTION, HUB_CAP_FWD_SERVICE, HUB_MAIN_HEAP_WATCH_LABEL, HUB_MAIN_RSS_BUDGET_MB, HUB_RSS_BUDGET_ENV, HubForwarderAddon, HubForwarderDestination, HubLogForwarder, HubNodeRegistry, HubPairing, INFRA_CAPABILITIES, INTEGRATIONS_LEGACY, INTEGRATION_SETTINGS_LEGACY, IntegrationRegistry, JWT_SIGNING_KEY_REF, JobJournal, JwtSigningKeyUnavailableError, LEAF_RENEWAL_WINDOW_DAYS, LifecycleJobEngine, LifecycleStateMachine, LivenessMonitorAddon, LocalAuthAddon, LocalChildClient, LocalChildRegistry, LogManager, LogRingBuffer, LoggingGate, LoginSessionManager, LokiDestination, LokiLoggingAddon, MAX_CAP_ACTIONS_PER_PEER, MAX_LEAF_VALIDITY_DAYS, MESH_ACTION_FORBIDDEN_TYPE, MESH_CA_FIELD, MESH_CA_KEY_REF, MESH_CA_SETTINGS_KEY, MESH_NODE_CERTIFICATES_COLLECTION, MESH_NODE_CERTIFICATES_COLUMNS, MESH_NODE_UNAUTHENTICATED_TYPE, MESH_QUEUE_TOP_N, MESH_TLS_PORT_HELLO_FIELD, METHOD_ACCESS_MAP, MeshCaKeeper, MeshCertificateRegistry, MeshCrl, MeshIdentityGate, ModelDownloadService, NATIVE_PROVIDER_SERVICE_INFIX, NATIVE_SCAN_DEPTH, NativeMetricsAddon, NativeMetricsProvider, NetworkQualityTracker, NotificationService, OUTBOUND_QUEUE_COOLDOWN_MS, OUTBOUND_QUEUE_SUSTAIN_MS, OUTBOUND_QUEUE_THRESHOLD_BYTES, PAIRING_CODE_DIGITS, PAIRING_MAX_CODE_ATTEMPTS, PAIRING_MAX_SESSIONS, PAIRING_PATHS, PAIRING_PIN_DIGITS, PAIRING_PROTOCOL, PAIRING_TTL_MS, PARENT_ROUTED_PROVIDER_ADDON_ID, PERMITTED_DNS_SUFFIXES, PERMITTED_IP_RANGES, PREVIOUS_LEAF_GRACE_MS, PYTHON_VERSION, PairingHttpError, PeerAnsweredError, PipelineRunner, PipelineValidator, PythonEnvManager, QUARANTINE_DIRNAME, REFRESH_TOKEN_PREFIX, RENEWAL_ABANDONED, RESTART_MARKER_FILE, RSS_BUDGET_REANNOUNCE_MIN_MS, RSS_BUDGET_RELEASE_RATIO, RUNNER_HEAP_WATCH_INTERVAL_MS, RUNNER_RSS_BUDGET_ENV, RUNTIME_DEFAULTS, ReadinessRegistry, ReadinessTimeoutError, RecordsEngine, ReplEngine, RingBuffer, SERVER_AUTH_OID, SERVER_NAMESPACE, SOCKET_PLANE_TOP_N, SOCKET_QUEUE_TOP_N, STALL_REPORT_MS, STALL_TICK_MS, STORAGE_DRAIN_STATE_LEGACY, STORE_READABLE_BOOTSTRAP_KEYS, SYSTEM_SECRET_OWNER, ScopedLogger, SettingsReadUnavailableError, SocketChannel, SqliteSettingsAddon, SqliteSettingsBackend, StagingArea, StorageLocationManager, StorageManager, StorageOrchestratorAddon, StorageOrchestratorService, SystemBackupService, SystemConfigAddon, SystemEventBus, TRADITIONAL_NATIVE_PACKAGES, TlsTcpTransporter, ToastService, UDS_NO_ROUTE_PREFIX, UNCLAIMED, UPLOADED_CA_FILE, USER_MANAGEMENT_INTERNAL, UdsLocalTransportClient, UdsLocalTransportServer, UnlockTicketJtiStore, UserManager, WinstonDestination, WinstonLoggingAddon, ZERO_LOOP_DELAY, __resetCapUsageRegistryForTests, __resetLoggingGateForTests, acceptAgentSans, adaptBrokerToCluster, addonSettingsCapability, adoptModelRevisions, afterWorkerOnlineAnnounce, agentHttpsPaths, allFamiliesListenHost, answerClaimedGetStatus, applyCertificateToListener, applyLanHttp, asBrokerLike, attachUserManagementInternal, attributeStall, backupOrchestratorRecordKinds, backupRecordStoresOf, bareAddonOf, bindPendingLanHttp, bootstrapSchema, brokerCallForCap, brokerTransportLink, buildAgentAnnouncement, buildBinaryPath, buildCapRouters, buildHeapSample, buildLinkChain, buildNameConstraintSet, buildNativeCapProxy, buildNodeManifest, buildNpmChildEnv, buildStorageLocationRegistry, buildTransporter, builderMountedCapNames, caFingerprint, caFingerprintCompact, caReplacementMarkerFile, callRegisterNodeWithRetry, callWithServiceDiscovery, canServeDataPlane, capActionLabel, capActionName, capActionSuffix, capBareAction, capServiceName, catalogNamespaceOf, certificateNames, chainsToPublicRoot, checkUploadedCa, classifyAddonDir, classifyCapRoute, clearHttpsListener, clearPendingRestart, clearPlatformKeychainKey, closeLanHttp, clusterAgentRecordKinds, clusterEventTopic, clusterNodeHistoryRecordKind, collectAgentNames, collectCertIdentity, collectModelFiles, compileLogFilter, computePairingCommitment, computePairingSas, connectBrokerTransport, contentTypeFor, copyDirRecursive, copyExtraFileDirs, createAddonContext, createAddonDataPlaneFacility, createAddonPeerBytesFacility, createAddonService, createAgentEventScope, createAgentHttpsRequest, createAgentTransport, createArrayBufferCensusGate, createAuthenticatedFileServer, createBroker, createBrokerDeviceManagerApi, createCapActionCensus, createCiaoPublisher, createCidrMatcher, createCoreCapService, createCoreCatalogRegistry, createDeferredHeapWatchSink, createDoorSettingsView, createEventPlaneMeter, createEventPlaneReader, createFileDataPlaneHandler, createHubCapForwardService, createHubService, createInspectorArrayBufferCensus, createKernelHwAccel, createKernelInferenceEngine, createLocalTransport, createLoopDelayMeter, createMeshAccessMiddleware, createMeshCsrPem, createMeshQueueReader, createOutboundQueueGate, createParentUnownedCallHandler, createProcessService, createReadinessService, createReadinessServiceForRegistry, createScopedProcessManager, createSocketDirectionCounters, createSocketPlaneMeter, createSocketPlaneReader, createStreamProbeBrokerService, createUdsAddonContext, createUdsEventBridge, createUdsEventBus, createUdsLogger, createUdsLoggerWithControl, createV8Reclaimer, currentBrokerTransporter, deleteModelFromDisk, deriveAgentListenPort, describeCsr, describeHttpsLeaf, describeMeshLeaf, describeProviderKindDrift, describeRss, detectWorkspacePackagesDir, deviceCapResolverLink, deviceOfGetStatus, diffCapActionCensus, diffEventPlane, diffSocketPlane, disconnectBrokerTransport, downloadBinary, downloadFile, downloadModel, dropProcessPeer, emitDownForOwnedCaps, emitHeapDiagnosticReport, emitProcessNodeRegistered, encodeFrame, ensureAddonNativePrebuilds, ensureBinary, ensureDir, ensureFfmpeg, ensureLibraryBuilt, ensureModel, ensureNativePrebuilds, ensurePython, ensureTlsCert, evaluateExistingCert, expandCapMethods, exportMeshPrivateKeyPem, fetchJson, filterIsEmpty, findAddonRefusal, findInPath, formatArrayBufferCensus, formatEventPlane, formatHeapSpaces, formatLogLine, formatMeshQueue, formatOutboundQueueVerdict, formatSocketPlane, generateBackupKeyPair, generateDeviceCa, generateMeshCa, generateMeshKeyPair, getBrokerEventBus, getBrokerTlsTransporter, getCapUsageRegistry, getCatalogRegistry, getFfmpegDownloadUrl, getLoggingGate, getModelFilePath, getMoleculerEventStats, getOrInitReadinessRegistry, getOrInitReadinessRegistryForClient, getPidStats, getPlatformInfo, getPlatformKeychainKey, getProcessAgentHttpsNames, getProcessJwtSigningKeyState, getProcessMeshCaState, getProcessMeshCertificateRegistry, getProcessMeshTlsListenerState, getProcessNodeMeshTransport, getProcessPeerLeaf, getPythonDownloadUrl, getRestartMarkerPath, getSinglePidStats, getUserManagementInternal, getWorkerDeviceRegistry, hasDotNode, heapSpaceField, hostNodeIdOf, hubHostFromMeshAddress, hubMainRssBudget, installAgentHttps, installBrokerTransporter, installManifestNativeDeps, installManifestPythonDeps, installManifestSystemDeps, installPackageFromNpm, installPythonPackages, installPythonRequirements, integrationRegistryRecordKinds, ipcParentLink, isAddonDeploySource, isAllowedAgentDashboardReturnTo, isArrayBufferCensusReport, isArrayOutputSchema, isCollectionArrayMethod, isConstrainedCa, isContainerBridgeAddress, isCredentialKeyName, isInfraCapability, isInstalledTransporter, isLocalOnlyHostname, isModelDownloaded, isPeerEventPacket, isPrivateAddress, isProcessVerifiedMeshPeer, isRemoteForbiddenAction, isRemoteForbiddenOnAgent, isSettingsReadUnavailable, isSourceNewer, isValidAgentNodeId, isolatedBuiltinPhase, issueAgentHttpsLeaf, issueDeviceLeaf, issueMeshLeafForNode, issueMeshLeafFromCsr, keyFingerprintShort, leafFingerprintOf, levelRank, lineContainsText, lineMatches, loadAgentHttps, loadDeviceCa, loadMeshCa, loadTlsCert, localCaCommonName, localEndpointPath, localProviderLink, localSupportedPythonRuntimes, mapSignalsToInferenceHardware, meshErrorType, mintAgentUiUnlockTicket, mountNativeCapService, nextRssBudgetState, normalizeIp, onProcessNodeRegistered, onSessionsRevoked, openMeshTlsWhenRevocationsLoaded, originNodeOf, overlayGetStatus, parseAgentDashboardOrigins, parseCapAction, parseCidrList, parseRangeHeader, parseRssBudgetMb, parseTokenExpiry, parseTokenizedUrl, partitionIsolatedBuiltinIds, pemDigest, permitsIdentity, permitsName, pinnedHttpsCaFingerprint, preferencesLimitReasonOf, prepareBootTls, prepareRestoreArchive, probePlatform, processJwtSigningKey, processMeshCrl, proxyToUpstream, quarantineAddonResidue, readAllRows, readBackupEncryptionHeader, readCidrSetting, readExtraSans, readHeapSpaces, readLanHttpState, readNameConstraints, readPendingRestart, readSocketQueues, readTlsAccessStatus, readTlsMode, readinessKey, reclaimIntervalMs, recordSocketFrame, redactLogEntry, redactLogMeta, redactLogText, regenerateCertificate, registerEventBusService, registerHttpsListener, registerLanHttpHandler, reissueTlsLeaf, reloadHttpsListener, renewMeshCertificate, replaceUnconstrainedLocalCa, requireProcessMeshCa, resetCatalogRegistryForTests, resolveFilePath, resolveFormatRevision, resolveHwAccel, resolveNpmInvocation, retirePreviousLocalCa, revertToGeneratedCertificate, revisionWeightUrl, revokeMeshCertificate, runHubAddonBoot, runNpm, sampleSocketDirection, scheduleSelfRestart, scopeKey, scopesAllowAddon, scopesAllowDeviceCap, selectAddonResidue, selectReportedSpaces, serializeTypedArrays, servedHttpsLeafFingerprint, setHubConnected, setNodeEventInterest, setPlatformKeychainKey, setProcessAgentHttpsNames, setProcessMeshCertificateRegistry, setProcessMeshPeerTransportLookup, setProcessMeshTlsEnabler, setProcessMeshTlsListenerState, setWrapperActive, shouldReclaim, signPairingProof, signalAllRunnerGroups, socketDirectionBytes, socketDirectionMessages, splitPemCertificates, stampCallerAddonId, startEventLoopStallMonitor, startHeapWatch, startRunnerHeapWatch, staticJwtSigningKey, storageOrchestratorRecordKinds, storeMayAnswer, storeUploadedCertificate, strandedMb, stripCamstackDeps, stripForgedIdentity, stripForwardedCaller, subscribePassthrough, systemHostFacts, udsChildLogToWorkerEntry, useStoredUploadedCertificate, validateProviderRegistrations, validateUploadedTls, verifyAgentUiUnlockTicket, verifyDeviceLeaf, verifyDeviceSignature, verifyPairingProof, waitUntilReady, writeExtraSans, writePendingRestart, writeTlsMode };
27881
+ export { ADDON_VERSION_REASON_HUB, ADDON_VERSION_REASON_REGISTRY_LATEST, AGENT_CAP_FWD_ACTION, AGENT_CAP_FWD_SERVICE, AGENT_DASHBOARD_ORIGINS_FIELD, AGENT_HTTPS_NAMES_COLLECTION, AGENT_HTTPS_NAMES_COLUMNS, AGENT_READINESS_SERVICE_NAME, AGENT_UI_UNLOCK_TTL_MS, AGENT_UI_UNLOCK_TYP, AGENT_UI_UNLOCK_USE, AGENT_UI_UNLOCK_VERSION, ALL_CAPABILITY_DEFINITIONS, ARRAY_BUFFER_CENSUS_COOLDOWN_MS, ARRAY_BUFFER_CENSUS_SUSTAIN_MS, ARRAY_BUFFER_CENSUS_THRESHOLD_MB, ARRAY_BUFFER_RELEASE_MIN_DROP_RATIO, AddonApiFactory, AddonDepsManager, AddonEngineManager, AddonHealthMonitor, AddonInstaller, AddonLoader, AddonManifest, AddonRefusedError, AddonRouteRegistry, AgentHttpsInstallError, AgentHttpsNames, AgentMdnsAdvertiser, AgentMeshIdentityGate, AgentPairing, AlertCenterAddon, AuthAuditLog, AuthManager, BackupDecryptError, BackupKeyFormatError, BackupKeyMismatchError, BackupKeyRequiredError, CAP_ACTION_OVERFLOW_LABEL, CAP_ACTION_UNLABELLED, CAP_METHOD_NOT_IMPLEMENTED, CA_COMMON_NAME, CA_VALIDITY_DAYS, CORE_CAP_SERVICE_NAME, CalendarsAddon, CapRouteError, CapRouteResolver, CapUsageRegistry, CapabilityHandle, CapabilityRegistry, CapabilityUnavailableError, CatalogRegistry, ClusterNodeHistoryBodySchema, ComposerAddon, ConfigManager, ConfigStore, ConsoleDestination, ConsoleLoggingAddon, CoreBlocksAddon, CustomActionRegistry, DECISIVE_HEAP_SPACES, DEFAULT_DATA_PATH, DEFAULT_HUB_TLS_TCP_PORT, DEFAULT_LAN_HTTP_PORT, DEFAULT_LOG_LEVEL, DEVICE_CA_KEY_REF, DEVICE_SETTINGS_CONTRIBUTION_METHODS, DEVICE_STATUS_METHOD, DataPlaneRegistry, DeviceCaStore, DeviceCredentialManager, DeviceHistoryAddon, DeviceManagerAddon, DeviceRegistry, DeviceStore, EMPTY_CAP_ACTION_READING, EMPTY_SOCKET_DIRECTION, EMPTY_SOCKET_PLANE_BASELINE, EVENT_PLANE_TOP_N, EVENT_TOPIC_PREFIX, EngineManagerResolver, EventBus, FIRST_BOOT_ADMIN_PASSWORD, FIRST_BOOT_ADMIN_USERNAME, FeatureManager, FilesystemStorageAddon, FilesystemStorageProvider, FrameDecoder, FsStorageBackend, GET_STATUS_METHOD, HEALTH_MONITOR_GRACE_PERIOD_MS, HEALTH_MONITOR_RETRY_INTERVALS_MS, HEALTH_MONITOR_TICK_MS, HEAP_RECLAIM_MIN_INTERVAL_MS, HEAP_RECLAIM_STEADY_STATE_INTERVAL_MS, HEAP_RECLAIM_TRIGGER_MB, HEAP_SPACE_REPORT_MIN_MB, HEAP_WATCH_INTERVAL_MS, HEAP_WATCH_WARN_RATIO, HUB_CAP_FWD_ACTION, HUB_CAP_FWD_SERVICE, HUB_MAIN_HEAP_WATCH_LABEL, HUB_MAIN_RSS_BUDGET_MB, HUB_RSS_BUDGET_ENV, HubForwarderAddon, HubForwarderDestination, HubLogForwarder, HubNodeRegistry, HubPairing, INFRA_CAPABILITIES, INTEGRATIONS_LEGACY, INTEGRATION_SETTINGS_LEGACY, IntegrationRegistry, JWT_SIGNING_KEY_REF, JobJournal, JwtSigningKeyUnavailableError, LEAF_RENEWAL_WINDOW_DAYS, LifecycleJobEngine, LifecycleStateMachine, LivenessMonitorAddon, LocalAuthAddon, LocalChildClient, LocalChildRegistry, LogManager, LogRingBuffer, LoggingGate, LoginSessionManager, LokiDestination, LokiLoggingAddon, MAX_CAP_ACTIONS_PER_PEER, MAX_LEAF_VALIDITY_DAYS, MESH_ACTION_FORBIDDEN_TYPE, MESH_CA_FIELD, MESH_CA_KEY_REF, MESH_CA_SETTINGS_KEY, MESH_NODE_CERTIFICATES_COLLECTION, MESH_NODE_CERTIFICATES_COLUMNS, MESH_NODE_UNAUTHENTICATED_TYPE, MESH_QUEUE_TOP_N, MESH_TLS_PORT_HELLO_FIELD, METHOD_ACCESS_MAP, MeshCaKeeper, MeshCertificateRegistry, MeshCrl, MeshIdentityGate, ModelDownloadService, NATIVE_PROVIDER_SERVICE_INFIX, NATIVE_SCAN_DEPTH, NativeMetricsAddon, NativeMetricsProvider, NetworkQualityTracker, NotificationService, OUTBOUND_QUEUE_COOLDOWN_MS, OUTBOUND_QUEUE_SUSTAIN_MS, OUTBOUND_QUEUE_THRESHOLD_BYTES, PAIRING_CODE_DIGITS, PAIRING_MAX_CODE_ATTEMPTS, PAIRING_MAX_SESSIONS, PAIRING_PATHS, PAIRING_PIN_DIGITS, PAIRING_PROTOCOL, PAIRING_TTL_MS, PARENT_ROUTED_PROVIDER_ADDON_ID, PERMITTED_DNS_SUFFIXES, PERMITTED_IP_RANGES, PREVIOUS_LEAF_GRACE_MS, PYTHON_VERSION, PairingHttpError, PeerAnsweredError, PipelineRunner, PipelineValidator, PythonEnvManager, QUARANTINE_DIRNAME, REFRESH_TOKEN_PREFIX, RENEWAL_ABANDONED, RESTART_MARKER_FILE, RSS_BUDGET_REANNOUNCE_MIN_MS, RSS_BUDGET_RELEASE_RATIO, RUNNER_HEAP_WATCH_INTERVAL_MS, RUNNER_RSS_BUDGET_ENV, RUNTIME_DEFAULTS, ReadinessRegistry, ReadinessTimeoutError, RecordsEngine, ReplEngine, RingBuffer, SERVER_AUTH_OID, SERVER_NAMESPACE, SOCKET_PLANE_TOP_N, SOCKET_QUEUE_TOP_N, STALL_REPORT_MS, STALL_TICK_MS, STORAGE_DRAIN_STATE_LEGACY, STORE_READABLE_BOOTSTRAP_KEYS, SYSTEM_SECRET_OWNER, ScopedLogger, SettingsReadUnavailableError, SocketChannel, SqliteSettingsAddon, SqliteSettingsBackend, StagingArea, StorageLocationManager, StorageManager, StorageOrchestratorAddon, StorageOrchestratorService, SystemBackupService, SystemConfigAddon, SystemEventBus, TRADITIONAL_NATIVE_PACKAGES, TlsTcpTransporter, ToastService, UDS_NO_ROUTE_PREFIX, UNCLAIMED, UPLOADED_CA_FILE, USER_MANAGEMENT_INTERNAL, UdsLocalTransportClient, UdsLocalTransportServer, UnlockTicketJtiStore, UserManager, WinstonDestination, WinstonLoggingAddon, ZERO_LOOP_DELAY, __resetCapUsageRegistryForTests, __resetLoggingGateForTests, acceptAgentSans, adaptBrokerToCluster, addonSettingsCapability, adoptModelRevisions, afterWorkerOnlineAnnounce, agentHttpsPaths, allFamiliesListenHost, answerClaimedGetStatus, applyCertificateToListener, applyLanHttp, asBrokerLike, attachUserManagementInternal, attributeStall, backupOrchestratorRecordKinds, backupRecordStoresOf, bareAddonOf, bindPendingLanHttp, bootstrapSchema, brokerCallForCap, brokerTransportLink, buildAgentAnnouncement, buildBinaryPath, buildCapRouters, buildHeapSample, buildLinkChain, buildNameConstraintSet, buildNativeCapProxy, buildNodeManifest, buildNpmChildEnv, buildStorageLocationRegistry, buildTransporter, builderMountedCapNames, caFingerprint, caFingerprintCompact, caReplacementMarkerFile, callRegisterNodeWithRetry, callWithServiceDiscovery, canServeDataPlane, capActionLabel, capActionName, capActionSuffix, capBareAction, capServiceName, catalogNamespaceOf, certificateNames, chainsToPublicRoot, checkUploadedCa, classifyAddonDir, classifyCapRoute, clearHttpsListener, clearPendingRestart, clearPlatformKeychainKey, closeLanHttp, clusterAgentRecordKinds, clusterEventTopic, clusterNodeHistoryRecordKind, collectAgentNames, collectCertIdentity, collectModelFiles, compileLogFilter, computePairingCommitment, computePairingSas, connectBrokerTransport, contentTypeFor, copyDirRecursive, copyExtraFileDirs, createAddonContext, createAddonDataPlaneFacility, createAddonPeerBytesFacility, createAddonService, createAgentEventScope, createAgentHttpsRequest, createAgentTransport, createArrayBufferCensusGate, createAuthenticatedFileServer, createBroker, createBrokerDeviceManagerApi, createCapActionCensus, createCiaoPublisher, createCidrMatcher, createCoreCapService, createCoreCatalogRegistry, createDeferredHeapWatchSink, createDoorSettingsView, createEventPlaneMeter, createEventPlaneReader, createFileDataPlaneHandler, createHubCapForwardService, createHubService, createInspectorArrayBufferCensus, createKernelHwAccel, createKernelInferenceEngine, createLocalTransport, createLoopDelayMeter, createMeshAccessMiddleware, createMeshCsrPem, createMeshQueueReader, createOutboundQueueGate, createParentUnownedCallHandler, createProcessService, createReadinessService, createReadinessServiceForRegistry, createScopedProcessManager, createSocketDirectionCounters, createSocketPlaneMeter, createSocketPlaneReader, createStreamProbeBrokerService, createUdsAddonContext, createUdsEventBridge, createUdsEventBus, createUdsLogger, createUdsLoggerWithControl, createV8Reclaimer, currentBrokerTransporter, decideAddonVersionMove, deleteModelFromDisk, deriveAgentListenPort, describeCsr, describeHttpsLeaf, describeMeshLeaf, describeProviderKindDrift, describeRss, detectWorkspacePackagesDir, deviceCapResolverLink, deviceOfGetStatus, diffCapActionCensus, diffEventPlane, diffSocketPlane, disconnectBrokerTransport, downloadBinary, downloadFile, downloadModel, dropProcessPeer, emitDownForOwnedCaps, emitHeapDiagnosticReport, emitProcessNodeRegistered, encodeFrame, ensureAddonNativePrebuilds, ensureBinary, ensureDir, ensureFfmpeg, ensureLibraryBuilt, ensureModel, ensureNativePrebuilds, ensurePython, ensureTlsCert, evaluateExistingCert, expandCapMethods, exportMeshPrivateKeyPem, fetchJson, filterIsEmpty, findAddonRefusal, findInPath, formatArrayBufferCensus, formatEventPlane, formatHeapSpaces, formatLogLine, formatMeshQueue, formatOutboundQueueVerdict, formatSocketPlane, generateBackupKeyPair, generateDeviceCa, generateMeshCa, generateMeshKeyPair, getBrokerEventBus, getBrokerTlsTransporter, getCapUsageRegistry, getCatalogRegistry, getFfmpegDownloadUrl, getLoggingGate, getModelFilePath, getMoleculerEventStats, getOrInitReadinessRegistry, getOrInitReadinessRegistryForClient, getPidStats, getPlatformInfo, getPlatformKeychainKey, getProcessAgentHttpsNames, getProcessJwtSigningKeyState, getProcessMeshCaState, getProcessMeshCertificateRegistry, getProcessMeshTlsListenerState, getProcessNodeMeshTransport, getProcessPeerLeaf, getPythonDownloadUrl, getRestartMarkerPath, getSinglePidStats, getUserManagementInternal, getWorkerDeviceRegistry, hasDotNode, heapSpaceField, hostNodeIdOf, hubHostFromMeshAddress, hubMainRssBudget, installAgentHttps, installBrokerTransporter, installManifestNativeDeps, installManifestPythonDeps, installManifestSystemDeps, installPackageFromNpm, installPythonPackages, installPythonRequirements, integrationRegistryRecordKinds, ipcParentLink, isAddonDeploySource, isAllowedAgentDashboardReturnTo, isArrayBufferCensusReport, isArrayOutputSchema, isCollectionArrayMethod, isConstrainedCa, isContainerBridgeAddress, isCredentialKeyName, isInfraCapability, isInstalledTransporter, isLocalOnlyHostname, isModelDownloaded, isPeerEventPacket, isPrivateAddress, isProcessVerifiedMeshPeer, isRemoteForbiddenAction, isRemoteForbiddenOnAgent, isSettingsReadUnavailable, isSourceNewer, isValidAgentNodeId, isolatedBuiltinPhase, issueAgentHttpsLeaf, issueDeviceLeaf, issueMeshLeafForNode, issueMeshLeafFromCsr, keyFingerprintShort, leafFingerprintOf, levelRank, lineContainsText, lineMatches, loadAgentHttps, loadDeviceCa, loadMeshCa, loadTlsCert, localCaCommonName, localEndpointPath, localProviderLink, localSupportedPythonRuntimes, mapSignalsToInferenceHardware, meshErrorType, mintAgentUiUnlockTicket, mountNativeCapService, nextRssBudgetState, normalizeIp, onProcessNodeRegistered, onSessionsRevoked, openMeshTlsWhenRevocationsLoaded, originNodeOf, overlayGetStatus, parseAgentDashboardOrigins, parseCapAction, parseCidrList, parseRangeHeader, parseRssBudgetMb, parseTokenExpiry, parseTokenizedUrl, partitionIsolatedBuiltinIds, pemDigest, permitsIdentity, permitsName, pinnedHttpsCaFingerprint, preferencesLimitReasonOf, prepareBootTls, prepareRestoreArchive, probePlatform, processJwtSigningKey, processMeshCrl, proxyToUpstream, quarantineAddonResidue, readAllRows, readBackupEncryptionHeader, readCidrSetting, readExtraSans, readHeapSpaces, readLanHttpState, readNameConstraints, readPendingRestart, readSocketQueues, readTlsAccessStatus, readTlsMode, readinessKey, reclaimIntervalMs, recordSocketFrame, redactLogEntry, redactLogMeta, redactLogText, regenerateCertificate, registerEventBusService, registerHttpsListener, registerLanHttpHandler, reissueTlsLeaf, reloadHttpsListener, renewMeshCertificate, replaceUnconstrainedLocalCa, requireProcessMeshCa, resetCatalogRegistryForTests, resolveFilePath, resolveFormatRevision, resolveHwAccel, resolveNpmInvocation, retirePreviousLocalCa, revertToGeneratedCertificate, revisionWeightUrl, revokeMeshCertificate, runHubAddonBoot, runNpm, sampleSocketDirection, scheduleSelfRestart, scopeKey, scopesAllowAddon, scopesAllowDeviceCap, selectAddonResidue, selectReportedSpaces, serializeTypedArrays, servedHttpsLeafFingerprint, setHubConnected, setNodeEventInterest, setPlatformKeychainKey, setProcessAgentHttpsNames, setProcessMeshCertificateRegistry, setProcessMeshPeerTransportLookup, setProcessMeshTlsEnabler, setProcessMeshTlsListenerState, setWrapperActive, shouldReclaim, signPairingProof, signalAllRunnerGroups, socketDirectionBytes, socketDirectionMessages, splitPemCertificates, stampCallerAddonId, startEventLoopStallMonitor, startHeapWatch, startRunnerHeapWatch, staticJwtSigningKey, storageOrchestratorRecordKinds, storeMayAnswer, storeUploadedCertificate, strandedMb, stripCamstackDeps, stripForgedIdentity, stripForwardedCaller, subscribePassthrough, systemHostFacts, udsChildLogToWorkerEntry, useStoredUploadedCertificate, validateProviderRegistrations, validateUploadedTls, verifyAgentUiUnlockTicket, verifyDeviceLeaf, verifyDeviceSignature, verifyPairingProof, waitUntilReady, writeExtraSans, writePendingRestart, writeTlsMode };
@@ -61,6 +61,12 @@ export interface AddonInstallerConfig {
61
61
  * specs point it at a fabricated closure dir.
62
62
  */
63
63
  readonly closureNodeModulesDir?: string;
64
+ /**
65
+ * Resolve dist-tag `latest` for a package. `null` means the registry could
66
+ * not be read — the caller leaves the installed copy alone (D942, D49).
67
+ * Production leaves it unset and asks the registry; specs inject it.
68
+ */
69
+ readonly resolveLatestVersion?: (packageName: string) => Promise<string | null>;
64
70
  }
65
71
  import type { InstalledPackage, IScopedLogger } from "@camstack/types";
66
72
  import { AddonManifest } from "./addon-manifest.js";
@@ -123,6 +129,7 @@ export declare class AddonInstaller {
123
129
  private readonly isPackageResolvable?;
124
130
  /** Test seam — production resolves via `CAMSTACK_FRAMEWORK_DIR`. */
125
131
  private readonly closureNodeModulesDir;
132
+ private readonly resolveLatestVersionOverride;
126
133
  /**
127
134
  * Central manifest of installed addons. Tracks version + source +
128
135
  * timestamps + last-backup pointer per package, written atomically
@@ -206,15 +213,28 @@ export declare class AddonInstaller {
206
213
  * defaults to npm in production.
207
214
  *
208
215
  * There is no version argument and there is deliberately no pin: the system is
209
- * addons-agnostic and `latest` is the whole contract at first boot (operator,
210
- * 2026-08-13). A copy already under the addon root is never replaced either —
211
- * bootstrap is seed-only, and overwriting a deployed bundle would be an
212
- * un-deploy ([D90](../../../../docs/decisions/adr-0090.md)).
216
+ * addons-agnostic and `latest` is the whole contract (operator, 2026-08-13,
217
+ * restated 2026-10-25 — D942). A copy already under the addon root is left
218
+ * alone when this installer is not on the npm source (a workspace or a
219
+ * bundled desktop seed) and when the package is the closure-provided
220
+ * `@camstack/system` (a copy there would shadow the closure). Every other
221
+ * required addon already on disk is moved to registry `latest` when that
222
+ * tag differs, higher or lower. An unreadable registry changes nothing.
213
223
  *
214
224
  * @param packages — optional custom package list (default: REQUIRED_PACKAGES)
215
225
  */
216
226
  ensureRequiredPackages(packages?: readonly string[]): Promise<void>;
217
227
  /**
228
+ * Move an already-installed required addon to registry `latest` when the
229
+ * installed version differs. `applyUpdate` keeps the previous tree as a
230
+ * backup and restores it if the install throws. A null latest (registry
231
+ * down, or no tag) leaves the copy where it is.
232
+ */
233
+ private followInstalledAddonToLatest;
234
+ /** `dist-tags.latest`, or `null` when the registry cannot be read. */
235
+ private readRegistryLatest;
236
+ private fetchRegistryLatest;
237
+ /**
218
238
  * Reconcile the install manifest against the addons actually present on
219
239
  * disk: register seeded addons, correct a version that disagrees with the
220
240
  * installed `package.json`, and drop entries naming a directory that does
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Which version an installed addon should be running (D942).
3
+ *
4
+ * The hub's target is the registry dist-tag `latest`. An agent's target is
5
+ * the hub's installed version — never the registry, and never "strictly
6
+ * newer". A missing target is an unreadable authority: a failed read changes
7
+ * nothing (D49), including never a move downward because the registry or the
8
+ * hub could not be asked.
9
+ */
10
+ export declare const ADDON_VERSION_REASON_REGISTRY_LATEST: "installed version differs from registry latest";
11
+ export declare const ADDON_VERSION_REASON_HUB: "agent follows the hub installed version";
12
+ export type AddonVersionReason = typeof ADDON_VERSION_REASON_REGISTRY_LATEST | typeof ADDON_VERSION_REASON_HUB;
13
+ export type AddonVersionMove = {
14
+ readonly move: false;
15
+ } | {
16
+ readonly move: true;
17
+ readonly from: string;
18
+ readonly to: string;
19
+ readonly reason: AddonVersionReason;
20
+ };
21
+ /**
22
+ * Move when `installed` is not `target`. `target === null` (or empty) means
23
+ * the authority could not be read — keep whatever is installed.
24
+ * `installed === null` with a known target is a first install of that target.
25
+ */
26
+ export declare function decideAddonVersionMove(installed: string | null, target: string | null, reason: AddonVersionReason): AddonVersionMove;
@@ -3,6 +3,8 @@ export { AddonLoader } from "./addon-loader.js";
3
3
  export { AddonEngineManager } from "./addon-engine-manager.js";
4
4
  export type { AddonInstallerConfig, InstallSource, InstalledPackage } from "./addon-installer.js";
5
5
  export { AddonInstaller } from "./addon-installer.js";
6
+ export type { AddonVersionMove, AddonVersionReason } from "./addon-version-policy.js";
7
+ export { ADDON_VERSION_REASON_HUB, ADDON_VERSION_REASON_REGISTRY_LATEST, decideAddonVersionMove } from "./addon-version-policy.js";
6
8
  export type { AddonInstallSource, AddonManifestEntry, AddonManifestFile } from "./addon-manifest.js";
7
9
  export { AddonManifest } from "./addon-manifest.js";
8
10
  export type { AddonDirCandidate, QuarantinedEntry, ResidueQuarantineResult, ResidueReason, ResidueVerdict } from "./addon-residue.js";