camstack 1.2.89 → 1.2.91

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.
@@ -14522,7 +14522,7 @@ function date4(params) {
14522
14522
  // ../../node_modules/zod/v4/classic/external.js
14523
14523
  config(en_default());
14524
14524
 
14525
- // ../types/dist/sleep-B195W080.mjs
14525
+ // ../types/dist/sleep-CbBk_3GJ.mjs
14526
14526
  var WELL_KNOWN_TABS = [
14527
14527
  {
14528
14528
  id: "overview",
@@ -26134,6 +26134,21 @@ var TrackFlagFields = {
26134
26134
  markForTrain: external_exports.boolean().optional(),
26135
26135
  /** Operator marked this track for diagnostic attention. */
26136
26136
  debug: external_exports.boolean().optional(),
26137
+ /**
26138
+ * What the operator wants CHECKED on this track, in their own words.
26139
+ *
26140
+ * The flag alone says "look at this" and nothing about what for; a debug set
26141
+ * reviewed hours later is a list of tracks with no question attached. Bound
26142
+ * to `debug` on the WRITE side — the body clears it when `debug` goes off,
26143
+ * and refuses it on a track whose debug is off — so a note can never outlive
26144
+ * the attention it belongs to.
26145
+ *
26146
+ * `''` is a real value ("marked, nothing to add"); the ABSENT key means
26147
+ * "leave whatever is stored alone", which is what lets a surface turn debug
26148
+ * on without a note (a cancelled prompt) and what lets it edit the note
26149
+ * without touching the flag.
26150
+ */
26151
+ debugNote: external_exports.string().max(500).optional(),
26137
26152
  /** Operator favourited this track. Pins it against pruning. */
26138
26153
  favourited: external_exports.boolean().optional()
26139
26154
  };
@@ -26143,6 +26158,12 @@ var TrackFlagsSchema = external_exports.object({
26143
26158
  trackId: external_exports.string(),
26144
26159
  markForTrain: external_exports.boolean(),
26145
26160
  debug: external_exports.boolean(),
26161
+ /** The note as it STANDS after the write — never absent here (a track with no
26162
+ * note reports `''`), for the same reason the booleans are required: a
26163
+ * surface that has just written must be able to render the note it now owns
26164
+ * without a re-fetch, and an absent key would read as "unchanged" on a
26165
+ * screen that has no previous value to keep. */
26166
+ debugNote: external_exports.string(),
26146
26167
  favourited: external_exports.boolean(),
26147
26168
  /** The lifecycle state the boolean was derived from. Required here (unlike on
26148
26169
  * a track row) because this shape is only ever produced by the write body,
@@ -27197,11 +27218,20 @@ var pipelineAnalyticsCapability = {
27197
27218
  * staging is a deliberate action of the retrain page, which is also the only
27198
27219
  * thing that produces `trained` in the first place.
27199
27220
  *
27200
- * Returns the RESOLVED state of both flags (absent → `false`) plus the
27201
- * `retrainStatus` they were derived from, so a caller can drive its toggle
27202
- * — and render a `trained` badge — without a re-fetch. Rejects an unknown
27203
- * track, a new staging mark on a device already holding its full budget, and
27204
- * any `markForTrain` write against a trained track.
27221
+ * `debugNote` is the operator's sentence about WHAT to check on this track,
27222
+ * and it is bound to `debug`: writing `debug: false` clears it in the same
27223
+ * statement, and a note sent for a track whose debug is off (and is not
27224
+ * being turned on) is DROPPED with a warning rather than stored where
27225
+ * nothing will ever read it. An omitted `debugNote` leaves the stored one
27226
+ * alone — which is what lets a surface turn debug on when the operator
27227
+ * declined to type anything, without that refusal costing them the flag.
27228
+ *
27229
+ * Returns the RESOLVED state of all three flags (absent → `false`) plus the
27230
+ * note (absent → `''`) and the `retrainStatus` they were derived from, so a
27231
+ * caller can drive its toggle — and render a `trained` badge — without a
27232
+ * re-fetch. Rejects an unknown track, a new staging mark on a device already
27233
+ * holding its full budget, and any `markForTrain` write against a trained
27234
+ * track.
27205
27235
  */
27206
27236
  setTrackFlags: method(external_exports.object({
27207
27237
  /** Log/audit scope only — the trackId is globally unique on its own. */
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runDiscover
4
- } from "./chunk-BLJRLA7I.js";
4
+ } from "./chunk-ECD5A36V.js";
5
5
  import "./chunk-LMMQX4CK.js";
6
6
 
7
7
  // src/cli.ts
@@ -38,7 +38,7 @@ async function runServe(args) {
38
38
  ...typeof values.data === "string" ? { data: values.data } : {}
39
39
  };
40
40
  Object.assign(process.env, buildServeEnv(opts));
41
- await import("./launcher-POOJGOAQ.js");
41
+ await import("./launcher-FFY5TY3C.js");
42
42
  }
43
43
 
44
44
  // src/commands/agent.ts
@@ -83,7 +83,7 @@ async function runAgent(args) {
83
83
  ...typeof values.port === "string" ? { port: values.port } : {}
84
84
  };
85
85
  Object.assign(process.env, buildAgentEnv(opts));
86
- await import("./launcher-POOJGOAQ.js");
86
+ await import("./launcher-FFY5TY3C.js");
87
87
  }
88
88
 
89
89
  // src/commands/setup.ts
@@ -1130,7 +1130,7 @@ function isUnknown(_value) {
1130
1130
  return true;
1131
1131
  }
1132
1132
  async function resolveServerInteractive(presetNamespace) {
1133
- const { discoverNodes, resolveHubFromDiscovered, filterHubNodes, DEFAULT_HUB_HTTPS_PORT } = await import("./discover-FHE2CTRJ.js");
1133
+ const { discoverNodes, resolveHubFromDiscovered, filterHubNodes, DEFAULT_HUB_HTTPS_PORT } = await import("./discover-QUITQWRC.js");
1134
1134
  if (presetNamespace) {
1135
1135
  const spinner4 = clack.spinner();
1136
1136
  spinner4.start(`Discovering hub on LAN (namespace "${presetNamespace}")`);
@@ -5,7 +5,7 @@ import {
5
5
  filterHubNodes,
6
6
  resolveHubFromDiscovered,
7
7
  runDiscover
8
- } from "./chunk-BLJRLA7I.js";
8
+ } from "./chunk-ECD5A36V.js";
9
9
  import "./chunk-LMMQX4CK.js";
10
10
  export {
11
11
  DEFAULT_HUB_HTTPS_PORT,
@@ -23633,9 +23633,9 @@ var require_zod = __commonJS({
23633
23633
  }
23634
23634
  });
23635
23635
 
23636
- // ../system/dist/dist-DE3OH-FG.js
23637
- var require_dist_DE3OH_FG = __commonJS({
23638
- "../system/dist/dist-DE3OH-FG.js"(exports) {
23636
+ // ../system/dist/dist-0fjBDzUu.js
23637
+ var require_dist_0fjBDzUu = __commonJS({
23638
+ "../system/dist/dist-0fjBDzUu.js"(exports) {
23639
23639
  "use strict";
23640
23640
  var zod = require_zod();
23641
23641
  var EventCategory = /* @__PURE__ */ (function(EventCategory2) {
@@ -36840,6 +36840,21 @@ var require_dist_DE3OH_FG = __commonJS({
36840
36840
  markForTrain: zod.z.boolean().optional(),
36841
36841
  /** Operator marked this track for diagnostic attention. */
36842
36842
  debug: zod.z.boolean().optional(),
36843
+ /**
36844
+ * What the operator wants CHECKED on this track, in their own words.
36845
+ *
36846
+ * The flag alone says "look at this" and nothing about what for; a debug set
36847
+ * reviewed hours later is a list of tracks with no question attached. Bound
36848
+ * to `debug` on the WRITE side — the body clears it when `debug` goes off,
36849
+ * and refuses it on a track whose debug is off — so a note can never outlive
36850
+ * the attention it belongs to.
36851
+ *
36852
+ * `''` is a real value ("marked, nothing to add"); the ABSENT key means
36853
+ * "leave whatever is stored alone", which is what lets a surface turn debug
36854
+ * on without a note (a cancelled prompt) and what lets it edit the note
36855
+ * without touching the flag.
36856
+ */
36857
+ debugNote: zod.z.string().max(500).optional(),
36843
36858
  /** Operator favourited this track. Pins it against pruning. */
36844
36859
  favourited: zod.z.boolean().optional()
36845
36860
  };
@@ -36849,6 +36864,12 @@ var require_dist_DE3OH_FG = __commonJS({
36849
36864
  trackId: zod.z.string(),
36850
36865
  markForTrain: zod.z.boolean(),
36851
36866
  debug: zod.z.boolean(),
36867
+ /** The note as it STANDS after the write — never absent here (a track with no
36868
+ * note reports `''`), for the same reason the booleans are required: a
36869
+ * surface that has just written must be able to render the note it now owns
36870
+ * without a re-fetch, and an absent key would read as "unchanged" on a
36871
+ * screen that has no previous value to keep. */
36872
+ debugNote: zod.z.string(),
36852
36873
  favourited: zod.z.boolean(),
36853
36874
  /** The lifecycle state the boolean was derived from. Required here (unlike on
36854
36875
  * a track row) because this shape is only ever produced by the write body,
@@ -37902,11 +37923,20 @@ var require_dist_DE3OH_FG = __commonJS({
37902
37923
  * staging is a deliberate action of the retrain page, which is also the only
37903
37924
  * thing that produces `trained` in the first place.
37904
37925
  *
37905
- * Returns the RESOLVED state of both flags (absent → `false`) plus the
37906
- * `retrainStatus` they were derived from, so a caller can drive its toggle
37907
- * — and render a `trained` badge — without a re-fetch. Rejects an unknown
37908
- * track, a new staging mark on a device already holding its full budget, and
37909
- * any `markForTrain` write against a trained track.
37926
+ * `debugNote` is the operator's sentence about WHAT to check on this track,
37927
+ * and it is bound to `debug`: writing `debug: false` clears it in the same
37928
+ * statement, and a note sent for a track whose debug is off (and is not
37929
+ * being turned on) is DROPPED with a warning rather than stored where
37930
+ * nothing will ever read it. An omitted `debugNote` leaves the stored one
37931
+ * alone — which is what lets a surface turn debug on when the operator
37932
+ * declined to type anything, without that refusal costing them the flag.
37933
+ *
37934
+ * Returns the RESOLVED state of all three flags (absent → `false`) plus the
37935
+ * note (absent → `''`) and the `retrainStatus` they were derived from, so a
37936
+ * caller can drive its toggle — and render a `trained` badge — without a
37937
+ * re-fetch. Rejects an unknown track, a new staging mark on a device already
37938
+ * holding its full budget, and any `markForTrain` write against a trained
37939
+ * track.
37910
37940
  */
37911
37941
  setTrackFlags: method(zod.z.object({
37912
37942
  /** Log/audit scope only — the trackId is globally unique on its own. */
@@ -60079,7 +60109,7 @@ var require_alerts_addon = __commonJS({
60079
60109
  [Symbol.toStringTag]: { value: "Module" }
60080
60110
  });
60081
60111
  require_chunk_Cek0wNdY();
60082
- var require_dist10 = require_dist_DE3OH_FG();
60112
+ var require_dist10 = require_dist_0fjBDzUu();
60083
60113
  function selectExpired(alerts, cutoffMs) {
60084
60114
  return alerts.filter((a) => a.createdAt < cutoffMs).sort((a, b) => a.createdAt - b.createdAt).map((a) => a.id);
60085
60115
  }
@@ -60898,7 +60928,7 @@ var require_console_logging = __commonJS({
60898
60928
  [Symbol.toStringTag]: { value: "Module" }
60899
60929
  });
60900
60930
  require_chunk_Cek0wNdY();
60901
- var require_dist10 = require_dist_DE3OH_FG();
60931
+ var require_dist10 = require_dist_0fjBDzUu();
60902
60932
  var require_formatter = require_formatter_DqAKDlvN();
60903
60933
  var LEVEL_RANK = {
60904
60934
  debug: 0,
@@ -60992,7 +61022,7 @@ var require_core_blocks_addon = __commonJS({
60992
61022
  "use strict";
60993
61023
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
60994
61024
  var require_chunk = require_chunk_Cek0wNdY();
60995
- var require_dist10 = require_dist_DE3OH_FG();
61025
+ var require_dist10 = require_dist_0fjBDzUu();
60996
61026
  var node_crypto = __require("crypto");
60997
61027
  var node_fs_promises = __require("fs/promises");
60998
61028
  node_fs_promises = require_chunk.__toESM(node_fs_promises);
@@ -61889,11 +61919,11 @@ var require_core_blocks = __commonJS({
61889
61919
  }
61890
61920
  });
61891
61921
 
61892
- // ../system/dist/retired-settings-keys-BgUS9Rr3.js
61893
- var require_retired_settings_keys_BgUS9Rr3 = __commonJS({
61894
- "../system/dist/retired-settings-keys-BgUS9Rr3.js"(exports) {
61922
+ // ../system/dist/retired-settings-keys-pL2Nq6KT.js
61923
+ var require_retired_settings_keys_pL2Nq6KT = __commonJS({
61924
+ "../system/dist/retired-settings-keys-pL2Nq6KT.js"(exports) {
61895
61925
  "use strict";
61896
- var require_dist10 = require_dist_DE3OH_FG();
61926
+ var require_dist10 = require_dist_0fjBDzUu();
61897
61927
  function settingsStoreIsAuthoritativeHere(env) {
61898
61928
  const raw = (env["CAMSTACK_ROLE"] ?? "").trim().toLowerCase();
61899
61929
  return raw === "" || raw === "hub";
@@ -64107,8 +64137,8 @@ var require_device_manager_addon = __commonJS({
64107
64137
  [Symbol.toStringTag]: { value: "Module" }
64108
64138
  });
64109
64139
  require_chunk_Cek0wNdY();
64110
- var require_dist10 = require_dist_DE3OH_FG();
64111
- var require_retired_settings_keys = require_retired_settings_keys_BgUS9Rr3();
64140
+ var require_dist10 = require_dist_0fjBDzUu();
64141
+ var require_retired_settings_keys = require_retired_settings_keys_pL2Nq6KT();
64112
64142
  var node_crypto = __require("crypto");
64113
64143
  var _camstack_types_node = require_node();
64114
64144
  var JOB_HISTORY = 20;
@@ -65799,6 +65829,68 @@ var require_device_manager_addon = __commonJS({
65799
65829
  return linkedIds.filter((id) => picked.has(id));
65800
65830
  }
65801
65831
  var LINK_CANDIDATE_PROJECTION = { projection: "slim" };
65832
+ function findLocationInvisibleContainers(params) {
65833
+ const { selfId, selfLocation, resolvedIds, candidates } = params;
65834
+ if (selfLocation === null || selfLocation.length === 0) return [];
65835
+ const byParent = /* @__PURE__ */ new Map();
65836
+ for (const c of candidates) {
65837
+ if (c.parentDeviceId === null) continue;
65838
+ const bucket = byParent.get(c.parentDeviceId);
65839
+ if (bucket) bucket.push(c);
65840
+ else byParent.set(c.parentDeviceId, [c]);
65841
+ }
65842
+ const out = [];
65843
+ for (const c of candidates) {
65844
+ if (c.type !== require_dist10.DeviceType.Container) continue;
65845
+ if (c.id === selfId) continue;
65846
+ if (c.location !== selfLocation) continue;
65847
+ let anyResolved = false;
65848
+ let anyNullLocation = false;
65849
+ let descendantCount = 0;
65850
+ const visited = /* @__PURE__ */ new Set([c.id]);
65851
+ let frontier = [c.id];
65852
+ while (frontier.length > 0) {
65853
+ const next = [];
65854
+ for (const parentId of frontier) for (const child of byParent.get(parentId) ?? []) {
65855
+ if (visited.has(child.id)) continue;
65856
+ visited.add(child.id);
65857
+ descendantCount += 1;
65858
+ if (resolvedIds.has(child.id)) anyResolved = true;
65859
+ if (child.location === null) anyNullLocation = true;
65860
+ next.push(child.id);
65861
+ }
65862
+ frontier = next;
65863
+ }
65864
+ if (descendantCount > 0 && !anyResolved && anyNullLocation) out.push(c.id);
65865
+ }
65866
+ return out;
65867
+ }
65868
+ var INVISIBLE_CONTAINER_WARN_CAP = 4096;
65869
+ var warnedInvisibleContainers = /* @__PURE__ */ new Set();
65870
+ function warnLocationInvisibleContainers(pctx, cameraId, byId, all, resolved) {
65871
+ if (resolved.mode !== "auto") return;
65872
+ const selfLocation = byId.get(cameraId)?.location ?? null;
65873
+ if (selfLocation === null || selfLocation.length === 0) return;
65874
+ const invisible = findLocationInvisibleContainers({
65875
+ selfId: cameraId,
65876
+ selfLocation,
65877
+ resolvedIds: new Set(resolved.devices.map((d) => d.deviceId)),
65878
+ candidates: all
65879
+ });
65880
+ for (const containerId of invisible) {
65881
+ const key = `${cameraId}:${containerId}`;
65882
+ if (warnedInvisibleContainers.has(key)) continue;
65883
+ if (warnedInvisibleContainers.size >= INVISIBLE_CONTAINER_WARN_CAP) return;
65884
+ warnedInvisibleContainers.add(key);
65885
+ pctx.host.ctx.logger.warn("getLinkedDevices: container matches the camera location but is invisible to auto-link \u2014 its children carry no location; re-save the container location to realign", {
65886
+ tags: { deviceId: containerId },
65887
+ meta: {
65888
+ cameraId,
65889
+ location: selfLocation
65890
+ }
65891
+ });
65892
+ }
65893
+ }
65802
65894
  function resolveFor(deviceId, all, byId, blob) {
65803
65895
  const config = parseLinkedDevicesConfig(blob);
65804
65896
  const ids = resolveLinkedDeviceIds({
@@ -65828,7 +65920,10 @@ var require_device_manager_addon = __commonJS({
65828
65920
  async function getLinkedDevices(pctx, input) {
65829
65921
  const { deviceId } = input;
65830
65922
  const [all, blob] = await Promise.all([listAll(pctx, LINK_CANDIDATE_PROJECTION), pctx.settings.readDeviceStore(deviceId)]);
65831
- return resolveFor(deviceId, all, new Map(all.map((d) => [d.id, d])), blob);
65923
+ const byId = new Map(all.map((d) => [d.id, d]));
65924
+ const resolved = resolveFor(deviceId, all, byId, blob);
65925
+ warnLocationInvisibleContainers(pctx, deviceId, byId, all, resolved);
65926
+ return resolved;
65832
65927
  }
65833
65928
  async function getLinkedDevicesBatch(pctx, input) {
65834
65929
  const deviceIds = [...new Set(input.deviceIds)];
@@ -65841,10 +65936,14 @@ var require_device_manager_addon = __commonJS({
65841
65936
  return {};
65842
65937
  })))]);
65843
65938
  const byId = new Map(all.map((d) => [d.id, d]));
65844
- return deviceIds.map((deviceId, index) => ({
65845
- deviceId,
65846
- ...resolveFor(deviceId, all, byId, blobs[index] ?? {})
65847
- }));
65939
+ return deviceIds.map((deviceId, index) => {
65940
+ const resolved = resolveFor(deviceId, all, byId, blobs[index] ?? {});
65941
+ warnLocationInvisibleContainers(pctx, deviceId, byId, all, resolved);
65942
+ return {
65943
+ deviceId,
65944
+ ...resolved
65945
+ };
65946
+ });
65848
65947
  }
65849
65948
  async function buildLinkedDevicesContribution(pctx, deviceId) {
65850
65949
  const persisted = await pctx.metaStore.resolvePersistedById(deviceId);
@@ -66773,6 +66872,121 @@ var require_device_manager_addon = __commonJS({
66773
66872
  roleKeysKeptAtTarget: Object.keys(target.role).toSorted()
66774
66873
  };
66775
66874
  }
66875
+ var LOCATION_BACKFILL_MARKER_KEY = "locationBackfillVersion";
66876
+ function nearestLocatedAncestor(byId, startParentId) {
66877
+ const visited = /* @__PURE__ */ new Set();
66878
+ let cursor = startParentId;
66879
+ while (cursor !== null && !visited.has(cursor)) {
66880
+ visited.add(cursor);
66881
+ const ancestor = byId.get(cursor);
66882
+ if (!ancestor) return null;
66883
+ if (ancestor.location !== null) return ancestor;
66884
+ cursor = ancestor.parentDeviceId;
66885
+ }
66886
+ return null;
66887
+ }
66888
+ function planNullLocationFills(rows) {
66889
+ const byId = new Map(rows.map((r) => [r.id, r]));
66890
+ const plan = [];
66891
+ for (const row of rows) {
66892
+ if (row.location !== null) continue;
66893
+ if (row.parentDeviceId === null) continue;
66894
+ const hit = nearestLocatedAncestor(byId, row.parentDeviceId);
66895
+ if (hit === null) continue;
66896
+ if (hit.type !== require_dist10.DeviceType.Container) continue;
66897
+ if (hit.location === null) continue;
66898
+ plan.push({
66899
+ id: row.id,
66900
+ location: hit.location,
66901
+ ancestorId: hit.id
66902
+ });
66903
+ }
66904
+ return plan;
66905
+ }
66906
+ async function resolveInheritedLocation(rows, parentDeviceId) {
66907
+ const visited = /* @__PURE__ */ new Set();
66908
+ let cursor = parentDeviceId;
66909
+ while (cursor !== null && !visited.has(cursor)) {
66910
+ visited.add(cursor);
66911
+ const ancestor = await rows.get(cursor);
66912
+ if (ancestor === null) return null;
66913
+ if (ancestor.meta.location !== null) return ancestor.meta.type === require_dist10.DeviceType.Container ? ancestor.meta.location : null;
66914
+ cursor = ancestor.meta.parentDeviceId;
66915
+ }
66916
+ return null;
66917
+ }
66918
+ function groupByAncestor(fills) {
66919
+ const grouped = /* @__PURE__ */ new Map();
66920
+ for (const fill of fills) {
66921
+ const bucket = grouped.get(fill.ancestorId);
66922
+ if (bucket) bucket.push(fill);
66923
+ else grouped.set(fill.ancestorId, [fill]);
66924
+ }
66925
+ return grouped;
66926
+ }
66927
+ async function runLocationBackfillAtBoot(pctx, bootRows) {
66928
+ const logger = pctx.host.ctx.logger;
66929
+ const markerRaw = (await pctx.settings.readAddonStore())[LOCATION_BACKFILL_MARKER_KEY];
66930
+ const completedVersion = typeof markerRaw === "number" ? markerRaw : 0;
66931
+ let repaired = false;
66932
+ if (completedVersion < 1) {
66933
+ const patched = [];
66934
+ const failed = [];
66935
+ await pctx.metaStore.withMetaWriteLock(async () => {
66936
+ const plan = planNullLocationFills((await pctx.metaStore.rows.listAll()).map((r) => r.meta));
66937
+ for (const fill of plan) try {
66938
+ const current = await pctx.metaStore.rows.get(fill.id);
66939
+ if (current === null || current.meta.location !== null) continue;
66940
+ await pctx.metaStore.rows.patch(fill.id, { location: fill.location });
66941
+ patched.push(fill);
66942
+ } catch (err) {
66943
+ failed.push({
66944
+ id: fill.id,
66945
+ error: err
66946
+ });
66947
+ }
66948
+ });
66949
+ repaired = true;
66950
+ for (const [ancestorId, fills] of groupByAncestor(patched)) {
66951
+ pctx.host.ctx.eventBus.emit({
66952
+ id: (0, node_crypto.randomUUID)(),
66953
+ timestamp: /* @__PURE__ */ new Date(),
66954
+ source: {
66955
+ type: "device",
66956
+ id: ancestorId
66957
+ },
66958
+ category: require_dist10.EventCategory.DeviceMetaChanged,
66959
+ data: {
66960
+ deviceId: ancestorId,
66961
+ field: "location",
66962
+ value: fills[0]?.location ?? null
66963
+ }
66964
+ });
66965
+ logger.info("location backfill: aligned location-less descendants to their ancestor", {
66966
+ tags: { deviceId: ancestorId },
66967
+ meta: {
66968
+ location: fills[0]?.location,
66969
+ updatedIds: fills.map((f) => f.id)
66970
+ }
66971
+ });
66972
+ }
66973
+ if (failed.length > 0) logger.error("location backfill partially failed \u2014 retrying on the next boot", { meta: {
66974
+ failedIds: failed.map((f) => f.id),
66975
+ errors: failed.map((f) => f.error instanceof Error ? f.error.message : String(f.error))
66976
+ } });
66977
+ else await pctx.metaStore.withAddonStoreWriteLock(async () => {
66978
+ await pctx.settings.writeAddonStore({ [LOCATION_BACKFILL_MARKER_KEY]: 1 });
66979
+ });
66980
+ }
66981
+ const residual = planNullLocationFills((!repaired && bootRows !== void 0 ? bootRows : await pctx.metaStore.rows.listAll()).map((r) => r.meta));
66982
+ for (const [ancestorId, fills] of groupByAncestor(residual)) logger.warn("location cascade misaligned \u2014 location-less descendants under a located ancestor never match location auto-link; re-save the ancestor location to realign", {
66983
+ tags: { deviceId: ancestorId },
66984
+ meta: {
66985
+ location: fills[0]?.location,
66986
+ misalignedDescendantIds: fills.map((f) => f.id)
66987
+ }
66988
+ });
66989
+ }
66776
66990
  async function stampIntegrationId(metaStore, ctx, deviceId, integrationId) {
66777
66991
  await metaStore.withMetaWriteLock(async () => {
66778
66992
  if (!await metaStore.resolvePersistedById(deviceId)) throw new Error(`[device-manager] stampIntegrationId: unknown device id=${deviceId}`);
@@ -66926,7 +67140,7 @@ var require_device_manager_addon = __commonJS({
66926
67140
  async function registerDevice(pctx, input) {
66927
67141
  const { addonId, stableId, id, type, name, parentDeviceId, features, config } = input;
66928
67142
  const featuresArr = Array.isArray(features) ? [...features] : [];
66929
- const { isFirstRegistration, exportFingerprint, fingerprintChanged } = await pctx.metaStore.withMetaWriteLock(async () => {
67143
+ const { isFirstRegistration, exportFingerprint, fingerprintChanged, inheritedLocation, inheritedDescendantIds, inheritFailed } = await pctx.metaStore.withMetaWriteLock(async () => {
66930
67144
  const existingRow = await pctx.metaStore.rows.get(id);
66931
67145
  const existingMeta = existingRow?.meta;
66932
67146
  const wasRegistered = existingRow?.registered ?? false;
@@ -66938,6 +67152,10 @@ var require_device_manager_addon = __commonJS({
66938
67152
  deviceType: type,
66939
67153
  features: featuresArr
66940
67154
  });
67155
+ const priorLocation = existingMeta?.location ?? null;
67156
+ const resolvedParentId = parentDeviceId ?? null;
67157
+ const parentChanged = existingMeta !== void 0 && (existingMeta.parentDeviceId ?? null) !== resolvedParentId;
67158
+ const inherited = priorLocation === null && resolvedParentId !== null && (isFirst || parentChanged) ? await resolveInheritedLocation(pctx.metaStore.rows, resolvedParentId) : null;
66941
67159
  await pctx.metaStore.rows.upsertRegistration({
66942
67160
  deviceId: id,
66943
67161
  addonId,
@@ -66945,21 +67163,69 @@ var require_device_manager_addon = __commonJS({
66945
67163
  type,
66946
67164
  name: resolvedName,
66947
67165
  userNamed: wasUserNamed,
66948
- location: existingMeta?.location ?? null,
67166
+ location: priorLocation ?? inherited,
66949
67167
  disabled: existingMeta?.disabled ?? false,
66950
- parentDeviceId: parentDeviceId ?? null,
67168
+ parentDeviceId: resolvedParentId,
66951
67169
  registered: true,
66952
67170
  features: featuresArr,
66953
67171
  exportFingerprint: fingerprint
66954
67172
  });
67173
+ const descendantsFilled = [];
67174
+ const descendantsFailed = [];
67175
+ if (inherited !== null) for (const descendant of await collectDescendants(pctx.metaStore, id)) {
67176
+ if (descendant.location !== null) continue;
67177
+ try {
67178
+ await pctx.metaStore.rows.patch(descendant.id, { location: inherited });
67179
+ descendantsFilled.push(descendant.id);
67180
+ } catch (err) {
67181
+ descendantsFailed.push({
67182
+ id: descendant.id,
67183
+ error: err
67184
+ });
67185
+ }
67186
+ }
66955
67187
  return {
66956
67188
  isFirstRegistration: isFirst,
66957
67189
  exportFingerprint: fingerprint,
66958
- fingerprintChanged: existingMeta?.exportFingerprint !== fingerprint
67190
+ fingerprintChanged: existingMeta?.exportFingerprint !== fingerprint,
67191
+ inheritedLocation: inherited,
67192
+ inheritedDescendantIds: descendantsFilled,
67193
+ inheritFailed: descendantsFailed
66959
67194
  };
66960
67195
  });
66961
67196
  if (Object.keys(config).length > 0) await pctx.settings.writeDeviceStore(id, config);
66962
67197
  pctx.metaStore.idToAddonId.set(id, addonId);
67198
+ if (inheritedLocation !== null) {
67199
+ for (const changedId of [id, ...inheritedDescendantIds]) pctx.host.ctx.eventBus.emit({
67200
+ id: (0, node_crypto.randomUUID)(),
67201
+ timestamp: /* @__PURE__ */ new Date(),
67202
+ source: {
67203
+ type: "device",
67204
+ id: changedId
67205
+ },
67206
+ category: require_dist10.EventCategory.DeviceMetaChanged,
67207
+ data: {
67208
+ deviceId: changedId,
67209
+ field: "location",
67210
+ value: inheritedLocation
67211
+ }
67212
+ });
67213
+ pctx.host.ctx.logger.info("registerDevice: inherited located-ancestor location", {
67214
+ tags: { deviceId: id },
67215
+ meta: {
67216
+ location: inheritedLocation,
67217
+ descendantsFilled: inheritedDescendantIds.length
67218
+ }
67219
+ });
67220
+ if (inheritFailed.length > 0) pctx.host.ctx.logger.error("registerDevice: inherited-location fill partially failed \u2014 some descendants NOT aligned", {
67221
+ tags: { deviceId: id },
67222
+ meta: {
67223
+ location: inheritedLocation,
67224
+ failedIds: inheritFailed.map((f) => f.id),
67225
+ errors: inheritFailed.map((f) => f.error instanceof Error ? f.error.message : String(f.error))
67226
+ }
67227
+ });
67228
+ }
66963
67229
  if (isFirstRegistration) pctx.host.ctx.eventBus.emit({
66964
67230
  id: (0, node_crypto.randomUUID)(),
66965
67231
  timestamp: /* @__PURE__ */ new Date(),
@@ -69142,7 +69408,8 @@ var require_device_manager_addon = __commonJS({
69142
69408
  const stateMirror = this.stateMirrorImpl;
69143
69409
  const resolvePersistedById = metaStore.resolvePersistedById;
69144
69410
  const idToAddonId = metaStore.idToAddonId;
69145
- for (const row of await deviceRows.listAll()) idToAddonId.set(row.meta.id, row.meta.addonId);
69411
+ const bootRows = await deviceRows.listAll();
69412
+ for (const row of bootRows) idToAddonId.set(row.meta.id, row.meta.addonId);
69146
69413
  const stampIntegrationId$1 = (deviceId, integrationId) => stampIntegrationId(metaStore, this.ctx, deviceId, integrationId);
69147
69414
  const pctx = {
69148
69415
  host: this.providerHost,
@@ -69157,6 +69424,11 @@ var require_device_manager_addon = __commonJS({
69157
69424
  return provider;
69158
69425
  }
69159
69426
  };
69427
+ try {
69428
+ await runLocationBackfillAtBoot(pctx, bootRows);
69429
+ } catch (err) {
69430
+ this.ctx.logger.warn("location backfill failed \u2014 fleet boots without it", { meta: { error: require_dist10.errMsg(err) } });
69431
+ }
69160
69432
  const provider = {
69161
69433
  resolveDeviceOwnerSync: (deviceId) => resolveDeviceOwnerSync(pctx, deviceId),
69162
69434
  resolveNativeCapOwnerSync: (capName, deviceId) => resolveNativeCapOwnerSync(pctx, capName, deviceId),
@@ -69392,7 +69664,7 @@ var require_hub_forwarder = __commonJS({
69392
69664
  [Symbol.toStringTag]: { value: "Module" }
69393
69665
  });
69394
69666
  require_chunk_Cek0wNdY();
69395
- var require_dist10 = require_dist_DE3OH_FG();
69667
+ var require_dist10 = require_dist_0fjBDzUu();
69396
69668
  var require_formatter = require_formatter_DqAKDlvN();
69397
69669
  var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
69398
69670
  var HubForwarderDestination = class {
@@ -69529,7 +69801,7 @@ var require_liveness_monitor_addon = __commonJS({
69529
69801
  "use strict";
69530
69802
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
69531
69803
  require_chunk_Cek0wNdY();
69532
- var require_dist10 = require_dist_DE3OH_FG();
69804
+ var require_dist10 = require_dist_0fjBDzUu();
69533
69805
  var NO_DEVICES = "liveness:no-devices";
69534
69806
  var ALL_OFFLINE = "liveness:all-devices-offline";
69535
69807
  var NO_FOOTAGE_PREFIX = "liveness:no-footage:";
@@ -69719,7 +69991,7 @@ var require_local_auth_addon = __commonJS({
69719
69991
  [Symbol.toStringTag]: { value: "Module" }
69720
69992
  });
69721
69993
  var require_chunk = require_chunk_Cek0wNdY();
69722
- var require_dist10 = require_dist_DE3OH_FG();
69994
+ var require_dist10 = require_dist_0fjBDzUu();
69723
69995
  var node_crypto = __require("crypto");
69724
69996
  node_crypto = require_chunk.__toESM(node_crypto);
69725
69997
  var crypto$1 = __require("crypto");
@@ -77532,7 +77804,7 @@ var require_loki_logging = __commonJS({
77532
77804
  [Symbol.toStringTag]: { value: "Module" }
77533
77805
  });
77534
77806
  require_chunk_Cek0wNdY();
77535
- var require_dist10 = require_dist_DE3OH_FG();
77807
+ var require_dist10 = require_dist_0fjBDzUu();
77536
77808
  function sanitizeLabelName(raw) {
77537
77809
  const replaced = raw.replaceAll(/[^a-zA-Z0-9_]/g, "_");
77538
77810
  return /^[a-zA-Z_]/.test(replaced) ? replaced : `_${replaced}`;
@@ -78097,7 +78369,7 @@ var require_native_metrics_addon = __commonJS({
78097
78369
  [Symbol.toStringTag]: { value: "Module" }
78098
78370
  });
78099
78371
  var require_chunk = require_chunk_Cek0wNdY();
78100
- var require_dist10 = require_dist_DE3OH_FG();
78372
+ var require_dist10 = require_dist_0fjBDzUu();
78101
78373
  var node_fs_promises = __require("fs/promises");
78102
78374
  var node_child_process = __require("child_process");
78103
78375
  var node_util = __require("util");
@@ -80681,7 +80953,7 @@ var require_filesystem_storage_addon = __commonJS({
80681
80953
  [Symbol.toStringTag]: { value: "Module" }
80682
80954
  });
80683
80955
  var require_chunk = require_chunk_Cek0wNdY();
80684
- var require_dist10 = require_dist_DE3OH_FG();
80956
+ var require_dist10 = require_dist_0fjBDzUu();
80685
80957
  var node_crypto = __require("crypto");
80686
80958
  var node_fs_promises = __require("fs/promises");
80687
80959
  var node_path = __require("path");
@@ -81797,8 +82069,8 @@ var require_sqlite_settings_addon = __commonJS({
81797
82069
  [Symbol.toStringTag]: { value: "Module" }
81798
82070
  });
81799
82071
  var require_chunk = require_chunk_Cek0wNdY();
81800
- var require_dist10 = require_dist_DE3OH_FG();
81801
- var require_retired_settings_keys = require_retired_settings_keys_BgUS9Rr3();
82072
+ var require_dist10 = require_dist_0fjBDzUu();
82073
+ var require_retired_settings_keys = require_retired_settings_keys_pL2Nq6KT();
81802
82074
  var node_crypto = __require("crypto");
81803
82075
  var node_fs = __require("fs");
81804
82076
  var node_module = __require("module");
@@ -84288,7 +84560,7 @@ var require_storage_orchestrator_addon = __commonJS({
84288
84560
  [Symbol.toStringTag]: { value: "Module" }
84289
84561
  });
84290
84562
  var require_chunk = require_chunk_Cek0wNdY();
84291
- var require_dist10 = require_dist_DE3OH_FG();
84563
+ var require_dist10 = require_dist_0fjBDzUu();
84292
84564
  var require_hub_cap_forward = require_hub_cap_forward_DmHNjbB0();
84293
84565
  var zod = require_zod();
84294
84566
  var node_crypto = __require("crypto");
@@ -87239,7 +87511,7 @@ var require_system_config_addon = __commonJS({
87239
87511
  [Symbol.toStringTag]: { value: "Module" }
87240
87512
  });
87241
87513
  require_chunk_Cek0wNdY();
87242
- var require_dist10 = require_dist_DE3OH_FG();
87514
+ var require_dist10 = require_dist_0fjBDzUu();
87243
87515
  var SECTION_TITLES = {
87244
87516
  server: "Server",
87245
87517
  auth: "Authentication"
@@ -105300,7 +105572,7 @@ var require_winston_logging = __commonJS({
105300
105572
  [Symbol.toStringTag]: { value: "Module" }
105301
105573
  });
105302
105574
  var require_chunk = require_chunk_Cek0wNdY();
105303
- var require_dist10 = require_dist_DE3OH_FG();
105575
+ var require_dist10 = require_dist_0fjBDzUu();
105304
105576
  var require_formatter = require_formatter_DqAKDlvN();
105305
105577
  var node_path = __require("path");
105306
105578
  node_path = require_chunk.__toESM(node_path);
@@ -107243,9 +107515,9 @@ var require_event_category_BaEgqJNv = __commonJS({
107243
107515
  }
107244
107516
  });
107245
107517
 
107246
- // ../types/dist/sleep-jdpPltQH.js
107247
- var require_sleep_jdpPltQH = __commonJS({
107248
- "../types/dist/sleep-jdpPltQH.js"(exports) {
107518
+ // ../types/dist/sleep-BtIF8lWc.js
107519
+ var require_sleep_BtIF8lWc = __commonJS({
107520
+ "../types/dist/sleep-BtIF8lWc.js"(exports) {
107249
107521
  "use strict";
107250
107522
  var require_event_category = require_event_category_BaEgqJNv();
107251
107523
  var zod = require_zod();
@@ -109236,6 +109508,7 @@ var require_sleep_jdpPltQH = __commonJS({
109236
109508
  DeviceRole2["GenericNotifier"] = "generic-notifier";
109237
109509
  return DeviceRole2;
109238
109510
  })({});
109511
+ var DEVICE_CHILDREN_BATCH_MAX = 256;
109239
109512
  var StaticDirOutputSchema = zod.z.object({ staticDir: zod.z.string() });
109240
109513
  var VersionOutputSchema = zod.z.object({ version: zod.z.string() });
109241
109514
  var viewerUiCapability = {
@@ -110490,6 +110763,12 @@ var require_sleep_jdpPltQH = __commonJS({
110490
110763
  return DEFAULT_RUNTIME_STATE_DURABILITY;
110491
110764
  }
110492
110765
  });
110766
+ Object.defineProperty(exports, "DEVICE_CHILDREN_BATCH_MAX", {
110767
+ enumerable: true,
110768
+ get: function() {
110769
+ return DEVICE_CHILDREN_BATCH_MAX;
110770
+ }
110771
+ });
110493
110772
  Object.defineProperty(exports, "DEVICE_SCOPED_CAPS", {
110494
110773
  enumerable: true,
110495
110774
  get: function() {
@@ -110919,7 +111198,7 @@ var require_addon = __commonJS({
110919
111198
  "use strict";
110920
111199
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
110921
111200
  var require_event_category = require_event_category_BaEgqJNv();
110922
- var require_sleep = require_sleep_jdpPltQH();
111201
+ var require_sleep = require_sleep_BtIF8lWc();
110923
111202
  var require_err_msg = require_err_msg_COpsHMw2();
110924
111203
  var CAP_INPUT_DEFAULTS = Object.freeze({
110925
111204
  "addons": { "getLogs": { "limit": 100 } },
@@ -111237,6 +111516,7 @@ var require_addon = __commonJS({
111237
111516
  exports.CAP_INPUT_DEFAULTS = CAP_INPUT_DEFAULTS;
111238
111517
  exports.COLLECTION_ARRAY_METHODS = COLLECTION_ARRAY_METHODS;
111239
111518
  exports.DATAPLANE_SECRET_HEADER = require_sleep.DATAPLANE_SECRET_HEADER;
111519
+ exports.DEVICE_CHILDREN_BATCH_MAX = require_sleep.DEVICE_CHILDREN_BATCH_MAX;
111240
111520
  exports.DEVICE_SCOPED_CAPS = require_sleep.DEVICE_SCOPED_CAPS;
111241
111521
  exports.DeviceType = require_sleep.DeviceType;
111242
111522
  exports.DisposerChain = require_sleep.DisposerChain;
@@ -117802,12 +118082,11 @@ var require_dist2 = __commonJS({
117802
118082
  }
117803
118083
  });
117804
118084
 
117805
- // ../system/dist/manifest-system-deps-DMWd5Ygf.js
117806
- var require_manifest_system_deps_DMWd5Ygf = __commonJS({
117807
- "../system/dist/manifest-system-deps-DMWd5Ygf.js"(exports) {
118085
+ // ../system/dist/manifest-system-deps-KBuTXH-y.js
118086
+ var require_manifest_system_deps_KBuTXH_y = __commonJS({
118087
+ "../system/dist/manifest-system-deps-KBuTXH-y.js"(exports) {
117808
118088
  "use strict";
117809
118089
  var require_chunk = require_chunk_Cek0wNdY();
117810
- require_dist_DE3OH_FG();
117811
118090
  require_hub_cap_forward_DmHNjbB0();
117812
118091
  var node_crypto = __require("crypto");
117813
118092
  node_crypto = require_chunk.__toESM(node_crypto);
@@ -119305,7 +119584,7 @@ var require_manifest_system_deps_DMWd5Ygf = __commonJS({
119305
119584
  return lowered.includes("not_found") || lowered.includes("no procedure") || lowered.includes("unknown method") || lowered.includes("no such method") || lowered.includes("not available");
119306
119585
  }
119307
119586
  function createChildrenBatchLoader(opts) {
119308
- const maxBatch = Math.max(1, opts.maxBatch ?? 256);
119587
+ const maxBatch = Math.max(1, opts.maxBatch ?? _camstack_types_addon.DEVICE_CHILDREN_BATCH_MAX);
119309
119588
  let pending = [];
119310
119589
  let flushScheduled = false;
119311
119590
  let flushing = false;
@@ -129874,7 +130153,7 @@ var require_dist3 = __commonJS({
129874
130153
  "use strict";
129875
130154
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
129876
130155
  var require_chunk = require_chunk_Cek0wNdY();
129877
- var require_dist10 = require_dist_DE3OH_FG();
130156
+ var require_dist10 = require_dist_0fjBDzUu();
129878
130157
  var require_builtins_alerts_alerts_addon = require_alerts_addon();
129879
130158
  require_alerts();
129880
130159
  var require_formatter = require_formatter_DqAKDlvN();
@@ -129901,7 +130180,7 @@ var require_dist3 = __commonJS({
129901
130180
  var require_builtins_winston_logging_index = require_winston_logging();
129902
130181
  var require_file_data_plane = require_file_data_plane_DO8KbxCe();
129903
130182
  var require_tls$1 = require_tls_BxQlomxd();
129904
- var require_manifest_system_deps = require_manifest_system_deps_DMWd5Ygf();
130183
+ var require_manifest_system_deps = require_manifest_system_deps_KBuTXH_y();
129905
130184
  var require_resource_monitor = require_resource_monitor_CdnzxBLP();
129906
130185
  var require_custom_action_registry = require_custom_action_registry_jY0NOZK8();
129907
130186
  var zod = require_zod();
@@ -210991,7 +211270,7 @@ var require_dist4 = __commonJS({
210991
211270
  "use strict";
210992
211271
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
210993
211272
  var require_event_category = require_event_category_BaEgqJNv();
210994
- var require_sleep = require_sleep_jdpPltQH();
211273
+ var require_sleep = require_sleep_BtIF8lWc();
210995
211274
  var require_canonical_hash = require_canonical_hash_DNV8S5ET();
210996
211275
  var require_enums2 = require_enums();
210997
211276
  var require_err_msg = require_err_msg_COpsHMw2();
@@ -218451,7 +218730,6 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
218451
218730
  })
218452
218731
  }
218453
218732
  };
218454
- var DEVICE_CHILDREN_BATCH_MAX = 256;
218455
218733
  var ChildLayoutEntrySchema = zod.z.object({
218456
218734
  childKey: zod.z.string(),
218457
218735
  section: zod.z.string(),
@@ -224869,12 +225147,28 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
224869
225147
  "staging",
224870
225148
  "trained"
224871
225149
  ]);
225150
+ var MAX_TRACK_DEBUG_NOTE_LEN = 500;
224872
225151
  var TrackFlagFields = {
224873
225152
  /** Operator marked this track as training material — i.e. `retrainStatus` is
224874
225153
  * `'staging'`. */
224875
225154
  markForTrain: zod.z.boolean().optional(),
224876
225155
  /** Operator marked this track for diagnostic attention. */
224877
225156
  debug: zod.z.boolean().optional(),
225157
+ /**
225158
+ * What the operator wants CHECKED on this track, in their own words.
225159
+ *
225160
+ * The flag alone says "look at this" and nothing about what for; a debug set
225161
+ * reviewed hours later is a list of tracks with no question attached. Bound
225162
+ * to `debug` on the WRITE side — the body clears it when `debug` goes off,
225163
+ * and refuses it on a track whose debug is off — so a note can never outlive
225164
+ * the attention it belongs to.
225165
+ *
225166
+ * `''` is a real value ("marked, nothing to add"); the ABSENT key means
225167
+ * "leave whatever is stored alone", which is what lets a surface turn debug
225168
+ * on without a note (a cancelled prompt) and what lets it edit the note
225169
+ * without touching the flag.
225170
+ */
225171
+ debugNote: zod.z.string().max(500).optional(),
224878
225172
  /** Operator favourited this track. Pins it against pruning. */
224879
225173
  favourited: zod.z.boolean().optional()
224880
225174
  };
@@ -224884,6 +225178,12 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
224884
225178
  trackId: zod.z.string(),
224885
225179
  markForTrain: zod.z.boolean(),
224886
225180
  debug: zod.z.boolean(),
225181
+ /** The note as it STANDS after the write — never absent here (a track with no
225182
+ * note reports `''`), for the same reason the booleans are required: a
225183
+ * surface that has just written must be able to render the note it now owns
225184
+ * without a re-fetch, and an absent key would read as "unchanged" on a
225185
+ * screen that has no previous value to keep. */
225186
+ debugNote: zod.z.string(),
224887
225187
  favourited: zod.z.boolean(),
224888
225188
  /** The lifecycle state the boolean was derived from. Required here (unlike on
224889
225189
  * a track row) because this shape is only ever produced by the write body,
@@ -225939,11 +226239,20 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
225939
226239
  * staging is a deliberate action of the retrain page, which is also the only
225940
226240
  * thing that produces `trained` in the first place.
225941
226241
  *
225942
- * Returns the RESOLVED state of both flags (absent → `false`) plus the
225943
- * `retrainStatus` they were derived from, so a caller can drive its toggle
225944
- * — and render a `trained` badge — without a re-fetch. Rejects an unknown
225945
- * track, a new staging mark on a device already holding its full budget, and
225946
- * any `markForTrain` write against a trained track.
226242
+ * `debugNote` is the operator's sentence about WHAT to check on this track,
226243
+ * and it is bound to `debug`: writing `debug: false` clears it in the same
226244
+ * statement, and a note sent for a track whose debug is off (and is not
226245
+ * being turned on) is DROPPED with a warning rather than stored where
226246
+ * nothing will ever read it. An omitted `debugNote` leaves the stored one
226247
+ * alone — which is what lets a surface turn debug on when the operator
226248
+ * declined to type anything, without that refusal costing them the flag.
226249
+ *
226250
+ * Returns the RESOLVED state of all three flags (absent → `false`) plus the
226251
+ * note (absent → `''`) and the `retrainStatus` they were derived from, so a
226252
+ * caller can drive its toggle — and render a `trained` badge — without a
226253
+ * re-fetch. Rejects an unknown track, a new staging mark on a device already
226254
+ * holding its full budget, and any `markForTrain` write against a trained
226255
+ * track.
225947
226256
  */
225948
226257
  setTrackFlags: require_sleep.method(zod.z.object({
225949
226258
  /** Log/audit scope only — the trackId is globally unique on its own. */
@@ -254477,7 +254786,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
254477
254786
  exports.DETECTION_PIPELINE_CAP_NAME = DETECTION_PIPELINE_CAP_NAME;
254478
254787
  exports.DEVICE_BACKEND_TO_FORMAT = DEVICE_BACKEND_TO_FORMAT;
254479
254788
  exports.DEVICE_CAP_NAMES = DEVICE_CAP_NAMES;
254480
- exports.DEVICE_CHILDREN_BATCH_MAX = DEVICE_CHILDREN_BATCH_MAX;
254789
+ exports.DEVICE_CHILDREN_BATCH_MAX = require_sleep.DEVICE_CHILDREN_BATCH_MAX;
254481
254790
  exports.DEVICE_PROFILES = DEVICE_PROFILES;
254482
254791
  exports.DEVICE_RESTORE_RETRY_CONCURRENCY = DEVICE_RESTORE_RETRY_CONCURRENCY;
254483
254792
  exports.DEVICE_RESTORE_RETRY_DELAYS_MS = DEVICE_RESTORE_RETRY_DELAYS_MS;
@@ -254713,6 +255022,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
254713
255022
  exports.MAX_KEYS = MAX_KEYS;
254714
255023
  exports.MAX_REASONS_PER_KEY = MAX_REASONS_PER_KEY;
254715
255024
  exports.MAX_SENSOR_TRIGGER_DEVICES = MAX_SENSOR_TRIGGER_DEVICES;
255025
+ exports.MAX_TRACK_DEBUG_NOTE_LEN = MAX_TRACK_DEBUG_NOTE_LEN;
254716
255026
  exports.METHOD_ACCESS_MAP = METHOD_ACCESS_MAP;
254717
255027
  exports.METHOD_DEVICE_SELECTORS = METHOD_DEVICE_SELECTORS;
254718
255028
  exports.MODEL_FORMATS = MODEL_FORMATS;
@@ -424248,9 +424558,9 @@ var require_agent_registry_service = __commonJS({
424248
424558
  }
424249
424559
  return nodes.delete(nodeId) === true;
424250
424560
  }
424251
- /** Typed view of the broker's node catalog — one documented boundary cast. */
424561
+ /** Typed view of the broker's node catalog — reached through the ONE cast. */
424252
424562
  nodeCatalogRegistry() {
424253
- return this.moleculer.broker.registry;
424563
+ return this.broker.registry;
424254
424564
  }
424255
424565
  /** Typed view of the Moleculer broker — single documented cast. */
424256
424566
  get broker() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "camstack",
3
- "version": "1.2.89",
3
+ "version": "1.2.91",
4
4
  "description": "CLI tool for managing and running CamStack server",
5
5
  "keywords": [
6
6
  "camstack",