@camstack/addon-remote-storage 1.2.117 → 1.2.119

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.
@@ -10452,6 +10452,15 @@ var ClipSearchStrictnessSchema = _enum([
10452
10452
  "balanced",
10453
10453
  "strict"
10454
10454
  ]);
10455
+ /** Steps whose effect a root label can BE. */
10456
+ var LABEL_SUPPLY_STEP_IDS = [
10457
+ "animal-classifier",
10458
+ "vehicle-classifier",
10459
+ "package-detection"
10460
+ ];
10461
+ /** Steps whose box a root detection can BE. */
10462
+ var CROP_SUPPLY_STEP_IDS = ["plate-detection", "face-detection"];
10463
+ [...LABEL_SUPPLY_STEP_IDS, ...CROP_SUPPLY_STEP_IDS];
10455
10464
  var MODEL_FORMATS = [
10456
10465
  "onnx",
10457
10466
  "coreml",
@@ -10521,11 +10530,11 @@ var ModelVariantGroupSchema = object({
10521
10530
  /** Quantization axis. Omit ⇒ the fp32 base build. */
10522
10531
  precision: _enum(["fp32", "int8"]).optional(),
10523
10532
  /**
10524
- * Speed-optimization axis. Omit ⇒ the standard build. `fast` marks a
10525
- * latency-optimized export (e.g. ReLU-activation variant) — the slot the
10526
- * future performance variants plug into.
10533
+ * Training / latency-variant axis. Omit ⇒ the standard build. `test` marks
10534
+ * an alternate training of the same family (Scrypted `relu_test`); chip
10535
+ * label is "Test".
10527
10536
  */
10528
- optimization: _enum(["standard", "fast"]).optional(),
10537
+ optimization: _enum(["standard", "test"]).optional(),
10529
10538
  /**
10530
10539
  * Input-resolution axis (square input side, px). Omit ⇒ the family's native
10531
10540
  * resolution (640 for yolo26). Reduced-input builds (320 / 256) are a big,
@@ -10548,9 +10557,10 @@ var ModelProviderIdSchema = _enum([
10548
10557
  * are per upstream. A persisted custom-model row written when this field was a
10549
10558
  * string still parses — the string is lifted into `{ weights }`.
10550
10559
  *
10551
- * Every licence surface (the admin "Models and licenses" page,
10552
- * `THIRD_PARTY_MODELS.md`, the Hugging Face model table) is GENERATED from
10553
- * these records by `scripts/gen-model-licenses.ts` (D661).
10560
+ * Every machine licence surface (`THIRD_PARTY_MODELS.md`, the Hugging Face
10561
+ * model table) is GENERATED from these records by
10562
+ * `scripts/gen-model-licenses.ts` (D661). Operator-facing docs live in
10563
+ * `camstack/docs` → `/docs/detection/models`.
10554
10564
  */
10555
10565
  var ModelLicenseSchema = preprocess((value) => typeof value === "string" ? { weights: value } : value, object({
10556
10566
  /** SPDX id of the WEIGHTS' terms, a `LicenseRef-*` for non-SPDX terms, or `UNKNOWN`. */
@@ -10583,6 +10593,35 @@ var ModelLicenseSchema = preprocess((value) => typeof value === "string" ? { wei
10583
10593
  /** True when the weights or their data forbid commercial use. */
10584
10594
  nonCommercial: boolean().optional()
10585
10595
  }));
10596
+ /**
10597
+ * One step a ROOT detector can supply from its own output (D730) — see
10598
+ * `ModelCatalogEntry.suppliesSteps`.
10599
+ *
10600
+ * - `label`: the root's raw class IS the step's answer. `labelToEffect` maps
10601
+ * the root's label to the step's vocabulary; `uncovered` is the vocabulary
10602
+ * the root cannot produce (shown as unavailable, never a blocker).
10603
+ * - `crop`: the root draws the box the step would have found (`license_plate`
10604
+ * for plate-detection, `face` for face-detection). The box becomes a detail
10605
+ * child of the `parentMacro` detection that contains it — never a track.
10606
+ */
10607
+ var RootStepSupplySchema = discriminatedUnion("kind", [object({
10608
+ kind: literal("label"),
10609
+ stepId: _enum(LABEL_SUPPLY_STEP_IDS),
10610
+ labelToEffect: record(string(), string()),
10611
+ uncovered: array(string()).readonly()
10612
+ }), object({
10613
+ kind: literal("crop"),
10614
+ stepId: _enum(CROP_SUPPLY_STEP_IDS),
10615
+ rootLabels: array(string()).readonly(),
10616
+ parentMacro: _enum(["vehicle", "person"]),
10617
+ childClass: _enum(["plate", "face"]),
10618
+ /**
10619
+ * The root's smaller input side, stamped on read by `rootSuppliesOf` from
10620
+ * the model entry — what a step's `minRootInputPx` gate judges. Never
10621
+ * stored by an import.
10622
+ */
10623
+ rootInputPx: number().int().positive().optional()
10624
+ })]);
10586
10625
  var ModelCatalogEntrySchema = object({
10587
10626
  id: string(),
10588
10627
  name: string(),
@@ -10709,6 +10748,16 @@ var ModelCatalogEntrySchema = object({
10709
10748
  */
10710
10749
  classMap: DetectionCatalogClassMapSchema.optional(),
10711
10750
  /**
10751
+ * The pipeline steps this ROOT detector can supply from its own output
10752
+ * (D730): its labels name a step's effect (`deer` for `animal-classifier`)
10753
+ * or draw a step's box (`license_plate` for `plate-detection`). Computed at
10754
+ * import from THIS model's labelmap by `deriveRootSupplies`, never written
10755
+ * by hand and never assumed per family; a row without it is derived on read
10756
+ * (`rootSuppliesOf`). Whether a camera uses it is the step's own
10757
+ * `useRootModel` flag (`resolveRootSupply`).
10758
+ */
10759
+ suppliesSteps: array(RootStepSupplySchema).readonly().optional(),
10760
+ /**
10712
10761
  * The model's CLIP feature-space contract (text encoder, dimension, vector
10713
10762
  * index, token window, search floor) — see `clip-model.ts`. Present ONLY on a
10714
10763
  * CLIP image encoder; its absence is what "not a CLIP model" means to the
@@ -14079,7 +14128,7 @@ DeviceType.Camera;
14079
14128
  * This matters here more than anywhere else in the repo, because every provider
14080
14129
  * that knows a device's host knows its PASSWORD too: `{ host, port, username,
14081
14130
  * password }` sit in one object on Hikvision, Amcrest, Reolink and ONVIF alike,
14082
- * and `http://admin:hunter2@192.168.x.x/` is a URL a browser accepts. The
14131
+ * and `http://admin:hunter2@192.168.60.139/` is a URL a browser accepts. The
14083
14132
  * camera's own page will ask for its own login. That is correct, and pre-
14084
14133
  * filling it is the operator's business, not ours.
14085
14134
  *
@@ -17063,7 +17112,7 @@ method(object({
17063
17112
  timeoutMs: 6e5
17064
17113
  });
17065
17114
  method(object({
17066
- nodeId: string(),
17115
+ targetNodeId: string(),
17067
17116
  modelId: string(),
17068
17117
  format: _enum(MODEL_FORMATS),
17069
17118
  entry: ModelCatalogEntrySchema
@@ -18431,6 +18480,8 @@ var NcSystemEventKindSchema = _enum([
18431
18480
  "stream-offline",
18432
18481
  "node-online",
18433
18482
  "node-offline",
18483
+ "node-restarting",
18484
+ "node-updating",
18434
18485
  "node-inference-unavailable",
18435
18486
  "detection-blind",
18436
18487
  "addon-crash-loop",
@@ -19529,8 +19580,9 @@ var NcRuleSchema = NcRuleInputSchema.extend({
19529
19580
  disabledTargetIds: array(string()).default([])
19530
19581
  });
19531
19582
  /**
19532
- * The state-summary SECTIONS (D647 / D698): the D637 kind groups that report a
19533
- * still-true state. `backups-exports` and `alarm` are not sections — a completed
19583
+ * The state-summary SECTIONS (D647 / D698 / D708): the D637 kind groups that
19584
+ * report a still-true state. `addons` is the crash-looped addons only and
19585
+ * `addon-updates` the addons that are behind (D708 split them). `backups-exports` and `alarm` are not sections — a completed
19534
19586
  * job is not an open state, and the alarm stays instant.
19535
19587
  */
19536
19588
  var NcStateSummarySectionIdSchema = _enum([
@@ -19542,6 +19594,7 @@ var NcStateSummarySectionIdSchema = _enum([
19542
19594
  "detection-blind",
19543
19595
  "nodes",
19544
19596
  "addons",
19597
+ "addon-updates",
19545
19598
  "updates"
19546
19599
  ]);
19547
19600
  /** One section of a previewed state summary. `unavailable` = its state could not be read. */
@@ -20022,7 +20075,19 @@ var NcAlarmModeDelaysListSchema = array(object({
20022
20075
  * When this mode may be armed. Absent / null = always allowed (same as a
20023
20076
  * rule with no `schedule`). Evaluated with {@link isScheduleActive}.
20024
20077
  */
20025
- schedule: NcScheduleSchema.optional()
20078
+ schedule: NcScheduleSchema.optional(),
20079
+ /**
20080
+ * D706: while this mode's ENTRY DELAY runs, do the alarm rules' own pushes go out (as an
20081
+ * intrusion naming the locations)? Absent = false — the entry-delay notification is the
20082
+ * only one, and the matches ride the triggered notification's mosaic (D705).
20083
+ */
20084
+ notifyDuringEntryDelay: boolean().optional(),
20085
+ /**
20086
+ * D706: notify "watched again" when a sensor this arm bypassed closes and opens again.
20087
+ * Absent = false (logged, not sent). Even when true it is not sent when that same sensor
20088
+ * is the one that starts the entry delay — the entry-delay notification already names it.
20089
+ */
20090
+ notifySensorRewatched: boolean().optional()
20026
20091
  })).max(8).refine(uniqueModes, { message: "modeDelays: at most one entry per arm mode" });
20027
20092
  var NcAlarmModeDelaysEditListSchema = array(object({
20028
20093
  mode: AlarmArmModeSchema,
@@ -20031,7 +20096,11 @@ var NcAlarmModeDelaysEditListSchema = array(object({
20031
20096
  triggeredDurationSec: NcAlarmTriggeredSecSchema.nullable().optional(),
20032
20097
  postTriggeredAction: NcAlarmPostTriggeredActionSchema.nullable().optional(),
20033
20098
  /** Set a schedule, or `null` to clear (mode always allowed again). */
20034
- schedule: NcScheduleSchema.nullable().optional()
20099
+ schedule: NcScheduleSchema.nullable().optional(),
20100
+ /** D706: set the switch, or `null` to clear it (back to the default, false). */
20101
+ notifyDuringEntryDelay: boolean().nullable().optional(),
20102
+ /** D706: set the switch, or `null` to clear it (back to the default, false). */
20103
+ notifySensorRewatched: boolean().nullable().optional()
20035
20104
  })).max(8).refine(uniqueModes, { message: "modeDelays: at most one edit per arm mode" });
20036
20105
  /** One switch of the alarm table: put ONE device on, or take it off, ONE mode's list. */
20037
20106
  var NcAlarmNonBlockingEditSchema = object({
@@ -20992,39 +21061,19 @@ Object.freeze(Object.fromEntries([{
20992
21061
  label: "Face recognition model",
20993
21062
  defaultModelId: "auraface-r100",
20994
21063
  indexName: "the enrolled face gallery",
20995
- options: [
20996
- {
20997
- id: "auraface-r100",
20998
- label: "AuraFace R100"
20999
- },
21000
- {
21001
- id: "arcface-r100",
21002
- label: "ArcFace (ResNet34)"
21003
- },
21004
- {
21005
- id: "inception-resnet-v1",
21006
- label: "Inception ResNet V1"
21007
- }
21008
- ]
21064
+ options: [{
21065
+ id: "auraface-r100",
21066
+ label: "AuraFace R100"
21067
+ }]
21009
21068
  }, {
21010
21069
  stepId: "clip-embedding",
21011
21070
  label: "Semantic search model",
21012
- defaultModelId: "mobileclip-s1",
21071
+ defaultModelId: "siglip2-b16-224",
21013
21072
  indexName: "the object semantic-search index",
21014
- options: [
21015
- {
21016
- id: "mobileclip-s1",
21017
- label: "MobileCLIP S1"
21018
- },
21019
- {
21020
- id: "mobileclip-s2",
21021
- label: "MobileCLIP S2"
21022
- },
21023
- {
21024
- id: "siglip2-b16-224",
21025
- label: "SigLIP2 B/16 (Apache-2.0)"
21026
- }
21027
- ]
21073
+ options: [{
21074
+ id: "siglip2-b16-224",
21075
+ label: "SigLIP2 B/16 (Apache-2.0)"
21076
+ }]
21028
21077
  }].map((s) => [s.stepId, s.defaultModelId])));
21029
21078
  var CLUSTER_STEP_SETTING_FIELDS = [{
21030
21079
  stepId: "face-embedding",
@@ -22950,6 +22999,34 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
22950
22999
  timestamp: number()
22951
23000
  });
22952
23001
  /**
23002
+ * A root model's boxes standing in for one crop-kind step's own inference
23003
+ * (D730) — see `runPipeline.suppliedRoot`.
23004
+ */
23005
+ var SuppliedRootOutputSchema = object({
23006
+ stepId: string(),
23007
+ /** The root model that drew the boxes — stamped on the result. */
23008
+ modelId: string(),
23009
+ detections: array(object({
23010
+ /** `[x1, y1, x2, y2]` in the pixels of the call's image. */
23011
+ bbox: tuple([
23012
+ number(),
23013
+ number(),
23014
+ number(),
23015
+ number()
23016
+ ]),
23017
+ score: number(),
23018
+ /**
23019
+ * Five facial landmarks in the same pixels — a face the step's own
23020
+ * detector already re-found inside a root face box (D730), so its
23021
+ * embedder child aligns it exactly as it aligns any detected face.
23022
+ */
23023
+ landmarks: array(object({
23024
+ x: number(),
23025
+ y: number()
23026
+ })).optional()
23027
+ })).min(1)
23028
+ });
23029
+ /**
22953
23030
  * Reference to the frame's retained NATIVE surface + the parent crop's placement
22954
23031
  * within the frame, so the executor can re-cut a leaf child ROI at native
22955
23032
  * resolution on the detail plane. See the `runPipeline` `nativeCropRef` field.
@@ -23079,7 +23156,8 @@ var PipelineModelOptionSchema = object({
23079
23156
  group: ModelVariantGroupSchema.optional(),
23080
23157
  legacy: boolean().optional(),
23081
23158
  provider: ModelProviderIdSchema.optional(),
23082
- defaultConfidence: number().optional()
23159
+ defaultConfidence: number().optional(),
23160
+ suppliesSteps: array(RootStepSupplySchema).readonly().optional()
23083
23161
  });
23084
23162
  var ConfigFieldBridge = custom();
23085
23163
  var PipelineAddonSchemaSchema = object({
@@ -23347,7 +23425,16 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
23347
23425
  * `device-not-servable`), and nothing reaches the camera's live
23348
23426
  * trace stream. Absent ⇒ unchanged behaviour.
23349
23427
  */
23350
- replay: literal(true).optional()
23428
+ replay: literal(true).optional(),
23429
+ /**
23430
+ * Root-supplied detections for the tree's ROOT step (D730). Set by
23431
+ * `runDetailSubtree` when the camera's root model supplies a crop-kind
23432
+ * step (a Frigate+ `license_plate` for `plate-detection`): the step is
23433
+ * NOT inferred, these boxes are its output, and its children (the plate
23434
+ * reader) run on them through their own crop policy. Boxes are in the
23435
+ * PIXELS of the image this call carries. Absent ⇒ the root step runs.
23436
+ */
23437
+ suppliedRoot: SuppliedRootOutputSchema.optional()
23351
23438
  }), PipelineRunResultBridge, { kind: "mutation" }), method(object({
23352
23439
  steps: array(PipelineStepInputSchema).min(1),
23353
23440
  frames: array(FrameInputSchema).min(1).max(255),
@@ -23872,6 +23959,22 @@ var MotionSourceEnum = _enum([
23872
23959
  "device-activity"
23873
23960
  ]);
23874
23961
  /**
23962
+ * What opened an on-motion detection SESSION: the motion source that passed the
23963
+ * camera's `motionSources` gate, and what raised it (the camera itself, or a
23964
+ * sensor the operator attached — D672). `sensorName` is the attached sensor's
23965
+ * device name as the orchestrator's camera-sensors resolution last read it;
23966
+ * absent when unknown or when the camera itself triggered.
23967
+ *
23968
+ * Carried on the session attach ONLY so the runner's `DetectionPhaseTransition`
23969
+ * can say what started the session (D672 rule 11, amended 2026-10-06). The
23970
+ * runner never decides anything on it.
23971
+ */
23972
+ var SessionTriggerSchema = object({
23973
+ source: MotionSourceEnum,
23974
+ triggeredBy: MotionTriggeredBySchema,
23975
+ sensorName: string().optional()
23976
+ });
23977
+ /**
23875
23978
  * List of motion sources active on a camera. Empty array is valid:
23876
23979
  * "no source" — happens for battery cams without firmware motion when
23877
23980
  * the operator hasn't opted into the SW analyzer (would hold the
@@ -24123,6 +24226,14 @@ var RunnerCameraConfigSchema = object({
24123
24226
  */
24124
24227
  motionSources: MotionSourcesSchema.default(["analyzer"]),
24125
24228
  /**
24229
+ * What opened this attach, on a SESSION attach only (see
24230
+ * {@link SessionTriggerSchema}). OPTIONAL with no default: absent on a
24231
+ * standing attach, an occupancy burst, a re-dispatch with no motion event
24232
+ * behind it, and every attach from an orchestrator older than the field — the
24233
+ * runner then names no source on the phase event.
24234
+ */
24235
+ sessionTrigger: SessionTriggerSchema.optional(),
24236
+ /**
24126
24237
  * WHICH root detector runs for this camera. The detection counterpart of
24127
24238
  * {@link motionSources}, same shape and same discipline: a per-camera list
24128
24239
  * of sources the system understands, vendor-agnostic, owned here.
@@ -24425,7 +24536,22 @@ method(RunnerCameraConfigSchema, object({ success: literal(true) }), { kind: "mu
24425
24536
  */
24426
24537
  cropJpeg: string().optional(),
24427
24538
  parent: DetailParentSchema,
24428
- steps: array(string()).optional()
24539
+ steps: array(string()).optional(),
24540
+ /**
24541
+ * The camera's root model already drew this step's boxes (D730): a
24542
+ * `license_plate` inside the parent vehicle. The named step is NOT
24543
+ * inferred — these FRAME-space boxes are its output — and its
24544
+ * requested children (the plate reader) run on them. Absent ⇒ every
24545
+ * requested step infers as before.
24546
+ */
24547
+ supplied: object({
24548
+ stepId: string(),
24549
+ modelId: string(),
24550
+ boxes: array(object({
24551
+ bbox: NativeCropBboxSchema,
24552
+ score: number()
24553
+ })).min(1)
24554
+ }).optional()
24429
24555
  }), object({ details: array(DetailResultSchema) }).nullable(), { kind: "mutation" }), method(object({
24430
24556
  /** Catalog step id, e.g. `clip-embedding`. */
24431
24557
  stepId: string(),
@@ -30406,7 +30532,7 @@ var LocalInterfaceSchema = object({
30406
30532
  name: string(),
30407
30533
  family: _enum(["IPv4", "IPv6"]),
30408
30534
  address: string(),
30409
- /** CIDR shorthand (e.g. `192.168.x.x/24`). Empty when OS doesn't expose. */
30535
+ /** CIDR shorthand (e.g. `192.168.10.10/24`). Empty when OS doesn't expose. */
30410
30536
  cidr: string(),
30411
30537
  /** OS netmask. Stable across calls so the SDK can hash on it. */
30412
30538
  netmask: string(),
@@ -30460,7 +30586,8 @@ var ConnectionEndpointSchema = object({
30460
30586
  "lan-ipv4",
30461
30587
  "lan-ipv6",
30462
30588
  "public",
30463
- "loopback"
30589
+ "loopback",
30590
+ "app-link"
30464
30591
  ]),
30465
30592
  /**
30466
30593
  * Originating-interface kind — `lan`/`wifi`/`docker`/`vpn`/`other`/
@@ -30529,15 +30656,27 @@ var GetConnectionEndpointsResultSchema = object({
30529
30656
  localPort: AdvertisedLocalPortSchema
30530
30657
  });
30531
30658
  /**
30532
- * The chosen outbound endpoint for notification artifacts. `baseUrl: null` =
30533
- * AUTO (resolved from the candidate ranking at send time); `resolved` reports
30534
- * what AUTO currently picks, so the UI can show the effective value either way.
30659
+ * The address flagged for notification links. `baseUrl: null` = AUTO, which
30660
+ * since D709 is the CamStack app link; `resolved` reports the effective value,
30661
+ * so the UI can show it either way.
30535
30662
  */
30536
30663
  var NotificationEndpointSchema = object({
30537
30664
  /** The operator's explicit choice, or null for AUTO. */
30538
30665
  baseUrl: string().nullable(),
30539
- /** What the ranking currently resolves to (null when nothing is reachable). */
30540
- resolved: string().nullable()
30666
+ /**
30667
+ * The effective flagged address: the explicit choice, else (AUTO) the
30668
+ * CamStack app link `https://camstack.zentik.app` (D709). A pre-D709 hub
30669
+ * answered the public tunnel / mesh here, or null.
30670
+ */
30671
+ resolved: string().nullable(),
30672
+ /**
30673
+ * The hub origin an app link carries as `hub=` (D709): the hub's best
30674
+ * public HTTPS address — the tunnel, then the mesh (Tailscale MagicDNS) —
30675
+ * picked from this cap's own palette by `pickAppLinkHub`. `null` when the
30676
+ * hub advertises neither; the app link is then minted without `hub=`.
30677
+ * Absent on a pre-D709 hub.
30678
+ */
30679
+ appLinkHub: string().nullable()
30541
30680
  });
30542
30681
  /**
30543
30682
  * The URLs the SDK / viewer should race for API access. `baseUrls` empty =
@@ -30550,6 +30689,27 @@ var ViewerEndpointsSchema = object({
30550
30689
  /** What the ranking currently resolves to (may be empty if nothing is up). */
30551
30690
  resolved: array(string()).readonly()
30552
30691
  });
30692
+ /**
30693
+ * One audience's hub address (see `hub-address.ts`): the operator's stored
30694
+ * override, the address in use, and where it came from.
30695
+ */
30696
+ var HubAddressSnapshotSchema = object({
30697
+ /** The operator's override, or null for automatic. */
30698
+ override: string().nullable(),
30699
+ /** The address in use, or null when nothing qualifies (never loopback). */
30700
+ resolved: string().nullable(),
30701
+ source: _enum([
30702
+ "override",
30703
+ "auto",
30704
+ "none"
30705
+ ])
30706
+ });
30707
+ var HubAddressesSchema = object({
30708
+ /** "Hub address for agents" — agents' bundle/model pulls, LAN devices. */
30709
+ cluster: HubAddressSnapshotSchema,
30710
+ /** "Public address for sign-in links" — e-mail links, OIDC, WebAuthn, OAuth2. */
30711
+ browser: HubAddressSnapshotSchema
30712
+ });
30553
30713
  var AllowedAddressesSchema = object({
30554
30714
  /**
30555
30715
  * Allowlist of interface addresses operators have explicitly opted
@@ -30591,8 +30751,18 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
30591
30751
  * Pass `'https'` when the caller is itself loaded over HTTPS
30592
30752
  * to avoid mixed-content blocks in the browser. The public
30593
30753
  * tunnel always emits `https://` regardless. */
30594
- scheme: _enum(["http", "https"]).optional()
30595
- }), 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, {
30754
+ scheme: _enum(["http", "https"]).optional(),
30755
+ /** Append the CamStack app link entry (`kind: 'app-link'`, D709) —
30756
+ * an address notification links can be flagged with, not a hub
30757
+ * route. Default `false`: racers and rankers never see it. */
30758
+ includeAppLink: boolean().optional()
30759
+ }), 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(), HubAddressesSchema), method(object({
30760
+ audience: _enum(["cluster", "browser"]),
30761
+ baseUrl: string().nullable()
30762
+ }), HubAddressesSchema, {
30763
+ kind: "mutation",
30764
+ auth: "admin"
30765
+ }), 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, {
30596
30766
  kind: "mutation",
30597
30767
  auth: "admin"
30598
30768
  }), method(object({
@@ -30852,7 +31022,7 @@ var MeshPeerSchema = object({
30852
31022
  tags: array(string()).readonly(),
30853
31023
  /** True when the peer advertises itself as an exit-node candidate. */
30854
31024
  exitNodeOption: boolean(),
30855
- /** Subnet routes the peer advertises (e.g. `["192.168.x.x/24"]`). */
31025
+ /** Subnet routes the peer advertises (e.g. `["192.168.10.0/24"]`). */
30856
31026
  advertisedRoutes: array(string()).readonly(),
30857
31027
  /** Owner account login (e.g. `foo@example.com`). Null for tagged peers. */
30858
31028
  userLogin: string().nullable(),
@@ -30982,7 +31152,8 @@ object({
30982
31152
  * writes this slice (not even a boot seed), and neither does the runner's
30983
31153
  * phase machine: its phase is "a session is attached" for every on-motion
30984
31154
  * session, not motion, and it now has its own `DetectionPhaseTransition`.
30985
- * A provider's `isDetected` answers from the hub's slice.
31155
+ * A provider's `isDetected` and `getStatus` answer from the hub's slice
31156
+ * (`hubMotionNativeProvider`).
30986
31157
  * - **Sensors** (Home Assistant binary sensors, Homematic, Matter, Alexa
30987
31158
  * imports) — the provider pushes both edges itself, from the upstream
30988
31159
  * system's own state change. That is the sensor's own fact.
@@ -31796,7 +31967,13 @@ var OsdStatusSchema = object({ overlays: array(object({
31796
31967
  */
31797
31968
  availablePositions: array(OsdPositionEnum).readonly(),
31798
31969
  /** Firmware does not allow editing the `text` field (e.g. timestamp). */
31799
- readOnly: boolean().optional()
31970
+ readOnly: boolean().optional(),
31971
+ /**
31972
+ * Firmware text ceiling for this overlay. Absent = no known limit.
31973
+ * The OSD manager truncates here on every write — never stores its own
31974
+ * copy on the binding.
31975
+ */
31976
+ maxCharacters: number().int().positive().optional()
31800
31977
  })).readonly() });
31801
31978
  var OsdOverlayPatchSchema = object({
31802
31979
  enabled: boolean().optional(),
@@ -31847,7 +32024,9 @@ var OsdTemplateBindingSchema = object({
31847
32024
  valuePath: string().min(1).max(64),
31848
32025
  /** Convert TO this unit at render (`tryConvertUnit`). Absent = source unit. */
31849
32026
  displayUnit: string().max(16).optional(),
31850
- maxDecimals: number().int().min(0).max(4).default(1)
32027
+ maxDecimals: number().int().min(0).max(4).default(1),
32028
+ /** Raw value → display text (same shape as slot binding). Empty string hides. */
32029
+ valueMap: record(string(), string()).optional()
31851
32030
  });
31852
32031
  /**
31853
32032
  * A named template: bindings (alias → leaf field) + a parser that
@@ -31897,18 +32076,11 @@ var OsdSlotBindingSchema = object({
31897
32076
  source: OsdSourceSchema,
31898
32077
  /** `${value}` and `${unit}` are substituted; every occurrence. */
31899
32078
  template: string().max(96).default("${value}"),
31900
- /** Truncate with an ellipsis past this length. Absent = no limit. */
31901
- maxCharacters: number().int().min(4).max(64).optional(),
31902
32079
  /**
31903
32080
  * Decimal places for a numeric value. `0` yields an integer — the
31904
32081
  * documented workaround for firmwares that reject `.` in overlay text.
31905
32082
  */
31906
32083
  maxDecimals: number().int().min(0).max(4).default(1),
31907
- /**
31908
- * Appended via `${unit}` when no unit conversion produces a label.
31909
- * Prefer `source.displayUnit` for converted device-state values.
31910
- */
31911
- unitLabel: string().max(8).optional(),
31912
32084
  /** Raw value → display text, e.g. `{"true":"MOTION","false":""}`. */
31913
32085
  valueMap: record(string(), string()).optional(),
31914
32086
  /** Time windows in which the slot is shown. Absent = always. */
@@ -31917,9 +32089,7 @@ var OsdSlotBindingSchema = object({
31917
32089
  * Display gate, in the notification centre's condition vocabulary.
31918
32090
  * Only the keys reported by `getConditionSupport` are accepted.
31919
32091
  */
31920
- conditions: NcConditionsSchema.optional(),
31921
- /** Rendered when the gate is closed or the value unreadable. Empty = hide. */
31922
- fallbackText: string().max(64).default("")
32092
+ conditions: NcConditionsSchema.optional()
31923
32093
  });
31924
32094
  /** One camera slot, as the operator sees it: firmware truth + our binding. */
31925
32095
  var OsdSlotViewSchema = object({
@@ -39060,6 +39230,12 @@ Object.freeze({
39060
39230
  addonId: null,
39061
39231
  access: "view"
39062
39232
  },
39233
+ "localNetwork.getHubAddresses": {
39234
+ capName: "local-network",
39235
+ capScope: "system",
39236
+ addonId: null,
39237
+ access: "view"
39238
+ },
39063
39239
  "localNetwork.getNotificationEndpoint": {
39064
39240
  capName: "local-network",
39065
39241
  capScope: "system",
@@ -39114,6 +39290,12 @@ Object.freeze({
39114
39290
  addonId: null,
39115
39291
  access: "create"
39116
39292
  },
39293
+ "localNetwork.setHubAddress": {
39294
+ capName: "local-network",
39295
+ capScope: "system",
39296
+ addonId: null,
39297
+ access: "create"
39298
+ },
39117
39299
  "localNetwork.setNotificationEndpoint": {
39118
39300
  capName: "local-network",
39119
39301
  capScope: "system",
@@ -47513,6 +47695,8 @@ new Map(Object.entries({
47513
47695
  "detection-blind": "device-events",
47514
47696
  "node-online": "system",
47515
47697
  "node-offline": "system",
47698
+ "node-restarting": "system",
47699
+ "node-updating": "system",
47516
47700
  "node-inference-unavailable": "system",
47517
47701
  "addon-crash-loop": "system",
47518
47702
  "addon-update-available": "system",
@@ -47590,18 +47774,21 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
47590
47774
  kinds: [
47591
47775
  "node-offline",
47592
47776
  "node-online",
47777
+ "node-restarting",
47593
47778
  "node-inference-unavailable"
47594
47779
  ]
47595
47780
  },
47596
47781
  {
47597
47782
  id: "addons",
47598
47783
  family: "system",
47599
- label: "Addons",
47600
- kinds: [
47601
- "addon-crash-loop",
47602
- "addon-update-available",
47603
- "addon-updated"
47604
- ]
47784
+ label: "Addons stopped",
47785
+ kinds: ["addon-crash-loop"]
47786
+ },
47787
+ {
47788
+ id: "addon-updates",
47789
+ family: "system",
47790
+ label: "Addon updates",
47791
+ kinds: ["addon-update-available", "addon-updated"]
47605
47792
  },
47606
47793
  {
47607
47794
  id: "updates",
@@ -47609,6 +47796,7 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
47609
47796
  label: "Server & container updates",
47610
47797
  kinds: [
47611
47798
  "server-update-available",
47799
+ "node-updating",
47612
47800
  "server-updated",
47613
47801
  "wrapper-update-available"
47614
47802
  ]
@@ -47756,18 +47944,21 @@ var STATE_SUMMARY_SECTION_VARS = [
47756
47944
  kinds: [
47757
47945
  "node-offline",
47758
47946
  "node-online",
47947
+ "node-restarting",
47759
47948
  "node-inference-unavailable"
47760
47949
  ]
47761
47950
  },
47762
47951
  {
47763
47952
  name: "summaryAddons",
47764
- label: "Summary: addons",
47765
- example: "@camstack/addon-recorder 1.2.3 → 1.2.4",
47766
- kinds: [
47767
- "addon-crash-loop",
47768
- "addon-update-available",
47769
- "addon-updated"
47770
- ]
47953
+ label: "Summary: addons stopped",
47954
+ example: "hub — recorder stopped after repeated crashes",
47955
+ kinds: ["addon-crash-loop"]
47956
+ },
47957
+ {
47958
+ name: "summaryAddonUpdates",
47959
+ label: "Summary: addon updates",
47960
+ example: "hub:\n• @camstack/addon-recorder 1.2.3 → 1.2.4",
47961
+ kinds: ["addon-update-available", "addon-updated"]
47771
47962
  },
47772
47963
  {
47773
47964
  name: "summaryUpdates",
@@ -47775,6 +47966,7 @@ var STATE_SUMMARY_SECTION_VARS = [
47775
47966
  example: "server 1.2.377 → 1.2.378",
47776
47967
  kinds: [
47777
47968
  "server-update-available",
47969
+ "node-updating",
47778
47970
  "server-updated",
47779
47971
  "wrapper-update-available"
47780
47972
  ]
@@ -47807,7 +47999,7 @@ var STATE_SUMMARY_VARS = [
47807
47999
  {
47808
48000
  name: "summarySection",
47809
48001
  label: "Summary: this section",
47810
- description: "The section a per-section summary row is about (D698); on a summary sent as one message, every section it reports, comma-separated.",
48002
+ description: "The section a per-section summary row is about; on a summary sent as one message, every section it reports, comma-separated.",
47811
48003
  example: "Batterie scariche",
47812
48004
  group: "system",
47813
48005
  families: ["rule"],
@@ -47851,6 +48043,7 @@ var STATE_SUMMARY_VARS = [
47851
48043
  [...RULE_BODY_ONLY],
47852
48044
  [...RULE_TEXT],
47853
48045
  ([...RULE_TEXT], [...DEVICE_EVENTS]),
48046
+ ([...RULE_TEXT], [...COMBINED_ALARM]),
47854
48047
  ([...RULE_TEXT], [...DEVICE_EVENTS]),
47855
48048
  ([...RULE_TEXT], [...BATTERY, ...CONSUMABLE]),
47856
48049
  ([...RULE_TEXT], [...CONSUMABLE]),
@@ -47891,6 +48084,8 @@ var STATE_SUMMARY_VARS = [
47891
48084
  [...RULE_TEXT],
47892
48085
  [...RULE_TEXT],
47893
48086
  [...RULE_TEXT],
48087
+ [...RULE_TEXT],
48088
+ [...RULE_TEXT],
47894
48089
  ...STATE_SUMMARY_VARS
47895
48090
  ];
47896
48091
  new Set([