@camstack/types 1.2.70 → 1.2.72

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.
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_event_category = require("./event-category-DxZbWydC.js");
3
- const require_sleep = require("./sleep-YuacOD41.js");
2
+ const require_event_category = require("./event-category-D3gG7oil.js");
3
+ const require_sleep = require("./sleep-CKWYtvXl.js");
4
4
  const require_canonical_hash = require("./canonical-hash-DNV8S5ET.js");
5
5
  const require_enums = require("./enums.js");
6
6
  const require_err_msg = require("./err-msg-COpsHMw2.js");
@@ -11958,6 +11958,8 @@ var NcSystemEventKindSchema = zod.z.enum([
11958
11958
  "stream-offline",
11959
11959
  "node-online",
11960
11960
  "node-offline",
11961
+ "node-inference-unavailable",
11962
+ "detection-blind",
11961
11963
  "addon-update-available",
11962
11964
  "server-update-available",
11963
11965
  "alarm-triggered",
@@ -12802,7 +12804,50 @@ var NcRuleInputSchema = zod.z.object({
12802
12804
  * tests every zone the track visited and a `crossing` condition can no longer
12803
12805
  * be satisfied, because a closed track carries no crossing.
12804
12806
  */
12805
- waitForEnhancement: zod.z.boolean().optional()
12807
+ waitForEnhancement: zod.z.boolean().optional(),
12808
+ /**
12809
+ * GROUP a burst of subjects into ONE notification that grows.
12810
+ *
12811
+ * Seconds of quiet after the last matching subject before the burst is
12812
+ * considered over. While it is open, the first subject enqueues immediately —
12813
+ * **exactly as today, with no added latency** — and every real growth (a new
12814
+ * subject, or a name confirmed on one already in it) REPLACES that
12815
+ * notification with an updated one naming everybody. The push carries the
12816
+ * group's own coalescing tag, so the phone replaces rather than stacks.
12817
+ *
12818
+ * `0` / absent = off, and off is today's behaviour byte for byte.
12819
+ *
12820
+ * ### Why an idle cutoff and not a window
12821
+ *
12822
+ * The measured seven-person arrival on device 590 spans 110 s with every
12823
+ * internal gap under 30 s. A 12 s fixed window cuts it into three groups; an
12824
+ * idle cutoff holds it as one and ends it when the arrival actually ends.
12825
+ * 30 is Frigate's shipped value for the same decision.
12826
+ *
12827
+ * ### What it replaces
12828
+ *
12829
+ * The blind cooldown, which collapses a burst by DISCARDING it. Measured on
12830
+ * device 615 / *Persona su Uscio* over six days: 116 qualifying tracks → 74
12831
+ * notifications, **44 (37.9%) suppressed outright**, 23 of them overlapping a
12832
+ * track that did fire and 7 carrying a confirmed identity nobody heard about.
12833
+ * A group collapses the same volume by MERGING, so the cooldown becomes a
12834
+ * budget over GROUPS — which is what it always meant — and a growth is never
12835
+ * throttled by the window its own first member spent.
12836
+ *
12837
+ * ### Interaction with {@link waitForEnhancement}
12838
+ *
12839
+ * They compose, and the order matters. `waitForEnhancement` defers the rule to
12840
+ * TRACK CLOSE, so with both set the group is opened by the first member to
12841
+ * CLOSE — already carrying its name — and grows as later members close. That
12842
+ * is later, and complete. With grouping alone the group opens on the first
12843
+ * object event and picks up names as they are confirmed, through the growth
12844
+ * path. Neither combination fires twice for one subject.
12845
+ *
12846
+ * `.optional()` and deliberately NOT `.default()`: a Zod default does not run
12847
+ * on the addon cap path, so absent must keep meaning what it meant before this
12848
+ * field existed.
12849
+ */
12850
+ groupIdleSec: zod.z.number().int().min(0).max(600).optional()
12806
12851
  });
12807
12852
  /**
12808
12853
  * Partial patch for `updateRule` — any subset of the input fields, plus the
@@ -12989,6 +13034,14 @@ var NC_CONDITION_CATALOG = [
12989
13034
  value: "node-offline",
12990
13035
  label: "Node offline"
12991
13036
  },
13037
+ {
13038
+ value: "node-inference-unavailable",
13039
+ label: "Node has no usable inference device"
13040
+ },
13041
+ {
13042
+ value: "detection-blind",
13043
+ label: "Camera detecting nothing"
13044
+ },
12992
13045
  {
12993
13046
  value: "addon-update-available",
12994
13047
  label: "Addon update available"
@@ -14250,7 +14303,7 @@ var TrackEnvelopeSchema = zod.z.object({
14250
14303
  * `snapshots[]` references — megabytes across a page of tracks. `slim`
14251
14304
  * keeps every scalar the list surfaces actually render (ids, class(es),
14252
14305
  * label / audioLabels / importance enrichment, firstSeen/lastSeen, state,
14253
- * zonesVisited, bestEventId, envelope, hasFace) and returns `positions` /
14306
+ * zonesVisited, bestEventId, envelope, hasFace, hasRider) and returns `positions` /
14254
14307
  * `snapshots` as EMPTY arrays — detail views re-fetch the full row via
14255
14308
  * `getTrack`. Mirrors the event-store `projection` convention
14256
14309
  * (`getObjectEvents` et al.).
@@ -14553,6 +14606,28 @@ var TrackSchema = zod.z.object({
14553
14606
  * `=== true` and render nothing otherwise, never infer "no face".
14554
14607
  */
14555
14608
  hasFace: zod.z.boolean().optional(),
14609
+ /**
14610
+ * This subject CONTAINS a folded rider — a person the rider-pairing step
14611
+ * ([D34](../decisions/adr-0034.md)) removed from the frame BEFORE the tracker,
14612
+ * so the passage is tracked once and as a VEHICLE.
14613
+ *
14614
+ * It exists because the fold's record was dishonest. D34 and the code both
14615
+ * said "the person is not lost — it is reported so both entities stay on the
14616
+ * record"; in fact the pair went into a per-processor RAM field behind an
14617
+ * accessor nobody called, and every durable surface said `vehicle`, full
14618
+ * stop. This is the composition note that makes the row true.
14619
+ *
14620
+ * A COMPOSITION, never a class and never a label. "This vehicle contains a
14621
+ * person" is not an answer to "what is this" — both label tiers would refuse
14622
+ * a macro token anyway (D89), and correctly. Nothing here changes what the
14623
+ * subject IS: a cyclist stays one vehicle track, occupancy still counts one,
14624
+ * and a `person` rule still does not fire for someone cycling past.
14625
+ *
14626
+ * **Absent ≠ false**, exactly like {@link hasFace}: every row written before
14627
+ * the column, and every hub that predates the field, omits it. Test
14628
+ * `=== true` and render nothing otherwise — never infer "no rider".
14629
+ */
14630
+ hasRider: zod.z.boolean().optional(),
14556
14631
  ...TrackFlagFields,
14557
14632
  ...TrackRetrainFields
14558
14633
  });
@@ -27303,9 +27378,47 @@ var recordingExportCapability = {
27303
27378
  * settings-contribution methods. `status.kind:'push'` — the engine pushes on
27304
27379
  * every hysteresis flip / availability change; consumers never poll.
27305
27380
  */
27306
- /** Extensible condition tag. Seeded 'day' | 'night'; open by design so more can
27307
- * be added without a wire break (matching falls back to any-condition refs). */
27381
+ /** Extensible condition tag. Seeded 'day' | 'ir' (the two variants the operator
27382
+ * captures) plus 'night' | 'dawn' | 'dusk' from the resolver's sun-times band.
27383
+ * Open by design so more can be added without a wire break.
27384
+ *
27385
+ * Matching does NOT fall back across conditions: cross-condition cosines are
27386
+ * not comparable, so "I have never seen this scene in this light" is reported
27387
+ * as `unknown`, never guessed. A day reference scored against an IR frame
27388
+ * collapses the cosine and would latch a false alarm every single night. */
27308
27389
  var SceneConditionSchema = zod.z.string();
27390
+ /** The conditions the resolver can produce. Seeds for the UI's coverage line;
27391
+ * the wire type stays an open string. */
27392
+ var SCENE_CONDITIONS = [
27393
+ "day",
27394
+ "ir",
27395
+ "night",
27396
+ "dawn",
27397
+ "dusk"
27398
+ ];
27399
+ /** Reserved, engine-owned state id standing for "the region no longer looks
27400
+ * like ANY captured reference". Never authored by an operator, never stored in
27401
+ * `states[]` — it is the synthetic candidate that makes divergence a
27402
+ * first-class hysteresis input rather than a bare `return`. */
27403
+ var SCENE_DIVERGED = "__diverged__";
27404
+ /** `matched` = the baseline is what we see; `diverged` = it demonstrably is not;
27405
+ * `unknown` = we cannot judge (no reference for this condition, encoder model
27406
+ * changed, view shifted, no snapshot). `unknown` is a real value, not a null,
27407
+ * and never counts toward hysteresis in either direction. */
27408
+ var SceneVerdictSchema = zod.z.enum([
27409
+ "matched",
27410
+ "diverged",
27411
+ "unknown"
27412
+ ]);
27413
+ /** Why a scene cannot judge. Named, because this feature's failure mode is
27414
+ * silence that reads as "nothing has happened". */
27415
+ var SceneUnavailableSchema = zod.z.enum([
27416
+ "no-reference-for-condition",
27417
+ "view-shifted",
27418
+ "no-vision-profile",
27419
+ "encoder-model-changed",
27420
+ "no-snapshot"
27421
+ ]);
27309
27422
  /** One captured reference — condition-tagged, model-version-gated. `embedding`
27310
27423
  * is `number[]` (Float32Array does NOT survive MsgPack/UDS). */
27311
27424
  var SceneReferenceSchema = zod.z.object({
@@ -27313,7 +27426,14 @@ var SceneReferenceSchema = zod.z.object({
27313
27426
  modelId: zod.z.string(),
27314
27427
  condition: SceneConditionSchema,
27315
27428
  capturedAt: zod.z.number(),
27316
- thumbnailMediaId: zod.z.string().optional()
27429
+ thumbnailMediaId: zod.z.string().optional(),
27430
+ /** Whole-frame (downscaled) embedding captured alongside the ROI crop. The
27431
+ * anti-view-shift anchor: a bumped camera, a PTZ preset or a re-aim makes the
27432
+ * normalized rect frame a different piece of world, and the scene would
27433
+ * diverge forever with a perfectly plausible cosine. Checked LAZILY, only
27434
+ * when hysteresis is about to flip — one extra encode per candidate
27435
+ * transition, not per poll. */
27436
+ anchorEmbedding: zod.z.array(zod.z.number()).optional()
27317
27437
  });
27318
27438
  var SceneMonitorStateSchema = zod.z.object({
27319
27439
  id: zod.z.string(),
@@ -27335,6 +27455,38 @@ var SceneCheckSchema = zod.z.discriminatedUnion("mode", [zod.z.object({
27335
27455
  profileId: zod.z.string().optional(),
27336
27456
  hysteresisCount: zod.z.number().int().positive()
27337
27457
  })]);
27458
+ /** Defaults, as CONSTANTS rather than only as Zod `.default()`. A Zod default
27459
+ * does NOT run on the addon→addon cap path, so every runtime seam reads these
27460
+ * as absent-with-a-constant (the `NcConfirmSchema` lesson, three production
27461
+ * failures in one day). The schema defaults and these values are the same
27462
+ * numbers on purpose. */
27463
+ var SCENE_DEFAULT_QUIET_SECONDS = 60;
27464
+ var SCENE_DEFAULT_OBSERVATION_SPACING_SEC = 120;
27465
+ var SCENE_DEFAULT_CHECK_INTERVAL_SEC = 60;
27466
+ var SCENE_DEFAULT_ANCHOR_THRESHOLD = .85;
27467
+ var SCENE_CONFIRM_DEFAULT_TIMEOUT_MS = 8e3;
27468
+ var SCENE_CONFIRM_DEFAULT_MAX_IMAGE_PX = 448;
27469
+ /** `resetScene({ recapture })` absent means TRUE — the operator decision. Read
27470
+ * at the seam, because a Zod `.optional()` carries no default at all. */
27471
+ var SCENE_RESET_RECAPTURES = true;
27472
+ /**
27473
+ * Vision-model adjudication of a candidate flip. Field names deliberately
27474
+ * mirror `NcConfirmSchema` so an operator meets one vocabulary, not two.
27475
+ *
27476
+ * `onTimeout` defaults to **'hold'**, the OPPOSITE of `NcConfirmGate`'s
27477
+ * fail-open: a notification suppressed is the worse error there, but a vision
27478
+ * model that timed out has not told us the bin is gone, and a latch is a
27479
+ * stateful claim that costs the operator a trip to reset.
27480
+ */
27481
+ var SceneConfirmSchema = zod.z.object({
27482
+ enabled: zod.z.boolean().default(false),
27483
+ prompt: zod.z.string().min(1).max(1e3),
27484
+ profileId: zod.z.string().optional(),
27485
+ timeoutMs: zod.z.number().int().min(1e3).max(2e4).default(SCENE_CONFIRM_DEFAULT_TIMEOUT_MS),
27486
+ maxImagePx: zod.z.number().int().min(64).max(2048).default(448),
27487
+ /** What a timeout / unavailable model means for the PENDING flip. */
27488
+ onTimeout: zod.z.enum(["flip", "hold"]).default("hold")
27489
+ });
27338
27490
  var SceneMonitorSchema = zod.z.object({
27339
27491
  id: zod.z.string(),
27340
27492
  label: zod.z.string(),
@@ -27353,7 +27505,41 @@ var SceneMonitorSchema = zod.z.object({
27353
27505
  lastConfidence: zod.z.number().nullable(),
27354
27506
  currentCondition: SceneConditionSchema.nullable(),
27355
27507
  availability: zod.z.enum(["ok", "unavailable"]),
27356
- unavailableReason: zod.z.string().nullable()
27508
+ unavailableReason: zod.z.string().nullable(),
27509
+ /** Which state is "the initial screen". `null` until the first capture. */
27510
+ baselineStateId: zod.z.string().nullable(),
27511
+ /** Which boolean drives notification rules and any export. */
27512
+ emit: zod.z.enum(["latched", "live"]).default("latched"),
27513
+ /** Live: does the region match the baseline RIGHT NOW. */
27514
+ verdict: SceneVerdictSchema,
27515
+ /** Has it been `diverged` at least once since `armedAt` — the operator's boolean. */
27516
+ latched: zod.z.boolean(),
27517
+ /** Last reset (or creation). */
27518
+ armedAt: zod.z.number(),
27519
+ divergedAt: zod.z.number().nullable(),
27520
+ restoredAt: zod.z.number().nullable(),
27521
+ /** A check is only COUNTED when the device has been quiet this long. Motion
27522
+ * during the window DISCARDS the observation — a car pulling up in front of
27523
+ * the bin must not be able to spend hysteresis credit. */
27524
+ quietSeconds: zod.z.number().int().min(0).max(3600).default(60),
27525
+ /** An observation only advances the pending count when it is at least this
27526
+ * far from the previously counted one, so N agreeing checks span real time
27527
+ * rather than N adjacent polls inside one occlusion. */
27528
+ minObservationSpacingSec: zod.z.number().int().min(0).max(3600).default(120),
27529
+ /** Vision-model adjudication of a candidate flip. Similarity primary only. */
27530
+ confirm: SceneConfirmSchema.optional(),
27531
+ /** Whole-frame anchor cosine below which a flip is REFUSED as `view-shifted`. */
27532
+ anchorThreshold: zod.z.number().min(0).max(1).default(SCENE_DEFAULT_ANCHOR_THRESHOLD),
27533
+ /** Clear the latch on its own when the scene matches again? Default false —
27534
+ * `restoredAt` and the `scene-restored` edge are recorded regardless, so an
27535
+ * automation can react to the bin coming back without the operator's own
27536
+ * alarm silently clearing itself. */
27537
+ autoRestore: zod.z.boolean().default(false),
27538
+ /** Named cause when `verdict === 'unknown'`. */
27539
+ unavailable: SceneUnavailableSchema.nullable(),
27540
+ /** Conditions that have at least one comparable reference — the coverage line
27541
+ * ("day ✓ · ir ✓ · dusk ✗") that turns a silent fallback into a visible fact. */
27542
+ coveredConditions: zod.z.array(SceneConditionSchema)
27357
27543
  });
27358
27544
  var SceneMonitorStatusSchema = zod.z.object({
27359
27545
  monitors: zod.z.array(SceneMonitorSchema),
@@ -27402,7 +27588,14 @@ var sceneMonitorCapability = {
27402
27588
  "both"
27403
27589
  ]).optional(),
27404
27590
  checkIntervalSec: zod.z.number().optional(),
27405
- check: SceneCheckSchema.optional()
27591
+ check: SceneCheckSchema.optional(),
27592
+ emit: zod.z.enum(["latched", "live"]).optional(),
27593
+ quietSeconds: zod.z.number().int().min(0).max(3600).optional(),
27594
+ minObservationSpacingSec: zod.z.number().int().min(0).max(3600).optional(),
27595
+ anchorThreshold: zod.z.number().min(0).max(1).optional(),
27596
+ autoRestore: zod.z.boolean().optional(),
27597
+ /** `null` clears the vision-model adjudicator. */
27598
+ confirm: SceneConfirmSchema.nullable().optional()
27406
27599
  })
27407
27600
  }), zod.z.void(), {
27408
27601
  kind: "mutation",
@@ -27443,6 +27636,26 @@ var sceneMonitorCapability = {
27443
27636
  }), zod.z.void(), {
27444
27637
  kind: "mutation",
27445
27638
  auth: "admin"
27639
+ }),
27640
+ /**
27641
+ * Clear the latch, re-arm, and — by default — RE-CAPTURE the baseline for
27642
+ * the CURRENT condition. The bin never goes back in exactly the same spot;
27643
+ * "reset" in the operator's head means *this is the new normal*, and
27644
+ * re-capture is what makes the feature self-healing against slow drift
27645
+ * instead of failing silently weeks later.
27646
+ *
27647
+ * Reachable from three surfaces on this one mutation: the scene card, a
27648
+ * notification button (an `onTrigger` sequence with a `kind:'cap'` step —
27649
+ * no new Notification-Center code at all), and tRPC for scripts.
27650
+ */
27651
+ resetScene: require_sleep.method(zod.z.object({
27652
+ deviceId: zod.z.number(),
27653
+ monitorId: zod.z.string(),
27654
+ /** Defaults to TRUE at the provider seam — see `SCENE_RESET_RECAPTURES`. */
27655
+ recapture: zod.z.boolean().optional()
27656
+ }), zod.z.void(), {
27657
+ kind: "mutation",
27658
+ auth: "admin"
27446
27659
  })
27447
27660
  },
27448
27661
  status: {
@@ -37403,6 +37616,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
37403
37616
  addonId: null,
37404
37617
  access: "create"
37405
37618
  },
37619
+ "sceneMonitor.resetScene": {
37620
+ capName: "scene-monitor",
37621
+ capScope: "device",
37622
+ addonId: null,
37623
+ access: "delete"
37624
+ },
37406
37625
  "sceneMonitor.updateScene": {
37407
37626
  capName: "scene-monitor",
37408
37627
  capScope: "device",
@@ -40342,6 +40561,11 @@ var METHOD_DEVICE_SELECTORS = Object.freeze({
40342
40561
  form: "single",
40343
40562
  optional: false
40344
40563
  }],
40564
+ "sceneMonitor.resetScene": [{
40565
+ name: "deviceId",
40566
+ form: "single",
40567
+ optional: false
40568
+ }],
40345
40569
  "sceneMonitor.updateScene": [{
40346
40570
  name: "deviceId",
40347
40571
  form: "single",
@@ -45382,6 +45606,15 @@ exports.RunnerFrameSourceSchema = RunnerFrameSourceSchema;
45382
45606
  exports.RunnerInferenceDeviceSchema = RunnerInferenceDeviceSchema;
45383
45607
  exports.RunnerLocalLoadSchema = RunnerLocalLoadSchema;
45384
45608
  exports.RunnerLocalMetricsSchema = RunnerLocalMetricsSchema;
45609
+ exports.SCENE_CONDITIONS = SCENE_CONDITIONS;
45610
+ exports.SCENE_CONFIRM_DEFAULT_MAX_IMAGE_PX = SCENE_CONFIRM_DEFAULT_MAX_IMAGE_PX;
45611
+ exports.SCENE_CONFIRM_DEFAULT_TIMEOUT_MS = SCENE_CONFIRM_DEFAULT_TIMEOUT_MS;
45612
+ exports.SCENE_DEFAULT_ANCHOR_THRESHOLD = SCENE_DEFAULT_ANCHOR_THRESHOLD;
45613
+ exports.SCENE_DEFAULT_CHECK_INTERVAL_SEC = SCENE_DEFAULT_CHECK_INTERVAL_SEC;
45614
+ exports.SCENE_DEFAULT_OBSERVATION_SPACING_SEC = SCENE_DEFAULT_OBSERVATION_SPACING_SEC;
45615
+ exports.SCENE_DEFAULT_QUIET_SECONDS = SCENE_DEFAULT_QUIET_SECONDS;
45616
+ exports.SCENE_DIVERGED = SCENE_DIVERGED;
45617
+ exports.SCENE_RESET_RECAPTURES = SCENE_RESET_RECAPTURES;
45385
45618
  exports.SCOPE_PRESETS = SCOPE_PRESETS;
45386
45619
  exports.SCRUB_THUMBNAIL_PRESETS = SCRUB_THUMBNAIL_PRESETS;
45387
45620
  exports.SCRUB_THUMBNAIL_PRESET_LABELS = SCRUB_THUMBNAIL_PRESET_LABELS;
@@ -45396,10 +45629,13 @@ exports.SYSTEM_CAP_NAMES = SYSTEM_CAP_NAMES;
45396
45629
  exports.SYSTEM_SCOPE_DEVICE_METHODS = SYSTEM_SCOPE_DEVICE_METHODS;
45397
45630
  exports.SceneCheckSchema = SceneCheckSchema;
45398
45631
  exports.SceneConditionSchema = SceneConditionSchema;
45632
+ exports.SceneConfirmSchema = SceneConfirmSchema;
45399
45633
  exports.SceneMonitorSchema = SceneMonitorSchema;
45400
45634
  exports.SceneMonitorStateSchema = SceneMonitorStateSchema;
45401
45635
  exports.SceneMonitorStatusSchema = SceneMonitorStatusSchema;
45402
45636
  exports.SceneReferenceSchema = SceneReferenceSchema;
45637
+ exports.SceneUnavailableSchema = SceneUnavailableSchema;
45638
+ exports.SceneVerdictSchema = SceneVerdictSchema;
45403
45639
  exports.ScopedTokenSchema = ScopedTokenSchema;
45404
45640
  exports.ScopedTokenSummarySchema = ScopedTokenSummarySchema;
45405
45641
  exports.ScoredObjectEventSchema = ScoredObjectEventSchema;