@camstack/addon-provider-rademacher 0.2.118 → 0.2.120

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 +123 -77
  2. package/dist/addon.mjs +123 -77
  3. package/package.json +1 -1
package/dist/addon.js CHANGED
@@ -11519,11 +11519,11 @@ var ModelVariantGroupSchema = object({
11519
11519
  /** Quantization axis. Omit ⇒ the fp32 base build. */
11520
11520
  precision: _enum(["fp32", "int8"]).optional(),
11521
11521
  /**
11522
- * Speed-optimization axis. Omit ⇒ the standard build. `fast` marks a
11523
- * latency-optimized export (e.g. ReLU-activation variant) — the slot the
11524
- * future performance variants plug into.
11522
+ * Training / latency-variant axis. Omit ⇒ the standard build. `test` marks
11523
+ * an alternate training of the same family (Scrypted `relu_test`); chip
11524
+ * label is "Test".
11525
11525
  */
11526
- optimization: _enum(["standard", "fast"]).optional(),
11526
+ optimization: _enum(["standard", "test"]).optional(),
11527
11527
  /**
11528
11528
  * Input-resolution axis (square input side, px). Omit ⇒ the family's native
11529
11529
  * resolution (640 for yolo26). Reduced-input builds (320 / 256) are a big,
@@ -11546,9 +11546,10 @@ var ModelProviderIdSchema = _enum([
11546
11546
  * are per upstream. A persisted custom-model row written when this field was a
11547
11547
  * string still parses — the string is lifted into `{ weights }`.
11548
11548
  *
11549
- * Every licence surface (the admin "Models and licenses" page,
11550
- * `THIRD_PARTY_MODELS.md`, the Hugging Face model table) is GENERATED from
11551
- * these records by `scripts/gen-model-licenses.ts` (D661).
11549
+ * Every machine licence surface (`THIRD_PARTY_MODELS.md`, the Hugging Face
11550
+ * model table) is GENERATED from these records by
11551
+ * `scripts/gen-model-licenses.ts` (D661). Operator-facing docs live in
11552
+ * `camstack/docs` → `/docs/detection/models`.
11552
11553
  */
11553
11554
  var ModelLicenseSchema = preprocess((value) => typeof value === "string" ? { weights: value } : value, object({
11554
11555
  /** SPDX id of the WEIGHTS' terms, a `LicenseRef-*` for non-SPDX terms, or `UNKNOWN`. */
@@ -15179,7 +15180,7 @@ DeviceType.Camera;
15179
15180
  * This matters here more than anywhere else in the repo, because every provider
15180
15181
  * that knows a device's host knows its PASSWORD too: `{ host, port, username,
15181
15182
  * password }` sit in one object on Hikvision, Amcrest, Reolink and ONVIF alike,
15182
- * and `http://admin:hunter2@192.168.x.x/` is a URL a browser accepts. The
15183
+ * and `http://admin:hunter2@192.168.60.139/` is a URL a browser accepts. The
15183
15184
  * camera's own page will ask for its own login. That is correct, and pre-
15184
15185
  * filling it is the operator's business, not ours.
15185
15186
  *
@@ -18464,7 +18465,7 @@ method(object({
18464
18465
  timeoutMs: 6e5
18465
18466
  });
18466
18467
  method(object({
18467
- nodeId: string(),
18468
+ targetNodeId: string(),
18468
18469
  modelId: string(),
18469
18470
  format: _enum(MODEL_FORMATS),
18470
18471
  entry: ModelCatalogEntrySchema
@@ -20968,8 +20969,9 @@ var NcRuleSchema = NcRuleInputSchema.extend({
20968
20969
  disabledTargetIds: array(string()).default([])
20969
20970
  });
20970
20971
  /**
20971
- * The state-summary SECTIONS (D647 / D698): the D637 kind groups that report a
20972
- * still-true state. `backups-exports` and `alarm` are not sections — a completed
20972
+ * The state-summary SECTIONS (D647 / D698 / D708): the D637 kind groups that
20973
+ * report a still-true state. `addons` is the crash-looped addons only and
20974
+ * `addon-updates` the addons that are behind (D708 split them). `backups-exports` and `alarm` are not sections — a completed
20973
20975
  * job is not an open state, and the alarm stays instant.
20974
20976
  */
20975
20977
  var NcStateSummarySectionIdSchema = _enum([
@@ -20981,6 +20983,7 @@ var NcStateSummarySectionIdSchema = _enum([
20981
20983
  "detection-blind",
20982
20984
  "nodes",
20983
20985
  "addons",
20986
+ "addon-updates",
20984
20987
  "updates"
20985
20988
  ]);
20986
20989
  /** One section of a previewed state summary. `unavailable` = its state could not be read. */
@@ -21461,7 +21464,19 @@ var NcAlarmModeDelaysListSchema = array(object({
21461
21464
  * When this mode may be armed. Absent / null = always allowed (same as a
21462
21465
  * rule with no `schedule`). Evaluated with {@link isScheduleActive}.
21463
21466
  */
21464
- schedule: NcScheduleSchema.optional()
21467
+ schedule: NcScheduleSchema.optional(),
21468
+ /**
21469
+ * D706: while this mode's ENTRY DELAY runs, do the alarm rules' own pushes go out (as an
21470
+ * intrusion naming the locations)? Absent = false — the entry-delay notification is the
21471
+ * only one, and the matches ride the triggered notification's mosaic (D705).
21472
+ */
21473
+ notifyDuringEntryDelay: boolean().optional(),
21474
+ /**
21475
+ * D706: notify "watched again" when a sensor this arm bypassed closes and opens again.
21476
+ * Absent = false (logged, not sent). Even when true it is not sent when that same sensor
21477
+ * is the one that starts the entry delay — the entry-delay notification already names it.
21478
+ */
21479
+ notifySensorRewatched: boolean().optional()
21465
21480
  })).max(8).refine(uniqueModes, { message: "modeDelays: at most one entry per arm mode" });
21466
21481
  var NcAlarmModeDelaysEditListSchema = array(object({
21467
21482
  mode: AlarmArmModeSchema,
@@ -21470,7 +21485,11 @@ var NcAlarmModeDelaysEditListSchema = array(object({
21470
21485
  triggeredDurationSec: NcAlarmTriggeredSecSchema.nullable().optional(),
21471
21486
  postTriggeredAction: NcAlarmPostTriggeredActionSchema.nullable().optional(),
21472
21487
  /** Set a schedule, or `null` to clear (mode always allowed again). */
21473
- schedule: NcScheduleSchema.nullable().optional()
21488
+ schedule: NcScheduleSchema.nullable().optional(),
21489
+ /** D706: set the switch, or `null` to clear it (back to the default, false). */
21490
+ notifyDuringEntryDelay: boolean().nullable().optional(),
21491
+ /** D706: set the switch, or `null` to clear it (back to the default, false). */
21492
+ notifySensorRewatched: boolean().nullable().optional()
21474
21493
  })).max(8).refine(uniqueModes, { message: "modeDelays: at most one edit per arm mode" });
21475
21494
  /** One switch of the alarm table: put ONE device on, or take it off, ONE mode's list. */
21476
21495
  var NcAlarmNonBlockingEditSchema = object({
@@ -22431,39 +22450,19 @@ Object.freeze(Object.fromEntries([{
22431
22450
  label: "Face recognition model",
22432
22451
  defaultModelId: "auraface-r100",
22433
22452
  indexName: "the enrolled face gallery",
22434
- options: [
22435
- {
22436
- id: "auraface-r100",
22437
- label: "AuraFace R100"
22438
- },
22439
- {
22440
- id: "arcface-r100",
22441
- label: "ArcFace (ResNet34)"
22442
- },
22443
- {
22444
- id: "inception-resnet-v1",
22445
- label: "Inception ResNet V1"
22446
- }
22447
- ]
22453
+ options: [{
22454
+ id: "auraface-r100",
22455
+ label: "AuraFace R100"
22456
+ }]
22448
22457
  }, {
22449
22458
  stepId: "clip-embedding",
22450
22459
  label: "Semantic search model",
22451
- defaultModelId: "mobileclip-s1",
22460
+ defaultModelId: "siglip2-b16-224",
22452
22461
  indexName: "the object semantic-search index",
22453
- options: [
22454
- {
22455
- id: "mobileclip-s1",
22456
- label: "MobileCLIP S1"
22457
- },
22458
- {
22459
- id: "mobileclip-s2",
22460
- label: "MobileCLIP S2"
22461
- },
22462
- {
22463
- id: "siglip2-b16-224",
22464
- label: "SigLIP2 B/16 (Apache-2.0)"
22465
- }
22466
- ]
22462
+ options: [{
22463
+ id: "siglip2-b16-224",
22464
+ label: "SigLIP2 B/16 (Apache-2.0)"
22465
+ }]
22467
22466
  }].map((s) => [s.stepId, s.defaultModelId])));
22468
22467
  var CLUSTER_STEP_SETTING_FIELDS = [{
22469
22468
  stepId: "face-embedding",
@@ -25351,6 +25350,22 @@ var MotionSourceEnum = _enum([
25351
25350
  "device-activity"
25352
25351
  ]);
25353
25352
  /**
25353
+ * What opened an on-motion detection SESSION: the motion source that passed the
25354
+ * camera's `motionSources` gate, and what raised it (the camera itself, or a
25355
+ * sensor the operator attached — D672). `sensorName` is the attached sensor's
25356
+ * device name as the orchestrator's camera-sensors resolution last read it;
25357
+ * absent when unknown or when the camera itself triggered.
25358
+ *
25359
+ * Carried on the session attach ONLY so the runner's `DetectionPhaseTransition`
25360
+ * can say what started the session (D672 rule 11, amended 2026-10-06). The
25361
+ * runner never decides anything on it.
25362
+ */
25363
+ var SessionTriggerSchema = object({
25364
+ source: MotionSourceEnum,
25365
+ triggeredBy: MotionTriggeredBySchema,
25366
+ sensorName: string().optional()
25367
+ });
25368
+ /**
25354
25369
  * List of motion sources active on a camera. Empty array is valid:
25355
25370
  * "no source" — happens for battery cams without firmware motion when
25356
25371
  * the operator hasn't opted into the SW analyzer (would hold the
@@ -25602,6 +25617,14 @@ var RunnerCameraConfigSchema = object({
25602
25617
  */
25603
25618
  motionSources: MotionSourcesSchema.default(["analyzer"]),
25604
25619
  /**
25620
+ * What opened this attach, on a SESSION attach only (see
25621
+ * {@link SessionTriggerSchema}). OPTIONAL with no default: absent on a
25622
+ * standing attach, an occupancy burst, a re-dispatch with no motion event
25623
+ * behind it, and every attach from an orchestrator older than the field — the
25624
+ * runner then names no source on the phase event.
25625
+ */
25626
+ sessionTrigger: SessionTriggerSchema.optional(),
25627
+ /**
25605
25628
  * WHICH root detector runs for this camera. The detection counterpart of
25606
25629
  * {@link motionSources}, same shape and same discipline: a per-camera list
25607
25630
  * of sources the system understands, vendor-agnostic, owned here.
@@ -32990,7 +33013,7 @@ var LocalInterfaceSchema = object({
32990
33013
  name: string(),
32991
33014
  family: _enum(["IPv4", "IPv6"]),
32992
33015
  address: string(),
32993
- /** CIDR shorthand (e.g. `192.168.x.x/24`). Empty when OS doesn't expose. */
33016
+ /** CIDR shorthand (e.g. `192.168.10.10/24`). Empty when OS doesn't expose. */
32994
33017
  cidr: string(),
32995
33018
  /** OS netmask. Stable across calls so the SDK can hash on it. */
32996
33019
  netmask: string(),
@@ -33044,7 +33067,8 @@ var ConnectionEndpointSchema = object({
33044
33067
  "lan-ipv4",
33045
33068
  "lan-ipv6",
33046
33069
  "public",
33047
- "loopback"
33070
+ "loopback",
33071
+ "app-link"
33048
33072
  ]),
33049
33073
  /**
33050
33074
  * Originating-interface kind — `lan`/`wifi`/`docker`/`vpn`/`other`/
@@ -33113,15 +33137,27 @@ var GetConnectionEndpointsResultSchema = object({
33113
33137
  localPort: AdvertisedLocalPortSchema
33114
33138
  });
33115
33139
  /**
33116
- * The chosen outbound endpoint for notification artifacts. `baseUrl: null` =
33117
- * AUTO (resolved from the candidate ranking at send time); `resolved` reports
33118
- * what AUTO currently picks, so the UI can show the effective value either way.
33140
+ * The address flagged for notification links. `baseUrl: null` = AUTO, which
33141
+ * since D709 is the CamStack app link; `resolved` reports the effective value,
33142
+ * so the UI can show it either way.
33119
33143
  */
33120
33144
  var NotificationEndpointSchema = object({
33121
33145
  /** The operator's explicit choice, or null for AUTO. */
33122
33146
  baseUrl: string().nullable(),
33123
- /** What the ranking currently resolves to (null when nothing is reachable). */
33124
- resolved: string().nullable()
33147
+ /**
33148
+ * The effective flagged address: the explicit choice, else (AUTO) the
33149
+ * CamStack app link `https://camstack.zentik.app` (D709). A pre-D709 hub
33150
+ * answered the public tunnel / mesh here, or null.
33151
+ */
33152
+ resolved: string().nullable(),
33153
+ /**
33154
+ * The hub origin an app link carries as `hub=` (D709): the hub's best
33155
+ * public HTTPS address — the tunnel, then the mesh (Tailscale MagicDNS) —
33156
+ * picked from this cap's own palette by `pickAppLinkHub`. `null` when the
33157
+ * hub advertises neither; the app link is then minted without `hub=`.
33158
+ * Absent on a pre-D709 hub.
33159
+ */
33160
+ appLinkHub: string().nullable()
33125
33161
  });
33126
33162
  /**
33127
33163
  * The URLs the SDK / viewer should race for API access. `baseUrls` empty =
@@ -33175,7 +33211,11 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
33175
33211
  * Pass `'https'` when the caller is itself loaded over HTTPS
33176
33212
  * to avoid mixed-content blocks in the browser. The public
33177
33213
  * tunnel always emits `https://` regardless. */
33178
- scheme: _enum(["http", "https"]).optional()
33214
+ scheme: _enum(["http", "https"]).optional(),
33215
+ /** Append the CamStack app link entry (`kind: 'app-link'`, D709) —
33216
+ * an address notification links can be flagged with, not a hub
33217
+ * route. Default `false`: racers and rankers never see it. */
33218
+ includeAppLink: boolean().optional()
33179
33219
  }), 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, {
33180
33220
  kind: "mutation",
33181
33221
  auth: "admin"
@@ -33504,7 +33544,7 @@ var MeshPeerSchema = object({
33504
33544
  tags: array(string()).readonly(),
33505
33545
  /** True when the peer advertises itself as an exit-node candidate. */
33506
33546
  exitNodeOption: boolean(),
33507
- /** Subnet routes the peer advertises (e.g. `["192.168.x.x/24"]`). */
33547
+ /** Subnet routes the peer advertises (e.g. `["192.168.10.0/24"]`). */
33508
33548
  advertisedRoutes: array(string()).readonly(),
33509
33549
  /** Owner account login (e.g. `foo@example.com`). Null for tagged peers. */
33510
33550
  userLogin: string().nullable(),
@@ -34832,7 +34872,13 @@ var OsdStatusSchema = object({ overlays: array(object({
34832
34872
  */
34833
34873
  availablePositions: array(OsdPositionEnum).readonly(),
34834
34874
  /** Firmware does not allow editing the `text` field (e.g. timestamp). */
34835
- readOnly: boolean().optional()
34875
+ readOnly: boolean().optional(),
34876
+ /**
34877
+ * Firmware text ceiling for this overlay. Absent = no known limit.
34878
+ * The OSD manager truncates here on every write — never stores its own
34879
+ * copy on the binding.
34880
+ */
34881
+ maxCharacters: number().int().positive().optional()
34836
34882
  })).readonly() });
34837
34883
  var OsdOverlayPatchSchema = object({
34838
34884
  enabled: boolean().optional(),
@@ -34883,7 +34929,9 @@ var OsdTemplateBindingSchema = object({
34883
34929
  valuePath: string().min(1).max(64),
34884
34930
  /** Convert TO this unit at render (`tryConvertUnit`). Absent = source unit. */
34885
34931
  displayUnit: string().max(16).optional(),
34886
- maxDecimals: number().int().min(0).max(4).default(1)
34932
+ maxDecimals: number().int().min(0).max(4).default(1),
34933
+ /** Raw value → display text (same shape as slot binding). Empty string hides. */
34934
+ valueMap: record(string(), string()).optional()
34887
34935
  });
34888
34936
  /**
34889
34937
  * A named template: bindings (alias → leaf field) + a parser that
@@ -34933,18 +34981,11 @@ var OsdSlotBindingSchema = object({
34933
34981
  source: OsdSourceSchema,
34934
34982
  /** `${value}` and `${unit}` are substituted; every occurrence. */
34935
34983
  template: string().max(96).default("${value}"),
34936
- /** Truncate with an ellipsis past this length. Absent = no limit. */
34937
- maxCharacters: number().int().min(4).max(64).optional(),
34938
34984
  /**
34939
34985
  * Decimal places for a numeric value. `0` yields an integer — the
34940
34986
  * documented workaround for firmwares that reject `.` in overlay text.
34941
34987
  */
34942
34988
  maxDecimals: number().int().min(0).max(4).default(1),
34943
- /**
34944
- * Appended via `${unit}` when no unit conversion produces a label.
34945
- * Prefer `source.displayUnit` for converted device-state values.
34946
- */
34947
- unitLabel: string().max(8).optional(),
34948
34989
  /** Raw value → display text, e.g. `{"true":"MOTION","false":""}`. */
34949
34990
  valueMap: record(string(), string()).optional(),
34950
34991
  /** Time windows in which the slot is shown. Absent = always. */
@@ -34953,9 +34994,7 @@ var OsdSlotBindingSchema = object({
34953
34994
  * Display gate, in the notification centre's condition vocabulary.
34954
34995
  * Only the keys reported by `getConditionSupport` are accepted.
34955
34996
  */
34956
- conditions: NcConditionsSchema.optional(),
34957
- /** Rendered when the gate is closed or the value unreadable. Empty = hide. */
34958
- fallbackText: string().max(64).default("")
34997
+ conditions: NcConditionsSchema.optional()
34959
34998
  });
34960
34999
  /** One camera slot, as the operator sees it: firmware truth + our binding. */
34961
35000
  var OsdSlotViewSchema = object({
@@ -53188,12 +53227,14 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
53188
53227
  {
53189
53228
  id: "addons",
53190
53229
  family: "system",
53191
- label: "Addons",
53192
- kinds: [
53193
- "addon-crash-loop",
53194
- "addon-update-available",
53195
- "addon-updated"
53196
- ]
53230
+ label: "Addons stopped",
53231
+ kinds: ["addon-crash-loop"]
53232
+ },
53233
+ {
53234
+ id: "addon-updates",
53235
+ family: "system",
53236
+ label: "Addon updates",
53237
+ kinds: ["addon-update-available", "addon-updated"]
53197
53238
  },
53198
53239
  {
53199
53240
  id: "updates",
@@ -53353,13 +53394,15 @@ var STATE_SUMMARY_SECTION_VARS = [
53353
53394
  },
53354
53395
  {
53355
53396
  name: "summaryAddons",
53356
- label: "Summary: addons",
53357
- example: "@camstack/addon-recorder 1.2.3 → 1.2.4",
53358
- kinds: [
53359
- "addon-crash-loop",
53360
- "addon-update-available",
53361
- "addon-updated"
53362
- ]
53397
+ label: "Summary: addons stopped",
53398
+ example: "hub — recorder stopped after repeated crashes",
53399
+ kinds: ["addon-crash-loop"]
53400
+ },
53401
+ {
53402
+ name: "summaryAddonUpdates",
53403
+ label: "Summary: addon updates",
53404
+ example: "hub:\n• @camstack/addon-recorder 1.2.3 → 1.2.4",
53405
+ kinds: ["addon-update-available", "addon-updated"]
53363
53406
  },
53364
53407
  {
53365
53408
  name: "summaryUpdates",
@@ -53443,6 +53486,7 @@ var STATE_SUMMARY_VARS = [
53443
53486
  [...RULE_BODY_ONLY],
53444
53487
  [...RULE_TEXT],
53445
53488
  ([...RULE_TEXT], [...DEVICE_EVENTS]),
53489
+ ([...RULE_TEXT], [...COMBINED_ALARM]),
53446
53490
  ([...RULE_TEXT], [...DEVICE_EVENTS]),
53447
53491
  ([...RULE_TEXT], [...BATTERY, ...CONSUMABLE]),
53448
53492
  ([...RULE_TEXT], [...CONSUMABLE]),
@@ -53483,6 +53527,8 @@ var STATE_SUMMARY_VARS = [
53483
53527
  [...RULE_TEXT],
53484
53528
  [...RULE_TEXT],
53485
53529
  [...RULE_TEXT],
53530
+ [...RULE_TEXT],
53531
+ [...RULE_TEXT],
53486
53532
  ...STATE_SUMMARY_VARS
53487
53533
  ];
53488
53534
  new Set([
@@ -54095,7 +54141,7 @@ function buildConnectionFormSchema() {
54095
54141
  key: "host",
54096
54142
  label: "Hub host / IP",
54097
54143
  required: true,
54098
- placeholder: "192.168.x.x"
54144
+ placeholder: "192.168.10.50"
54099
54145
  },
54100
54146
  {
54101
54147
  type: "password",
package/dist/addon.mjs CHANGED
@@ -11518,11 +11518,11 @@ var ModelVariantGroupSchema = object({
11518
11518
  /** Quantization axis. Omit ⇒ the fp32 base build. */
11519
11519
  precision: _enum(["fp32", "int8"]).optional(),
11520
11520
  /**
11521
- * Speed-optimization axis. Omit ⇒ the standard build. `fast` marks a
11522
- * latency-optimized export (e.g. ReLU-activation variant) — the slot the
11523
- * future performance variants plug into.
11521
+ * Training / latency-variant axis. Omit ⇒ the standard build. `test` marks
11522
+ * an alternate training of the same family (Scrypted `relu_test`); chip
11523
+ * label is "Test".
11524
11524
  */
11525
- optimization: _enum(["standard", "fast"]).optional(),
11525
+ optimization: _enum(["standard", "test"]).optional(),
11526
11526
  /**
11527
11527
  * Input-resolution axis (square input side, px). Omit ⇒ the family's native
11528
11528
  * resolution (640 for yolo26). Reduced-input builds (320 / 256) are a big,
@@ -11545,9 +11545,10 @@ var ModelProviderIdSchema = _enum([
11545
11545
  * are per upstream. A persisted custom-model row written when this field was a
11546
11546
  * string still parses — the string is lifted into `{ weights }`.
11547
11547
  *
11548
- * Every licence surface (the admin "Models and licenses" page,
11549
- * `THIRD_PARTY_MODELS.md`, the Hugging Face model table) is GENERATED from
11550
- * these records by `scripts/gen-model-licenses.ts` (D661).
11548
+ * Every machine licence surface (`THIRD_PARTY_MODELS.md`, the Hugging Face
11549
+ * model table) is GENERATED from these records by
11550
+ * `scripts/gen-model-licenses.ts` (D661). Operator-facing docs live in
11551
+ * `camstack/docs` → `/docs/detection/models`.
11551
11552
  */
11552
11553
  var ModelLicenseSchema = preprocess((value) => typeof value === "string" ? { weights: value } : value, object({
11553
11554
  /** SPDX id of the WEIGHTS' terms, a `LicenseRef-*` for non-SPDX terms, or `UNKNOWN`. */
@@ -15178,7 +15179,7 @@ DeviceType.Camera;
15178
15179
  * This matters here more than anywhere else in the repo, because every provider
15179
15180
  * that knows a device's host knows its PASSWORD too: `{ host, port, username,
15180
15181
  * password }` sit in one object on Hikvision, Amcrest, Reolink and ONVIF alike,
15181
- * and `http://admin:hunter2@192.168.x.x/` is a URL a browser accepts. The
15182
+ * and `http://admin:hunter2@192.168.60.139/` is a URL a browser accepts. The
15182
15183
  * camera's own page will ask for its own login. That is correct, and pre-
15183
15184
  * filling it is the operator's business, not ours.
15184
15185
  *
@@ -18463,7 +18464,7 @@ method(object({
18463
18464
  timeoutMs: 6e5
18464
18465
  });
18465
18466
  method(object({
18466
- nodeId: string(),
18467
+ targetNodeId: string(),
18467
18468
  modelId: string(),
18468
18469
  format: _enum(MODEL_FORMATS),
18469
18470
  entry: ModelCatalogEntrySchema
@@ -20967,8 +20968,9 @@ var NcRuleSchema = NcRuleInputSchema.extend({
20967
20968
  disabledTargetIds: array(string()).default([])
20968
20969
  });
20969
20970
  /**
20970
- * The state-summary SECTIONS (D647 / D698): the D637 kind groups that report a
20971
- * still-true state. `backups-exports` and `alarm` are not sections — a completed
20971
+ * The state-summary SECTIONS (D647 / D698 / D708): the D637 kind groups that
20972
+ * report a still-true state. `addons` is the crash-looped addons only and
20973
+ * `addon-updates` the addons that are behind (D708 split them). `backups-exports` and `alarm` are not sections — a completed
20972
20974
  * job is not an open state, and the alarm stays instant.
20973
20975
  */
20974
20976
  var NcStateSummarySectionIdSchema = _enum([
@@ -20980,6 +20982,7 @@ var NcStateSummarySectionIdSchema = _enum([
20980
20982
  "detection-blind",
20981
20983
  "nodes",
20982
20984
  "addons",
20985
+ "addon-updates",
20983
20986
  "updates"
20984
20987
  ]);
20985
20988
  /** One section of a previewed state summary. `unavailable` = its state could not be read. */
@@ -21460,7 +21463,19 @@ var NcAlarmModeDelaysListSchema = array(object({
21460
21463
  * When this mode may be armed. Absent / null = always allowed (same as a
21461
21464
  * rule with no `schedule`). Evaluated with {@link isScheduleActive}.
21462
21465
  */
21463
- schedule: NcScheduleSchema.optional()
21466
+ schedule: NcScheduleSchema.optional(),
21467
+ /**
21468
+ * D706: while this mode's ENTRY DELAY runs, do the alarm rules' own pushes go out (as an
21469
+ * intrusion naming the locations)? Absent = false — the entry-delay notification is the
21470
+ * only one, and the matches ride the triggered notification's mosaic (D705).
21471
+ */
21472
+ notifyDuringEntryDelay: boolean().optional(),
21473
+ /**
21474
+ * D706: notify "watched again" when a sensor this arm bypassed closes and opens again.
21475
+ * Absent = false (logged, not sent). Even when true it is not sent when that same sensor
21476
+ * is the one that starts the entry delay — the entry-delay notification already names it.
21477
+ */
21478
+ notifySensorRewatched: boolean().optional()
21464
21479
  })).max(8).refine(uniqueModes, { message: "modeDelays: at most one entry per arm mode" });
21465
21480
  var NcAlarmModeDelaysEditListSchema = array(object({
21466
21481
  mode: AlarmArmModeSchema,
@@ -21469,7 +21484,11 @@ var NcAlarmModeDelaysEditListSchema = array(object({
21469
21484
  triggeredDurationSec: NcAlarmTriggeredSecSchema.nullable().optional(),
21470
21485
  postTriggeredAction: NcAlarmPostTriggeredActionSchema.nullable().optional(),
21471
21486
  /** Set a schedule, or `null` to clear (mode always allowed again). */
21472
- schedule: NcScheduleSchema.nullable().optional()
21487
+ schedule: NcScheduleSchema.nullable().optional(),
21488
+ /** D706: set the switch, or `null` to clear it (back to the default, false). */
21489
+ notifyDuringEntryDelay: boolean().nullable().optional(),
21490
+ /** D706: set the switch, or `null` to clear it (back to the default, false). */
21491
+ notifySensorRewatched: boolean().nullable().optional()
21473
21492
  })).max(8).refine(uniqueModes, { message: "modeDelays: at most one edit per arm mode" });
21474
21493
  /** One switch of the alarm table: put ONE device on, or take it off, ONE mode's list. */
21475
21494
  var NcAlarmNonBlockingEditSchema = object({
@@ -22430,39 +22449,19 @@ Object.freeze(Object.fromEntries([{
22430
22449
  label: "Face recognition model",
22431
22450
  defaultModelId: "auraface-r100",
22432
22451
  indexName: "the enrolled face gallery",
22433
- options: [
22434
- {
22435
- id: "auraface-r100",
22436
- label: "AuraFace R100"
22437
- },
22438
- {
22439
- id: "arcface-r100",
22440
- label: "ArcFace (ResNet34)"
22441
- },
22442
- {
22443
- id: "inception-resnet-v1",
22444
- label: "Inception ResNet V1"
22445
- }
22446
- ]
22452
+ options: [{
22453
+ id: "auraface-r100",
22454
+ label: "AuraFace R100"
22455
+ }]
22447
22456
  }, {
22448
22457
  stepId: "clip-embedding",
22449
22458
  label: "Semantic search model",
22450
- defaultModelId: "mobileclip-s1",
22459
+ defaultModelId: "siglip2-b16-224",
22451
22460
  indexName: "the object semantic-search index",
22452
- options: [
22453
- {
22454
- id: "mobileclip-s1",
22455
- label: "MobileCLIP S1"
22456
- },
22457
- {
22458
- id: "mobileclip-s2",
22459
- label: "MobileCLIP S2"
22460
- },
22461
- {
22462
- id: "siglip2-b16-224",
22463
- label: "SigLIP2 B/16 (Apache-2.0)"
22464
- }
22465
- ]
22461
+ options: [{
22462
+ id: "siglip2-b16-224",
22463
+ label: "SigLIP2 B/16 (Apache-2.0)"
22464
+ }]
22466
22465
  }].map((s) => [s.stepId, s.defaultModelId])));
22467
22466
  var CLUSTER_STEP_SETTING_FIELDS = [{
22468
22467
  stepId: "face-embedding",
@@ -25350,6 +25349,22 @@ var MotionSourceEnum = _enum([
25350
25349
  "device-activity"
25351
25350
  ]);
25352
25351
  /**
25352
+ * What opened an on-motion detection SESSION: the motion source that passed the
25353
+ * camera's `motionSources` gate, and what raised it (the camera itself, or a
25354
+ * sensor the operator attached — D672). `sensorName` is the attached sensor's
25355
+ * device name as the orchestrator's camera-sensors resolution last read it;
25356
+ * absent when unknown or when the camera itself triggered.
25357
+ *
25358
+ * Carried on the session attach ONLY so the runner's `DetectionPhaseTransition`
25359
+ * can say what started the session (D672 rule 11, amended 2026-10-06). The
25360
+ * runner never decides anything on it.
25361
+ */
25362
+ var SessionTriggerSchema = object({
25363
+ source: MotionSourceEnum,
25364
+ triggeredBy: MotionTriggeredBySchema,
25365
+ sensorName: string().optional()
25366
+ });
25367
+ /**
25353
25368
  * List of motion sources active on a camera. Empty array is valid:
25354
25369
  * "no source" — happens for battery cams without firmware motion when
25355
25370
  * the operator hasn't opted into the SW analyzer (would hold the
@@ -25601,6 +25616,14 @@ var RunnerCameraConfigSchema = object({
25601
25616
  */
25602
25617
  motionSources: MotionSourcesSchema.default(["analyzer"]),
25603
25618
  /**
25619
+ * What opened this attach, on a SESSION attach only (see
25620
+ * {@link SessionTriggerSchema}). OPTIONAL with no default: absent on a
25621
+ * standing attach, an occupancy burst, a re-dispatch with no motion event
25622
+ * behind it, and every attach from an orchestrator older than the field — the
25623
+ * runner then names no source on the phase event.
25624
+ */
25625
+ sessionTrigger: SessionTriggerSchema.optional(),
25626
+ /**
25604
25627
  * WHICH root detector runs for this camera. The detection counterpart of
25605
25628
  * {@link motionSources}, same shape and same discipline: a per-camera list
25606
25629
  * of sources the system understands, vendor-agnostic, owned here.
@@ -32989,7 +33012,7 @@ var LocalInterfaceSchema = object({
32989
33012
  name: string(),
32990
33013
  family: _enum(["IPv4", "IPv6"]),
32991
33014
  address: string(),
32992
- /** CIDR shorthand (e.g. `192.168.x.x/24`). Empty when OS doesn't expose. */
33015
+ /** CIDR shorthand (e.g. `192.168.10.10/24`). Empty when OS doesn't expose. */
32993
33016
  cidr: string(),
32994
33017
  /** OS netmask. Stable across calls so the SDK can hash on it. */
32995
33018
  netmask: string(),
@@ -33043,7 +33066,8 @@ var ConnectionEndpointSchema = object({
33043
33066
  "lan-ipv4",
33044
33067
  "lan-ipv6",
33045
33068
  "public",
33046
- "loopback"
33069
+ "loopback",
33070
+ "app-link"
33047
33071
  ]),
33048
33072
  /**
33049
33073
  * Originating-interface kind — `lan`/`wifi`/`docker`/`vpn`/`other`/
@@ -33112,15 +33136,27 @@ var GetConnectionEndpointsResultSchema = object({
33112
33136
  localPort: AdvertisedLocalPortSchema
33113
33137
  });
33114
33138
  /**
33115
- * The chosen outbound endpoint for notification artifacts. `baseUrl: null` =
33116
- * AUTO (resolved from the candidate ranking at send time); `resolved` reports
33117
- * what AUTO currently picks, so the UI can show the effective value either way.
33139
+ * The address flagged for notification links. `baseUrl: null` = AUTO, which
33140
+ * since D709 is the CamStack app link; `resolved` reports the effective value,
33141
+ * so the UI can show it either way.
33118
33142
  */
33119
33143
  var NotificationEndpointSchema = object({
33120
33144
  /** The operator's explicit choice, or null for AUTO. */
33121
33145
  baseUrl: string().nullable(),
33122
- /** What the ranking currently resolves to (null when nothing is reachable). */
33123
- resolved: string().nullable()
33146
+ /**
33147
+ * The effective flagged address: the explicit choice, else (AUTO) the
33148
+ * CamStack app link `https://camstack.zentik.app` (D709). A pre-D709 hub
33149
+ * answered the public tunnel / mesh here, or null.
33150
+ */
33151
+ resolved: string().nullable(),
33152
+ /**
33153
+ * The hub origin an app link carries as `hub=` (D709): the hub's best
33154
+ * public HTTPS address — the tunnel, then the mesh (Tailscale MagicDNS) —
33155
+ * picked from this cap's own palette by `pickAppLinkHub`. `null` when the
33156
+ * hub advertises neither; the app link is then minted without `hub=`.
33157
+ * Absent on a pre-D709 hub.
33158
+ */
33159
+ appLinkHub: string().nullable()
33124
33160
  });
33125
33161
  /**
33126
33162
  * The URLs the SDK / viewer should race for API access. `baseUrls` empty =
@@ -33174,7 +33210,11 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
33174
33210
  * Pass `'https'` when the caller is itself loaded over HTTPS
33175
33211
  * to avoid mixed-content blocks in the browser. The public
33176
33212
  * tunnel always emits `https://` regardless. */
33177
- scheme: _enum(["http", "https"]).optional()
33213
+ scheme: _enum(["http", "https"]).optional(),
33214
+ /** Append the CamStack app link entry (`kind: 'app-link'`, D709) —
33215
+ * an address notification links can be flagged with, not a hub
33216
+ * route. Default `false`: racers and rankers never see it. */
33217
+ includeAppLink: boolean().optional()
33178
33218
  }), 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, {
33179
33219
  kind: "mutation",
33180
33220
  auth: "admin"
@@ -33503,7 +33543,7 @@ var MeshPeerSchema = object({
33503
33543
  tags: array(string()).readonly(),
33504
33544
  /** True when the peer advertises itself as an exit-node candidate. */
33505
33545
  exitNodeOption: boolean(),
33506
- /** Subnet routes the peer advertises (e.g. `["192.168.x.x/24"]`). */
33546
+ /** Subnet routes the peer advertises (e.g. `["192.168.10.0/24"]`). */
33507
33547
  advertisedRoutes: array(string()).readonly(),
33508
33548
  /** Owner account login (e.g. `foo@example.com`). Null for tagged peers. */
33509
33549
  userLogin: string().nullable(),
@@ -34831,7 +34871,13 @@ var OsdStatusSchema = object({ overlays: array(object({
34831
34871
  */
34832
34872
  availablePositions: array(OsdPositionEnum).readonly(),
34833
34873
  /** Firmware does not allow editing the `text` field (e.g. timestamp). */
34834
- readOnly: boolean().optional()
34874
+ readOnly: boolean().optional(),
34875
+ /**
34876
+ * Firmware text ceiling for this overlay. Absent = no known limit.
34877
+ * The OSD manager truncates here on every write — never stores its own
34878
+ * copy on the binding.
34879
+ */
34880
+ maxCharacters: number().int().positive().optional()
34835
34881
  })).readonly() });
34836
34882
  var OsdOverlayPatchSchema = object({
34837
34883
  enabled: boolean().optional(),
@@ -34882,7 +34928,9 @@ var OsdTemplateBindingSchema = object({
34882
34928
  valuePath: string().min(1).max(64),
34883
34929
  /** Convert TO this unit at render (`tryConvertUnit`). Absent = source unit. */
34884
34930
  displayUnit: string().max(16).optional(),
34885
- maxDecimals: number().int().min(0).max(4).default(1)
34931
+ maxDecimals: number().int().min(0).max(4).default(1),
34932
+ /** Raw value → display text (same shape as slot binding). Empty string hides. */
34933
+ valueMap: record(string(), string()).optional()
34886
34934
  });
34887
34935
  /**
34888
34936
  * A named template: bindings (alias → leaf field) + a parser that
@@ -34932,18 +34980,11 @@ var OsdSlotBindingSchema = object({
34932
34980
  source: OsdSourceSchema,
34933
34981
  /** `${value}` and `${unit}` are substituted; every occurrence. */
34934
34982
  template: string().max(96).default("${value}"),
34935
- /** Truncate with an ellipsis past this length. Absent = no limit. */
34936
- maxCharacters: number().int().min(4).max(64).optional(),
34937
34983
  /**
34938
34984
  * Decimal places for a numeric value. `0` yields an integer — the
34939
34985
  * documented workaround for firmwares that reject `.` in overlay text.
34940
34986
  */
34941
34987
  maxDecimals: number().int().min(0).max(4).default(1),
34942
- /**
34943
- * Appended via `${unit}` when no unit conversion produces a label.
34944
- * Prefer `source.displayUnit` for converted device-state values.
34945
- */
34946
- unitLabel: string().max(8).optional(),
34947
34988
  /** Raw value → display text, e.g. `{"true":"MOTION","false":""}`. */
34948
34989
  valueMap: record(string(), string()).optional(),
34949
34990
  /** Time windows in which the slot is shown. Absent = always. */
@@ -34952,9 +34993,7 @@ var OsdSlotBindingSchema = object({
34952
34993
  * Display gate, in the notification centre's condition vocabulary.
34953
34994
  * Only the keys reported by `getConditionSupport` are accepted.
34954
34995
  */
34955
- conditions: NcConditionsSchema.optional(),
34956
- /** Rendered when the gate is closed or the value unreadable. Empty = hide. */
34957
- fallbackText: string().max(64).default("")
34996
+ conditions: NcConditionsSchema.optional()
34958
34997
  });
34959
34998
  /** One camera slot, as the operator sees it: firmware truth + our binding. */
34960
34999
  var OsdSlotViewSchema = object({
@@ -53187,12 +53226,14 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
53187
53226
  {
53188
53227
  id: "addons",
53189
53228
  family: "system",
53190
- label: "Addons",
53191
- kinds: [
53192
- "addon-crash-loop",
53193
- "addon-update-available",
53194
- "addon-updated"
53195
- ]
53229
+ label: "Addons stopped",
53230
+ kinds: ["addon-crash-loop"]
53231
+ },
53232
+ {
53233
+ id: "addon-updates",
53234
+ family: "system",
53235
+ label: "Addon updates",
53236
+ kinds: ["addon-update-available", "addon-updated"]
53196
53237
  },
53197
53238
  {
53198
53239
  id: "updates",
@@ -53352,13 +53393,15 @@ var STATE_SUMMARY_SECTION_VARS = [
53352
53393
  },
53353
53394
  {
53354
53395
  name: "summaryAddons",
53355
- label: "Summary: addons",
53356
- example: "@camstack/addon-recorder 1.2.3 → 1.2.4",
53357
- kinds: [
53358
- "addon-crash-loop",
53359
- "addon-update-available",
53360
- "addon-updated"
53361
- ]
53396
+ label: "Summary: addons stopped",
53397
+ example: "hub — recorder stopped after repeated crashes",
53398
+ kinds: ["addon-crash-loop"]
53399
+ },
53400
+ {
53401
+ name: "summaryAddonUpdates",
53402
+ label: "Summary: addon updates",
53403
+ example: "hub:\n• @camstack/addon-recorder 1.2.3 → 1.2.4",
53404
+ kinds: ["addon-update-available", "addon-updated"]
53362
53405
  },
53363
53406
  {
53364
53407
  name: "summaryUpdates",
@@ -53442,6 +53485,7 @@ var STATE_SUMMARY_VARS = [
53442
53485
  [...RULE_BODY_ONLY],
53443
53486
  [...RULE_TEXT],
53444
53487
  ([...RULE_TEXT], [...DEVICE_EVENTS]),
53488
+ ([...RULE_TEXT], [...COMBINED_ALARM]),
53445
53489
  ([...RULE_TEXT], [...DEVICE_EVENTS]),
53446
53490
  ([...RULE_TEXT], [...BATTERY, ...CONSUMABLE]),
53447
53491
  ([...RULE_TEXT], [...CONSUMABLE]),
@@ -53482,6 +53526,8 @@ var STATE_SUMMARY_VARS = [
53482
53526
  [...RULE_TEXT],
53483
53527
  [...RULE_TEXT],
53484
53528
  [...RULE_TEXT],
53529
+ [...RULE_TEXT],
53530
+ [...RULE_TEXT],
53485
53531
  ...STATE_SUMMARY_VARS
53486
53532
  ];
53487
53533
  new Set([
@@ -54094,7 +54140,7 @@ function buildConnectionFormSchema() {
54094
54140
  key: "host",
54095
54141
  label: "Hub host / IP",
54096
54142
  required: true,
54097
- placeholder: "192.168.x.x"
54143
+ placeholder: "192.168.10.50"
54098
54144
  },
54099
54145
  {
54100
54146
  type: "password",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-rademacher",
3
- "version": "0.2.118",
3
+ "version": "0.2.120",
4
4
  "description": "Rademacher HomePilot device-provider addon for CamStack — wraps the @apocaliss92/noderademacher local-hub client (roller shutters over the cover cap)",
5
5
  "keywords": [
6
6
  "camstack",