@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,16 @@
1
+ import type { AddonRegistry } from "@/addon/registry"
2
+ import { systemStatusManifest } from "./manifest"
3
+
4
+ export const registerSystemStatusAddon = (registry: AddonRegistry): void => {
5
+ registry.load(systemStatusManifest)
6
+ }
7
+
8
+ export {
9
+ POLL_INTERVAL_MS,
10
+ SystemStatusConfigSchema,
11
+ SYSTEM_METRIC_IDS,
12
+ systemStatusAddon,
13
+ systemStatusManifest,
14
+ } from "./manifest"
15
+ export type { SystemStatusConfig, SystemMetricId } from "./manifest"
16
+ export default systemStatusManifest
@@ -0,0 +1,105 @@
1
+ import type { AddonGlobalPoller, AddonManifestV1 } from "@/addon/api"
2
+
3
+ import systemStatusFrontend from "./buttons/system-status/frontend"
4
+ import {
5
+ POLL_INTERVAL_MS,
6
+ SystemStatusConfigSchema,
7
+ type SystemStatusConfig,
8
+ } from "./buttons/system-status/schemas"
9
+ import { CHART_HISTORY_CHANNEL } from "./domain"
10
+ import {
11
+ SYSTEM_METRIC_IDS,
12
+ type SystemMetricId,
13
+ } from "./shared/metrics-catalog"
14
+
15
+ // ponytail: pollers are server-only; lazy-import live-metrics so the manifest
16
+ // can be loaded by the frontend addon virtual module without dragging
17
+ // node:os / node:fs into the browser bundle.
18
+ function makePoller(metricId: SystemMetricId): AddonGlobalPoller {
19
+ return {
20
+ id: `metric:${metricId}`,
21
+ channel: `runtime:system-status:${metricId}`,
22
+ // ponytail: one cadence for all metrics. POLL_INTERVAL_MS
23
+ // is the single source of truth. Per-button overrides would require moving
24
+ // polling into per-button onMount handlers (multiple buttons on the same
25
+ // metric would race on one channel); not worth the refactor today.
26
+ intervalMs: POLL_INTERVAL_MS,
27
+ poll: async () => {
28
+ const { probeMetric } = await import("./domain/live-metrics")
29
+ const result = await probeMetric(metricId)
30
+ if (result.value !== undefined && result.available) {
31
+ const { feedSampler } = await import("./domain/chart-sampler")
32
+ feedSampler(metricId, result.value, Date.now())
33
+ }
34
+ return result
35
+ },
36
+ }
37
+ }
38
+
39
+ export const systemStatusManifest: AddonManifestV1 = {
40
+ apiVersion: 1,
41
+ name: "system-status",
42
+ buttonTypes: {
43
+ "system-status:system-status": {
44
+ frontend: systemStatusFrontend,
45
+ service: {
46
+ configSchema: SystemStatusConfigSchema,
47
+ internal: false,
48
+ gestureHandlers: ["tap"] as const,
49
+ },
50
+ },
51
+ },
52
+ globalService: {
53
+ pollers: [
54
+ ...SYSTEM_METRIC_IDS.map(makePoller),
55
+ {
56
+ id: "metric:chart-history",
57
+ channel: CHART_HISTORY_CHANNEL,
58
+ intervalMs: POLL_INTERVAL_MS,
59
+ poll: async () => {
60
+ const { getSamplerState } = await import("./domain/chart-sampler")
61
+ return getSamplerState()
62
+ },
63
+ },
64
+ ],
65
+ },
66
+ checks: [
67
+ {
68
+ // ponytail: mirrors the media addon's media-control check. On Apple
69
+ // Silicon, CPU/GPU temperature and fan RPM have no unprivileged source
70
+ // from the tools already in use here — powermetrics needs root and the
71
+ // only readable Temperature in ioreg is the battery's. macmon reads them
72
+ // through IOReport without sudo. Absent, those three metrics simply stay
73
+ // unavailable, so this is a hint rather than a hard requirement.
74
+ name: "macos-sensors",
75
+ check: async () => {
76
+ if (process.platform !== "darwin") return { available: true }
77
+ const { execFile } = await import("node:child_process")
78
+ const { promisify } = await import("node:util")
79
+ try {
80
+ await promisify(execFile)("sh", ["-c", "command -v macmon"], {
81
+ timeout: 2_000,
82
+ })
83
+ return { available: true }
84
+ } catch {
85
+ return {
86
+ available: false,
87
+ reason:
88
+ "install macmon (`brew install macmon`) to report CPU/GPU temperature and fan RPM; without it those three metrics stay unavailable on Apple Silicon",
89
+ }
90
+ }
91
+ },
92
+ },
93
+ ],
94
+ }
95
+
96
+ export const systemStatusAddon = systemStatusManifest
97
+ export default systemStatusManifest
98
+
99
+ export {
100
+ POLL_INTERVAL_MS,
101
+ SystemStatusConfigSchema,
102
+ SYSTEM_METRIC_IDS,
103
+ type SystemStatusConfig,
104
+ }
105
+ export type { SystemMetricId }
@@ -0,0 +1,316 @@
1
+ export type MetricFormatter =
2
+ | "bytes"
3
+ | "bool"
4
+ | "count"
5
+ | "frequency-ghz"
6
+ | "percent"
7
+ | "rate-bytes"
8
+ | "uptime"
9
+
10
+ // ponytail: formatters emit value-only; the unit lives in `DisplayMetric.unit`
11
+ // so the renderer can style the value and the unit independently (e.g. bigger
12
+ // digits + smaller "%" suffix). When the unit is magnitude-dependent (bytes,
13
+ // rate-bytes, uptime) the formatter picks the right scale and returns both halves.
14
+ export interface FormattedValue {
15
+ value: string
16
+ unit?: string
17
+ unitLong?: string
18
+ }
19
+
20
+ export type MetricView = "bars" | "chart" | "kpis"
21
+ export type MetricColor = "default" | "success" | "warning" | "danger"
22
+
23
+ export interface MetricThreshold {
24
+ /** Lower bound, inclusive. Omit for -Infinity. */
25
+ minValue?: number
26
+ /** Upper bound, inclusive. Omit for +Infinity. */
27
+ maxValue?: number
28
+ color: MetricColor
29
+ }
30
+
31
+ export interface DisplayMetric {
32
+ id: SystemMetricId
33
+ label: string
34
+ available: boolean
35
+ // ponytail: numeric/digit portion only — units live in `unit` so the
36
+ // renderer can style them independently. Magnitude-dependent formatters
37
+ // (bytes, rate-bytes, uptime) emit a scale-aware unit; static formatters
38
+ // (percent) emit "%"; magnitude-independent formatters (count,
39
+ // frequency-ghz, bool) emit no unit and let the probe/catalog supply it.
40
+ formattedValue: string
41
+ unit?: string
42
+ unitLong?: string
43
+ value?: number
44
+ max?: number
45
+ percentage?: number
46
+ }
47
+
48
+ export interface MetricDef {
49
+ readonly id: SystemMetricId
50
+ readonly defaultLabel: string
51
+ readonly defaultShortLabel?: string
52
+ readonly icon?: string
53
+ readonly unit?: string
54
+ readonly formatter: MetricFormatter
55
+ readonly views: ReadonlyArray<MetricView>
56
+ /** Upper bound for bar rendering. Omit when bars aren't supported. */
57
+ readonly maxValue?: number
58
+ readonly thresholds?: ReadonlyArray<MetricThreshold>
59
+ }
60
+
61
+ export interface SystemMetricSnapshot {
62
+ available: boolean
63
+ id: SystemMetricId
64
+ label: string
65
+ max?: number
66
+ percentage?: number
67
+ unit?: string
68
+ value?: number
69
+ }
70
+
71
+ export interface MetricConfig {
72
+ id: SystemMetricId
73
+ label?: string
74
+ }
75
+
76
+ export type SystemMetricId =
77
+ | "battery"
78
+ | "cpu"
79
+ | "cpu-boost"
80
+ | "cpu-voltages"
81
+ | "disk"
82
+ | "disk-io"
83
+ | "fan-rpm"
84
+ | "frequency"
85
+ | "gpu-temp"
86
+ | "gpu-usage"
87
+ | "load"
88
+ | "network"
89
+ | "network-read"
90
+ | "network-write"
91
+ | "processes"
92
+ | "ram"
93
+ | "swap"
94
+ | "temperature"
95
+ | "uptime"
96
+
97
+ export const METRICS_CATALOG: Readonly<Record<SystemMetricId, MetricDef>> = {
98
+ cpu: {
99
+ id: "cpu",
100
+ defaultLabel: "CPU",
101
+ defaultShortLabel: "CPU",
102
+ icon: "icon://cpu",
103
+ unit: "%",
104
+ formatter: "percent",
105
+ views: ["bars", "chart", "kpis"],
106
+ maxValue: 100,
107
+ thresholds: [
108
+ { maxValue: 70, color: "default" },
109
+ { minValue: 70, maxValue: 90, color: "warning" },
110
+ { minValue: 90, color: "danger" },
111
+ ],
112
+ },
113
+ ram: {
114
+ id: "ram",
115
+ defaultLabel: "RAM",
116
+ icon: "icon://memory-stick",
117
+ unit: "%",
118
+ formatter: "percent",
119
+ views: ["bars", "chart", "kpis"],
120
+ maxValue: 100,
121
+ thresholds: [
122
+ { maxValue: 70, color: "default" },
123
+ { minValue: 70, maxValue: 90, color: "warning" },
124
+ { minValue: 90, color: "danger" },
125
+ ],
126
+ },
127
+ swap: {
128
+ id: "swap",
129
+ defaultLabel: "Swap",
130
+ defaultShortLabel: "SWP",
131
+ icon: "icon://repeat",
132
+ unit: "%",
133
+ formatter: "percent",
134
+ views: ["bars", "chart", "kpis"],
135
+ maxValue: 100,
136
+ thresholds: [
137
+ { maxValue: 50, color: "default" },
138
+ { minValue: 50, maxValue: 80, color: "warning" },
139
+ { minValue: 80, color: "danger" },
140
+ ],
141
+ },
142
+ disk: {
143
+ id: "disk",
144
+ defaultLabel: "Disk",
145
+ defaultShortLabel: "DSK",
146
+ icon: "icon://hard-drive",
147
+ unit: "%",
148
+ formatter: "percent",
149
+ views: ["bars", "chart", "kpis"],
150
+ maxValue: 100,
151
+ thresholds: [
152
+ { maxValue: 70, color: "default" },
153
+ { minValue: 70, maxValue: 90, color: "warning" },
154
+ { minValue: 90, color: "danger" },
155
+ ],
156
+ },
157
+ battery: {
158
+ id: "battery",
159
+ defaultLabel: "Battery",
160
+ defaultShortLabel: "BAT",
161
+ icon: "icon://battery",
162
+ unit: "%",
163
+ formatter: "percent",
164
+ views: ["bars", "chart", "kpis"],
165
+ maxValue: 100,
166
+ thresholds: [
167
+ { minValue: 40, color: "default" },
168
+ { minValue: 20, maxValue: 40, color: "warning" },
169
+ { maxValue: 20, color: "danger" },
170
+ ],
171
+ },
172
+ temperature: {
173
+ id: "temperature",
174
+ defaultLabel: "Temp",
175
+ defaultShortLabel: "TMP",
176
+ icon: "icon://thermometer",
177
+ unit: "°C",
178
+ formatter: "count",
179
+ views: ["bars", "chart", "kpis"],
180
+ maxValue: 100,
181
+ thresholds: [
182
+ { maxValue: 70, color: "default" },
183
+ { minValue: 70, maxValue: 85, color: "warning" },
184
+ { minValue: 85, color: "danger" },
185
+ ],
186
+ },
187
+ frequency: {
188
+ id: "frequency",
189
+ defaultLabel: "Freq",
190
+ defaultShortLabel: "FRQ",
191
+ icon: "icon://activity",
192
+ unit: "GHz",
193
+ formatter: "frequency-ghz",
194
+ views: ["bars", "chart", "kpis"],
195
+ maxValue: 5,
196
+ thresholds: [{ minValue: 4, color: "success" }],
197
+ },
198
+ load: {
199
+ id: "load",
200
+ defaultLabel: "Load",
201
+ defaultShortLabel: "LD",
202
+ icon: "icon://gauge",
203
+ formatter: "count",
204
+ views: ["bars", "chart", "kpis"],
205
+ maxValue: 100,
206
+ thresholds: [
207
+ { maxValue: 50, color: "default" },
208
+ { minValue: 50, maxValue: 80, color: "warning" },
209
+ { minValue: 80, color: "danger" },
210
+ ],
211
+ },
212
+ // ponytail: these three have no meaningful `maxValue` — bars would lie.
213
+ // Catalog pins them to kpis-only; the bars frontend renders nothing for
214
+ // them if a config sneaks them in.
215
+ processes: {
216
+ id: "processes",
217
+ defaultLabel: "Procs",
218
+ icon: "icon://boxes",
219
+ formatter: "count",
220
+ views: ["kpis"],
221
+ },
222
+ network: {
223
+ id: "network",
224
+ defaultLabel: "Net",
225
+ icon: "icon://network",
226
+ formatter: "count",
227
+ views: ["kpis"],
228
+ },
229
+ uptime: {
230
+ id: "uptime",
231
+ defaultLabel: "Uptime",
232
+ icon: "icon://clock",
233
+ formatter: "uptime",
234
+ unit: "m",
235
+ views: ["kpis"],
236
+ },
237
+ "cpu-boost": {
238
+ id: "cpu-boost",
239
+ defaultLabel: "Boost",
240
+ icon: "icon://zap",
241
+ formatter: "bool",
242
+ views: ["kpis"],
243
+ thresholds: [{ minValue: 1, maxValue: 1, color: "success" }],
244
+ },
245
+ "cpu-voltages": {
246
+ id: "cpu-voltages",
247
+ defaultLabel: "Vcore",
248
+ icon: "icon://bolt",
249
+ formatter: "count",
250
+ unit: "V",
251
+ views: ["kpis"],
252
+ },
253
+ "disk-io": {
254
+ id: "disk-io",
255
+ defaultLabel: "Disk I/O",
256
+ icon: "icon://arrow-down-up",
257
+ formatter: "rate-bytes",
258
+ views: ["kpis"],
259
+ },
260
+ "fan-rpm": {
261
+ id: "fan-rpm",
262
+ defaultLabel: "Fan",
263
+ icon: "icon://fan",
264
+ formatter: "count",
265
+ unit: "RPM",
266
+ views: ["kpis"],
267
+ },
268
+ "gpu-temp": {
269
+ id: "gpu-temp",
270
+ defaultLabel: "GPU Temp",
271
+ defaultShortLabel: "GTT",
272
+ icon: "icon://thermometer-sun",
273
+ formatter: "count",
274
+ unit: "°C",
275
+ views: ["bars", "chart", "kpis"],
276
+ maxValue: 100,
277
+ thresholds: [
278
+ { maxValue: 70, color: "default" },
279
+ { minValue: 70, maxValue: 85, color: "warning" },
280
+ { minValue: 85, color: "danger" },
281
+ ],
282
+ },
283
+ "gpu-usage": {
284
+ id: "gpu-usage",
285
+ defaultLabel: "GPU",
286
+ defaultShortLabel: "GPU",
287
+ icon: "icon://microchip",
288
+ formatter: "percent",
289
+ unit: "%",
290
+ views: ["bars", "chart", "kpis"],
291
+ maxValue: 100,
292
+ thresholds: [
293
+ { maxValue: 70, color: "default" },
294
+ { minValue: 70, maxValue: 90, color: "warning" },
295
+ { minValue: 90, color: "danger" },
296
+ ],
297
+ },
298
+ "network-read": {
299
+ id: "network-read",
300
+ defaultLabel: "Net RX",
301
+ icon: "icon://arrow-down",
302
+ formatter: "rate-bytes",
303
+ views: ["kpis"],
304
+ },
305
+ "network-write": {
306
+ id: "network-write",
307
+ defaultLabel: "Net TX",
308
+ icon: "icon://arrow-up",
309
+ formatter: "rate-bytes",
310
+ views: ["kpis"],
311
+ },
312
+ } as const satisfies Readonly<Record<string, MetricDef>>
313
+
314
+ export const SYSTEM_METRIC_IDS = Object.keys(
315
+ METRICS_CATALOG,
316
+ ) as SystemMetricId[]
@@ -0,0 +1,6 @@
1
+ {
2
+ "kind": "addon",
3
+ "apiVersion": 1,
4
+ "name": "system-status",
5
+ "entry": "index.ts"
6
+ }
@@ -0,0 +1,56 @@
1
+ import type { AddonDeckEntry } from "@/addon/api"
2
+
3
+ /**
4
+ * Action Buttons Test deck — one `core:action` button per icon-source
5
+ * shape, so a single deck exercises every accepted (and a few rejected)
6
+ * icon configuration in the validator and runtime.
7
+ *
8
+ * The buttons are intentionally simple (no `actions.tap` — they're
9
+ * static, no-op displays) so tapping them is harmless. Each one's only
10
+ * job is to render a different icon shape, so the test deck reads as
11
+ * a visual matrix of "what each icon source renders as".
12
+ */
13
+
14
+ const ICON_CASES: ReadonlyArray<{ label: string; icon: string }> = [
15
+ // Lucide / icon:// — the most common shape
16
+ { label: "icon://play", icon: "icon://play" },
17
+ { label: "icon://settings", icon: "icon://settings" },
18
+ { label: "icon://volume-x", icon: "icon://volume-x" },
19
+ // Addon asset refs
20
+ {
21
+ label: "addon://emoji-selector/assets/smileys.svg",
22
+ icon: "addon://emoji-selector/assets/smileys.svg",
23
+ },
24
+ {
25
+ label: "addon://emoji-selector/assets/launcher.svg",
26
+ icon: "addon://emoji-selector/assets/launcher.svg",
27
+ },
28
+ // Single emoji
29
+ { label: "🔥", icon: "🔥" },
30
+ { label: "✈️", icon: "✈️" },
31
+ // Edge: empty name in scheme
32
+ { label: "icon:// (invalid)", icon: "icon://" },
33
+ // No icon at all (just label) — exercises the label-only path
34
+ { label: "(no icon)", icon: "" },
35
+ // Inline data URL (rejected by runtime — must be pre-resolved)
36
+ { label: "data: (invalid)", icon: "data:image/svg+xml;base64,PHN2Zy8+" },
37
+ ]
38
+
39
+ // ponytail: phase 11 array form. The deck is now a static AddonDeckEntry
40
+ // whose inline shape is the deck itself. No factory needed since the
41
+ // icon cases are baked in.
42
+ const ICON_BUTTONS = ICON_CASES.map(({ label, icon }, i) => ({
43
+ type: "core:action",
44
+ position: i,
45
+ ...(icon !== "" ? { config: { icon, label } } : { config: { label } }),
46
+ }))
47
+
48
+ const actionButtonsTestDeck: AddonDeckEntry = {
49
+ id: "test-buildin:action-buttons-test",
50
+ name: "Action Buttons Test",
51
+ icon: "🧪",
52
+ buttons: ICON_BUTTONS,
53
+ }
54
+
55
+ export default actionButtonsTestDeck
56
+ export { actionButtonsTestDeck }
@@ -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,16 @@
1
+ import type { AddonManifestV1 } from "@/addon/api"
2
+
3
+ import actionButtonsTestDeck from "./decks/action-buttons-test"
4
+
5
+ export const manifest: AddonManifestV1 = {
6
+ apiVersion: 1,
7
+ name: "test-buildin",
8
+ // No custom buttonTypes — the test deck uses the existing core:action
9
+ // button type so we can exercise the runtime's icon pipeline without
10
+ // introducing new backend code.
11
+ buttonTypes: {},
12
+ decks: [actionButtonsTestDeck],
13
+ }
14
+
15
+ export const testBuildinAddon = manifest
16
+ export default manifest
@@ -0,0 +1,59 @@
1
+ # value-display
2
+
3
+ Run shell commands and show their output. Useful for showing disk usage, git status, weather (without Open-Meteo), battery percentage (Linux), etc.
4
+
5
+ Each button has up to 4 `values` entries; each entry runs a command via the action executor and shows its output.
6
+
7
+ ## Buttons
8
+
9
+ | Type | Description |
10
+ | ----------------------- | ------------------------------------------------------ |
11
+ | `value-display:display` | Single button: shows N values (label + command output) |
12
+
13
+ ## Config
14
+
15
+ ```yaml
16
+ - position: 6
17
+ type: value-display:display
18
+ config:
19
+ poll_interval_ms: 5000 # optional, default 5000
20
+ timeout_ms: 5000 # optional, default 5000 (per command)
21
+ values:
22
+ - label: Disk
23
+ command: "df -h / | tail -1 | awk '{print $5}'"
24
+ formatter: strip # "raw" (default), "strip", or "line"
25
+ units: "%"
26
+ - label: Uptime
27
+ command: "uptime -p"
28
+ formatter: strip
29
+ - label: CPU Temp
30
+ command: "sensors | grep 'Core 0' | awk '{print $3}'"
31
+ timeout_ms: 2000
32
+ ```
33
+
34
+ ### Formatters
35
+
36
+ | Formatter | Behavior |
37
+ | --------- | --------------------------------------------------- |
38
+ | `raw` | Output the command's stdout verbatim |
39
+ | `strip` | Trim leading/trailing whitespace |
40
+ | `line` | Take only the first non-empty line, trim whitespace |
41
+
42
+ ## Example
43
+
44
+ ```yaml
45
+ - position: 6
46
+ type: value-display:display
47
+ config:
48
+ values:
49
+ - label: Disk
50
+ command: "df -h / | tail -1 | awk '{print $5}'"
51
+ units: "%"
52
+ - label: CPU Temp
53
+ command: "sensors | grep 'Core 0' | awk '{print $3}'"
54
+ ```
55
+
56
+ ## See also
57
+
58
+ - [weather](../weather/README.md) — `weather:weather` is a wrapper around Open-Meteo; `value-display:display` is the manual version
59
+ - [system-status](../system-status/README.md) — same polling pattern, but for built-in OS metrics
@@ -0,0 +1,86 @@
1
+ import type { AddonServiceContext, AddonGlobalService } from "@/addon/api"
2
+
3
+ import type { ConfigSchema } from "./buttons/value-display/config"
4
+
5
+ const DEFAULT_POLL_MS = 5000
6
+
7
+ const buttonRegistry = new Map<string, ConfigSchema>()
8
+ let ctxRef: AddonServiceContext | undefined
9
+
10
+ export const globalService: AddonGlobalService = {
11
+ methods: {
12
+ registerValues: (buttonId: unknown, config: unknown): void => {
13
+ buttonRegistry.set(String(buttonId), config as ConfigSchema)
14
+ ctxRef?.poll("values")
15
+ },
16
+ unregisterValues: (buttonId: unknown): void => {
17
+ buttonRegistry.delete(String(buttonId))
18
+ },
19
+ },
20
+ pollers: [
21
+ {
22
+ id: "values",
23
+ channel: "value-display:values",
24
+ intervalMs: DEFAULT_POLL_MS,
25
+ poll: async (ctx: AddonServiceContext) => {
26
+ const byButton: Record<
27
+ string,
28
+ Array<{
29
+ label: string
30
+ value: string
31
+ units?: string
32
+ }>
33
+ > = {}
34
+ if (buttonRegistry.size === 0) return { byButton }
35
+
36
+ await Promise.all(
37
+ [...buttonRegistry.entries()].map(async ([buttonId, config]) => {
38
+ const results = await Promise.all(
39
+ config.values.map(async (entry) => {
40
+ try {
41
+ const res = await ctx.executor.run(entry.command, {
42
+ timeoutMs: entry.timeout_ms ?? config.timeout_ms,
43
+ })
44
+ const raw = res.stdout ?? ""
45
+ let value: string
46
+ switch (entry.formatter) {
47
+ case "strip":
48
+ value = raw.replace(/\s+$/, "")
49
+ break
50
+ case "line":
51
+ value = (
52
+ raw.indexOf("\n") === -1
53
+ ? raw
54
+ : raw.slice(0, raw.indexOf("\n"))
55
+ ).trim()
56
+ break
57
+ case "raw":
58
+ default:
59
+ value = raw.trim()
60
+ break
61
+ }
62
+ return { label: entry.label, value, units: entry.units }
63
+ } catch {
64
+ return {
65
+ label: entry.label,
66
+ value: "err",
67
+ units: entry.units,
68
+ }
69
+ }
70
+ }),
71
+ )
72
+ byButton[buttonId] = results
73
+ }),
74
+ )
75
+ return { byButton }
76
+ },
77
+ },
78
+ ],
79
+ onLoad: async (ctx: AddonServiceContext) => {
80
+ ctxRef = ctx
81
+ },
82
+ onUnload: () => {
83
+ ctxRef = undefined
84
+ buttonRegistry.clear()
85
+ },
86
+ }
@@ -0,0 +1,17 @@
1
+ import type {
2
+ AddonButtonServiceContext,
3
+ AddonButtonTypeService,
4
+ } from "@/addon/api"
5
+
6
+ import { configSchema, type ConfigSchema } from "./config"
7
+
8
+ export default {
9
+ configSchema,
10
+ onMount: (ctx: AddonButtonServiceContext<ConfigSchema>) => {
11
+ ctx.methods["value-display:registerValues"]?.(ctx.buttonId, ctx.config)
12
+ },
13
+ dispose: (ctx: AddonButtonServiceContext<ConfigSchema>) => {
14
+ ctx.methods["value-display:unregisterValues"]?.(ctx.buttonId)
15
+ },
16
+ defaultRenderIntervalMs: 5000,
17
+ } satisfies AddonButtonTypeService<ConfigSchema>