@camstack/addon-osd-manager 0.1.137 → 0.1.139

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (18) hide show
  1. package/dist/{MotionZonesSettings-B4onRgUN.mjs → MotionZonesSettings-CG1jsdMo.mjs} +2 -2
  2. package/dist/{PrivacyMaskSettings-15mTDT2b.mjs → PrivacyMaskSettings-mBWMKyY2.mjs} +4 -4
  3. package/dist/{SceneMonitorEditor-DFU0p0mQ.mjs → SceneMonitorEditor-C_L1sFhf.mjs} +3 -3
  4. package/dist/_stub.js +10 -10
  5. package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_osd_manager_page-CGBPavbq.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_osd_manager_page-COPuIhJm.mjs} +3 -3
  6. package/dist/_virtual_mf___mfe_internal__addon_osd_manager_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-B8-UPDOD.mjs +26 -0
  7. package/dist/{hostInit-jIJC0_ID.mjs → hostInit-CtlLZppQ.mjs} +2 -2
  8. package/dist/index.js +442 -19
  9. package/dist/index.mjs +442 -19
  10. package/dist/{player-overlays-B_ERqzqj.mjs → player-overlays-Cxv7i44p.mjs} +1 -1
  11. package/dist/remoteEntry.js +1 -1
  12. package/dist/{responsive-BOpuh3Lr.mjs → responsive-BpLjT1Jf.mjs} +1 -1
  13. package/dist/{scene-monitor-copy-D5o6-VNM.mjs → scene-monitor-copy-CglGNTA4.mjs} +1 -1
  14. package/dist/{square-oUeZZbza.mjs → square-CeQEcUQK.mjs} +1 -1
  15. package/dist/{trash-2-BrFLAkuW.mjs → trash-2-D4OQxTrz.mjs} +1 -1
  16. package/dist/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_osd_manager_page__remoteEntry_js-C-OUB_74.mjs → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_osd_manager_page__remoteEntry_js-CJGlrZlS.mjs} +1 -1
  17. package/package.json +1 -1
  18. package/dist/_virtual_mf___mfe_internal__addon_osd_manager_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CVM3jGoe.mjs +0 -26
package/dist/index.mjs CHANGED
@@ -5359,7 +5359,7 @@ var ZodIssueCode = {
5359
5359
  var ZodFirstPartyTypeKind;
5360
5360
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5361
5361
  //#endregion
5362
- //#region ../types/dist/sleep-D_4W7xuQ.mjs
5362
+ //#region ../types/dist/sleep-DU7mu4wb.mjs
5363
5363
  /**
5364
5364
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5365
5365
  * window to float samples (D455).
@@ -16738,18 +16738,30 @@ var LlmErrorCodeSchema = _enum([
16738
16738
  "budget-exceeded",
16739
16739
  "adapter-error"
16740
16740
  ]);
16741
- var LlmGenerateResultSchema = discriminatedUnion("ok", [object({
16741
+ var LlmGenerateOkSchema = object({
16742
16742
  ok: literal(true),
16743
16743
  text: string(),
16744
16744
  model: string(),
16745
16745
  usage: LlmUsageSchema,
16746
16746
  truncated: boolean(),
16747
16747
  latencyMs: number()
16748
- }), object({
16748
+ });
16749
+ /**
16750
+ * WHO refused, on a `refusal`. `guardrail` = a safety filter in front of the
16751
+ * model rejected the request before it answered (Apple Foundation Models
16752
+ * refuses surveillance-framed prompts in 0.1 s); `model` = the model itself
16753
+ * declined. They are different faults: a guardrail refusal is a property of
16754
+ * the BACKEND, so the provider falls back to the next profile; a model refusal
16755
+ * is an answer. Absent on every other code, and on a refusal a wire cannot
16756
+ * attribute.
16757
+ */
16758
+ var LlmRefusalSourceSchema = _enum(["guardrail", "model"]);
16759
+ var LlmGenerateResultSchema = discriminatedUnion("ok", [LlmGenerateOkSchema, object({
16749
16760
  ok: literal(false),
16750
16761
  code: LlmErrorCodeSchema,
16751
16762
  message: string(),
16752
- retryAfterMs: number().optional()
16763
+ retryAfterMs: number().optional(),
16764
+ refusalSource: LlmRefusalSourceSchema.optional()
16753
16765
  })]);
16754
16766
  /**
16755
16767
  * `Uint8Array` is the sanctioned binary convention — superjson + the UDS
@@ -16979,6 +16991,77 @@ var LlmRuntimeDiskUsageSchema = object({
16979
16991
  modelsBytes: number(),
16980
16992
  freeBytes: number().optional()
16981
16993
  });
16994
+ var LlmRuntimeCompleteInputSchema = LlmGenerateBaseInputSchema.extend({
16995
+ images: array(LlmImageSchema).optional(),
16996
+ runtime: ManagedRuntimeConfigSchema,
16997
+ /** The managed profile's timeout, threaded by the hub provider. */
16998
+ timeoutMs: number().int().positive().optional()
16999
+ });
17000
+ /**
17001
+ * Why Apple Foundation Models cannot run on a node that has it in principle.
17002
+ * The first three are Apple's own `UnavailableReason`s, verbatim; the rest are
17003
+ * ours: the OS predates the framework (macOS < 26), the helper binary is not
17004
+ * in the installed addon, or it crashed past the respawn bound.
17005
+ */
17006
+ var AppleFmUnavailableReasonSchema = _enum([
17007
+ "deviceNotEligible",
17008
+ "appleIntelligenceNotEnabled",
17009
+ "modelNotReady",
17010
+ "osTooOld",
17011
+ "helperMissing",
17012
+ "helperCrashed"
17013
+ ]);
17014
+ /**
17015
+ * Apple Foundation Models on ONE node — four states, never a boolean (D315).
17016
+ *
17017
+ * - `available` — the helper probed it; what it CAN do is reported
17018
+ * here (`imageInput`, `contextSize`, languages),
17019
+ * never typed by an operator.
17020
+ * - `unavailable` — a known absence, with the reason to act on.
17021
+ * - `unsupported-platform` — not a Mac; there is nothing to enable.
17022
+ * - `unknown` — the probe did not answer (not yet run, timed
17023
+ * out, helper crashed mid-probe). A failed
17024
+ * measurement is NEVER `unavailable` (D393).
17025
+ */
17026
+ var AppleFmAvailabilitySchema = discriminatedUnion("state", [
17027
+ object({
17028
+ state: literal("available"),
17029
+ osVersion: string(),
17030
+ /** Tokens, as the framework reports it. Read at runtime, never assumed. */
17031
+ contextSize: number().int().positive(),
17032
+ /** BCP-47-ish tags (`it-IT`) of the languages the model supports. */
17033
+ languages: array(string()),
17034
+ /** Whether prompts may carry images. `false` on a macOS 26 build. */
17035
+ imageInput: boolean()
17036
+ }),
17037
+ object({
17038
+ state: literal("unavailable"),
17039
+ reason: AppleFmUnavailableReasonSchema,
17040
+ osVersion: string().nullable(),
17041
+ detail: string()
17042
+ }),
17043
+ object({
17044
+ state: literal("unsupported-platform"),
17045
+ platform: string()
17046
+ }),
17047
+ object({
17048
+ state: literal("unknown"),
17049
+ error: string()
17050
+ })
17051
+ ]);
17052
+ /**
17053
+ * A generation on the node's Apple Foundation Models helper. A separate verb
17054
+ * from `complete`, whose `runtime` is a llama.cpp config: overloading it would
17055
+ * drag a GGUF model reference into a backend that has none. `images` is part
17056
+ * of the contract so vision needs no cap change later; a node whose model has
17057
+ * no image input REFUSES them (`unavailable`), never drops them.
17058
+ */
17059
+ var LlmRuntimeAppleCompleteInputSchema = LlmGenerateBaseInputSchema.extend({
17060
+ images: array(LlmImageSchema).optional(),
17061
+ /** The profile's timeout, threaded by the hub provider. */
17062
+ timeoutMs: number().int().positive().optional()
17063
+ });
17064
+ var LlmRuntimeCancelInputSchema = object({ requestId: string() });
16982
17065
  var llmRuntimeCapability = {
16983
17066
  name: "llm-runtime",
16984
17067
  scope: "system",
@@ -16998,12 +17081,7 @@ var llmRuntimeCapability = {
16998
17081
  * nothing; the public `llm` cap (which end users and non-admin sessions
16999
17082
  * legitimately call for chat/generation) is untouched.
17000
17083
  */
17001
- complete: method(LlmGenerateBaseInputSchema.extend({
17002
- images: array(LlmImageSchema).optional(),
17003
- runtime: ManagedRuntimeConfigSchema,
17004
- /** The managed profile's timeout, threaded by the hub provider. */
17005
- timeoutMs: number().int().positive().optional()
17006
- }), LlmGenerateResultSchema, {
17084
+ complete: method(LlmRuntimeCompleteInputSchema, LlmGenerateResultSchema, {
17007
17085
  kind: "mutation",
17008
17086
  auth: "admin",
17009
17087
  timeoutMs: AI_CAP_TRANSPORT_TIMEOUT_MS
@@ -17028,7 +17106,28 @@ var llmRuntimeCapability = {
17028
17106
  auth: "admin"
17029
17107
  }),
17030
17108
  listLocalModels: method(object({}), array(LlmNodeModelSchema), { auth: "admin" }),
17031
- getDiskUsage: method(object({}), LlmRuntimeDiskUsageSchema, { auth: "admin" })
17109
+ getDiskUsage: method(object({}), LlmRuntimeDiskUsageSchema, { auth: "admin" }),
17110
+ /**
17111
+ * Stop a node-side generation started with a `requestId` — `complete` or
17112
+ * `completeApple`. The hub's `llm.cancel` forwards here with the same
17113
+ * nodePin the generation took; before this existed a cancelled
17114
+ * managed-local generation kept running on the node to its own timeout.
17115
+ * Idempotent: an unknown or finished id is a no-op.
17116
+ */
17117
+ cancel: method(LlmRuntimeCancelInputSchema, _void(), {
17118
+ kind: "mutation",
17119
+ auth: "admin"
17120
+ }),
17121
+ /**
17122
+ * This node's Apple Foundation Models state, answered from a mirror the
17123
+ * node refreshes in the background — it never waits on a probe.
17124
+ */
17125
+ appleAvailability: method(object({}), AppleFmAvailabilitySchema, { auth: "admin" }),
17126
+ completeApple: method(LlmRuntimeAppleCompleteInputSchema, LlmGenerateResultSchema, {
17127
+ kind: "mutation",
17128
+ auth: "admin",
17129
+ timeoutMs: AI_CAP_TRANSPORT_TIMEOUT_MS
17130
+ })
17032
17131
  }
17033
17132
  };
17034
17133
  /**
@@ -17047,7 +17146,8 @@ var LlmProfileKindSchema = _enum([
17047
17146
  "openai",
17048
17147
  "anthropic",
17049
17148
  "google",
17050
- "managed-local"
17149
+ "managed-local",
17150
+ "apple-foundation"
17051
17151
  ]);
17052
17152
  var LlmProfileSchema = object({
17053
17153
  id: string(),
@@ -17105,7 +17205,14 @@ var LlmProfileSchema = object({
17105
17205
  toolsEnabled: boolean().default(false),
17106
17206
  extraHeaders: record(string(), string()).optional(),
17107
17207
  /** kind === 'managed-local' only (spec §4). */
17108
- runtime: ManagedRuntimeConfigSchema.optional()
17208
+ runtime: ManagedRuntimeConfigSchema.optional(),
17209
+ /**
17210
+ * kind === 'apple-foundation' only: WHERE it runs — the only thing there is
17211
+ * to configure (no key, no URL, no download; `model` is `apple-system`).
17212
+ * `supportsVision` on such a row is stamped by the provider from the node's
17213
+ * reported `imageInput`, never taken from the operator (D62).
17214
+ */
17215
+ appleFoundation: object({ nodeId: string() }).optional()
17109
17216
  });
17110
17217
  /** ConfigUISchema tree passed through untyped on the wire (the
17111
17218
  * notification-output `ConfigSchemaPassthrough` precedent at
@@ -17187,7 +17294,9 @@ var LlmRuntimeNodeSchema = object({
17187
17294
  reachable: boolean(),
17188
17295
  status: LlmRuntimeStatusSchema.optional(),
17189
17296
  disk: LlmRuntimeDiskUsageSchema.optional(),
17190
- error: string().optional()
17297
+ error: string().optional(),
17298
+ /** Absent = the node did not answer the question (render as unknown). */
17299
+ apple: AppleFmAvailabilitySchema.optional()
17191
17300
  });
17192
17301
  var GenerateVisionInputSchema = LlmGenerateBaseInputSchema.extend({ images: array(LlmImageSchema).min(1) });
17193
17302
  var ProfileRefInputSchema = object({
@@ -19631,6 +19740,16 @@ var NcCrossingSchema = _enum([
19631
19740
  "exit",
19632
19741
  "any"
19633
19742
  ]);
19743
+ /**
19744
+ * Which edge of a BOOLEAN sensor fires a device-event rule (D640).
19745
+ * - `raised` — the sensor went high: water detected, smoke, open, tampered.
19746
+ * - `cleared` — it went back: dry, clear, closed.
19747
+ * - absent — both edges, which is what every rule authored before this did.
19748
+ *
19749
+ * There is no third member for "both": absence already says it, and a value
19750
+ * that means the same as absence is a second way to write one rule.
19751
+ */
19752
+ var NcSensorTransitionSchema = _enum(["raised", "cleared"]);
19634
19753
  /** Admin-zone membership condition (zone IDs as stamped by the ZoneEngine). */
19635
19754
  var NcZoneConditionSchema = object({
19636
19755
  ids: array(string().min(1)).min(1),
@@ -19820,6 +19939,20 @@ var NcConditionsSchema = object({
19820
19939
  scene: NcSceneConditionSchema.optional(),
19821
19940
  /** Device scope — absent = all devices. */
19822
19941
  devices: array(number()).optional(),
19942
+ /**
19943
+ * Device EXCLUSION (D641) — "every device except these". Judged on the SAME
19944
+ * subject ids {@link devices} is judged on (the camera, the sensor that
19945
+ * fired, a linked set's sensor and row cameras), so a sensor fanned out per
19946
+ * linked camera is excluded exactly where an include would have tested it.
19947
+ * `min(1)`: an empty exclusion excludes nothing and is written as absent.
19948
+ *
19949
+ * Not for `system-event` rules — those carry their own
19950
+ * `systemEvent.excludeDeviceIds` (D636), and the hub refuses this key there.
19951
+ * Editors present the two lists as ONE field (All | Only these | All except
19952
+ * these); the engine evaluates each independently, so a legacy rule
19953
+ * carrying both still means "these, minus those".
19954
+ */
19955
+ devicesExclude: array(number()).min(1).optional(),
19823
19956
  /** Detector class names (any overlap with the record's class set). */
19824
19957
  classes: array(string().min(1)).optional(),
19825
19958
  /** Veto classes — any overlap fails the rule. */
@@ -19953,6 +20086,16 @@ var NcConditionsSchema = object({
19953
20086
  */
19954
20087
  sensorKinds: array(string().min(1)).optional(),
19955
20088
  /**
20089
+ * DEVICE-EVENT only (D640). Fire on one edge of a boolean sensor —
20090
+ * {@link NcSensorTransitionSchema}. Which field of the slice means "raised"
20091
+ * is `@camstack/types` → `notification/sensor-raised.ts`. A reading the
20092
+ * engine cannot place (a kind with no raise, an unreadable slice) PASSES:
20093
+ * the condition fails open towards notifying, never towards silence. Editors
20094
+ * offer it only when every chosen {@link sensorKinds} member has a raise
20095
+ * (`sensorTransitionOffered`), and the hub refuses it on any other delivery.
20096
+ */
20097
+ sensorTransition: NcSensorTransitionSchema.optional(),
20098
+ /**
19956
20099
  * PACKAGE-EVENT only. Which package phase fires the rule — `delivered`
19957
20100
  * (a parked parcel appeared), `picked-up` (it departed), or `both`. Fails
19958
20101
  * when the subject's phase does not match (a subject always carries a phase
@@ -20452,9 +20595,29 @@ var NcTestResultSchema = object({
20452
20595
  className: string().optional(),
20453
20596
  label: string().optional()
20454
20597
  });
20455
- /** The five rule kinds, as data. `NcRuleKind` in `notification/rule-kinds.ts`
20456
- * is the same union; the template-vars spec pins the two together. */
20598
+ /** The rule kinds, as data. `NcRuleKind` in `notification/rule-kinds.ts` is the
20599
+ * same union; the template-vars spec pins the two together. `mixed` is DERIVED
20600
+ * (a stored system rule whose kinds span families, D637) and never authored. */
20457
20601
  var NcRuleKindSchema = _enum([
20602
+ "detection",
20603
+ "sensor",
20604
+ "occupancy",
20605
+ "sound",
20606
+ "device-events",
20607
+ "system",
20608
+ "alarm",
20609
+ "mixed"
20610
+ ]);
20611
+ /**
20612
+ * The kinds a SERVED template-variable descriptor may name: the five that
20613
+ * existed before D637, frozen. `getTemplateCatalog` ships `kinds` to every
20614
+ * installed viewer, and a viewer at `@camstack/types` 1.2.25x parses them with a
20615
+ * strict five-member enum — one `device-events` in one descriptor fails the
20616
+ * whole catalog parse. So the WIRE says `system`, and the MATCH widens it:
20617
+ * `templateVarKindApplies` reads a `system` descriptor as applying to every
20618
+ * system rule kind (`device-events`, `system`, `alarm`, `mixed`).
20619
+ */
20620
+ var NcTemplateVarKindSchema = _enum([
20458
20621
  "detection",
20459
20622
  "sensor",
20460
20623
  "occupancy",
@@ -20492,7 +20655,7 @@ var NcTemplateVarGroupSchema = _enum([
20492
20655
  *
20493
20656
  * `families` / `fields` / `kinds` / `deliveries` / `systemEventKinds` say WHERE
20494
20657
  * it has a value; absent = no restriction on that axis. `systemEventKinds` is
20495
- * read only for a `system` rule. `dynamic` declares a FAMILY of names
20658
+ * read only for a system-event rule (any family, or `mixed`). `dynamic` declares a FAMILY of names
20496
20659
  * (`count_<class>`): the descriptor's `name` is the example member.
20497
20660
  */
20498
20661
  var NcTemplateVarDescriptorSchema = object({
@@ -20503,7 +20666,7 @@ var NcTemplateVarDescriptorSchema = object({
20503
20666
  group: NcTemplateVarGroupSchema,
20504
20667
  families: array(NcTemplateFamilySchema).min(1),
20505
20668
  fields: array(NcTemplateFieldSchema).optional(),
20506
- kinds: array(NcRuleKindSchema).optional(),
20669
+ kinds: array(NcTemplateVarKindSchema).optional(),
20507
20670
  deliveries: array(NcDeliverySchema).optional(),
20508
20671
  systemEventKinds: array(NcSystemEventKindSchema).optional(),
20509
20672
  dynamic: object({
@@ -20551,6 +20714,7 @@ var NcConditionDescriptorSchema = object({
20551
20714
  /** Editor widget the UI renders — never hardcode per-condition forms. */
20552
20715
  valueType: _enum([
20553
20716
  "deviceIdList",
20717
+ "deviceIdExcludeList",
20554
20718
  "stringList",
20555
20719
  "number01",
20556
20720
  "number",
@@ -20561,6 +20725,7 @@ var NcConditionDescriptorSchema = object({
20561
20725
  "plateMatcher",
20562
20726
  "packagePhase",
20563
20727
  "crossingSelect",
20728
+ "sensorTransition",
20564
20729
  "polygonDraw",
20565
20730
  "occupancy",
20566
20731
  "audio",
@@ -20759,6 +20924,21 @@ var NC_CONDITION_CATALOG = [
20759
20924
  phase: "P1",
20760
20925
  description: "Restrict the rule to these devices; absent = all devices. A sensor event matches either the SENSOR that fired or the camera it is attributed to, so a rule may name either one."
20761
20926
  },
20927
+ {
20928
+ id: "devicesExclude",
20929
+ group: "scope",
20930
+ label: "Excluded devices",
20931
+ valueType: "deviceIdExcludeList",
20932
+ operator: "notIn",
20933
+ appliesTo: [
20934
+ "immediate",
20935
+ "track-end",
20936
+ "device-event",
20937
+ "package-event"
20938
+ ],
20939
+ phase: "P1",
20940
+ description: "Every device except these. Judged on the same device ids as Devices: a sensor event is excluded by the SENSOR that fired or by the camera it is attributed to."
20941
+ },
20762
20942
  {
20763
20943
  id: "classes",
20764
20944
  group: "class",
@@ -21015,6 +21195,33 @@ var NC_CONDITION_CATALOG = [
21015
21195
  phase: "P1",
21016
21196
  description: "Raw device event-type tokens (e.g. doorbell press / press_long) from the event-emitter slice; absent on doorbell-pulse / passive sensors."
21017
21197
  },
21198
+ {
21199
+ id: "sensorTransition",
21200
+ group: "device",
21201
+ label: "Notify when",
21202
+ valueType: "sensorTransition",
21203
+ options: [
21204
+ {
21205
+ value: "",
21206
+ label: "It triggers and when it clears",
21207
+ hint: "Every change: water detected, and back to dry."
21208
+ },
21209
+ {
21210
+ value: "raised",
21211
+ label: "Only when it triggers",
21212
+ hint: "Water detected, smoke, a contact opening — never the return to normal."
21213
+ },
21214
+ {
21215
+ value: "cleared",
21216
+ label: "Only when it clears",
21217
+ hint: "Back to dry, smoke gone, a contact closing — never the alert itself."
21218
+ }
21219
+ ],
21220
+ operator: "in",
21221
+ appliesTo: ["device-event"],
21222
+ phase: "P2",
21223
+ description: "Fire on one edge of a boolean sensor. Offered only when every chosen sensor kind raises and clears; a reading that cannot be placed still notifies."
21224
+ },
21018
21225
  {
21019
21226
  id: "packagePhase",
21020
21227
  group: "package",
@@ -21198,6 +21405,28 @@ var NcHistoryFilterSchema = object({
21198
21405
  limit: number().int().min(1).max(500).default(100)
21199
21406
  });
21200
21407
  /**
21408
+ * Every rule's last run, in one answer.
21409
+ *
21410
+ * A rule ABSENT from `runs` produced no delivery inside `horizonMs` — how far
21411
+ * back this answer looked, in ms before the hub's now. It is the outbox prune
21412
+ * window (7 days by default, operator-configurable), NARROWED when the read hit
21413
+ * its row bound: the answer never claims a window it did not read. `null` means
21414
+ * the operator keeps the outbox forever AND the read reached its end, so absent
21415
+ * means "never on record". A UI derives its "not in the last N days" from this
21416
+ * value, never from a constant — and only when the call ANSWERED (D315).
21417
+ */
21418
+ var NcRuleLastRunsSchema = object({
21419
+ runs: array(object({
21420
+ ruleId: string(),
21421
+ /** Fire time of the newest row (`createdAt`, epoch ms). */
21422
+ lastAt: number(),
21423
+ status: NcHistoryStatusSchema,
21424
+ /** The camera/device of that row (a digest row files under its first camera). */
21425
+ deviceId: number()
21426
+ })),
21427
+ horizonMs: number().nonnegative().nullable()
21428
+ });
21429
+ /**
21201
21430
  * What a snooze covers. Broader scopes win when several overlap, so one window
21202
21431
  * leaves ONE digest rather than a rule snooze and a whole-feed snooze both
21203
21432
  * summarising the same silence.
@@ -21378,6 +21607,14 @@ var NcAlarmModeCoverageSchema = object({
21378
21607
  /** Ids named by the covering rules. A SUBSET when `allDevices` is true. */
21379
21608
  deviceIds: array(number().int()),
21380
21609
  /**
21610
+ * D641: the ids NOT covered although `allDevices` is true — every unscoped
21611
+ * covering rule EXCLUDES them (`conditions.devicesExclude`) and no named rule
21612
+ * covers them. Always `[]` when `allDevices` is false. Excluded by the rules,
21613
+ * which is not the same as skipped by a switch: never in `skippedDevices`.
21614
+ * Defaulted so an answer computed before this field parses as "none".
21615
+ */
21616
+ allDevicesExcept: array(number().int()).default([]),
21617
+ /**
21381
21618
  * Devices this mode NAMES but cannot actually arm, each with the switch that
21382
21619
  * excludes it.
21383
21620
  *
@@ -21601,6 +21838,15 @@ var notificationRulesCapability = {
21601
21838
  */
21602
21839
  getHistory: method(object({ filter: NcHistoryFilterSchema.default({ limit: 100 }) }), object({ entries: array(NcHistoryEntrySchema) }), { auth: "admin" }),
21603
21840
  /**
21841
+ * The newest delivery of every rule, in ONE bounded read of the outbox —
21842
+ * the "Last run" column. Never a `getHistory` per rule. A rule with no
21843
+ * delivery inside `horizonMs` is absent from `runs`; see
21844
+ * {@link NcRuleLastRunsSchema} for what absent means. A store that cannot
21845
+ * answer FAILS the call rather than answering "nothing ran". Admin-only,
21846
+ * like `getHistory`, of which it is a projection.
21847
+ */
21848
+ getRuleLastRuns: method(object({}), NcRuleLastRunsSchema, { auth: "admin" }),
21849
+ /**
21604
21850
  * Mint a fresh, externally-reachable URL for one artefact a history row
21605
21851
  * named in {@link NcHistoryEntrySchema.shape.artifactIds} — the SAME
21606
21852
  * signed-link mechanism the dispatcher uses to attach media to an
@@ -27529,7 +27775,11 @@ function buildDescriptor(capName, kind) {
27529
27775
  icon: legacyIcon(t.iconId)
27530
27776
  };
27531
27777
  }
27532
- Object.freeze(Object.fromEntries(Object.entries(CAP_TO_KIND).map(([capName, kind]) => [capName, buildDescriptor(capName, kind)])));
27778
+ /**
27779
+ * Sensor / control cap name → static event-kind descriptor. A linked device
27780
+ * contributes one entry per bound cap present in this map.
27781
+ */
27782
+ var EVENT_KIND_BY_CAP = Object.freeze(Object.fromEntries(Object.entries(CAP_TO_KIND).map(([capName, kind]) => [capName, buildDescriptor(capName, kind)])));
27533
27783
  /**
27534
27784
  * server-management — per-NODE singleton capability for a node's ROOT
27535
27785
  * package lifecycle (runtime-updatable node packages).
@@ -36549,6 +36799,29 @@ var RenameNodeResultSchema = object({
36549
36799
  name: string()
36550
36800
  });
36551
36801
  /**
36802
+ * The cheap node list. A consumer's rule for a STORED node id (a rule's
36803
+ * `nodeIds`) that is missing from `nodes`, whatever `complete` says: render it
36804
+ * as a removable chip labelled unknown, never drop it (D49). Even a complete
36805
+ * list omits a node that joined and left between two history captures, so a
36806
+ * missing id means "not known to the hub", never "removed". Only the operator
36807
+ * removes it.
36808
+ *
36809
+ * `complete` changes only the WORDING: `false` = no history read has ever
36810
+ * answered, so the list may be missing offline nodes the hub does know (D315).
36811
+ *
36812
+ * `name` is the history row's name (≤ 30 s behind a rename), or the id when
36813
+ * the history has none.
36814
+ */
36815
+ var NodeDirectorySchema = object({
36816
+ nodes: array(object({
36817
+ id: string(),
36818
+ name: string(),
36819
+ isHub: boolean(),
36820
+ isOnline: boolean()
36821
+ })).readonly(),
36822
+ complete: boolean()
36823
+ });
36824
+ /**
36552
36825
  * `nodes` is a **hub-centric** cluster-management cap: the hub hosts
36553
36826
  * the single provider and every per-node method (`getNodeAddons`,
36554
36827
  * `restartProcess`, `restartNode`, `undeployAddon`, …) takes `nodeId`
@@ -36567,6 +36840,12 @@ var nodesCapability = {
36567
36840
  nodeIdMode: "data",
36568
36841
  methods: {
36569
36842
  topology: method(_void(), array(TopologyNodeSchema).readonly(), { auth: "admin" }),
36843
+ /**
36844
+ * The cheap node list for pickers (D637): the hub's in-memory registry plus
36845
+ * the durable node history, no per-node RPC. `complete: false` when the
36846
+ * history could not be read.
36847
+ */
36848
+ directory: method(_void(), NodeDirectorySchema, { auth: "admin" }),
36570
36849
  deployAddon: method(NodeAddonInputSchema, SuccessSchema, {
36571
36850
  kind: "mutation",
36572
36851
  auth: "admin"
@@ -42861,6 +43140,42 @@ function readDeviceStateFrom(runtimeState) {
42861
43140
  }
42862
43141
  }
42863
43142
  /**
43143
+ * LA tabella "quale booleano di questo tipo di device conta come ALTO", e il
43144
+ * valutatore puro del suo FRONTE.
43145
+ *
43146
+ * Viveva dentro il builtin virtual-doorbell
43147
+ * (`@camstack/system` — `builtins/doorbell/trigger-engine.ts`) e i suoi
43148
+ * predicati erano privati al modulo. Il recorder ne ha bisogno per il trigger
43149
+ * `RecordingTriggers.sensorDeviceIds`: copiarla avrebbe creato la SECONDA
43150
+ * tabella, che diverge alla prima cap aggiunta e il cui sintomo — "il sensore
43151
+ * fa suonare il campanello ma non registra" — è esattamente D62. Quindi si
43152
+ * SPOSTA qui e il doorbell la ri-esporta.
43153
+ *
43154
+ * ⚠ NON è `DEVICE_STATE_READERS` (`catalogs/device-state-vocabulary.ts`), e le
43155
+ * due non vanno unificate: quella risponde a "qual è la PAROLA di stato per una
43156
+ * regola" (e include `presence`, `cover`, `alarm-panel`), questa a "qual è il
43157
+ * booleano il cui FRONTE conta". Vocabolari deliberatamente diversi.
43158
+ */
43159
+ /**
43160
+ * Known binary / switch source caps → the boolean slice field whose
43161
+ * false→true rise counts as ACTIVE. Every entry is "fire on active".
43162
+ * Sensors whose "active" reading is not a plain boolean (presence's string
43163
+ * state, connectivity's connected flag) are deliberately excluded — a
43164
+ * reconnect is not a doorbell press, and it is not a recording either.
43165
+ */
43166
+ var SOURCE_CAP_ACTIVE_FIELD = {
43167
+ contact: "entryOpen",
43168
+ binary: "on",
43169
+ switch: "on",
43170
+ motion: "detected",
43171
+ flood: "flooded",
43172
+ gas: "detected",
43173
+ smoke: "detected",
43174
+ "carbon-monoxide": "detected",
43175
+ vibration: "detected",
43176
+ tamper: "tampered"
43177
+ };
43178
+ /**
42864
43179
  * Accessory device helpers — shared across drivers.
42865
43180
  *
42866
43181
  * Many vendor-specific drivers register accessory child devices on
@@ -47067,12 +47382,30 @@ Object.freeze({
47067
47382
  addonId: null,
47068
47383
  access: "create"
47069
47384
  },
47385
+ "llmRuntime.appleAvailability": {
47386
+ capName: "llm-runtime",
47387
+ capScope: "system",
47388
+ addonId: null,
47389
+ access: "view"
47390
+ },
47391
+ "llmRuntime.cancel": {
47392
+ capName: "llm-runtime",
47393
+ capScope: "system",
47394
+ addonId: null,
47395
+ access: "create"
47396
+ },
47070
47397
  "llmRuntime.complete": {
47071
47398
  capName: "llm-runtime",
47072
47399
  capScope: "system",
47073
47400
  addonId: null,
47074
47401
  access: "create"
47075
47402
  },
47403
+ "llmRuntime.completeApple": {
47404
+ capName: "llm-runtime",
47405
+ capScope: "system",
47406
+ addonId: null,
47407
+ access: "create"
47408
+ },
47076
47409
  "llmRuntime.deleteModel": {
47077
47410
  capName: "llm-runtime",
47078
47411
  capScope: "system",
@@ -47745,6 +48078,12 @@ Object.freeze({
47745
48078
  addonId: null,
47746
48079
  access: "create"
47747
48080
  },
48081
+ "nodes.directory": {
48082
+ capName: "nodes",
48083
+ capScope: "system",
48084
+ addonId: null,
48085
+ access: "view"
48086
+ },
47748
48087
  "nodes.executeQuery": {
47749
48088
  capName: "nodes",
47750
48089
  capScope: "system",
@@ -47913,6 +48252,12 @@ Object.freeze({
47913
48252
  addonId: null,
47914
48253
  access: "view"
47915
48254
  },
48255
+ "notificationRules.getRuleLastRuns": {
48256
+ capName: "notification-rules",
48257
+ capScope: "system",
48258
+ addonId: null,
48259
+ access: "view"
48260
+ },
47916
48261
  "notificationRules.getTemplateCatalog": {
47917
48262
  capName: "notification-rules",
47918
48263
  capScope: "system",
@@ -53509,6 +53854,51 @@ var NC_AUDIO_DEFAULTS = {
53509
53854
  samplingSeconds: 10
53510
53855
  };
53511
53856
  new Set(["devices", "classes"]);
53857
+ /** Every filter, for the callers that must cover all four (guards, tests). */
53858
+ var NC_SYSTEM_EVENT_FILTER_KEYS = [
53859
+ "deviceIds",
53860
+ "deviceTypes",
53861
+ "nodeIds",
53862
+ "packageNames"
53863
+ ];
53864
+ new Map(Object.entries({
53865
+ "device-online": "device-events",
53866
+ "device-offline": "device-events",
53867
+ "device-disabled": "device-events",
53868
+ "device-enabled": "device-events",
53869
+ "device-battery-low": "device-events",
53870
+ "device-battery-normal": "device-events",
53871
+ "device-consumable-low": "device-events",
53872
+ "device-consumable-normal": "device-events",
53873
+ "stream-online": "device-events",
53874
+ "stream-offline": "device-events",
53875
+ "detection-blind": "device-events",
53876
+ "node-online": "system",
53877
+ "node-offline": "system",
53878
+ "node-inference-unavailable": "system",
53879
+ "addon-crash-loop": "system",
53880
+ "addon-update-available": "system",
53881
+ "addon-updated": "system",
53882
+ "server-update-available": "system",
53883
+ "server-updated": "system",
53884
+ "wrapper-update-available": "system",
53885
+ "backup-completed": "system",
53886
+ "export-completed": "system",
53887
+ "alarm-triggered": "alarm",
53888
+ "alarm-armed": "alarm",
53889
+ "alarm-disarmed": "alarm",
53890
+ "alarm-arming": "alarm",
53891
+ "alarm-arm-refused": "alarm",
53892
+ "alarm-pending": "alarm",
53893
+ "alarm-rearmed": "alarm",
53894
+ "alarm-sensor-bypass": "alarm",
53895
+ "alarm-check-failed": "alarm",
53896
+ "camera-online": null,
53897
+ "camera-offline": null,
53898
+ "camera-disabled": null,
53899
+ "camera-enabled": null
53900
+ }));
53901
+ [...NC_SYSTEM_EVENT_FILTER_KEYS];
53512
53902
  NC_AUDIO_DEFAULTS.hitPercent, NC_AUDIO_DEFAULTS.samplingSeconds;
53513
53903
  var WEEKDAY_TO_DAY = {
53514
53904
  Sun: 0,
@@ -53570,6 +53960,39 @@ function isScheduleActive(schedule, atMs) {
53570
53960
  }
53571
53961
  return schedule.invert === true ? !inside : inside;
53572
53962
  }
53963
+ /**
53964
+ * WHICH WAY A BOOLEAN SENSOR MOVED — read off the one slice a sensor event
53965
+ * persists (D640 "a sensor rule fires on the raise, the clear, or both").
53966
+ *
53967
+ * A device-event rule over a flood sensor notified on BOTH edges: water
53968
+ * detected, and back to dry. `NcConditions.sensorTransition` lets the rule
53969
+ * name one edge; this file answers, for one `SensorEvent`, which edge it is.
53970
+ *
53971
+ * NOT A SECOND TABLE. The "which boolean of this cap counts as HIGH" question
53972
+ * already has one answer, `SOURCE_CAP_ACTIVE_FIELD`
53973
+ * (`catalogs/sensor-active-state.ts`, the doorbell's and the recorder's edge
53974
+ * table), and a sensor event names its kind, not its cap. So the table here is
53975
+ * DERIVED: event kind → cap (`EVENT_KIND_BY_CAP`) → that cap's active field.
53976
+ * Only kinds whose taxonomy category is `sensor` take part — a switch has an
53977
+ * `on` boolean too, but "it triggers / it clears" is not a sentence about a
53978
+ * light, and offering it there would be a knob with a misleading label.
53979
+ * `presence` is a WORD (`home` / `not_home` / a zone), not a boolean, and is
53980
+ * absent from the source table, so it is absent here.
53981
+ *
53982
+ * `undefined` = never guessed: a kind with no raise (a doorbell press, a
53983
+ * button, a cover), or a slice whose field is missing or not a boolean. The
53984
+ * engine then does NOT filter — a flood alert must not go silent because one
53985
+ * read came back unreadable (the same stance as the alarm's `sensorEdgeOf`).
53986
+ *
53987
+ * Pure, RN-safe: the viewer imports the support rule from here.
53988
+ */
53989
+ /** Event kind → the boolean field of its cap slice that means "raised". */
53990
+ var NC_SENSOR_RAISED_FIELD_BY_KIND = Object.freeze(Object.fromEntries(Object.entries(EVENT_KIND_BY_CAP).flatMap(([capName, descriptor]) => {
53991
+ const field = SOURCE_CAP_ACTIVE_FIELD[capName];
53992
+ if (field === void 0 || descriptor.category !== "sensor") return [];
53993
+ return [[descriptor.kind, field]];
53994
+ })));
53995
+ Object.freeze(Object.keys(NC_SENSOR_RAISED_FIELD_BY_KIND));
53573
53996
  var RULE_BODY_ONLY = ["body"];
53574
53997
  var RULE_TEXT = ["title", "body"];
53575
53998
  var BATTERY = ["device-battery-low", "device-battery-normal"];
@@ -1,5 +1,5 @@
1
1
  import { h as e, l as t, u as n, y as r } from "./_virtual_mf___mfe_internal__addon_osd_manager_page__loadShare__react__loadShare__.js-Bs1t18EM.mjs";
2
- import { o as i, s as a } from "./responsive-BOpuh3Lr.mjs";
2
+ import { o as i, s as a } from "./responsive-BpLjT1Jf.mjs";
3
3
  import { n as o, r as s, t as c } from "./_virtual_mf___mfe_internal__addon_osd_manager_page__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-DalfdIDw.mjs";
4
4
  var l = a("chevron-down", [["path", {
5
5
  d: "m6 9 6 6 6-6",
@@ -1,2 +1,2 @@
1
- import { n as e, t } from "./virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_osd_manager_page__remoteEntry_js-C-OUB_74.mjs";
1
+ import { n as e, t } from "./virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_osd_manager_page__remoteEntry_js-CJGlrZlS.mjs";
2
2
  export { t as get, e as init };