@camstack/addon-training 0.1.103 → 0.1.105

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 (23) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/{MotionZonesSettings-HAJ6awj4.mjs → MotionZonesSettings-CTiGmTwm.mjs} +2 -2
  3. package/dist/{PrivacyMaskSettings-BF0NUmVm.mjs → PrivacyMaskSettings-evTcHeEU.mjs} +2 -2
  4. package/dist/{SceneMonitorEditor-CeEWTp0p.mjs → SceneMonitorEditor-C03Xg6cM.mjs} +2 -2
  5. package/dist/_stub.js +6578 -6515
  6. package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_training_page-T_zCH7zZ.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_training_page-1sr2B1A2.mjs} +3 -3
  7. package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-rMgUaeoj.mjs +26 -0
  8. package/dist/addon-training.css +1 -1
  9. package/dist/{dist-Cq0HT75H.js → dist-BhNuTgrA.js} +490 -11
  10. package/dist/{dist-BfxOw6-O.mjs → dist-CCRzGEk1.mjs} +490 -11
  11. package/dist/{hostInit-DRiiL3Ka.mjs → hostInit-Cxx4Eh3M.mjs} +2 -2
  12. package/dist/index.js +1 -1
  13. package/dist/orchestrator/training.addon.js +1 -1
  14. package/dist/orchestrator/training.addon.mjs +1 -1
  15. package/dist/{player-overlays-NVql0bBe.mjs → player-overlays-0haBt2oQ.mjs} +1 -1
  16. package/dist/providers/modal/training-modal.addon.js +1 -1
  17. package/dist/providers/modal/training-modal.addon.mjs +1 -1
  18. package/dist/remoteEntry.js +1 -1
  19. package/dist/{responsive-Cw10UV1G.mjs → responsive-BnXGZLBS.mjs} +1 -1
  20. package/dist/{scene-monitor-copy-BiaQA_PZ.mjs → scene-monitor-copy-Bh54RJt8.mjs} +1 -1
  21. package/dist/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_training_page__remoteEntry_js-Bg8j40fX.mjs → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_training_page__remoteEntry_js-X8CJUTYR.mjs} +399 -390
  22. package/package.json +1 -1
  23. package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CLeWJI6-.mjs +0 -26
@@ -5580,7 +5580,7 @@ var ZodIssueCode = {
5580
5580
  var ZodFirstPartyTypeKind;
5581
5581
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5582
5582
  //#endregion
5583
- //#region ../types/dist/sleep-BAvUCi_2.mjs
5583
+ //#region ../types/dist/sleep-C_u6cEAJ.mjs
5584
5584
  /**
5585
5585
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5586
5586
  * window to float samples (D455).
@@ -8991,6 +8991,7 @@ var CAP_NAMES = Object.freeze([
8991
8991
  "network-link",
8992
8992
  "network-quality",
8993
8993
  "node-certificates",
8994
+ "node-removal-hook",
8994
8995
  "nodes",
8995
8996
  "notification-output",
8996
8997
  "notification-rules",
@@ -9021,6 +9022,7 @@ var CAP_NAMES = Object.freeze([
9021
9022
  "recording-onboard",
9022
9023
  "recording-signal",
9023
9024
  "records",
9025
+ "remote",
9024
9026
  "running-state",
9025
9027
  "scene-monitor",
9026
9028
  "script-runner",
@@ -9044,6 +9046,7 @@ var CAP_NAMES = Object.freeze([
9044
9046
  "system",
9045
9047
  "tamper",
9046
9048
  "temperature-sensor",
9049
+ "template",
9047
9050
  "terminal-session",
9048
9051
  "toast",
9049
9052
  "training",
@@ -9984,6 +9987,11 @@ Object.freeze({
9984
9987
  "standby"
9985
9988
  ]
9986
9989
  },
9990
+ {
9991
+ "path": "stateSource",
9992
+ "valueType": "enum",
9993
+ "enumValues": ["reported", "assumed"]
9994
+ },
9987
9995
  {
9988
9996
  "path": "volumeLevel",
9989
9997
  "valueType": "number"
@@ -10259,6 +10267,18 @@ Object.freeze({
10259
10267
  {
10260
10268
  "path": "volume",
10261
10269
  "valueType": "number"
10270
+ },
10271
+ {
10272
+ "path": "lastFeedGrams",
10273
+ "valueType": "number"
10274
+ },
10275
+ {
10276
+ "path": "lastFeedHopper1",
10277
+ "valueType": "number"
10278
+ },
10279
+ {
10280
+ "path": "lastFeedHopper2",
10281
+ "valueType": "number"
10262
10282
  }
10263
10283
  ],
10264
10284
  "power-meter": [
@@ -11150,7 +11170,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
11150
11170
  return DeviceRole;
11151
11171
  }({});
11152
11172
  //#endregion
11153
- //#region ../types/dist/composition-DpFv_J6D.mjs
11173
+ //#region ../types/dist/composition-bIBW5_13.mjs
11154
11174
  /**
11155
11175
  * The ffmpeg build every CamStack node downloads, per platform and arch.
11156
11176
  *
@@ -42748,6 +42768,14 @@ method(object({
42748
42768
  kind: "mutation",
42749
42769
  auth: "admin"
42750
42770
  });
42771
+ method(object({
42772
+ nodeId: string().min(1),
42773
+ /** Epoch ms the node was forgotten (the tombstone's `removedAt`). */
42774
+ removedAt: number()
42775
+ }), object({ counts: record(string(), number().int().nonnegative()) }), {
42776
+ kind: "mutation",
42777
+ auth: "admin"
42778
+ });
42751
42779
  /**
42752
42780
  * `device-removal-hook` — the reliable way an addon learns a device was DELETED,
42753
42781
  * so it can delete what it keeps for that device (D865).
@@ -57760,6 +57788,318 @@ DeviceType.Light, method(object({
57760
57788
  level: number().min(0).max(100),
57761
57789
  lastChangedAt: number()
57762
57790
  });
57791
+ /**
57792
+ * The role vocabulary of a remote (D963): what a button MEANS, independent of
57793
+ * how it is wired. A layout template places buttons by role; a device binds a
57794
+ * role to an action; an exporter asks for a role by name. Roles are shared so
57795
+ * one layout fits every appliance and one voice command fits every binding.
57796
+ *
57797
+ * A role outside this list is `custom:<key>` — the operator's own button (a
57798
+ * SmartIR source, a channel preset). The key is a lowercase slug.
57799
+ */
57800
+ var REMOTE_KNOWN_ROLES = [
57801
+ "power",
57802
+ "power_on",
57803
+ "power_off",
57804
+ "volume_up",
57805
+ "volume_down",
57806
+ "mute",
57807
+ "channel_up",
57808
+ "channel_down",
57809
+ "up",
57810
+ "down",
57811
+ "left",
57812
+ "right",
57813
+ "ok",
57814
+ "back",
57815
+ "home",
57816
+ "menu",
57817
+ "info",
57818
+ "guide",
57819
+ "exit",
57820
+ "input",
57821
+ "play",
57822
+ "pause",
57823
+ "play_pause",
57824
+ "stop",
57825
+ "next",
57826
+ "previous",
57827
+ "fast_forward",
57828
+ "rewind",
57829
+ "digit_0",
57830
+ "digit_1",
57831
+ "digit_2",
57832
+ "digit_3",
57833
+ "digit_4",
57834
+ "digit_5",
57835
+ "digit_6",
57836
+ "digit_7",
57837
+ "digit_8",
57838
+ "digit_9"
57839
+ ];
57840
+ var CUSTOM_KEY_RE = /^[a-z0-9][a-z0-9_]{0,47}$/;
57841
+ var KNOWN_ROLES = new Set(REMOTE_KNOWN_ROLES);
57842
+ function isRemoteKnownRole(value) {
57843
+ return KNOWN_ROLES.has(value);
57844
+ }
57845
+ function isRemoteCustomKey(key) {
57846
+ return CUSTOM_KEY_RE.test(key);
57847
+ }
57848
+ /** The key of a `custom:<key>` role, or null for any other string. */
57849
+ function customKeyOfRole(role) {
57850
+ if (!role.startsWith("custom:")) return null;
57851
+ const key = role.slice(7);
57852
+ return isRemoteCustomKey(key) ? key : null;
57853
+ }
57854
+ function isRemoteRole(value) {
57855
+ return isRemoteKnownRole(value) || customKeyOfRole(value) !== null;
57856
+ }
57857
+ var RemoteRoleSchema = string().refine(isRemoteRole, { message: "a role is one of the known roles or custom:<key> (lowercase letters, digits, _)" });
57858
+ var RemoteBindingSchema = object({ action: AutomationCapStepSchema.extend({ deviceId: number().int().nonnegative() }) });
57859
+ var RemoteCustomButtonSchema = object({
57860
+ /** The slug after `custom:` in the role. */
57861
+ key: string().refine(isRemoteCustomKey, { message: "a lowercase slug" }),
57862
+ /** What the operator calls it, and what a voice command may name. */
57863
+ name: string().min(1).max(60)
57864
+ });
57865
+ var RemotePowerModeSchema = _enum(["toggle", "discrete"]);
57866
+ var RemoteConfigSchema = object({
57867
+ layoutTemplateId: string().min(1).nullable(),
57868
+ /**
57869
+ * The transmitter device new bindings and an import send through. A binding
57870
+ * names its own device, so one command may override it.
57871
+ */
57872
+ defaultTransmitterId: number().int().nonnegative().nullable().default(null),
57873
+ /** Keyed by role. A role with no entry falls back to the native cap. */
57874
+ bindings: record(string(), RemoteBindingSchema),
57875
+ customButtons: array(RemoteCustomButtonSchema).max(100),
57876
+ power: object({ mode: RemotePowerModeSchema })
57877
+ }).superRefine((config, ctx) => {
57878
+ const roles = Object.keys(config.bindings);
57879
+ if (roles.length > 200) ctx.addIssue({
57880
+ code: "custom",
57881
+ message: "too many bindings",
57882
+ path: ["bindings"]
57883
+ });
57884
+ for (const role of roles) if (!isRemoteRole(role)) ctx.addIssue({
57885
+ code: "custom",
57886
+ message: `"${role}" is not a role`,
57887
+ path: ["bindings", role]
57888
+ });
57889
+ const keys = /* @__PURE__ */ new Set();
57890
+ config.customButtons.forEach((button, index) => {
57891
+ if (keys.has(button.key)) ctx.addIssue({
57892
+ code: "custom",
57893
+ message: `custom button "${button.key}" is listed twice`,
57894
+ path: [
57895
+ "customButtons",
57896
+ index,
57897
+ "key"
57898
+ ]
57899
+ });
57900
+ keys.add(button.key);
57901
+ });
57902
+ for (const role of roles) {
57903
+ const key = customKeyOfRole(role);
57904
+ if (key !== null && !keys.has(key)) ctx.addIssue({
57905
+ code: "custom",
57906
+ message: `${role} is bound but has no entry in customButtons`,
57907
+ path: ["bindings", role]
57908
+ });
57909
+ }
57910
+ });
57911
+ object({
57912
+ power: object({
57913
+ state: _enum(["on", "off"]),
57914
+ at: number()
57915
+ }).nullable(),
57916
+ muted: object({
57917
+ value: boolean(),
57918
+ at: number()
57919
+ }).nullable()
57920
+ });
57921
+ var RemoteLayoutButtonSchema = object({
57922
+ id: string().min(1).max(40),
57923
+ /** 0-based grid position. */
57924
+ row: number().int().min(0).max(24),
57925
+ col: number().int().min(0).max(24),
57926
+ rowSpan: number().int().min(1).max(24),
57927
+ colSpan: number().int().min(1).max(24),
57928
+ icon: string().min(1).max(60).optional(),
57929
+ label: string().min(1).max(40).optional(),
57930
+ role: RemoteRoleSchema
57931
+ });
57932
+ object({
57933
+ columns: number().int().min(1).max(24),
57934
+ rows: number().int().min(1).max(24),
57935
+ buttons: array(RemoteLayoutButtonSchema).max(200)
57936
+ }).superRefine((grid, ctx) => {
57937
+ const ids = /* @__PURE__ */ new Set();
57938
+ const taken = /* @__PURE__ */ new Map();
57939
+ grid.buttons.forEach((button, index) => {
57940
+ if (ids.has(button.id)) ctx.addIssue({
57941
+ code: "custom",
57942
+ message: `button id "${button.id}" is used twice`,
57943
+ path: [
57944
+ "buttons",
57945
+ index,
57946
+ "id"
57947
+ ]
57948
+ });
57949
+ ids.add(button.id);
57950
+ if (button.row + button.rowSpan > grid.rows || button.col + button.colSpan > grid.columns) {
57951
+ ctx.addIssue({
57952
+ code: "custom",
57953
+ message: `button "${button.id}" leaves the grid`,
57954
+ path: ["buttons", index]
57955
+ });
57956
+ return;
57957
+ }
57958
+ for (let r = button.row; r < button.row + button.rowSpan; r += 1) for (let c = button.col; c < button.col + button.colSpan; c += 1) {
57959
+ const cell = `${r}:${c}`;
57960
+ const other = taken.get(cell);
57961
+ if (other !== void 0) {
57962
+ ctx.addIssue({
57963
+ code: "custom",
57964
+ message: `buttons "${other}" and "${button.id}" overlap`,
57965
+ path: ["buttons", index]
57966
+ });
57967
+ return;
57968
+ }
57969
+ taken.set(cell, button.id);
57970
+ }
57971
+ });
57972
+ });
57973
+ var RemoteBoundCommandSchema = object({
57974
+ role: RemoteRoleSchema,
57975
+ /** The operator's name for a custom button; absent for a known role. */
57976
+ label: string().optional(),
57977
+ custom: boolean()
57978
+ });
57979
+ var RemoteCommandListSchema = object({
57980
+ layoutTemplateId: string().nullable(),
57981
+ power: object({ mode: RemotePowerModeSchema }),
57982
+ /** Only the roles that are BOUND — the ones a press can reach. */
57983
+ commands: array(RemoteBoundCommandSchema)
57984
+ });
57985
+ var RemoteRefusalReasonSchema = _enum([
57986
+ "no-remote",
57987
+ "unbound-role",
57988
+ "action-failed"
57989
+ ]);
57990
+ var RemoteSendResultSchema = discriminatedUnion("status", [
57991
+ object({
57992
+ status: literal("sent"),
57993
+ /** How many times the action ran. */
57994
+ sends: number().int().min(1)
57995
+ }),
57996
+ object({
57997
+ status: literal("skipped"),
57998
+ reason: literal("already-in-state")
57999
+ }),
58000
+ object({
58001
+ status: literal("refused"),
58002
+ reason: RemoteRefusalReasonSchema,
58003
+ detail: string().optional()
58004
+ })
58005
+ ]);
58006
+ var RemoteMediaCommandSchema = _enum([
58007
+ "play",
58008
+ "pause",
58009
+ "stop",
58010
+ "next",
58011
+ "previous",
58012
+ "setMute",
58013
+ "selectSource"
58014
+ ]);
58015
+ /** A send result, or `not-routed`: the role is not bound, so the native cap answers. */
58016
+ var RemoteMediaCommandResultSchema = discriminatedUnion("status", [...RemoteSendResultSchema.options, object({ status: literal("not-routed") })]);
58017
+ var RemoteSetConfigResultSchema = discriminatedUnion("status", [object({ status: literal("saved") }), object({
58018
+ status: literal("refused"),
58019
+ reason: _enum(["unknown-template", "not-a-media-player"]),
58020
+ detail: string()
58021
+ })]);
58022
+ var deviceInput = object({ deviceId: number().int().nonnegative() });
58023
+ DeviceType.MediaPlayer;
58024
+ method(deviceInput, RemoteConfigSchema, { auth: "admin" }), method(deviceInput.extend({ config: RemoteConfigSchema }), RemoteSetConfigResultSchema, {
58025
+ kind: "mutation",
58026
+ auth: "admin"
58027
+ }), method(deviceInput, RemoteCommandListSchema, { auth: "protected" }), method(deviceInput.extend({
58028
+ role: RemoteRoleSchema,
58029
+ /** Sends in a row (volume steps). */
58030
+ repeat: number().int().min(1).max(50).default(1)
58031
+ }), RemoteSendResultSchema, {
58032
+ kind: "mutation",
58033
+ auth: "protected"
58034
+ }), method(deviceInput.extend({
58035
+ command: RemoteMediaCommandSchema,
58036
+ muted: boolean().optional(),
58037
+ source: string().optional(),
58038
+ repeat: number().int().min(1).max(50).default(1)
58039
+ }), RemoteMediaCommandResultSchema, {
58040
+ kind: "mutation",
58041
+ auth: "protected"
58042
+ });
58043
+ var TemplateKindSchema = _enum(["remote"]);
58044
+ /**
58045
+ * template — the generic store of reusable, named operator data (D963). A
58046
+ * record is `{ id, kind, name, payload }`; the kinds (today only `remote`, the
58047
+ * button grid of a remote) and the schema each payload must satisfy are
58048
+ * declared by the system in `template-kinds.ts`. Nothing here is specific to a
58049
+ * kind: the engine validates a payload against its kind's schema and, on a
58050
+ * delete, asks the kind's owner whether anything still points at the record.
58051
+ *
58052
+ * Every refusal is a typed result — a UI says "unknown kind" or names the
58053
+ * devices that still use a template, without parsing text.
58054
+ */
58055
+ var TemplateRecordSchema = object({
58056
+ id: string().min(1),
58057
+ kind: TemplateKindSchema,
58058
+ name: string().min(1).max(120),
58059
+ /** Shaped by the kind; `checkTemplatePayload(kind, payload)` reads it. */
58060
+ payload: unknown(),
58061
+ createdAt: number(),
58062
+ updatedAt: number()
58063
+ });
58064
+ var TemplateWriteResultSchema = discriminatedUnion("status", [object({
58065
+ status: literal("saved"),
58066
+ template: TemplateRecordSchema
58067
+ }), object({
58068
+ status: literal("refused"),
58069
+ reason: _enum(["invalid-payload", "not-found"]),
58070
+ detail: string()
58071
+ })]);
58072
+ /** A device still pointing at a template. */
58073
+ var TemplateUserSchema = object({
58074
+ deviceId: number().int().nonnegative(),
58075
+ name: string()
58076
+ });
58077
+ var TemplateDeleteResultSchema = discriminatedUnion("status", [
58078
+ object({ status: literal("deleted") }),
58079
+ object({ status: literal("not-found") }),
58080
+ object({
58081
+ status: literal("in-use"),
58082
+ devices: array(TemplateUserSchema).min(1)
58083
+ })
58084
+ ]);
58085
+ method(object({ kind: TemplateKindSchema.optional() }), array(TemplateRecordSchema), { auth: "protected" }), method(object({ id: string().min(1) }), TemplateRecordSchema.nullable(), { auth: "protected" }), method(object({
58086
+ kind: TemplateKindSchema,
58087
+ name: string().min(1).max(120),
58088
+ payload: unknown()
58089
+ }), TemplateWriteResultSchema, {
58090
+ kind: "mutation",
58091
+ auth: "admin"
58092
+ }), method(object({
58093
+ id: string().min(1),
58094
+ name: string().min(1).max(120).optional(),
58095
+ payload: unknown().optional()
58096
+ }), TemplateWriteResultSchema, {
58097
+ kind: "mutation",
58098
+ auth: "admin"
58099
+ }), method(object({ id: string().min(1) }), TemplateDeleteResultSchema, {
58100
+ kind: "mutation",
58101
+ auth: "admin"
58102
+ });
57763
58103
  DeviceType.Button, method(object({ deviceId: number().int().nonnegative() }), _void(), {
57764
58104
  kind: "mutation",
57765
58105
  auth: "protected"
@@ -60509,9 +60849,35 @@ var MediaInfoSchema = object({
60509
60849
  /** Optional cover-art / thumbnail URL. */
60510
60850
  imageUrl: string().optional()
60511
60851
  });
60852
+ /**
60853
+ * Where `state`, `volumeLevel`, `isMuted` and `source` come from. `reported`:
60854
+ * the device said so. `assumed`: the driver has no feedback (infrared) and
60855
+ * tracks what it last SENT; it moves only after a send was accepted, and a
60856
+ * human at the real remote makes it wrong. A UI shows an assumed value as a
60857
+ * guess, never as a reading.
60858
+ */
60859
+ var MediaPlayerStateSourceSchema = _enum(["reported", "assumed"]);
60860
+ /** The fields of a media-player status a driver can only guess. */
60861
+ var MediaPlayerAssumedFieldSchema = _enum([
60862
+ "state",
60863
+ "volumeLevel",
60864
+ "isMuted",
60865
+ "source"
60866
+ ]);
60512
60867
  object({
60513
60868
  /** Playback lifecycle state. */
60514
60869
  state: MediaPlayerStateSchema,
60870
+ /**
60871
+ * Whether the state fields are readings or the driver's own bookkeeping.
60872
+ * A slice written before this field existed parses as `reported`.
60873
+ */
60874
+ stateSource: MediaPlayerStateSourceSchema.default("reported"),
60875
+ /**
60876
+ * Which fields are the driver's own guess. `stateSource` is `assumed` when
60877
+ * this is not empty; a field not listed here is a reading even then (power
60878
+ * from a running-state source, mute guessed from the last send).
60879
+ */
60880
+ assumedFields: array(MediaPlayerAssumedFieldSchema).default([]),
60515
60881
  /** Volume as 0..100 inclusive. Null when the device has no volume
60516
60882
  * surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
60517
60883
  volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
@@ -61952,6 +62318,14 @@ object({
61952
62318
  feedSound: boolean(),
61953
62319
  /** Speaker / prompt volume level (device-scaled integer). */
61954
62320
  volume: number().meta(readingMeta("none")),
62321
+ /** Portion (grams) of the last manual feed sent from a single-hopper
62322
+ * stepper — the default the next manual feed starts from. Persisted per
62323
+ * device by the provider; null until a manual feed has been sent. */
62324
+ lastFeedGrams: gramsPortion.nullable(),
62325
+ /** Hopper-1 portion of the last manual feed (dual-hopper); null until sent. */
62326
+ lastFeedHopper1: gramsPortion.nullable(),
62327
+ /** Hopper-2 portion of the last manual feed (dual-hopper); null until sent. */
62328
+ lastFeedHopper2: gramsPortion.nullable(),
61955
62329
  /** Ms epoch when the slice was last refreshed from the cloud. */
61956
62330
  lastFetchedAt: number()
61957
62331
  });
@@ -66695,9 +67069,17 @@ var trainingCapability = {
66695
67069
  })
66696
67070
  }
66697
67071
  };
67072
+ discriminatedUnion("kind", [object({
67073
+ kind: literal("raw"),
67074
+ timings: array(number().int()),
67075
+ settings: TransmitSettingsSchema.optional()
67076
+ }), object({
67077
+ kind: literal("pronto"),
67078
+ code: string()
67079
+ })]);
66698
67080
  DeviceFeature.FanSpeed, DeviceFeature.FanPreset, DeviceFeature.FanDirection, DeviceFeature.FanOscillating, DeviceFeature.CoverPositionable, DeviceFeature.CoverTilt, DeviceFeature.ValvePositionable, DeviceFeature.MediaPlayerVolume, DeviceFeature.ClimateFanMode;
66699
67081
  SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
66700
- 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;
67082
+ 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;
66701
67083
  String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
66702
67084
  DeviceRole.BinarySensor, DeviceRole.MotionSensor;
66703
67085
  new Set(CAP_NAMES);
@@ -71548,6 +71930,13 @@ Object.freeze({
71548
71930
  access: "create",
71549
71931
  role: "admin"
71550
71932
  },
71933
+ "nodeRemovalHook.onNodeRemoved": {
71934
+ capName: "node-removal-hook",
71935
+ capScope: "system",
71936
+ addonId: null,
71937
+ access: "create",
71938
+ role: "admin"
71939
+ },
71551
71940
  "nodes.clusterAddonStatus": {
71552
71941
  capName: "nodes",
71553
71942
  capScope: "system",
@@ -74439,6 +74828,41 @@ Object.freeze({
74439
74828
  access: "create",
74440
74829
  role: "admin"
74441
74830
  },
74831
+ "remote.getConfig": {
74832
+ capName: "remote",
74833
+ capScope: "system",
74834
+ addonId: null,
74835
+ access: "view",
74836
+ role: "admin"
74837
+ },
74838
+ "remote.listCommands": {
74839
+ capName: "remote",
74840
+ capScope: "system",
74841
+ addonId: null,
74842
+ access: "view",
74843
+ role: "admin"
74844
+ },
74845
+ "remote.sendCommand": {
74846
+ capName: "remote",
74847
+ capScope: "system",
74848
+ addonId: null,
74849
+ access: "create",
74850
+ role: "admin"
74851
+ },
74852
+ "remote.sendMediaCommand": {
74853
+ capName: "remote",
74854
+ capScope: "system",
74855
+ addonId: null,
74856
+ access: "create",
74857
+ role: "admin"
74858
+ },
74859
+ "remote.setConfig": {
74860
+ capName: "remote",
74861
+ capScope: "system",
74862
+ addonId: null,
74863
+ access: "create",
74864
+ role: "admin"
74865
+ },
74442
74866
  "runningState.getStatus": {
74443
74867
  capName: "running-state",
74444
74868
  capScope: "device",
@@ -75629,6 +76053,41 @@ Object.freeze({
75629
76053
  access: "view",
75630
76054
  role: "viewer"
75631
76055
  },
76056
+ "template.create": {
76057
+ capName: "template",
76058
+ capScope: "system",
76059
+ addonId: null,
76060
+ access: "create",
76061
+ role: "admin"
76062
+ },
76063
+ "template.delete": {
76064
+ capName: "template",
76065
+ capScope: "system",
76066
+ addonId: null,
76067
+ access: "delete",
76068
+ role: "admin"
76069
+ },
76070
+ "template.get": {
76071
+ capName: "template",
76072
+ capScope: "system",
76073
+ addonId: null,
76074
+ access: "view",
76075
+ role: "admin"
76076
+ },
76077
+ "template.list": {
76078
+ capName: "template",
76079
+ capScope: "system",
76080
+ addonId: null,
76081
+ access: "view",
76082
+ role: "admin"
76083
+ },
76084
+ "template.update": {
76085
+ capName: "template",
76086
+ capScope: "system",
76087
+ addonId: null,
76088
+ access: "create",
76089
+ role: "admin"
76090
+ },
75632
76091
  "terminalSession.adoptLegacyMonitor": {
75633
76092
  capName: "terminal-session",
75634
76093
  capScope: "system",
@@ -80421,6 +80880,7 @@ var SYSTEM_CAP_VOCABULARY = {
80421
80880
  "device-manager": system("the device registry itself — rename, move and remove are administration"),
80422
80881
  "device-provider": system(INTERNAL),
80423
80882
  "device-removal-hook": system(INTERNAL),
80883
+ "node-removal-hook": system(INTERNAL),
80424
80884
  "device-state": system("the runtime-state mirror every trigger already reads through"),
80425
80885
  "display-palette": system("the cluster display palette — one colour table for every client, not a device action"),
80426
80886
  "embedding-encoder": system(ML),
@@ -80460,6 +80920,7 @@ var SYSTEM_CAP_VOCABULARY = {
80460
80920
  "recording-archive": system(STORAGE),
80461
80921
  "recording-export": system("recording exports — requested from the timeline, not an automation step"),
80462
80922
  records: system(INTERNAL),
80923
+ remote: system("the per-device remote setup — authored in the Customize remote editor, sent through the remote UI"),
80463
80924
  "server-management": system(CLUSTER),
80464
80925
  "settings-store": system(INTERNAL),
80465
80926
  "smtp-provider": system(INTERNAL),
@@ -80472,6 +80933,7 @@ var SYSTEM_CAP_VOCABULARY = {
80472
80933
  "storage-provider": system(STORAGE),
80473
80934
  "stream-broker": system(PIPELINE),
80474
80935
  system: system(CLUSTER),
80936
+ template: system("operator-authored templates — edited in their own editor, never actuated"),
80475
80937
  "terminal-session": system(CLUSTER),
80476
80938
  toast: system(UI_PLUMBING),
80477
80939
  training: system(ML),
@@ -82898,6 +83360,31 @@ Object.freeze({
82898
83360
  form: "single",
82899
83361
  optional: true
82900
83362
  }],
83363
+ "remote.getConfig": [{
83364
+ name: "deviceId",
83365
+ form: "single",
83366
+ optional: false
83367
+ }],
83368
+ "remote.listCommands": [{
83369
+ name: "deviceId",
83370
+ form: "single",
83371
+ optional: false
83372
+ }],
83373
+ "remote.sendCommand": [{
83374
+ name: "deviceId",
83375
+ form: "single",
83376
+ optional: false
83377
+ }],
83378
+ "remote.sendMediaCommand": [{
83379
+ name: "deviceId",
83380
+ form: "single",
83381
+ optional: false
83382
+ }],
83383
+ "remote.setConfig": [{
83384
+ name: "deviceId",
83385
+ form: "single",
83386
+ optional: false
83387
+ }],
82901
83388
  "runningState.getStatus": [{
82902
83389
  name: "deviceId",
82903
83390
  form: "single",
@@ -84706,14 +85193,6 @@ DEFAULT_NATIVE_LEASE_SETTINGS.admission;
84706
85193
  String.raw`(?<=^|["'(\s>,\[{])`;
84707
85194
  var MB = 1024 * 1024;
84708
85195
  1024 * MB, 3072 * MB;
84709
- discriminatedUnion("kind", [object({
84710
- kind: literal("raw"),
84711
- timings: array(number().int()),
84712
- settings: TransmitSettingsSchema.optional()
84713
- }), object({
84714
- kind: literal("pronto"),
84715
- code: string()
84716
- })]);
84717
85196
  object({
84718
85197
  manufacturer: string().optional(),
84719
85198
  supportedModels: array(string()).optional(),
@@ -36,7 +36,7 @@ async function r() {
36
36
  }
37
37
  },
38
38
  "@camstack/types": {
39
- version: "1.2.440",
39
+ version: "1.2.443",
40
40
  scope: "default",
41
41
  shareConfig: {
42
42
  singleton: !0,
@@ -81,7 +81,7 @@ async function r() {
81
81
  }
82
82
  },
83
83
  "@camstack/ui-library": {
84
- version: "1.2.347",
84
+ version: "1.2.349",
85
85
  scope: "default",
86
86
  shareConfig: {
87
87
  singleton: !0,
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- require("./dist-Cq0HT75H.js");
2
+ require("./dist-BhNuTgrA.js");
3
3
  const require_orchestrator_training_addon = require("./orchestrator/training.addon.js");
4
4
  const require_providers_modal_training_modal_addon = require("./providers/modal/training-modal.addon.js");
5
5
  //#region src/providers/fake/fake-provider.ts
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_dist = require("../dist-Cq0HT75H.js");
2
+ const require_dist = require("../dist-BhNuTgrA.js");
3
3
  let node_path = require("node:path");
4
4
  node_path = require_dist.__toESM(node_path);
5
5
  let node_crypto = require("node:crypto");
@@ -1,4 +1,4 @@
1
- import { a as addonPagesSourceCapability, i as TrainingResultSchema, l as BaseAddon, m as defineRecordKinds, n as TrainingJobSchema, o as parseTrainingEventLine, r as TrainingJobSpecSchema, s as trainingCapability, t as TRAINING_JOB_SCHEMA, u as RECORD_MAX_DATA_BYTES } from "../dist-BfxOw6-O.mjs";
1
+ import { a as addonPagesSourceCapability, i as TrainingResultSchema, l as BaseAddon, m as defineRecordKinds, n as TrainingJobSchema, o as parseTrainingEventLine, r as TrainingJobSpecSchema, s as trainingCapability, t as TRAINING_JOB_SCHEMA, u as RECORD_MAX_DATA_BYTES } from "../dist-CCRzGEk1.mjs";
2
2
  import path from "node:path";
3
3
  import { createHash } from "node:crypto";
4
4
  import { createReadStream } from "node:fs";
@@ -1,7 +1,7 @@
1
1
  import { d as e, u as t, w as n, y as r } from "./_virtual_mf___mfe_internal__addon_training_page__loadShare__react__loadShare__.js-CEvdvp1T.mjs";
2
2
  import { n as i, r as a, t as o } from "./_virtual_mf___mfe_internal__addon_training_page__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-DnrbBvrw.mjs";
3
3
  import { n as s, t as c } from "./chevron-right-cA8Hucbi.mjs";
4
- import { g as l } from "./responsive-Cw10UV1G.mjs";
4
+ import { g as l } from "./responsive-BnXGZLBS.mjs";
5
5
  //#region ../ui-library/src/composites/widget-panel.tsx
6
6
  n();
7
7
  function u({ title: e, icon: t, headerRight: n, collapsible: l = !1, defaultOpen: u = !0, open: d, onOpenChange: f, bodyClassName: p = "p-3", children: m }) {