@camstack/addon-admin-ui 1.2.511 → 1.2.513

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 (155) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/assets/{AddonAssetIcon-BhmFaWF6.js → AddonAssetIcon-BXUI3-Tf.js} +1 -1
  3. package/dist/assets/Addons-BbTJ2Fig.js +5 -0
  4. package/dist/assets/{AdminPage-Cywt1sv5.js → AdminPage-DUSx45NB.js} +1 -1
  5. package/dist/assets/{AdminSectionedPage-D8XbpLmz.js → AdminSectionedPage-soMjTdb7.js} +1 -1
  6. package/dist/assets/AiProfiles-Z0lIY6qW.js +3 -0
  7. package/dist/assets/{BrokerEditorDialog-C2p0P4ye.js → BrokerEditorDialog-61ZhKBtB.js} +1 -1
  8. package/dist/assets/Build-DYS91I2j.js +40 -0
  9. package/dist/assets/{Calendars-74ckkFP0.js → Calendars-B70yeC96.js} +1 -1
  10. package/dist/assets/{Cluster-1JwXjjed.js → Cluster-MhCZmNm6.js} +1 -1
  11. package/dist/assets/CompositionBlockEditor-TlnzLRS-.js +1 -0
  12. package/dist/assets/{CompositionEditorPage-DE9Rccl2.js → CompositionEditorPage-BI-Y8v0_.js} +1 -1
  13. package/dist/assets/Data-B-pDPXqV.js +2 -0
  14. package/dist/assets/DeviceDetail-BejggRfL.js +2 -0
  15. package/dist/assets/DeviceDoActionFields-3YdRpdH5.js +1 -0
  16. package/dist/assets/{Devices-DdCovTvt.js → Devices-D38AMunx.js} +1 -1
  17. package/dist/assets/{EmbedPlayerPage-BeuVN1QD.js → EmbedPlayerPage-BBZB_KmG.js} +1 -1
  18. package/dist/assets/HelperWizard-B_3MTQzU.js +2 -0
  19. package/dist/assets/History-v659n-q1.js +1 -0
  20. package/dist/assets/Identity-Dtc3gsXQ.js +1 -0
  21. package/dist/assets/IntegrationDetail-X94WkFek.js +1 -0
  22. package/dist/assets/IntegrationHub-CUAqtcr0.js +1 -0
  23. package/dist/assets/Integrations-BlD0JmVC.js +1 -0
  24. package/dist/assets/Integrations-C-JT0QSz.js +1 -0
  25. package/dist/assets/{Library-D268sj-L.js → Library-BrvU57J_.js} +1 -1
  26. package/dist/assets/Locations-BXbmZQwL.js +3 -0
  27. package/dist/assets/{Logs-IXGaCSMo.js → Logs-B0XBZZ8Q.js} +1 -1
  28. package/dist/assets/{MaskShapeCanvas-D6XVNdwA.js → MaskShapeCanvas-DnEx9aLt.js} +1 -1
  29. package/dist/assets/{MotionZonesSettings-BXHdXw3X.js → MotionZonesSettings-BMDPF6-L.js} +1 -1
  30. package/dist/assets/MyAccess-DfkZc8jj.js +2 -0
  31. package/dist/assets/{Network-sb7soD7f.js → Network-B9UvgIh-.js} +1 -1
  32. package/dist/assets/NodeAddonsSettingsPanel-D8UZOHme.js +1 -0
  33. package/dist/assets/Notifications-2R56_ebY.js +1 -0
  34. package/dist/assets/Pipeline-BdjiguQv.js +1 -0
  35. package/dist/assets/{PrivacyMaskSettings-BXiuTmLQ.js → PrivacyMaskSettings-DXcb1Xsj.js} +1 -1
  36. package/dist/assets/Recordings-BnGaDgIg.js +1 -0
  37. package/dist/assets/RemoteGrid-C_hwBm7-.js +1 -0
  38. package/dist/assets/{ScanNetworkModal-9eawQeIJ.js → ScanNetworkModal-BTQIrvGc.js} +1 -1
  39. package/dist/assets/{SceneMonitorEditor-ChgZnP_I.js → SceneMonitorEditor-BeZzFwDE.js} +1 -1
  40. package/dist/assets/SessionsList-C03j936p.js +2 -0
  41. package/dist/assets/{Showroom-C0KMMGgI.js → Showroom-hqqCXmrT.js} +1 -1
  42. package/dist/assets/System-C9oV_d1y.js +1 -0
  43. package/dist/assets/Templates-cp28J05t.js +1 -0
  44. package/dist/assets/{Terminal-Ct5pxKeO.js → Terminal-C2kXj9wO.js} +3 -3
  45. package/dist/assets/{Viewer-D_HQWvCc.js → Viewer-zU0ym-3m.js} +1 -1
  46. package/dist/assets/{_virtual_mf-localSharedImportMap___mfe_internal__admin_ui_host-BTJLKrn5.js → _virtual_mf-localSharedImportMap___mfe_internal__admin_ui_host-RW_iqTJh.js} +1 -1
  47. package/dist/assets/{addon-icons-context-7pMoFmo9.js → addon-icons-context-Dvq70FHG.js} +1 -1
  48. package/dist/assets/{archive-P7vGIXBL.js → archive-DEQjGSlb.js} +1 -1
  49. package/dist/assets/{assignment-candidates-DctD4-Kk.js → assignment-candidates-CYEy8Oew.js} +1 -1
  50. package/dist/assets/{authed-media-DyWWajaJ.js → authed-media-ei7XgIJl.js} +1 -1
  51. package/dist/assets/automation-data-E3BGzBLE.js +1 -0
  52. package/dist/assets/{bell-off-B4S4Brhx.js → bell-off-BtOUApIg.js} +1 -1
  53. package/dist/assets/{board-model-DKqEIHLh.js → board-model-uN4dojCw.js} +1 -1
  54. package/dist/assets/{boxes-Cc83jXU7.js → boxes-vYLDJNRv.js} +1 -1
  55. package/dist/assets/circle-slash-DG3-Ibc_.js +1 -0
  56. package/dist/assets/client-gOfL8FDq.js +674 -0
  57. package/dist/assets/{cloud-upload-BNAApVPM.js → cloud-upload-CzsF_jzI.js} +1 -1
  58. package/dist/assets/crop-BYOsBPcF.js +1 -0
  59. package/dist/assets/{device-integration-icon-Bh0Znsav.js → device-integration-icon-CMOElaCq.js} +1 -1
  60. package/dist/assets/device-picker-model-CtJOP06v.js +1 -0
  61. package/dist/assets/dist-BIFugJlu.js +674 -0
  62. package/dist/assets/{dist-97mm2unN.js → dist-ODNaReOx.js} +1 -1
  63. package/dist/assets/{eraser-CfQsg9Ve.js → eraser-DdxDfnsw.js} +1 -1
  64. package/dist/assets/file-up-DtWjJzxE.js +1 -0
  65. package/dist/assets/{hard-drive-download-PwUdP9sZ.js → hard-drive-download-BUYTmxO8.js} +1 -1
  66. package/dist/assets/{hostInit-B2k6yhyi.js → hostInit-CEmOeO-p.js} +1 -1
  67. package/dist/assets/i18n-CtSKEBgX.js +1 -0
  68. package/dist/assets/icons-BS95Q050.js +1 -0
  69. package/dist/assets/index-CUQ_1-3M.js +4 -0
  70. package/dist/assets/index-i7JLUpAu.css +2 -0
  71. package/dist/assets/key-BHqMlU3n.js +1 -0
  72. package/dist/assets/{key-round-CBhTR29b.js → key-round-DEGX9D7v.js} +1 -1
  73. package/dist/assets/{layers-C5Yl1IY5.js → layers-CmVPxgW7.js} +1 -1
  74. package/dist/assets/{linked-devices-model-B8JwCaUn.js → linked-devices-model-9YMVfHc9.js} +1 -1
  75. package/dist/assets/{list-ordered-A3gv0vJA.js → list-ordered-CheGo-ag.js} +1 -1
  76. package/dist/assets/location-owned-usage-CkEO8Lym.js +1 -0
  77. package/dist/assets/{log-in-ChqbFBLh.js → log-in-CiEueJS1.js} +1 -1
  78. package/dist/assets/{memory-stick-B__TSEyk.js → memory-stick-BR7h-gLy.js} +1 -1
  79. package/dist/assets/{message-square-plus-BERx-QaF.js → message-square-plus-pFenYopk.js} +1 -1
  80. package/dist/assets/{mf-entry-bootstrap-0-56c74718.js → mf-entry-bootstrap-0-f252a886.js} +2 -2
  81. package/dist/assets/{mic-off-Dyo6dwK_.js → mic-off-Cy2vjOdb.js} +1 -1
  82. package/dist/assets/{monitor-off-Czfm61g6.js → monitor-off-DSnpgX4h.js} +1 -1
  83. package/dist/assets/{monitor-smartphone-tJnvQ6Wt.js → monitor-smartphone-Bbz5EYKE.js} +1 -1
  84. package/dist/assets/mount-CtJOP06v.js +1 -0
  85. package/dist/assets/{player-overlays-B5FSaids.js → player-overlays-CeCeKlFy.js} +1 -1
  86. package/dist/assets/{recycle-droAKct3.js → recycle-CRCqoNuC.js} +1 -1
  87. package/dist/assets/remoteEntry-DHoKCa7I.js +1 -0
  88. package/dist/assets/ruler-D4nA2AkO.js +1 -0
  89. package/dist/assets/{scan-eye-gmpggdW4.js → scan-eye-B6ToEyNT.js} +1 -1
  90. package/dist/assets/{scissors-CCgXntCX.js → scissors-Cy9qo-01.js} +1 -1
  91. package/dist/assets/{search-x-D1xSmXhu.js → search-x-Bc6YoEgC.js} +1 -1
  92. package/dist/assets/{send-B8FKrOyC.js → send-C88bJpzN.js} +1 -1
  93. package/dist/assets/{settings-2-BdhYf7UQ.js → settings-2-CT7EhY20.js} +1 -1
  94. package/dist/assets/shapes-D49xx3pl.js +1 -0
  95. package/dist/assets/{sigma-Bzh2qqL3.js → sigma-r_LYWpZC.js} +1 -1
  96. package/dist/assets/{speaker-CmGzkRdE.js → speaker-Ki0ZHj9k.js} +1 -1
  97. package/dist/assets/src-Cq4wbXVd.js +67 -0
  98. package/dist/assets/step-inspector-model-DybV6iGj.js +1 -0
  99. package/dist/assets/{table-2-DaQYtXJ7.js → table-2-BCrCvQBE.js} +1 -1
  100. package/dist/assets/{timer-reset-ceaN5uh6.js → timer-reset-BCU9mQbt.js} +1 -1
  101. package/dist/assets/{unlink-CZPQIK73.js → unlink-Bdf-2hM2.js} +1 -1
  102. package/dist/assets/{usb-CdZusF7Y.js → usb-Dk1-9w-h.js} +1 -1
  103. package/dist/assets/{use-scenes-feed-CGtWB1L7.js → use-scenes-feed-kuO8vvaU.js} +1 -1
  104. package/dist/assets/{use-stationary-objects-Cp1KGKmU.js → use-stationary-objects-h9zEu1aK.js} +1 -1
  105. package/dist/assets/useEventInvalidation-CtJOP06v.js +1 -0
  106. package/dist/assets/{useNodeUrlSelection-BsZGUghh.js → useNodeUrlSelection-DxKAfF2w.js} +1 -1
  107. package/dist/assets/user-round-ucYAzmFE.js +1 -0
  108. package/dist/assets/{user-x-DKorc3CR.js → user-x-Ci81AHsS.js} +1 -1
  109. package/dist/assets/{variable-BXBhuk59.js → variable-6lR9ETRn.js} +1 -1
  110. package/dist/assets/video-BSJxItXj.js +1 -0
  111. package/dist/assets/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__admin_ui_host__remoteEntry-_hash_-BQEGoWCP.js → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__admin_ui_host__remoteEntry-_hash_-CCXtVAMI.js} +2 -2
  112. package/dist/index.html +10 -10
  113. package/dist/server/addon.js +473 -11
  114. package/package.json +1 -1
  115. package/dist/assets/Addons-DaNcypAW.js +0 -5
  116. package/dist/assets/AiProfiles-qBccFu5d.js +0 -3
  117. package/dist/assets/Build-DRh7B9_e.js +0 -40
  118. package/dist/assets/CompositionBlockEditor-CV4xvSqS.js +0 -1
  119. package/dist/assets/Data-DWYM-kxy.js +0 -2
  120. package/dist/assets/DeviceDetail-CVMOCWi5.js +0 -2
  121. package/dist/assets/DeviceDoActionFields-BDdQwLvn.js +0 -1
  122. package/dist/assets/HelperWizard-TPowwspC.js +0 -2
  123. package/dist/assets/History-DVdEMBYJ.js +0 -1
  124. package/dist/assets/Identity-DNSkhe9x.js +0 -1
  125. package/dist/assets/IntegrationDetail-DZttjxiw.js +0 -1
  126. package/dist/assets/IntegrationHub-DqbKVh4N.js +0 -1
  127. package/dist/assets/Integrations-BfgfABQl.js +0 -1
  128. package/dist/assets/Integrations-BmU9vQlf.js +0 -1
  129. package/dist/assets/Locations-D7E3SmAX.js +0 -3
  130. package/dist/assets/MyAccess-Bred4wkj.js +0 -2
  131. package/dist/assets/NodeAddonsSettingsPanel-BswQpSzM.js +0 -1
  132. package/dist/assets/Notifications-CjXAcavg.js +0 -1
  133. package/dist/assets/Pipeline-DURRCrIJ.js +0 -1
  134. package/dist/assets/Recordings-D1a7Ipp3.js +0 -1
  135. package/dist/assets/SessionsList-BtpHp2KM.js +0 -2
  136. package/dist/assets/System-Ca9giuGu.js +0 -1
  137. package/dist/assets/circle-slash-fwUwJ3r8.js +0 -1
  138. package/dist/assets/client-JLEP7nv7.js +0 -674
  139. package/dist/assets/crop-j4n-xPUF.js +0 -1
  140. package/dist/assets/device-picker-model-CreVFMrD.js +0 -1
  141. package/dist/assets/dist-BW5MRjy3.js +0 -674
  142. package/dist/assets/format-D360_J0N.js +0 -1
  143. package/dist/assets/i18n-B5uU8u6u.js +0 -1
  144. package/dist/assets/icons-BJz9Yj7E.js +0 -1
  145. package/dist/assets/index-CuvJet67.js +0 -4
  146. package/dist/assets/index-DUl9HFmr.css +0 -2
  147. package/dist/assets/key-drN5OJov.js +0 -1
  148. package/dist/assets/location-owned-usage-CVWBPy28.js +0 -1
  149. package/dist/assets/mount-CreVFMrD.js +0 -1
  150. package/dist/assets/remoteEntry-BlJC9q2U.js +0 -1
  151. package/dist/assets/src-vYMgzn3X.js +0 -67
  152. package/dist/assets/step-inspector-model-BZFtfupM.js +0 -1
  153. package/dist/assets/useEventInvalidation-CreVFMrD.js +0 -1
  154. package/dist/assets/user-round-yFN2hAUV.js +0 -1
  155. package/dist/assets/video-2nOnVl_R.js +0 -1
@@ -5448,7 +5448,7 @@ var ZodIssueCode = {
5448
5448
  var ZodFirstPartyTypeKind;
5449
5449
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5450
5450
  //#endregion
5451
- //#region ../types/dist/sleep-BAvUCi_2.mjs
5451
+ //#region ../types/dist/sleep-DJws6ho7.mjs
5452
5452
  /**
5453
5453
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5454
5454
  * window to float samples (D455).
@@ -8659,6 +8659,7 @@ var CAP_NAMES = Object.freeze([
8659
8659
  "recording-onboard",
8660
8660
  "recording-signal",
8661
8661
  "records",
8662
+ "remote",
8662
8663
  "running-state",
8663
8664
  "scene-monitor",
8664
8665
  "script-runner",
@@ -8682,6 +8683,7 @@ var CAP_NAMES = Object.freeze([
8682
8683
  "system",
8683
8684
  "tamper",
8684
8685
  "temperature-sensor",
8686
+ "template",
8685
8687
  "terminal-session",
8686
8688
  "toast",
8687
8689
  "training",
@@ -9622,6 +9624,11 @@ Object.freeze({
9622
9624
  "standby"
9623
9625
  ]
9624
9626
  },
9627
+ {
9628
+ "path": "stateSource",
9629
+ "valueType": "enum",
9630
+ "enumValues": ["reported", "assumed"]
9631
+ },
9625
9632
  {
9626
9633
  "path": "volumeLevel",
9627
9634
  "valueType": "number"
@@ -9897,6 +9904,18 @@ Object.freeze({
9897
9904
  {
9898
9905
  "path": "volume",
9899
9906
  "valueType": "number"
9907
+ },
9908
+ {
9909
+ "path": "lastFeedGrams",
9910
+ "valueType": "number"
9911
+ },
9912
+ {
9913
+ "path": "lastFeedHopper1",
9914
+ "valueType": "number"
9915
+ },
9916
+ {
9917
+ "path": "lastFeedHopper2",
9918
+ "valueType": "number"
9900
9919
  }
9901
9920
  ],
9902
9921
  "power-meter": [
@@ -57363,6 +57382,318 @@ DeviceType.Light, method(object({
57363
57382
  level: number().min(0).max(100),
57364
57383
  lastChangedAt: number()
57365
57384
  });
57385
+ /**
57386
+ * The role vocabulary of a remote (D963): what a button MEANS, independent of
57387
+ * how it is wired. A layout template places buttons by role; a device binds a
57388
+ * role to an action; an exporter asks for a role by name. Roles are shared so
57389
+ * one layout fits every appliance and one voice command fits every binding.
57390
+ *
57391
+ * A role outside this list is `custom:<key>` — the operator's own button (a
57392
+ * SmartIR source, a channel preset). The key is a lowercase slug.
57393
+ */
57394
+ var REMOTE_KNOWN_ROLES = [
57395
+ "power",
57396
+ "power_on",
57397
+ "power_off",
57398
+ "volume_up",
57399
+ "volume_down",
57400
+ "mute",
57401
+ "channel_up",
57402
+ "channel_down",
57403
+ "up",
57404
+ "down",
57405
+ "left",
57406
+ "right",
57407
+ "ok",
57408
+ "back",
57409
+ "home",
57410
+ "menu",
57411
+ "info",
57412
+ "guide",
57413
+ "exit",
57414
+ "input",
57415
+ "play",
57416
+ "pause",
57417
+ "play_pause",
57418
+ "stop",
57419
+ "next",
57420
+ "previous",
57421
+ "fast_forward",
57422
+ "rewind",
57423
+ "digit_0",
57424
+ "digit_1",
57425
+ "digit_2",
57426
+ "digit_3",
57427
+ "digit_4",
57428
+ "digit_5",
57429
+ "digit_6",
57430
+ "digit_7",
57431
+ "digit_8",
57432
+ "digit_9"
57433
+ ];
57434
+ var CUSTOM_KEY_RE = /^[a-z0-9][a-z0-9_]{0,47}$/;
57435
+ var KNOWN_ROLES = new Set(REMOTE_KNOWN_ROLES);
57436
+ function isRemoteKnownRole(value) {
57437
+ return KNOWN_ROLES.has(value);
57438
+ }
57439
+ function isRemoteCustomKey(key) {
57440
+ return CUSTOM_KEY_RE.test(key);
57441
+ }
57442
+ /** The key of a `custom:<key>` role, or null for any other string. */
57443
+ function customKeyOfRole(role) {
57444
+ if (!role.startsWith("custom:")) return null;
57445
+ const key = role.slice(7);
57446
+ return isRemoteCustomKey(key) ? key : null;
57447
+ }
57448
+ function isRemoteRole(value) {
57449
+ return isRemoteKnownRole(value) || customKeyOfRole(value) !== null;
57450
+ }
57451
+ var RemoteRoleSchema = string().refine(isRemoteRole, { message: "a role is one of the known roles or custom:<key> (lowercase letters, digits, _)" });
57452
+ var RemoteBindingSchema = object({ action: AutomationCapStepSchema.extend({ deviceId: number().int().nonnegative() }) });
57453
+ var RemoteCustomButtonSchema = object({
57454
+ /** The slug after `custom:` in the role. */
57455
+ key: string().refine(isRemoteCustomKey, { message: "a lowercase slug" }),
57456
+ /** What the operator calls it, and what a voice command may name. */
57457
+ name: string().min(1).max(60)
57458
+ });
57459
+ var RemotePowerModeSchema = _enum(["toggle", "discrete"]);
57460
+ var RemoteConfigSchema = object({
57461
+ layoutTemplateId: string().min(1).nullable(),
57462
+ /**
57463
+ * The transmitter device new bindings and an import send through. A binding
57464
+ * names its own device, so one command may override it.
57465
+ */
57466
+ defaultTransmitterId: number().int().nonnegative().nullable().default(null),
57467
+ /** Keyed by role. A role with no entry falls back to the native cap. */
57468
+ bindings: record(string(), RemoteBindingSchema),
57469
+ customButtons: array(RemoteCustomButtonSchema).max(100),
57470
+ power: object({ mode: RemotePowerModeSchema })
57471
+ }).superRefine((config, ctx) => {
57472
+ const roles = Object.keys(config.bindings);
57473
+ if (roles.length > 200) ctx.addIssue({
57474
+ code: "custom",
57475
+ message: "too many bindings",
57476
+ path: ["bindings"]
57477
+ });
57478
+ for (const role of roles) if (!isRemoteRole(role)) ctx.addIssue({
57479
+ code: "custom",
57480
+ message: `"${role}" is not a role`,
57481
+ path: ["bindings", role]
57482
+ });
57483
+ const keys = /* @__PURE__ */ new Set();
57484
+ config.customButtons.forEach((button, index) => {
57485
+ if (keys.has(button.key)) ctx.addIssue({
57486
+ code: "custom",
57487
+ message: `custom button "${button.key}" is listed twice`,
57488
+ path: [
57489
+ "customButtons",
57490
+ index,
57491
+ "key"
57492
+ ]
57493
+ });
57494
+ keys.add(button.key);
57495
+ });
57496
+ for (const role of roles) {
57497
+ const key = customKeyOfRole(role);
57498
+ if (key !== null && !keys.has(key)) ctx.addIssue({
57499
+ code: "custom",
57500
+ message: `${role} is bound but has no entry in customButtons`,
57501
+ path: ["bindings", role]
57502
+ });
57503
+ }
57504
+ });
57505
+ object({
57506
+ power: object({
57507
+ state: _enum(["on", "off"]),
57508
+ at: number()
57509
+ }).nullable(),
57510
+ muted: object({
57511
+ value: boolean(),
57512
+ at: number()
57513
+ }).nullable()
57514
+ });
57515
+ var RemoteLayoutButtonSchema = object({
57516
+ id: string().min(1).max(40),
57517
+ /** 0-based grid position. */
57518
+ row: number().int().min(0).max(24),
57519
+ col: number().int().min(0).max(24),
57520
+ rowSpan: number().int().min(1).max(24),
57521
+ colSpan: number().int().min(1).max(24),
57522
+ icon: string().min(1).max(60).optional(),
57523
+ label: string().min(1).max(40).optional(),
57524
+ role: RemoteRoleSchema
57525
+ });
57526
+ object({
57527
+ columns: number().int().min(1).max(24),
57528
+ rows: number().int().min(1).max(24),
57529
+ buttons: array(RemoteLayoutButtonSchema).max(200)
57530
+ }).superRefine((grid, ctx) => {
57531
+ const ids = /* @__PURE__ */ new Set();
57532
+ const taken = /* @__PURE__ */ new Map();
57533
+ grid.buttons.forEach((button, index) => {
57534
+ if (ids.has(button.id)) ctx.addIssue({
57535
+ code: "custom",
57536
+ message: `button id "${button.id}" is used twice`,
57537
+ path: [
57538
+ "buttons",
57539
+ index,
57540
+ "id"
57541
+ ]
57542
+ });
57543
+ ids.add(button.id);
57544
+ if (button.row + button.rowSpan > grid.rows || button.col + button.colSpan > grid.columns) {
57545
+ ctx.addIssue({
57546
+ code: "custom",
57547
+ message: `button "${button.id}" leaves the grid`,
57548
+ path: ["buttons", index]
57549
+ });
57550
+ return;
57551
+ }
57552
+ for (let r = button.row; r < button.row + button.rowSpan; r += 1) for (let c = button.col; c < button.col + button.colSpan; c += 1) {
57553
+ const cell = `${r}:${c}`;
57554
+ const other = taken.get(cell);
57555
+ if (other !== void 0) {
57556
+ ctx.addIssue({
57557
+ code: "custom",
57558
+ message: `buttons "${other}" and "${button.id}" overlap`,
57559
+ path: ["buttons", index]
57560
+ });
57561
+ return;
57562
+ }
57563
+ taken.set(cell, button.id);
57564
+ }
57565
+ });
57566
+ });
57567
+ var RemoteBoundCommandSchema = object({
57568
+ role: RemoteRoleSchema,
57569
+ /** The operator's name for a custom button; absent for a known role. */
57570
+ label: string().optional(),
57571
+ custom: boolean()
57572
+ });
57573
+ var RemoteCommandListSchema = object({
57574
+ layoutTemplateId: string().nullable(),
57575
+ power: object({ mode: RemotePowerModeSchema }),
57576
+ /** Only the roles that are BOUND — the ones a press can reach. */
57577
+ commands: array(RemoteBoundCommandSchema)
57578
+ });
57579
+ var RemoteRefusalReasonSchema = _enum([
57580
+ "no-remote",
57581
+ "unbound-role",
57582
+ "action-failed"
57583
+ ]);
57584
+ var RemoteSendResultSchema = discriminatedUnion("status", [
57585
+ object({
57586
+ status: literal("sent"),
57587
+ /** How many times the action ran. */
57588
+ sends: number().int().min(1)
57589
+ }),
57590
+ object({
57591
+ status: literal("skipped"),
57592
+ reason: literal("already-in-state")
57593
+ }),
57594
+ object({
57595
+ status: literal("refused"),
57596
+ reason: RemoteRefusalReasonSchema,
57597
+ detail: string().optional()
57598
+ })
57599
+ ]);
57600
+ var RemoteMediaCommandSchema = _enum([
57601
+ "play",
57602
+ "pause",
57603
+ "stop",
57604
+ "next",
57605
+ "previous",
57606
+ "setMute",
57607
+ "selectSource"
57608
+ ]);
57609
+ /** A send result, or `not-routed`: the role is not bound, so the native cap answers. */
57610
+ var RemoteMediaCommandResultSchema = discriminatedUnion("status", [...RemoteSendResultSchema.options, object({ status: literal("not-routed") })]);
57611
+ var RemoteSetConfigResultSchema = discriminatedUnion("status", [object({ status: literal("saved") }), object({
57612
+ status: literal("refused"),
57613
+ reason: _enum(["unknown-template", "not-a-media-player"]),
57614
+ detail: string()
57615
+ })]);
57616
+ var deviceInput = object({ deviceId: number().int().nonnegative() });
57617
+ DeviceType.MediaPlayer;
57618
+ method(deviceInput, RemoteConfigSchema, { auth: "admin" }), method(deviceInput.extend({ config: RemoteConfigSchema }), RemoteSetConfigResultSchema, {
57619
+ kind: "mutation",
57620
+ auth: "admin"
57621
+ }), method(deviceInput, RemoteCommandListSchema, { auth: "protected" }), method(deviceInput.extend({
57622
+ role: RemoteRoleSchema,
57623
+ /** Sends in a row (volume steps). */
57624
+ repeat: number().int().min(1).max(50).default(1)
57625
+ }), RemoteSendResultSchema, {
57626
+ kind: "mutation",
57627
+ auth: "protected"
57628
+ }), method(deviceInput.extend({
57629
+ command: RemoteMediaCommandSchema,
57630
+ muted: boolean().optional(),
57631
+ source: string().optional(),
57632
+ repeat: number().int().min(1).max(50).default(1)
57633
+ }), RemoteMediaCommandResultSchema, {
57634
+ kind: "mutation",
57635
+ auth: "protected"
57636
+ });
57637
+ var TemplateKindSchema = _enum(["remote"]);
57638
+ /**
57639
+ * template — the generic store of reusable, named operator data (D963). A
57640
+ * record is `{ id, kind, name, payload }`; the kinds (today only `remote`, the
57641
+ * button grid of a remote) and the schema each payload must satisfy are
57642
+ * declared by the system in `template-kinds.ts`. Nothing here is specific to a
57643
+ * kind: the engine validates a payload against its kind's schema and, on a
57644
+ * delete, asks the kind's owner whether anything still points at the record.
57645
+ *
57646
+ * Every refusal is a typed result — a UI says "unknown kind" or names the
57647
+ * devices that still use a template, without parsing text.
57648
+ */
57649
+ var TemplateRecordSchema = object({
57650
+ id: string().min(1),
57651
+ kind: TemplateKindSchema,
57652
+ name: string().min(1).max(120),
57653
+ /** Shaped by the kind; `checkTemplatePayload(kind, payload)` reads it. */
57654
+ payload: unknown(),
57655
+ createdAt: number(),
57656
+ updatedAt: number()
57657
+ });
57658
+ var TemplateWriteResultSchema = discriminatedUnion("status", [object({
57659
+ status: literal("saved"),
57660
+ template: TemplateRecordSchema
57661
+ }), object({
57662
+ status: literal("refused"),
57663
+ reason: _enum(["invalid-payload", "not-found"]),
57664
+ detail: string()
57665
+ })]);
57666
+ /** A device still pointing at a template. */
57667
+ var TemplateUserSchema = object({
57668
+ deviceId: number().int().nonnegative(),
57669
+ name: string()
57670
+ });
57671
+ var TemplateDeleteResultSchema = discriminatedUnion("status", [
57672
+ object({ status: literal("deleted") }),
57673
+ object({ status: literal("not-found") }),
57674
+ object({
57675
+ status: literal("in-use"),
57676
+ devices: array(TemplateUserSchema).min(1)
57677
+ })
57678
+ ]);
57679
+ method(object({ kind: TemplateKindSchema.optional() }), array(TemplateRecordSchema), { auth: "protected" }), method(object({ id: string().min(1) }), TemplateRecordSchema.nullable(), { auth: "protected" }), method(object({
57680
+ kind: TemplateKindSchema,
57681
+ name: string().min(1).max(120),
57682
+ payload: unknown()
57683
+ }), TemplateWriteResultSchema, {
57684
+ kind: "mutation",
57685
+ auth: "admin"
57686
+ }), method(object({
57687
+ id: string().min(1),
57688
+ name: string().min(1).max(120).optional(),
57689
+ payload: unknown().optional()
57690
+ }), TemplateWriteResultSchema, {
57691
+ kind: "mutation",
57692
+ auth: "admin"
57693
+ }), method(object({ id: string().min(1) }), TemplateDeleteResultSchema, {
57694
+ kind: "mutation",
57695
+ auth: "admin"
57696
+ });
57366
57697
  DeviceType.Button, method(object({ deviceId: number().int().nonnegative() }), _void(), {
57367
57698
  kind: "mutation",
57368
57699
  auth: "protected"
@@ -60112,9 +60443,35 @@ var MediaInfoSchema = object({
60112
60443
  /** Optional cover-art / thumbnail URL. */
60113
60444
  imageUrl: string().optional()
60114
60445
  });
60446
+ /**
60447
+ * Where `state`, `volumeLevel`, `isMuted` and `source` come from. `reported`:
60448
+ * the device said so. `assumed`: the driver has no feedback (infrared) and
60449
+ * tracks what it last SENT; it moves only after a send was accepted, and a
60450
+ * human at the real remote makes it wrong. A UI shows an assumed value as a
60451
+ * guess, never as a reading.
60452
+ */
60453
+ var MediaPlayerStateSourceSchema = _enum(["reported", "assumed"]);
60454
+ /** The fields of a media-player status a driver can only guess. */
60455
+ var MediaPlayerAssumedFieldSchema = _enum([
60456
+ "state",
60457
+ "volumeLevel",
60458
+ "isMuted",
60459
+ "source"
60460
+ ]);
60115
60461
  object({
60116
60462
  /** Playback lifecycle state. */
60117
60463
  state: MediaPlayerStateSchema,
60464
+ /**
60465
+ * Whether the state fields are readings or the driver's own bookkeeping.
60466
+ * A slice written before this field existed parses as `reported`.
60467
+ */
60468
+ stateSource: MediaPlayerStateSourceSchema.default("reported"),
60469
+ /**
60470
+ * Which fields are the driver's own guess. `stateSource` is `assumed` when
60471
+ * this is not empty; a field not listed here is a reading even then (power
60472
+ * from a running-state source, mute guessed from the last send).
60473
+ */
60474
+ assumedFields: array(MediaPlayerAssumedFieldSchema).default([]),
60118
60475
  /** Volume as 0..100 inclusive. Null when the device has no volume
60119
60476
  * surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
60120
60477
  volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
@@ -61555,6 +61912,14 @@ object({
61555
61912
  feedSound: boolean(),
61556
61913
  /** Speaker / prompt volume level (device-scaled integer). */
61557
61914
  volume: number().meta(readingMeta("none")),
61915
+ /** Portion (grams) of the last manual feed sent from a single-hopper
61916
+ * stepper — the default the next manual feed starts from. Persisted per
61917
+ * device by the provider; null until a manual feed has been sent. */
61918
+ lastFeedGrams: gramsPortion.nullable(),
61919
+ /** Hopper-1 portion of the last manual feed (dual-hopper); null until sent. */
61920
+ lastFeedHopper1: gramsPortion.nullable(),
61921
+ /** Hopper-2 portion of the last manual feed (dual-hopper); null until sent. */
61922
+ lastFeedHopper2: gramsPortion.nullable(),
61558
61923
  /** Ms epoch when the slice was last refreshed from the cloud. */
61559
61924
  lastFetchedAt: number()
61560
61925
  });
@@ -66196,9 +66561,17 @@ method(object({}), array(TrainingBaseModelSchema).readonly(), { auth: "admin" })
66196
66561
  kind: "mutation",
66197
66562
  auth: "admin"
66198
66563
  });
66564
+ discriminatedUnion("kind", [object({
66565
+ kind: literal("raw"),
66566
+ timings: array(number().int()),
66567
+ settings: TransmitSettingsSchema.optional()
66568
+ }), object({
66569
+ kind: literal("pronto"),
66570
+ code: string()
66571
+ })]);
66199
66572
  DeviceFeature.FanSpeed, DeviceFeature.FanPreset, DeviceFeature.FanDirection, DeviceFeature.FanOscillating, DeviceFeature.CoverPositionable, DeviceFeature.CoverTilt, DeviceFeature.ValvePositionable, DeviceFeature.MediaPlayerVolume, DeviceFeature.ClimateFanMode;
66200
66573
  SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
66201
- 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;
66574
+ 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;
66202
66575
  String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
66203
66576
  DeviceRole.BinarySensor, DeviceRole.MotionSensor;
66204
66577
  new Set(CAP_NAMES);
@@ -73940,6 +74313,41 @@ Object.freeze({
73940
74313
  access: "create",
73941
74314
  role: "admin"
73942
74315
  },
74316
+ "remote.getConfig": {
74317
+ capName: "remote",
74318
+ capScope: "system",
74319
+ addonId: null,
74320
+ access: "view",
74321
+ role: "admin"
74322
+ },
74323
+ "remote.listCommands": {
74324
+ capName: "remote",
74325
+ capScope: "system",
74326
+ addonId: null,
74327
+ access: "view",
74328
+ role: "admin"
74329
+ },
74330
+ "remote.sendCommand": {
74331
+ capName: "remote",
74332
+ capScope: "system",
74333
+ addonId: null,
74334
+ access: "create",
74335
+ role: "admin"
74336
+ },
74337
+ "remote.sendMediaCommand": {
74338
+ capName: "remote",
74339
+ capScope: "system",
74340
+ addonId: null,
74341
+ access: "create",
74342
+ role: "admin"
74343
+ },
74344
+ "remote.setConfig": {
74345
+ capName: "remote",
74346
+ capScope: "system",
74347
+ addonId: null,
74348
+ access: "create",
74349
+ role: "admin"
74350
+ },
73943
74351
  "runningState.getStatus": {
73944
74352
  capName: "running-state",
73945
74353
  capScope: "device",
@@ -75130,6 +75538,41 @@ Object.freeze({
75130
75538
  access: "view",
75131
75539
  role: "viewer"
75132
75540
  },
75541
+ "template.create": {
75542
+ capName: "template",
75543
+ capScope: "system",
75544
+ addonId: null,
75545
+ access: "create",
75546
+ role: "admin"
75547
+ },
75548
+ "template.delete": {
75549
+ capName: "template",
75550
+ capScope: "system",
75551
+ addonId: null,
75552
+ access: "delete",
75553
+ role: "admin"
75554
+ },
75555
+ "template.get": {
75556
+ capName: "template",
75557
+ capScope: "system",
75558
+ addonId: null,
75559
+ access: "view",
75560
+ role: "admin"
75561
+ },
75562
+ "template.list": {
75563
+ capName: "template",
75564
+ capScope: "system",
75565
+ addonId: null,
75566
+ access: "view",
75567
+ role: "admin"
75568
+ },
75569
+ "template.update": {
75570
+ capName: "template",
75571
+ capScope: "system",
75572
+ addonId: null,
75573
+ access: "create",
75574
+ role: "admin"
75575
+ },
75133
75576
  "terminalSession.adoptLegacyMonitor": {
75134
75577
  capName: "terminal-session",
75135
75578
  capScope: "system",
@@ -79961,6 +80404,7 @@ var SYSTEM_CAP_VOCABULARY = {
79961
80404
  "recording-archive": system(STORAGE),
79962
80405
  "recording-export": system("recording exports — requested from the timeline, not an automation step"),
79963
80406
  records: system(INTERNAL),
80407
+ remote: system("the per-device remote setup — authored in the Customize remote editor, sent through the remote UI"),
79964
80408
  "server-management": system(CLUSTER),
79965
80409
  "settings-store": system(INTERNAL),
79966
80410
  "smtp-provider": system(INTERNAL),
@@ -79973,6 +80417,7 @@ var SYSTEM_CAP_VOCABULARY = {
79973
80417
  "storage-provider": system(STORAGE),
79974
80418
  "stream-broker": system(PIPELINE),
79975
80419
  system: system(CLUSTER),
80420
+ template: system("operator-authored templates — edited in their own editor, never actuated"),
79976
80421
  "terminal-session": system(CLUSTER),
79977
80422
  toast: system(UI_PLUMBING),
79978
80423
  training: system(ML),
@@ -82399,6 +82844,31 @@ Object.freeze({
82399
82844
  form: "single",
82400
82845
  optional: true
82401
82846
  }],
82847
+ "remote.getConfig": [{
82848
+ name: "deviceId",
82849
+ form: "single",
82850
+ optional: false
82851
+ }],
82852
+ "remote.listCommands": [{
82853
+ name: "deviceId",
82854
+ form: "single",
82855
+ optional: false
82856
+ }],
82857
+ "remote.sendCommand": [{
82858
+ name: "deviceId",
82859
+ form: "single",
82860
+ optional: false
82861
+ }],
82862
+ "remote.sendMediaCommand": [{
82863
+ name: "deviceId",
82864
+ form: "single",
82865
+ optional: false
82866
+ }],
82867
+ "remote.setConfig": [{
82868
+ name: "deviceId",
82869
+ form: "single",
82870
+ optional: false
82871
+ }],
82402
82872
  "runningState.getStatus": [{
82403
82873
  name: "deviceId",
82404
82874
  form: "single",
@@ -84207,14 +84677,6 @@ DEFAULT_NATIVE_LEASE_SETTINGS.admission;
84207
84677
  String.raw`(?<=^|["'(\s>,\[{])`;
84208
84678
  var MB = 1024 * 1024;
84209
84679
  1024 * MB, 3072 * MB;
84210
- discriminatedUnion("kind", [object({
84211
- kind: literal("raw"),
84212
- timings: array(number().int()),
84213
- settings: TransmitSettingsSchema.optional()
84214
- }), object({
84215
- kind: literal("pronto"),
84216
- code: string()
84217
- })]);
84218
84680
  object({
84219
84681
  manufacturer: string().optional(),
84220
84682
  supportedModels: array(string()).optional(),
@@ -84242,7 +84704,7 @@ var AdminUIAddon = class extends BaseAddon {
84242
84704
  capability: adminUiCapability,
84243
84705
  provider: {
84244
84706
  getStaticDir: async () => ({ staticDir: resolveAdminUiDistDir() }),
84245
- getVersion: async () => ({ version: "1.2.511" })
84707
+ getVersion: async () => ({ version: "1.2.513" })
84246
84708
  }
84247
84709
  }];
84248
84710
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-admin-ui",
3
- "version": "1.2.511",
3
+ "version": "1.2.513",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Admin UI — Vite frontend build and server-side addon",