@camstack/addon-provider-rtsp 1.2.120 → 1.2.121

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 (3) hide show
  1. package/dist/addon.js +122 -76
  2. package/dist/addon.mjs +122 -76
  3. package/package.json +1 -1
package/dist/addon.js CHANGED
@@ -10590,11 +10590,11 @@ var ModelVariantGroupSchema = object({
10590
10590
  /** Quantization axis. Omit ⇒ the fp32 base build. */
10591
10591
  precision: _enum(["fp32", "int8"]).optional(),
10592
10592
  /**
10593
- * Speed-optimization axis. Omit ⇒ the standard build. `fast` marks a
10594
- * latency-optimized export (e.g. ReLU-activation variant) — the slot the
10595
- * future performance variants plug into.
10593
+ * Training / latency-variant axis. Omit ⇒ the standard build. `test` marks
10594
+ * an alternate training of the same family (Scrypted `relu_test`); chip
10595
+ * label is "Test".
10596
10596
  */
10597
- optimization: _enum(["standard", "fast"]).optional(),
10597
+ optimization: _enum(["standard", "test"]).optional(),
10598
10598
  /**
10599
10599
  * Input-resolution axis (square input side, px). Omit ⇒ the family's native
10600
10600
  * resolution (640 for yolo26). Reduced-input builds (320 / 256) are a big,
@@ -10617,9 +10617,10 @@ var ModelProviderIdSchema = _enum([
10617
10617
  * are per upstream. A persisted custom-model row written when this field was a
10618
10618
  * string still parses — the string is lifted into `{ weights }`.
10619
10619
  *
10620
- * Every licence surface (the admin "Models and licenses" page,
10621
- * `THIRD_PARTY_MODELS.md`, the Hugging Face model table) is GENERATED from
10622
- * these records by `scripts/gen-model-licenses.ts` (D661).
10620
+ * Every machine licence surface (`THIRD_PARTY_MODELS.md`, the Hugging Face
10621
+ * model table) is GENERATED from these records by
10622
+ * `scripts/gen-model-licenses.ts` (D661). Operator-facing docs live in
10623
+ * `camstack/docs` → `/docs/detection/models`.
10623
10624
  */
10624
10625
  var ModelLicenseSchema = preprocess((value) => typeof value === "string" ? { weights: value } : value, object({
10625
10626
  /** SPDX id of the WEIGHTS' terms, a `LicenseRef-*` for non-SPDX terms, or `UNKNOWN`. */
@@ -14250,7 +14251,7 @@ DeviceType.Camera;
14250
14251
  * This matters here more than anywhere else in the repo, because every provider
14251
14252
  * that knows a device's host knows its PASSWORD too: `{ host, port, username,
14252
14253
  * password }` sit in one object on Hikvision, Amcrest, Reolink and ONVIF alike,
14253
- * and `http://admin:hunter2@192.168.x.x/` is a URL a browser accepts. The
14254
+ * and `http://admin:hunter2@192.168.60.139/` is a URL a browser accepts. The
14254
14255
  * camera's own page will ask for its own login. That is correct, and pre-
14255
14256
  * filling it is the operator's business, not ours.
14256
14257
  *
@@ -17422,7 +17423,7 @@ method(object({
17422
17423
  timeoutMs: 6e5
17423
17424
  });
17424
17425
  method(object({
17425
- nodeId: string(),
17426
+ targetNodeId: string(),
17426
17427
  modelId: string(),
17427
17428
  format: _enum(MODEL_FORMATS),
17428
17429
  entry: ModelCatalogEntrySchema
@@ -19926,8 +19927,9 @@ var NcRuleSchema = NcRuleInputSchema.extend({
19926
19927
  disabledTargetIds: array(string()).default([])
19927
19928
  });
19928
19929
  /**
19929
- * The state-summary SECTIONS (D647 / D698): the D637 kind groups that report a
19930
- * still-true state. `backups-exports` and `alarm` are not sections — a completed
19930
+ * The state-summary SECTIONS (D647 / D698 / D708): the D637 kind groups that
19931
+ * report a still-true state. `addons` is the crash-looped addons only and
19932
+ * `addon-updates` the addons that are behind (D708 split them). `backups-exports` and `alarm` are not sections — a completed
19931
19933
  * job is not an open state, and the alarm stays instant.
19932
19934
  */
19933
19935
  var NcStateSummarySectionIdSchema = _enum([
@@ -19939,6 +19941,7 @@ var NcStateSummarySectionIdSchema = _enum([
19939
19941
  "detection-blind",
19940
19942
  "nodes",
19941
19943
  "addons",
19944
+ "addon-updates",
19942
19945
  "updates"
19943
19946
  ]);
19944
19947
  /** One section of a previewed state summary. `unavailable` = its state could not be read. */
@@ -20419,7 +20422,19 @@ var NcAlarmModeDelaysListSchema = array(object({
20419
20422
  * When this mode may be armed. Absent / null = always allowed (same as a
20420
20423
  * rule with no `schedule`). Evaluated with {@link isScheduleActive}.
20421
20424
  */
20422
- schedule: NcScheduleSchema.optional()
20425
+ schedule: NcScheduleSchema.optional(),
20426
+ /**
20427
+ * D706: while this mode's ENTRY DELAY runs, do the alarm rules' own pushes go out (as an
20428
+ * intrusion naming the locations)? Absent = false — the entry-delay notification is the
20429
+ * only one, and the matches ride the triggered notification's mosaic (D705).
20430
+ */
20431
+ notifyDuringEntryDelay: boolean().optional(),
20432
+ /**
20433
+ * D706: notify "watched again" when a sensor this arm bypassed closes and opens again.
20434
+ * Absent = false (logged, not sent). Even when true it is not sent when that same sensor
20435
+ * is the one that starts the entry delay — the entry-delay notification already names it.
20436
+ */
20437
+ notifySensorRewatched: boolean().optional()
20423
20438
  })).max(8).refine(uniqueModes, { message: "modeDelays: at most one entry per arm mode" });
20424
20439
  var NcAlarmModeDelaysEditListSchema = array(object({
20425
20440
  mode: AlarmArmModeSchema,
@@ -20428,7 +20443,11 @@ var NcAlarmModeDelaysEditListSchema = array(object({
20428
20443
  triggeredDurationSec: NcAlarmTriggeredSecSchema.nullable().optional(),
20429
20444
  postTriggeredAction: NcAlarmPostTriggeredActionSchema.nullable().optional(),
20430
20445
  /** Set a schedule, or `null` to clear (mode always allowed again). */
20431
- schedule: NcScheduleSchema.nullable().optional()
20446
+ schedule: NcScheduleSchema.nullable().optional(),
20447
+ /** D706: set the switch, or `null` to clear it (back to the default, false). */
20448
+ notifyDuringEntryDelay: boolean().nullable().optional(),
20449
+ /** D706: set the switch, or `null` to clear it (back to the default, false). */
20450
+ notifySensorRewatched: boolean().nullable().optional()
20432
20451
  })).max(8).refine(uniqueModes, { message: "modeDelays: at most one edit per arm mode" });
20433
20452
  /** One switch of the alarm table: put ONE device on, or take it off, ONE mode's list. */
20434
20453
  var NcAlarmNonBlockingEditSchema = object({
@@ -21389,39 +21408,19 @@ Object.freeze(Object.fromEntries([{
21389
21408
  label: "Face recognition model",
21390
21409
  defaultModelId: "auraface-r100",
21391
21410
  indexName: "the enrolled face gallery",
21392
- options: [
21393
- {
21394
- id: "auraface-r100",
21395
- label: "AuraFace R100"
21396
- },
21397
- {
21398
- id: "arcface-r100",
21399
- label: "ArcFace (ResNet34)"
21400
- },
21401
- {
21402
- id: "inception-resnet-v1",
21403
- label: "Inception ResNet V1"
21404
- }
21405
- ]
21411
+ options: [{
21412
+ id: "auraface-r100",
21413
+ label: "AuraFace R100"
21414
+ }]
21406
21415
  }, {
21407
21416
  stepId: "clip-embedding",
21408
21417
  label: "Semantic search model",
21409
- defaultModelId: "mobileclip-s1",
21418
+ defaultModelId: "siglip2-b16-224",
21410
21419
  indexName: "the object semantic-search index",
21411
- options: [
21412
- {
21413
- id: "mobileclip-s1",
21414
- label: "MobileCLIP S1"
21415
- },
21416
- {
21417
- id: "mobileclip-s2",
21418
- label: "MobileCLIP S2"
21419
- },
21420
- {
21421
- id: "siglip2-b16-224",
21422
- label: "SigLIP2 B/16 (Apache-2.0)"
21423
- }
21424
- ]
21420
+ options: [{
21421
+ id: "siglip2-b16-224",
21422
+ label: "SigLIP2 B/16 (Apache-2.0)"
21423
+ }]
21425
21424
  }].map((s) => [s.stepId, s.defaultModelId])));
21426
21425
  var CLUSTER_STEP_SETTING_FIELDS = [{
21427
21426
  stepId: "face-embedding",
@@ -24309,6 +24308,22 @@ var MotionSourceEnum = _enum([
24309
24308
  "device-activity"
24310
24309
  ]);
24311
24310
  /**
24311
+ * What opened an on-motion detection SESSION: the motion source that passed the
24312
+ * camera's `motionSources` gate, and what raised it (the camera itself, or a
24313
+ * sensor the operator attached — D672). `sensorName` is the attached sensor's
24314
+ * device name as the orchestrator's camera-sensors resolution last read it;
24315
+ * absent when unknown or when the camera itself triggered.
24316
+ *
24317
+ * Carried on the session attach ONLY so the runner's `DetectionPhaseTransition`
24318
+ * can say what started the session (D672 rule 11, amended 2026-10-06). The
24319
+ * runner never decides anything on it.
24320
+ */
24321
+ var SessionTriggerSchema = object({
24322
+ source: MotionSourceEnum,
24323
+ triggeredBy: MotionTriggeredBySchema,
24324
+ sensorName: string().optional()
24325
+ });
24326
+ /**
24312
24327
  * List of motion sources active on a camera. Empty array is valid:
24313
24328
  * "no source" — happens for battery cams without firmware motion when
24314
24329
  * the operator hasn't opted into the SW analyzer (would hold the
@@ -24560,6 +24575,14 @@ var RunnerCameraConfigSchema = object({
24560
24575
  */
24561
24576
  motionSources: MotionSourcesSchema.default(["analyzer"]),
24562
24577
  /**
24578
+ * What opened this attach, on a SESSION attach only (see
24579
+ * {@link SessionTriggerSchema}). OPTIONAL with no default: absent on a
24580
+ * standing attach, an occupancy burst, a re-dispatch with no motion event
24581
+ * behind it, and every attach from an orchestrator older than the field — the
24582
+ * runner then names no source on the phase event.
24583
+ */
24584
+ sessionTrigger: SessionTriggerSchema.optional(),
24585
+ /**
24563
24586
  * WHICH root detector runs for this camera. The detection counterpart of
24564
24587
  * {@link motionSources}, same shape and same discipline: a per-camera list
24565
24588
  * of sources the system understands, vendor-agnostic, owned here.
@@ -32060,7 +32083,7 @@ var LocalInterfaceSchema = object({
32060
32083
  name: string(),
32061
32084
  family: _enum(["IPv4", "IPv6"]),
32062
32085
  address: string(),
32063
- /** CIDR shorthand (e.g. `192.168.x.x/24`). Empty when OS doesn't expose. */
32086
+ /** CIDR shorthand (e.g. `192.168.10.10/24`). Empty when OS doesn't expose. */
32064
32087
  cidr: string(),
32065
32088
  /** OS netmask. Stable across calls so the SDK can hash on it. */
32066
32089
  netmask: string(),
@@ -32114,7 +32137,8 @@ var ConnectionEndpointSchema = object({
32114
32137
  "lan-ipv4",
32115
32138
  "lan-ipv6",
32116
32139
  "public",
32117
- "loopback"
32140
+ "loopback",
32141
+ "app-link"
32118
32142
  ]),
32119
32143
  /**
32120
32144
  * Originating-interface kind — `lan`/`wifi`/`docker`/`vpn`/`other`/
@@ -32183,15 +32207,27 @@ var GetConnectionEndpointsResultSchema = object({
32183
32207
  localPort: AdvertisedLocalPortSchema
32184
32208
  });
32185
32209
  /**
32186
- * The chosen outbound endpoint for notification artifacts. `baseUrl: null` =
32187
- * AUTO (resolved from the candidate ranking at send time); `resolved` reports
32188
- * what AUTO currently picks, so the UI can show the effective value either way.
32210
+ * The address flagged for notification links. `baseUrl: null` = AUTO, which
32211
+ * since D709 is the CamStack app link; `resolved` reports the effective value,
32212
+ * so the UI can show it either way.
32189
32213
  */
32190
32214
  var NotificationEndpointSchema = object({
32191
32215
  /** The operator's explicit choice, or null for AUTO. */
32192
32216
  baseUrl: string().nullable(),
32193
- /** What the ranking currently resolves to (null when nothing is reachable). */
32194
- resolved: string().nullable()
32217
+ /**
32218
+ * The effective flagged address: the explicit choice, else (AUTO) the
32219
+ * CamStack app link `https://camstack.zentik.app` (D709). A pre-D709 hub
32220
+ * answered the public tunnel / mesh here, or null.
32221
+ */
32222
+ resolved: string().nullable(),
32223
+ /**
32224
+ * The hub origin an app link carries as `hub=` (D709): the hub's best
32225
+ * public HTTPS address — the tunnel, then the mesh (Tailscale MagicDNS) —
32226
+ * picked from this cap's own palette by `pickAppLinkHub`. `null` when the
32227
+ * hub advertises neither; the app link is then minted without `hub=`.
32228
+ * Absent on a pre-D709 hub.
32229
+ */
32230
+ appLinkHub: string().nullable()
32195
32231
  });
32196
32232
  /**
32197
32233
  * The URLs the SDK / viewer should race for API access. `baseUrls` empty =
@@ -32245,7 +32281,11 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
32245
32281
  * Pass `'https'` when the caller is itself loaded over HTTPS
32246
32282
  * to avoid mixed-content blocks in the browser. The public
32247
32283
  * tunnel always emits `https://` regardless. */
32248
- scheme: _enum(["http", "https"]).optional()
32284
+ scheme: _enum(["http", "https"]).optional(),
32285
+ /** Append the CamStack app link entry (`kind: 'app-link'`, D709) —
32286
+ * an address notification links can be flagged with, not a hub
32287
+ * route. Default `false`: racers and rankers never see it. */
32288
+ includeAppLink: boolean().optional()
32249
32289
  }), GetConnectionEndpointsResultSchema), method(_void(), NotificationEndpointSchema), method(object({ baseUrl: string().nullable() }), NotificationEndpointSchema, { kind: "mutation" }), method(_void(), ViewerEndpointsSchema), method(object({ baseUrls: array(string()).readonly() }), ViewerEndpointsSchema, { kind: "mutation" }), method(_void(), AllowedAddressesSchema), method(AllowedAddressesSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), AllowedAddressesSchema, { kind: "mutation" }), method(_void(), TlsStatusSchema), method(object({ reason: string().optional() }), TlsStatusSchema, {
32250
32290
  kind: "mutation",
32251
32291
  auth: "admin"
@@ -32574,7 +32614,7 @@ var MeshPeerSchema = object({
32574
32614
  tags: array(string()).readonly(),
32575
32615
  /** True when the peer advertises itself as an exit-node candidate. */
32576
32616
  exitNodeOption: boolean(),
32577
- /** Subnet routes the peer advertises (e.g. `["192.168.x.x/24"]`). */
32617
+ /** Subnet routes the peer advertises (e.g. `["192.168.10.0/24"]`). */
32578
32618
  advertisedRoutes: array(string()).readonly(),
32579
32619
  /** Owner account login (e.g. `foo@example.com`). Null for tagged peers. */
32580
32620
  userLogin: string().nullable(),
@@ -33902,7 +33942,13 @@ var OsdStatusSchema = object({ overlays: array(object({
33902
33942
  */
33903
33943
  availablePositions: array(OsdPositionEnum).readonly(),
33904
33944
  /** Firmware does not allow editing the `text` field (e.g. timestamp). */
33905
- readOnly: boolean().optional()
33945
+ readOnly: boolean().optional(),
33946
+ /**
33947
+ * Firmware text ceiling for this overlay. Absent = no known limit.
33948
+ * The OSD manager truncates here on every write — never stores its own
33949
+ * copy on the binding.
33950
+ */
33951
+ maxCharacters: number().int().positive().optional()
33906
33952
  })).readonly() });
33907
33953
  var OsdOverlayPatchSchema = object({
33908
33954
  enabled: boolean().optional(),
@@ -33953,7 +33999,9 @@ var OsdTemplateBindingSchema = object({
33953
33999
  valuePath: string().min(1).max(64),
33954
34000
  /** Convert TO this unit at render (`tryConvertUnit`). Absent = source unit. */
33955
34001
  displayUnit: string().max(16).optional(),
33956
- maxDecimals: number().int().min(0).max(4).default(1)
34002
+ maxDecimals: number().int().min(0).max(4).default(1),
34003
+ /** Raw value → display text (same shape as slot binding). Empty string hides. */
34004
+ valueMap: record(string(), string()).optional()
33957
34005
  });
33958
34006
  /**
33959
34007
  * A named template: bindings (alias → leaf field) + a parser that
@@ -34003,18 +34051,11 @@ var OsdSlotBindingSchema = object({
34003
34051
  source: OsdSourceSchema,
34004
34052
  /** `${value}` and `${unit}` are substituted; every occurrence. */
34005
34053
  template: string().max(96).default("${value}"),
34006
- /** Truncate with an ellipsis past this length. Absent = no limit. */
34007
- maxCharacters: number().int().min(4).max(64).optional(),
34008
34054
  /**
34009
34055
  * Decimal places for a numeric value. `0` yields an integer — the
34010
34056
  * documented workaround for firmwares that reject `.` in overlay text.
34011
34057
  */
34012
34058
  maxDecimals: number().int().min(0).max(4).default(1),
34013
- /**
34014
- * Appended via `${unit}` when no unit conversion produces a label.
34015
- * Prefer `source.displayUnit` for converted device-state values.
34016
- */
34017
- unitLabel: string().max(8).optional(),
34018
34059
  /** Raw value → display text, e.g. `{"true":"MOTION","false":""}`. */
34019
34060
  valueMap: record(string(), string()).optional(),
34020
34061
  /** Time windows in which the slot is shown. Absent = always. */
@@ -34023,9 +34064,7 @@ var OsdSlotBindingSchema = object({
34023
34064
  * Display gate, in the notification centre's condition vocabulary.
34024
34065
  * Only the keys reported by `getConditionSupport` are accepted.
34025
34066
  */
34026
- conditions: NcConditionsSchema.optional(),
34027
- /** Rendered when the gate is closed or the value unreadable. Empty = hide. */
34028
- fallbackText: string().max(64).default("")
34067
+ conditions: NcConditionsSchema.optional()
34029
34068
  });
34030
34069
  /** One camera slot, as the operator sees it: firmware truth + our binding. */
34031
34070
  var OsdSlotViewSchema = object({
@@ -52324,12 +52363,14 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
52324
52363
  {
52325
52364
  id: "addons",
52326
52365
  family: "system",
52327
- label: "Addons",
52328
- kinds: [
52329
- "addon-crash-loop",
52330
- "addon-update-available",
52331
- "addon-updated"
52332
- ]
52366
+ label: "Addons stopped",
52367
+ kinds: ["addon-crash-loop"]
52368
+ },
52369
+ {
52370
+ id: "addon-updates",
52371
+ family: "system",
52372
+ label: "Addon updates",
52373
+ kinds: ["addon-update-available", "addon-updated"]
52333
52374
  },
52334
52375
  {
52335
52376
  id: "updates",
@@ -52489,13 +52530,15 @@ var STATE_SUMMARY_SECTION_VARS = [
52489
52530
  },
52490
52531
  {
52491
52532
  name: "summaryAddons",
52492
- label: "Summary: addons",
52493
- example: "@camstack/addon-recorder 1.2.3 → 1.2.4",
52494
- kinds: [
52495
- "addon-crash-loop",
52496
- "addon-update-available",
52497
- "addon-updated"
52498
- ]
52533
+ label: "Summary: addons stopped",
52534
+ example: "hub — recorder stopped after repeated crashes",
52535
+ kinds: ["addon-crash-loop"]
52536
+ },
52537
+ {
52538
+ name: "summaryAddonUpdates",
52539
+ label: "Summary: addon updates",
52540
+ example: "hub:\n• @camstack/addon-recorder 1.2.3 → 1.2.4",
52541
+ kinds: ["addon-update-available", "addon-updated"]
52499
52542
  },
52500
52543
  {
52501
52544
  name: "summaryUpdates",
@@ -52579,6 +52622,7 @@ var STATE_SUMMARY_VARS = [
52579
52622
  [...RULE_BODY_ONLY],
52580
52623
  [...RULE_TEXT],
52581
52624
  ([...RULE_TEXT], [...DEVICE_EVENTS]),
52625
+ ([...RULE_TEXT], [...COMBINED_ALARM]),
52582
52626
  ([...RULE_TEXT], [...DEVICE_EVENTS]),
52583
52627
  ([...RULE_TEXT], [...BATTERY, ...CONSUMABLE]),
52584
52628
  ([...RULE_TEXT], [...CONSUMABLE]),
@@ -52619,6 +52663,8 @@ var STATE_SUMMARY_VARS = [
52619
52663
  [...RULE_TEXT],
52620
52664
  [...RULE_TEXT],
52621
52665
  [...RULE_TEXT],
52666
+ [...RULE_TEXT],
52667
+ [...RULE_TEXT],
52622
52668
  ...STATE_SUMMARY_VARS
52623
52669
  ];
52624
52670
  new Set([
package/dist/addon.mjs CHANGED
@@ -10566,11 +10566,11 @@ var ModelVariantGroupSchema = object({
10566
10566
  /** Quantization axis. Omit ⇒ the fp32 base build. */
10567
10567
  precision: _enum(["fp32", "int8"]).optional(),
10568
10568
  /**
10569
- * Speed-optimization axis. Omit ⇒ the standard build. `fast` marks a
10570
- * latency-optimized export (e.g. ReLU-activation variant) — the slot the
10571
- * future performance variants plug into.
10569
+ * Training / latency-variant axis. Omit ⇒ the standard build. `test` marks
10570
+ * an alternate training of the same family (Scrypted `relu_test`); chip
10571
+ * label is "Test".
10572
10572
  */
10573
- optimization: _enum(["standard", "fast"]).optional(),
10573
+ optimization: _enum(["standard", "test"]).optional(),
10574
10574
  /**
10575
10575
  * Input-resolution axis (square input side, px). Omit ⇒ the family's native
10576
10576
  * resolution (640 for yolo26). Reduced-input builds (320 / 256) are a big,
@@ -10593,9 +10593,10 @@ var ModelProviderIdSchema = _enum([
10593
10593
  * are per upstream. A persisted custom-model row written when this field was a
10594
10594
  * string still parses — the string is lifted into `{ weights }`.
10595
10595
  *
10596
- * Every licence surface (the admin "Models and licenses" page,
10597
- * `THIRD_PARTY_MODELS.md`, the Hugging Face model table) is GENERATED from
10598
- * these records by `scripts/gen-model-licenses.ts` (D661).
10596
+ * Every machine licence surface (`THIRD_PARTY_MODELS.md`, the Hugging Face
10597
+ * model table) is GENERATED from these records by
10598
+ * `scripts/gen-model-licenses.ts` (D661). Operator-facing docs live in
10599
+ * `camstack/docs` → `/docs/detection/models`.
10599
10600
  */
10600
10601
  var ModelLicenseSchema = preprocess((value) => typeof value === "string" ? { weights: value } : value, object({
10601
10602
  /** SPDX id of the WEIGHTS' terms, a `LicenseRef-*` for non-SPDX terms, or `UNKNOWN`. */
@@ -14226,7 +14227,7 @@ DeviceType.Camera;
14226
14227
  * This matters here more than anywhere else in the repo, because every provider
14227
14228
  * that knows a device's host knows its PASSWORD too: `{ host, port, username,
14228
14229
  * password }` sit in one object on Hikvision, Amcrest, Reolink and ONVIF alike,
14229
- * and `http://admin:hunter2@192.168.x.x/` is a URL a browser accepts. The
14230
+ * and `http://admin:hunter2@192.168.60.139/` is a URL a browser accepts. The
14230
14231
  * camera's own page will ask for its own login. That is correct, and pre-
14231
14232
  * filling it is the operator's business, not ours.
14232
14233
  *
@@ -17398,7 +17399,7 @@ method(object({
17398
17399
  timeoutMs: 6e5
17399
17400
  });
17400
17401
  method(object({
17401
- nodeId: string(),
17402
+ targetNodeId: string(),
17402
17403
  modelId: string(),
17403
17404
  format: _enum(MODEL_FORMATS),
17404
17405
  entry: ModelCatalogEntrySchema
@@ -19902,8 +19903,9 @@ var NcRuleSchema = NcRuleInputSchema.extend({
19902
19903
  disabledTargetIds: array(string()).default([])
19903
19904
  });
19904
19905
  /**
19905
- * The state-summary SECTIONS (D647 / D698): the D637 kind groups that report a
19906
- * still-true state. `backups-exports` and `alarm` are not sections — a completed
19906
+ * The state-summary SECTIONS (D647 / D698 / D708): the D637 kind groups that
19907
+ * report a still-true state. `addons` is the crash-looped addons only and
19908
+ * `addon-updates` the addons that are behind (D708 split them). `backups-exports` and `alarm` are not sections — a completed
19907
19909
  * job is not an open state, and the alarm stays instant.
19908
19910
  */
19909
19911
  var NcStateSummarySectionIdSchema = _enum([
@@ -19915,6 +19917,7 @@ var NcStateSummarySectionIdSchema = _enum([
19915
19917
  "detection-blind",
19916
19918
  "nodes",
19917
19919
  "addons",
19920
+ "addon-updates",
19918
19921
  "updates"
19919
19922
  ]);
19920
19923
  /** One section of a previewed state summary. `unavailable` = its state could not be read. */
@@ -20395,7 +20398,19 @@ var NcAlarmModeDelaysListSchema = array(object({
20395
20398
  * When this mode may be armed. Absent / null = always allowed (same as a
20396
20399
  * rule with no `schedule`). Evaluated with {@link isScheduleActive}.
20397
20400
  */
20398
- schedule: NcScheduleSchema.optional()
20401
+ schedule: NcScheduleSchema.optional(),
20402
+ /**
20403
+ * D706: while this mode's ENTRY DELAY runs, do the alarm rules' own pushes go out (as an
20404
+ * intrusion naming the locations)? Absent = false — the entry-delay notification is the
20405
+ * only one, and the matches ride the triggered notification's mosaic (D705).
20406
+ */
20407
+ notifyDuringEntryDelay: boolean().optional(),
20408
+ /**
20409
+ * D706: notify "watched again" when a sensor this arm bypassed closes and opens again.
20410
+ * Absent = false (logged, not sent). Even when true it is not sent when that same sensor
20411
+ * is the one that starts the entry delay — the entry-delay notification already names it.
20412
+ */
20413
+ notifySensorRewatched: boolean().optional()
20399
20414
  })).max(8).refine(uniqueModes, { message: "modeDelays: at most one entry per arm mode" });
20400
20415
  var NcAlarmModeDelaysEditListSchema = array(object({
20401
20416
  mode: AlarmArmModeSchema,
@@ -20404,7 +20419,11 @@ var NcAlarmModeDelaysEditListSchema = array(object({
20404
20419
  triggeredDurationSec: NcAlarmTriggeredSecSchema.nullable().optional(),
20405
20420
  postTriggeredAction: NcAlarmPostTriggeredActionSchema.nullable().optional(),
20406
20421
  /** Set a schedule, or `null` to clear (mode always allowed again). */
20407
- schedule: NcScheduleSchema.nullable().optional()
20422
+ schedule: NcScheduleSchema.nullable().optional(),
20423
+ /** D706: set the switch, or `null` to clear it (back to the default, false). */
20424
+ notifyDuringEntryDelay: boolean().nullable().optional(),
20425
+ /** D706: set the switch, or `null` to clear it (back to the default, false). */
20426
+ notifySensorRewatched: boolean().nullable().optional()
20408
20427
  })).max(8).refine(uniqueModes, { message: "modeDelays: at most one edit per arm mode" });
20409
20428
  /** One switch of the alarm table: put ONE device on, or take it off, ONE mode's list. */
20410
20429
  var NcAlarmNonBlockingEditSchema = object({
@@ -21365,39 +21384,19 @@ Object.freeze(Object.fromEntries([{
21365
21384
  label: "Face recognition model",
21366
21385
  defaultModelId: "auraface-r100",
21367
21386
  indexName: "the enrolled face gallery",
21368
- options: [
21369
- {
21370
- id: "auraface-r100",
21371
- label: "AuraFace R100"
21372
- },
21373
- {
21374
- id: "arcface-r100",
21375
- label: "ArcFace (ResNet34)"
21376
- },
21377
- {
21378
- id: "inception-resnet-v1",
21379
- label: "Inception ResNet V1"
21380
- }
21381
- ]
21387
+ options: [{
21388
+ id: "auraface-r100",
21389
+ label: "AuraFace R100"
21390
+ }]
21382
21391
  }, {
21383
21392
  stepId: "clip-embedding",
21384
21393
  label: "Semantic search model",
21385
- defaultModelId: "mobileclip-s1",
21394
+ defaultModelId: "siglip2-b16-224",
21386
21395
  indexName: "the object semantic-search index",
21387
- options: [
21388
- {
21389
- id: "mobileclip-s1",
21390
- label: "MobileCLIP S1"
21391
- },
21392
- {
21393
- id: "mobileclip-s2",
21394
- label: "MobileCLIP S2"
21395
- },
21396
- {
21397
- id: "siglip2-b16-224",
21398
- label: "SigLIP2 B/16 (Apache-2.0)"
21399
- }
21400
- ]
21396
+ options: [{
21397
+ id: "siglip2-b16-224",
21398
+ label: "SigLIP2 B/16 (Apache-2.0)"
21399
+ }]
21401
21400
  }].map((s) => [s.stepId, s.defaultModelId])));
21402
21401
  var CLUSTER_STEP_SETTING_FIELDS = [{
21403
21402
  stepId: "face-embedding",
@@ -24285,6 +24284,22 @@ var MotionSourceEnum = _enum([
24285
24284
  "device-activity"
24286
24285
  ]);
24287
24286
  /**
24287
+ * What opened an on-motion detection SESSION: the motion source that passed the
24288
+ * camera's `motionSources` gate, and what raised it (the camera itself, or a
24289
+ * sensor the operator attached — D672). `sensorName` is the attached sensor's
24290
+ * device name as the orchestrator's camera-sensors resolution last read it;
24291
+ * absent when unknown or when the camera itself triggered.
24292
+ *
24293
+ * Carried on the session attach ONLY so the runner's `DetectionPhaseTransition`
24294
+ * can say what started the session (D672 rule 11, amended 2026-10-06). The
24295
+ * runner never decides anything on it.
24296
+ */
24297
+ var SessionTriggerSchema = object({
24298
+ source: MotionSourceEnum,
24299
+ triggeredBy: MotionTriggeredBySchema,
24300
+ sensorName: string().optional()
24301
+ });
24302
+ /**
24288
24303
  * List of motion sources active on a camera. Empty array is valid:
24289
24304
  * "no source" — happens for battery cams without firmware motion when
24290
24305
  * the operator hasn't opted into the SW analyzer (would hold the
@@ -24536,6 +24551,14 @@ var RunnerCameraConfigSchema = object({
24536
24551
  */
24537
24552
  motionSources: MotionSourcesSchema.default(["analyzer"]),
24538
24553
  /**
24554
+ * What opened this attach, on a SESSION attach only (see
24555
+ * {@link SessionTriggerSchema}). OPTIONAL with no default: absent on a
24556
+ * standing attach, an occupancy burst, a re-dispatch with no motion event
24557
+ * behind it, and every attach from an orchestrator older than the field — the
24558
+ * runner then names no source on the phase event.
24559
+ */
24560
+ sessionTrigger: SessionTriggerSchema.optional(),
24561
+ /**
24539
24562
  * WHICH root detector runs for this camera. The detection counterpart of
24540
24563
  * {@link motionSources}, same shape and same discipline: a per-camera list
24541
24564
  * of sources the system understands, vendor-agnostic, owned here.
@@ -32036,7 +32059,7 @@ var LocalInterfaceSchema = object({
32036
32059
  name: string(),
32037
32060
  family: _enum(["IPv4", "IPv6"]),
32038
32061
  address: string(),
32039
- /** CIDR shorthand (e.g. `192.168.x.x/24`). Empty when OS doesn't expose. */
32062
+ /** CIDR shorthand (e.g. `192.168.10.10/24`). Empty when OS doesn't expose. */
32040
32063
  cidr: string(),
32041
32064
  /** OS netmask. Stable across calls so the SDK can hash on it. */
32042
32065
  netmask: string(),
@@ -32090,7 +32113,8 @@ var ConnectionEndpointSchema = object({
32090
32113
  "lan-ipv4",
32091
32114
  "lan-ipv6",
32092
32115
  "public",
32093
- "loopback"
32116
+ "loopback",
32117
+ "app-link"
32094
32118
  ]),
32095
32119
  /**
32096
32120
  * Originating-interface kind — `lan`/`wifi`/`docker`/`vpn`/`other`/
@@ -32159,15 +32183,27 @@ var GetConnectionEndpointsResultSchema = object({
32159
32183
  localPort: AdvertisedLocalPortSchema
32160
32184
  });
32161
32185
  /**
32162
- * The chosen outbound endpoint for notification artifacts. `baseUrl: null` =
32163
- * AUTO (resolved from the candidate ranking at send time); `resolved` reports
32164
- * what AUTO currently picks, so the UI can show the effective value either way.
32186
+ * The address flagged for notification links. `baseUrl: null` = AUTO, which
32187
+ * since D709 is the CamStack app link; `resolved` reports the effective value,
32188
+ * so the UI can show it either way.
32165
32189
  */
32166
32190
  var NotificationEndpointSchema = object({
32167
32191
  /** The operator's explicit choice, or null for AUTO. */
32168
32192
  baseUrl: string().nullable(),
32169
- /** What the ranking currently resolves to (null when nothing is reachable). */
32170
- resolved: string().nullable()
32193
+ /**
32194
+ * The effective flagged address: the explicit choice, else (AUTO) the
32195
+ * CamStack app link `https://camstack.zentik.app` (D709). A pre-D709 hub
32196
+ * answered the public tunnel / mesh here, or null.
32197
+ */
32198
+ resolved: string().nullable(),
32199
+ /**
32200
+ * The hub origin an app link carries as `hub=` (D709): the hub's best
32201
+ * public HTTPS address — the tunnel, then the mesh (Tailscale MagicDNS) —
32202
+ * picked from this cap's own palette by `pickAppLinkHub`. `null` when the
32203
+ * hub advertises neither; the app link is then minted without `hub=`.
32204
+ * Absent on a pre-D709 hub.
32205
+ */
32206
+ appLinkHub: string().nullable()
32171
32207
  });
32172
32208
  /**
32173
32209
  * The URLs the SDK / viewer should race for API access. `baseUrls` empty =
@@ -32221,7 +32257,11 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
32221
32257
  * Pass `'https'` when the caller is itself loaded over HTTPS
32222
32258
  * to avoid mixed-content blocks in the browser. The public
32223
32259
  * tunnel always emits `https://` regardless. */
32224
- scheme: _enum(["http", "https"]).optional()
32260
+ scheme: _enum(["http", "https"]).optional(),
32261
+ /** Append the CamStack app link entry (`kind: 'app-link'`, D709) —
32262
+ * an address notification links can be flagged with, not a hub
32263
+ * route. Default `false`: racers and rankers never see it. */
32264
+ includeAppLink: boolean().optional()
32225
32265
  }), GetConnectionEndpointsResultSchema), method(_void(), NotificationEndpointSchema), method(object({ baseUrl: string().nullable() }), NotificationEndpointSchema, { kind: "mutation" }), method(_void(), ViewerEndpointsSchema), method(object({ baseUrls: array(string()).readonly() }), ViewerEndpointsSchema, { kind: "mutation" }), method(_void(), AllowedAddressesSchema), method(AllowedAddressesSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), AllowedAddressesSchema, { kind: "mutation" }), method(_void(), TlsStatusSchema), method(object({ reason: string().optional() }), TlsStatusSchema, {
32226
32266
  kind: "mutation",
32227
32267
  auth: "admin"
@@ -32550,7 +32590,7 @@ var MeshPeerSchema = object({
32550
32590
  tags: array(string()).readonly(),
32551
32591
  /** True when the peer advertises itself as an exit-node candidate. */
32552
32592
  exitNodeOption: boolean(),
32553
- /** Subnet routes the peer advertises (e.g. `["192.168.x.x/24"]`). */
32593
+ /** Subnet routes the peer advertises (e.g. `["192.168.10.0/24"]`). */
32554
32594
  advertisedRoutes: array(string()).readonly(),
32555
32595
  /** Owner account login (e.g. `foo@example.com`). Null for tagged peers. */
32556
32596
  userLogin: string().nullable(),
@@ -33878,7 +33918,13 @@ var OsdStatusSchema = object({ overlays: array(object({
33878
33918
  */
33879
33919
  availablePositions: array(OsdPositionEnum).readonly(),
33880
33920
  /** Firmware does not allow editing the `text` field (e.g. timestamp). */
33881
- readOnly: boolean().optional()
33921
+ readOnly: boolean().optional(),
33922
+ /**
33923
+ * Firmware text ceiling for this overlay. Absent = no known limit.
33924
+ * The OSD manager truncates here on every write — never stores its own
33925
+ * copy on the binding.
33926
+ */
33927
+ maxCharacters: number().int().positive().optional()
33882
33928
  })).readonly() });
33883
33929
  var OsdOverlayPatchSchema = object({
33884
33930
  enabled: boolean().optional(),
@@ -33929,7 +33975,9 @@ var OsdTemplateBindingSchema = object({
33929
33975
  valuePath: string().min(1).max(64),
33930
33976
  /** Convert TO this unit at render (`tryConvertUnit`). Absent = source unit. */
33931
33977
  displayUnit: string().max(16).optional(),
33932
- maxDecimals: number().int().min(0).max(4).default(1)
33978
+ maxDecimals: number().int().min(0).max(4).default(1),
33979
+ /** Raw value → display text (same shape as slot binding). Empty string hides. */
33980
+ valueMap: record(string(), string()).optional()
33933
33981
  });
33934
33982
  /**
33935
33983
  * A named template: bindings (alias → leaf field) + a parser that
@@ -33979,18 +34027,11 @@ var OsdSlotBindingSchema = object({
33979
34027
  source: OsdSourceSchema,
33980
34028
  /** `${value}` and `${unit}` are substituted; every occurrence. */
33981
34029
  template: string().max(96).default("${value}"),
33982
- /** Truncate with an ellipsis past this length. Absent = no limit. */
33983
- maxCharacters: number().int().min(4).max(64).optional(),
33984
34030
  /**
33985
34031
  * Decimal places for a numeric value. `0` yields an integer — the
33986
34032
  * documented workaround for firmwares that reject `.` in overlay text.
33987
34033
  */
33988
34034
  maxDecimals: number().int().min(0).max(4).default(1),
33989
- /**
33990
- * Appended via `${unit}` when no unit conversion produces a label.
33991
- * Prefer `source.displayUnit` for converted device-state values.
33992
- */
33993
- unitLabel: string().max(8).optional(),
33994
34035
  /** Raw value → display text, e.g. `{"true":"MOTION","false":""}`. */
33995
34036
  valueMap: record(string(), string()).optional(),
33996
34037
  /** Time windows in which the slot is shown. Absent = always. */
@@ -33999,9 +34040,7 @@ var OsdSlotBindingSchema = object({
33999
34040
  * Display gate, in the notification centre's condition vocabulary.
34000
34041
  * Only the keys reported by `getConditionSupport` are accepted.
34001
34042
  */
34002
- conditions: NcConditionsSchema.optional(),
34003
- /** Rendered when the gate is closed or the value unreadable. Empty = hide. */
34004
- fallbackText: string().max(64).default("")
34043
+ conditions: NcConditionsSchema.optional()
34005
34044
  });
34006
34045
  /** One camera slot, as the operator sees it: firmware truth + our binding. */
34007
34046
  var OsdSlotViewSchema = object({
@@ -52300,12 +52339,14 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
52300
52339
  {
52301
52340
  id: "addons",
52302
52341
  family: "system",
52303
- label: "Addons",
52304
- kinds: [
52305
- "addon-crash-loop",
52306
- "addon-update-available",
52307
- "addon-updated"
52308
- ]
52342
+ label: "Addons stopped",
52343
+ kinds: ["addon-crash-loop"]
52344
+ },
52345
+ {
52346
+ id: "addon-updates",
52347
+ family: "system",
52348
+ label: "Addon updates",
52349
+ kinds: ["addon-update-available", "addon-updated"]
52309
52350
  },
52310
52351
  {
52311
52352
  id: "updates",
@@ -52465,13 +52506,15 @@ var STATE_SUMMARY_SECTION_VARS = [
52465
52506
  },
52466
52507
  {
52467
52508
  name: "summaryAddons",
52468
- label: "Summary: addons",
52469
- example: "@camstack/addon-recorder 1.2.3 → 1.2.4",
52470
- kinds: [
52471
- "addon-crash-loop",
52472
- "addon-update-available",
52473
- "addon-updated"
52474
- ]
52509
+ label: "Summary: addons stopped",
52510
+ example: "hub — recorder stopped after repeated crashes",
52511
+ kinds: ["addon-crash-loop"]
52512
+ },
52513
+ {
52514
+ name: "summaryAddonUpdates",
52515
+ label: "Summary: addon updates",
52516
+ example: "hub:\n• @camstack/addon-recorder 1.2.3 → 1.2.4",
52517
+ kinds: ["addon-update-available", "addon-updated"]
52475
52518
  },
52476
52519
  {
52477
52520
  name: "summaryUpdates",
@@ -52555,6 +52598,7 @@ var STATE_SUMMARY_VARS = [
52555
52598
  [...RULE_BODY_ONLY],
52556
52599
  [...RULE_TEXT],
52557
52600
  ([...RULE_TEXT], [...DEVICE_EVENTS]),
52601
+ ([...RULE_TEXT], [...COMBINED_ALARM]),
52558
52602
  ([...RULE_TEXT], [...DEVICE_EVENTS]),
52559
52603
  ([...RULE_TEXT], [...BATTERY, ...CONSUMABLE]),
52560
52604
  ([...RULE_TEXT], [...CONSUMABLE]),
@@ -52595,6 +52639,8 @@ var STATE_SUMMARY_VARS = [
52595
52639
  [...RULE_TEXT],
52596
52640
  [...RULE_TEXT],
52597
52641
  [...RULE_TEXT],
52642
+ [...RULE_TEXT],
52643
+ [...RULE_TEXT],
52598
52644
  ...STATE_SUMMARY_VARS
52599
52645
  ];
52600
52646
  new Set([
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-rtsp",
3
- "version": "1.2.120",
3
+ "version": "1.2.121",
4
4
  "description": "Generic RTSP camera device provider addon for CamStack",
5
5
  "keywords": [
6
6
  "camstack",