@camstack/addon-post-analysis 1.2.649 → 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 +12 -0
  2. package/dist/{clip-model-registry-DLCu17dL.mjs → clip-model-registry-BWY8P-AK.mjs} +620 -7
  3. package/dist/{clip-model-registry-BweA9zEK.js → clip-model-registry-Dte3QQEt.js} +620 -7
  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-DFq-lnbD.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-Dog0wpFI.mjs → hostInit-A7m5uu3n.mjs} +2 -2
  11. package/dist/pipeline-analytics/index.js +148 -3
  12. package/dist/pipeline-analytics/index.mjs +148 -4
  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-YDf26qsN.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-DQTr4r2P.mjs +0 -26
@@ -5645,7 +5645,7 @@ var ZodIssueCode = {
5645
5645
  var ZodFirstPartyTypeKind;
5646
5646
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5647
5647
  //#endregion
5648
- //#region ../types/dist/sleep-Crlmu_tO.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).
@@ -9078,6 +9078,7 @@ var CAP_NAMES = Object.freeze([
9078
9078
  "image-settings",
9079
9079
  "integrations",
9080
9080
  "intercom",
9081
+ "ir-transmitter",
9081
9082
  "keychain",
9082
9083
  "keychain-admin",
9083
9084
  "lawn-mower-control",
@@ -9106,6 +9107,7 @@ var CAP_NAMES = Object.freeze([
9106
9107
  "network-link",
9107
9108
  "network-quality",
9108
9109
  "node-certificates",
9110
+ "node-removal-hook",
9109
9111
  "nodes",
9110
9112
  "notification-output",
9111
9113
  "notification-rules",
@@ -9136,6 +9138,7 @@ var CAP_NAMES = Object.freeze([
9136
9138
  "recording-onboard",
9137
9139
  "recording-signal",
9138
9140
  "records",
9141
+ "remote",
9139
9142
  "running-state",
9140
9143
  "scene-monitor",
9141
9144
  "script-runner",
@@ -9159,6 +9162,7 @@ var CAP_NAMES = Object.freeze([
9159
9162
  "system",
9160
9163
  "tamper",
9161
9164
  "temperature-sensor",
9165
+ "template",
9162
9166
  "terminal-session",
9163
9167
  "toast",
9164
9168
  "training",
@@ -10099,6 +10103,11 @@ Object.freeze({
10099
10103
  "standby"
10100
10104
  ]
10101
10105
  },
10106
+ {
10107
+ "path": "stateSource",
10108
+ "valueType": "enum",
10109
+ "enumValues": ["reported", "assumed"]
10110
+ },
10102
10111
  {
10103
10112
  "path": "volumeLevel",
10104
10113
  "valueType": "number"
@@ -10325,6 +10334,11 @@ Object.freeze({
10325
10334
  "path": "batteryPower",
10326
10335
  "valueType": "number"
10327
10336
  },
10337
+ {
10338
+ "path": "powerSource",
10339
+ "valueType": "enum",
10340
+ "enumValues": ["mains", "battery"]
10341
+ },
10328
10342
  {
10329
10343
  "path": "desiccantLeftDays",
10330
10344
  "valueType": "number"
@@ -10369,6 +10383,18 @@ Object.freeze({
10369
10383
  {
10370
10384
  "path": "volume",
10371
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"
10372
10398
  }
10373
10399
  ],
10374
10400
  "power-meter": [
@@ -10910,7 +10936,7 @@ Object.freeze({
10910
10936
  * can answer "may a rule actuate this?" without importing the schema barrel
10911
10937
  * (~144MB RSS per runner, D28).
10912
10938
  *
10913
- * Coverage: 95 device-scoped capabilities.
10939
+ * Coverage: 96 device-scoped capabilities.
10914
10940
  */
10915
10941
  var DEVICE_SCOPED_CAPS = new Set([
10916
10942
  "accessories",
@@ -10960,6 +10986,7 @@ var DEVICE_SCOPED_CAPS = new Set([
10960
10986
  "image",
10961
10987
  "image-settings",
10962
10988
  "intercom",
10989
+ "ir-transmitter",
10963
10990
  "lawn-mower-control",
10964
10991
  "lock-control",
10965
10992
  "media-player",
@@ -11053,7 +11080,7 @@ function sleep(ms) {
11053
11080
  return new Promise((resolve) => setTimeout(resolve, Math.max(0, ms)));
11054
11081
  }
11055
11082
  //#endregion
11056
- //#region ../types/dist/err-msg-DIorGYeC.mjs
11083
+ //#region ../types/dist/err-msg-BCdlR2Li.mjs
11057
11084
  var DeviceType = /* @__PURE__ */ function(DeviceType) {
11058
11085
  DeviceType["Camera"] = "camera";
11059
11086
  DeviceType["Hub"] = "hub";
@@ -11399,6 +11426,9 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
11399
11426
  /** Fallback when the notifier service name doesn't match a known
11400
11427
  * pattern. */
11401
11428
  DeviceRole["GenericNotifier"] = "generic-notifier";
11429
+ /** Emits a pulse train (infrared or RF) on request — the `ir-transmitter`
11430
+ * cap. A `DeviceType.Generic` device. */
11431
+ DeviceRole["IrTransmitter"] = "ir-transmitter";
11402
11432
  return DeviceRole;
11403
11433
  }({});
11404
11434
  /**
@@ -11412,7 +11442,7 @@ function errMsg(err) {
11412
11442
  return String(err);
11413
11443
  }
11414
11444
  //#endregion
11415
- //#region ../types/dist/composition-DwA0uVW5.mjs
11445
+ //#region ../types/dist/composition-bIBW5_13.mjs
11416
11446
  /**
11417
11447
  * Deterministic SHA-256 hash of an arbitrary serialisable value. The
11418
11448
  * canonical form sorts object keys alphabetically at every depth so two
@@ -17783,9 +17813,21 @@ var AlertSeveritySchema = _enum([
17783
17813
  "error",
17784
17814
  "critical"
17785
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). */
17786
17827
  var AlertActionSchema = object({
17787
17828
  label: string(),
17788
17829
  href: string().optional(),
17830
+ invoke: AlertActionInvokeSchema.optional(),
17789
17831
  /**
17790
17832
  * How `href` is followed. Absent / `app`: an admin-ui route (client-side).
17791
17833
  * `server`: a route the HUB serves (an addon HTTP route such as an OAuth
@@ -44227,6 +44269,14 @@ var embeddingEncoderCapability = {
44227
44269
  })
44228
44270
  }
44229
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
+ });
44230
44280
  /**
44231
44281
  * `device-removal-hook` — the reliable way an addon learns a device was DELETED,
44232
44282
  * so it can delete what it keeps for that device (D865).
@@ -44996,6 +45046,17 @@ var LlmProfileSchema = object({
44996
45046
  * field in its editor only when its descriptor lists it in `profileFields`. */
44997
45047
  topK: number().int().positive().optional(),
44998
45048
  maxTokens: number().int().positive().optional(),
45049
+ /** How hard the model "thinks" before it answers. Omitted = the model's own
45050
+ * default. `off` matters for structured output: a thinking model can spend
45051
+ * the whole completion on reasoning and return an empty `content`. Carried
45052
+ * only by the wires that have it — a kind offers the field in its editor
45053
+ * only when its descriptor lists it in `profileFields`. */
45054
+ reasoningEffort: _enum([
45055
+ "off",
45056
+ "low",
45057
+ "medium",
45058
+ "high"
45059
+ ]).optional(),
44999
45060
  /** Prompt context window. Advisory for cloud kinds (they enforce their own). */
45000
45061
  contextLength: number().int().positive().optional(),
45001
45062
  /** Default system prompt. A caller's `system` REPLACES it (never appends —
@@ -45034,6 +45095,7 @@ var LlmProfileFieldSchema = _enum([
45034
45095
  "topP",
45035
45096
  "topK",
45036
45097
  "maxTokens",
45098
+ "reasoningEffort",
45037
45099
  "contextLength",
45038
45100
  "systemPrompt",
45039
45101
  "timeoutMs",
@@ -61744,11 +61806,373 @@ onBrightnessChanged: { data: object({
61744
61806
  minIntervalMs: 0
61745
61807
  } } }
61746
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
+ });
61747
62121
  DeviceType.Button, method(object({ deviceId: number().int().nonnegative() }), _void(), {
61748
62122
  kind: "mutation",
61749
62123
  auth: "protected"
61750
62124
  });
61751
62125
  /**
62126
+ * A pulse train in signed microseconds: mark (+) first, then space (-), strictly
62127
+ * alternating, no zeros, 2..1024 entries.
62128
+ */
62129
+ var IrTimingsSchema = array(number().int()).min(2).max(1024).superRefine((timings, ctx) => {
62130
+ timings.forEach((value, index) => {
62131
+ const expectMark = index % 2 === 0;
62132
+ if (value === 0 || value > 0 !== expectMark) ctx.addIssue({
62133
+ code: "custom",
62134
+ message: `timing ${index} must be a non-zero ${expectMark ? "mark (positive)" : "space (negative)"}`,
62135
+ path: [index]
62136
+ });
62137
+ });
62138
+ });
62139
+ /** Per-command transmit options. Every key is optional; a transmitter applies what it can. */
62140
+ var TransmitSettingsSchema = object({
62141
+ carrierHz: number().int().positive().optional(),
62142
+ dutyCyclePercent: number().int().min(1).max(100).optional(),
62143
+ repeat: number().int().min(0).max(20).optional(),
62144
+ repeatDelayMs: number().int().min(0).optional()
62145
+ });
62146
+ /** The setting keys a transmitter may declare as settable (`getInfo.settable`). */
62147
+ var TransmitSettingKeySchema = _enum([
62148
+ "carrierHz",
62149
+ "dutyCyclePercent",
62150
+ "repeat",
62151
+ "repeatDelayMs"
62152
+ ]);
62153
+ var IrMediumSchema = _enum(["ir", "rf"]);
62154
+ var IrSendResultSchema = object({
62155
+ ok: literal(true),
62156
+ /** Settings the transmitter could not apply; the train was still sent. */
62157
+ ignoredSettings: array(string())
62158
+ });
62159
+ var IrTransmitterInfoSchema = object({
62160
+ media: array(IrMediumSchema),
62161
+ settable: array(TransmitSettingKeySchema),
62162
+ maxTimings: number().int().positive()
62163
+ });
62164
+ DeviceType.Generic, method(object({
62165
+ deviceId: number().int().nonnegative(),
62166
+ timings: IrTimingsSchema,
62167
+ settings: TransmitSettingsSchema.optional()
62168
+ }), IrSendResultSchema, {
62169
+ kind: "mutation",
62170
+ auth: "protected"
62171
+ }), method(object({ deviceId: number().int().nonnegative() }), IrTransmitterInfoSchema, {
62172
+ kind: "query",
62173
+ auth: "protected"
62174
+ });
62175
+ /**
61752
62176
  * `calendar-source` — collection cap exposing per-provider calendars and
61753
62177
  * their events. Every addon that contributes calendars (Home Assistant,
61754
62178
  * a future Google Calendar addon, …) registers a provider here. The hub
@@ -65969,9 +66393,35 @@ var MediaInfoSchema = object({
65969
66393
  /** Optional cover-art / thumbnail URL. */
65970
66394
  imageUrl: string().optional()
65971
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
+ ]);
65972
66411
  var MediaPlayerStatusSchema = object({
65973
66412
  /** Playback lifecycle state. */
65974
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([]),
65975
66425
  /** Volume as 0..100 inclusive. Null when the device has no volume
65976
66426
  * surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
65977
66427
  volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
@@ -67924,9 +68374,14 @@ var PetFeederStatusSchema = object({
67924
68374
  * (`device_class: problem`, on = low). True when the tank reports empty,
67925
68375
  * or, on a dual-hopper model, when EITHER hopper is empty. */
67926
68376
  lowFood: boolean(),
67927
- /** Battery charge 0..100 (%). Null on mains-powered models or when the
67928
- * device has no battery reading. */
68377
+ /** Battery charge 0..100 (%). On a feeder running on `mains` this is the
68378
+ * BACKUP battery's charge, not the power source. Null when the device has
68379
+ * no battery reading. */
67929
68380
  batteryPower: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
68381
+ /** What the feeder is powered from right now: `mains` (plugged in, the
68382
+ * battery is only a backup) or `battery`. Null when the device does not
68383
+ * report it. */
68384
+ powerSource: _enum(["mains", "battery"]).nullable(),
67930
68385
  /**
67931
68386
  * Desiccant life remaining, stored in seconds (duration base, D944).
67932
68387
  * Providers convert from the days the feeder reports. Null when the
@@ -67954,6 +68409,14 @@ var PetFeederStatusSchema = object({
67954
68409
  feedSound: boolean(),
67955
68410
  /** Speaker / prompt volume level (device-scaled integer). */
67956
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(),
67957
68420
  /** Ms epoch when the slice was last refreshed from the cloud. */
67958
68421
  lastFetchedAt: number()
67959
68422
  });
@@ -74076,9 +74539,17 @@ method(object({}), array(TrainingBaseModelSchema).readonly(), { auth: "admin" })
74076
74539
  kind: "mutation",
74077
74540
  auth: "admin"
74078
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
+ })]);
74079
74550
  DeviceFeature.FanSpeed, DeviceFeature.FanPreset, DeviceFeature.FanDirection, DeviceFeature.FanOscillating, DeviceFeature.CoverPositionable, DeviceFeature.CoverTilt, DeviceFeature.ValvePositionable, DeviceFeature.MediaPlayerVolume, DeviceFeature.ClimateFanMode;
74080
74551
  SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
74081
- 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;
74082
74553
  String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
74083
74554
  DeviceRole.BinarySensor, DeviceRole.MotionSensor;
74084
74555
  new Set(CAP_NAMES);
@@ -78801,6 +79272,20 @@ Object.freeze({
78801
79272
  access: "create",
78802
79273
  role: "viewer"
78803
79274
  },
79275
+ "irTransmitter.getInfo": {
79276
+ capName: "ir-transmitter",
79277
+ capScope: "device",
79278
+ addonId: null,
79279
+ access: "view",
79280
+ role: "viewer"
79281
+ },
79282
+ "irTransmitter.send": {
79283
+ capName: "ir-transmitter",
79284
+ capScope: "device",
79285
+ addonId: null,
79286
+ access: "create",
79287
+ role: "viewer"
79288
+ },
78804
79289
  "keychain.delete": {
78805
79290
  capName: "keychain",
78806
79291
  capScope: "system",
@@ -80033,6 +80518,13 @@ Object.freeze({
80033
80518
  access: "create",
80034
80519
  role: "admin"
80035
80520
  },
80521
+ "nodeRemovalHook.onNodeRemoved": {
80522
+ capName: "node-removal-hook",
80523
+ capScope: "system",
80524
+ addonId: null,
80525
+ access: "create",
80526
+ role: "admin"
80527
+ },
80036
80528
  "nodes.clusterAddonStatus": {
80037
80529
  capName: "nodes",
80038
80530
  capScope: "system",
@@ -82924,6 +83416,41 @@ Object.freeze({
82924
83416
  access: "create",
82925
83417
  role: "admin"
82926
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
+ },
82927
83454
  "runningState.getStatus": {
82928
83455
  capName: "running-state",
82929
83456
  capScope: "device",
@@ -84114,6 +84641,41 @@ Object.freeze({
84114
84641
  access: "view",
84115
84642
  role: "viewer"
84116
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
+ },
84117
84679
  "terminalSession.adoptLegacyMonitor": {
84118
84680
  capName: "terminal-session",
84119
84681
  capScope: "system",
@@ -86424,6 +86986,11 @@ var ACTUATOR_CAP_VOCABULARY = {
86424
86986
  icon: "circle-dot"
86425
86987
  }]
86426
86988
  },
86989
+ "ir-transmitter": {
86990
+ scope: "device",
86991
+ noun: t("IR / RF transmitter", "Trasmettitore IR / RF"),
86992
+ notOperatorFacing: { send: "a raw pulse train is not something an operator composes in an automation; the remote that owns the command table sends it" }
86993
+ },
86427
86994
  control: {
86428
86995
  scope: "device",
86429
86996
  noun: t("Control", "Controllo"),
@@ -88901,6 +89468,7 @@ var SYSTEM_CAP_VOCABULARY = {
88901
89468
  "device-manager": system("the device registry itself — rename, move and remove are administration"),
88902
89469
  "device-provider": system(INTERNAL),
88903
89470
  "device-removal-hook": system(INTERNAL),
89471
+ "node-removal-hook": system(INTERNAL),
88904
89472
  "device-state": system("the runtime-state mirror every trigger already reads through"),
88905
89473
  "display-palette": system("the cluster display palette — one colour table for every client, not a device action"),
88906
89474
  "embedding-encoder": system(ML),
@@ -88940,6 +89508,7 @@ var SYSTEM_CAP_VOCABULARY = {
88940
89508
  "recording-archive": system(STORAGE),
88941
89509
  "recording-export": system("recording exports — requested from the timeline, not an automation step"),
88942
89510
  records: system(INTERNAL),
89511
+ remote: system("the per-device remote setup — authored in the Customize remote editor, sent through the remote UI"),
88943
89512
  "server-management": system(CLUSTER),
88944
89513
  "settings-store": system(INTERNAL),
88945
89514
  "smtp-provider": system(INTERNAL),
@@ -88952,6 +89521,7 @@ var SYSTEM_CAP_VOCABULARY = {
88952
89521
  "storage-provider": system(STORAGE),
88953
89522
  "stream-broker": system(PIPELINE),
88954
89523
  system: system(CLUSTER),
89524
+ template: system("operator-authored templates — edited in their own editor, never actuated"),
88955
89525
  "terminal-session": system(CLUSTER),
88956
89526
  toast: system(UI_PLUMBING),
88957
89527
  training: system(ML),
@@ -90143,6 +90713,16 @@ Object.freeze({
90143
90713
  form: "single",
90144
90714
  optional: false
90145
90715
  }],
90716
+ "irTransmitter.getInfo": [{
90717
+ name: "deviceId",
90718
+ form: "single",
90719
+ optional: false
90720
+ }],
90721
+ "irTransmitter.send": [{
90722
+ name: "deviceId",
90723
+ form: "single",
90724
+ optional: false
90725
+ }],
90146
90726
  "keychain.deleteDeviceScope": [{
90147
90727
  name: "deviceId",
90148
90728
  form: "single",
@@ -91368,6 +91948,31 @@ Object.freeze({
91368
91948
  form: "single",
91369
91949
  optional: true
91370
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
+ }],
91371
91976
  "runningState.getStatus": [{
91372
91977
  name: "deviceId",
91373
91978
  form: "single",
@@ -96737,6 +97342,14 @@ function armRemovalReconcile(opts) {
96737
97342
  timer.unref?.();
96738
97343
  return () => clearInterval(timer);
96739
97344
  }
97345
+ object({
97346
+ manufacturer: string().optional(),
97347
+ supportedModels: array(string()).optional(),
97348
+ supportedController: string().optional(),
97349
+ commandsEncoding: string(),
97350
+ delay: number().nonnegative().optional(),
97351
+ commands: record(string(), unknown())
97352
+ });
96740
97353
  //#endregion
96741
97354
  //#region src/pipeline-analytics/cluster-model-pin.ts
96742
97355
  /**