@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.
@@ -10475,6 +10475,15 @@ var ClipSearchStrictnessSchema = _enum([
10475
10475
  "balanced",
10476
10476
  "strict"
10477
10477
  ]);
10478
+ /** Steps whose effect a root label can BE. */
10479
+ var LABEL_SUPPLY_STEP_IDS = [
10480
+ "animal-classifier",
10481
+ "vehicle-classifier",
10482
+ "package-detection"
10483
+ ];
10484
+ /** Steps whose box a root detection can BE. */
10485
+ var CROP_SUPPLY_STEP_IDS = ["plate-detection", "face-detection"];
10486
+ [...LABEL_SUPPLY_STEP_IDS, ...CROP_SUPPLY_STEP_IDS];
10478
10487
  var MODEL_FORMATS = [
10479
10488
  "onnx",
10480
10489
  "coreml",
@@ -10544,11 +10553,11 @@ var ModelVariantGroupSchema = object({
10544
10553
  /** Quantization axis. Omit ⇒ the fp32 base build. */
10545
10554
  precision: _enum(["fp32", "int8"]).optional(),
10546
10555
  /**
10547
- * Speed-optimization axis. Omit ⇒ the standard build. `fast` marks a
10548
- * latency-optimized export (e.g. ReLU-activation variant) — the slot the
10549
- * future performance variants plug into.
10556
+ * Training / latency-variant axis. Omit ⇒ the standard build. `test` marks
10557
+ * an alternate training of the same family (Scrypted `relu_test`); chip
10558
+ * label is "Test".
10550
10559
  */
10551
- optimization: _enum(["standard", "fast"]).optional(),
10560
+ optimization: _enum(["standard", "test"]).optional(),
10552
10561
  /**
10553
10562
  * Input-resolution axis (square input side, px). Omit ⇒ the family's native
10554
10563
  * resolution (640 for yolo26). Reduced-input builds (320 / 256) are a big,
@@ -10571,9 +10580,10 @@ var ModelProviderIdSchema = _enum([
10571
10580
  * are per upstream. A persisted custom-model row written when this field was a
10572
10581
  * string still parses — the string is lifted into `{ weights }`.
10573
10582
  *
10574
- * Every licence surface (the admin "Models and licenses" page,
10575
- * `THIRD_PARTY_MODELS.md`, the Hugging Face model table) is GENERATED from
10576
- * these records by `scripts/gen-model-licenses.ts` (D661).
10583
+ * Every machine licence surface (`THIRD_PARTY_MODELS.md`, the Hugging Face
10584
+ * model table) is GENERATED from these records by
10585
+ * `scripts/gen-model-licenses.ts` (D661). Operator-facing docs live in
10586
+ * `camstack/docs` → `/docs/detection/models`.
10577
10587
  */
10578
10588
  var ModelLicenseSchema = preprocess((value) => typeof value === "string" ? { weights: value } : value, object({
10579
10589
  /** SPDX id of the WEIGHTS' terms, a `LicenseRef-*` for non-SPDX terms, or `UNKNOWN`. */
@@ -10606,6 +10616,35 @@ var ModelLicenseSchema = preprocess((value) => typeof value === "string" ? { wei
10606
10616
  /** True when the weights or their data forbid commercial use. */
10607
10617
  nonCommercial: boolean().optional()
10608
10618
  }));
10619
+ /**
10620
+ * One step a ROOT detector can supply from its own output (D730) — see
10621
+ * `ModelCatalogEntry.suppliesSteps`.
10622
+ *
10623
+ * - `label`: the root's raw class IS the step's answer. `labelToEffect` maps
10624
+ * the root's label to the step's vocabulary; `uncovered` is the vocabulary
10625
+ * the root cannot produce (shown as unavailable, never a blocker).
10626
+ * - `crop`: the root draws the box the step would have found (`license_plate`
10627
+ * for plate-detection, `face` for face-detection). The box becomes a detail
10628
+ * child of the `parentMacro` detection that contains it — never a track.
10629
+ */
10630
+ var RootStepSupplySchema = discriminatedUnion("kind", [object({
10631
+ kind: literal("label"),
10632
+ stepId: _enum(LABEL_SUPPLY_STEP_IDS),
10633
+ labelToEffect: record(string(), string()),
10634
+ uncovered: array(string()).readonly()
10635
+ }), object({
10636
+ kind: literal("crop"),
10637
+ stepId: _enum(CROP_SUPPLY_STEP_IDS),
10638
+ rootLabels: array(string()).readonly(),
10639
+ parentMacro: _enum(["vehicle", "person"]),
10640
+ childClass: _enum(["plate", "face"]),
10641
+ /**
10642
+ * The root's smaller input side, stamped on read by `rootSuppliesOf` from
10643
+ * the model entry — what a step's `minRootInputPx` gate judges. Never
10644
+ * stored by an import.
10645
+ */
10646
+ rootInputPx: number().int().positive().optional()
10647
+ })]);
10609
10648
  var ModelCatalogEntrySchema = object({
10610
10649
  id: string(),
10611
10650
  name: string(),
@@ -10732,6 +10771,16 @@ var ModelCatalogEntrySchema = object({
10732
10771
  */
10733
10772
  classMap: DetectionCatalogClassMapSchema.optional(),
10734
10773
  /**
10774
+ * The pipeline steps this ROOT detector can supply from its own output
10775
+ * (D730): its labels name a step's effect (`deer` for `animal-classifier`)
10776
+ * or draw a step's box (`license_plate` for `plate-detection`). Computed at
10777
+ * import from THIS model's labelmap by `deriveRootSupplies`, never written
10778
+ * by hand and never assumed per family; a row without it is derived on read
10779
+ * (`rootSuppliesOf`). Whether a camera uses it is the step's own
10780
+ * `useRootModel` flag (`resolveRootSupply`).
10781
+ */
10782
+ suppliesSteps: array(RootStepSupplySchema).readonly().optional(),
10783
+ /**
10735
10784
  * The model's CLIP feature-space contract (text encoder, dimension, vector
10736
10785
  * index, token window, search floor) — see `clip-model.ts`. Present ONLY on a
10737
10786
  * CLIP image encoder; its absence is what "not a CLIP model" means to the
@@ -14102,7 +14151,7 @@ DeviceType.Camera;
14102
14151
  * This matters here more than anywhere else in the repo, because every provider
14103
14152
  * that knows a device's host knows its PASSWORD too: `{ host, port, username,
14104
14153
  * password }` sit in one object on Hikvision, Amcrest, Reolink and ONVIF alike,
14105
- * and `http://admin:hunter2@192.168.x.x/` is a URL a browser accepts. The
14154
+ * and `http://admin:hunter2@192.168.60.139/` is a URL a browser accepts. The
14106
14155
  * camera's own page will ask for its own login. That is correct, and pre-
14107
14156
  * filling it is the operator's business, not ours.
14108
14157
  *
@@ -17086,7 +17135,7 @@ method(object({
17086
17135
  timeoutMs: 6e5
17087
17136
  });
17088
17137
  method(object({
17089
- nodeId: string(),
17138
+ targetNodeId: string(),
17090
17139
  modelId: string(),
17091
17140
  format: _enum(MODEL_FORMATS),
17092
17141
  entry: ModelCatalogEntrySchema
@@ -18454,6 +18503,8 @@ var NcSystemEventKindSchema = _enum([
18454
18503
  "stream-offline",
18455
18504
  "node-online",
18456
18505
  "node-offline",
18506
+ "node-restarting",
18507
+ "node-updating",
18457
18508
  "node-inference-unavailable",
18458
18509
  "detection-blind",
18459
18510
  "addon-crash-loop",
@@ -19552,8 +19603,9 @@ var NcRuleSchema = NcRuleInputSchema.extend({
19552
19603
  disabledTargetIds: array(string()).default([])
19553
19604
  });
19554
19605
  /**
19555
- * The state-summary SECTIONS (D647 / D698): the D637 kind groups that report a
19556
- * still-true state. `backups-exports` and `alarm` are not sections — a completed
19606
+ * The state-summary SECTIONS (D647 / D698 / D708): the D637 kind groups that
19607
+ * report a still-true state. `addons` is the crash-looped addons only and
19608
+ * `addon-updates` the addons that are behind (D708 split them). `backups-exports` and `alarm` are not sections — a completed
19557
19609
  * job is not an open state, and the alarm stays instant.
19558
19610
  */
19559
19611
  var NcStateSummarySectionIdSchema = _enum([
@@ -19565,6 +19617,7 @@ var NcStateSummarySectionIdSchema = _enum([
19565
19617
  "detection-blind",
19566
19618
  "nodes",
19567
19619
  "addons",
19620
+ "addon-updates",
19568
19621
  "updates"
19569
19622
  ]);
19570
19623
  /** One section of a previewed state summary. `unavailable` = its state could not be read. */
@@ -20045,7 +20098,19 @@ var NcAlarmModeDelaysListSchema = array(object({
20045
20098
  * When this mode may be armed. Absent / null = always allowed (same as a
20046
20099
  * rule with no `schedule`). Evaluated with {@link isScheduleActive}.
20047
20100
  */
20048
- schedule: NcScheduleSchema.optional()
20101
+ schedule: NcScheduleSchema.optional(),
20102
+ /**
20103
+ * D706: while this mode's ENTRY DELAY runs, do the alarm rules' own pushes go out (as an
20104
+ * intrusion naming the locations)? Absent = false — the entry-delay notification is the
20105
+ * only one, and the matches ride the triggered notification's mosaic (D705).
20106
+ */
20107
+ notifyDuringEntryDelay: boolean().optional(),
20108
+ /**
20109
+ * D706: notify "watched again" when a sensor this arm bypassed closes and opens again.
20110
+ * Absent = false (logged, not sent). Even when true it is not sent when that same sensor
20111
+ * is the one that starts the entry delay — the entry-delay notification already names it.
20112
+ */
20113
+ notifySensorRewatched: boolean().optional()
20049
20114
  })).max(8).refine(uniqueModes, { message: "modeDelays: at most one entry per arm mode" });
20050
20115
  var NcAlarmModeDelaysEditListSchema = array(object({
20051
20116
  mode: AlarmArmModeSchema,
@@ -20054,7 +20119,11 @@ var NcAlarmModeDelaysEditListSchema = array(object({
20054
20119
  triggeredDurationSec: NcAlarmTriggeredSecSchema.nullable().optional(),
20055
20120
  postTriggeredAction: NcAlarmPostTriggeredActionSchema.nullable().optional(),
20056
20121
  /** Set a schedule, or `null` to clear (mode always allowed again). */
20057
- schedule: NcScheduleSchema.nullable().optional()
20122
+ schedule: NcScheduleSchema.nullable().optional(),
20123
+ /** D706: set the switch, or `null` to clear it (back to the default, false). */
20124
+ notifyDuringEntryDelay: boolean().nullable().optional(),
20125
+ /** D706: set the switch, or `null` to clear it (back to the default, false). */
20126
+ notifySensorRewatched: boolean().nullable().optional()
20058
20127
  })).max(8).refine(uniqueModes, { message: "modeDelays: at most one edit per arm mode" });
20059
20128
  /** One switch of the alarm table: put ONE device on, or take it off, ONE mode's list. */
20060
20129
  var NcAlarmNonBlockingEditSchema = object({
@@ -21015,39 +21084,19 @@ Object.freeze(Object.fromEntries([{
21015
21084
  label: "Face recognition model",
21016
21085
  defaultModelId: "auraface-r100",
21017
21086
  indexName: "the enrolled face gallery",
21018
- options: [
21019
- {
21020
- id: "auraface-r100",
21021
- label: "AuraFace R100"
21022
- },
21023
- {
21024
- id: "arcface-r100",
21025
- label: "ArcFace (ResNet34)"
21026
- },
21027
- {
21028
- id: "inception-resnet-v1",
21029
- label: "Inception ResNet V1"
21030
- }
21031
- ]
21087
+ options: [{
21088
+ id: "auraface-r100",
21089
+ label: "AuraFace R100"
21090
+ }]
21032
21091
  }, {
21033
21092
  stepId: "clip-embedding",
21034
21093
  label: "Semantic search model",
21035
- defaultModelId: "mobileclip-s1",
21094
+ defaultModelId: "siglip2-b16-224",
21036
21095
  indexName: "the object semantic-search index",
21037
- options: [
21038
- {
21039
- id: "mobileclip-s1",
21040
- label: "MobileCLIP S1"
21041
- },
21042
- {
21043
- id: "mobileclip-s2",
21044
- label: "MobileCLIP S2"
21045
- },
21046
- {
21047
- id: "siglip2-b16-224",
21048
- label: "SigLIP2 B/16 (Apache-2.0)"
21049
- }
21050
- ]
21096
+ options: [{
21097
+ id: "siglip2-b16-224",
21098
+ label: "SigLIP2 B/16 (Apache-2.0)"
21099
+ }]
21051
21100
  }].map((s) => [s.stepId, s.defaultModelId])));
21052
21101
  var CLUSTER_STEP_SETTING_FIELDS = [{
21053
21102
  stepId: "face-embedding",
@@ -22973,6 +23022,34 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
22973
23022
  timestamp: number()
22974
23023
  });
22975
23024
  /**
23025
+ * A root model's boxes standing in for one crop-kind step's own inference
23026
+ * (D730) — see `runPipeline.suppliedRoot`.
23027
+ */
23028
+ var SuppliedRootOutputSchema = object({
23029
+ stepId: string(),
23030
+ /** The root model that drew the boxes — stamped on the result. */
23031
+ modelId: string(),
23032
+ detections: array(object({
23033
+ /** `[x1, y1, x2, y2]` in the pixels of the call's image. */
23034
+ bbox: tuple([
23035
+ number(),
23036
+ number(),
23037
+ number(),
23038
+ number()
23039
+ ]),
23040
+ score: number(),
23041
+ /**
23042
+ * Five facial landmarks in the same pixels — a face the step's own
23043
+ * detector already re-found inside a root face box (D730), so its
23044
+ * embedder child aligns it exactly as it aligns any detected face.
23045
+ */
23046
+ landmarks: array(object({
23047
+ x: number(),
23048
+ y: number()
23049
+ })).optional()
23050
+ })).min(1)
23051
+ });
23052
+ /**
22976
23053
  * Reference to the frame's retained NATIVE surface + the parent crop's placement
22977
23054
  * within the frame, so the executor can re-cut a leaf child ROI at native
22978
23055
  * resolution on the detail plane. See the `runPipeline` `nativeCropRef` field.
@@ -23102,7 +23179,8 @@ var PipelineModelOptionSchema = object({
23102
23179
  group: ModelVariantGroupSchema.optional(),
23103
23180
  legacy: boolean().optional(),
23104
23181
  provider: ModelProviderIdSchema.optional(),
23105
- defaultConfidence: number().optional()
23182
+ defaultConfidence: number().optional(),
23183
+ suppliesSteps: array(RootStepSupplySchema).readonly().optional()
23106
23184
  });
23107
23185
  var ConfigFieldBridge = custom();
23108
23186
  var PipelineAddonSchemaSchema = object({
@@ -23370,7 +23448,16 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
23370
23448
  * `device-not-servable`), and nothing reaches the camera's live
23371
23449
  * trace stream. Absent ⇒ unchanged behaviour.
23372
23450
  */
23373
- replay: literal(true).optional()
23451
+ replay: literal(true).optional(),
23452
+ /**
23453
+ * Root-supplied detections for the tree's ROOT step (D730). Set by
23454
+ * `runDetailSubtree` when the camera's root model supplies a crop-kind
23455
+ * step (a Frigate+ `license_plate` for `plate-detection`): the step is
23456
+ * NOT inferred, these boxes are its output, and its children (the plate
23457
+ * reader) run on them through their own crop policy. Boxes are in the
23458
+ * PIXELS of the image this call carries. Absent ⇒ the root step runs.
23459
+ */
23460
+ suppliedRoot: SuppliedRootOutputSchema.optional()
23374
23461
  }), PipelineRunResultBridge, { kind: "mutation" }), method(object({
23375
23462
  steps: array(PipelineStepInputSchema).min(1),
23376
23463
  frames: array(FrameInputSchema).min(1).max(255),
@@ -23895,6 +23982,22 @@ var MotionSourceEnum = _enum([
23895
23982
  "device-activity"
23896
23983
  ]);
23897
23984
  /**
23985
+ * What opened an on-motion detection SESSION: the motion source that passed the
23986
+ * camera's `motionSources` gate, and what raised it (the camera itself, or a
23987
+ * sensor the operator attached — D672). `sensorName` is the attached sensor's
23988
+ * device name as the orchestrator's camera-sensors resolution last read it;
23989
+ * absent when unknown or when the camera itself triggered.
23990
+ *
23991
+ * Carried on the session attach ONLY so the runner's `DetectionPhaseTransition`
23992
+ * can say what started the session (D672 rule 11, amended 2026-10-06). The
23993
+ * runner never decides anything on it.
23994
+ */
23995
+ var SessionTriggerSchema = object({
23996
+ source: MotionSourceEnum,
23997
+ triggeredBy: MotionTriggeredBySchema,
23998
+ sensorName: string().optional()
23999
+ });
24000
+ /**
23898
24001
  * List of motion sources active on a camera. Empty array is valid:
23899
24002
  * "no source" — happens for battery cams without firmware motion when
23900
24003
  * the operator hasn't opted into the SW analyzer (would hold the
@@ -24146,6 +24249,14 @@ var RunnerCameraConfigSchema = object({
24146
24249
  */
24147
24250
  motionSources: MotionSourcesSchema.default(["analyzer"]),
24148
24251
  /**
24252
+ * What opened this attach, on a SESSION attach only (see
24253
+ * {@link SessionTriggerSchema}). OPTIONAL with no default: absent on a
24254
+ * standing attach, an occupancy burst, a re-dispatch with no motion event
24255
+ * behind it, and every attach from an orchestrator older than the field — the
24256
+ * runner then names no source on the phase event.
24257
+ */
24258
+ sessionTrigger: SessionTriggerSchema.optional(),
24259
+ /**
24149
24260
  * WHICH root detector runs for this camera. The detection counterpart of
24150
24261
  * {@link motionSources}, same shape and same discipline: a per-camera list
24151
24262
  * of sources the system understands, vendor-agnostic, owned here.
@@ -24448,7 +24559,22 @@ method(RunnerCameraConfigSchema, object({ success: literal(true) }), { kind: "mu
24448
24559
  */
24449
24560
  cropJpeg: string().optional(),
24450
24561
  parent: DetailParentSchema,
24451
- steps: array(string()).optional()
24562
+ steps: array(string()).optional(),
24563
+ /**
24564
+ * The camera's root model already drew this step's boxes (D730): a
24565
+ * `license_plate` inside the parent vehicle. The named step is NOT
24566
+ * inferred — these FRAME-space boxes are its output — and its
24567
+ * requested children (the plate reader) run on them. Absent ⇒ every
24568
+ * requested step infers as before.
24569
+ */
24570
+ supplied: object({
24571
+ stepId: string(),
24572
+ modelId: string(),
24573
+ boxes: array(object({
24574
+ bbox: NativeCropBboxSchema,
24575
+ score: number()
24576
+ })).min(1)
24577
+ }).optional()
24452
24578
  }), object({ details: array(DetailResultSchema) }).nullable(), { kind: "mutation" }), method(object({
24453
24579
  /** Catalog step id, e.g. `clip-embedding`. */
24454
24580
  stepId: string(),
@@ -30429,7 +30555,7 @@ var LocalInterfaceSchema = object({
30429
30555
  name: string(),
30430
30556
  family: _enum(["IPv4", "IPv6"]),
30431
30557
  address: string(),
30432
- /** CIDR shorthand (e.g. `192.168.x.x/24`). Empty when OS doesn't expose. */
30558
+ /** CIDR shorthand (e.g. `192.168.10.10/24`). Empty when OS doesn't expose. */
30433
30559
  cidr: string(),
30434
30560
  /** OS netmask. Stable across calls so the SDK can hash on it. */
30435
30561
  netmask: string(),
@@ -30483,7 +30609,8 @@ var ConnectionEndpointSchema = object({
30483
30609
  "lan-ipv4",
30484
30610
  "lan-ipv6",
30485
30611
  "public",
30486
- "loopback"
30612
+ "loopback",
30613
+ "app-link"
30487
30614
  ]),
30488
30615
  /**
30489
30616
  * Originating-interface kind — `lan`/`wifi`/`docker`/`vpn`/`other`/
@@ -30552,15 +30679,27 @@ var GetConnectionEndpointsResultSchema = object({
30552
30679
  localPort: AdvertisedLocalPortSchema
30553
30680
  });
30554
30681
  /**
30555
- * The chosen outbound endpoint for notification artifacts. `baseUrl: null` =
30556
- * AUTO (resolved from the candidate ranking at send time); `resolved` reports
30557
- * what AUTO currently picks, so the UI can show the effective value either way.
30682
+ * The address flagged for notification links. `baseUrl: null` = AUTO, which
30683
+ * since D709 is the CamStack app link; `resolved` reports the effective value,
30684
+ * so the UI can show it either way.
30558
30685
  */
30559
30686
  var NotificationEndpointSchema = object({
30560
30687
  /** The operator's explicit choice, or null for AUTO. */
30561
30688
  baseUrl: string().nullable(),
30562
- /** What the ranking currently resolves to (null when nothing is reachable). */
30563
- resolved: string().nullable()
30689
+ /**
30690
+ * The effective flagged address: the explicit choice, else (AUTO) the
30691
+ * CamStack app link `https://camstack.zentik.app` (D709). A pre-D709 hub
30692
+ * answered the public tunnel / mesh here, or null.
30693
+ */
30694
+ resolved: string().nullable(),
30695
+ /**
30696
+ * The hub origin an app link carries as `hub=` (D709): the hub's best
30697
+ * public HTTPS address — the tunnel, then the mesh (Tailscale MagicDNS) —
30698
+ * picked from this cap's own palette by `pickAppLinkHub`. `null` when the
30699
+ * hub advertises neither; the app link is then minted without `hub=`.
30700
+ * Absent on a pre-D709 hub.
30701
+ */
30702
+ appLinkHub: string().nullable()
30564
30703
  });
30565
30704
  /**
30566
30705
  * The URLs the SDK / viewer should race for API access. `baseUrls` empty =
@@ -30573,6 +30712,27 @@ var ViewerEndpointsSchema = object({
30573
30712
  /** What the ranking currently resolves to (may be empty if nothing is up). */
30574
30713
  resolved: array(string()).readonly()
30575
30714
  });
30715
+ /**
30716
+ * One audience's hub address (see `hub-address.ts`): the operator's stored
30717
+ * override, the address in use, and where it came from.
30718
+ */
30719
+ var HubAddressSnapshotSchema = object({
30720
+ /** The operator's override, or null for automatic. */
30721
+ override: string().nullable(),
30722
+ /** The address in use, or null when nothing qualifies (never loopback). */
30723
+ resolved: string().nullable(),
30724
+ source: _enum([
30725
+ "override",
30726
+ "auto",
30727
+ "none"
30728
+ ])
30729
+ });
30730
+ var HubAddressesSchema = object({
30731
+ /** "Hub address for agents" — agents' bundle/model pulls, LAN devices. */
30732
+ cluster: HubAddressSnapshotSchema,
30733
+ /** "Public address for sign-in links" — e-mail links, OIDC, WebAuthn, OAuth2. */
30734
+ browser: HubAddressSnapshotSchema
30735
+ });
30576
30736
  var AllowedAddressesSchema = object({
30577
30737
  /**
30578
30738
  * Allowlist of interface addresses operators have explicitly opted
@@ -30614,8 +30774,18 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
30614
30774
  * Pass `'https'` when the caller is itself loaded over HTTPS
30615
30775
  * to avoid mixed-content blocks in the browser. The public
30616
30776
  * tunnel always emits `https://` regardless. */
30617
- scheme: _enum(["http", "https"]).optional()
30618
- }), 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, {
30777
+ scheme: _enum(["http", "https"]).optional(),
30778
+ /** Append the CamStack app link entry (`kind: 'app-link'`, D709) —
30779
+ * an address notification links can be flagged with, not a hub
30780
+ * route. Default `false`: racers and rankers never see it. */
30781
+ includeAppLink: boolean().optional()
30782
+ }), 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({
30783
+ audience: _enum(["cluster", "browser"]),
30784
+ baseUrl: string().nullable()
30785
+ }), HubAddressesSchema, {
30786
+ kind: "mutation",
30787
+ auth: "admin"
30788
+ }), 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, {
30619
30789
  kind: "mutation",
30620
30790
  auth: "admin"
30621
30791
  }), method(object({
@@ -30875,7 +31045,7 @@ var MeshPeerSchema = object({
30875
31045
  tags: array(string()).readonly(),
30876
31046
  /** True when the peer advertises itself as an exit-node candidate. */
30877
31047
  exitNodeOption: boolean(),
30878
- /** Subnet routes the peer advertises (e.g. `["192.168.x.x/24"]`). */
31048
+ /** Subnet routes the peer advertises (e.g. `["192.168.10.0/24"]`). */
30879
31049
  advertisedRoutes: array(string()).readonly(),
30880
31050
  /** Owner account login (e.g. `foo@example.com`). Null for tagged peers. */
30881
31051
  userLogin: string().nullable(),
@@ -31005,7 +31175,8 @@ object({
31005
31175
  * writes this slice (not even a boot seed), and neither does the runner's
31006
31176
  * phase machine: its phase is "a session is attached" for every on-motion
31007
31177
  * session, not motion, and it now has its own `DetectionPhaseTransition`.
31008
- * A provider's `isDetected` answers from the hub's slice.
31178
+ * A provider's `isDetected` and `getStatus` answer from the hub's slice
31179
+ * (`hubMotionNativeProvider`).
31009
31180
  * - **Sensors** (Home Assistant binary sensors, Homematic, Matter, Alexa
31010
31181
  * imports) — the provider pushes both edges itself, from the upstream
31011
31182
  * system's own state change. That is the sensor's own fact.
@@ -31819,7 +31990,13 @@ var OsdStatusSchema = object({ overlays: array(object({
31819
31990
  */
31820
31991
  availablePositions: array(OsdPositionEnum).readonly(),
31821
31992
  /** Firmware does not allow editing the `text` field (e.g. timestamp). */
31822
- readOnly: boolean().optional()
31993
+ readOnly: boolean().optional(),
31994
+ /**
31995
+ * Firmware text ceiling for this overlay. Absent = no known limit.
31996
+ * The OSD manager truncates here on every write — never stores its own
31997
+ * copy on the binding.
31998
+ */
31999
+ maxCharacters: number().int().positive().optional()
31823
32000
  })).readonly() });
31824
32001
  var OsdOverlayPatchSchema = object({
31825
32002
  enabled: boolean().optional(),
@@ -31870,7 +32047,9 @@ var OsdTemplateBindingSchema = object({
31870
32047
  valuePath: string().min(1).max(64),
31871
32048
  /** Convert TO this unit at render (`tryConvertUnit`). Absent = source unit. */
31872
32049
  displayUnit: string().max(16).optional(),
31873
- maxDecimals: number().int().min(0).max(4).default(1)
32050
+ maxDecimals: number().int().min(0).max(4).default(1),
32051
+ /** Raw value → display text (same shape as slot binding). Empty string hides. */
32052
+ valueMap: record(string(), string()).optional()
31874
32053
  });
31875
32054
  /**
31876
32055
  * A named template: bindings (alias → leaf field) + a parser that
@@ -31920,18 +32099,11 @@ var OsdSlotBindingSchema = object({
31920
32099
  source: OsdSourceSchema,
31921
32100
  /** `${value}` and `${unit}` are substituted; every occurrence. */
31922
32101
  template: string().max(96).default("${value}"),
31923
- /** Truncate with an ellipsis past this length. Absent = no limit. */
31924
- maxCharacters: number().int().min(4).max(64).optional(),
31925
32102
  /**
31926
32103
  * Decimal places for a numeric value. `0` yields an integer — the
31927
32104
  * documented workaround for firmwares that reject `.` in overlay text.
31928
32105
  */
31929
32106
  maxDecimals: number().int().min(0).max(4).default(1),
31930
- /**
31931
- * Appended via `${unit}` when no unit conversion produces a label.
31932
- * Prefer `source.displayUnit` for converted device-state values.
31933
- */
31934
- unitLabel: string().max(8).optional(),
31935
32107
  /** Raw value → display text, e.g. `{"true":"MOTION","false":""}`. */
31936
32108
  valueMap: record(string(), string()).optional(),
31937
32109
  /** Time windows in which the slot is shown. Absent = always. */
@@ -31940,9 +32112,7 @@ var OsdSlotBindingSchema = object({
31940
32112
  * Display gate, in the notification centre's condition vocabulary.
31941
32113
  * Only the keys reported by `getConditionSupport` are accepted.
31942
32114
  */
31943
- conditions: NcConditionsSchema.optional(),
31944
- /** Rendered when the gate is closed or the value unreadable. Empty = hide. */
31945
- fallbackText: string().max(64).default("")
32115
+ conditions: NcConditionsSchema.optional()
31946
32116
  });
31947
32117
  /** One camera slot, as the operator sees it: firmware truth + our binding. */
31948
32118
  var OsdSlotViewSchema = object({
@@ -39083,6 +39253,12 @@ Object.freeze({
39083
39253
  addonId: null,
39084
39254
  access: "view"
39085
39255
  },
39256
+ "localNetwork.getHubAddresses": {
39257
+ capName: "local-network",
39258
+ capScope: "system",
39259
+ addonId: null,
39260
+ access: "view"
39261
+ },
39086
39262
  "localNetwork.getNotificationEndpoint": {
39087
39263
  capName: "local-network",
39088
39264
  capScope: "system",
@@ -39137,6 +39313,12 @@ Object.freeze({
39137
39313
  addonId: null,
39138
39314
  access: "create"
39139
39315
  },
39316
+ "localNetwork.setHubAddress": {
39317
+ capName: "local-network",
39318
+ capScope: "system",
39319
+ addonId: null,
39320
+ access: "create"
39321
+ },
39140
39322
  "localNetwork.setNotificationEndpoint": {
39141
39323
  capName: "local-network",
39142
39324
  capScope: "system",
@@ -47536,6 +47718,8 @@ new Map(Object.entries({
47536
47718
  "detection-blind": "device-events",
47537
47719
  "node-online": "system",
47538
47720
  "node-offline": "system",
47721
+ "node-restarting": "system",
47722
+ "node-updating": "system",
47539
47723
  "node-inference-unavailable": "system",
47540
47724
  "addon-crash-loop": "system",
47541
47725
  "addon-update-available": "system",
@@ -47613,18 +47797,21 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
47613
47797
  kinds: [
47614
47798
  "node-offline",
47615
47799
  "node-online",
47800
+ "node-restarting",
47616
47801
  "node-inference-unavailable"
47617
47802
  ]
47618
47803
  },
47619
47804
  {
47620
47805
  id: "addons",
47621
47806
  family: "system",
47622
- label: "Addons",
47623
- kinds: [
47624
- "addon-crash-loop",
47625
- "addon-update-available",
47626
- "addon-updated"
47627
- ]
47807
+ label: "Addons stopped",
47808
+ kinds: ["addon-crash-loop"]
47809
+ },
47810
+ {
47811
+ id: "addon-updates",
47812
+ family: "system",
47813
+ label: "Addon updates",
47814
+ kinds: ["addon-update-available", "addon-updated"]
47628
47815
  },
47629
47816
  {
47630
47817
  id: "updates",
@@ -47632,6 +47819,7 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
47632
47819
  label: "Server & container updates",
47633
47820
  kinds: [
47634
47821
  "server-update-available",
47822
+ "node-updating",
47635
47823
  "server-updated",
47636
47824
  "wrapper-update-available"
47637
47825
  ]
@@ -47779,18 +47967,21 @@ var STATE_SUMMARY_SECTION_VARS = [
47779
47967
  kinds: [
47780
47968
  "node-offline",
47781
47969
  "node-online",
47970
+ "node-restarting",
47782
47971
  "node-inference-unavailable"
47783
47972
  ]
47784
47973
  },
47785
47974
  {
47786
47975
  name: "summaryAddons",
47787
- label: "Summary: addons",
47788
- example: "@camstack/addon-recorder 1.2.3 → 1.2.4",
47789
- kinds: [
47790
- "addon-crash-loop",
47791
- "addon-update-available",
47792
- "addon-updated"
47793
- ]
47976
+ label: "Summary: addons stopped",
47977
+ example: "hub — recorder stopped after repeated crashes",
47978
+ kinds: ["addon-crash-loop"]
47979
+ },
47980
+ {
47981
+ name: "summaryAddonUpdates",
47982
+ label: "Summary: addon updates",
47983
+ example: "hub:\n• @camstack/addon-recorder 1.2.3 → 1.2.4",
47984
+ kinds: ["addon-update-available", "addon-updated"]
47794
47985
  },
47795
47986
  {
47796
47987
  name: "summaryUpdates",
@@ -47798,6 +47989,7 @@ var STATE_SUMMARY_SECTION_VARS = [
47798
47989
  example: "server 1.2.377 → 1.2.378",
47799
47990
  kinds: [
47800
47991
  "server-update-available",
47992
+ "node-updating",
47801
47993
  "server-updated",
47802
47994
  "wrapper-update-available"
47803
47995
  ]
@@ -47830,7 +48022,7 @@ var STATE_SUMMARY_VARS = [
47830
48022
  {
47831
48023
  name: "summarySection",
47832
48024
  label: "Summary: this section",
47833
- description: "The section a per-section summary row is about (D698); on a summary sent as one message, every section it reports, comma-separated.",
48025
+ description: "The section a per-section summary row is about; on a summary sent as one message, every section it reports, comma-separated.",
47834
48026
  example: "Batterie scariche",
47835
48027
  group: "system",
47836
48028
  families: ["rule"],
@@ -47874,6 +48066,7 @@ var STATE_SUMMARY_VARS = [
47874
48066
  [...RULE_BODY_ONLY],
47875
48067
  [...RULE_TEXT],
47876
48068
  ([...RULE_TEXT], [...DEVICE_EVENTS]),
48069
+ ([...RULE_TEXT], [...COMBINED_ALARM]),
47877
48070
  ([...RULE_TEXT], [...DEVICE_EVENTS]),
47878
48071
  ([...RULE_TEXT], [...BATTERY, ...CONSUMABLE]),
47879
48072
  ([...RULE_TEXT], [...CONSUMABLE]),
@@ -47914,6 +48107,8 @@ var STATE_SUMMARY_VARS = [
47914
48107
  [...RULE_TEXT],
47915
48108
  [...RULE_TEXT],
47916
48109
  [...RULE_TEXT],
48110
+ [...RULE_TEXT],
48111
+ [...RULE_TEXT],
47917
48112
  ...STATE_SUMMARY_VARS
47918
48113
  ];
47919
48114
  new Set([
package/dist/smb.addon.js CHANGED
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_shared = require("./shared-D-2AWs6r.js");
5
+ const require_shared = require("./shared-DMfVszv1.js");
6
6
  let node_crypto = require("node:crypto");
7
7
  let node_path = require("node:path");
8
8
  node_path = require_shared.__toESM(node_path);
@@ -1,4 +1,4 @@
1
- import { c as BaseAddon, i as rearmIdleAbort, o as scheduleIdleAbort, s as storageProviderCapability } from "./shared-DI-61q1s.mjs";
1
+ import { c as BaseAddon, i as rearmIdleAbort, o as scheduleIdleAbort, s as storageProviderCapability } from "./shared-CwPb52BO.mjs";
2
2
  import { randomUUID } from "node:crypto";
3
3
  import * as path from "node:path";
4
4
  import * as fsp from "node:fs/promises";
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_shared = require("./shared-D-2AWs6r.js");
5
+ const require_shared = require("./shared-DMfVszv1.js");
6
6
  let node_stream = require("node:stream");
7
7
  let webdav = require("webdav");
8
8
  //#region src/providers/webdav/webdav-config-schema.ts