@camstack/addon-auth 1.2.126 → 1.2.128

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.
@@ -10577,6 +10577,15 @@ var ClipSearchStrictnessSchema = _enum([
10577
10577
  "balanced",
10578
10578
  "strict"
10579
10579
  ]);
10580
+ /** Steps whose effect a root label can BE. */
10581
+ var LABEL_SUPPLY_STEP_IDS = [
10582
+ "animal-classifier",
10583
+ "vehicle-classifier",
10584
+ "package-detection"
10585
+ ];
10586
+ /** Steps whose box a root detection can BE. */
10587
+ var CROP_SUPPLY_STEP_IDS = ["plate-detection", "face-detection"];
10588
+ [...LABEL_SUPPLY_STEP_IDS, ...CROP_SUPPLY_STEP_IDS];
10580
10589
  var MODEL_FORMATS = [
10581
10590
  "onnx",
10582
10591
  "coreml",
@@ -10646,11 +10655,11 @@ var ModelVariantGroupSchema = object({
10646
10655
  /** Quantization axis. Omit ⇒ the fp32 base build. */
10647
10656
  precision: _enum(["fp32", "int8"]).optional(),
10648
10657
  /**
10649
- * Speed-optimization axis. Omit ⇒ the standard build. `fast` marks a
10650
- * latency-optimized export (e.g. ReLU-activation variant) — the slot the
10651
- * future performance variants plug into.
10658
+ * Training / latency-variant axis. Omit ⇒ the standard build. `test` marks
10659
+ * an alternate training of the same family (Scrypted `relu_test`); chip
10660
+ * label is "Test".
10652
10661
  */
10653
- optimization: _enum(["standard", "fast"]).optional(),
10662
+ optimization: _enum(["standard", "test"]).optional(),
10654
10663
  /**
10655
10664
  * Input-resolution axis (square input side, px). Omit ⇒ the family's native
10656
10665
  * resolution (640 for yolo26). Reduced-input builds (320 / 256) are a big,
@@ -10673,9 +10682,10 @@ var ModelProviderIdSchema = _enum([
10673
10682
  * are per upstream. A persisted custom-model row written when this field was a
10674
10683
  * string still parses — the string is lifted into `{ weights }`.
10675
10684
  *
10676
- * Every licence surface (the admin "Models and licenses" page,
10677
- * `THIRD_PARTY_MODELS.md`, the Hugging Face model table) is GENERATED from
10678
- * these records by `scripts/gen-model-licenses.ts` (D661).
10685
+ * Every machine licence surface (`THIRD_PARTY_MODELS.md`, the Hugging Face
10686
+ * model table) is GENERATED from these records by
10687
+ * `scripts/gen-model-licenses.ts` (D661). Operator-facing docs live in
10688
+ * `camstack/docs` → `/docs/detection/models`.
10679
10689
  */
10680
10690
  var ModelLicenseSchema = preprocess((value) => typeof value === "string" ? { weights: value } : value, object({
10681
10691
  /** SPDX id of the WEIGHTS' terms, a `LicenseRef-*` for non-SPDX terms, or `UNKNOWN`. */
@@ -10708,6 +10718,35 @@ var ModelLicenseSchema = preprocess((value) => typeof value === "string" ? { wei
10708
10718
  /** True when the weights or their data forbid commercial use. */
10709
10719
  nonCommercial: boolean().optional()
10710
10720
  }));
10721
+ /**
10722
+ * One step a ROOT detector can supply from its own output (D730) — see
10723
+ * `ModelCatalogEntry.suppliesSteps`.
10724
+ *
10725
+ * - `label`: the root's raw class IS the step's answer. `labelToEffect` maps
10726
+ * the root's label to the step's vocabulary; `uncovered` is the vocabulary
10727
+ * the root cannot produce (shown as unavailable, never a blocker).
10728
+ * - `crop`: the root draws the box the step would have found (`license_plate`
10729
+ * for plate-detection, `face` for face-detection). The box becomes a detail
10730
+ * child of the `parentMacro` detection that contains it — never a track.
10731
+ */
10732
+ var RootStepSupplySchema = discriminatedUnion("kind", [object({
10733
+ kind: literal("label"),
10734
+ stepId: _enum(LABEL_SUPPLY_STEP_IDS),
10735
+ labelToEffect: record(string(), string()),
10736
+ uncovered: array(string()).readonly()
10737
+ }), object({
10738
+ kind: literal("crop"),
10739
+ stepId: _enum(CROP_SUPPLY_STEP_IDS),
10740
+ rootLabels: array(string()).readonly(),
10741
+ parentMacro: _enum(["vehicle", "person"]),
10742
+ childClass: _enum(["plate", "face"]),
10743
+ /**
10744
+ * The root's smaller input side, stamped on read by `rootSuppliesOf` from
10745
+ * the model entry — what a step's `minRootInputPx` gate judges. Never
10746
+ * stored by an import.
10747
+ */
10748
+ rootInputPx: number().int().positive().optional()
10749
+ })]);
10711
10750
  var ModelCatalogEntrySchema = object({
10712
10751
  id: string(),
10713
10752
  name: string(),
@@ -10834,6 +10873,16 @@ var ModelCatalogEntrySchema = object({
10834
10873
  */
10835
10874
  classMap: DetectionCatalogClassMapSchema.optional(),
10836
10875
  /**
10876
+ * The pipeline steps this ROOT detector can supply from its own output
10877
+ * (D730): its labels name a step's effect (`deer` for `animal-classifier`)
10878
+ * or draw a step's box (`license_plate` for `plate-detection`). Computed at
10879
+ * import from THIS model's labelmap by `deriveRootSupplies`, never written
10880
+ * by hand and never assumed per family; a row without it is derived on read
10881
+ * (`rootSuppliesOf`). Whether a camera uses it is the step's own
10882
+ * `useRootModel` flag (`resolveRootSupply`).
10883
+ */
10884
+ suppliesSteps: array(RootStepSupplySchema).readonly().optional(),
10885
+ /**
10837
10886
  * The model's CLIP feature-space contract (text encoder, dimension, vector
10838
10887
  * index, token window, search floor) — see `clip-model.ts`. Present ONLY on a
10839
10888
  * CLIP image encoder; its absence is what "not a CLIP model" means to the
@@ -14255,7 +14304,7 @@ DeviceType.Camera;
14255
14304
  * This matters here more than anywhere else in the repo, because every provider
14256
14305
  * that knows a device's host knows its PASSWORD too: `{ host, port, username,
14257
14306
  * password }` sit in one object on Hikvision, Amcrest, Reolink and ONVIF alike,
14258
- * and `http://admin:hunter2@192.168.x.x/` is a URL a browser accepts. The
14307
+ * and `http://admin:hunter2@192.168.60.139/` is a URL a browser accepts. The
14259
14308
  * camera's own page will ask for its own login. That is correct, and pre-
14260
14309
  * filling it is the operator's business, not ours.
14261
14310
  *
@@ -17247,7 +17296,7 @@ method(object({
17247
17296
  timeoutMs: 6e5
17248
17297
  });
17249
17298
  method(object({
17250
- nodeId: string(),
17299
+ targetNodeId: string(),
17251
17300
  modelId: string(),
17252
17301
  format: _enum(MODEL_FORMATS),
17253
17302
  entry: ModelCatalogEntrySchema
@@ -18615,6 +18664,8 @@ var NcSystemEventKindSchema = _enum([
18615
18664
  "stream-offline",
18616
18665
  "node-online",
18617
18666
  "node-offline",
18667
+ "node-restarting",
18668
+ "node-updating",
18618
18669
  "node-inference-unavailable",
18619
18670
  "detection-blind",
18620
18671
  "addon-crash-loop",
@@ -19713,8 +19764,9 @@ var NcRuleSchema = NcRuleInputSchema.extend({
19713
19764
  disabledTargetIds: array(string()).default([])
19714
19765
  });
19715
19766
  /**
19716
- * The state-summary SECTIONS (D647 / D698): the D637 kind groups that report a
19717
- * still-true state. `backups-exports` and `alarm` are not sections — a completed
19767
+ * The state-summary SECTIONS (D647 / D698 / D708): the D637 kind groups that
19768
+ * report a still-true state. `addons` is the crash-looped addons only and
19769
+ * `addon-updates` the addons that are behind (D708 split them). `backups-exports` and `alarm` are not sections — a completed
19718
19770
  * job is not an open state, and the alarm stays instant.
19719
19771
  */
19720
19772
  var NcStateSummarySectionIdSchema = _enum([
@@ -19726,6 +19778,7 @@ var NcStateSummarySectionIdSchema = _enum([
19726
19778
  "detection-blind",
19727
19779
  "nodes",
19728
19780
  "addons",
19781
+ "addon-updates",
19729
19782
  "updates"
19730
19783
  ]);
19731
19784
  /** One section of a previewed state summary. `unavailable` = its state could not be read. */
@@ -20206,7 +20259,19 @@ var NcAlarmModeDelaysListSchema = array(object({
20206
20259
  * When this mode may be armed. Absent / null = always allowed (same as a
20207
20260
  * rule with no `schedule`). Evaluated with {@link isScheduleActive}.
20208
20261
  */
20209
- schedule: NcScheduleSchema.optional()
20262
+ schedule: NcScheduleSchema.optional(),
20263
+ /**
20264
+ * D706: while this mode's ENTRY DELAY runs, do the alarm rules' own pushes go out (as an
20265
+ * intrusion naming the locations)? Absent = false — the entry-delay notification is the
20266
+ * only one, and the matches ride the triggered notification's mosaic (D705).
20267
+ */
20268
+ notifyDuringEntryDelay: boolean().optional(),
20269
+ /**
20270
+ * D706: notify "watched again" when a sensor this arm bypassed closes and opens again.
20271
+ * Absent = false (logged, not sent). Even when true it is not sent when that same sensor
20272
+ * is the one that starts the entry delay — the entry-delay notification already names it.
20273
+ */
20274
+ notifySensorRewatched: boolean().optional()
20210
20275
  })).max(8).refine(uniqueModes, { message: "modeDelays: at most one entry per arm mode" });
20211
20276
  var NcAlarmModeDelaysEditListSchema = array(object({
20212
20277
  mode: AlarmArmModeSchema,
@@ -20215,7 +20280,11 @@ var NcAlarmModeDelaysEditListSchema = array(object({
20215
20280
  triggeredDurationSec: NcAlarmTriggeredSecSchema.nullable().optional(),
20216
20281
  postTriggeredAction: NcAlarmPostTriggeredActionSchema.nullable().optional(),
20217
20282
  /** Set a schedule, or `null` to clear (mode always allowed again). */
20218
- schedule: NcScheduleSchema.nullable().optional()
20283
+ schedule: NcScheduleSchema.nullable().optional(),
20284
+ /** D706: set the switch, or `null` to clear it (back to the default, false). */
20285
+ notifyDuringEntryDelay: boolean().nullable().optional(),
20286
+ /** D706: set the switch, or `null` to clear it (back to the default, false). */
20287
+ notifySensorRewatched: boolean().nullable().optional()
20219
20288
  })).max(8).refine(uniqueModes, { message: "modeDelays: at most one edit per arm mode" });
20220
20289
  /** One switch of the alarm table: put ONE device on, or take it off, ONE mode's list. */
20221
20290
  var NcAlarmNonBlockingEditSchema = object({
@@ -21176,39 +21245,19 @@ Object.freeze(Object.fromEntries([{
21176
21245
  label: "Face recognition model",
21177
21246
  defaultModelId: "auraface-r100",
21178
21247
  indexName: "the enrolled face gallery",
21179
- options: [
21180
- {
21181
- id: "auraface-r100",
21182
- label: "AuraFace R100"
21183
- },
21184
- {
21185
- id: "arcface-r100",
21186
- label: "ArcFace (ResNet34)"
21187
- },
21188
- {
21189
- id: "inception-resnet-v1",
21190
- label: "Inception ResNet V1"
21191
- }
21192
- ]
21248
+ options: [{
21249
+ id: "auraface-r100",
21250
+ label: "AuraFace R100"
21251
+ }]
21193
21252
  }, {
21194
21253
  stepId: "clip-embedding",
21195
21254
  label: "Semantic search model",
21196
- defaultModelId: "mobileclip-s1",
21255
+ defaultModelId: "siglip2-b16-224",
21197
21256
  indexName: "the object semantic-search index",
21198
- options: [
21199
- {
21200
- id: "mobileclip-s1",
21201
- label: "MobileCLIP S1"
21202
- },
21203
- {
21204
- id: "mobileclip-s2",
21205
- label: "MobileCLIP S2"
21206
- },
21207
- {
21208
- id: "siglip2-b16-224",
21209
- label: "SigLIP2 B/16 (Apache-2.0)"
21210
- }
21211
- ]
21257
+ options: [{
21258
+ id: "siglip2-b16-224",
21259
+ label: "SigLIP2 B/16 (Apache-2.0)"
21260
+ }]
21212
21261
  }].map((s) => [s.stepId, s.defaultModelId])));
21213
21262
  var CLUSTER_STEP_SETTING_FIELDS = [{
21214
21263
  stepId: "face-embedding",
@@ -23134,6 +23183,34 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
23134
23183
  timestamp: number()
23135
23184
  });
23136
23185
  /**
23186
+ * A root model's boxes standing in for one crop-kind step's own inference
23187
+ * (D730) — see `runPipeline.suppliedRoot`.
23188
+ */
23189
+ var SuppliedRootOutputSchema = object({
23190
+ stepId: string(),
23191
+ /** The root model that drew the boxes — stamped on the result. */
23192
+ modelId: string(),
23193
+ detections: array(object({
23194
+ /** `[x1, y1, x2, y2]` in the pixels of the call's image. */
23195
+ bbox: tuple([
23196
+ number(),
23197
+ number(),
23198
+ number(),
23199
+ number()
23200
+ ]),
23201
+ score: number(),
23202
+ /**
23203
+ * Five facial landmarks in the same pixels — a face the step's own
23204
+ * detector already re-found inside a root face box (D730), so its
23205
+ * embedder child aligns it exactly as it aligns any detected face.
23206
+ */
23207
+ landmarks: array(object({
23208
+ x: number(),
23209
+ y: number()
23210
+ })).optional()
23211
+ })).min(1)
23212
+ });
23213
+ /**
23137
23214
  * Reference to the frame's retained NATIVE surface + the parent crop's placement
23138
23215
  * within the frame, so the executor can re-cut a leaf child ROI at native
23139
23216
  * resolution on the detail plane. See the `runPipeline` `nativeCropRef` field.
@@ -23263,7 +23340,8 @@ var PipelineModelOptionSchema = object({
23263
23340
  group: ModelVariantGroupSchema.optional(),
23264
23341
  legacy: boolean().optional(),
23265
23342
  provider: ModelProviderIdSchema.optional(),
23266
- defaultConfidence: number().optional()
23343
+ defaultConfidence: number().optional(),
23344
+ suppliesSteps: array(RootStepSupplySchema).readonly().optional()
23267
23345
  });
23268
23346
  var ConfigFieldBridge = custom();
23269
23347
  var PipelineAddonSchemaSchema = object({
@@ -23531,7 +23609,16 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
23531
23609
  * `device-not-servable`), and nothing reaches the camera's live
23532
23610
  * trace stream. Absent ⇒ unchanged behaviour.
23533
23611
  */
23534
- replay: literal(true).optional()
23612
+ replay: literal(true).optional(),
23613
+ /**
23614
+ * Root-supplied detections for the tree's ROOT step (D730). Set by
23615
+ * `runDetailSubtree` when the camera's root model supplies a crop-kind
23616
+ * step (a Frigate+ `license_plate` for `plate-detection`): the step is
23617
+ * NOT inferred, these boxes are its output, and its children (the plate
23618
+ * reader) run on them through their own crop policy. Boxes are in the
23619
+ * PIXELS of the image this call carries. Absent ⇒ the root step runs.
23620
+ */
23621
+ suppliedRoot: SuppliedRootOutputSchema.optional()
23535
23622
  }), PipelineRunResultBridge, { kind: "mutation" }), method(object({
23536
23623
  steps: array(PipelineStepInputSchema).min(1),
23537
23624
  frames: array(FrameInputSchema).min(1).max(255),
@@ -24056,6 +24143,22 @@ var MotionSourceEnum = _enum([
24056
24143
  "device-activity"
24057
24144
  ]);
24058
24145
  /**
24146
+ * What opened an on-motion detection SESSION: the motion source that passed the
24147
+ * camera's `motionSources` gate, and what raised it (the camera itself, or a
24148
+ * sensor the operator attached — D672). `sensorName` is the attached sensor's
24149
+ * device name as the orchestrator's camera-sensors resolution last read it;
24150
+ * absent when unknown or when the camera itself triggered.
24151
+ *
24152
+ * Carried on the session attach ONLY so the runner's `DetectionPhaseTransition`
24153
+ * can say what started the session (D672 rule 11, amended 2026-10-06). The
24154
+ * runner never decides anything on it.
24155
+ */
24156
+ var SessionTriggerSchema = object({
24157
+ source: MotionSourceEnum,
24158
+ triggeredBy: MotionTriggeredBySchema,
24159
+ sensorName: string().optional()
24160
+ });
24161
+ /**
24059
24162
  * List of motion sources active on a camera. Empty array is valid:
24060
24163
  * "no source" — happens for battery cams without firmware motion when
24061
24164
  * the operator hasn't opted into the SW analyzer (would hold the
@@ -24307,6 +24410,14 @@ var RunnerCameraConfigSchema = object({
24307
24410
  */
24308
24411
  motionSources: MotionSourcesSchema.default(["analyzer"]),
24309
24412
  /**
24413
+ * What opened this attach, on a SESSION attach only (see
24414
+ * {@link SessionTriggerSchema}). OPTIONAL with no default: absent on a
24415
+ * standing attach, an occupancy burst, a re-dispatch with no motion event
24416
+ * behind it, and every attach from an orchestrator older than the field — the
24417
+ * runner then names no source on the phase event.
24418
+ */
24419
+ sessionTrigger: SessionTriggerSchema.optional(),
24420
+ /**
24310
24421
  * WHICH root detector runs for this camera. The detection counterpart of
24311
24422
  * {@link motionSources}, same shape and same discipline: a per-camera list
24312
24423
  * of sources the system understands, vendor-agnostic, owned here.
@@ -24609,7 +24720,22 @@ method(RunnerCameraConfigSchema, object({ success: literal(true) }), { kind: "mu
24609
24720
  */
24610
24721
  cropJpeg: string().optional(),
24611
24722
  parent: DetailParentSchema,
24612
- steps: array(string()).optional()
24723
+ steps: array(string()).optional(),
24724
+ /**
24725
+ * The camera's root model already drew this step's boxes (D730): a
24726
+ * `license_plate` inside the parent vehicle. The named step is NOT
24727
+ * inferred — these FRAME-space boxes are its output — and its
24728
+ * requested children (the plate reader) run on them. Absent ⇒ every
24729
+ * requested step infers as before.
24730
+ */
24731
+ supplied: object({
24732
+ stepId: string(),
24733
+ modelId: string(),
24734
+ boxes: array(object({
24735
+ bbox: NativeCropBboxSchema,
24736
+ score: number()
24737
+ })).min(1)
24738
+ }).optional()
24613
24739
  }), object({ details: array(DetailResultSchema) }).nullable(), { kind: "mutation" }), method(object({
24614
24740
  /** Catalog step id, e.g. `clip-embedding`. */
24615
24741
  stepId: string(),
@@ -30565,7 +30691,7 @@ var LocalInterfaceSchema = object({
30565
30691
  name: string(),
30566
30692
  family: _enum(["IPv4", "IPv6"]),
30567
30693
  address: string(),
30568
- /** CIDR shorthand (e.g. `192.168.x.x/24`). Empty when OS doesn't expose. */
30694
+ /** CIDR shorthand (e.g. `192.168.10.10/24`). Empty when OS doesn't expose. */
30569
30695
  cidr: string(),
30570
30696
  /** OS netmask. Stable across calls so the SDK can hash on it. */
30571
30697
  netmask: string(),
@@ -30619,7 +30745,8 @@ var ConnectionEndpointSchema = object({
30619
30745
  "lan-ipv4",
30620
30746
  "lan-ipv6",
30621
30747
  "public",
30622
- "loopback"
30748
+ "loopback",
30749
+ "app-link"
30623
30750
  ]),
30624
30751
  /**
30625
30752
  * Originating-interface kind — `lan`/`wifi`/`docker`/`vpn`/`other`/
@@ -30688,15 +30815,27 @@ var GetConnectionEndpointsResultSchema = object({
30688
30815
  localPort: AdvertisedLocalPortSchema
30689
30816
  });
30690
30817
  /**
30691
- * The chosen outbound endpoint for notification artifacts. `baseUrl: null` =
30692
- * AUTO (resolved from the candidate ranking at send time); `resolved` reports
30693
- * what AUTO currently picks, so the UI can show the effective value either way.
30818
+ * The address flagged for notification links. `baseUrl: null` = AUTO, which
30819
+ * since D709 is the CamStack app link; `resolved` reports the effective value,
30820
+ * so the UI can show it either way.
30694
30821
  */
30695
30822
  var NotificationEndpointSchema = object({
30696
30823
  /** The operator's explicit choice, or null for AUTO. */
30697
30824
  baseUrl: string().nullable(),
30698
- /** What the ranking currently resolves to (null when nothing is reachable). */
30699
- resolved: string().nullable()
30825
+ /**
30826
+ * The effective flagged address: the explicit choice, else (AUTO) the
30827
+ * CamStack app link `https://camstack.zentik.app` (D709). A pre-D709 hub
30828
+ * answered the public tunnel / mesh here, or null.
30829
+ */
30830
+ resolved: string().nullable(),
30831
+ /**
30832
+ * The hub origin an app link carries as `hub=` (D709): the hub's best
30833
+ * public HTTPS address — the tunnel, then the mesh (Tailscale MagicDNS) —
30834
+ * picked from this cap's own palette by `pickAppLinkHub`. `null` when the
30835
+ * hub advertises neither; the app link is then minted without `hub=`.
30836
+ * Absent on a pre-D709 hub.
30837
+ */
30838
+ appLinkHub: string().nullable()
30700
30839
  });
30701
30840
  /**
30702
30841
  * The URLs the SDK / viewer should race for API access. `baseUrls` empty =
@@ -30709,6 +30848,27 @@ var ViewerEndpointsSchema = object({
30709
30848
  /** What the ranking currently resolves to (may be empty if nothing is up). */
30710
30849
  resolved: array(string()).readonly()
30711
30850
  });
30851
+ /**
30852
+ * One audience's hub address (see `hub-address.ts`): the operator's stored
30853
+ * override, the address in use, and where it came from.
30854
+ */
30855
+ var HubAddressSnapshotSchema = object({
30856
+ /** The operator's override, or null for automatic. */
30857
+ override: string().nullable(),
30858
+ /** The address in use, or null when nothing qualifies (never loopback). */
30859
+ resolved: string().nullable(),
30860
+ source: _enum([
30861
+ "override",
30862
+ "auto",
30863
+ "none"
30864
+ ])
30865
+ });
30866
+ var HubAddressesSchema = object({
30867
+ /** "Hub address for agents" — agents' bundle/model pulls, LAN devices. */
30868
+ cluster: HubAddressSnapshotSchema,
30869
+ /** "Public address for sign-in links" — e-mail links, OIDC, WebAuthn, OAuth2. */
30870
+ browser: HubAddressSnapshotSchema
30871
+ });
30712
30872
  var AllowedAddressesSchema = object({
30713
30873
  /**
30714
30874
  * Allowlist of interface addresses operators have explicitly opted
@@ -30750,8 +30910,18 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
30750
30910
  * Pass `'https'` when the caller is itself loaded over HTTPS
30751
30911
  * to avoid mixed-content blocks in the browser. The public
30752
30912
  * tunnel always emits `https://` regardless. */
30753
- scheme: _enum(["http", "https"]).optional()
30754
- }), 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, {
30913
+ scheme: _enum(["http", "https"]).optional(),
30914
+ /** Append the CamStack app link entry (`kind: 'app-link'`, D709) —
30915
+ * an address notification links can be flagged with, not a hub
30916
+ * route. Default `false`: racers and rankers never see it. */
30917
+ includeAppLink: boolean().optional()
30918
+ }), 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({
30919
+ audience: _enum(["cluster", "browser"]),
30920
+ baseUrl: string().nullable()
30921
+ }), HubAddressesSchema, {
30922
+ kind: "mutation",
30923
+ auth: "admin"
30924
+ }), 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, {
30755
30925
  kind: "mutation",
30756
30926
  auth: "admin"
30757
30927
  }), method(object({
@@ -31011,7 +31181,7 @@ var MeshPeerSchema = object({
31011
31181
  tags: array(string()).readonly(),
31012
31182
  /** True when the peer advertises itself as an exit-node candidate. */
31013
31183
  exitNodeOption: boolean(),
31014
- /** Subnet routes the peer advertises (e.g. `["192.168.x.x/24"]`). */
31184
+ /** Subnet routes the peer advertises (e.g. `["192.168.10.0/24"]`). */
31015
31185
  advertisedRoutes: array(string()).readonly(),
31016
31186
  /** Owner account login (e.g. `foo@example.com`). Null for tagged peers. */
31017
31187
  userLogin: string().nullable(),
@@ -31141,7 +31311,8 @@ object({
31141
31311
  * writes this slice (not even a boot seed), and neither does the runner's
31142
31312
  * phase machine: its phase is "a session is attached" for every on-motion
31143
31313
  * session, not motion, and it now has its own `DetectionPhaseTransition`.
31144
- * A provider's `isDetected` answers from the hub's slice.
31314
+ * A provider's `isDetected` and `getStatus` answer from the hub's slice
31315
+ * (`hubMotionNativeProvider`).
31145
31316
  * - **Sensors** (Home Assistant binary sensors, Homematic, Matter, Alexa
31146
31317
  * imports) — the provider pushes both edges itself, from the upstream
31147
31318
  * system's own state change. That is the sensor's own fact.
@@ -31955,7 +32126,13 @@ var OsdStatusSchema = object({ overlays: array(object({
31955
32126
  */
31956
32127
  availablePositions: array(OsdPositionEnum).readonly(),
31957
32128
  /** Firmware does not allow editing the `text` field (e.g. timestamp). */
31958
- readOnly: boolean().optional()
32129
+ readOnly: boolean().optional(),
32130
+ /**
32131
+ * Firmware text ceiling for this overlay. Absent = no known limit.
32132
+ * The OSD manager truncates here on every write — never stores its own
32133
+ * copy on the binding.
32134
+ */
32135
+ maxCharacters: number().int().positive().optional()
31959
32136
  })).readonly() });
31960
32137
  var OsdOverlayPatchSchema = object({
31961
32138
  enabled: boolean().optional(),
@@ -32006,7 +32183,9 @@ var OsdTemplateBindingSchema = object({
32006
32183
  valuePath: string().min(1).max(64),
32007
32184
  /** Convert TO this unit at render (`tryConvertUnit`). Absent = source unit. */
32008
32185
  displayUnit: string().max(16).optional(),
32009
- maxDecimals: number().int().min(0).max(4).default(1)
32186
+ maxDecimals: number().int().min(0).max(4).default(1),
32187
+ /** Raw value → display text (same shape as slot binding). Empty string hides. */
32188
+ valueMap: record(string(), string()).optional()
32010
32189
  });
32011
32190
  /**
32012
32191
  * A named template: bindings (alias → leaf field) + a parser that
@@ -32056,18 +32235,11 @@ var OsdSlotBindingSchema = object({
32056
32235
  source: OsdSourceSchema,
32057
32236
  /** `${value}` and `${unit}` are substituted; every occurrence. */
32058
32237
  template: string().max(96).default("${value}"),
32059
- /** Truncate with an ellipsis past this length. Absent = no limit. */
32060
- maxCharacters: number().int().min(4).max(64).optional(),
32061
32238
  /**
32062
32239
  * Decimal places for a numeric value. `0` yields an integer — the
32063
32240
  * documented workaround for firmwares that reject `.` in overlay text.
32064
32241
  */
32065
32242
  maxDecimals: number().int().min(0).max(4).default(1),
32066
- /**
32067
- * Appended via `${unit}` when no unit conversion produces a label.
32068
- * Prefer `source.displayUnit` for converted device-state values.
32069
- */
32070
- unitLabel: string().max(8).optional(),
32071
32243
  /** Raw value → display text, e.g. `{"true":"MOTION","false":""}`. */
32072
32244
  valueMap: record(string(), string()).optional(),
32073
32245
  /** Time windows in which the slot is shown. Absent = always. */
@@ -32076,9 +32248,7 @@ var OsdSlotBindingSchema = object({
32076
32248
  * Display gate, in the notification centre's condition vocabulary.
32077
32249
  * Only the keys reported by `getConditionSupport` are accepted.
32078
32250
  */
32079
- conditions: NcConditionsSchema.optional(),
32080
- /** Rendered when the gate is closed or the value unreadable. Empty = hide. */
32081
- fallbackText: string().max(64).default("")
32251
+ conditions: NcConditionsSchema.optional()
32082
32252
  });
32083
32253
  /** One camera slot, as the operator sees it: firmware truth + our binding. */
32084
32254
  var OsdSlotViewSchema = object({
@@ -39219,6 +39389,12 @@ Object.freeze({
39219
39389
  addonId: null,
39220
39390
  access: "view"
39221
39391
  },
39392
+ "localNetwork.getHubAddresses": {
39393
+ capName: "local-network",
39394
+ capScope: "system",
39395
+ addonId: null,
39396
+ access: "view"
39397
+ },
39222
39398
  "localNetwork.getNotificationEndpoint": {
39223
39399
  capName: "local-network",
39224
39400
  capScope: "system",
@@ -39273,6 +39449,12 @@ Object.freeze({
39273
39449
  addonId: null,
39274
39450
  access: "create"
39275
39451
  },
39452
+ "localNetwork.setHubAddress": {
39453
+ capName: "local-network",
39454
+ capScope: "system",
39455
+ addonId: null,
39456
+ access: "create"
39457
+ },
39276
39458
  "localNetwork.setNotificationEndpoint": {
39277
39459
  capName: "local-network",
39278
39460
  capScope: "system",
@@ -47672,6 +47854,8 @@ new Map(Object.entries({
47672
47854
  "detection-blind": "device-events",
47673
47855
  "node-online": "system",
47674
47856
  "node-offline": "system",
47857
+ "node-restarting": "system",
47858
+ "node-updating": "system",
47675
47859
  "node-inference-unavailable": "system",
47676
47860
  "addon-crash-loop": "system",
47677
47861
  "addon-update-available": "system",
@@ -47749,18 +47933,21 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
47749
47933
  kinds: [
47750
47934
  "node-offline",
47751
47935
  "node-online",
47936
+ "node-restarting",
47752
47937
  "node-inference-unavailable"
47753
47938
  ]
47754
47939
  },
47755
47940
  {
47756
47941
  id: "addons",
47757
47942
  family: "system",
47758
- label: "Addons",
47759
- kinds: [
47760
- "addon-crash-loop",
47761
- "addon-update-available",
47762
- "addon-updated"
47763
- ]
47943
+ label: "Addons stopped",
47944
+ kinds: ["addon-crash-loop"]
47945
+ },
47946
+ {
47947
+ id: "addon-updates",
47948
+ family: "system",
47949
+ label: "Addon updates",
47950
+ kinds: ["addon-update-available", "addon-updated"]
47764
47951
  },
47765
47952
  {
47766
47953
  id: "updates",
@@ -47768,6 +47955,7 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
47768
47955
  label: "Server & container updates",
47769
47956
  kinds: [
47770
47957
  "server-update-available",
47958
+ "node-updating",
47771
47959
  "server-updated",
47772
47960
  "wrapper-update-available"
47773
47961
  ]
@@ -47915,18 +48103,21 @@ var STATE_SUMMARY_SECTION_VARS = [
47915
48103
  kinds: [
47916
48104
  "node-offline",
47917
48105
  "node-online",
48106
+ "node-restarting",
47918
48107
  "node-inference-unavailable"
47919
48108
  ]
47920
48109
  },
47921
48110
  {
47922
48111
  name: "summaryAddons",
47923
- label: "Summary: addons",
47924
- example: "@camstack/addon-recorder 1.2.3 → 1.2.4",
47925
- kinds: [
47926
- "addon-crash-loop",
47927
- "addon-update-available",
47928
- "addon-updated"
47929
- ]
48112
+ label: "Summary: addons stopped",
48113
+ example: "hub — recorder stopped after repeated crashes",
48114
+ kinds: ["addon-crash-loop"]
48115
+ },
48116
+ {
48117
+ name: "summaryAddonUpdates",
48118
+ label: "Summary: addon updates",
48119
+ example: "hub:\n• @camstack/addon-recorder 1.2.3 → 1.2.4",
48120
+ kinds: ["addon-update-available", "addon-updated"]
47930
48121
  },
47931
48122
  {
47932
48123
  name: "summaryUpdates",
@@ -47934,6 +48125,7 @@ var STATE_SUMMARY_SECTION_VARS = [
47934
48125
  example: "server 1.2.377 → 1.2.378",
47935
48126
  kinds: [
47936
48127
  "server-update-available",
48128
+ "node-updating",
47937
48129
  "server-updated",
47938
48130
  "wrapper-update-available"
47939
48131
  ]
@@ -47966,7 +48158,7 @@ var STATE_SUMMARY_VARS = [
47966
48158
  {
47967
48159
  name: "summarySection",
47968
48160
  label: "Summary: this section",
47969
- description: "The section a per-section summary row is about (D698); on a summary sent as one message, every section it reports, comma-separated.",
48161
+ description: "The section a per-section summary row is about; on a summary sent as one message, every section it reports, comma-separated.",
47970
48162
  example: "Batterie scariche",
47971
48163
  group: "system",
47972
48164
  families: ["rule"],
@@ -48010,6 +48202,7 @@ var STATE_SUMMARY_VARS = [
48010
48202
  [...RULE_BODY_ONLY],
48011
48203
  [...RULE_TEXT],
48012
48204
  ([...RULE_TEXT], [...DEVICE_EVENTS]),
48205
+ ([...RULE_TEXT], [...COMBINED_ALARM]),
48013
48206
  ([...RULE_TEXT], [...DEVICE_EVENTS]),
48014
48207
  ([...RULE_TEXT], [...BATTERY, ...CONSUMABLE]),
48015
48208
  ([...RULE_TEXT], [...CONSUMABLE]),
@@ -48050,6 +48243,8 @@ var STATE_SUMMARY_VARS = [
48050
48243
  [...RULE_TEXT],
48051
48244
  [...RULE_TEXT],
48052
48245
  [...RULE_TEXT],
48246
+ [...RULE_TEXT],
48247
+ [...RULE_TEXT],
48053
48248
  ...STATE_SUMMARY_VARS
48054
48249
  ];
48055
48250
  new Set([
@@ -48570,4 +48765,14 @@ DEFAULT_NATIVE_LEASE_SETTINGS.admission;
48570
48765
  var MB = 1024 * 1024;
48571
48766
  1024 * MB, 3072 * MB;
48572
48767
  //#endregion
48573
- export { loginMethodCapability as a, BaseAddon as c, number as d, object as f, buildAddonRouteProvider as i, array as l, addonWidgetsSourceCapability as n, userPasskeysCapability as o, string as p, authProviderCapability as r, errMsg as s, addonRoutesCapability as t, boolean as u };
48768
+ //#region src/hub-browser-origin.ts
48769
+ async function hubBrowserOrigin(localNetwork, logger) {
48770
+ try {
48771
+ return (await localNetwork.getHubAddresses.query()).browser.resolved;
48772
+ } catch (err) {
48773
+ logger.warn("hub address unavailable from local-network — using the localhost default", { meta: { error: err instanceof Error ? err.message : String(err) } });
48774
+ return null;
48775
+ }
48776
+ }
48777
+ //#endregion
48778
+ export { buildAddonRouteProvider as a, errMsg as c, boolean as d, number as f, authProviderCapability as i, BaseAddon as l, string as m, addonRoutesCapability as n, loginMethodCapability as o, object as p, addonWidgetsSourceCapability as r, userPasskeysCapability as s, hubBrowserOrigin as t, array as u };