@camstack/addon-post-analysis 1.2.650 → 1.2.651

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 (16) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/{clip-model-registry-B_mY0hd7.mjs → clip-model-registry-BWY8P-AK.mjs} +502 -11
  3. package/dist/{clip-model-registry-CC7pvitG.js → clip-model-registry-Dte3QQEt.js} +502 -11
  4. package/dist/embedding-encoder/index.js +1 -1
  5. package/dist/embedding-encoder/index.mjs +1 -1
  6. package/dist/pipeline-analytics/_stub.js +2 -2
  7. package/dist/pipeline-analytics/{_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-HjnmptAc.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-_vVfXkDx.mjs} +2 -2
  8. package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-6PIugMbv.mjs +26 -0
  9. package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-Bk6VlAsZ.mjs +26 -0
  10. package/dist/pipeline-analytics/{hostInit-BjUFFpLS.mjs → hostInit-A7m5uu3n.mjs} +2 -2
  11. package/dist/pipeline-analytics/index.js +40 -2
  12. package/dist/pipeline-analytics/index.mjs +40 -3
  13. package/dist/pipeline-analytics/remoteEntry.js +1 -1
  14. package/package.json +1 -1
  15. package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-YNYqWfWY.mjs +0 -26
  16. package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-OPayQG8i.mjs +0 -26
package/CHANGELOG.md CHANGED
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.2.651] - 2026-10-29
11
+
12
+ ### Changed
13
+
14
+ - The live detection overlay no longer shows boxes from replayed pre-roll frames
15
+
10
16
  ## [1.2.650] - 2026-10-28
11
17
 
12
18
  ### Changed
@@ -5645,7 +5645,7 @@ var ZodIssueCode = {
5645
5645
  var ZodFirstPartyTypeKind;
5646
5646
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5647
5647
  //#endregion
5648
- //#region ../types/dist/sleep-BAvUCi_2.mjs
5648
+ //#region ../types/dist/sleep-C_u6cEAJ.mjs
5649
5649
  /**
5650
5650
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5651
5651
  * window to float samples (D455).
@@ -9107,6 +9107,7 @@ var CAP_NAMES = Object.freeze([
9107
9107
  "network-link",
9108
9108
  "network-quality",
9109
9109
  "node-certificates",
9110
+ "node-removal-hook",
9110
9111
  "nodes",
9111
9112
  "notification-output",
9112
9113
  "notification-rules",
@@ -9137,6 +9138,7 @@ var CAP_NAMES = Object.freeze([
9137
9138
  "recording-onboard",
9138
9139
  "recording-signal",
9139
9140
  "records",
9141
+ "remote",
9140
9142
  "running-state",
9141
9143
  "scene-monitor",
9142
9144
  "script-runner",
@@ -9160,6 +9162,7 @@ var CAP_NAMES = Object.freeze([
9160
9162
  "system",
9161
9163
  "tamper",
9162
9164
  "temperature-sensor",
9165
+ "template",
9163
9166
  "terminal-session",
9164
9167
  "toast",
9165
9168
  "training",
@@ -10100,6 +10103,11 @@ Object.freeze({
10100
10103
  "standby"
10101
10104
  ]
10102
10105
  },
10106
+ {
10107
+ "path": "stateSource",
10108
+ "valueType": "enum",
10109
+ "enumValues": ["reported", "assumed"]
10110
+ },
10103
10111
  {
10104
10112
  "path": "volumeLevel",
10105
10113
  "valueType": "number"
@@ -10375,6 +10383,18 @@ Object.freeze({
10375
10383
  {
10376
10384
  "path": "volume",
10377
10385
  "valueType": "number"
10386
+ },
10387
+ {
10388
+ "path": "lastFeedGrams",
10389
+ "valueType": "number"
10390
+ },
10391
+ {
10392
+ "path": "lastFeedHopper1",
10393
+ "valueType": "number"
10394
+ },
10395
+ {
10396
+ "path": "lastFeedHopper2",
10397
+ "valueType": "number"
10378
10398
  }
10379
10399
  ],
10380
10400
  "power-meter": [
@@ -11422,7 +11442,7 @@ function errMsg(err) {
11422
11442
  return String(err);
11423
11443
  }
11424
11444
  //#endregion
11425
- //#region ../types/dist/composition-DpFv_J6D.mjs
11445
+ //#region ../types/dist/composition-bIBW5_13.mjs
11426
11446
  /**
11427
11447
  * Deterministic SHA-256 hash of an arbitrary serialisable value. The
11428
11448
  * canonical form sorts object keys alphabetically at every depth so two
@@ -17793,9 +17813,21 @@ var AlertSeveritySchema = _enum([
17793
17813
  "error",
17794
17814
  "critical"
17795
17815
  ]);
17816
+ /**
17817
+ * An action that RUNS something instead of going somewhere: the admin UI calls
17818
+ * the addon's custom action (`addons.custom`) with exactly these fields. The
17819
+ * producer owns the meaning; the UI knows nothing about the addon or the kind.
17820
+ */
17821
+ var AlertActionInvokeSchema = object({
17822
+ addonId: string().min(1),
17823
+ action: string().min(1),
17824
+ input: record(string(), unknown()).optional()
17825
+ });
17826
+ /** An action has `href` (a link) OR `invoke` (a button that runs a custom action). */
17796
17827
  var AlertActionSchema = object({
17797
17828
  label: string(),
17798
17829
  href: string().optional(),
17830
+ invoke: AlertActionInvokeSchema.optional(),
17799
17831
  /**
17800
17832
  * How `href` is followed. Absent / `app`: an admin-ui route (client-side).
17801
17833
  * `server`: a route the HUB serves (an addon HTTP route such as an OAuth
@@ -44237,6 +44269,14 @@ var embeddingEncoderCapability = {
44237
44269
  })
44238
44270
  }
44239
44271
  };
44272
+ method(object({
44273
+ nodeId: string().min(1),
44274
+ /** Epoch ms the node was forgotten (the tombstone's `removedAt`). */
44275
+ removedAt: number()
44276
+ }), object({ counts: record(string(), number().int().nonnegative()) }), {
44277
+ kind: "mutation",
44278
+ auth: "admin"
44279
+ });
44240
44280
  /**
44241
44281
  * `device-removal-hook` — the reliable way an addon learns a device was DELETED,
44242
44282
  * so it can delete what it keeps for that device (D865).
@@ -61766,6 +61806,318 @@ onBrightnessChanged: { data: object({
61766
61806
  minIntervalMs: 0
61767
61807
  } } }
61768
61808
  };
61809
+ /**
61810
+ * The role vocabulary of a remote (D963): what a button MEANS, independent of
61811
+ * how it is wired. A layout template places buttons by role; a device binds a
61812
+ * role to an action; an exporter asks for a role by name. Roles are shared so
61813
+ * one layout fits every appliance and one voice command fits every binding.
61814
+ *
61815
+ * A role outside this list is `custom:<key>` — the operator's own button (a
61816
+ * SmartIR source, a channel preset). The key is a lowercase slug.
61817
+ */
61818
+ var REMOTE_KNOWN_ROLES = [
61819
+ "power",
61820
+ "power_on",
61821
+ "power_off",
61822
+ "volume_up",
61823
+ "volume_down",
61824
+ "mute",
61825
+ "channel_up",
61826
+ "channel_down",
61827
+ "up",
61828
+ "down",
61829
+ "left",
61830
+ "right",
61831
+ "ok",
61832
+ "back",
61833
+ "home",
61834
+ "menu",
61835
+ "info",
61836
+ "guide",
61837
+ "exit",
61838
+ "input",
61839
+ "play",
61840
+ "pause",
61841
+ "play_pause",
61842
+ "stop",
61843
+ "next",
61844
+ "previous",
61845
+ "fast_forward",
61846
+ "rewind",
61847
+ "digit_0",
61848
+ "digit_1",
61849
+ "digit_2",
61850
+ "digit_3",
61851
+ "digit_4",
61852
+ "digit_5",
61853
+ "digit_6",
61854
+ "digit_7",
61855
+ "digit_8",
61856
+ "digit_9"
61857
+ ];
61858
+ var CUSTOM_KEY_RE = /^[a-z0-9][a-z0-9_]{0,47}$/;
61859
+ var KNOWN_ROLES = new Set(REMOTE_KNOWN_ROLES);
61860
+ function isRemoteKnownRole(value) {
61861
+ return KNOWN_ROLES.has(value);
61862
+ }
61863
+ function isRemoteCustomKey(key) {
61864
+ return CUSTOM_KEY_RE.test(key);
61865
+ }
61866
+ /** The key of a `custom:<key>` role, or null for any other string. */
61867
+ function customKeyOfRole(role) {
61868
+ if (!role.startsWith("custom:")) return null;
61869
+ const key = role.slice(7);
61870
+ return isRemoteCustomKey(key) ? key : null;
61871
+ }
61872
+ function isRemoteRole(value) {
61873
+ return isRemoteKnownRole(value) || customKeyOfRole(value) !== null;
61874
+ }
61875
+ var RemoteRoleSchema = string().refine(isRemoteRole, { message: "a role is one of the known roles or custom:<key> (lowercase letters, digits, _)" });
61876
+ var RemoteBindingSchema = object({ action: AutomationCapStepSchema.extend({ deviceId: number().int().nonnegative() }) });
61877
+ var RemoteCustomButtonSchema = object({
61878
+ /** The slug after `custom:` in the role. */
61879
+ key: string().refine(isRemoteCustomKey, { message: "a lowercase slug" }),
61880
+ /** What the operator calls it, and what a voice command may name. */
61881
+ name: string().min(1).max(60)
61882
+ });
61883
+ var RemotePowerModeSchema = _enum(["toggle", "discrete"]);
61884
+ var RemoteConfigSchema = object({
61885
+ layoutTemplateId: string().min(1).nullable(),
61886
+ /**
61887
+ * The transmitter device new bindings and an import send through. A binding
61888
+ * names its own device, so one command may override it.
61889
+ */
61890
+ defaultTransmitterId: number().int().nonnegative().nullable().default(null),
61891
+ /** Keyed by role. A role with no entry falls back to the native cap. */
61892
+ bindings: record(string(), RemoteBindingSchema),
61893
+ customButtons: array(RemoteCustomButtonSchema).max(100),
61894
+ power: object({ mode: RemotePowerModeSchema })
61895
+ }).superRefine((config, ctx) => {
61896
+ const roles = Object.keys(config.bindings);
61897
+ if (roles.length > 200) ctx.addIssue({
61898
+ code: "custom",
61899
+ message: "too many bindings",
61900
+ path: ["bindings"]
61901
+ });
61902
+ for (const role of roles) if (!isRemoteRole(role)) ctx.addIssue({
61903
+ code: "custom",
61904
+ message: `"${role}" is not a role`,
61905
+ path: ["bindings", role]
61906
+ });
61907
+ const keys = /* @__PURE__ */ new Set();
61908
+ config.customButtons.forEach((button, index) => {
61909
+ if (keys.has(button.key)) ctx.addIssue({
61910
+ code: "custom",
61911
+ message: `custom button "${button.key}" is listed twice`,
61912
+ path: [
61913
+ "customButtons",
61914
+ index,
61915
+ "key"
61916
+ ]
61917
+ });
61918
+ keys.add(button.key);
61919
+ });
61920
+ for (const role of roles) {
61921
+ const key = customKeyOfRole(role);
61922
+ if (key !== null && !keys.has(key)) ctx.addIssue({
61923
+ code: "custom",
61924
+ message: `${role} is bound but has no entry in customButtons`,
61925
+ path: ["bindings", role]
61926
+ });
61927
+ }
61928
+ });
61929
+ object({
61930
+ power: object({
61931
+ state: _enum(["on", "off"]),
61932
+ at: number()
61933
+ }).nullable(),
61934
+ muted: object({
61935
+ value: boolean(),
61936
+ at: number()
61937
+ }).nullable()
61938
+ });
61939
+ var RemoteLayoutButtonSchema = object({
61940
+ id: string().min(1).max(40),
61941
+ /** 0-based grid position. */
61942
+ row: number().int().min(0).max(24),
61943
+ col: number().int().min(0).max(24),
61944
+ rowSpan: number().int().min(1).max(24),
61945
+ colSpan: number().int().min(1).max(24),
61946
+ icon: string().min(1).max(60).optional(),
61947
+ label: string().min(1).max(40).optional(),
61948
+ role: RemoteRoleSchema
61949
+ });
61950
+ object({
61951
+ columns: number().int().min(1).max(24),
61952
+ rows: number().int().min(1).max(24),
61953
+ buttons: array(RemoteLayoutButtonSchema).max(200)
61954
+ }).superRefine((grid, ctx) => {
61955
+ const ids = /* @__PURE__ */ new Set();
61956
+ const taken = /* @__PURE__ */ new Map();
61957
+ grid.buttons.forEach((button, index) => {
61958
+ if (ids.has(button.id)) ctx.addIssue({
61959
+ code: "custom",
61960
+ message: `button id "${button.id}" is used twice`,
61961
+ path: [
61962
+ "buttons",
61963
+ index,
61964
+ "id"
61965
+ ]
61966
+ });
61967
+ ids.add(button.id);
61968
+ if (button.row + button.rowSpan > grid.rows || button.col + button.colSpan > grid.columns) {
61969
+ ctx.addIssue({
61970
+ code: "custom",
61971
+ message: `button "${button.id}" leaves the grid`,
61972
+ path: ["buttons", index]
61973
+ });
61974
+ return;
61975
+ }
61976
+ for (let r = button.row; r < button.row + button.rowSpan; r += 1) for (let c = button.col; c < button.col + button.colSpan; c += 1) {
61977
+ const cell = `${r}:${c}`;
61978
+ const other = taken.get(cell);
61979
+ if (other !== void 0) {
61980
+ ctx.addIssue({
61981
+ code: "custom",
61982
+ message: `buttons "${other}" and "${button.id}" overlap`,
61983
+ path: ["buttons", index]
61984
+ });
61985
+ return;
61986
+ }
61987
+ taken.set(cell, button.id);
61988
+ }
61989
+ });
61990
+ });
61991
+ var RemoteBoundCommandSchema = object({
61992
+ role: RemoteRoleSchema,
61993
+ /** The operator's name for a custom button; absent for a known role. */
61994
+ label: string().optional(),
61995
+ custom: boolean()
61996
+ });
61997
+ var RemoteCommandListSchema = object({
61998
+ layoutTemplateId: string().nullable(),
61999
+ power: object({ mode: RemotePowerModeSchema }),
62000
+ /** Only the roles that are BOUND — the ones a press can reach. */
62001
+ commands: array(RemoteBoundCommandSchema)
62002
+ });
62003
+ var RemoteRefusalReasonSchema = _enum([
62004
+ "no-remote",
62005
+ "unbound-role",
62006
+ "action-failed"
62007
+ ]);
62008
+ var RemoteSendResultSchema = discriminatedUnion("status", [
62009
+ object({
62010
+ status: literal("sent"),
62011
+ /** How many times the action ran. */
62012
+ sends: number().int().min(1)
62013
+ }),
62014
+ object({
62015
+ status: literal("skipped"),
62016
+ reason: literal("already-in-state")
62017
+ }),
62018
+ object({
62019
+ status: literal("refused"),
62020
+ reason: RemoteRefusalReasonSchema,
62021
+ detail: string().optional()
62022
+ })
62023
+ ]);
62024
+ var RemoteMediaCommandSchema = _enum([
62025
+ "play",
62026
+ "pause",
62027
+ "stop",
62028
+ "next",
62029
+ "previous",
62030
+ "setMute",
62031
+ "selectSource"
62032
+ ]);
62033
+ /** A send result, or `not-routed`: the role is not bound, so the native cap answers. */
62034
+ var RemoteMediaCommandResultSchema = discriminatedUnion("status", [...RemoteSendResultSchema.options, object({ status: literal("not-routed") })]);
62035
+ var RemoteSetConfigResultSchema = discriminatedUnion("status", [object({ status: literal("saved") }), object({
62036
+ status: literal("refused"),
62037
+ reason: _enum(["unknown-template", "not-a-media-player"]),
62038
+ detail: string()
62039
+ })]);
62040
+ var deviceInput = object({ deviceId: number().int().nonnegative() });
62041
+ DeviceType.MediaPlayer;
62042
+ method(deviceInput, RemoteConfigSchema, { auth: "admin" }), method(deviceInput.extend({ config: RemoteConfigSchema }), RemoteSetConfigResultSchema, {
62043
+ kind: "mutation",
62044
+ auth: "admin"
62045
+ }), method(deviceInput, RemoteCommandListSchema, { auth: "protected" }), method(deviceInput.extend({
62046
+ role: RemoteRoleSchema,
62047
+ /** Sends in a row (volume steps). */
62048
+ repeat: number().int().min(1).max(50).default(1)
62049
+ }), RemoteSendResultSchema, {
62050
+ kind: "mutation",
62051
+ auth: "protected"
62052
+ }), method(deviceInput.extend({
62053
+ command: RemoteMediaCommandSchema,
62054
+ muted: boolean().optional(),
62055
+ source: string().optional(),
62056
+ repeat: number().int().min(1).max(50).default(1)
62057
+ }), RemoteMediaCommandResultSchema, {
62058
+ kind: "mutation",
62059
+ auth: "protected"
62060
+ });
62061
+ var TemplateKindSchema = _enum(["remote"]);
62062
+ /**
62063
+ * template — the generic store of reusable, named operator data (D963). A
62064
+ * record is `{ id, kind, name, payload }`; the kinds (today only `remote`, the
62065
+ * button grid of a remote) and the schema each payload must satisfy are
62066
+ * declared by the system in `template-kinds.ts`. Nothing here is specific to a
62067
+ * kind: the engine validates a payload against its kind's schema and, on a
62068
+ * delete, asks the kind's owner whether anything still points at the record.
62069
+ *
62070
+ * Every refusal is a typed result — a UI says "unknown kind" or names the
62071
+ * devices that still use a template, without parsing text.
62072
+ */
62073
+ var TemplateRecordSchema = object({
62074
+ id: string().min(1),
62075
+ kind: TemplateKindSchema,
62076
+ name: string().min(1).max(120),
62077
+ /** Shaped by the kind; `checkTemplatePayload(kind, payload)` reads it. */
62078
+ payload: unknown(),
62079
+ createdAt: number(),
62080
+ updatedAt: number()
62081
+ });
62082
+ var TemplateWriteResultSchema = discriminatedUnion("status", [object({
62083
+ status: literal("saved"),
62084
+ template: TemplateRecordSchema
62085
+ }), object({
62086
+ status: literal("refused"),
62087
+ reason: _enum(["invalid-payload", "not-found"]),
62088
+ detail: string()
62089
+ })]);
62090
+ /** A device still pointing at a template. */
62091
+ var TemplateUserSchema = object({
62092
+ deviceId: number().int().nonnegative(),
62093
+ name: string()
62094
+ });
62095
+ var TemplateDeleteResultSchema = discriminatedUnion("status", [
62096
+ object({ status: literal("deleted") }),
62097
+ object({ status: literal("not-found") }),
62098
+ object({
62099
+ status: literal("in-use"),
62100
+ devices: array(TemplateUserSchema).min(1)
62101
+ })
62102
+ ]);
62103
+ method(object({ kind: TemplateKindSchema.optional() }), array(TemplateRecordSchema), { auth: "protected" }), method(object({ id: string().min(1) }), TemplateRecordSchema.nullable(), { auth: "protected" }), method(object({
62104
+ kind: TemplateKindSchema,
62105
+ name: string().min(1).max(120),
62106
+ payload: unknown()
62107
+ }), TemplateWriteResultSchema, {
62108
+ kind: "mutation",
62109
+ auth: "admin"
62110
+ }), method(object({
62111
+ id: string().min(1),
62112
+ name: string().min(1).max(120).optional(),
62113
+ payload: unknown().optional()
62114
+ }), TemplateWriteResultSchema, {
62115
+ kind: "mutation",
62116
+ auth: "admin"
62117
+ }), method(object({ id: string().min(1) }), TemplateDeleteResultSchema, {
62118
+ kind: "mutation",
62119
+ auth: "admin"
62120
+ });
61769
62121
  DeviceType.Button, method(object({ deviceId: number().int().nonnegative() }), _void(), {
61770
62122
  kind: "mutation",
61771
62123
  auth: "protected"
@@ -66041,9 +66393,35 @@ var MediaInfoSchema = object({
66041
66393
  /** Optional cover-art / thumbnail URL. */
66042
66394
  imageUrl: string().optional()
66043
66395
  });
66396
+ /**
66397
+ * Where `state`, `volumeLevel`, `isMuted` and `source` come from. `reported`:
66398
+ * the device said so. `assumed`: the driver has no feedback (infrared) and
66399
+ * tracks what it last SENT; it moves only after a send was accepted, and a
66400
+ * human at the real remote makes it wrong. A UI shows an assumed value as a
66401
+ * guess, never as a reading.
66402
+ */
66403
+ var MediaPlayerStateSourceSchema = _enum(["reported", "assumed"]);
66404
+ /** The fields of a media-player status a driver can only guess. */
66405
+ var MediaPlayerAssumedFieldSchema = _enum([
66406
+ "state",
66407
+ "volumeLevel",
66408
+ "isMuted",
66409
+ "source"
66410
+ ]);
66044
66411
  var MediaPlayerStatusSchema = object({
66045
66412
  /** Playback lifecycle state. */
66046
66413
  state: MediaPlayerStateSchema,
66414
+ /**
66415
+ * Whether the state fields are readings or the driver's own bookkeeping.
66416
+ * A slice written before this field existed parses as `reported`.
66417
+ */
66418
+ stateSource: MediaPlayerStateSourceSchema.default("reported"),
66419
+ /**
66420
+ * Which fields are the driver's own guess. `stateSource` is `assumed` when
66421
+ * this is not empty; a field not listed here is a reading even then (power
66422
+ * from a running-state source, mute guessed from the last send).
66423
+ */
66424
+ assumedFields: array(MediaPlayerAssumedFieldSchema).default([]),
66047
66425
  /** Volume as 0..100 inclusive. Null when the device has no volume
66048
66426
  * surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
66049
66427
  volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
@@ -68031,6 +68409,14 @@ var PetFeederStatusSchema = object({
68031
68409
  feedSound: boolean(),
68032
68410
  /** Speaker / prompt volume level (device-scaled integer). */
68033
68411
  volume: number().meta(readingMeta("none")),
68412
+ /** Portion (grams) of the last manual feed sent from a single-hopper
68413
+ * stepper — the default the next manual feed starts from. Persisted per
68414
+ * device by the provider; null until a manual feed has been sent. */
68415
+ lastFeedGrams: gramsPortion.nullable(),
68416
+ /** Hopper-1 portion of the last manual feed (dual-hopper); null until sent. */
68417
+ lastFeedHopper1: gramsPortion.nullable(),
68418
+ /** Hopper-2 portion of the last manual feed (dual-hopper); null until sent. */
68419
+ lastFeedHopper2: gramsPortion.nullable(),
68034
68420
  /** Ms epoch when the slice was last refreshed from the cloud. */
68035
68421
  lastFetchedAt: number()
68036
68422
  });
@@ -74153,9 +74539,17 @@ method(object({}), array(TrainingBaseModelSchema).readonly(), { auth: "admin" })
74153
74539
  kind: "mutation",
74154
74540
  auth: "admin"
74155
74541
  });
74542
+ discriminatedUnion("kind", [object({
74543
+ kind: literal("raw"),
74544
+ timings: array(number().int()),
74545
+ settings: TransmitSettingsSchema.optional()
74546
+ }), object({
74547
+ kind: literal("pronto"),
74548
+ code: string()
74549
+ })]);
74156
74550
  DeviceFeature.FanSpeed, DeviceFeature.FanPreset, DeviceFeature.FanDirection, DeviceFeature.FanOscillating, DeviceFeature.CoverPositionable, DeviceFeature.CoverTilt, DeviceFeature.ValvePositionable, DeviceFeature.MediaPlayerVolume, DeviceFeature.ClimateFanMode;
74157
74551
  SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
74158
- DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, DeviceType.EventEmitter, DeviceType.Camera, DeviceType.Hub, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.Dishwasher, DeviceType.Washer, DeviceType.Dryer, DeviceType.Camera, DeviceType.Camera, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
74552
+ DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, DeviceType.EventEmitter, DeviceType.Camera, DeviceType.Hub, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.Dishwasher, DeviceType.Washer, DeviceType.Dryer, DeviceType.Camera, DeviceType.Camera, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
74159
74553
  String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
74160
74554
  DeviceRole.BinarySensor, DeviceRole.MotionSensor;
74161
74555
  new Set(CAP_NAMES);
@@ -80124,6 +80518,13 @@ Object.freeze({
80124
80518
  access: "create",
80125
80519
  role: "admin"
80126
80520
  },
80521
+ "nodeRemovalHook.onNodeRemoved": {
80522
+ capName: "node-removal-hook",
80523
+ capScope: "system",
80524
+ addonId: null,
80525
+ access: "create",
80526
+ role: "admin"
80527
+ },
80127
80528
  "nodes.clusterAddonStatus": {
80128
80529
  capName: "nodes",
80129
80530
  capScope: "system",
@@ -83015,6 +83416,41 @@ Object.freeze({
83015
83416
  access: "create",
83016
83417
  role: "admin"
83017
83418
  },
83419
+ "remote.getConfig": {
83420
+ capName: "remote",
83421
+ capScope: "system",
83422
+ addonId: null,
83423
+ access: "view",
83424
+ role: "admin"
83425
+ },
83426
+ "remote.listCommands": {
83427
+ capName: "remote",
83428
+ capScope: "system",
83429
+ addonId: null,
83430
+ access: "view",
83431
+ role: "admin"
83432
+ },
83433
+ "remote.sendCommand": {
83434
+ capName: "remote",
83435
+ capScope: "system",
83436
+ addonId: null,
83437
+ access: "create",
83438
+ role: "admin"
83439
+ },
83440
+ "remote.sendMediaCommand": {
83441
+ capName: "remote",
83442
+ capScope: "system",
83443
+ addonId: null,
83444
+ access: "create",
83445
+ role: "admin"
83446
+ },
83447
+ "remote.setConfig": {
83448
+ capName: "remote",
83449
+ capScope: "system",
83450
+ addonId: null,
83451
+ access: "create",
83452
+ role: "admin"
83453
+ },
83018
83454
  "runningState.getStatus": {
83019
83455
  capName: "running-state",
83020
83456
  capScope: "device",
@@ -84205,6 +84641,41 @@ Object.freeze({
84205
84641
  access: "view",
84206
84642
  role: "viewer"
84207
84643
  },
84644
+ "template.create": {
84645
+ capName: "template",
84646
+ capScope: "system",
84647
+ addonId: null,
84648
+ access: "create",
84649
+ role: "admin"
84650
+ },
84651
+ "template.delete": {
84652
+ capName: "template",
84653
+ capScope: "system",
84654
+ addonId: null,
84655
+ access: "delete",
84656
+ role: "admin"
84657
+ },
84658
+ "template.get": {
84659
+ capName: "template",
84660
+ capScope: "system",
84661
+ addonId: null,
84662
+ access: "view",
84663
+ role: "admin"
84664
+ },
84665
+ "template.list": {
84666
+ capName: "template",
84667
+ capScope: "system",
84668
+ addonId: null,
84669
+ access: "view",
84670
+ role: "admin"
84671
+ },
84672
+ "template.update": {
84673
+ capName: "template",
84674
+ capScope: "system",
84675
+ addonId: null,
84676
+ access: "create",
84677
+ role: "admin"
84678
+ },
84208
84679
  "terminalSession.adoptLegacyMonitor": {
84209
84680
  capName: "terminal-session",
84210
84681
  capScope: "system",
@@ -88997,6 +89468,7 @@ var SYSTEM_CAP_VOCABULARY = {
88997
89468
  "device-manager": system("the device registry itself — rename, move and remove are administration"),
88998
89469
  "device-provider": system(INTERNAL),
88999
89470
  "device-removal-hook": system(INTERNAL),
89471
+ "node-removal-hook": system(INTERNAL),
89000
89472
  "device-state": system("the runtime-state mirror every trigger already reads through"),
89001
89473
  "display-palette": system("the cluster display palette — one colour table for every client, not a device action"),
89002
89474
  "embedding-encoder": system(ML),
@@ -89036,6 +89508,7 @@ var SYSTEM_CAP_VOCABULARY = {
89036
89508
  "recording-archive": system(STORAGE),
89037
89509
  "recording-export": system("recording exports — requested from the timeline, not an automation step"),
89038
89510
  records: system(INTERNAL),
89511
+ remote: system("the per-device remote setup — authored in the Customize remote editor, sent through the remote UI"),
89039
89512
  "server-management": system(CLUSTER),
89040
89513
  "settings-store": system(INTERNAL),
89041
89514
  "smtp-provider": system(INTERNAL),
@@ -89048,6 +89521,7 @@ var SYSTEM_CAP_VOCABULARY = {
89048
89521
  "storage-provider": system(STORAGE),
89049
89522
  "stream-broker": system(PIPELINE),
89050
89523
  system: system(CLUSTER),
89524
+ template: system("operator-authored templates — edited in their own editor, never actuated"),
89051
89525
  "terminal-session": system(CLUSTER),
89052
89526
  toast: system(UI_PLUMBING),
89053
89527
  training: system(ML),
@@ -91474,6 +91948,31 @@ Object.freeze({
91474
91948
  form: "single",
91475
91949
  optional: true
91476
91950
  }],
91951
+ "remote.getConfig": [{
91952
+ name: "deviceId",
91953
+ form: "single",
91954
+ optional: false
91955
+ }],
91956
+ "remote.listCommands": [{
91957
+ name: "deviceId",
91958
+ form: "single",
91959
+ optional: false
91960
+ }],
91961
+ "remote.sendCommand": [{
91962
+ name: "deviceId",
91963
+ form: "single",
91964
+ optional: false
91965
+ }],
91966
+ "remote.sendMediaCommand": [{
91967
+ name: "deviceId",
91968
+ form: "single",
91969
+ optional: false
91970
+ }],
91971
+ "remote.setConfig": [{
91972
+ name: "deviceId",
91973
+ form: "single",
91974
+ optional: false
91975
+ }],
91477
91976
  "runningState.getStatus": [{
91478
91977
  name: "deviceId",
91479
91978
  form: "single",
@@ -96843,14 +97342,6 @@ function armRemovalReconcile(opts) {
96843
97342
  timer.unref?.();
96844
97343
  return () => clearInterval(timer);
96845
97344
  }
96846
- discriminatedUnion("kind", [object({
96847
- kind: literal("raw"),
96848
- timings: array(number().int()),
96849
- settings: TransmitSettingsSchema.optional()
96850
- }), object({
96851
- kind: literal("pronto"),
96852
- code: string()
96853
- })]);
96854
97345
  object({
96855
97346
  manufacturer: string().optional(),
96856
97347
  supportedModels: array(string()).optional(),