@camstack/types 1.2.304 → 1.2.306

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.
@@ -204,6 +204,15 @@ declare const PipelineModelOptionSchema: z.ZodObject<{
204
204
  scrypted: "scrypted";
205
205
  }>>;
206
206
  defaultConfidence: z.ZodOptional<z.ZodNumber>;
207
+ fillsClassifierEffects: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodObject<{
208
+ stepId: z.ZodEnum<{
209
+ "animal-classifier": "animal-classifier";
210
+ "vehicle-classifier": "vehicle-classifier";
211
+ "package-detection": "package-detection";
212
+ }>;
213
+ labelToEffect: z.ZodRecord<z.ZodString, z.ZodString>;
214
+ uncovered: z.ZodReadonly<z.ZodArray<z.ZodString>>;
215
+ }, z.core.$strip>>>>;
207
216
  }, z.core.$strip>;
208
217
  declare const PipelineAddonSchemaSchema: z.ZodObject<{
209
218
  id: z.ZodString;
@@ -252,6 +261,15 @@ declare const PipelineAddonSchemaSchema: z.ZodObject<{
252
261
  scrypted: "scrypted";
253
262
  }>>;
254
263
  defaultConfidence: z.ZodOptional<z.ZodNumber>;
264
+ fillsClassifierEffects: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodObject<{
265
+ stepId: z.ZodEnum<{
266
+ "animal-classifier": "animal-classifier";
267
+ "vehicle-classifier": "vehicle-classifier";
268
+ "package-detection": "package-detection";
269
+ }>;
270
+ labelToEffect: z.ZodRecord<z.ZodString, z.ZodString>;
271
+ uncovered: z.ZodReadonly<z.ZodArray<z.ZodString>>;
272
+ }, z.core.$strip>>>>;
255
273
  }, z.core.$strip>>>;
256
274
  defaultModelId: z.ZodString;
257
275
  defaultModelIdByFormat: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
@@ -325,6 +343,15 @@ declare const PipelineSlotSchemaSchema: z.ZodObject<{
325
343
  scrypted: "scrypted";
326
344
  }>>;
327
345
  defaultConfidence: z.ZodOptional<z.ZodNumber>;
346
+ fillsClassifierEffects: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodObject<{
347
+ stepId: z.ZodEnum<{
348
+ "animal-classifier": "animal-classifier";
349
+ "vehicle-classifier": "vehicle-classifier";
350
+ "package-detection": "package-detection";
351
+ }>;
352
+ labelToEffect: z.ZodRecord<z.ZodString, z.ZodString>;
353
+ uncovered: z.ZodReadonly<z.ZodArray<z.ZodString>>;
354
+ }, z.core.$strip>>>>;
328
355
  }, z.core.$strip>>>;
329
356
  defaultModelId: z.ZodString;
330
357
  defaultModelIdByFormat: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
@@ -434,6 +461,15 @@ declare const PipelineSchemaSchema: z.ZodObject<{
434
461
  scrypted: "scrypted";
435
462
  }>>;
436
463
  defaultConfidence: z.ZodOptional<z.ZodNumber>;
464
+ fillsClassifierEffects: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodObject<{
465
+ stepId: z.ZodEnum<{
466
+ "animal-classifier": "animal-classifier";
467
+ "vehicle-classifier": "vehicle-classifier";
468
+ "package-detection": "package-detection";
469
+ }>;
470
+ labelToEffect: z.ZodRecord<z.ZodString, z.ZodString>;
471
+ uncovered: z.ZodReadonly<z.ZodArray<z.ZodString>>;
472
+ }, z.core.$strip>>>>;
437
473
  }, z.core.$strip>>>;
438
474
  defaultModelId: z.ZodString;
439
475
  defaultModelIdByFormat: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
@@ -789,6 +825,15 @@ export declare const pipelineExecutorCapability: {
789
825
  scrypted: "scrypted";
790
826
  }>>;
791
827
  defaultConfidence: z.ZodOptional<z.ZodNumber>;
828
+ fillsClassifierEffects: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodObject<{
829
+ stepId: z.ZodEnum<{
830
+ "animal-classifier": "animal-classifier";
831
+ "vehicle-classifier": "vehicle-classifier";
832
+ "package-detection": "package-detection";
833
+ }>;
834
+ labelToEffect: z.ZodRecord<z.ZodString, z.ZodString>;
835
+ uncovered: z.ZodReadonly<z.ZodArray<z.ZodString>>;
836
+ }, z.core.$strip>>>>;
792
837
  }, z.core.$strip>>>;
793
838
  defaultModelId: z.ZodString;
794
839
  defaultModelIdByFormat: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
@@ -180,6 +180,32 @@ export declare const MotionSourceEnum: z.ZodEnum<{
180
180
  "device-activity": "device-activity";
181
181
  }>;
182
182
  export type MotionSource = z.infer<typeof MotionSourceEnum>;
183
+ /**
184
+ * What opened an on-motion detection SESSION: the motion source that passed the
185
+ * camera's `motionSources` gate, and what raised it (the camera itself, or a
186
+ * sensor the operator attached — D672). `sensorName` is the attached sensor's
187
+ * device name as the orchestrator's camera-sensors resolution last read it;
188
+ * absent when unknown or when the camera itself triggered.
189
+ *
190
+ * Carried on the session attach ONLY so the runner's `DetectionPhaseTransition`
191
+ * can say what started the session (D672 rule 11, amended 2026-10-06). The
192
+ * runner never decides anything on it.
193
+ */
194
+ export declare const SessionTriggerSchema: z.ZodObject<{
195
+ source: z.ZodEnum<{
196
+ onboard: "onboard";
197
+ analyzer: "analyzer";
198
+ "device-activity": "device-activity";
199
+ }>;
200
+ triggeredBy: z.ZodDiscriminatedUnion<[z.ZodObject<{
201
+ kind: z.ZodLiteral<"camera">;
202
+ }, z.core.$strip>, z.ZodObject<{
203
+ kind: z.ZodLiteral<"sensor">;
204
+ deviceId: z.ZodNumber;
205
+ }, z.core.$strip>], "kind">;
206
+ sensorName: z.ZodOptional<z.ZodString>;
207
+ }, z.core.$strip>;
208
+ export type SessionTrigger = z.infer<typeof SessionTriggerSchema>;
183
209
  /**
184
210
  * List of motion sources active on a camera. Empty array is valid:
185
211
  * "no source" — happens for battery cams without firmware motion when
@@ -371,6 +397,20 @@ declare const RunnerCameraConfigSchema: z.ZodObject<{
371
397
  analyzer: "analyzer";
372
398
  "device-activity": "device-activity";
373
399
  }>>>;
400
+ sessionTrigger: z.ZodOptional<z.ZodObject<{
401
+ source: z.ZodEnum<{
402
+ onboard: "onboard";
403
+ analyzer: "analyzer";
404
+ "device-activity": "device-activity";
405
+ }>;
406
+ triggeredBy: z.ZodDiscriminatedUnion<[z.ZodObject<{
407
+ kind: z.ZodLiteral<"camera">;
408
+ }, z.core.$strip>, z.ZodObject<{
409
+ kind: z.ZodLiteral<"sensor">;
410
+ deviceId: z.ZodNumber;
411
+ }, z.core.$strip>], "kind">;
412
+ sensorName: z.ZodOptional<z.ZodString>;
413
+ }, z.core.$strip>>;
374
414
  detectionSources: z.ZodDefault<z.ZodPreprocess<z.ZodArray<z.ZodEnum<{
375
415
  pipeline: "pipeline";
376
416
  onboard: "onboard";
@@ -660,6 +700,20 @@ export declare const pipelineRunnerCapability: {
660
700
  analyzer: "analyzer";
661
701
  "device-activity": "device-activity";
662
702
  }>>>;
703
+ sessionTrigger: z.ZodOptional<z.ZodObject<{
704
+ source: z.ZodEnum<{
705
+ onboard: "onboard";
706
+ analyzer: "analyzer";
707
+ "device-activity": "device-activity";
708
+ }>;
709
+ triggeredBy: z.ZodDiscriminatedUnion<[z.ZodObject<{
710
+ kind: z.ZodLiteral<"camera">;
711
+ }, z.core.$strip>, z.ZodObject<{
712
+ kind: z.ZodLiteral<"sensor">;
713
+ deviceId: z.ZodNumber;
714
+ }, z.core.$strip>], "kind">;
715
+ sensorName: z.ZodOptional<z.ZodString>;
716
+ }, z.core.$strip>>;
663
717
  detectionSources: z.ZodDefault<z.ZodPreprocess<z.ZodArray<z.ZodEnum<{
664
718
  pipeline: "pipeline";
665
719
  onboard: "onboard";
@@ -0,0 +1,104 @@
1
+ /**
2
+ * viewer-link-url — the ONE builder for a link that opens a VIEWER page
3
+ * (a camera at an instant, the events timeline, the notification centre),
4
+ * and the one definition of the "CamStack app link" address (D709).
5
+ *
6
+ * The address a link points at is the endpoint the operator FLAGS for
7
+ * notifications on the admin Network page (`local-network`'s notification
8
+ * endpoint — one flag, one store). Among the addresses that page lists,
9
+ * `local-network` adds one generic entry: the app link,
10
+ * `https://camstack.zentik.app`, and that entry carries the flag BY DEFAULT.
11
+ * Two forms follow from which address is flagged:
12
+ *
13
+ * - `app` — the app link is flagged:
14
+ * `https://camstack.zentik.app/<path>?<query>&hub=<hub origin>`. The central
15
+ * domain the native app claims as a Universal Link / App Link
16
+ * (docs/design/2026-08-19-central-link-redirect.md): on a phone with the app
17
+ * it opens the app on that page; anywhere else the hosted viewer opens and
18
+ * `hub=` tells it which hub to talk to. `hub=` is filled automatically from
19
+ * the hub's own best public HTTPS address ({@link pickAppLinkHub}).
20
+ * - `hub` — one of the hub's own addresses is flagged:
21
+ * `<hub base>/viewer/camstack/<path>?<query>` (the pre-D709 form).
22
+ *
23
+ * The paths are the viewer's own routes, verbatim (§2.3 of that design), and
24
+ * only the families the app claims in its AASA (`camstack/web-server/
25
+ * app-links.ts`): `/camera/*`, `/events*`, `/notifications*`. A destination
26
+ * is a typed union rather than a free path so a caller cannot mint a central
27
+ * link the domain would 404.
28
+ *
29
+ * The admin UI is NOT a viewer destination: the central site hosts the
30
+ * viewer only, so an admin page (an addon update row → `/system/addons`)
31
+ * always points at the hub itself — see `system-event-tap-url.ts`. Nor is the
32
+ * app link a HUB address: signed media and action-button links never use it.
33
+ */
34
+ import type { ConnectionEndpoint } from './local-network.cap.js';
35
+ /** The central link domain the viewer app claims (Universal Links / App Links). */
36
+ export declare const CAMSTACK_APP_LINK_ORIGIN = "https://camstack.zentik.app";
37
+ /** Where the hub serves the viewer SPA. */
38
+ export declare const HUB_VIEWER_MOUNT = "/viewer/camstack";
39
+ /** Which form a viewer link takes — see the module header. */
40
+ export type ViewerLinkForm = 'hub' | 'app';
41
+ /**
42
+ * The base a viewer link is built on. `hub`: the flagged hub address (null =
43
+ * none reachable — no link). `app`: the hub origin to carry as `hub=` (null =
44
+ * none known — the link is still minted, without `hub=`; the central page then
45
+ * asks once, design §5).
46
+ */
47
+ export interface ViewerLinkBase {
48
+ readonly form: ViewerLinkForm;
49
+ readonly hubBaseUrl: string | null;
50
+ }
51
+ /** A viewer page a link may open. One member per AASA-claimed route family. */
52
+ export type ViewerDestination = {
53
+ readonly kind: 'camera';
54
+ readonly deviceId: number;
55
+ /** Recorded seek instant (`?at=`), epoch ms. Absent = live. */
56
+ readonly atMs?: number;
57
+ } | {
58
+ readonly kind: 'events';
59
+ } | {
60
+ readonly kind: 'notifications';
61
+ };
62
+ export interface ViewerLinkInput {
63
+ readonly base: ViewerLinkBase;
64
+ readonly destination: ViewerDestination;
65
+ }
66
+ /** True when `baseUrl` names the CamStack app link rather than a hub address. */
67
+ export declare function isAppLinkBase(baseUrl: string | null | undefined): boolean;
68
+ /**
69
+ * The fields of `local-network.getNotificationEndpoint` a viewer link reads.
70
+ * `appLinkHub` is absent on a pre-D709 hub, which never flags the app link.
71
+ */
72
+ export interface NotificationLinkEndpoint {
73
+ readonly baseUrl: string | null;
74
+ readonly resolved: string | null;
75
+ readonly appLinkHub?: string | null;
76
+ }
77
+ /**
78
+ * The base a viewer link is built on, from the flagged notification address:
79
+ * the effective address is the explicit choice, else AUTO's `resolved`. The
80
+ * one reading of that answer — the NC's tap and the Network page's preview
81
+ * both go through it.
82
+ */
83
+ export declare function viewerLinkBaseOf(endpoint: NotificationLinkEndpoint): ViewerLinkBase;
84
+ /**
85
+ * Reduce a base URL to the bare origin the central page accepts as `hub=`,
86
+ * or `null` when it cannot be one: not http(s), carries credentials, or does
87
+ * not parse. A path/query/fragment is dropped — the central page mounts the
88
+ * viewer under the origin itself.
89
+ */
90
+ export declare function toAppLinkHubOrigin(baseUrl: string): string | null;
91
+ /**
92
+ * The hub address an app link carries as `hub=`, chosen from the hub's OWN
93
+ * advertised palette so it always agrees with what the Network page lists:
94
+ * the public tunnel first, then the mesh (Tailscale MagicDNS) — HTTPS only,
95
+ * because the app and the hosted viewer reach it from off the LAN. `null`
96
+ * when the hub advertises neither.
97
+ */
98
+ export declare function pickAppLinkHub(endpoints: readonly ConnectionEndpoint[]): string | null;
99
+ /**
100
+ * The link for a viewer destination, or `null` when none can be minted: an
101
+ * unknown destination, or the `hub` form with no reachable base (a dead link
102
+ * is worse than none).
103
+ */
104
+ export declare function buildViewerLink(input: ViewerLinkInput): string | null;
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Detector ↔ step label link — the ONE place that says which pipeline steps a
3
+ * root detector can stand in for, in whose vocabulary, and who writes tier 1.
4
+ *
5
+ * A Frigate+ detector already emits `deer`, `car`, `package`: the effect
6
+ * `animal-classifier`, `vehicle-classifier` and `package-detection` exist to
7
+ * produce. The model DECLARES that (`ModelCatalogEntry.fillsClassifierEffects`,
8
+ * derived here from its labelmap), and the step's own `labelLink` policy says
9
+ * whether the declaration is honoured. Pure — no I/O, no clock.
10
+ */
11
+ import type { FillsClassifierEffect, ModelCatalogEntry } from '../types/models.js';
12
+ /** Steps a root detector may declare it fills. */
13
+ export declare const FILLABLE_STEP_IDS: readonly ["animal-classifier", "vehicle-classifier", "package-detection"];
14
+ export type FillableStepId = (typeof FILLABLE_STEP_IDS)[number];
15
+ /** Narrow a step id to a fillable one — type guard, not a cast. */
16
+ export declare function isFillableStepId(value: string): value is FillableStepId;
17
+ /**
18
+ * The EFFECT vocabulary of each fillable step: exactly the strings the step
19
+ * itself emits, in its own spelling. A linked label is one of these and nothing
20
+ * else, so a tier-1 value means the same thing whichever writer produced it.
21
+ *
22
+ * - `animal-classifier`: the PRIMARY model's `-labels.json` (Open Images V7,
23
+ * 8 classes) — also the species allow-list the step offers.
24
+ * - `vehicle-classifier`: `vehicle-type-v1-labels.json`, capitalised as the
25
+ * model emits them (the classifier writes `winner.class` verbatim).
26
+ * - `package-detection`: its one output class.
27
+ *
28
+ * `scripts/check-label-link-vocabulary.ts` fails the build if a model entry's
29
+ * `labelToEffect` names anything outside this table.
30
+ */
31
+ export declare const FILLABLE_STEP_VOCABULARIES: Readonly<Record<FillableStepId, readonly string[]>>;
32
+ /** The macro a detection must carry for the step to apply to it. */
33
+ export declare const FILLABLE_STEP_MACRO: Readonly<Record<FillableStepId, string>>;
34
+ /** The policy values of a step's `labelLink` setting. */
35
+ export declare const LABEL_LINK_POLICIES: readonly ["run", "skip-when-filled"];
36
+ export type LabelLinkPolicy = (typeof LABEL_LINK_POLICIES)[number];
37
+ /** Absent setting ⇒ this. It changes nothing unless the root model declares a fill. */
38
+ export declare const DEFAULT_LABEL_LINK_POLICY: LabelLinkPolicy;
39
+ /** The step-settings key the policy is stored under (DeviceStepConfig.settings). */
40
+ export declare const LABEL_LINK_SETTING_KEY = "labelLink";
41
+ /** One fill a root model declares — the catalog schema's own type. */
42
+ export type ClassifierFillDeclaration = FillsClassifierEffect;
43
+ /** `ScoredLabel.stepId` prefix of a label the detector wrote for a step. */
44
+ export declare const LINKED_LABEL_STEP_PREFIX = "detector-link:";
45
+ /** `detector-link:<stepId>` — the attribution of a linked label. */
46
+ export declare function linkedLabelStepId(stepId: FillableStepId): string;
47
+ /** The step a linked label stands in for, or `undefined` for any other attribution. */
48
+ export declare function linkedStepOf(attributionStepId: string | undefined): FillableStepId | undefined;
49
+ /**
50
+ * A labelmap is COCO when it carries at least half of the COCO-80 classes. A
51
+ * COCO detector NEVER fills a step (operator decision, D715): its `dog` / `car`
52
+ * is the generic class the classifier exists to refine, and its six animal
53
+ * classes would otherwise read as "fills animal-classifier 6/8". Frigate+
54
+ * shares about a dozen COCO names; a COCO-80 or COCO-91 labelmap carries ~80.
55
+ */
56
+ export declare function isCocoLabelmap(labels: readonly string[]): boolean;
57
+ /**
58
+ * Which steps a root detector fills, from its labelmap and classMap. A label
59
+ * counts for a step only when the model's classMap sends it to that step's
60
+ * macro AND it names a vocabulary entry. A step none of the labels reach is
61
+ * not declared; a COCO labelmap declares nothing.
62
+ */
63
+ export declare function deriveClassifierFills(labels: readonly string[], classMap: {
64
+ readonly mapping: Readonly<Record<string, string>>;
65
+ } | undefined): readonly ClassifierFillDeclaration[];
66
+ /** The fill a model declares for one step, if any. */
67
+ export declare function fillFor(entry: Pick<ModelCatalogEntry, 'fillsClassifierEffects'> | undefined, stepId: FillableStepId): ClassifierFillDeclaration | undefined;
68
+ /** Read the `labelLink` policy off a step's settings bag; anything else ⇒ the default. */
69
+ export declare function readLabelLinkPolicy(settings: Readonly<Record<string, unknown>> | undefined): LabelLinkPolicy;
70
+ /** The configured step the decision is about, as the attach tree carries it. */
71
+ export interface LinkedStepState {
72
+ readonly enabled: boolean;
73
+ readonly settings?: Readonly<Record<string, unknown>>;
74
+ }
75
+ /** Who writes the step's effect for this camera. */
76
+ export interface LabelLinkDecision {
77
+ /**
78
+ * The detector is the ONE writer of this effect: its linked label carries
79
+ * the detection's score. Otherwise it is written at score 0, a fallback any
80
+ * scored answer of the step outranks.
81
+ */
82
+ readonly authoritative: boolean;
83
+ /** The step is configured to run and must NOT be dispatched. */
84
+ readonly skip: boolean;
85
+ readonly policy: LabelLinkPolicy;
86
+ /**
87
+ * Vocabulary entries the detector cannot produce that the step's
88
+ * `enabledClasses` still asks for (empty allow-list = all). The skip waits
89
+ * until the operator switches every one of them off.
90
+ */
91
+ readonly openGaps: readonly string[];
92
+ }
93
+ /**
94
+ * Decide the writer of one filled effect for one camera.
95
+ *
96
+ * - The step is not running (disabled, or not in the camera's tree): the
97
+ * detector is the only writer — authoritative, nothing to skip.
98
+ * - The step runs, the policy is `skip-when-filled` and every coverage gap is
99
+ * switched off in `enabledClasses`: the detector is authoritative and the
100
+ * step is skipped.
101
+ * - Otherwise the step runs and is the writer; the linked label is a score-0
102
+ * fallback.
103
+ */
104
+ export declare function resolveLabelLink(fill: ClassifierFillDeclaration, step: LinkedStepState | undefined): LabelLinkDecision;
@@ -0,0 +1,49 @@
1
+ import { CLASS_MAP_MACRO_TARGETS, type DetectionCatalogClassMap } from '../types/labels.js';
2
+ import { type ClassifierFillDeclaration } from './classifier-fill.js';
3
+ /** A macro a detection catalog classMap may resolve to. */
4
+ export type ClassMapMacroTarget = (typeof CLASS_MAP_MACRO_TARGETS)[number];
5
+ /**
6
+ * Raw Frigate+ label → detection macro. Every label of the documented
7
+ * Frigate+ base set (docs.frigate.video/plus, verified 2026-08-21) is either
8
+ * here or in {@link FRIGATE_PLUS_UNMAPPED_LABELS}, with the reason it is not.
9
+ *
10
+ * Why this exists: a Frigate+ import used to carry NO classMap, so it inherited
11
+ * the step's `COCO_TO_MACRO` (`preserveOriginal: false`) and the executor
12
+ * dropped every label COCO does not name — deer, raccoon, fox, squirrel, goat,
13
+ * rabbit, skunk, kangaroo, possum, rodent, school_bus, garbage_truck and even
14
+ * `package` vanished as `class-filter` discards. The executor keeps the raw
15
+ * label as `originalClass` whenever the map resolves it, so the fine identity
16
+ * survives under the macro.
17
+ */
18
+ export declare const FRIGATE_PLUS_TO_MACRO: Readonly<Record<string, ClassMapMacroTarget>>;
19
+ /**
20
+ * Frigate+ labels deliberately left OUT of {@link FRIGATE_PLUS_TO_MACRO}.
21
+ *
22
+ * - `attribute`: Frigate+ emits these INSIDE a parent box (a face inside a
23
+ * person, a plate or a carrier logo on a vehicle). Mapping one to its
24
+ * parent's macro would spawn a second, overlapping track for the same
25
+ * subject; CamStack derives faces and plates with its own detail steps.
26
+ * - `no-macro`: an object with no detection macro to live under.
27
+ */
28
+ export declare const FRIGATE_PLUS_UNMAPPED_LABELS: Readonly<Record<string, 'attribute' | 'no-macro'>>;
29
+ /**
30
+ * The per-model classMap for a Frigate / Frigate+ detector, derived from ITS
31
+ * labelmap: each label resolves through {@link FRIGATE_PLUS_TO_MACRO} first,
32
+ * then `COCO_TO_MACRO` (Frigate's default model ships the COCO-91 labelmap, so
33
+ * a preset import may carry either vocabulary). A label neither knows is left
34
+ * out, and `preserveOriginal: false` drops it in the executor — the same
35
+ * contract as the COCO map, now with the Frigate+ vocabulary in it.
36
+ */
37
+ export declare function buildFrigateClassMap(labels: readonly string[]): DetectionCatalogClassMap;
38
+ /** The label-derived fields of a Frigate catalog entry. */
39
+ export interface FrigateLabelFields {
40
+ readonly classMap: DetectionCatalogClassMap;
41
+ readonly fillsClassifierEffects?: readonly ClassifierFillDeclaration[];
42
+ }
43
+ /**
44
+ * Everything a Frigate / Frigate+ entry derives from its labelmap: the classMap
45
+ * and the steps it fills (D715). Every Frigate builder spreads this, so the two
46
+ * cannot be derived from different label lists. A COCO labelmap gets its map
47
+ * and no fill.
48
+ */
49
+ export declare function frigateLabelFields(labels: readonly string[]): FrigateLabelFields;
@@ -1,4 +1,6 @@
1
1
  export * from './coco-classmap.js';
2
+ export * from './frigate-plus-classmap.js';
3
+ export * from './classifier-fill.js';
2
4
  export * from './sensor-active-state.js';
3
5
  export * from './audio-classmap.js';
4
6
  export * from './event-taxonomy.js';
@@ -0,0 +1,17 @@
1
+ /**
2
+ * `@camstack/types/client` — the runtime values a CLIENT bundle needs, and
3
+ * nothing it does not.
4
+ *
5
+ * The bare entry is one pre-bundled `index.mjs` (~1.1 MB minified) and Metro
6
+ * does not tree-shake, so the viewer's web bundle carried every capability
7
+ * schema the hub knows for the ~80 values it actually reads (D721). This entry
8
+ * is built on its own (`vite.client.config.ts`) with module side effects
9
+ * OFF, so only the modules these names reach are emitted.
10
+ *
11
+ * The list is the viewer's: every non-type import of `@camstack/types` in
12
+ * `camstack/src` + `app`, plus what `@camstack/sdk` imports at runtime.
13
+ * The viewer's guard (`types-client-entry.spec.ts`) fails when it imports a
14
+ * value this entry does not export — a missing name here is `undefined` at
15
+ * runtime, not a build error.
16
+ */
17
+ export { APPLE_SA_TO_MACRO, AUDIO_MACRO_LABELS, AlarmArmModeSchema, CLIP_BROKER_PACED_RATES, COCO_TO_MACRO, CamProfileSchema, DEFAULT_TIMELAPSE_PREVIEW_TEXT, DeviceType, EVENTFUL_CAP_NAMES, EVENT_KIND_BY_CAP, EVENT_TAXONOMY, MACRO_LABELS, NC_ALARM_DELAY_MAX_SEC, NC_ALARM_SENSORS_MAX, NC_ALARM_SYSTEM_EVENT_KINDS, NC_ALARM_TRIGGERED_MAX_SEC, NC_BATTERY_CONSUMABLE_SYSTEM_EVENT_KINDS, NC_CAMERA_SCOPE_CAP_NAME, NC_CONSUMABLE_LOW_PERCENT_DEFAULT, NC_CONSUMABLE_LOW_PERCENT_MAX, NC_GROUPING_DEFAULT_SEC, NC_GROUPING_MAX_SEC, NC_GROUPING_MIN_SEC, NC_RULE_EDITOR_SECTION_ORDER, NC_RULE_KIND_SPECS, NC_SENSOR_TRANSITION_UNSUPPORTED_REASON, NC_SYSTEM_EVENT_FAMILY_FILTERS, NC_SYSTEM_EVENT_KIND_GROUP_SPECS, NC_SYSTEM_EVENT_SUMMARY_FAMILIES, NC_TEMPLATE_HELD_BACK_SYSTEM_EVENT_KINDS, NC_TEMPLATE_VARS, NcAlarmConfigSchema, NcAlarmSensorsSchema, NcAlarmSettingsPatchSchema, NcHistoryEntrySchema, NcRuleLastRunsSchema, NodeDirectorySchema, RECORDING_EXPORT_MAX_READ_BYTES, SystemMirror, TIMELAPSE_DENSE_FLOOR_SEC, TimelapseRuleSchema, YAMNET_TO_MACRO, alarmDeviceBlocksArming, alarmDeviceSecureOnArm, alarmPatchLanded, conditionVisibleForKind, createSystemProxy, droppedConditionsForKind, isHeldBackTemplateVar, isSystemRuleKind, kindsForDiscriminator, knownValues, nodePickerItems, packagePickerItems, pickerForCondition, pickerForRuleClasses, resolveModeDelays, ruleDeviceCompatCapNames, ruleEditorSectionsForKind, ruleGroupingApplies, ruleKindOf, ruleKindSpec, ruleSeedForSection, sensorTransitionNeverFires, sensorTransitionOffered, stateLabel, systemEventDeliveryProblems, systemEventFilterAppliesToAnyKind, systemEventKindsOfFamily, systemFamilyOfKind, templateCarriesSummary, templateVarDeliveryApplies, templateVarKindApplies, templateVarSystemEventApplies, } from './index.js';