@camstack/addon-pipeline 1.2.153 → 1.2.155

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 (38) hide show
  1. package/dist/audio-analyzer/index.js +2 -2
  2. package/dist/audio-analyzer/index.mjs +2 -2
  3. package/dist/detection-pipeline/index.js +5 -5
  4. package/dist/detection-pipeline/index.mjs +4 -4
  5. package/dist/{dist-Dsritt4-.mjs → dist-CBRky_dz.mjs} +304 -4
  6. package/dist/{dist-DnVnWACi.js → dist-CmrtJ8RB.js} +304 -4
  7. package/dist/{lazy-sharp-DZWYKdV2.js → lazy-sharp-BODx7w1t.js} +1 -1
  8. package/dist/{local-frame-registry-BpFLRfbw.js → local-frame-registry-BRG0GTmK.js} +1 -1
  9. package/dist/{local-frame-registry-Yf-uIxbS.mjs → local-frame-registry-ByKcWWPU.mjs} +1 -1
  10. package/dist/motion-wasm/index.js +2 -2
  11. package/dist/motion-wasm/index.mjs +1 -1
  12. package/dist/{node-C5xmFvjS.js → node-BSeMUwxJ.js} +1 -1
  13. package/dist/{node-CNGxkfes.mjs → node-CQzPpwIR.mjs} +1 -1
  14. package/dist/pipeline-runner/index.js +5 -5
  15. package/dist/pipeline-runner/index.mjs +4 -4
  16. package/dist/{process-memory-DX_KCfdx.mjs → process-memory-DQX-DbHx.mjs} +1 -1
  17. package/dist/{process-memory-COT8rA8L.js → process-memory-DVmHBraW.js} +1 -1
  18. package/dist/recorder/index.js +667 -100
  19. package/dist/recorder/index.mjs +667 -100
  20. package/dist/{segment-demux-js-CTFSl-b9.mjs → segment-demux-js-DGX1iGLL.mjs} +1 -1
  21. package/dist/{segment-demux-js-Dwg9Jq5_.js → segment-demux-js-DmqnujVx.js} +1 -1
  22. package/dist/session-decode/decode-worker-child.js +2 -2
  23. package/dist/session-decode/decode-worker-child.mjs +1 -1
  24. package/dist/stream-broker/_stub.js +2 -2
  25. package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-ZucA907q.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-DvfM0ofY.mjs} +3 -3
  26. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-lMPlG5w5.mjs +26 -0
  27. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-CSNuIp4J.mjs +26 -0
  28. package/dist/stream-broker/demux-worker-child.js +1 -1
  29. package/dist/stream-broker/demux-worker-child.mjs +1 -1
  30. package/dist/stream-broker/{hostInit-BqUcM0Fh.mjs → hostInit-DQGeMfoN.mjs} +3 -3
  31. package/dist/stream-broker/index.js +3 -3
  32. package/dist/stream-broker/index.mjs +3 -3
  33. package/dist/stream-broker/remoteEntry.js +1 -1
  34. package/dist/{worker-protocol-CDBQXOIu.mjs → worker-protocol-C7jOjCsc.mjs} +1 -1
  35. package/dist/{worker-protocol-BsvaPb-G.js → worker-protocol-S2nAdf6B.js} +1 -1
  36. package/package.json +1 -1
  37. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-B14Zc1oq.mjs +0 -26
  38. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-DO6LkN6o.mjs +0 -26
@@ -2,8 +2,8 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_dist = require("../dist-DnVnWACi.js");
6
- const require_process_memory = require("../process-memory-COT8rA8L.js");
5
+ const require_dist = require("../dist-CmrtJ8RB.js");
6
+ const require_process_memory = require("../process-memory-DVmHBraW.js");
7
7
  let node_fs = require("node:fs");
8
8
  node_fs = require_dist.__toESM(node_fs);
9
9
  let node_path = require("node:path");
@@ -1,6 +1,6 @@
1
1
  import { n as __require } from "../chunk-DnnnRqeS.mjs";
2
- import { A as audioAnalysisCapability, It as hydrateSchema, S as PoolMemoryWatchdog, _t as resolvePoolMemoryPolicy, j as audioAnalyzerCapability, jt as BaseAddon, n as AUDIO_BACKEND_CHOICES, nt as mapAudioLabelToMacro, s as DEFAULT_AUDIO_ANALYZER_CONFIG, v as HF_BASE_URL, wt as errMsg } from "../dist-Dsritt4-.mjs";
3
- import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-DX_KCfdx.mjs";
2
+ import { A as audioAnalysisCapability, It as hydrateSchema, S as PoolMemoryWatchdog, _t as resolvePoolMemoryPolicy, j as audioAnalyzerCapability, jt as BaseAddon, n as AUDIO_BACKEND_CHOICES, nt as mapAudioLabelToMacro, s as DEFAULT_AUDIO_ANALYZER_CONFIG, v as HF_BASE_URL, wt as errMsg } from "../dist-CBRky_dz.mjs";
3
+ import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-DQX-DbHx.mjs";
4
4
  import * as fs from "node:fs";
5
5
  import * as path$1 from "node:path";
6
6
  import { downloadFile } from "@camstack/system/addon-utils";
@@ -2,12 +2,12 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_dist = require("../dist-DnVnWACi.js");
6
- const require_node = require("../node-C5xmFvjS.js");
7
- const require_local_frame_registry = require("../local-frame-registry-BpFLRfbw.js");
8
- const require_lazy_sharp = require("../lazy-sharp-DZWYKdV2.js");
5
+ const require_dist = require("../dist-CmrtJ8RB.js");
6
+ const require_node = require("../node-BSeMUwxJ.js");
7
+ const require_local_frame_registry = require("../local-frame-registry-BRG0GTmK.js");
8
+ const require_lazy_sharp = require("../lazy-sharp-BODx7w1t.js");
9
9
  const require_event_loop_stall_monitor = require("../event-loop-stall-monitor-DaUBcb13.js");
10
- const require_process_memory = require("../process-memory-COT8rA8L.js");
10
+ const require_process_memory = require("../process-memory-DVmHBraW.js");
11
11
  let node_fs = require("node:fs");
12
12
  node_fs = require_dist.__toESM(node_fs);
13
13
  let node_path = require("node:path");
@@ -1,10 +1,10 @@
1
1
  import { n as __require } from "../chunk-DnnnRqeS.mjs";
2
- import { Bt as nodePin, Ft as createEvent, It as hydrateSchema, Kt as array, O as YAMNET_TO_MACRO, Q as inferModelProvider, Qt as object, S as PoolMemoryWatchdog, St as supportedRuntimes$1, Vt as parseJsonUnknown, W as detectionPipelineCapability, Wt as sleep, Y as evaluateZoneRules, _t as resolvePoolMemoryPolicy, at as overlayClusterStepSettings, c as DEFAULT_CLUSTER_STEP_MODELS, ct as pickClusterStepSettings, dt as pipelineExecutorCapability, en as string, et as loadContributionCapability, ht as resolveClusterStepModelId, jt as BaseAddon, l as DEFAULT_CLUSTER_STEP_SETTINGS, m as DEVICE_BACKEND_TO_FORMAT, nn as EventCategory, q as enumerateInferenceDevices, st as pickClusterStepModels, t as APPLE_SA_TO_MACRO, tn as union, wt as errMsg, yt as runtimeDevices$1, z as defaultDeviceFor$1 } from "../dist-Dsritt4-.mjs";
3
- import { a as readProcessCost } from "../node-CNGxkfes.mjs";
4
- import { a as getDefaultModelForFormat, c as getStepDefinition, i as ALL_STEPS, l as resolveModelForFormat, o as getDefaultModelForFormatFromDef, r as ALL_PIPELINE_STEPS, s as getStep, t as localFrameRegistry, u as landmarkPrecisionVerdict } from "../local-frame-registry-Yf-uIxbS.mjs";
2
+ import { Bt as nodePin, Ft as createEvent, It as hydrateSchema, Kt as array, O as YAMNET_TO_MACRO, Q as inferModelProvider, Qt as object, S as PoolMemoryWatchdog, St as supportedRuntimes$1, Vt as parseJsonUnknown, W as detectionPipelineCapability, Wt as sleep, Y as evaluateZoneRules, _t as resolvePoolMemoryPolicy, at as overlayClusterStepSettings, c as DEFAULT_CLUSTER_STEP_MODELS, ct as pickClusterStepSettings, dt as pipelineExecutorCapability, en as string, et as loadContributionCapability, ht as resolveClusterStepModelId, jt as BaseAddon, l as DEFAULT_CLUSTER_STEP_SETTINGS, m as DEVICE_BACKEND_TO_FORMAT, nn as EventCategory, q as enumerateInferenceDevices, st as pickClusterStepModels, t as APPLE_SA_TO_MACRO, tn as union, wt as errMsg, yt as runtimeDevices$1, z as defaultDeviceFor$1 } from "../dist-CBRky_dz.mjs";
3
+ import { a as readProcessCost } from "../node-CQzPpwIR.mjs";
4
+ import { a as getDefaultModelForFormat, c as getStepDefinition, i as ALL_STEPS, l as resolveModelForFormat, o as getDefaultModelForFormatFromDef, r as ALL_PIPELINE_STEPS, s as getStep, t as localFrameRegistry, u as landmarkPrecisionVerdict } from "../local-frame-registry-ByKcWWPU.mjs";
5
5
  import { t as getSharp } from "../lazy-sharp-DXsqwpph.mjs";
6
6
  import { n as startEventLoopStallMonitor } from "../event-loop-stall-monitor-DXLNBMkY.mjs";
7
- import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-DX_KCfdx.mjs";
7
+ import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-DQX-DbHx.mjs";
8
8
  import * as fs from "node:fs";
9
9
  import * as path$1 from "node:path";
10
10
  import { spawn } from "node:child_process";
@@ -9330,6 +9330,20 @@ var RelocateJobSchema = object({
9330
9330
  * in its row, not in its name, so `MediaRelocateEngine` never reconciles one.
9331
9331
  */
9332
9332
  rowsReconciled: number().int().nonnegative().optional(),
9333
+ /**
9334
+ * Rows this run FORGOT because the file they name is not on disk.
9335
+ *
9336
+ * The mover derived the path from the row's own fields and `stat`ed it; an
9337
+ * ENOENT there is a per-path confirmation that the segment is gone (D296),
9338
+ * and the durable row is dropped through the same channel eviction uses. It
9339
+ * is reported for the same reason `rowsReconciled` is: this is a durable
9340
+ * mutation nobody asked for, and a migration that quietly erases hour rows is
9341
+ * the same failure as one that quietly skips them (D295).
9342
+ *
9343
+ * The production drain of 2026-08-30 would have reported 11 074 here — the
9344
+ * ledger claimed 5.65 GB of footage that no longer existed.
9345
+ */
9346
+ rowsForgotten: number().int().nonnegative().optional(),
9333
9347
  startedAt: number(),
9334
9348
  finishedAt: number().nullable(),
9335
9349
  error: string().nullable()
@@ -9693,6 +9707,91 @@ var RelocateResidueSchema = object({
9693
9707
  segments: number().int().nonnegative(),
9694
9708
  bytes: number().int().nonnegative()
9695
9709
  }).nullable();
9710
+ /**
9711
+ * Ask one location whether its durable hour rows describe the disk — the walk
9712
+ * (D319).
9713
+ *
9714
+ * `apply` DEFAULTS TO FALSE and that default is the product: the operator's
9715
+ * missing tool is the question, and the dry run is how they sanity-check the
9716
+ * destructive run before authorising it.
9717
+ */
9718
+ var LedgerWalkInputSchema = object({
9719
+ locationId: string().min(1),
9720
+ /** Forget the confirmed-absent rows, rather than only counting them. */
9721
+ apply: boolean().optional(),
9722
+ /** Narrow to one camera. */
9723
+ deviceId: number().int().positive().optional(),
9724
+ /** Narrow to these recording profiles; empty/absent = every profile. */
9725
+ profiles: array(string().min(1)).optional()
9726
+ });
9727
+ /** Why a whole walk did nothing. Every one leaves the ledger untouched. */
9728
+ var LedgerWalkRefusalSchema = _enum([
9729
+ "location-unknown",
9730
+ "source-writable",
9731
+ "no-ledger",
9732
+ "archive-unreadable",
9733
+ "anchor-absent",
9734
+ "anchor-unreadable",
9735
+ "anchor-moved"
9736
+ ]);
9737
+ _enum([
9738
+ "live-tail",
9739
+ "listing-error",
9740
+ "path-mismatch",
9741
+ "durable-refused"
9742
+ ]);
9743
+ /** Every skip reason, always present, always a number — so a reason that never
9744
+ * fired reports as zero rather than absent and the report shape is constant
9745
+ * between passes. Spelled out rather than `z.record` for exactly that. */
9746
+ var LedgerWalkSkipCountsSchema = object({
9747
+ "live-tail": number().int().nonnegative(),
9748
+ "listing-error": number().int().nonnegative(),
9749
+ "path-mismatch": number().int().nonnegative(),
9750
+ "durable-refused": number().int().nonnegative()
9751
+ });
9752
+ /** One camera's share of a walk, so a report names cameras and not rows. */
9753
+ var LedgerWalkDeviceReportSchema = object({
9754
+ deviceId: number().int(),
9755
+ hoursWalked: number().int().nonnegative(),
9756
+ hoursMissing: number().int().nonnegative(),
9757
+ ghostSegments: number().int().nonnegative(),
9758
+ ghostBytes: number().int().nonnegative(),
9759
+ forgottenSegments: number().int().nonnegative(),
9760
+ orphanFiles: number().int().nonnegative()
9761
+ });
9762
+ /**
9763
+ * What one walk claimed, listed, found and (only when armed) forgot.
9764
+ *
9765
+ * `archiveSegments` is the **M** and `segmentsClaimed` the **N** (D295), so a
9766
+ * walk that saw a fraction of the location is visible in its own report rather
9767
+ * than in the absence of one.
9768
+ */
9769
+ var LedgerWalkReportSchema = object({
9770
+ locationId: string(),
9771
+ applied: boolean(),
9772
+ refused: LedgerWalkRefusalSchema.nullable(),
9773
+ archiveSegments: number().int().nonnegative().nullable(),
9774
+ archiveBytes: number().int().nonnegative().nullable(),
9775
+ hoursClaimed: number().int().nonnegative(),
9776
+ hoursWalked: number().int().nonnegative(),
9777
+ hoursMissing: number().int().nonnegative(),
9778
+ /** `readdir` calls issued — the cost, stated in the unit that is paid. */
9779
+ listings: number().int().nonnegative(),
9780
+ segmentsClaimed: number().int().nonnegative(),
9781
+ ghostSegments: number().int().nonnegative(),
9782
+ ghostBytes: number().int().nonnegative(),
9783
+ ghostHoursWhole: number().int().nonnegative(),
9784
+ forgottenSegments: number().int().nonnegative(),
9785
+ forgottenBytes: number().int().nonnegative(),
9786
+ /** Files under a claimed hour that no durable row names. Never deleted. */
9787
+ orphanFiles: number().int().nonnegative(),
9788
+ orphanSample: array(string()).readonly(),
9789
+ hoursSkipped: number().int().nonnegative(),
9790
+ skippedByReason: LedgerWalkSkipCountsSchema,
9791
+ /** The walk stopped at its per-pass hour bound with claims unwalked. */
9792
+ bounded: boolean(),
9793
+ byDevice: array(LedgerWalkDeviceReportSchema).readonly()
9794
+ });
9696
9795
  /** How many rows a media pass would still act on against a given target — the
9697
9796
  * media lane's denominator AND its residue, from ONE derivation so the two can
9698
9797
  * never disagree. `null` = the count could not be taken. */
@@ -21128,13 +21227,15 @@ var ListGroupsPageSchema = object({
21128
21227
  groups: array(AnalyticsGroupRecordSchema).readonly(),
21129
21228
  nextCursor: string().nullable()
21130
21229
  });
21230
+ var KEY_EVENTS_DEFAULT_LIMIT = 50;
21231
+ var KEY_EVENTS_MAX_LIMIT = 200;
21131
21232
  var KeyEventQueryInput = object({
21132
21233
  deviceId: number(),
21133
21234
  /** Window lower bound (track firstSeen ≥ since). */
21134
21235
  since: number(),
21135
21236
  /** Window upper bound (track firstSeen ≤ until). */
21136
21237
  until: number(),
21137
- limit: number().int().min(1).max(200).default(50),
21238
+ limit: number().int().min(1).max(KEY_EVENTS_MAX_LIMIT).default(KEY_EVENTS_DEFAULT_LIMIT),
21138
21239
  /** Drop tracks scoring below this importance. */
21139
21240
  minImportance: number().min(0).max(1).optional(),
21140
21241
  /** Restrict to a single class (e.g. 'person'). */
@@ -21156,6 +21257,32 @@ var KeyEventSchema = object({
21156
21257
  ...TrackFlagFields,
21157
21258
  ...TrackRetrainFields
21158
21259
  });
21260
+ /** `getKeyEvents`' window and filters, asked of a SET of cameras at once. */
21261
+ var KeyEventBatchQueryInput = object({
21262
+ deviceIds: array(number()).min(1).max(200),
21263
+ since: number(),
21264
+ until: number(),
21265
+ /** Applied PER CAMERA, exactly as `getKeyEvents.limit` is — never a total
21266
+ * across the set, which would let a busy camera starve a quiet one of its
21267
+ * rows and change what the merged feed contains. */
21268
+ limit: number().int().min(1).max(KEY_EVENTS_MAX_LIMIT).default(KEY_EVENTS_DEFAULT_LIMIT),
21269
+ minImportance: number().min(0).max(1).optional(),
21270
+ classFilter: string().optional()
21271
+ });
21272
+ /**
21273
+ * One camera's key events in a batch answer.
21274
+ *
21275
+ * The row exists for every requested id. `getKeyEvents` degrades to `[]` on
21276
+ * error rather than throwing, so a camera whose store read failed and one with
21277
+ * no events in the window were ALREADY indistinguishable per camera — the
21278
+ * batch does not make that worse, and the row keeps the deviceId the single
21279
+ * method's output never carried (the caller used to stamp it from the fan-out
21280
+ * key, which only worked because there was one query per camera).
21281
+ */
21282
+ var KeyEventsForDeviceSchema = object({
21283
+ deviceId: number(),
21284
+ events: array(KeyEventSchema).readonly()
21285
+ });
21159
21286
  object({
21160
21287
  trackId: string(),
21161
21288
  className: string(),
@@ -21227,6 +21354,50 @@ var EventStoreFootprintSchema = object({
21227
21354
  totalBytes: number().int(),
21228
21355
  devices: array(EventStoreDeviceFootprintSchema).readonly()
21229
21356
  });
21357
+ /** Event-media footprint for one {@link MediaFileKind}. */
21358
+ var EventMediaKindFootprintSchema = object({
21359
+ kind: MediaFileKindEnum,
21360
+ /** Media rows of this kind. */
21361
+ rows: number().int(),
21362
+ /** Bytes on disk held by those rows. */
21363
+ bytes: number().int()
21364
+ });
21365
+ /**
21366
+ * The media footprint broken down by KIND — the axis a deletion decision
21367
+ * actually turns on.
21368
+ *
21369
+ * A byte total says how much there is; it cannot say what is safe to remove.
21370
+ * The deletable set (the periodic `snapshot` filmstrip, the surplus per-edge
21371
+ * motion stills) and the keep set (`firstFrame`, rolling `lastFrame`,
21372
+ * `thumbnail`/`thumbnailSmall`, `keyFrame`/`keyFrameSmall`, the face/plate
21373
+ * buffers, gallery media, the CLIP `crop`) are distinguished by `kind` and by
21374
+ * nothing else, so sizing a deletion means summing per kind.
21375
+ *
21376
+ * ## Why `unaccounted*` exists
21377
+ *
21378
+ * `kinds` is enumerated from {@link MediaFileKindEnum} — the closed set the
21379
+ * writers use — and summed one kind at a time. `totalRows` / `totalBytes` come
21380
+ * from a SEPARATE unfiltered aggregate over the same rows, never from adding
21381
+ * `kinds` up. A row whose stored `kind` is not in the enum (written by a
21382
+ * retired code path, or by a version that knew a kind this one does not) would
21383
+ * otherwise vanish from the total silently, and an operator would delete
21384
+ * against a denominator smaller than the disk.
21385
+ *
21386
+ * `unaccountedRows` / `unaccountedBytes` are the difference. They are normally
21387
+ * zero; a non-zero value is a real finding and must be shown, not rounded away.
21388
+ */
21389
+ var EventMediaKindBreakdownSchema = object({
21390
+ /** Every media row in scope, from one unfiltered aggregate. */
21391
+ totalRows: number().int(),
21392
+ /** Every media byte in scope, from that same aggregate. */
21393
+ totalBytes: number().int(),
21394
+ /** Per-kind footprint, ordered by bytes descending. */
21395
+ kinds: array(EventMediaKindFootprintSchema).readonly(),
21396
+ /** `totalRows` minus the summed `kinds` rows — see the schema note. */
21397
+ unaccountedRows: number().int(),
21398
+ /** `totalBytes` minus the summed `kinds` bytes — see the schema note. */
21399
+ unaccountedBytes: number().int()
21400
+ });
21230
21401
  /** Per-kind counts returned by the event-prune / device-delete mutations. */
21231
21402
  var EventPruneCountsSchema = object({
21232
21403
  motion: number().int(),
@@ -21381,7 +21552,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
21381
21552
  until: number().optional(),
21382
21553
  kinds: array(string()).optional(),
21383
21554
  limit: number().int().min(1).max(MAX_EVENT_QUERY_LIMIT).default(DEFAULT_EVENT_QUERY_LIMIT)
21384
- }), array(SensorEventSchema).readonly()), method(KeyEventQueryInput, array(KeyEventSchema).readonly()), method(object({
21555
+ }), array(SensorEventSchema).readonly()), method(KeyEventQueryInput, array(KeyEventSchema).readonly()), method(KeyEventBatchQueryInput, array(KeyEventsForDeviceSchema).readonly()), method(object({
21385
21556
  deviceId: number(),
21386
21557
  since: number(),
21387
21558
  until: number(),
@@ -21430,6 +21601,9 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
21430
21601
  }), TrackFlagsSchema, { kind: "mutation" }), method(object({}), EventStoreFootprintSchema, {
21431
21602
  kind: "query",
21432
21603
  auth: "admin"
21604
+ }), method(object({ deviceId: number().int().optional() }), EventMediaKindBreakdownSchema, {
21605
+ kind: "query",
21606
+ auth: "admin"
21433
21607
  }), method(object({
21434
21608
  olderThanMs: number(),
21435
21609
  reason: OpsLogReasonSchema.optional()
@@ -23523,6 +23697,20 @@ method(object({
23523
23697
  error: string().optional()
23524
23698
  }), { auth: "admin" }), method(_void(), array(ProviderListEntrySchema).readonly()), method(object({
23525
23699
  providerId: string(),
23700
+ /**
23701
+ * The location this config is an UNSAVED edit of, when there is one.
23702
+ *
23703
+ * `listLocations` replaces every declared secret with the redaction
23704
+ * sentinel, so the edit modal's form state holds the sentinel for any
23705
+ * credential the operator did not retype — and posting that here
23706
+ * without a way to resolve it makes the provider try to authenticate
23707
+ * as `__camstack_redacted__` and report the operator's own working
23708
+ * password as wrong. Given this id, the orchestrator restores each
23709
+ * sentinel from the stored config (same rule as `upsertLocation`)
23710
+ * before dispatching. Omitted by the "Add location" wizard, where
23711
+ * every value was typed just now and nothing is stored yet.
23712
+ */
23713
+ locationId: string().optional(),
23526
23714
  config: record(string(), unknown())
23527
23715
  }), object({
23528
23716
  ok: boolean(),
@@ -29435,6 +29623,23 @@ var recordingCapability = {
29435
29623
  kind: "query",
29436
29624
  auth: "admin"
29437
29625
  }),
29626
+ /**
29627
+ * Does this location's LEDGER tell the truth about its disk? (D319)
29628
+ *
29629
+ * One `readdir` per claimed hour, diffed both ways: durable rows whose file
29630
+ * is not there, and files no durable row names. `apply` defaults to FALSE —
29631
+ * the report is the product, and the dry run is how an operator
29632
+ * sanity-checks the destructive run before authorising it.
29633
+ *
29634
+ * REFUSES a source that is still a write target: a listing of a live
29635
+ * location is a lower bound, which is not the strong evidence that lets
29636
+ * this pass forget without a budget. A live location is reconciled by the
29637
+ * mover, under D318's bound.
29638
+ */
29639
+ reconcileLedgerAgainstDisk: method(LedgerWalkInputSchema, LedgerWalkReportSchema, {
29640
+ kind: "mutation",
29641
+ auth: "admin"
29642
+ }),
29438
29643
  /** Cancel a running or queued relocate job. A queued job never runs. */
29439
29644
  cancelRelocateJob: method(object({ jobId: string() }), object({ cancelled: boolean() }), {
29440
29645
  kind: "mutation",
@@ -29888,7 +30093,26 @@ var SceneMonitorStatusSchema = object({
29888
30093
  monitors: array(SceneMonitorSchema),
29889
30094
  lastFetchedAt: number()
29890
30095
  });
29891
- DeviceType.Camera, method(object({ deviceId: number() }), SceneMonitorStatusSchema), method(object({
30096
+ /**
30097
+ * One camera's row in a `listScenesBatch` answer.
30098
+ *
30099
+ * `status` is NULLABLE and the nullability is the whole point. `scene-monitor`
30100
+ * is a `defaultActive` wrapper, so every camera is asked; a camera whose
30101
+ * provider is absent (pipeline-analytics not deployed, the post-processing node
30102
+ * down) cannot answer, and that is not the same fact as a camera with no scenes
30103
+ * configured. Fanned out per camera the difference was visible — one query
30104
+ * errored while the others resolved — and a batch that returned only the rows
30105
+ * it managed would have destroyed it, silently, by making an unreachable camera
30106
+ * indistinguishable from one that answered `monitors: []`.
30107
+ *
30108
+ * So: EVERY requested deviceId gets a row. `status: null` means "this camera
30109
+ * could not be read"; `status.monitors: []` means "read, and it has none".
30110
+ */
30111
+ var SceneMonitorStatusForDeviceSchema = object({
30112
+ deviceId: number(),
30113
+ status: SceneMonitorStatusSchema.nullable()
30114
+ });
30115
+ DeviceType.Camera, method(object({ deviceId: number() }), SceneMonitorStatusSchema), method(object({ deviceIds: array(number()).min(1).max(200) }), array(SceneMonitorStatusForDeviceSchema).readonly()), method(object({
29892
30116
  deviceId: number(),
29893
30117
  label: string(),
29894
30118
  roi: MaskRectShapeSchema,
@@ -31212,6 +31436,27 @@ var CameraOccupancySnapshotSchema = object({
31212
31436
  stationaryObjects: array(StationaryObjectSchema).readonly().optional()
31213
31437
  });
31214
31438
  /**
31439
+ * One camera's row in a `getCurrentSnapshotBatch` answer.
31440
+ *
31441
+ * THREE outcomes, and the single-camera method could only express two of them
31442
+ * because `snapshot: null` was already spoken for:
31443
+ *
31444
+ * - `read: 'read'`, `snapshot` present — the live occupancy reading.
31445
+ * - `read: 'read'`, `snapshot: null` — read, and this camera has no reading
31446
+ * yet: no frame since boot, and no parked-object registry to hydrate from.
31447
+ * - `read: 'unreadable'` — the owner could not answer for this
31448
+ * camera. `snapshot` is null, and it does NOT mean "nothing parked here".
31449
+ *
31450
+ * Collapsing the last two is the failure this field exists to prevent: a
31451
+ * hydration that threw would otherwise render as an empty Stationary section,
31452
+ * which is a definite claim about a camera nobody could read.
31453
+ */
31454
+ var CameraOccupancySnapshotForDeviceSchema = object({
31455
+ deviceId: number(),
31456
+ read: _enum(["read", "unreadable"]),
31457
+ snapshot: CameraOccupancySnapshotSchema.nullable()
31458
+ });
31459
+ /**
31215
31460
  * Time-series resolution. The history methods return one bucket per
31216
31461
  * step over the requested range. Smaller resolutions cost more
31217
31462
  * memory + bandwidth; bound to discrete steps so caller cannot ask
@@ -31235,7 +31480,7 @@ var HistoryPointSchema = object({
31235
31480
  /** Object count averaged over the bucket (rounded to nearest integer). */
31236
31481
  count: number().int().nonnegative()
31237
31482
  });
31238
- DeviceType.Camera, method(object({ deviceId: number() }), CameraOccupancySnapshotSchema.nullable()), method(object({
31483
+ DeviceType.Camera, method(object({ deviceId: number() }), CameraOccupancySnapshotSchema.nullable()), method(object({ deviceIds: array(number()).min(1).max(200) }), array(CameraOccupancySnapshotForDeviceSchema).readonly()), method(object({
31239
31484
  deviceId: number(),
31240
31485
  zoneId: string(),
31241
31486
  className: string().optional()
@@ -34675,6 +34920,12 @@ Object.freeze({
34675
34920
  addonId: null,
34676
34921
  access: "view"
34677
34922
  },
34923
+ "pipelineAnalytics.getEventMediaFootprintByKind": {
34924
+ capName: "pipeline-analytics",
34925
+ capScope: "device",
34926
+ addonId: null,
34927
+ access: "view"
34928
+ },
34678
34929
  "pipelineAnalytics.getEventStoreFootprint": {
34679
34930
  capName: "pipeline-analytics",
34680
34931
  capScope: "device",
@@ -34693,6 +34944,12 @@ Object.freeze({
34693
34944
  addonId: null,
34694
34945
  access: "view"
34695
34946
  },
34947
+ "pipelineAnalytics.getKeyEventsBatch": {
34948
+ capName: "pipeline-analytics",
34949
+ capScope: "device",
34950
+ addonId: null,
34951
+ access: "view"
34952
+ },
34696
34953
  "pipelineAnalytics.getMotionEvents": {
34697
34954
  capName: "pipeline-analytics",
34698
34955
  capScope: "device",
@@ -35869,6 +36126,12 @@ Object.freeze({
35869
36126
  addonId: null,
35870
36127
  access: "view"
35871
36128
  },
36129
+ "recording.reconcileLedgerAgainstDisk": {
36130
+ capName: "recording",
36131
+ capScope: "system",
36132
+ addonId: null,
36133
+ access: "create"
36134
+ },
35872
36135
  "recording.refreshStorageLocationsForMigration": {
35873
36136
  capName: "recording",
35874
36137
  capScope: "system",
@@ -35995,6 +36258,12 @@ Object.freeze({
35995
36258
  addonId: null,
35996
36259
  access: "view"
35997
36260
  },
36261
+ "sceneMonitor.listScenesBatch": {
36262
+ capName: "scene-monitor",
36263
+ capScope: "device",
36264
+ addonId: null,
36265
+ access: "view"
36266
+ },
35998
36267
  "sceneMonitor.recheckNow": {
35999
36268
  capName: "scene-monitor",
36000
36269
  capScope: "device",
@@ -37351,6 +37620,12 @@ Object.freeze({
37351
37620
  addonId: null,
37352
37621
  access: "view"
37353
37622
  },
37623
+ "zoneAnalytics.getCurrentSnapshotBatch": {
37624
+ capName: "zone-analytics",
37625
+ capScope: "device",
37626
+ addonId: null,
37627
+ access: "view"
37628
+ },
37354
37629
  "zoneAnalytics.getUnzonedHistory": {
37355
37630
  capName: "zone-analytics",
37356
37631
  capScope: "device",
@@ -38340,6 +38615,11 @@ Object.freeze({
38340
38615
  form: "single",
38341
38616
  optional: false
38342
38617
  }],
38618
+ "pipelineAnalytics.getEventMediaFootprintByKind": [{
38619
+ name: "deviceId",
38620
+ form: "single",
38621
+ optional: true
38622
+ }],
38343
38623
  "pipelineAnalytics.getGroup": [{
38344
38624
  name: "deviceId",
38345
38625
  form: "single",
@@ -38350,6 +38630,11 @@ Object.freeze({
38350
38630
  form: "single",
38351
38631
  optional: false
38352
38632
  }],
38633
+ "pipelineAnalytics.getKeyEventsBatch": [{
38634
+ name: "deviceIds",
38635
+ form: "array",
38636
+ optional: false
38637
+ }],
38353
38638
  "pipelineAnalytics.getMotionEvents": [{
38354
38639
  name: "deviceId",
38355
38640
  form: "single",
@@ -38790,6 +39075,11 @@ Object.freeze({
38790
39075
  form: "single",
38791
39076
  optional: false
38792
39077
  }],
39078
+ "recording.reconcileLedgerAgainstDisk": [{
39079
+ name: "deviceId",
39080
+ form: "single",
39081
+ optional: true
39082
+ }],
38793
39083
  "recording.relocateFootage": [{
38794
39084
  name: "deviceId",
38795
39085
  form: "single",
@@ -38855,6 +39145,11 @@ Object.freeze({
38855
39145
  form: "single",
38856
39146
  optional: false
38857
39147
  }],
39148
+ "sceneMonitor.listScenesBatch": [{
39149
+ name: "deviceIds",
39150
+ form: "array",
39151
+ optional: false
39152
+ }],
38858
39153
  "sceneMonitor.recheckNow": [{
38859
39154
  name: "deviceId",
38860
39155
  form: "single",
@@ -39116,6 +39411,11 @@ Object.freeze({
39116
39411
  form: "single",
39117
39412
  optional: false
39118
39413
  }],
39414
+ "zoneAnalytics.getCurrentSnapshotBatch": [{
39415
+ name: "deviceIds",
39416
+ form: "array",
39417
+ optional: false
39418
+ }],
39119
39419
  "zoneAnalytics.getUnzonedHistory": [{
39120
39420
  name: "deviceId",
39121
39421
  form: "single",