@sirenodeck/sirenodeck 0.1.1-alpha.0

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 (485) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +69 -0
  3. package/bin/_wrapper-shared.js +42 -0
  4. package/bin/dev.js +95 -0
  5. package/bin/sirenodeck.js +42 -0
  6. package/config/default-config.yml +117 -0
  7. package/config/starter-config.yml +54 -0
  8. package/dist/main.mjs +64702 -0
  9. package/package.json +140 -0
  10. package/src/action/executor.ts +156 -0
  11. package/src/action/index.ts +7 -0
  12. package/src/addon/api-types.ts +15 -0
  13. package/src/addon/api.ts +461 -0
  14. package/src/addon/check-runner.ts +84 -0
  15. package/src/addon/index.ts +5 -0
  16. package/src/addon/loader.ts +441 -0
  17. package/src/addon/registry.ts +230 -0
  18. package/src/addon/spec.ts +69 -0
  19. package/src/api/addon.ts +33 -0
  20. package/src/api/asset-url.ts +24 -0
  21. package/src/api/index.ts +50 -0
  22. package/src/api/protocol-internal.ts +656 -0
  23. package/src/api/protocol.ts +2 -0
  24. package/src/api/react/index.ts +11 -0
  25. package/src/api/react/registry.ts +91 -0
  26. package/src/api/react/use-addon-channel.ts +26 -0
  27. package/src/api/react/use-button-state.tsx +23 -0
  28. package/src/api/react/use-deck.ts +24 -0
  29. package/src/assets/logo.png +0 -0
  30. package/src/assets/logo72x72.png +0 -0
  31. package/src/assets/logoFull.png +0 -0
  32. package/src/builtin-addons/brightness/README.md +51 -0
  33. package/src/builtin-addons/brightness/buttons/brightness/backend.ts +13 -0
  34. package/src/builtin-addons/brightness/buttons/brightness/config.ts +10 -0
  35. package/src/builtin-addons/brightness/buttons/brightness/frontend.tsx +50 -0
  36. package/src/builtin-addons/brightness/domain/macos.ts +46 -0
  37. package/src/builtin-addons/brightness/index.d.ts +5 -0
  38. package/src/builtin-addons/brightness/index.ts +20 -0
  39. package/src/builtin-addons/brightness/poller.ts +27 -0
  40. package/src/builtin-addons/brightness/providers/darwin.ts +107 -0
  41. package/src/builtin-addons/brightness/providers/index.ts +81 -0
  42. package/src/builtin-addons/brightness/providers/linux.ts +108 -0
  43. package/src/builtin-addons/brightness/providers/windows.ts +77 -0
  44. package/src/builtin-addons/brightness/sirenodeck.json +6 -0
  45. package/src/builtin-addons/coding-agents/assets/claude-code.svg +1 -0
  46. package/src/builtin-addons/coding-agents/assets/opencode-dark-square.svg +1 -0
  47. package/src/builtin-addons/coding-agents/buttons/agent/backend.ts +82 -0
  48. package/src/builtin-addons/coding-agents/buttons/agent/config.ts +13 -0
  49. package/src/builtin-addons/coding-agents/buttons/agent/frontend.tsx +130 -0
  50. package/src/builtin-addons/coding-agents/buttons/agent/pages.tsx +150 -0
  51. package/src/builtin-addons/coding-agents/buttons/summary/backend.ts +48 -0
  52. package/src/builtin-addons/coding-agents/buttons/summary/config.ts +11 -0
  53. package/src/builtin-addons/coding-agents/buttons/summary/frontend.tsx +254 -0
  54. package/src/builtin-addons/coding-agents/decks/agents.ts +69 -0
  55. package/src/builtin-addons/coding-agents/global/backend.ts +402 -0
  56. package/src/builtin-addons/coding-agents/global-entry.ts +7 -0
  57. package/src/builtin-addons/coding-agents/hook/script.ts +123 -0
  58. package/src/builtin-addons/coding-agents/index.ts +15 -0
  59. package/src/builtin-addons/coding-agents/manifest.ts +115 -0
  60. package/src/builtin-addons/coding-agents/providers/claude-code.ts +470 -0
  61. package/src/builtin-addons/coding-agents/providers/claude-instances.ts +184 -0
  62. package/src/builtin-addons/coding-agents/providers/opencode-instances.ts +108 -0
  63. package/src/builtin-addons/coding-agents/providers/opencode.ts +636 -0
  64. package/src/builtin-addons/coding-agents/providers/registry.ts +120 -0
  65. package/src/builtin-addons/coding-agents/providers/spawn.ts +112 -0
  66. package/src/builtin-addons/coding-agents/shared/claude-hook-events.ts +55 -0
  67. package/src/builtin-addons/coding-agents/shared/claude-status.ts +236 -0
  68. package/src/builtin-addons/coding-agents/shared/live-count.ts +39 -0
  69. package/src/builtin-addons/coding-agents/shared/notifier.ts +58 -0
  70. package/src/builtin-addons/coding-agents/shared/opencode-status.ts +82 -0
  71. package/src/builtin-addons/coding-agents/shared/snapshot.ts +66 -0
  72. package/src/builtin-addons/coding-agents/shared/state.ts +72 -0
  73. package/src/builtin-addons/coding-agents/sirenodeck.json +6 -0
  74. package/src/builtin-addons/coding-agents/types/types.ts +33 -0
  75. package/src/builtin-addons/core/README.md +89 -0
  76. package/src/builtin-addons/core/buttons/action/backend.ts +7 -0
  77. package/src/builtin-addons/core/buttons/action/config.ts +13 -0
  78. package/src/builtin-addons/core/buttons/action/frontend.tsx +16 -0
  79. package/src/builtin-addons/core/buttons/change-deck/backend.ts +18 -0
  80. package/src/builtin-addons/core/buttons/change-deck/config.ts +15 -0
  81. package/src/builtin-addons/core/buttons/change-deck/frontend.tsx +18 -0
  82. package/src/builtin-addons/core/buttons/media-sample/backend.ts +8 -0
  83. package/src/builtin-addons/core/buttons/media-sample/config.ts +7 -0
  84. package/src/builtin-addons/core/buttons/media-sample/frontend.tsx +2 -0
  85. package/src/builtin-addons/core/buttons/page-nav/backend.ts +28 -0
  86. package/src/builtin-addons/core/buttons/page-nav/config.ts +9 -0
  87. package/src/builtin-addons/core/buttons/page-nav/frontend.tsx +68 -0
  88. package/src/builtin-addons/core/buttons/toggle/backend.ts +119 -0
  89. package/src/builtin-addons/core/buttons/toggle/config.ts +57 -0
  90. package/src/builtin-addons/core/buttons/toggle/frontend.tsx +57 -0
  91. package/src/builtin-addons/core/buttons/toggle/global-service.ts +174 -0
  92. package/src/builtin-addons/core/index.ts +120 -0
  93. package/src/builtin-addons/core/sirenodeck.json +6 -0
  94. package/src/builtin-addons/date-time/README.md +73 -0
  95. package/src/builtin-addons/date-time/buttons/analog-clock/backend.ts +10 -0
  96. package/src/builtin-addons/date-time/buttons/analog-clock/config.ts +4 -0
  97. package/src/builtin-addons/date-time/buttons/analog-clock/frontend.tsx +88 -0
  98. package/src/builtin-addons/date-time/buttons/custom/backend.ts +10 -0
  99. package/src/builtin-addons/date-time/buttons/custom/config.ts +9 -0
  100. package/src/builtin-addons/date-time/buttons/custom/frontend.tsx +26 -0
  101. package/src/builtin-addons/date-time/buttons/date/backend.ts +10 -0
  102. package/src/builtin-addons/date-time/buttons/date/config.ts +10 -0
  103. package/src/builtin-addons/date-time/buttons/date/frontend.tsx +42 -0
  104. package/src/builtin-addons/date-time/buttons/time/backend.ts +10 -0
  105. package/src/builtin-addons/date-time/buttons/time/config.ts +9 -0
  106. package/src/builtin-addons/date-time/buttons/time/frontend.tsx +29 -0
  107. package/src/builtin-addons/date-time/index.d.ts +5 -0
  108. package/src/builtin-addons/date-time/index.ts +30 -0
  109. package/src/builtin-addons/date-time/poller.ts +11 -0
  110. package/src/builtin-addons/date-time/shared/format-date.ts +36 -0
  111. package/src/builtin-addons/date-time/shared/format.ts +105 -0
  112. package/src/builtin-addons/date-time/shared/use-now.ts +10 -0
  113. package/src/builtin-addons/date-time/sirenodeck.json +6 -0
  114. package/src/builtin-addons/emoji-selector/README.md +45 -0
  115. package/src/builtin-addons/emoji-selector/assets/launcher.svg +10 -0
  116. package/src/builtin-addons/emoji-selector/assets/smileys.svg +8 -0
  117. package/src/builtin-addons/emoji-selector/buttons/category/backend.ts +14 -0
  118. package/src/builtin-addons/emoji-selector/buttons/category/config.ts +8 -0
  119. package/src/builtin-addons/emoji-selector/buttons/category/frontend.tsx +19 -0
  120. package/src/builtin-addons/emoji-selector/buttons/emoji/backend.ts +7 -0
  121. package/src/builtin-addons/emoji-selector/buttons/emoji/config.ts +9 -0
  122. package/src/builtin-addons/emoji-selector/buttons/emoji/frontend.tsx +11 -0
  123. package/src/builtin-addons/emoji-selector/buttons/launcher/backend.ts +13 -0
  124. package/src/builtin-addons/emoji-selector/buttons/launcher/config.ts +6 -0
  125. package/src/builtin-addons/emoji-selector/buttons/launcher/frontend.tsx +31 -0
  126. package/src/builtin-addons/emoji-selector/data/categories.ts +1084 -0
  127. package/src/builtin-addons/emoji-selector/decks/index.ts +137 -0
  128. package/src/builtin-addons/emoji-selector/index.d.ts +5 -0
  129. package/src/builtin-addons/emoji-selector/index.ts +29 -0
  130. package/src/builtin-addons/emoji-selector/sirenodeck.json +6 -0
  131. package/src/builtin-addons/emoji-selector/support.ts +49 -0
  132. package/src/builtin-addons/index.ts +13 -0
  133. package/src/builtin-addons/internal-settings/README.md +26 -0
  134. package/src/builtin-addons/internal-settings/backend.ts +58 -0
  135. package/src/builtin-addons/internal-settings/buttons/app-info/backend.ts +7 -0
  136. package/src/builtin-addons/internal-settings/buttons/app-info/config.ts +13 -0
  137. package/src/builtin-addons/internal-settings/buttons/app-info/frontend.tsx +18 -0
  138. package/src/builtin-addons/internal-settings/buttons/brightness/common/frontend.tsx +50 -0
  139. package/src/builtin-addons/internal-settings/buttons/brightness-down/backend.ts +16 -0
  140. package/src/builtin-addons/internal-settings/buttons/brightness-down/config.ts +6 -0
  141. package/src/builtin-addons/internal-settings/buttons/brightness-down/frontend.tsx +8 -0
  142. package/src/builtin-addons/internal-settings/buttons/brightness-up/backend.ts +16 -0
  143. package/src/builtin-addons/internal-settings/buttons/brightness-up/config.ts +6 -0
  144. package/src/builtin-addons/internal-settings/buttons/brightness-up/frontend.tsx +8 -0
  145. package/src/builtin-addons/internal-settings/decks/settings.ts +25 -0
  146. package/src/builtin-addons/internal-settings/index.d.ts +4 -0
  147. package/src/builtin-addons/internal-settings/index.ts +53 -0
  148. package/src/builtin-addons/internal-settings/logo72x72.png +0 -0
  149. package/src/builtin-addons/internal-settings/sirenodeck.json +6 -0
  150. package/src/builtin-addons/media/README.md +45 -0
  151. package/src/builtin-addons/media/backend.ts +143 -0
  152. package/src/builtin-addons/media/buttons/media-player/backend.ts +19 -0
  153. package/src/builtin-addons/media/buttons/media-player/components/MediaStatus.tsx +25 -0
  154. package/src/builtin-addons/media/buttons/media-player/components/MediaSurface.tsx +52 -0
  155. package/src/builtin-addons/media/buttons/media-player/components/ProgressBar.tsx +21 -0
  156. package/src/builtin-addons/media/buttons/media-player/components/status-meta.ts +36 -0
  157. package/src/builtin-addons/media/buttons/media-player/config.ts +4 -0
  158. package/src/builtin-addons/media/buttons/media-player/frontend.tsx +29 -0
  159. package/src/builtin-addons/media/buttons/volume/common/frontend.tsx +52 -0
  160. package/src/builtin-addons/media/buttons/volume/mute/backend.ts +13 -0
  161. package/src/builtin-addons/media/buttons/volume/mute/config.ts +4 -0
  162. package/src/builtin-addons/media/buttons/volume/mute/frontend.tsx +26 -0
  163. package/src/builtin-addons/media/buttons/volume/volume-down/backend.ts +14 -0
  164. package/src/builtin-addons/media/buttons/volume/volume-down/config.ts +6 -0
  165. package/src/builtin-addons/media/buttons/volume/volume-down/frontend.tsx +10 -0
  166. package/src/builtin-addons/media/buttons/volume/volume-up/backend.ts +14 -0
  167. package/src/builtin-addons/media/buttons/volume/volume-up/config.ts +6 -0
  168. package/src/builtin-addons/media/buttons/volume/volume-up/frontend.tsx +8 -0
  169. package/src/builtin-addons/media/checks.ts +104 -0
  170. package/src/builtin-addons/media/executor.ts +36 -0
  171. package/src/builtin-addons/media/index.d.ts +5 -0
  172. package/src/builtin-addons/media/index.ts +53 -0
  173. package/src/builtin-addons/media/progress.ts +16 -0
  174. package/src/builtin-addons/media/providers/darwin.ts +391 -0
  175. package/src/builtin-addons/media/providers/index.ts +27 -0
  176. package/src/builtin-addons/media/providers/linux.ts +196 -0
  177. package/src/builtin-addons/media/providers/types.ts +48 -0
  178. package/src/builtin-addons/media/providers/windows.ts +121 -0
  179. package/src/builtin-addons/media/sirenodeck.json +6 -0
  180. package/src/builtin-addons/media/state.ts +19 -0
  181. package/src/builtin-addons/register-builtins.ts +65 -0
  182. package/src/builtin-addons/session/README.md +14 -0
  183. package/src/builtin-addons/session/buttons/session-info/backend.ts +8 -0
  184. package/src/builtin-addons/session/buttons/session-info/config.ts +4 -0
  185. package/src/builtin-addons/session/buttons/session-info/frontend.tsx +2 -0
  186. package/src/builtin-addons/session/buttons/time/backend.ts +7 -0
  187. package/src/builtin-addons/session/buttons/time/config.ts +6 -0
  188. package/src/builtin-addons/session/buttons/time/frontend.tsx +2 -0
  189. package/src/builtin-addons/session/index.d.ts +5 -0
  190. package/src/builtin-addons/session/index.ts +18 -0
  191. package/src/builtin-addons/session/sirenodeck.json +6 -0
  192. package/src/builtin-addons/system-status/README.md +169 -0
  193. package/src/builtin-addons/system-status/buttons/_shared.ts +131 -0
  194. package/src/builtin-addons/system-status/buttons/system-status/frontend.tsx +224 -0
  195. package/src/builtin-addons/system-status/buttons/system-status/schemas.ts +67 -0
  196. package/src/builtin-addons/system-status/domain/catalog.ts +53 -0
  197. package/src/builtin-addons/system-status/domain/chart-sampler.ts +58 -0
  198. package/src/builtin-addons/system-status/domain/display-metrics.ts +128 -0
  199. package/src/builtin-addons/system-status/domain/index.ts +10 -0
  200. package/src/builtin-addons/system-status/domain/live-metrics.ts +1021 -0
  201. package/src/builtin-addons/system-status/domain/metric-ids.ts +0 -0
  202. package/src/builtin-addons/system-status/index.ts +16 -0
  203. package/src/builtin-addons/system-status/manifest.ts +105 -0
  204. package/src/builtin-addons/system-status/shared/metrics-catalog.ts +316 -0
  205. package/src/builtin-addons/system-status/sirenodeck.json +6 -0
  206. package/src/builtin-addons/test-buildin/decks/action-buttons-test.ts +56 -0
  207. package/src/builtin-addons/test-buildin/index.d.ts +5 -0
  208. package/src/builtin-addons/test-buildin/index.ts +16 -0
  209. package/src/builtin-addons/value-display/README.md +59 -0
  210. package/src/builtin-addons/value-display/backend.ts +86 -0
  211. package/src/builtin-addons/value-display/buttons/value-display/backend.ts +17 -0
  212. package/src/builtin-addons/value-display/buttons/value-display/config.ts +36 -0
  213. package/src/builtin-addons/value-display/buttons/value-display/frontend.tsx +54 -0
  214. package/src/builtin-addons/value-display/index.d.ts +5 -0
  215. package/src/builtin-addons/value-display/index.ts +23 -0
  216. package/src/builtin-addons/value-display/sirenodeck.json +6 -0
  217. package/src/builtin-addons/weather/README.md +46 -0
  218. package/src/builtin-addons/weather/backend.ts +121 -0
  219. package/src/builtin-addons/weather/buttons/weather/backend.ts +27 -0
  220. package/src/builtin-addons/weather/buttons/weather/config.ts +29 -0
  221. package/src/builtin-addons/weather/buttons/weather/frontend.tsx +63 -0
  222. package/src/builtin-addons/weather/buttons/weather/icons.tsx +88 -0
  223. package/src/builtin-addons/weather/buttons/weather/pages.tsx +109 -0
  224. package/src/builtin-addons/weather/domain/codes.ts +35 -0
  225. package/src/builtin-addons/weather/domain/fetch.ts +47 -0
  226. package/src/builtin-addons/weather/index.d.ts +5 -0
  227. package/src/builtin-addons/weather/index.ts +23 -0
  228. package/src/builtin-addons/weather/poller.ts +70 -0
  229. package/src/builtin-addons/weather/provider/city-key.ts +9 -0
  230. package/src/builtin-addons/weather/provider/codes.ts +35 -0
  231. package/src/builtin-addons/weather/provider/fetch.ts +97 -0
  232. package/src/builtin-addons/weather/provider/geocode.ts +67 -0
  233. package/src/builtin-addons/weather/provider/types.ts +42 -0
  234. package/src/builtin-addons/weather/sirenodeck.json +6 -0
  235. package/src/cli/coding-agents-onboarding.ts +434 -0
  236. package/src/cli/commands/addon-decks.ts +441 -0
  237. package/src/cli/commands/addon-registry.ts +639 -0
  238. package/src/cli/commands/emulator-mode.ts +289 -0
  239. package/src/cli/commands/install.ts +128 -0
  240. package/src/cli/commands/logs.ts +74 -0
  241. package/src/cli/commands/network-bind.ts +111 -0
  242. package/src/cli/commands/pipeline/helpers.ts +75 -0
  243. package/src/cli/commands/pipeline/preflight.ts +20 -0
  244. package/src/cli/commands/port-identity.ts +152 -0
  245. package/src/cli/commands/reload.ts +37 -0
  246. package/src/cli/commands/restart.ts +139 -0
  247. package/src/cli/commands/run.ts +2270 -0
  248. package/src/cli/commands/service/install.ts +121 -0
  249. package/src/cli/commands/service/render-template.ts +158 -0
  250. package/src/cli/commands/service-manager.ts +184 -0
  251. package/src/cli/commands/spawn-daemon.ts +251 -0
  252. package/src/cli/commands/start.ts +1061 -0
  253. package/src/cli/commands/status.ts +110 -0
  254. package/src/cli/commands/stop.ts +121 -0
  255. package/src/cli/commands/subprocess-supervisor.ts +203 -0
  256. package/src/cli/commands/system-requirements.ts +699 -0
  257. package/src/cli/cwd.ts +28 -0
  258. package/src/cli/first-run.ts +149 -0
  259. package/src/cli/http-server.ts +244 -0
  260. package/src/cli/index.ts +355 -0
  261. package/src/cli/install-root.ts +26 -0
  262. package/src/cli/main.ts +194 -0
  263. package/src/cli/package-manager.ts +175 -0
  264. package/src/cli/probe-deps.ts +45 -0
  265. package/src/cli/prompt.ts +22 -0
  266. package/src/cli/startup-display.ts +452 -0
  267. package/src/config/builtin-icons.ts +57 -0
  268. package/src/config/config-diff.ts +54 -0
  269. package/src/config/discovery.ts +64 -0
  270. package/src/config/icon-resolver.ts +90 -0
  271. package/src/config/include-resolver.ts +202 -0
  272. package/src/config/index.ts +9 -0
  273. package/src/config/loader.ts +187 -0
  274. package/src/config/mutation.ts +514 -0
  275. package/src/config/reference-expander.ts +84 -0
  276. package/src/config/schemas.ts +223 -0
  277. package/src/config/validation.ts +254 -0
  278. package/src/core/asset-id.ts +21 -0
  279. package/src/core/gesture-state.ts +344 -0
  280. package/src/core/icon-asset-registry.ts +127 -0
  281. package/src/core/icon-source.ts +86 -0
  282. package/src/core/index.ts +30 -0
  283. package/src/core/mime.ts +16 -0
  284. package/src/core/pagination.ts +90 -0
  285. package/src/core/pub-sub.ts +126 -0
  286. package/src/core/settings.ts +153 -0
  287. package/src/core/store.ts +88 -0
  288. package/src/core/watcher.ts +73 -0
  289. package/src/deck/addon-handler-bridge.ts +516 -0
  290. package/src/deck/deck-config.ts +271 -0
  291. package/src/deck/editor-surfaces.ts +87 -0
  292. package/src/deck/host-context.ts +18 -0
  293. package/src/deck/index.ts +102 -0
  294. package/src/deck/macro-parse.ts +182 -0
  295. package/src/deck/methods.ts +348 -0
  296. package/src/deck/paginate-deck.ts +98 -0
  297. package/src/deck/position-buttons.ts +57 -0
  298. package/src/deck/runtime/index.ts +5 -0
  299. package/src/deck/runtime/runtime.ts +1060 -0
  300. package/src/deck/runtime-subscriptions.ts +45 -0
  301. package/src/deck/system-back-injection.ts +62 -0
  302. package/src/deck/system-buttons/registry.tsx +97 -0
  303. package/src/deck/system-buttons/types.ts +14 -0
  304. package/src/device/black-frame.ts +73 -0
  305. package/src/device/index.ts +13 -0
  306. package/src/device/linux-udev.ts +36 -0
  307. package/src/device/models.ts +89 -0
  308. package/src/device/reconnecting.ts +193 -0
  309. package/src/device/registry.ts +38 -0
  310. package/src/device/stream-deck.ts +155 -0
  311. package/src/index.ts +74 -0
  312. package/src/outputClient/emulator.ts +357 -0
  313. package/src/outputClient/index.ts +26 -0
  314. package/src/outputClient/open-browser.ts +26 -0
  315. package/src/outputClient/real.ts +393 -0
  316. package/src/outputClient/types.ts +83 -0
  317. package/src/render/browser-renderer.ts +240 -0
  318. package/src/render/buffer-hash.ts +20 -0
  319. package/src/render/editor-handler.ts +197 -0
  320. package/src/render/emulator-server.ts +128 -0
  321. package/src/render/icon-source-resolver.ts +69 -0
  322. package/src/render/index.ts +16 -0
  323. package/src/render/protocol.ts +61 -0
  324. package/src/render/push-raw-image.ts +100 -0
  325. package/src/render/screenshot-cadence.ts +87 -0
  326. package/src/render/state-publisher.ts +110 -0
  327. package/src/render/vite-server.ts +138 -0
  328. package/src/render/ws-bridge.ts +315 -0
  329. package/src/system/device-selection.ts +80 -0
  330. package/src/system/glob-match.ts +74 -0
  331. package/src/system/providers/active-app/darwin.ts +117 -0
  332. package/src/system/providers/active-app/linux.ts +245 -0
  333. package/src/system/providers/active-app/wayland-gnome.ts +303 -0
  334. package/src/system/providers/active-app/windows.ts +94 -0
  335. package/src/system/providers/active-app.ts +97 -0
  336. package/src/system/providers/clipboard/darwin.ts +65 -0
  337. package/src/system/providers/clipboard/linux.ts +163 -0
  338. package/src/system/providers/clipboard/windows.ts +94 -0
  339. package/src/system/providers/clipboard.ts +84 -0
  340. package/src/system/providers/error.ts +16 -0
  341. package/src/system/providers/key-macro/darwin.ts +221 -0
  342. package/src/system/providers/key-macro/linux.ts +651 -0
  343. package/src/system/providers/key-macro/parser.ts +215 -0
  344. package/src/system/providers/key-macro/windows.ts +476 -0
  345. package/src/system/providers/key-macro.ts +79 -0
  346. package/src/system/providers/notification/darwin.ts +36 -0
  347. package/src/system/providers/notification/linux.ts +115 -0
  348. package/src/system/providers/notification/windows.ts +72 -0
  349. package/src/system/providers/notification.ts +75 -0
  350. package/src/system/providers/session/darwin.ts +82 -0
  351. package/src/system/providers/session/linux.ts +175 -0
  352. package/src/system/providers/session/windows.ts +73 -0
  353. package/src/system/providers/session.ts +89 -0
  354. package/src/system/providers/shared.ts +65 -0
  355. package/src/system/requirements.ts +235 -0
  356. package/src/system/setup-wizard/config-seed.ts +30 -0
  357. package/src/system/setup-wizard/format.ts +275 -0
  358. package/src/system/setup-wizard/index.ts +45 -0
  359. package/src/system/setup-wizard/open-settings.ts +26 -0
  360. package/src/system/setup-wizard/plan.ts +230 -0
  361. package/src/system/setup-wizard/probe-cache.ts +34 -0
  362. package/src/system/setup-wizard/probe.ts +486 -0
  363. package/src/system/setup-wizard/runtime-features.ts +85 -0
  364. package/src/system/setup-wizard/sudo.ts +178 -0
  365. package/src/system/setup-wizard/types.ts +133 -0
  366. package/src/system/virtual-stream-deck.ts +67 -0
  367. package/src/themes/css.ts +210 -0
  368. package/src/themes/default/assets/IBMPlexSans-Italic-VariableFont_wdth,wght.ttf +0 -0
  369. package/src/themes/default/assets/IBMPlexSans-VariableFont_wdth,wght.ttf +0 -0
  370. package/src/themes/default/assets/IBM_Plex_Mono/IBMPlexMono-Bold.ttf +0 -0
  371. package/src/themes/default/assets/IBM_Plex_Mono/IBMPlexMono-BoldItalic.ttf +0 -0
  372. package/src/themes/default/assets/IBM_Plex_Mono/IBMPlexMono-ExtraLight.ttf +0 -0
  373. package/src/themes/default/assets/IBM_Plex_Mono/IBMPlexMono-ExtraLightItalic.ttf +0 -0
  374. package/src/themes/default/assets/IBM_Plex_Mono/IBMPlexMono-Italic.ttf +0 -0
  375. package/src/themes/default/assets/IBM_Plex_Mono/IBMPlexMono-Light.ttf +0 -0
  376. package/src/themes/default/assets/IBM_Plex_Mono/IBMPlexMono-LightItalic.ttf +0 -0
  377. package/src/themes/default/assets/IBM_Plex_Mono/IBMPlexMono-Medium.ttf +0 -0
  378. package/src/themes/default/assets/IBM_Plex_Mono/IBMPlexMono-MediumItalic.ttf +0 -0
  379. package/src/themes/default/assets/IBM_Plex_Mono/IBMPlexMono-Regular.ttf +0 -0
  380. package/src/themes/default/assets/IBM_Plex_Mono/IBMPlexMono-SemiBold.ttf +0 -0
  381. package/src/themes/default/assets/IBM_Plex_Mono/IBMPlexMono-SemiBoldItalic.ttf +0 -0
  382. package/src/themes/default/assets/IBM_Plex_Mono/IBMPlexMono-Thin.ttf +0 -0
  383. package/src/themes/default/assets/IBM_Plex_Mono/IBMPlexMono-ThinItalic.ttf +0 -0
  384. package/src/themes/default/assets/IBM_Plex_Mono/OFL.txt +93 -0
  385. package/src/themes/default/assets/OFL.txt +93 -0
  386. package/src/themes/default/assets/README.txt +106 -0
  387. package/src/themes/default/assets/static/IBMPlexSans-Bold.ttf +0 -0
  388. package/src/themes/default/assets/static/IBMPlexSans-BoldItalic.ttf +0 -0
  389. package/src/themes/default/assets/static/IBMPlexSans-ExtraLight.ttf +0 -0
  390. package/src/themes/default/assets/static/IBMPlexSans-ExtraLightItalic.ttf +0 -0
  391. package/src/themes/default/assets/static/IBMPlexSans-Italic.ttf +0 -0
  392. package/src/themes/default/assets/static/IBMPlexSans-Light.ttf +0 -0
  393. package/src/themes/default/assets/static/IBMPlexSans-LightItalic.ttf +0 -0
  394. package/src/themes/default/assets/static/IBMPlexSans-Medium.ttf +0 -0
  395. package/src/themes/default/assets/static/IBMPlexSans-MediumItalic.ttf +0 -0
  396. package/src/themes/default/assets/static/IBMPlexSans-Regular.ttf +0 -0
  397. package/src/themes/default/assets/static/IBMPlexSans-SemiBold.ttf +0 -0
  398. package/src/themes/default/assets/static/IBMPlexSans-SemiBoldItalic.ttf +0 -0
  399. package/src/themes/default/assets/static/IBMPlexSans-Thin.ttf +0 -0
  400. package/src/themes/default/assets/static/IBMPlexSans-ThinItalic.ttf +0 -0
  401. package/src/themes/default/assets/static/IBMPlexSans_Condensed-Bold.ttf +0 -0
  402. package/src/themes/default/assets/static/IBMPlexSans_Condensed-BoldItalic.ttf +0 -0
  403. package/src/themes/default/assets/static/IBMPlexSans_Condensed-ExtraLight.ttf +0 -0
  404. package/src/themes/default/assets/static/IBMPlexSans_Condensed-ExtraLightItalic.ttf +0 -0
  405. package/src/themes/default/assets/static/IBMPlexSans_Condensed-Italic.ttf +0 -0
  406. package/src/themes/default/assets/static/IBMPlexSans_Condensed-Light.ttf +0 -0
  407. package/src/themes/default/assets/static/IBMPlexSans_Condensed-LightItalic.ttf +0 -0
  408. package/src/themes/default/assets/static/IBMPlexSans_Condensed-Medium.ttf +0 -0
  409. package/src/themes/default/assets/static/IBMPlexSans_Condensed-MediumItalic.ttf +0 -0
  410. package/src/themes/default/assets/static/IBMPlexSans_Condensed-Regular.ttf +0 -0
  411. package/src/themes/default/assets/static/IBMPlexSans_Condensed-SemiBold.ttf +0 -0
  412. package/src/themes/default/assets/static/IBMPlexSans_Condensed-SemiBoldItalic.ttf +0 -0
  413. package/src/themes/default/assets/static/IBMPlexSans_Condensed-Thin.ttf +0 -0
  414. package/src/themes/default/assets/static/IBMPlexSans_Condensed-ThinItalic.ttf +0 -0
  415. package/src/themes/default/assets/static/IBMPlexSans_SemiCondensed-Bold.ttf +0 -0
  416. package/src/themes/default/assets/static/IBMPlexSans_SemiCondensed-BoldItalic.ttf +0 -0
  417. package/src/themes/default/assets/static/IBMPlexSans_SemiCondensed-ExtraLight.ttf +0 -0
  418. package/src/themes/default/assets/static/IBMPlexSans_SemiCondensed-ExtraLightItalic.ttf +0 -0
  419. package/src/themes/default/assets/static/IBMPlexSans_SemiCondensed-Italic.ttf +0 -0
  420. package/src/themes/default/assets/static/IBMPlexSans_SemiCondensed-Light.ttf +0 -0
  421. package/src/themes/default/assets/static/IBMPlexSans_SemiCondensed-LightItalic.ttf +0 -0
  422. package/src/themes/default/assets/static/IBMPlexSans_SemiCondensed-Medium.ttf +0 -0
  423. package/src/themes/default/assets/static/IBMPlexSans_SemiCondensed-MediumItalic.ttf +0 -0
  424. package/src/themes/default/assets/static/IBMPlexSans_SemiCondensed-Regular.ttf +0 -0
  425. package/src/themes/default/assets/static/IBMPlexSans_SemiCondensed-SemiBold.ttf +0 -0
  426. package/src/themes/default/assets/static/IBMPlexSans_SemiCondensed-SemiBoldItalic.ttf +0 -0
  427. package/src/themes/default/assets/static/IBMPlexSans_SemiCondensed-Thin.ttf +0 -0
  428. package/src/themes/default/assets/static/IBMPlexSans_SemiCondensed-ThinItalic.ttf +0 -0
  429. package/src/themes/default/components.css +81 -0
  430. package/src/themes/default/sirenodeck.json +170 -0
  431. package/src/themes/index.ts +14 -0
  432. package/src/themes/light/assets/IBMPlexSans-Italic-VariableFont_wdth,wght.ttf +0 -0
  433. package/src/themes/light/assets/IBMPlexSans-VariableFont_wdth,wght.ttf +0 -0
  434. package/src/themes/light/assets/IBM_Plex_Mono/IBMPlexMono-Bold.ttf +0 -0
  435. package/src/themes/light/assets/IBM_Plex_Mono/IBMPlexMono-Medium.ttf +0 -0
  436. package/src/themes/light/assets/IBM_Plex_Mono/IBMPlexMono-Regular.ttf +0 -0
  437. package/src/themes/light/assets/IBM_Plex_Mono/OFL.txt +93 -0
  438. package/src/themes/light/assets/OFL.txt +93 -0
  439. package/src/themes/light/assets/README.txt +106 -0
  440. package/src/themes/light/assets/static/IBMPlexSans-Light.ttf +0 -0
  441. package/src/themes/light/assets/static/IBMPlexSans-LightItalic.ttf +0 -0
  442. package/src/themes/light/assets/static/IBMPlexSans-Thin.ttf +0 -0
  443. package/src/themes/light/components.css +70 -0
  444. package/src/themes/light/sirenodeck.json +170 -0
  445. package/src/themes/loader.ts +343 -0
  446. package/src/themes/manifest.ts +164 -0
  447. package/src/themes/use-resolved-theme.tsx +32 -0
  448. package/src/ui/ButtonFrame.tsx +230 -0
  449. package/src/ui/contexts/AssetCacheContext.tsx +43 -0
  450. package/src/ui/index.ts +20 -0
  451. package/src/ui/primitives/Chip.tsx +53 -0
  452. package/src/ui/primitives/Icon.tsx +209 -0
  453. package/src/ui/primitives/Label.tsx +82 -0
  454. package/src/ui/primitives/ProgressBar.tsx +38 -0
  455. package/src/ui/primitives/TapIndicator.tsx +67 -0
  456. package/src/ui/primitives/Text.tsx +810 -0
  457. package/src/ui/primitives/index.ts +6 -0
  458. package/src/ui/surfaces/BarsSurface.tsx +211 -0
  459. package/src/ui/surfaces/IconLabelProgressSurface.tsx +133 -0
  460. package/src/ui/surfaces/IconLabelSurface.tsx +59 -0
  461. package/src/ui/surfaces/LabelValueListSurface.tsx +202 -0
  462. package/src/ui/surfaces/PaginatedSurface.tsx +164 -0
  463. package/src/ui/surfaces/SplitActionSurface.tsx +98 -0
  464. package/src/ui/surfaces/TemporaryErrorSurface.tsx +68 -0
  465. package/src/ui/surfaces/ValueChart.tsx +218 -0
  466. package/src/ui/surfaces/index.ts +32 -0
  467. package/src/ui/surfaces/paginated-schema.ts +22 -0
  468. package/src/ui/theme-presentation-builder.ts +184 -0
  469. package/src/ui/theme-presentation.tsx +146 -0
  470. package/src/ui/utils/cn.ts +12 -0
  471. package/src/util/cache-paths.ts +38 -0
  472. package/src/util/config-diff.ts +16 -0
  473. package/src/util/daemon-control.ts +85 -0
  474. package/src/util/daemon.ts +575 -0
  475. package/src/util/device-config.ts +56 -0
  476. package/src/util/errors.ts +13 -0
  477. package/src/util/log-reader.ts +114 -0
  478. package/src/util/log-tail.ts +103 -0
  479. package/src/util/logger.ts +417 -0
  480. package/src/util/process-title.ts +79 -0
  481. package/src/util/single-instance.ts +202 -0
  482. package/src/version.ts +10 -0
  483. package/src/vite/index.ts +6 -0
  484. package/src/vite/virtual-modules.ts +631 -0
  485. package/src/vite-env.d.ts +1 -0
@@ -0,0 +1,137 @@
1
+ import type { AddonDeckEntry, AddonGeneratedDeck } from "@/addon/api"
2
+
3
+ import { categories, type Emoji } from "../data/categories"
4
+ import {
5
+ DEFAULT_FAVORITES,
6
+ EmojiSelectorDeckSchema,
7
+ type EmojiSelectorDeckConfig,
8
+ } from "../support"
9
+
10
+ // ponytail: build a char→shortcode lookup at module load so favorites
11
+ // get their shortcode filled in without a separate data file.
12
+ const CHAR_TO_SHORTCODE: ReadonlyMap<string, string | undefined> = new Map(
13
+ categories.flatMap((c) =>
14
+ c.emojis.map((e) => [e.char, e.shortcode] as const),
15
+ ),
16
+ )
17
+
18
+ const lookupShortcode = (char: string): string | undefined =>
19
+ CHAR_TO_SHORTCODE.get(char)
20
+
21
+ const EMOJI_PAGE_SIZE = 13
22
+
23
+ const FAVORITES = {
24
+ id: "favorites",
25
+ label: "Favorites",
26
+ icon: "⭐",
27
+ } as const
28
+
29
+ const buildCategoryDeckId = (baseDeckId: string, categoryId: string): string =>
30
+ `${baseDeckId}-${categoryId}`
31
+
32
+ const buildEmojiDeck = (name: string, emojis: readonly Emoji[]) => {
33
+ return {
34
+ name,
35
+ buttons: emojis.map((emoji, offset) => ({
36
+ type: "emoji-selector:emoji",
37
+ emoji: emoji.char,
38
+ ...(emoji.shortcode !== undefined ? { shortcode: emoji.shortcode } : {}),
39
+ position: offset,
40
+ actions: {
41
+ tap: `type://${emoji.char}`,
42
+ ...(emoji.shortcode !== undefined
43
+ ? { dbltap: `type://:${emoji.shortcode}:` }
44
+ : {}),
45
+ },
46
+ })),
47
+ paginated: true,
48
+ }
49
+ }
50
+
51
+ const generateDecks = (
52
+ deck: { id: string },
53
+ config: EmojiSelectorDeckConfig,
54
+ ): Record<string, AddonGeneratedDeck> => {
55
+ const decks: Record<string, AddonGeneratedDeck> = {}
56
+ const favorites = (
57
+ config.favorites.length > 0 ? config.favorites : [...DEFAULT_FAVORITES]
58
+ ).map((emoji) => ({
59
+ char: emoji,
60
+ shortcode: lookupShortcode(emoji),
61
+ }))
62
+
63
+ const favoritesDeckId = buildCategoryDeckId(deck.id, FAVORITES.id)
64
+ decks[favoritesDeckId] = buildEmojiDeck(FAVORITES.label, favorites)
65
+
66
+ const topButtons: {
67
+ type: string
68
+ icon: string
69
+ label: string
70
+ position: number
71
+ target_deck: string
72
+ }[] = []
73
+
74
+ const favTotalPages = Math.max(
75
+ 1,
76
+ Math.ceil(favorites.length / EMOJI_PAGE_SIZE),
77
+ )
78
+ topButtons.push({
79
+ type: "emoji-selector:category",
80
+ icon: FAVORITES.icon,
81
+ label: FAVORITES.label,
82
+ position: 0,
83
+ target_deck: favTotalPages > 1 ? `${favoritesDeckId}-p1` : favoritesDeckId,
84
+ })
85
+
86
+ categories.forEach((category, idx) => {
87
+ const categoryDeckId = buildCategoryDeckId(deck.id, category.id)
88
+ const totalPages = Math.max(
89
+ 1,
90
+ Math.ceil(category.emojis.length / EMOJI_PAGE_SIZE),
91
+ )
92
+ decks[categoryDeckId] = buildEmojiDeck(category.label, category.emojis)
93
+ topButtons.push({
94
+ type: "emoji-selector:category",
95
+ icon: category.icon,
96
+ label: category.label,
97
+ position: idx + 1,
98
+ target_deck: totalPages > 1 ? `${categoryDeckId}-p1` : categoryDeckId,
99
+ })
100
+ })
101
+
102
+ decks[deck.id] = {
103
+ name: "Emoji Selector",
104
+ buttons: topButtons,
105
+ paginated: true,
106
+ }
107
+
108
+ return decks
109
+ }
110
+
111
+ // ponytail: phase 11 array form. The factory takes the addon's
112
+ // runtime config (favorites override) and produces the multi-dynamic
113
+ // record keyed by deck id. Each generated deck id is the run-time
114
+ // identifier — `emoji-selector` is the launcher; `emoji-selector-<category>`
115
+ // are the category drill-downs; the synthetic multi key isn't used
116
+ // here because the factory has a fixed id.
117
+ const emojiSelectorDeckEntry: AddonDeckEntry = {
118
+ createDecks: ({
119
+ config,
120
+ }: {
121
+ config: unknown
122
+ deck: { id: string }
123
+ keyCount: number
124
+ }): Record<string, AddonGeneratedDeck> => {
125
+ const cfg =
126
+ config && typeof config === "object" && "favorites" in config
127
+ ? (config as EmojiSelectorDeckConfig)
128
+ : { favorites: [] }
129
+ return generateDecks({ id: "emoji-selector" }, cfg)
130
+ },
131
+ }
132
+
133
+ export default emojiSelectorDeckEntry
134
+ export {
135
+ emojiSelectorDeckEntry as emojiSelectorDeckFactory,
136
+ EmojiSelectorDeckSchema,
137
+ }
@@ -0,0 +1,5 @@
1
+ import type { NewAddonManifest } from "@/addon/api"
2
+
3
+ declare const manifest: NewAddonManifest
4
+ export default manifest
5
+ export { manifest }
@@ -0,0 +1,29 @@
1
+ import type { AddonManifestV1 } from "@/addon/api"
2
+
3
+ import categoryBackend from "./buttons/category/backend"
4
+ import categoryFrontend from "./buttons/category/frontend"
5
+ import emojiBackend from "./buttons/emoji/backend"
6
+ import emojiFrontend from "./buttons/emoji/frontend"
7
+ import launcherBackend from "./buttons/launcher/backend"
8
+ import launcherFrontend from "./buttons/launcher/frontend"
9
+ import emojiSelectorDeckEntry from "./decks"
10
+
11
+ export const manifest: AddonManifestV1 = {
12
+ apiVersion: 1,
13
+ name: "emoji-selector",
14
+ buttonTypes: {
15
+ "emoji-selector:category": {
16
+ frontend: categoryFrontend,
17
+ service: categoryBackend,
18
+ },
19
+ "emoji-selector:emoji": { frontend: emojiFrontend, service: emojiBackend },
20
+ "emoji-selector:launcher": {
21
+ frontend: launcherFrontend,
22
+ service: { ...launcherBackend, gestureHandlers: ["tap"] as const },
23
+ },
24
+ },
25
+ decks: [emojiSelectorDeckEntry],
26
+ }
27
+
28
+ export const emojiSelectorAddon = manifest
29
+ export default manifest
@@ -0,0 +1,6 @@
1
+ {
2
+ "kind": "addon",
3
+ "apiVersion": 1,
4
+ "name": "emoji-selector",
5
+ "entry": "index.ts"
6
+ }
@@ -0,0 +1,49 @@
1
+ import { z } from "zod"
2
+
3
+ export const EMOJI_LAUNCHER_GRID: readonly string[] = [
4
+ "\u{1F602}",
5
+ "\u{1F525}",
6
+ "\u2764\uFE0F",
7
+ "\u2B50",
8
+ "\u{1F355}",
9
+ "\u{1F3B5}",
10
+ ]
11
+
12
+ export const EMOJI_FONT_STACK =
13
+ "'Apple Color Emoji', 'Segoe UI Emoji', 'Noto Color Emoji', 'Twemoji Mozilla', system-ui, sans-serif"
14
+
15
+ export const DEFAULT_FAVORITES: readonly string[] = [
16
+ "❤️",
17
+ "🔥",
18
+ "⭐",
19
+ "😂",
20
+ "👍",
21
+ "🎉",
22
+ "💯",
23
+ "✨",
24
+ "🙏",
25
+ "👑",
26
+ ] as const
27
+
28
+ export const EmojiLauncherButtonSchema = z
29
+ .object({
30
+ label: z.string().min(1).default("Emojis"),
31
+ // Curated favorites shown first in the emoji deck. Valid on the launcher
32
+ // button (this schema) AND on the per-deck override record
33
+ // (decks["emoji-selector:__multi__"].config.favorites); the launcher
34
+ // wins when both are set. Falls back to DEFAULT_FAVORITES.
35
+ favorites: z.array(z.string().min(1)).optional(),
36
+ })
37
+ .strict()
38
+
39
+ export type EmojiLauncherButtonConfig = z.infer<
40
+ typeof EmojiLauncherButtonSchema
41
+ >
42
+
43
+ export const EmojiSelectorDeckSchema = z
44
+ .object({
45
+ favorites: z.array(z.string().min(1)).default([...DEFAULT_FAVORITES]),
46
+ })
47
+ .strict()
48
+
49
+ export type EmojiSelectorDeckConfig = z.infer<typeof EmojiSelectorDeckSchema>
@@ -0,0 +1,13 @@
1
+ export { SYSTEM_BUTTON_TYPES } from "@/deck/system-buttons/types"
2
+ export { default as brightnessAddon } from "./brightness/index"
3
+ export { coreAddon } from "./core/index"
4
+ export { default as dateTimeAddon } from "./date-time/index"
5
+ export { default as emojiSelectorAddon } from "./emoji-selector/index"
6
+ export { internalSettingsAddon } from "./internal-settings/index"
7
+ export { default as mediaPlayerAddon } from "./media/index"
8
+ export { registerBuiltins } from "./register-builtins"
9
+ export { sessionAddon } from "./session/index"
10
+ export { systemStatusAddon } from "./system-status/index"
11
+ export { default as testBuildinAddon } from "./test-buildin/index"
12
+ export { default as valueDisplayAddon } from "./value-display/index"
13
+ export { default as weatherAddon } from "./weather/index"
@@ -0,0 +1,26 @@
1
+ # internal-settings
2
+
3
+ **Internal-only addon.** Provides the `settings` overlay deck (brightness up/down, app info). The runtime injects `settings` automatically when the `internal-settings:settings` deck is opened from the reserved `n-1` slot.
4
+
5
+ You don't reference this addon directly in `config.yml`. The settings overlay is always available via the back/settings entry button on every deck.
6
+
7
+ ## Buttons
8
+
9
+ | Type | Description |
10
+ | ----------------------------------- | -------------------------------- |
11
+ | `internal-settings:brightness-up` | Increase screen brightness |
12
+ | `internal-settings:brightness-down` | Decrease screen brightness |
13
+ | `internal-settings:app-info` | Shows the about / app info panel |
14
+
15
+ ## Decks
16
+
17
+ | Deck id | Buttons |
18
+ | ---------------------------- | ---------------------------------------------------- |
19
+ | `internal-settings:settings` | brightness-up (0), brightness-down (1), app-info (2) |
20
+
21
+ The `settings` deck is auto-generated. The brightness buttons delegate to the OS provider's brightness control (see [brightness](../brightness/README.md)).
22
+
23
+ ## See also
24
+
25
+ - [brightness](../brightness/README.md) — brightness OS provider
26
+ - [Session](../session/README.md) — provides the `session:locked` overlay
@@ -0,0 +1,58 @@
1
+ import type pino from "pino"
2
+
3
+ import { AddonServiceContext, AddonGlobalService } from "@/addon/api"
4
+ import {
5
+ createBrightnessProvider,
6
+ type BrightnessProvider,
7
+ } from "@/builtin-addons/brightness/providers"
8
+
9
+ let brightnessProvider: BrightnessProvider | null = null
10
+
11
+ const clampStep = (step: unknown, fallback: number): number => {
12
+ if (typeof step !== "number" || !Number.isFinite(step)) return fallback
13
+ return Math.max(0, Math.min(100, step))
14
+ }
15
+
16
+ const noOpLogger = {
17
+ info: () => undefined,
18
+ warn: () => undefined,
19
+ } as unknown as pino.Logger
20
+
21
+ export const globalService: AddonGlobalService = {
22
+ methods: {
23
+ brightnessUp: async (...args: readonly unknown[]) => {
24
+ if (brightnessProvider === null) return
25
+ const step = clampStep(args[0], 5)
26
+ const current = await brightnessProvider.getCurrent()
27
+ await brightnessProvider.setBrightness(
28
+ Math.min(100, current.value + step),
29
+ )
30
+ },
31
+ brightnessDown: async (...args: readonly unknown[]) => {
32
+ if (brightnessProvider === null) return
33
+ const step = clampStep(args[0], 5)
34
+ const current = await brightnessProvider.getCurrent()
35
+ await brightnessProvider.setBrightness(Math.max(0, current.value - step))
36
+ },
37
+ },
38
+ onLoad: (ctx: AddonServiceContext) => {
39
+ // ponytail: brightness providers speak the system-provider CommandExecutor
40
+ // dialect (command + args array); the addon executor runs a single shell
41
+ // string. Quote args and bridge the two — per-command timeouts are not
42
+ // needed for these one-shot probes.
43
+ const shellQuote = (value: string): string =>
44
+ `'${value.replaceAll("'", `'\\''`)}'`
45
+ const executor = {
46
+ run: async (command: string, args: ReadonlyArray<string>) =>
47
+ ctx.executor.run([command, ...args].map(shellQuote).join(" ")),
48
+ }
49
+ brightnessProvider = createBrightnessProvider({
50
+ executor,
51
+ platform: process.platform,
52
+ logger: noOpLogger,
53
+ })
54
+ },
55
+ onUnload: () => {
56
+ brightnessProvider = null
57
+ },
58
+ }
@@ -0,0 +1,7 @@
1
+ import type { AddonButtonService } from "@/addon/api"
2
+
3
+ export default {
4
+ onTap: async () => {
5
+ // no-op — display-only button
6
+ },
7
+ } satisfies AddonButtonService
@@ -0,0 +1,13 @@
1
+ import { z } from "zod"
2
+
3
+ export const configSchema = z
4
+ .object({
5
+ icon: z
6
+ .string()
7
+ .min(1)
8
+ .optional()
9
+ .default("addon://internal-settings/logo72x72.png"),
10
+ })
11
+ .strict()
12
+
13
+ export type ConfigSchema = z.infer<typeof configSchema>
@@ -0,0 +1,18 @@
1
+ import type { AddonFrontendButton } from "@/addon/api"
2
+ import { Icon, Text } from "@/ui/index"
3
+
4
+ import pkg from "../../../../../package.json" with { type: "json" }
5
+ import type { ConfigSchema } from "./config"
6
+
7
+ const version: string = typeof pkg.version === "string" ? pkg.version : "0.0.0"
8
+
9
+ const AppInfoButtonFrontend: AddonFrontendButton<ConfigSchema> = ({
10
+ config,
11
+ }) => (
12
+ <div className="flex h-full w-full items-center justify-center gap-1 flex-col">
13
+ <Icon source={config.icon} size={40} />
14
+ <Text text={version} />
15
+ </div>
16
+ )
17
+
18
+ export default AppInfoButtonFrontend
@@ -0,0 +1,50 @@
1
+ import type { AddonGestureEvent } from "@/addon/api"
2
+ import { useAddonChannel } from "@/api/react"
3
+ import { IconLabelProgressSurface } from "@/ui/index"
4
+ import { useEffect, useRef, useState } from "react"
5
+
6
+ const BRIGHTNESS_CHANNEL = "sireno:settings:brightness"
7
+ const PROGRESS_VISIBLE_MS = 2000
8
+
9
+ export type BrightnessVariant = "down" | "up"
10
+
11
+ interface BrightnessButtonFrontendProps {
12
+ readonly variant: BrightnessVariant
13
+ readonly gesture?: AddonGestureEvent | null
14
+ }
15
+
16
+ export const BrightnessButtonFrontend = ({
17
+ variant,
18
+ gesture,
19
+ }: BrightnessButtonFrontendProps) => {
20
+ const { data } = useAddonChannel<{ value: number }>(BRIGHTNESS_CHANNEL)
21
+ const progress = typeof data?.value === "number" ? data.value : 0
22
+ const [showProgress, setShowProgress] = useState(false)
23
+ const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
24
+
25
+ useEffect(() => {
26
+ if (gesture?.gesture !== "tap" && gesture?.gesture !== "dbl-tap") return
27
+ setShowProgress(true)
28
+ if (timerRef.current) clearTimeout(timerRef.current)
29
+ timerRef.current = setTimeout(
30
+ () => setShowProgress(false),
31
+ PROGRESS_VISIBLE_MS,
32
+ )
33
+ }, [gesture?.at])
34
+
35
+ useEffect(
36
+ () => () => {
37
+ if (timerRef.current) clearTimeout(timerRef.current)
38
+ },
39
+ [],
40
+ )
41
+
42
+ return (
43
+ <IconLabelProgressSurface
44
+ source={`icon://${variant === "down" ? "sun-dim" : "sun"}`}
45
+ label={variant === "down" ? "Darker" : "Lighter"}
46
+ progress={progress}
47
+ visible={showProgress}
48
+ />
49
+ )
50
+ }
@@ -0,0 +1,16 @@
1
+ import { z } from "zod"
2
+ import type { AddonButtonTypeService } from "@/addon/api"
3
+
4
+ import { configSchema } from "./config"
5
+
6
+ type Config = z.infer<typeof configSchema>
7
+
8
+ export default {
9
+ configSchema,
10
+ onTap: ({ coreMethods }) => {
11
+ coreMethods.adjustBrightness({ direction: "down" })
12
+ },
13
+ onDblTap: ({ coreMethods }) => {
14
+ coreMethods.adjustBrightness({ direction: "down" })
15
+ },
16
+ } satisfies AddonButtonTypeService<Config>
@@ -0,0 +1,6 @@
1
+ import { z } from "zod"
2
+
3
+ export const configSchema = z.object({
4
+ step: z.number().positive().max(100).default(5),
5
+ })
6
+ export type ConfigSchema = z.infer<typeof configSchema>
@@ -0,0 +1,8 @@
1
+ import type { AddonFrontendButton } from "@/addon/api"
2
+ import { BrightnessButtonFrontend } from "../brightness/common/frontend"
3
+
4
+ const BrightnessDownButtonFrontend: AddonFrontendButton<unknown> = ({
5
+ gesture,
6
+ }) => <BrightnessButtonFrontend variant="down" gesture={gesture ?? null} />
7
+
8
+ export default BrightnessDownButtonFrontend
@@ -0,0 +1,16 @@
1
+ import { z } from "zod"
2
+ import type { AddonButtonTypeService } from "@/addon/api"
3
+
4
+ import { configSchema } from "./config"
5
+
6
+ type Config = z.infer<typeof configSchema>
7
+
8
+ export default {
9
+ configSchema,
10
+ onTap: ({ coreMethods }) => {
11
+ coreMethods.adjustBrightness({ direction: "up" })
12
+ },
13
+ onDblTap: ({ coreMethods }) => {
14
+ coreMethods.adjustBrightness({ direction: "up" })
15
+ },
16
+ } satisfies AddonButtonTypeService<Config>
@@ -0,0 +1,6 @@
1
+ import { z } from "zod"
2
+
3
+ export const configSchema = z.object({
4
+ step: z.number().positive().max(100).default(5),
5
+ })
6
+ export type ConfigSchema = z.infer<typeof configSchema>
@@ -0,0 +1,8 @@
1
+ import type { AddonFrontendButton } from "@/addon/api"
2
+ import { BrightnessButtonFrontend } from "../brightness/common/frontend"
3
+
4
+ const BrightnessUpButtonFrontend: AddonFrontendButton<unknown> = ({
5
+ gesture,
6
+ }) => <BrightnessButtonFrontend variant="up" gesture={gesture ?? null} />
7
+
8
+ export default BrightnessUpButtonFrontend
@@ -0,0 +1,25 @@
1
+ import type { AddonDeckFactory } from "@/addon/api"
2
+
3
+ const settingsDeck: AddonDeckFactory = () => ({
4
+ name: "Settings",
5
+ buttons: [
6
+ {
7
+ id: "brightness-down",
8
+ type: "internal-settings:brightness-down",
9
+ position: 0,
10
+ },
11
+ {
12
+ id: "brightness-up",
13
+ type: "internal-settings:brightness-up",
14
+ position: 1,
15
+ },
16
+ {
17
+ id: "app-info",
18
+ type: "internal-settings:app-info",
19
+ position: 2,
20
+ config: { icon: "addon://internal-settings/logo72x72.png" },
21
+ },
22
+ ],
23
+ })
24
+
25
+ export default settingsDeck
@@ -0,0 +1,4 @@
1
+ import type { NewAddonManifest } from "@/addon/api"
2
+
3
+ declare const manifest: NewAddonManifest
4
+ export default manifest
@@ -0,0 +1,53 @@
1
+ import type { AddonManifestV1 } from "@/addon/api"
2
+
3
+ import appInfoBackend from "./buttons/app-info/backend"
4
+ import appInfoFrontend from "./buttons/app-info/frontend"
5
+ import brightnessDownBackend from "./buttons/brightness-down/backend"
6
+ import brightnessDownFrontend from "./buttons/brightness-down/frontend"
7
+ import brightnessUpBackend from "./buttons/brightness-up/backend"
8
+ import brightnessUpFrontend from "./buttons/brightness-up/frontend"
9
+ import settingsDeck from "./decks/settings"
10
+
11
+ const withInternal = <T extends object>(impl: T): T & { internal: true } => ({
12
+ ...impl,
13
+ internal: true,
14
+ })
15
+
16
+ export const manifest: AddonManifestV1 = {
17
+ apiVersion: 1,
18
+ name: "internal-settings",
19
+ buttonTypes: {
20
+ "internal-settings:brightness-down": {
21
+ frontend: brightnessDownFrontend,
22
+ service: {
23
+ ...withInternal(brightnessDownBackend),
24
+ gestureHandlers: ["tap", "dbl-tap"] as const,
25
+ },
26
+ },
27
+ "internal-settings:brightness-up": {
28
+ frontend: brightnessUpFrontend,
29
+ service: {
30
+ ...withInternal(brightnessUpBackend),
31
+ gestureHandlers: ["tap", "dbl-tap"] as const,
32
+ },
33
+ },
34
+ "internal-settings:app-info": {
35
+ frontend: appInfoFrontend,
36
+ service: {
37
+ ...withInternal(appInfoBackend),
38
+ gestureHandlers: ["tap"] as const,
39
+ full: true,
40
+ },
41
+ },
42
+ },
43
+ decks: [
44
+ {
45
+ id: "internal-settings:settings",
46
+ createDeck: () => settingsDeck(0),
47
+ internal: true,
48
+ },
49
+ ],
50
+ }
51
+
52
+ export const internalSettingsAddon = manifest
53
+ export default manifest
@@ -0,0 +1,6 @@
1
+ {
2
+ "kind": "addon",
3
+ "apiVersion": 1,
4
+ "name": "internal-settings",
5
+ "entry": "index.ts"
6
+ }
@@ -0,0 +1,45 @@
1
+ # media
2
+
3
+ Single button that shows the current track + play/pause state. Tap = play/pause. Hold = next track. The left half of the button is prev/play/pause, the right half is next/volume (split button).
4
+
5
+ Uses the OS media provider from `packages/cli/src/system/providers/`:
6
+
7
+ - Linux: `playerctl` (MPRIS)
8
+ - macOS: `osascript`
9
+ - Windows: PowerShell + UIA
10
+
11
+ ## Buttons
12
+
13
+ | Type | Description |
14
+ | ------------------- | --------------------------------------------------------------- |
15
+ | `media:player` | Single button: prev / play-pause / next + volume (split action) |
16
+ | `media:mute` | Toggle mute |
17
+ | `media:volume:up` | Volume up by step |
18
+ | `media:volume:down` | Volume down by step |
19
+
20
+ ## Config
21
+
22
+ The `media:player` button has no config — it auto-discovers the OS media provider.
23
+
24
+ ```yaml
25
+ - position: 12
26
+ type: media:player
27
+ ```
28
+
29
+ ## Example
30
+
31
+ ```yaml
32
+ decks:
33
+ main:
34
+ name: Main
35
+ buttons:
36
+ - position: 12
37
+ type: media:player
38
+ ```
39
+
40
+ Run `playerctl status` (Linux) or open Music (macOS) / Windows Media Player to see the state reflected on the button.
41
+
42
+ ## See also
43
+
44
+ - [OS providers](../../../../system/providers/README.md) — media player integration per OS
45
+ - [system-status](../system-status/README.md) — same addon pattern (no config, polls OS)