@agentdeck/bridge 0.2.1 → 0.2.3

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 (383) hide show
  1. package/assets/fonts/IBMPlexSans-Bold.ttf +0 -0
  2. package/assets/fonts/IBMPlexSans-Regular.ttf +0 -0
  3. package/assets/fonts/JetBrainsMono-Bold.ttf +0 -0
  4. package/assets/fonts/JetBrainsMono-Regular.ttf +0 -0
  5. package/assets/fonts/LICENSES.md +22 -0
  6. package/dist/adapters/claude-code.d.ts +6 -0
  7. package/dist/adapters/claude-code.d.ts.map +1 -1
  8. package/dist/adapters/claude-code.js +8 -0
  9. package/dist/adapters/claude-code.js.map +1 -1
  10. package/dist/adapters/openclaw.d.ts +24 -0
  11. package/dist/adapters/openclaw.d.ts.map +1 -1
  12. package/dist/adapters/openclaw.js +291 -35
  13. package/dist/adapters/openclaw.js.map +1 -1
  14. package/dist/adapters/opencode-adapter.d.ts +59 -0
  15. package/dist/adapters/opencode-adapter.d.ts.map +1 -1
  16. package/dist/adapters/opencode-adapter.js +297 -35
  17. package/dist/adapters/opencode-adapter.js.map +1 -1
  18. package/dist/adb-reverse.d.ts +1 -1
  19. package/dist/adb-reverse.js +1 -1
  20. package/dist/antigravity-local.d.ts +1 -0
  21. package/dist/antigravity-local.d.ts.map +1 -1
  22. package/dist/antigravity-local.js +33 -0
  23. package/dist/antigravity-local.js.map +1 -1
  24. package/dist/apme/adapters/claude-hook.d.ts.map +1 -1
  25. package/dist/apme/adapters/claude-hook.js +5 -0
  26. package/dist/apme/adapters/claude-hook.js.map +1 -1
  27. package/dist/apme/adapters/codex-hook.d.ts +17 -0
  28. package/dist/apme/adapters/codex-hook.d.ts.map +1 -0
  29. package/dist/apme/adapters/codex-hook.js +95 -0
  30. package/dist/apme/adapters/codex-hook.js.map +1 -0
  31. package/dist/apme/adapters/codex-turn-manager.d.ts +86 -0
  32. package/dist/apme/adapters/codex-turn-manager.d.ts.map +1 -0
  33. package/dist/apme/adapters/codex-turn-manager.js +496 -0
  34. package/dist/apme/adapters/codex-turn-manager.js.map +1 -0
  35. package/dist/apme/adapters/openclaw-hook.d.ts +99 -0
  36. package/dist/apme/adapters/openclaw-hook.d.ts.map +1 -0
  37. package/dist/apme/adapters/openclaw-hook.js +234 -0
  38. package/dist/apme/adapters/openclaw-hook.js.map +1 -0
  39. package/dist/apme/adapters/opencode-hook.d.ts +56 -0
  40. package/dist/apme/adapters/opencode-hook.d.ts.map +1 -0
  41. package/dist/apme/adapters/opencode-hook.js +182 -0
  42. package/dist/apme/adapters/opencode-hook.js.map +1 -0
  43. package/dist/apme/adapters/timeline.d.ts.map +1 -1
  44. package/dist/apme/adapters/timeline.js +6 -1
  45. package/dist/apme/adapters/timeline.js.map +1 -1
  46. package/dist/apme/antigravity-transcript.d.ts +18 -0
  47. package/dist/apme/antigravity-transcript.d.ts.map +1 -0
  48. package/dist/apme/antigravity-transcript.js +94 -0
  49. package/dist/apme/antigravity-transcript.js.map +1 -0
  50. package/dist/apme/classify-turn.d.ts +13 -0
  51. package/dist/apme/classify-turn.d.ts.map +1 -0
  52. package/dist/apme/classify-turn.js +49 -0
  53. package/dist/apme/classify-turn.js.map +1 -0
  54. package/dist/apme/claude-transcript-reader.d.ts +10 -0
  55. package/dist/apme/claude-transcript-reader.d.ts.map +1 -1
  56. package/dist/apme/claude-transcript-reader.js +35 -0
  57. package/dist/apme/claude-transcript-reader.js.map +1 -1
  58. package/dist/apme/collector.d.ts +129 -6
  59. package/dist/apme/collector.d.ts.map +1 -1
  60. package/dist/apme/collector.js +470 -23
  61. package/dist/apme/collector.js.map +1 -1
  62. package/dist/apme/dashboard-html.d.ts.map +1 -1
  63. package/dist/apme/dashboard-html.js +87 -11
  64. package/dist/apme/dashboard-html.js.map +1 -1
  65. package/dist/apme/http.d.ts.map +1 -1
  66. package/dist/apme/http.js +43 -6
  67. package/dist/apme/http.js.map +1 -1
  68. package/dist/apme/index.d.ts +26 -5
  69. package/dist/apme/index.d.ts.map +1 -1
  70. package/dist/apme/index.js +135 -9
  71. package/dist/apme/index.js.map +1 -1
  72. package/dist/apme/pareto.d.ts +39 -0
  73. package/dist/apme/pareto.d.ts.map +1 -0
  74. package/dist/apme/pareto.js +59 -0
  75. package/dist/apme/pareto.js.map +1 -0
  76. package/dist/apme/recommend.d.ts +3 -0
  77. package/dist/apme/recommend.d.ts.map +1 -1
  78. package/dist/apme/recommend.js +43 -1
  79. package/dist/apme/recommend.js.map +1 -1
  80. package/dist/apme/runner.d.ts +92 -4
  81. package/dist/apme/runner.d.ts.map +1 -1
  82. package/dist/apme/runner.js +586 -70
  83. package/dist/apme/runner.js.map +1 -1
  84. package/dist/apme/sample-to-timeline.d.ts +26 -0
  85. package/dist/apme/sample-to-timeline.d.ts.map +1 -0
  86. package/dist/apme/sample-to-timeline.js +95 -0
  87. package/dist/apme/sample-to-timeline.js.map +1 -0
  88. package/dist/apme/scorers/index.d.ts +47 -0
  89. package/dist/apme/scorers/index.d.ts.map +1 -0
  90. package/dist/apme/scorers/index.js +96 -0
  91. package/dist/apme/scorers/index.js.map +1 -0
  92. package/dist/apme/settings.d.ts +14 -10
  93. package/dist/apme/settings.d.ts.map +1 -1
  94. package/dist/apme/settings.js +34 -8
  95. package/dist/apme/settings.js.map +1 -1
  96. package/dist/apme/store.d.ts +33 -1
  97. package/dist/apme/store.d.ts.map +1 -1
  98. package/dist/apme/store.js +334 -25
  99. package/dist/apme/store.js.map +1 -1
  100. package/dist/awaiting-overlay.d.ts +99 -0
  101. package/dist/awaiting-overlay.d.ts.map +1 -0
  102. package/dist/awaiting-overlay.js +148 -0
  103. package/dist/awaiting-overlay.js.map +1 -0
  104. package/dist/ble-sync-spawn.d.ts +63 -0
  105. package/dist/ble-sync-spawn.d.ts.map +1 -0
  106. package/dist/ble-sync-spawn.js +196 -0
  107. package/dist/ble-sync-spawn.js.map +1 -0
  108. package/dist/bridge-core.d.ts +24 -1
  109. package/dist/bridge-core.d.ts.map +1 -1
  110. package/dist/bridge-core.js +157 -24
  111. package/dist/bridge-core.js.map +1 -1
  112. package/dist/broadcast.d.ts +3 -0
  113. package/dist/broadcast.d.ts.map +1 -0
  114. package/dist/broadcast.js +122 -0
  115. package/dist/broadcast.js.map +1 -0
  116. package/dist/check-deps.d.ts.map +1 -1
  117. package/dist/check-deps.js +25 -9
  118. package/dist/check-deps.js.map +1 -1
  119. package/dist/cli.d.ts +15 -1
  120. package/dist/cli.d.ts.map +1 -1
  121. package/dist/cli.js +1025 -94
  122. package/dist/cli.js.map +1 -1
  123. package/dist/codex-auth.d.ts +21 -0
  124. package/dist/codex-auth.d.ts.map +1 -1
  125. package/dist/codex-auth.js +52 -1
  126. package/dist/codex-auth.js.map +1 -1
  127. package/dist/codex-output-parser.d.ts +8 -0
  128. package/dist/codex-output-parser.d.ts.map +1 -1
  129. package/dist/codex-output-parser.js +110 -25
  130. package/dist/codex-output-parser.js.map +1 -1
  131. package/dist/codex-rate-limits.d.ts +16 -0
  132. package/dist/codex-rate-limits.d.ts.map +1 -0
  133. package/dist/codex-rate-limits.js +197 -0
  134. package/dist/codex-rate-limits.js.map +1 -0
  135. package/dist/codex-rollout-response.d.ts +31 -0
  136. package/dist/codex-rollout-response.d.ts.map +1 -0
  137. package/dist/codex-rollout-response.js +135 -0
  138. package/dist/codex-rollout-response.js.map +1 -0
  139. package/dist/daemon-server.d.ts +85 -0
  140. package/dist/daemon-server.d.ts.map +1 -1
  141. package/dist/daemon-server.js +1627 -159
  142. package/dist/daemon-server.js.map +1 -1
  143. package/dist/daemon.js +15 -6
  144. package/dist/daemon.js.map +1 -1
  145. package/dist/display-dim.d.ts +9 -0
  146. package/dist/display-dim.d.ts.map +1 -0
  147. package/dist/display-dim.js +53 -0
  148. package/dist/display-dim.js.map +1 -0
  149. package/dist/display-monitor.d.ts +15 -2
  150. package/dist/display-monitor.d.ts.map +1 -1
  151. package/dist/display-monitor.js +104 -26
  152. package/dist/display-monitor.js.map +1 -1
  153. package/dist/esp32-serial.d.ts +160 -1
  154. package/dist/esp32-serial.d.ts.map +1 -1
  155. package/dist/esp32-serial.js +950 -153
  156. package/dist/esp32-serial.js.map +1 -1
  157. package/dist/fallback-task-timeline.d.ts +42 -0
  158. package/dist/fallback-task-timeline.d.ts.map +1 -0
  159. package/dist/fallback-task-timeline.js +112 -0
  160. package/dist/fallback-task-timeline.js.map +1 -0
  161. package/dist/foundation-models-helper.d.ts +11 -0
  162. package/dist/foundation-models-helper.d.ts.map +1 -0
  163. package/dist/foundation-models-helper.js +241 -0
  164. package/dist/foundation-models-helper.js.map +1 -0
  165. package/dist/hook-migration.js +1 -1
  166. package/dist/hook-migration.js.map +1 -1
  167. package/dist/hook-server.d.ts +2 -3
  168. package/dist/hook-server.d.ts.map +1 -1
  169. package/dist/hook-server.js +22 -10
  170. package/dist/hook-server.js.map +1 -1
  171. package/dist/idotmatrix/idotmatrix-daemon-sync.d.ts +33 -0
  172. package/dist/idotmatrix/idotmatrix-daemon-sync.d.ts.map +1 -0
  173. package/dist/idotmatrix/idotmatrix-daemon-sync.js +164 -0
  174. package/dist/idotmatrix/idotmatrix-daemon-sync.js.map +1 -0
  175. package/dist/idotmatrix/idotmatrix-discover.d.ts +18 -0
  176. package/dist/idotmatrix/idotmatrix-discover.d.ts.map +1 -0
  177. package/dist/idotmatrix/idotmatrix-discover.js +85 -0
  178. package/dist/idotmatrix/idotmatrix-discover.js.map +1 -0
  179. package/dist/idotmatrix/idotmatrix-settings.d.ts +20 -0
  180. package/dist/idotmatrix/idotmatrix-settings.d.ts.map +1 -0
  181. package/dist/idotmatrix/idotmatrix-settings.js +57 -0
  182. package/dist/idotmatrix/idotmatrix-settings.js.map +1 -0
  183. package/dist/index.d.ts.map +1 -1
  184. package/dist/index.js +215 -179
  185. package/dist/index.js.map +1 -1
  186. package/dist/log-stream.d.ts +15 -16
  187. package/dist/log-stream.d.ts.map +1 -1
  188. package/dist/log-stream.js +18 -96
  189. package/dist/log-stream.js.map +1 -1
  190. package/dist/logger.d.ts.map +1 -1
  191. package/dist/logger.js +12 -3
  192. package/dist/logger.js.map +1 -1
  193. package/dist/mdns.d.ts +17 -0
  194. package/dist/mdns.d.ts.map +1 -1
  195. package/dist/mdns.js +52 -18
  196. package/dist/mdns.js.map +1 -1
  197. package/dist/modules/adb-module.d.ts +1 -1
  198. package/dist/modules/adb-module.d.ts.map +1 -1
  199. package/dist/modules/adb-module.js +4 -3
  200. package/dist/modules/adb-module.js.map +1 -1
  201. package/dist/modules/broadcast-module.d.ts +17 -0
  202. package/dist/modules/broadcast-module.d.ts.map +1 -0
  203. package/dist/modules/broadcast-module.js +26 -0
  204. package/dist/modules/broadcast-module.js.map +1 -0
  205. package/dist/modules/idotmatrix-module.d.ts +9 -0
  206. package/dist/modules/idotmatrix-module.d.ts.map +1 -0
  207. package/dist/modules/idotmatrix-module.js +46 -0
  208. package/dist/modules/idotmatrix-module.js.map +1 -0
  209. package/dist/modules/index.d.ts +3 -1
  210. package/dist/modules/index.d.ts.map +1 -1
  211. package/dist/modules/index.js +9 -3
  212. package/dist/modules/index.js.map +1 -1
  213. package/dist/modules/pixoo-module.d.ts.map +1 -1
  214. package/dist/modules/pixoo-module.js +14 -4
  215. package/dist/modules/pixoo-module.js.map +1 -1
  216. package/dist/modules/serial-module.d.ts +4 -0
  217. package/dist/modules/serial-module.d.ts.map +1 -1
  218. package/dist/modules/serial-module.js +14 -12
  219. package/dist/modules/serial-module.js.map +1 -1
  220. package/dist/modules/timebox-module.d.ts +9 -0
  221. package/dist/modules/timebox-module.d.ts.map +1 -0
  222. package/dist/modules/timebox-module.js +46 -0
  223. package/dist/modules/timebox-module.js.map +1 -0
  224. package/dist/modules/types.d.ts +4 -2
  225. package/dist/modules/types.d.ts.map +1 -1
  226. package/dist/openclaw-session.d.ts +18 -0
  227. package/dist/openclaw-session.d.ts.map +1 -0
  228. package/dist/openclaw-session.js +34 -0
  229. package/dist/openclaw-session.js.map +1 -0
  230. package/dist/output-parser.d.ts +30 -0
  231. package/dist/output-parser.d.ts.map +1 -1
  232. package/dist/output-parser.js +125 -9
  233. package/dist/output-parser.js.map +1 -1
  234. package/dist/passive-observer.d.ts +26 -0
  235. package/dist/passive-observer.d.ts.map +1 -1
  236. package/dist/passive-observer.js +258 -49
  237. package/dist/passive-observer.js.map +1 -1
  238. package/dist/permission-resolver.d.ts +47 -0
  239. package/dist/permission-resolver.d.ts.map +1 -0
  240. package/dist/permission-resolver.js +103 -0
  241. package/dist/permission-resolver.js.map +1 -0
  242. package/dist/pixoo/micro-glyphs.d.ts +49 -0
  243. package/dist/pixoo/micro-glyphs.d.ts.map +1 -0
  244. package/dist/pixoo/micro-glyphs.js +276 -0
  245. package/dist/pixoo/micro-glyphs.js.map +1 -0
  246. package/dist/pixoo/pixoo-bridge.d.ts +2 -2
  247. package/dist/pixoo/pixoo-bridge.d.ts.map +1 -1
  248. package/dist/pixoo/pixoo-bridge.js +93 -25
  249. package/dist/pixoo/pixoo-bridge.js.map +1 -1
  250. package/dist/pixoo/pixoo-camera.d.ts +19 -3
  251. package/dist/pixoo/pixoo-camera.d.ts.map +1 -1
  252. package/dist/pixoo/pixoo-camera.js +62 -27
  253. package/dist/pixoo/pixoo-camera.js.map +1 -1
  254. package/dist/pixoo/pixoo-client.d.ts +13 -3
  255. package/dist/pixoo/pixoo-client.d.ts.map +1 -1
  256. package/dist/pixoo/pixoo-client.js +51 -22
  257. package/dist/pixoo/pixoo-client.js.map +1 -1
  258. package/dist/pixoo/pixoo-discover.d.ts +37 -0
  259. package/dist/pixoo/pixoo-discover.d.ts.map +1 -0
  260. package/dist/pixoo/pixoo-discover.js +105 -0
  261. package/dist/pixoo/pixoo-discover.js.map +1 -0
  262. package/dist/pixoo/pixoo-renderer.d.ts +8 -3
  263. package/dist/pixoo/pixoo-renderer.d.ts.map +1 -1
  264. package/dist/pixoo/pixoo-renderer.js +189 -60
  265. package/dist/pixoo/pixoo-renderer.js.map +1 -1
  266. package/dist/pixoo/pixoo-settings.d.ts +6 -0
  267. package/dist/pixoo/pixoo-settings.d.ts.map +1 -1
  268. package/dist/pixoo/pixoo-settings.js +9 -0
  269. package/dist/pixoo/pixoo-settings.js.map +1 -1
  270. package/dist/pixoo/pixoo-sprites.d.ts +60 -11
  271. package/dist/pixoo/pixoo-sprites.d.ts.map +1 -1
  272. package/dist/pixoo/pixoo-sprites.js +512 -209
  273. package/dist/pixoo/pixoo-sprites.js.map +1 -1
  274. package/dist/pty-manager.d.ts.map +1 -1
  275. package/dist/pty-manager.js +8 -2
  276. package/dist/pty-manager.js.map +1 -1
  277. package/dist/session-activity.d.ts +14 -0
  278. package/dist/session-activity.d.ts.map +1 -0
  279. package/dist/session-activity.js +160 -0
  280. package/dist/session-activity.js.map +1 -0
  281. package/dist/session-aggregator.d.ts +17 -0
  282. package/dist/session-aggregator.d.ts.map +1 -1
  283. package/dist/session-aggregator.js +48 -9
  284. package/dist/session-aggregator.js.map +1 -1
  285. package/dist/session-registry.d.ts +71 -3
  286. package/dist/session-registry.d.ts.map +1 -1
  287. package/dist/session-registry.js +137 -8
  288. package/dist/session-registry.js.map +1 -1
  289. package/dist/session-timeline-relay.d.ts.map +1 -1
  290. package/dist/session-timeline-relay.js +13 -4
  291. package/dist/session-timeline-relay.js.map +1 -1
  292. package/dist/session-transcript-timeline.d.ts +49 -0
  293. package/dist/session-transcript-timeline.d.ts.map +1 -0
  294. package/dist/session-transcript-timeline.js +276 -0
  295. package/dist/session-transcript-timeline.js.map +1 -0
  296. package/dist/state-machine.d.ts +6 -1
  297. package/dist/state-machine.d.ts.map +1 -1
  298. package/dist/state-machine.js +86 -28
  299. package/dist/state-machine.js.map +1 -1
  300. package/dist/timebox/timebox-daemon-sync.d.ts +19 -0
  301. package/dist/timebox/timebox-daemon-sync.d.ts.map +1 -0
  302. package/dist/timebox/timebox-daemon-sync.js +135 -0
  303. package/dist/timebox/timebox-daemon-sync.js.map +1 -0
  304. package/dist/timebox/timebox-discover.d.ts +19 -0
  305. package/dist/timebox/timebox-discover.d.ts.map +1 -0
  306. package/dist/timebox/timebox-discover.js +87 -0
  307. package/dist/timebox/timebox-discover.js.map +1 -0
  308. package/dist/timebox/timebox-settings.d.ts +32 -0
  309. package/dist/timebox/timebox-settings.d.ts.map +1 -0
  310. package/dist/timebox/timebox-settings.js +80 -0
  311. package/dist/timebox/timebox-settings.js.map +1 -0
  312. package/dist/timeline-store.d.ts +63 -3
  313. package/dist/timeline-store.d.ts.map +1 -1
  314. package/dist/timeline-store.js +292 -14
  315. package/dist/timeline-store.js.map +1 -1
  316. package/dist/timeline-summarizer.d.ts.map +1 -1
  317. package/dist/timeline-summarizer.js +29 -5
  318. package/dist/timeline-summarizer.js.map +1 -1
  319. package/dist/tui/ansi.d.ts +0 -4
  320. package/dist/tui/ansi.d.ts.map +1 -1
  321. package/dist/tui/ansi.js +14 -7
  322. package/dist/tui/ansi.js.map +1 -1
  323. package/dist/tui/dashboard.d.ts +1 -0
  324. package/dist/tui/dashboard.d.ts.map +1 -1
  325. package/dist/tui/dashboard.js +24 -7
  326. package/dist/tui/dashboard.js.map +1 -1
  327. package/dist/tui/renderer.d.ts +36 -0
  328. package/dist/tui/renderer.d.ts.map +1 -1
  329. package/dist/tui/renderer.js +303 -119
  330. package/dist/tui/renderer.js.map +1 -1
  331. package/dist/tui/terrarium.d.ts.map +1 -1
  332. package/dist/tui/terrarium.js +37 -49
  333. package/dist/tui/terrarium.js.map +1 -1
  334. package/dist/types.d.ts +2 -2
  335. package/dist/types.d.ts.map +1 -1
  336. package/dist/types.js +2 -2
  337. package/dist/types.js.map +1 -1
  338. package/dist/usage-api.d.ts.map +1 -1
  339. package/dist/usage-api.js +7 -1
  340. package/dist/usage-api.js.map +1 -1
  341. package/dist/usage-event.d.ts +10 -3
  342. package/dist/usage-event.d.ts.map +1 -1
  343. package/dist/usage-event.js +74 -12
  344. package/dist/usage-event.js.map +1 -1
  345. package/dist/utility-proxy.d.ts.map +1 -1
  346. package/dist/utility-proxy.js +8 -0
  347. package/dist/utility-proxy.js.map +1 -1
  348. package/dist/utils/project-name.d.ts +3 -0
  349. package/dist/utils/project-name.d.ts.map +1 -1
  350. package/dist/utils/project-name.js +44 -2
  351. package/dist/utils/project-name.js.map +1 -1
  352. package/dist/windows-service.d.ts +26 -0
  353. package/dist/windows-service.d.ts.map +1 -0
  354. package/dist/windows-service.js +145 -0
  355. package/dist/windows-service.js.map +1 -0
  356. package/dist/ws-server.d.ts +22 -1
  357. package/dist/ws-server.d.ts.map +1 -1
  358. package/dist/ws-server.js +89 -4
  359. package/dist/ws-server.js.map +1 -1
  360. package/fm-helper/AgentDeckFMHelper.swift +112 -0
  361. package/package.json +9 -3
  362. package/scripts/build-fm-helper.mjs +26 -0
  363. package/LICENSE +0 -21
  364. package/dist/apme/tuner.d.ts +0 -64
  365. package/dist/apme/tuner.d.ts.map +0 -1
  366. package/dist/apme/tuner.js +0 -297
  367. package/dist/apme/tuner.js.map +0 -1
  368. package/dist/d200h/hid-protocol.d.ts +0 -62
  369. package/dist/d200h/hid-protocol.d.ts.map +0 -1
  370. package/dist/d200h/hid-protocol.js +0 -124
  371. package/dist/d200h/hid-protocol.js.map +0 -1
  372. package/dist/d200h/image-renderer.d.ts +0 -36
  373. package/dist/d200h/image-renderer.d.ts.map +0 -1
  374. package/dist/d200h/image-renderer.js +0 -487
  375. package/dist/d200h/image-renderer.js.map +0 -1
  376. package/dist/modules/d200h-module.d.ts +0 -43
  377. package/dist/modules/d200h-module.d.ts.map +0 -1
  378. package/dist/modules/d200h-module.js +0 -360
  379. package/dist/modules/d200h-module.js.map +0 -1
  380. package/dist/modules/d200h-renderer.d.ts +0 -7
  381. package/dist/modules/d200h-renderer.d.ts.map +0 -1
  382. package/dist/modules/d200h-renderer.js +0 -321
  383. package/dist/modules/d200h-renderer.js.map +0 -1
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Daemon-managed Divoom Timebox Mini sync.
3
+ *
4
+ * Timebox Mini BLE devices (`device.address`) are driven by `sync_ble.py`
5
+ * (bleak/GATT). Node has no built-in BLE support, so we spawn the small Python
6
+ * writer. This code is terminal-managed CLI daemon only.
7
+ */
8
+ import { existsSync } from 'fs';
9
+ import { dirname, join } from 'path';
10
+ import { fileURLToPath } from 'url';
11
+ import { deviceId, loadTimeboxDevices } from './timebox-settings.js';
12
+ import { createSyncCycleSquelch, spawnPythonSync, terminateSyncChild } from '../ble-sync-spawn.js';
13
+ const entries = new Map();
14
+ const BASE_BACKOFF_MS = 5_000;
15
+ const MAX_BACKOFF_MS = 60_000;
16
+ const HEALTHY_UPTIME_MS = 30_000;
17
+ function log(msg) {
18
+ console.error(`[agentdeck] [timebox] ${msg}`);
19
+ }
20
+ function resolvePaths() {
21
+ const here = dirname(fileURLToPath(import.meta.url));
22
+ const projectRoot = join(here, '..', '..', '..');
23
+ const timeboxDir = join(projectRoot, 'bridge', 'src', 'timebox');
24
+ return {
25
+ venvPython: join(projectRoot, '.venv', 'bin', 'python'),
26
+ bleScript: join(timeboxDir, 'sync_ble.py'),
27
+ };
28
+ }
29
+ export function startTimeboxSync(httpPort) {
30
+ const devices = loadTimeboxDevices();
31
+ if (devices.length === 0)
32
+ return;
33
+ const { venvPython, bleScript } = resolvePaths();
34
+ if (!existsSync(venvPython)) {
35
+ log('sync unavailable (missing Python venv (.venv)); Timebox Mini will not be driven by the daemon');
36
+ return;
37
+ }
38
+ for (const device of devices) {
39
+ const id = deviceId(device);
40
+ if (!id || entries.has(id))
41
+ continue;
42
+ if (!existsSync(bleScript)) {
43
+ log(`sync unavailable (missing sync_ble.py) for ${id}`);
44
+ continue;
45
+ }
46
+ const entry = {
47
+ device,
48
+ child: null,
49
+ stopping: false,
50
+ respawnTimer: null,
51
+ consecutiveFailures: 0,
52
+ startedAt: 0,
53
+ squelch: createSyncCycleSquelch(log),
54
+ };
55
+ entries.set(id, entry);
56
+ spawnSync(entry, venvPython, bleScript, httpPort);
57
+ }
58
+ }
59
+ function spawnSync(entry, venvPython, syncScript, httpPort) {
60
+ if (entry.stopping)
61
+ return;
62
+ const device = entry.device;
63
+ const id = deviceId(device);
64
+ const url = `http://127.0.0.1:${httpPort}`;
65
+ const brightness = Math.max(0, Math.min(100, Math.round(device.brightness ?? 100)));
66
+ const args = [syncScript, '--address', device.address, '--url', url, '--brightness', String(brightness)];
67
+ entry.squelch.logStart(`Starting BLE sync for ${device.name ?? 'Timebox Mini'} (${id}, bridge ${url}, brightness ${brightness}%)`);
68
+ entry.startedAt = Date.now();
69
+ // stdout/stderr are captured into small rings so clean exits and crashes both
70
+ // leave enough context without flooding the daemon log while running.
71
+ const { proc, stderrTail, outputTail } = spawnPythonSync(venvPython, args);
72
+ entry.child = proc;
73
+ proc.on('error', (err) => {
74
+ log(`sync failed to spawn for ${id}: ${err.message}`);
75
+ });
76
+ proc.on('exit', (code, signal) => {
77
+ if (entry.child === proc)
78
+ entry.child = null;
79
+ if (entry.stopping)
80
+ return;
81
+ // A clean code=0 exit is still abnormal here; normal daemon shutdown is
82
+ // gated by `entry.stopping` above. Do not reset backoff for repeated
83
+ // "device not found" / BLE disconnect exits just because they lasted long
84
+ // enough to cross the healthy-uptime threshold.
85
+ const uptimeMs = Date.now() - entry.startedAt;
86
+ if (code !== 0 && uptimeMs > HEALTHY_UPTIME_MS)
87
+ entry.consecutiveFailures = 0;
88
+ entry.consecutiveFailures += 1;
89
+ const delay = Math.min(MAX_BACKOFF_MS, BASE_BACKOFF_MS * entry.consecutiveFailures);
90
+ const tail = stderrTail() || outputTail();
91
+ const why = tail ? `; output: ${tail}` : '';
92
+ entry.squelch.logExit(code, signal, uptimeMs, tail, `sync for ${id} exited (code=${code} signal=${signal})${why}; respawning in ${Math.round(delay / 1000)}s`);
93
+ entry.respawnTimer = setTimeout(() => spawnSync(entry, venvPython, syncScript, httpPort), delay);
94
+ if (entry.respawnTimer.unref)
95
+ entry.respawnTimer.unref();
96
+ });
97
+ }
98
+ /**
99
+ * Stop all managed Timebox BLE syncs and cancel pending respawns.
100
+ *
101
+ * When `awaitFarewell` is true (daemon shutdown), wait for each child to exit so
102
+ * its blank-panel farewell finishes painting before the daemon process exits —
103
+ * otherwise launchd tears the job down and SIGKILLs the orphaned children
104
+ * mid-farewell, freezing each panel on its last dashboard frame. Children are
105
+ * awaited in parallel (BLE is per-device, so farewells don't serialize).
106
+ */
107
+ export async function stopTimeboxSync(awaitFarewell = false) {
108
+ const procs = [];
109
+ for (const entry of entries.values()) {
110
+ entry.stopping = true;
111
+ if (entry.respawnTimer) {
112
+ clearTimeout(entry.respawnTimer);
113
+ entry.respawnTimer = null;
114
+ }
115
+ if (entry.child) {
116
+ const proc = entry.child;
117
+ entry.child = null;
118
+ if (awaitFarewell) {
119
+ procs.push(proc);
120
+ }
121
+ else {
122
+ try {
123
+ proc.kill('SIGTERM');
124
+ }
125
+ catch {
126
+ /* already gone */
127
+ }
128
+ }
129
+ }
130
+ }
131
+ entries.clear();
132
+ if (procs.length)
133
+ await Promise.all(procs.map((p) => terminateSyncChild(p)));
134
+ }
135
+ //# sourceMappingURL=timebox-daemon-sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timebox-daemon-sync.js","sourceRoot":"","sources":["../../src/timebox/timebox-daemon-sync.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Daemon-side auto-discovery for the Divoom Timebox Mini (BLE).
3
+ *
4
+ * Reuses the existing `scan_ble.py` (bleak) scanner the CLI `timebox scan`
5
+ * command already drives, but runs it automatically at daemon start when no
6
+ * Timebox is configured yet — so a fresh install "just finds" the device
7
+ * instead of requiring a manual `timebox add`. Auto-add only happens when zero
8
+ * devices are configured (avoid grabbing a neighbour's panel on a shared LAN),
9
+ * and only when `timeboxAutoDiscover` isn't disabled in settings.
10
+ *
11
+ * This is terminal-managed CLI daemon code (spawns Python); it never runs in
12
+ * the App Store Swift build, which does BLE discovery natively via CoreBluetooth.
13
+ */
14
+ /**
15
+ * BLE-scan for a Timebox Mini and add the first match to settings.
16
+ * @returns number of devices added (0 or 1).
17
+ */
18
+ export declare function autoDiscoverTimebox(): Promise<number>;
19
+ //# sourceMappingURL=timebox-discover.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timebox-discover.d.ts","sourceRoot":"","sources":["../../src/timebox/timebox-discover.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAkEH;;;GAGG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC,CAc3D"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Daemon-side auto-discovery for the Divoom Timebox Mini (BLE).
3
+ *
4
+ * Reuses the existing `scan_ble.py` (bleak) scanner the CLI `timebox scan`
5
+ * command already drives, but runs it automatically at daemon start when no
6
+ * Timebox is configured yet — so a fresh install "just finds" the device
7
+ * instead of requiring a manual `timebox add`. Auto-add only happens when zero
8
+ * devices are configured (avoid grabbing a neighbour's panel on a shared LAN),
9
+ * and only when `timeboxAutoDiscover` isn't disabled in settings.
10
+ *
11
+ * This is terminal-managed CLI daemon code (spawns Python); it never runs in
12
+ * the App Store Swift build, which does BLE discovery natively via CoreBluetooth.
13
+ */
14
+ import { spawn } from 'child_process';
15
+ import { existsSync } from 'fs';
16
+ import { dirname, join } from 'path';
17
+ import { fileURLToPath } from 'url';
18
+ import { addTimeboxDevice, isTimeboxAutoDiscoverEnabled, loadTimeboxDevices, } from './timebox-settings.js';
19
+ function log(msg) {
20
+ console.error(`[agentdeck] [timebox] ${msg}`);
21
+ }
22
+ function resolvePaths() {
23
+ const here = dirname(fileURLToPath(import.meta.url));
24
+ const projectRoot = join(here, '..', '..', '..');
25
+ const timeboxDir = join(projectRoot, 'bridge', 'src', 'timebox');
26
+ return {
27
+ venvPython: join(projectRoot, '.venv', 'bin', 'python'),
28
+ scanScript: join(timeboxDir, 'scan_ble.py'),
29
+ };
30
+ }
31
+ /** Run scan_ble.py and parse its JSON, with a hard outer timeout. */
32
+ function runScan(venvPython, scanScript, timeoutMs) {
33
+ return new Promise((resolve) => {
34
+ const proc = spawn(venvPython, [scanScript], { stdio: ['ignore', 'pipe', 'ignore'] });
35
+ let out = '';
36
+ const timer = setTimeout(() => {
37
+ try {
38
+ proc.kill('SIGKILL');
39
+ }
40
+ catch {
41
+ /* already gone */
42
+ }
43
+ resolve([]);
44
+ }, timeoutMs);
45
+ if (timer.unref)
46
+ timer.unref();
47
+ proc.stdout?.on('data', (d) => {
48
+ out += d.toString();
49
+ });
50
+ proc.on('error', () => {
51
+ clearTimeout(timer);
52
+ resolve([]);
53
+ });
54
+ proc.on('close', () => {
55
+ clearTimeout(timer);
56
+ try {
57
+ const parsed = JSON.parse(out);
58
+ resolve(Array.isArray(parsed) ? parsed : []);
59
+ }
60
+ catch {
61
+ resolve([]);
62
+ }
63
+ });
64
+ });
65
+ }
66
+ /**
67
+ * BLE-scan for a Timebox Mini and add the first match to settings.
68
+ * @returns number of devices added (0 or 1).
69
+ */
70
+ export async function autoDiscoverTimebox() {
71
+ if (!isTimeboxAutoDiscoverEnabled())
72
+ return 0;
73
+ if (loadTimeboxDevices().length > 0)
74
+ return 0; // only when nothing configured
75
+ const { venvPython, scanScript } = resolvePaths();
76
+ if (!existsSync(venvPython) || !existsSync(scanScript))
77
+ return 0;
78
+ const results = await runScan(venvPython, scanScript, 8_000);
79
+ const match = results.find((r) => r.is_timebox && r.address);
80
+ if (!match)
81
+ return 0;
82
+ const added = addTimeboxDevice({ address: match.address, name: match.name });
83
+ if (added)
84
+ log(`auto-discovered Timebox Mini ${match.address} (${match.name})`);
85
+ return added ? 1 : 0;
86
+ }
87
+ //# sourceMappingURL=timebox-discover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timebox-discover.js","sourceRoot":"","sources":["../../src/timebox/timebox-discover.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Timebox Mini device settings CRUD.
3
+ *
4
+ * The Timebox Mini is driven over **BLE** — BLE GATT (ISSC transparent-UART
5
+ * `49535343-…`), advertised as "TimeBox-mini-light". Driven over CoreBluetooth,
6
+ * so the App Store Swift daemon can drive it; the Node daemon spawns
7
+ * `sync_ble.py` (bleak).
8
+ *
9
+ * (The legacy Bluetooth Classic SPP variant was removed — poor macOS
10
+ * compatibility and no App Store path; BLE supersedes it.)
11
+ */
12
+ export interface TimeboxDevice {
13
+ /** BLE address/UUID of the TimeBox-mini-light peripheral. */
14
+ address: string;
15
+ name?: string;
16
+ /** Software brightness scale applied while encoding pixels. */
17
+ brightness?: number;
18
+ }
19
+ /** Stable identity for a device — its BLE address. */
20
+ export declare function deviceId(device: TimeboxDevice): string;
21
+ export declare function loadTimeboxDevices(): TimeboxDevice[];
22
+ export declare function saveTimeboxDevices(devices: TimeboxDevice[]): void;
23
+ export declare function addTimeboxDevice(device: TimeboxDevice): boolean;
24
+ /** Remove a device by its BLE address. */
25
+ export declare function removeTimeboxDevice(id: string): boolean;
26
+ /**
27
+ * Whether the daemon may BLE-scan for a Timebox Mini when none is configured.
28
+ * Defaults to true (zero-config plug-and-play); set `timeboxAutoDiscover: false`
29
+ * in settings.json to opt out.
30
+ */
31
+ export declare function isTimeboxAutoDiscoverEnabled(): boolean;
32
+ //# sourceMappingURL=timebox-settings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timebox-settings.d.ts","sourceRoot":"","sources":["../../src/timebox/timebox-settings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,MAAM,WAAW,aAAa;IAC5B,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,sDAAsD;AACtD,wBAAgB,QAAQ,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAEtD;AAmBD,wBAAgB,kBAAkB,IAAI,aAAa,EAAE,CAYpD;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,IAAI,CAIjE;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAO/D;AAED,0CAA0C;AAC1C,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAMvD;AAED;;;;GAIG;AACH,wBAAgB,4BAA4B,IAAI,OAAO,CAEtD"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Timebox Mini device settings CRUD.
3
+ *
4
+ * The Timebox Mini is driven over **BLE** — BLE GATT (ISSC transparent-UART
5
+ * `49535343-…`), advertised as "TimeBox-mini-light". Driven over CoreBluetooth,
6
+ * so the App Store Swift daemon can drive it; the Node daemon spawns
7
+ * `sync_ble.py` (bleak).
8
+ *
9
+ * (The legacy Bluetooth Classic SPP variant was removed — poor macOS
10
+ * compatibility and no App Store path; BLE supersedes it.)
11
+ */
12
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
13
+ import { homedir } from 'os';
14
+ import { join } from 'path';
15
+ /** Stable identity for a device — its BLE address. */
16
+ export function deviceId(device) {
17
+ return device.address ?? '';
18
+ }
19
+ const SETTINGS_DIR = join(homedir(), '.agentdeck');
20
+ const SETTINGS_PATH = join(SETTINGS_DIR, 'settings.json');
21
+ function readSettings() {
22
+ try {
23
+ if (!existsSync(SETTINGS_PATH))
24
+ return {};
25
+ return JSON.parse(readFileSync(SETTINGS_PATH, 'utf-8'));
26
+ }
27
+ catch {
28
+ return {};
29
+ }
30
+ }
31
+ function writeSettings(settings) {
32
+ mkdirSync(SETTINGS_DIR, { recursive: true });
33
+ writeFileSync(SETTINGS_PATH, JSON.stringify(settings, null, 2) + '\n');
34
+ }
35
+ export function loadTimeboxDevices() {
36
+ const settings = readSettings();
37
+ if (!Array.isArray(settings.timeboxDevices))
38
+ return [];
39
+ return settings.timeboxDevices
40
+ .filter((d) => !!d && typeof d === 'object')
41
+ // Keep a device only if it has a BLE address.
42
+ .filter((d) => typeof d.address === 'string')
43
+ .map((d) => ({
44
+ address: d.address,
45
+ name: typeof d.name === 'string' ? d.name : undefined,
46
+ brightness: typeof d.brightness === 'number' ? d.brightness : undefined,
47
+ }));
48
+ }
49
+ export function saveTimeboxDevices(devices) {
50
+ const settings = readSettings();
51
+ settings.timeboxDevices = devices;
52
+ writeSettings(settings);
53
+ }
54
+ export function addTimeboxDevice(device) {
55
+ const devices = loadTimeboxDevices();
56
+ const id = deviceId(device);
57
+ if (!id || devices.some((d) => deviceId(d) === id))
58
+ return false;
59
+ devices.push(device);
60
+ saveTimeboxDevices(devices);
61
+ return true;
62
+ }
63
+ /** Remove a device by its BLE address. */
64
+ export function removeTimeboxDevice(id) {
65
+ const devices = loadTimeboxDevices();
66
+ const filtered = devices.filter((d) => deviceId(d) !== id);
67
+ if (filtered.length === devices.length)
68
+ return false;
69
+ saveTimeboxDevices(filtered);
70
+ return true;
71
+ }
72
+ /**
73
+ * Whether the daemon may BLE-scan for a Timebox Mini when none is configured.
74
+ * Defaults to true (zero-config plug-and-play); set `timeboxAutoDiscover: false`
75
+ * in settings.json to opt out.
76
+ */
77
+ export function isTimeboxAutoDiscoverEnabled() {
78
+ return readSettings().timeboxAutoDiscover !== false;
79
+ }
80
+ //# sourceMappingURL=timebox-settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timebox-settings.js","sourceRoot":"","sources":["../../src/timebox/timebox-settings.ts"],"names":[],"mappings":"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"}
@@ -5,18 +5,78 @@
5
5
  */
6
6
  import type { TimelineEntry } from './types.js';
7
7
  type EntryListener = (entry: TimelineEntry, upsert?: boolean) => void;
8
+ /** Attribute an entry with session-scoped metadata (sessionId, projectName,
9
+ * taskId, runId, ...) before it lands in the buffer. Run once at storage
10
+ * time so history replay carries the same attribution as the live broadcast.
11
+ * Must be idempotent: caller already-set fields take precedence. */
12
+ type EntryAttributor = (entry: TimelineEntry) => TimelineEntry;
8
13
  export declare class BridgeTimelineStore {
9
14
  private entries;
10
15
  private listeners;
11
- addEntry(entry: TimelineEntry): void;
16
+ private attributor;
17
+ /** Phase 6 cutover (default OFF). When true, locally-emitted chat/tool rows
18
+ * are dropped — the SessionSample projection (added via `bypassSuppression`)
19
+ * becomes the single source. Relayed + projected entries bypass this. */
20
+ private suppressLocalChatTool;
21
+ setSuppressLocalChatTool(v: boolean): void;
22
+ /** Install (or replace) the attributor invoked on every addEntry / upsertEntry
23
+ * before dedup. Wired by `BridgeCore.wireTimeline` so the store and the
24
+ * live broadcast see identical, fully-attributed entries — critical for
25
+ * history replay (`timeline_history`). */
26
+ setAttributor(fn: EntryAttributor | null): void;
27
+ addEntry(entry: TimelineEntry, opts?: {
28
+ bypassSuppression?: boolean;
29
+ }): void;
30
+ /** Evict a single entry to enforce MAX_ENTRIES, protecting task rows.
31
+ *
32
+ * Task rows only leave under their own cap (MAX_TASK_ENTRIES), and an
33
+ * in-flight task's `task_start` (no matching `task_end` yet) is never
34
+ * evicted — otherwise a long task's start scrolls away mid-task and the
35
+ * pair splits. Everything else FIFOs as before. */
36
+ private evictOne;
12
37
  getHistory(since?: number): TimelineEntry[];
38
+ /** Load persisted timeline rows into the bounded replay buffer without
39
+ * broadcasting them as live events. The Node daemon normally keeps the
40
+ * device timeline in memory, but macOS/previous daemon runs may leave a
41
+ * timeline.json behind. Rehydrating it lets reconnecting Android/tablet
42
+ * clients receive a non-empty initial `timeline_history`.
43
+ */
44
+ loadPersistedFile(path: string): number;
45
+ loadPersistedEntries(rows: unknown[]): void;
46
+ /** Node mirror of the Swift daemon's orphan reaper
47
+ * (DaemonServer.computeOrphanTaskEnds): synthesize a `task_end` for every
48
+ * `task_start` whose pair was never written. The producer only guarantees
49
+ * the pair within a single daemon lifetime (ApmeCollector.closeTask is
50
+ * in-memory), so a daemon killed mid-task leaves task_start rows that
51
+ * clients render as in-flight — spinning the task marker forever. Called
52
+ * once after `loadPersistedFile` at daemon startup. Idempotent: a real
53
+ * task_end arriving later merges over the synthetic via
54
+ * `tryMergeTaskEndByTaskId`. Returns the number of synthesized rows. */
55
+ reapOrphanTaskStarts(): number;
56
+ /** Recent entries attributed to one session, for the `query_session_timeline`
57
+ * poll — lets a device that connects mid-session fill its Detail view. */
58
+ getHistoryForSession(sessionId: string, since?: number, limit?: number): TimelineEntry[];
13
59
  updateEntryStatus(approvalId: string, status: 'approved' | 'denied'): void;
14
- /** Update existing entry with same ts+type (1s tolerance), or add new */
15
- upsertEntry(entry: TimelineEntry): void;
60
+ /** Update existing entry with same ts+type (1s tolerance), or add new.
61
+ *
62
+ * Update path: the existing entry's session/task/run/project attribution
63
+ * was set at *its* creation time and is authoritative. We do NOT re-run
64
+ * the attributor on update — by the time a late upsert lands (e.g. async
65
+ * LLM summary on a chat_end), the active task may have rotated, and
66
+ * re-attributing would silently move the entry to the wrong task. The
67
+ * raw caller `entry` only overrides existing fields when the caller
68
+ * explicitly set them.
69
+ *
70
+ * Insert path (no match): falls through to `addEntry`, which runs the
71
+ * attributor as usual to capture creation-time attribution. */
72
+ upsertEntry(entry: TimelineEntry, opts?: {
73
+ bypassSuppression?: boolean;
74
+ }): void;
16
75
  /** Get the most recent entry of a given type */
17
76
  getLastEntry(type: string): TimelineEntry | null;
18
77
  onEntry(cb: EntryListener): void;
19
78
  removeListener(cb: EntryListener): void;
79
+ private tryMergeTaskEndByTaskId;
20
80
  }
21
81
  export {};
22
82
  //# sourceMappingURL=timeline-store.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"timeline-store.d.ts","sourceRoot":"","sources":["../src/timeline-store.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGhD,KAAK,aAAa,GAAG,CAAC,KAAK,EAAE,aAAa,EAAE,MAAM,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;AAItE,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,SAAS,CAAuB;IAExC,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAwBpC,UAAU,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,aAAa,EAAE;IAO3C,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,QAAQ,GAAG,IAAI;IAS1E,yEAAyE;IACzE,WAAW,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAavC,gDAAgD;IAChD,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI;IAOhD,OAAO,CAAC,EAAE,EAAE,aAAa,GAAG,IAAI;IAIhC,cAAc,CAAC,EAAE,EAAE,aAAa,GAAG,IAAI;CAIxC"}
1
+ {"version":3,"file":"timeline-store.d.ts","sourceRoot":"","sources":["../src/timeline-store.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAIhD,KAAK,aAAa,GAAG,CAAC,KAAK,EAAE,aAAa,EAAE,MAAM,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;AACtE;;;qEAGqE;AACrE,KAAK,eAAe,GAAG,CAAC,KAAK,EAAE,aAAa,KAAK,aAAa,CAAC;AAqB/D,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,UAAU,CAAgC;IAClD;;8EAE0E;IAC1E,OAAO,CAAC,qBAAqB,CAAS;IAEtC,wBAAwB,CAAC,CAAC,EAAE,OAAO,GAAG,IAAI;IAI1C;;;+CAG2C;IAC3C,aAAa,CAAC,EAAE,EAAE,eAAe,GAAG,IAAI,GAAG,IAAI;IAI/C,QAAQ,CAAC,KAAK,EAAE,aAAa,EAAE,IAAI,CAAC,EAAE;QAAE,iBAAiB,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI;IA6D5E;;;;;wDAKoD;IACpD,OAAO,CAAC,QAAQ;IAyBhB,UAAU,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,aAAa,EAAE;IAO3C;;;;;OAKG;IACH,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAiBvC,oBAAoB,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAuB3C;;;;;;;;6EAQyE;IACzE,oBAAoB,IAAI,MAAM;IA8B9B;+EAC2E;IAC3E,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,aAAa,EAAE;IAkBpF,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,QAAQ,GAAG,IAAI;IAS1E;;;;;;;;;;;oEAWgE;IAChE,WAAW,CAAC,KAAK,EAAE,aAAa,EAAE,IAAI,CAAC,EAAE;QAAE,iBAAiB,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI;IA4C/E,gDAAgD;IAChD,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI;IAOhD,OAAO,CAAC,EAAE,EAAE,aAAa,GAAG,IAAI;IAIhC,cAAc,CAAC,EAAE,EAAE,aAAa,GAAG,IAAI;IAKvC,OAAO,CAAC,uBAAuB;CAiChC"}