@agentdeck/bridge 0.2.2 → 1.0.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 (435) hide show
  1. package/assets/fm-helper/agentdeck-fm-helper +0 -0
  2. package/assets/fonts/IBMPlexSans-Bold.ttf +0 -0
  3. package/assets/fonts/IBMPlexSans-Regular.ttf +0 -0
  4. package/assets/fonts/JetBrainsMono-Bold.ttf +0 -0
  5. package/assets/fonts/JetBrainsMono-Regular.ttf +0 -0
  6. package/assets/fonts/LICENSES.md +22 -0
  7. package/dist/adapters/claude-code.d.ts +6 -0
  8. package/dist/adapters/claude-code.d.ts.map +1 -1
  9. package/dist/adapters/claude-code.js +8 -0
  10. package/dist/adapters/claude-code.js.map +1 -1
  11. package/dist/adapters/openclaw.d.ts +24 -0
  12. package/dist/adapters/openclaw.d.ts.map +1 -1
  13. package/dist/adapters/openclaw.js +291 -35
  14. package/dist/adapters/openclaw.js.map +1 -1
  15. package/dist/adapters/opencode-adapter.d.ts +59 -0
  16. package/dist/adapters/opencode-adapter.d.ts.map +1 -1
  17. package/dist/adapters/opencode-adapter.js +297 -35
  18. package/dist/adapters/opencode-adapter.js.map +1 -1
  19. package/dist/adb-reverse.d.ts +1 -1
  20. package/dist/adb-reverse.js +1 -1
  21. package/dist/antigravity-local.d.ts +1 -0
  22. package/dist/antigravity-local.d.ts.map +1 -1
  23. package/dist/antigravity-local.js +33 -0
  24. package/dist/antigravity-local.js.map +1 -1
  25. package/dist/apme/adapters/claude-hook.d.ts.map +1 -1
  26. package/dist/apme/adapters/claude-hook.js +5 -0
  27. package/dist/apme/adapters/claude-hook.js.map +1 -1
  28. package/dist/apme/adapters/codex-hook.d.ts +17 -0
  29. package/dist/apme/adapters/codex-hook.d.ts.map +1 -0
  30. package/dist/apme/adapters/codex-hook.js +95 -0
  31. package/dist/apme/adapters/codex-hook.js.map +1 -0
  32. package/dist/apme/adapters/codex-turn-manager.d.ts +86 -0
  33. package/dist/apme/adapters/codex-turn-manager.d.ts.map +1 -0
  34. package/dist/apme/adapters/codex-turn-manager.js +496 -0
  35. package/dist/apme/adapters/codex-turn-manager.js.map +1 -0
  36. package/dist/apme/adapters/openclaw-hook.d.ts +99 -0
  37. package/dist/apme/adapters/openclaw-hook.d.ts.map +1 -0
  38. package/dist/apme/adapters/openclaw-hook.js +234 -0
  39. package/dist/apme/adapters/openclaw-hook.js.map +1 -0
  40. package/dist/apme/adapters/opencode-hook.d.ts +56 -0
  41. package/dist/apme/adapters/opencode-hook.d.ts.map +1 -0
  42. package/dist/apme/adapters/opencode-hook.js +182 -0
  43. package/dist/apme/adapters/opencode-hook.js.map +1 -0
  44. package/dist/apme/adapters/timeline.d.ts.map +1 -1
  45. package/dist/apme/adapters/timeline.js +6 -1
  46. package/dist/apme/adapters/timeline.js.map +1 -1
  47. package/dist/apme/antigravity-transcript.d.ts +18 -0
  48. package/dist/apme/antigravity-transcript.d.ts.map +1 -0
  49. package/dist/apme/antigravity-transcript.js +94 -0
  50. package/dist/apme/antigravity-transcript.js.map +1 -0
  51. package/dist/apme/classify-turn.d.ts +13 -0
  52. package/dist/apme/classify-turn.d.ts.map +1 -0
  53. package/dist/apme/classify-turn.js +49 -0
  54. package/dist/apme/classify-turn.js.map +1 -0
  55. package/dist/apme/claude-transcript-reader.d.ts +10 -0
  56. package/dist/apme/claude-transcript-reader.d.ts.map +1 -1
  57. package/dist/apme/claude-transcript-reader.js +35 -0
  58. package/dist/apme/claude-transcript-reader.js.map +1 -1
  59. package/dist/apme/collector.d.ts +133 -6
  60. package/dist/apme/collector.d.ts.map +1 -1
  61. package/dist/apme/collector.js +471 -23
  62. package/dist/apme/collector.js.map +1 -1
  63. package/dist/apme/dashboard-html.d.ts.map +1 -1
  64. package/dist/apme/dashboard-html.js +117 -11
  65. package/dist/apme/dashboard-html.js.map +1 -1
  66. package/dist/apme/http.d.ts.map +1 -1
  67. package/dist/apme/http.js +52 -6
  68. package/dist/apme/http.js.map +1 -1
  69. package/dist/apme/index.d.ts +26 -5
  70. package/dist/apme/index.d.ts.map +1 -1
  71. package/dist/apme/index.js +146 -9
  72. package/dist/apme/index.js.map +1 -1
  73. package/dist/apme/judge-detect.d.ts +26 -0
  74. package/dist/apme/judge-detect.d.ts.map +1 -0
  75. package/dist/apme/judge-detect.js +69 -0
  76. package/dist/apme/judge-detect.js.map +1 -0
  77. package/dist/apme/pareto.d.ts +39 -0
  78. package/dist/apme/pareto.d.ts.map +1 -0
  79. package/dist/apme/pareto.js +59 -0
  80. package/dist/apme/pareto.js.map +1 -0
  81. package/dist/apme/recommend.d.ts +3 -0
  82. package/dist/apme/recommend.d.ts.map +1 -1
  83. package/dist/apme/recommend.js +43 -1
  84. package/dist/apme/recommend.js.map +1 -1
  85. package/dist/apme/runner.d.ts +99 -4
  86. package/dist/apme/runner.d.ts.map +1 -1
  87. package/dist/apme/runner.js +743 -72
  88. package/dist/apme/runner.js.map +1 -1
  89. package/dist/apme/sample-to-timeline.d.ts +26 -0
  90. package/dist/apme/sample-to-timeline.d.ts.map +1 -0
  91. package/dist/apme/sample-to-timeline.js +95 -0
  92. package/dist/apme/sample-to-timeline.js.map +1 -0
  93. package/dist/apme/scorers/index.d.ts +47 -0
  94. package/dist/apme/scorers/index.d.ts.map +1 -0
  95. package/dist/apme/scorers/index.js +96 -0
  96. package/dist/apme/scorers/index.js.map +1 -0
  97. package/dist/apme/settings.d.ts +17 -11
  98. package/dist/apme/settings.d.ts.map +1 -1
  99. package/dist/apme/settings.js +30 -9
  100. package/dist/apme/settings.js.map +1 -1
  101. package/dist/apme/store.d.ts +33 -1
  102. package/dist/apme/store.d.ts.map +1 -1
  103. package/dist/apme/store.js +334 -25
  104. package/dist/apme/store.js.map +1 -1
  105. package/dist/awaiting-overlay.d.ts +112 -0
  106. package/dist/awaiting-overlay.d.ts.map +1 -0
  107. package/dist/awaiting-overlay.js +179 -0
  108. package/dist/awaiting-overlay.js.map +1 -0
  109. package/dist/ble-sync-spawn.d.ts +63 -0
  110. package/dist/ble-sync-spawn.d.ts.map +1 -0
  111. package/dist/ble-sync-spawn.js +196 -0
  112. package/dist/ble-sync-spawn.js.map +1 -0
  113. package/dist/bridge-core.d.ts +34 -1
  114. package/dist/bridge-core.d.ts.map +1 -1
  115. package/dist/bridge-core.js +207 -24
  116. package/dist/bridge-core.js.map +1 -1
  117. package/dist/broadcast.d.ts +3 -0
  118. package/dist/broadcast.d.ts.map +1 -0
  119. package/dist/broadcast.js +122 -0
  120. package/dist/broadcast.js.map +1 -0
  121. package/dist/check-deps.d.ts.map +1 -1
  122. package/dist/check-deps.js +25 -9
  123. package/dist/check-deps.js.map +1 -1
  124. package/dist/claude-permission-rules.d.ts +55 -0
  125. package/dist/claude-permission-rules.d.ts.map +1 -0
  126. package/dist/claude-permission-rules.js +197 -0
  127. package/dist/claude-permission-rules.js.map +1 -0
  128. package/dist/cli.d.ts +15 -1
  129. package/dist/cli.d.ts.map +1 -1
  130. package/dist/cli.js +1030 -93
  131. package/dist/cli.js.map +1 -1
  132. package/dist/codex-auth.d.ts +21 -0
  133. package/dist/codex-auth.d.ts.map +1 -1
  134. package/dist/codex-auth.js +52 -1
  135. package/dist/codex-auth.js.map +1 -1
  136. package/dist/codex-output-parser.d.ts +8 -0
  137. package/dist/codex-output-parser.d.ts.map +1 -1
  138. package/dist/codex-output-parser.js +110 -25
  139. package/dist/codex-output-parser.js.map +1 -1
  140. package/dist/codex-rate-limits.d.ts +16 -0
  141. package/dist/codex-rate-limits.d.ts.map +1 -0
  142. package/dist/codex-rate-limits.js +197 -0
  143. package/dist/codex-rate-limits.js.map +1 -0
  144. package/dist/codex-rollout-response.d.ts +31 -0
  145. package/dist/codex-rollout-response.d.ts.map +1 -0
  146. package/dist/codex-rollout-response.js +135 -0
  147. package/dist/codex-rollout-response.js.map +1 -0
  148. package/dist/d200h/image-renderer.d.ts +4 -16
  149. package/dist/d200h/image-renderer.d.ts.map +1 -1
  150. package/dist/d200h/image-renderer.js +46 -212
  151. package/dist/d200h/image-renderer.js.map +1 -1
  152. package/dist/daemon-server.d.ts +85 -0
  153. package/dist/daemon-server.d.ts.map +1 -1
  154. package/dist/daemon-server.js +1975 -159
  155. package/dist/daemon-server.js.map +1 -1
  156. package/dist/daemon.js +15 -6
  157. package/dist/daemon.js.map +1 -1
  158. package/dist/display-dim.d.ts +9 -0
  159. package/dist/display-dim.d.ts.map +1 -0
  160. package/dist/display-dim.js +53 -0
  161. package/dist/display-dim.js.map +1 -0
  162. package/dist/display-monitor.d.ts +15 -2
  163. package/dist/display-monitor.d.ts.map +1 -1
  164. package/dist/display-monitor.js +104 -26
  165. package/dist/display-monitor.js.map +1 -1
  166. package/dist/esp32-serial.d.ts +190 -1
  167. package/dist/esp32-serial.d.ts.map +1 -1
  168. package/dist/esp32-serial.js +1090 -156
  169. package/dist/esp32-serial.js.map +1 -1
  170. package/dist/fallback-task-timeline.d.ts +42 -0
  171. package/dist/fallback-task-timeline.d.ts.map +1 -0
  172. package/dist/fallback-task-timeline.js +119 -0
  173. package/dist/fallback-task-timeline.js.map +1 -0
  174. package/dist/foundation-models-helper.d.ts +11 -0
  175. package/dist/foundation-models-helper.d.ts.map +1 -0
  176. package/dist/foundation-models-helper.js +241 -0
  177. package/dist/foundation-models-helper.js.map +1 -0
  178. package/dist/hook-migration.js +1 -1
  179. package/dist/hook-migration.js.map +1 -1
  180. package/dist/hook-server.d.ts +2 -3
  181. package/dist/hook-server.d.ts.map +1 -1
  182. package/dist/hook-server.js +23 -10
  183. package/dist/hook-server.js.map +1 -1
  184. package/dist/idotmatrix/idotmatrix-daemon-sync.d.ts +33 -0
  185. package/dist/idotmatrix/idotmatrix-daemon-sync.d.ts.map +1 -0
  186. package/dist/idotmatrix/idotmatrix-daemon-sync.js +164 -0
  187. package/dist/idotmatrix/idotmatrix-daemon-sync.js.map +1 -0
  188. package/dist/idotmatrix/idotmatrix-discover.d.ts +18 -0
  189. package/dist/idotmatrix/idotmatrix-discover.d.ts.map +1 -0
  190. package/dist/idotmatrix/idotmatrix-discover.js +85 -0
  191. package/dist/idotmatrix/idotmatrix-discover.js.map +1 -0
  192. package/dist/idotmatrix/idotmatrix-settings.d.ts +20 -0
  193. package/dist/idotmatrix/idotmatrix-settings.d.ts.map +1 -0
  194. package/dist/idotmatrix/idotmatrix-settings.js +57 -0
  195. package/dist/idotmatrix/idotmatrix-settings.js.map +1 -0
  196. package/dist/index.d.ts.map +1 -1
  197. package/dist/index.js +217 -179
  198. package/dist/index.js.map +1 -1
  199. package/dist/log-stream.d.ts +15 -16
  200. package/dist/log-stream.d.ts.map +1 -1
  201. package/dist/log-stream.js +18 -96
  202. package/dist/log-stream.js.map +1 -1
  203. package/dist/logger.d.ts +3 -1
  204. package/dist/logger.d.ts.map +1 -1
  205. package/dist/logger.js +18 -5
  206. package/dist/logger.js.map +1 -1
  207. package/dist/mdns.d.ts +17 -0
  208. package/dist/mdns.d.ts.map +1 -1
  209. package/dist/mdns.js +52 -18
  210. package/dist/mdns.js.map +1 -1
  211. package/dist/model-catalog.d.ts +1 -1
  212. package/dist/model-catalog.d.ts.map +1 -1
  213. package/dist/model-catalog.js +2 -4
  214. package/dist/model-catalog.js.map +1 -1
  215. package/dist/modules/adb-module.d.ts +1 -1
  216. package/dist/modules/adb-module.d.ts.map +1 -1
  217. package/dist/modules/adb-module.js +4 -3
  218. package/dist/modules/adb-module.js.map +1 -1
  219. package/dist/modules/broadcast-module.d.ts +17 -0
  220. package/dist/modules/broadcast-module.d.ts.map +1 -0
  221. package/dist/modules/broadcast-module.js +26 -0
  222. package/dist/modules/broadcast-module.js.map +1 -0
  223. package/dist/modules/d200h-module.d.ts +22 -0
  224. package/dist/modules/d200h-module.d.ts.map +1 -1
  225. package/dist/modules/d200h-module.js +200 -65
  226. package/dist/modules/d200h-module.js.map +1 -1
  227. package/dist/modules/idotmatrix-module.d.ts +9 -0
  228. package/dist/modules/idotmatrix-module.d.ts.map +1 -0
  229. package/dist/modules/idotmatrix-module.js +46 -0
  230. package/dist/modules/idotmatrix-module.js.map +1 -0
  231. package/dist/modules/index.d.ts +3 -1
  232. package/dist/modules/index.d.ts.map +1 -1
  233. package/dist/modules/index.js +9 -3
  234. package/dist/modules/index.js.map +1 -1
  235. package/dist/modules/pixoo-module.d.ts.map +1 -1
  236. package/dist/modules/pixoo-module.js +14 -4
  237. package/dist/modules/pixoo-module.js.map +1 -1
  238. package/dist/modules/serial-module.d.ts +4 -0
  239. package/dist/modules/serial-module.d.ts.map +1 -1
  240. package/dist/modules/serial-module.js +14 -12
  241. package/dist/modules/serial-module.js.map +1 -1
  242. package/dist/modules/timebox-module.d.ts +9 -0
  243. package/dist/modules/timebox-module.d.ts.map +1 -0
  244. package/dist/modules/timebox-module.js +46 -0
  245. package/dist/modules/timebox-module.js.map +1 -0
  246. package/dist/modules/trmnl-module.d.ts +38 -0
  247. package/dist/modules/trmnl-module.d.ts.map +1 -0
  248. package/dist/modules/trmnl-module.js +111 -0
  249. package/dist/modules/trmnl-module.js.map +1 -0
  250. package/dist/modules/types.d.ts +4 -2
  251. package/dist/modules/types.d.ts.map +1 -1
  252. package/dist/observed-steering.d.ts +93 -0
  253. package/dist/observed-steering.d.ts.map +1 -0
  254. package/dist/observed-steering.js +247 -0
  255. package/dist/observed-steering.js.map +1 -0
  256. package/dist/openclaw-session.d.ts +18 -0
  257. package/dist/openclaw-session.d.ts.map +1 -0
  258. package/dist/openclaw-session.js +34 -0
  259. package/dist/openclaw-session.js.map +1 -0
  260. package/dist/opencode-steering.d.ts +36 -0
  261. package/dist/opencode-steering.d.ts.map +1 -0
  262. package/dist/opencode-steering.js +84 -0
  263. package/dist/opencode-steering.js.map +1 -0
  264. package/dist/output-parser.d.ts +30 -0
  265. package/dist/output-parser.d.ts.map +1 -1
  266. package/dist/output-parser.js +172 -18
  267. package/dist/output-parser.js.map +1 -1
  268. package/dist/passive-observer.d.ts +32 -0
  269. package/dist/passive-observer.d.ts.map +1 -1
  270. package/dist/passive-observer.js +288 -49
  271. package/dist/passive-observer.js.map +1 -1
  272. package/dist/permission-resolver.d.ts +55 -0
  273. package/dist/permission-resolver.d.ts.map +1 -0
  274. package/dist/permission-resolver.js +112 -0
  275. package/dist/permission-resolver.js.map +1 -0
  276. package/dist/pixoo/micro-glyphs.d.ts +18 -0
  277. package/dist/pixoo/micro-glyphs.d.ts.map +1 -0
  278. package/dist/pixoo/micro-glyphs.js +143 -0
  279. package/dist/pixoo/micro-glyphs.js.map +1 -0
  280. package/dist/pixoo/official-dot-glyphs.generated.d.ts +8 -0
  281. package/dist/pixoo/official-dot-glyphs.generated.d.ts.map +1 -0
  282. package/dist/pixoo/official-dot-glyphs.generated.js +247 -0
  283. package/dist/pixoo/official-dot-glyphs.generated.js.map +1 -0
  284. package/dist/pixoo/pixoo-bridge.d.ts +16 -8
  285. package/dist/pixoo/pixoo-bridge.d.ts.map +1 -1
  286. package/dist/pixoo/pixoo-bridge.js +127 -35
  287. package/dist/pixoo/pixoo-bridge.js.map +1 -1
  288. package/dist/pixoo/pixoo-camera.d.ts +19 -3
  289. package/dist/pixoo/pixoo-camera.d.ts.map +1 -1
  290. package/dist/pixoo/pixoo-camera.js +62 -27
  291. package/dist/pixoo/pixoo-camera.js.map +1 -1
  292. package/dist/pixoo/pixoo-client.d.ts +13 -3
  293. package/dist/pixoo/pixoo-client.d.ts.map +1 -1
  294. package/dist/pixoo/pixoo-client.js +51 -22
  295. package/dist/pixoo/pixoo-client.js.map +1 -1
  296. package/dist/pixoo/pixoo-discover.d.ts +37 -0
  297. package/dist/pixoo/pixoo-discover.d.ts.map +1 -0
  298. package/dist/pixoo/pixoo-discover.js +105 -0
  299. package/dist/pixoo/pixoo-discover.js.map +1 -0
  300. package/dist/pixoo/pixoo-renderer.d.ts +27 -3
  301. package/dist/pixoo/pixoo-renderer.d.ts.map +1 -1
  302. package/dist/pixoo/pixoo-renderer.js +533 -135
  303. package/dist/pixoo/pixoo-renderer.js.map +1 -1
  304. package/dist/pixoo/pixoo-settings.d.ts +6 -0
  305. package/dist/pixoo/pixoo-settings.d.ts.map +1 -1
  306. package/dist/pixoo/pixoo-settings.js +9 -0
  307. package/dist/pixoo/pixoo-settings.js.map +1 -1
  308. package/dist/pixoo/pixoo-sprites.d.ts +84 -11
  309. package/dist/pixoo/pixoo-sprites.d.ts.map +1 -1
  310. package/dist/pixoo/pixoo-sprites.js +620 -209
  311. package/dist/pixoo/pixoo-sprites.js.map +1 -1
  312. package/dist/pty-manager.d.ts.map +1 -1
  313. package/dist/pty-manager.js +8 -2
  314. package/dist/pty-manager.js.map +1 -1
  315. package/dist/review-runner.d.ts +113 -0
  316. package/dist/review-runner.d.ts.map +1 -0
  317. package/dist/review-runner.js +428 -0
  318. package/dist/review-runner.js.map +1 -0
  319. package/dist/session-activity.d.ts +14 -0
  320. package/dist/session-activity.d.ts.map +1 -0
  321. package/dist/session-activity.js +160 -0
  322. package/dist/session-activity.js.map +1 -0
  323. package/dist/session-aggregator.d.ts +25 -0
  324. package/dist/session-aggregator.d.ts.map +1 -1
  325. package/dist/session-aggregator.js +48 -9
  326. package/dist/session-aggregator.js.map +1 -1
  327. package/dist/session-focus-relay.d.ts.map +1 -1
  328. package/dist/session-focus-relay.js +7 -1
  329. package/dist/session-focus-relay.js.map +1 -1
  330. package/dist/session-registry.d.ts +74 -3
  331. package/dist/session-registry.d.ts.map +1 -1
  332. package/dist/session-registry.js +140 -8
  333. package/dist/session-registry.js.map +1 -1
  334. package/dist/session-timeline-relay.d.ts.map +1 -1
  335. package/dist/session-timeline-relay.js +13 -4
  336. package/dist/session-timeline-relay.js.map +1 -1
  337. package/dist/session-transcript-timeline.d.ts +49 -0
  338. package/dist/session-transcript-timeline.d.ts.map +1 -0
  339. package/dist/session-transcript-timeline.js +276 -0
  340. package/dist/session-transcript-timeline.js.map +1 -0
  341. package/dist/state-machine.d.ts +6 -1
  342. package/dist/state-machine.d.ts.map +1 -1
  343. package/dist/state-machine.js +86 -28
  344. package/dist/state-machine.js.map +1 -1
  345. package/dist/timebox/timebox-daemon-sync.d.ts +19 -0
  346. package/dist/timebox/timebox-daemon-sync.d.ts.map +1 -0
  347. package/dist/timebox/timebox-daemon-sync.js +135 -0
  348. package/dist/timebox/timebox-daemon-sync.js.map +1 -0
  349. package/dist/timebox/timebox-discover.d.ts +19 -0
  350. package/dist/timebox/timebox-discover.d.ts.map +1 -0
  351. package/dist/timebox/timebox-discover.js +87 -0
  352. package/dist/timebox/timebox-discover.js.map +1 -0
  353. package/dist/timebox/timebox-settings.d.ts +32 -0
  354. package/dist/timebox/timebox-settings.d.ts.map +1 -0
  355. package/dist/timebox/timebox-settings.js +80 -0
  356. package/dist/timebox/timebox-settings.js.map +1 -0
  357. package/dist/timeline-store.d.ts +112 -3
  358. package/dist/timeline-store.d.ts.map +1 -1
  359. package/dist/timeline-store.js +460 -14
  360. package/dist/timeline-store.js.map +1 -1
  361. package/dist/timeline-summarizer.d.ts.map +1 -1
  362. package/dist/timeline-summarizer.js +29 -5
  363. package/dist/timeline-summarizer.js.map +1 -1
  364. package/dist/trmnl/byos-server.d.ts +39 -0
  365. package/dist/trmnl/byos-server.d.ts.map +1 -0
  366. package/dist/trmnl/byos-server.js +301 -0
  367. package/dist/trmnl/byos-server.js.map +1 -0
  368. package/dist/trmnl/frame-cache.d.ts +37 -0
  369. package/dist/trmnl/frame-cache.d.ts.map +1 -0
  370. package/dist/trmnl/frame-cache.js +157 -0
  371. package/dist/trmnl/frame-cache.js.map +1 -0
  372. package/dist/trmnl/image-renderer.d.ts +27 -0
  373. package/dist/trmnl/image-renderer.d.ts.map +1 -0
  374. package/dist/trmnl/image-renderer.js +235 -0
  375. package/dist/trmnl/image-renderer.js.map +1 -0
  376. package/dist/trmnl/trmnl-settings.d.ts +96 -0
  377. package/dist/trmnl/trmnl-settings.d.ts.map +1 -0
  378. package/dist/trmnl/trmnl-settings.js +177 -0
  379. package/dist/trmnl/trmnl-settings.js.map +1 -0
  380. package/dist/trmnl/trmnl-telemetry.d.ts +47 -0
  381. package/dist/trmnl/trmnl-telemetry.d.ts.map +1 -0
  382. package/dist/trmnl/trmnl-telemetry.js +56 -0
  383. package/dist/trmnl/trmnl-telemetry.js.map +1 -0
  384. package/dist/tui/ansi.d.ts +0 -4
  385. package/dist/tui/ansi.d.ts.map +1 -1
  386. package/dist/tui/ansi.js +14 -7
  387. package/dist/tui/ansi.js.map +1 -1
  388. package/dist/tui/dashboard.d.ts +1 -0
  389. package/dist/tui/dashboard.d.ts.map +1 -1
  390. package/dist/tui/dashboard.js +38 -11
  391. package/dist/tui/dashboard.js.map +1 -1
  392. package/dist/tui/renderer.d.ts +36 -0
  393. package/dist/tui/renderer.d.ts.map +1 -1
  394. package/dist/tui/renderer.js +355 -121
  395. package/dist/tui/renderer.js.map +1 -1
  396. package/dist/tui/terrarium.d.ts.map +1 -1
  397. package/dist/tui/terrarium.js +44 -51
  398. package/dist/tui/terrarium.js.map +1 -1
  399. package/dist/types.d.ts +2 -2
  400. package/dist/types.d.ts.map +1 -1
  401. package/dist/types.js +2 -2
  402. package/dist/types.js.map +1 -1
  403. package/dist/usage-api.d.ts.map +1 -1
  404. package/dist/usage-api.js +7 -1
  405. package/dist/usage-api.js.map +1 -1
  406. package/dist/usage-event.d.ts +10 -3
  407. package/dist/usage-event.d.ts.map +1 -1
  408. package/dist/usage-event.js +98 -13
  409. package/dist/usage-event.js.map +1 -1
  410. package/dist/utility-proxy.d.ts.map +1 -1
  411. package/dist/utility-proxy.js +8 -0
  412. package/dist/utility-proxy.js.map +1 -1
  413. package/dist/utils/project-name.d.ts +3 -0
  414. package/dist/utils/project-name.d.ts.map +1 -1
  415. package/dist/utils/project-name.js +44 -2
  416. package/dist/utils/project-name.js.map +1 -1
  417. package/dist/version-check.d.ts.map +1 -1
  418. package/dist/version-check.js +1 -17
  419. package/dist/version-check.js.map +1 -1
  420. package/dist/windows-service.d.ts +26 -0
  421. package/dist/windows-service.d.ts.map +1 -0
  422. package/dist/windows-service.js +145 -0
  423. package/dist/windows-service.js.map +1 -0
  424. package/dist/ws-server.d.ts +17 -3
  425. package/dist/ws-server.d.ts.map +1 -1
  426. package/dist/ws-server.js +78 -8
  427. package/dist/ws-server.js.map +1 -1
  428. package/fm-helper/AgentDeckFMHelper.swift +112 -0
  429. package/package.json +10 -4
  430. package/scripts/build-fm-helper.mjs +26 -0
  431. package/LICENSE +0 -21
  432. package/dist/apme/tuner.d.ts +0 -64
  433. package/dist/apme/tuner.d.ts.map +0 -1
  434. package/dist/apme/tuner.js +0 -297
  435. package/dist/apme/tuner.js.map +0 -1
@@ -3,39 +3,409 @@
3
3
  * Stores recent timeline entries for relay to Android/plugin clients.
4
4
  * No scroll/grouping logic (that's client-side).
5
5
  */
6
- import { deduplicateEntry } from '@agentdeck/shared';
6
+ import { deduplicateEntry, formatDurationSec, normalizeTimelineEntryForStorage } from '@agentdeck/shared';
7
+ import { readFileSync, writeFileSync, renameSync, mkdirSync, unlinkSync } from 'fs';
8
+ import { dirname } from 'path';
7
9
  const MAX_ENTRIES = 200;
10
+ /** Separate retention cap for task hierarchy rows (task_start/task_end/
11
+ * task_milestone). Task rows are exempt from the generic FIFO shift —
12
+ * a long task's `task_start` must not scroll away while its turns stream
13
+ * in, or the eventual `task_end` renders as an unpaired orphan. ~30 pairs. */
14
+ const MAX_TASK_ENTRIES = 60;
15
+ /** Coalescing window for persistence writes. Timeline mutation is bursty (a
16
+ * single turn emits chat_start + several tool rows + chat_response + chat_end),
17
+ * so writing per mutation would amplify a turn into a dozen disk writes. */
18
+ const PERSIST_DEBOUNCE_MS = 500;
19
+ function isTaskRow(e) {
20
+ return e.type === 'task_start' || e.type === 'task_end' || e.type === 'task_milestone';
21
+ }
22
+ /** Chat/tool entry types that, in projection mode, come from the SessionSample
23
+ * projection instead of the adapters' direct emitters. Locally-emitted entries
24
+ * of these types are suppressed when projection mode is on so the timeline has
25
+ * exactly one source. Task hierarchy + error/scheduled rows are never affected. */
26
+ const PROJECTED_TYPES = new Set([
27
+ 'chat_start', 'chat_response', 'chat_end', 'tool_request', 'tool_resolved', 'tool_exec',
28
+ ]);
8
29
  export class BridgeTimelineStore {
9
30
  entries = [];
10
31
  listeners = [];
11
- addEntry(entry) {
12
- const result = deduplicateEntry(entry, this.entries);
32
+ attributor = null;
33
+ /** Set only by the daemon (see enablePersistence). Session bridges share this
34
+ * class but must never write: several can run at once and would clobber each
35
+ * other and the daemon's file. */
36
+ persistPath = null;
37
+ persistTimer = null;
38
+ dirty = false;
39
+ /** Phase 6 cutover (default OFF). When true, locally-emitted chat/tool rows
40
+ * are dropped — the SessionSample projection (added via `bypassSuppression`)
41
+ * becomes the single source. Relayed + projected entries bypass this. */
42
+ suppressLocalChatTool = false;
43
+ setSuppressLocalChatTool(v) {
44
+ this.suppressLocalChatTool = v;
45
+ }
46
+ /** Install (or replace) the attributor invoked on every addEntry / upsertEntry
47
+ * before dedup. Wired by `BridgeCore.wireTimeline` so the store and the
48
+ * live broadcast see identical, fully-attributed entries — critical for
49
+ * history replay (`timeline_history`). */
50
+ setAttributor(fn) {
51
+ this.attributor = fn;
52
+ }
53
+ addEntry(entry, opts) {
54
+ // Phase 6: in projection mode, drop locally-emitted chat/tool rows — they
55
+ // now come from the SessionSample projection (which bypasses) or are
56
+ // relayed from another bridge (which bypasses). No-op when mode is off.
57
+ if (this.suppressLocalChatTool && !opts?.bypassSuppression && PROJECTED_TYPES.has(entry.type)) {
58
+ return;
59
+ }
60
+ const enriched = this.attributor ? this.attributor(entry) : entry;
61
+ const normalized = normalizeTimelineEntryForStorage(enriched);
62
+ if (!normalized)
63
+ return;
64
+ if (this.tryMergeTaskEndByTaskId(normalized)) {
65
+ return;
66
+ }
67
+ const result = deduplicateEntry(normalized, this.entries);
13
68
  if (result.action === 'skip')
14
69
  return;
15
70
  if (result.action === 'merge') {
71
+ // Merge path is an *update* — the existing entry was attributed at its
72
+ // own creation time and that attribution is the truth. Do NOT pull
73
+ // session/task/run/project from `enriched` (the attributor on this call
74
+ // reflects the *current* active task, which may have rotated since the
75
+ // original entry was stored). Use the raw caller `entry` so explicit
76
+ // caller-set fields still win, and otherwise keep `existing.*`.
16
77
  const existing = this.entries[result.index];
17
78
  existing.repeatCount = (existing.repeatCount || 1) + 1;
18
- existing.ts = entry.ts;
79
+ existing.ts = normalized.ts;
80
+ existing.raw = normalized.raw;
81
+ existing.detail = normalized.detail ?? existing.detail;
82
+ existing.agentType = entry.agentType ?? existing.agentType;
83
+ existing.projectName = entry.projectName ?? existing.projectName;
84
+ existing.sessionId = entry.sessionId ?? existing.sessionId;
85
+ existing.runId = entry.runId ?? existing.runId;
86
+ existing.taskId = entry.taskId ?? existing.taskId;
87
+ existing.startedAt = normalized.startedAt ?? existing.startedAt;
88
+ existing.endedAt = normalized.endedAt ?? existing.endedAt;
89
+ existing.automated = normalized.automated ?? existing.automated;
90
+ existing.summaryKind = normalized.summaryKind ?? existing.summaryKind;
91
+ existing.boundarySignal = normalized.boundarySignal ?? existing.boundarySignal;
92
+ existing.taskScore = normalized.taskScore ?? existing.taskScore;
93
+ existing.taskOutcome = normalized.taskOutcome ?? existing.taskOutcome;
94
+ existing.taskCategory = normalized.taskCategory ?? existing.taskCategory;
95
+ existing.taskSummary = normalized.taskSummary ?? existing.taskSummary;
19
96
  if (result.removeChatStartIndex != null) {
20
97
  this.entries.splice(result.removeChatStartIndex, 1);
21
98
  }
99
+ this.schedulePersist();
22
100
  for (const cb of this.listeners)
23
101
  cb(existing, true);
24
102
  return;
25
103
  }
26
- // action === 'add'
104
+ // action === 'add' — fresh entry. Push the enriched form so storage and
105
+ // history replay carry attribution from the time of creation.
27
106
  this.entries.push(result.entry);
28
107
  if (this.entries.length > MAX_ENTRIES) {
29
- this.entries.shift();
108
+ this.evictOne();
30
109
  }
110
+ this.schedulePersist();
31
111
  for (const cb of this.listeners)
32
112
  cb(result.entry);
33
113
  }
114
+ /** Evict a single entry to enforce MAX_ENTRIES, protecting task rows.
115
+ *
116
+ * Task rows only leave under their own cap (MAX_TASK_ENTRIES), and an
117
+ * in-flight task's `task_start` (no matching `task_end` yet) is never
118
+ * evicted — otherwise a long task's start scrolls away mid-task and the
119
+ * pair splits. Everything else FIFOs as before. */
120
+ evictOne() {
121
+ const taskRowCount = this.entries.reduce((n, e) => n + (isTaskRow(e) ? 1 : 0), 0);
122
+ if (taskRowCount > MAX_TASK_ENTRIES) {
123
+ const closed = new Set();
124
+ for (const e of this.entries) {
125
+ if (e.type === 'task_end' && e.taskId)
126
+ closed.add(e.taskId);
127
+ }
128
+ const idx = this.entries.findIndex((e) => isTaskRow(e) && !(e.type === 'task_start' && e.taskId && !closed.has(e.taskId)));
129
+ if (idx >= 0) {
130
+ this.entries.splice(idx, 1);
131
+ return;
132
+ }
133
+ }
134
+ // Shed the oldest `tool_exec` before any chat/turn row. Observed codex/
135
+ // opencode command rows carry real sessionIds + command detail, so they
136
+ // pass the anonymous-noise storage filter and accumulate — a live daemon
137
+ // snapshot ran 87% tool_exec (87/100). Undifferentiated FIFO would then
138
+ // evict a turn's `chat_start` (always the oldest ts in its turn) before its
139
+ // own tool_exec rows, leaving an orphaned chat_response/chat_end in the
140
+ // `timeline_history` replay a reconnecting client receives — the Node-side
141
+ // face of the "answer with no prompt" symptom. tool_exec is standalone
142
+ // (unlike the tool_request/tool_resolved approval pair, which must not be
143
+ // split), so shedding it first is safe and preserves the turn skeleton.
144
+ const toolIdx = this.entries.findIndex((e) => e.type === 'tool_exec');
145
+ if (toolIdx >= 0) {
146
+ this.entries.splice(toolIdx, 1);
147
+ return;
148
+ }
149
+ const idx = this.entries.findIndex((e) => !isTaskRow(e));
150
+ if (idx >= 0) {
151
+ this.entries.splice(idx, 1);
152
+ return;
153
+ }
154
+ // Pathological: buffer is 100% task rows — fall back to plain FIFO so the
155
+ // buffer stays bounded.
156
+ this.entries.shift();
157
+ }
158
+ /**
159
+ * Take ownership of on-disk persistence.
160
+ *
161
+ * The daemon is the timeline's source of truth — every surface's entries flow
162
+ * through it — so it is also the only process that may write the file. Call
163
+ * this once at daemon startup, AFTER `loadPersistedFile`, so the first write
164
+ * carries the rehydrated history rather than truncating it.
165
+ *
166
+ * Session bridges deliberately do not call this: they are per-session and
167
+ * short-lived, and concurrent writers would interleave partial histories.
168
+ */
169
+ enablePersistence(path) {
170
+ this.persistPath = path;
171
+ }
172
+ /** Mark the buffer dirty and schedule a coalesced write. */
173
+ schedulePersist() {
174
+ if (!this.persistPath)
175
+ return;
176
+ this.dirty = true;
177
+ if (this.persistTimer)
178
+ return;
179
+ this.persistTimer = setTimeout(() => {
180
+ this.persistTimer = null;
181
+ this.flushPersist();
182
+ }, PERSIST_DEBOUNCE_MS);
183
+ this.persistTimer.unref?.();
184
+ }
185
+ /**
186
+ * Write the buffer to disk now. Safe to call when persistence is off or the
187
+ * buffer is clean — both are no-ops.
188
+ *
189
+ * Writes through a temp file + rename so a crash or a concurrent reader can
190
+ * never observe a half-written array: `loadPersistedFile` treats malformed
191
+ * JSON as "no history", so a torn write would silently erase the timeline.
192
+ */
193
+ flushPersist() {
194
+ if (!this.persistPath || !this.dirty)
195
+ return;
196
+ this.dirty = false;
197
+ const target = this.persistPath;
198
+ const tmp = `${target}.tmp`;
199
+ try {
200
+ mkdirSync(dirname(target), { recursive: true });
201
+ writeFileSync(tmp, JSON.stringify(this.entries), 'utf-8');
202
+ renameSync(tmp, target);
203
+ }
204
+ catch {
205
+ // Disk full, permissions, read-only home — persistence is best-effort and
206
+ // must never take the daemon down with it.
207
+ try {
208
+ unlinkSync(tmp);
209
+ }
210
+ catch { /* nothing to clean up */ }
211
+ }
212
+ }
213
+ /** Stop the pending write timer, flushing anything outstanding first. */
214
+ stopPersistence() {
215
+ if (this.persistTimer) {
216
+ clearTimeout(this.persistTimer);
217
+ this.persistTimer = null;
218
+ }
219
+ this.flushPersist();
220
+ }
34
221
  getHistory(since) {
35
- if (since) {
36
- return this.entries.filter((e) => e.ts > since);
222
+ const entries = since
223
+ ? this.entries.filter((e) => e.ts > since)
224
+ : this.entries;
225
+ return [...entries].sort((a, b) => a.ts - b.ts);
226
+ }
227
+ /** Load persisted timeline rows into the bounded replay buffer without
228
+ * broadcasting them as live events. The Node daemon normally keeps the
229
+ * device timeline in memory, but macOS/previous daemon runs may leave a
230
+ * timeline.json behind. Rehydrating it lets reconnecting Android/tablet
231
+ * clients receive a non-empty initial `timeline_history`.
232
+ */
233
+ loadPersistedFile(path) {
234
+ let parsed;
235
+ try {
236
+ parsed = JSON.parse(readFileSync(path, 'utf-8'));
237
+ }
238
+ catch {
239
+ return 0;
37
240
  }
38
- return [...this.entries];
241
+ const rows = Array.isArray(parsed)
242
+ ? parsed
243
+ : parsed && typeof parsed === 'object' && Array.isArray(parsed.entries)
244
+ ? parsed.entries
245
+ : [];
246
+ const before = this.entries.length;
247
+ this.loadPersistedEntries(rows);
248
+ return Math.max(0, this.entries.length - before);
249
+ }
250
+ loadPersistedEntries(rows) {
251
+ const normalized = [];
252
+ for (const row of rows) {
253
+ if (!row || typeof row !== 'object')
254
+ continue;
255
+ const entry = row;
256
+ if (typeof entry.ts !== 'number' || typeof entry.type !== 'string' || typeof entry.raw !== 'string')
257
+ continue;
258
+ const clean = normalizeTimelineEntryForStorage(entry);
259
+ if (clean)
260
+ normalized.push(clean);
261
+ }
262
+ if (normalized.length === 0)
263
+ return;
264
+ const byKey = new Map();
265
+ for (const entry of [...this.entries, ...normalized].sort((a, b) => a.ts - b.ts)) {
266
+ byKey.set(`${entry.ts}:${entry.type}:${entry.raw}`, entry);
267
+ }
268
+ const merged = Array.from(byKey.values()).sort((a, b) => a.ts - b.ts);
269
+ // Trim with the same task-row protection as live eviction: task rows keep
270
+ // their own (deeper) retention so start/end pairs survive a reload even
271
+ // when chat/tool rows overflowed the generic cap.
272
+ const taskRows = merged.filter(isTaskRow).slice(-MAX_TASK_ENTRIES);
273
+ const rest = merged.filter((e) => !isTaskRow(e)).slice(-(MAX_ENTRIES - taskRows.length));
274
+ this.entries = [...taskRows, ...rest].sort((a, b) => a.ts - b.ts);
275
+ }
276
+ /** Node mirror of the Swift daemon's orphan reaper
277
+ * (DaemonServer.computeOrphanTaskEnds): synthesize a `task_end` for every
278
+ * `task_start` whose pair was never written. The producer only guarantees
279
+ * the pair within a single daemon lifetime (ApmeCollector.closeTask is
280
+ * in-memory), so a daemon killed mid-task leaves task_start rows that
281
+ * clients render as in-flight — spinning the task marker forever. Called
282
+ * once after `loadPersistedFile` at daemon startup. Idempotent: a real
283
+ * task_end arriving later merges over the synthetic via
284
+ * `tryMergeTaskEndByTaskId`. Returns the number of synthesized rows. */
285
+ reapOrphanTaskStarts() {
286
+ const closed = new Set();
287
+ for (const e of this.entries) {
288
+ if (e.type === 'task_end' && e.taskId)
289
+ closed.add(e.taskId);
290
+ }
291
+ let count = 0;
292
+ for (const start of [...this.entries]) {
293
+ if (start.type !== 'task_start' || !start.taskId || closed.has(start.taskId))
294
+ continue;
295
+ const startedAtMs = start.startedAt ?? start.ts;
296
+ // Anchor the synthetic end 1ms after the task's LAST known row so it
297
+ // sorts below the turns it closes. Anchoring at task_start+1 (the
298
+ // original behavior) rendered "TASK END" directly under its header,
299
+ // ABOVE every turn of the task — an empty-looking closed task with its
300
+ // rows dangling underneath. The last row's ts also gives an honest
301
+ // lower-bound duration ("Interrupted · ~55m"); "–" remains only when
302
+ // the task has no other rows at all.
303
+ let lastTs = startedAtMs;
304
+ for (const e of this.entries) {
305
+ if (e !== start && e.taskId === start.taskId && e.ts > lastTs)
306
+ lastTs = e.ts;
307
+ }
308
+ const approxSec = Math.round((lastTs - startedAtMs) / 1000);
309
+ this.addEntry({
310
+ ts: lastTs + 1,
311
+ type: 'task_end',
312
+ raw: approxSec > 0 ? `Interrupted · ~${formatDurationSec(approxSec)}` : 'Interrupted · –',
313
+ ...(start.agentType ? { agentType: start.agentType } : {}),
314
+ ...(start.projectName ? { projectName: start.projectName } : {}),
315
+ ...(start.sessionId ? { sessionId: start.sessionId } : {}),
316
+ ...(start.runId ? { runId: start.runId } : {}),
317
+ startedAt: startedAtMs,
318
+ ...(approxSec > 0 ? { endedAt: lastTs } : {}),
319
+ taskId: start.taskId,
320
+ boundarySignal: 'interrupted',
321
+ }, { bypassSuppression: true });
322
+ closed.add(start.taskId);
323
+ count++;
324
+ }
325
+ return count;
326
+ }
327
+ /** Chat-turn counterpart of `reapOrphanTaskStarts`: close persisted
328
+ * `chat_start` rows whose completion (chat_response / chat_end) never
329
+ * arrived — a session killed mid-turn (no Stop, no SessionEnd — e.g. a
330
+ * /merge skill removing its own worktree+tmux window) leaves the prompt
331
+ * row spinning "in progress" forever on every dashboard.
332
+ *
333
+ * Two live-turn guards, because agentic turns regularly run past any
334
+ * fixed age threshold: only rows older than `staleMs` (default: the
335
+ * 30-minute interactive idle TTL) are considered, AND sessions in
336
+ * `skipSessionIds` — sessions that posted a hook since this daemon
337
+ * started, i.e. provably alive — are never touched. Callers should
338
+ * therefore run this DELAYED after startup, not immediately, so live
339
+ * sessions have had a chance to identify themselves. The synthetic
340
+ * close is anchored after the turn's last same-session row but strictly
341
+ * BEFORE the session's next chat_start — a completion row placed after
342
+ * a newer prompt would stop that newer (possibly live) turn's spinner
343
+ * too. */
344
+ reapOrphanChatStarts(staleMs = 30 * 60_000, now = Date.now(), skipSessionIds) {
345
+ let count = 0;
346
+ const sorted = [...this.entries].sort((a, b) => a.ts - b.ts);
347
+ for (let i = 0; i < sorted.length; i++) {
348
+ const start = sorted[i];
349
+ if (start.type !== 'chat_start' || !start.sessionId)
350
+ continue;
351
+ if (skipSessionIds?.has(start.sessionId))
352
+ continue;
353
+ if (now - start.ts <= staleMs)
354
+ continue;
355
+ // Next chat_start of the same session bounds this turn.
356
+ let nextStartTs = Number.POSITIVE_INFINITY;
357
+ let completed = false;
358
+ let lastTurnTs = start.ts;
359
+ for (let j = i + 1; j < sorted.length; j++) {
360
+ const e = sorted[j];
361
+ if (e.sessionId !== start.sessionId)
362
+ continue;
363
+ if (e.type === 'chat_start') {
364
+ nextStartTs = e.ts;
365
+ break;
366
+ }
367
+ if (e.type === 'chat_response' || e.type === 'chat_end') {
368
+ completed = true;
369
+ break;
370
+ }
371
+ if (e.ts > lastTurnTs)
372
+ lastTurnTs = e.ts;
373
+ }
374
+ if (completed)
375
+ continue;
376
+ const approxSec = Math.round((lastTurnTs - start.ts) / 1000);
377
+ this.addEntry({
378
+ ts: Math.min(lastTurnTs + 1, nextStartTs - 1),
379
+ type: 'chat_end',
380
+ raw: approxSec > 0 ? `Interrupted · ~${formatDurationSec(approxSec)}` : 'Interrupted · –',
381
+ summaryKind: 'none',
382
+ ...(start.agentType ? { agentType: start.agentType } : {}),
383
+ ...(start.projectName ? { projectName: start.projectName } : {}),
384
+ sessionId: start.sessionId,
385
+ ...(start.runId ? { runId: start.runId } : {}),
386
+ ...(start.taskId ? { taskId: start.taskId } : {}),
387
+ startedAt: start.startedAt ?? start.ts,
388
+ }, { bypassSuppression: true });
389
+ count++;
390
+ }
391
+ return count;
392
+ }
393
+ /** Recent entries attributed to one session, for the `query_session_timeline`
394
+ * poll — lets a device that connects mid-session fill its Detail view. */
395
+ getHistoryForSession(sessionId, since, limit = 16) {
396
+ // sessions_list ids for passively-observed sessions are prefixed
397
+ // ("observed:claude:<uuid>") while timeline entries are keyed by the raw uuid,
398
+ // so accept either form.
399
+ const raw = sessionId.replace(/^observed:(?:claude|codex|opencode|antigravity):/, '');
400
+ const matched = this.entries.filter((e) => (e.sessionId === sessionId || e.sessionId === raw) && (since == null || e.ts > since));
401
+ matched.sort((a, b) => a.ts - b.ts);
402
+ // `limit` applies to the chat/tool stream; task hierarchy rows ride along
403
+ // in full so a long task's start/end pair never splits at the per-session
404
+ // window (a task_start older than the last `limit` rows used to vanish,
405
+ // leaving the Detail view an unpaired task_end).
406
+ const taskRows = matched.filter(isTaskRow);
407
+ const rest = matched.filter((e) => !isTaskRow(e)).slice(-limit);
408
+ return [...taskRows, ...rest].sort((a, b) => a.ts - b.ts);
39
409
  }
40
410
  updateEntryStatus(approvalId, status) {
41
411
  for (let i = this.entries.length - 1; i >= 0; i--) {
@@ -45,19 +415,60 @@ export class BridgeTimelineStore {
45
415
  }
46
416
  }
47
417
  }
48
- /** Update existing entry with same ts+type (1s tolerance), or add new */
49
- upsertEntry(entry) {
418
+ /** Update existing entry with same ts+type (1s tolerance), or add new.
419
+ *
420
+ * Update path: the existing entry's session/task/run/project attribution
421
+ * was set at *its* creation time and is authoritative. We do NOT re-run
422
+ * the attributor on update — by the time a late upsert lands (e.g. async
423
+ * LLM summary on a chat_end), the active task may have rotated, and
424
+ * re-attributing would silently move the entry to the wrong task. The
425
+ * raw caller `entry` only overrides existing fields when the caller
426
+ * explicitly set them.
427
+ *
428
+ * Insert path (no match): falls through to `addEntry`, which runs the
429
+ * attributor as usual to capture creation-time attribution. */
430
+ upsertEntry(entry, opts) {
431
+ // An upsert that finds no match falls through to addEntry; honor the same
432
+ // suppression bypass on that insert path (relayed task_end upserts, etc.).
433
+ const normalized = normalizeTimelineEntryForStorage(entry);
434
+ if (!normalized)
435
+ return;
436
+ if (this.tryMergeTaskEndByTaskId(normalized)) {
437
+ return;
438
+ }
50
439
  const tolerance = 1000;
51
440
  for (let i = this.entries.length - 1; i >= 0; i--) {
52
441
  const e = this.entries[i];
53
- if (e.type === entry.type && Math.abs(e.ts - entry.ts) < tolerance) {
54
- this.entries[i] = { ...e, raw: entry.raw, ...(entry.detail ? { detail: entry.detail } : {}) };
442
+ if (e.type === normalized.type && Math.abs(e.ts - normalized.ts) < tolerance) {
443
+ this.entries[i] = {
444
+ ...e,
445
+ raw: normalized.raw,
446
+ ...(normalized.detail ? { detail: normalized.detail } : {}),
447
+ ...(normalized.agentType ? { agentType: normalized.agentType } : {}),
448
+ ...(normalized.projectName ? { projectName: normalized.projectName } : {}),
449
+ ...(normalized.sessionId ? { sessionId: normalized.sessionId } : {}),
450
+ ...(normalized.runId ? { runId: normalized.runId } : {}),
451
+ ...(normalized.taskId ? { taskId: normalized.taskId } : {}),
452
+ ...(normalized.boundarySignal ? { boundarySignal: normalized.boundarySignal } : {}),
453
+ ...(normalized.startedAt != null ? { startedAt: normalized.startedAt } : {}),
454
+ ...(normalized.endedAt != null ? { endedAt: normalized.endedAt } : {}),
455
+ ...(normalized.automated ? { automated: normalized.automated } : {}),
456
+ // summaryKind progresses heuristic/none → llm when the async LLM
457
+ // summary lands. Without this propagation, the dashboard never
458
+ // sees the kind upgrade and (for `summaryKind: 'none'` rows) the
459
+ // detail pane stays suppressed even after the LLM rescues it.
460
+ ...(normalized.summaryKind ? { summaryKind: normalized.summaryKind } : {}),
461
+ ...(normalized.taskScore != null ? { taskScore: normalized.taskScore } : {}),
462
+ ...(normalized.taskOutcome ? { taskOutcome: normalized.taskOutcome } : {}),
463
+ ...(normalized.taskCategory ? { taskCategory: normalized.taskCategory } : {}),
464
+ ...(normalized.taskSummary ? { taskSummary: normalized.taskSummary } : {}),
465
+ };
55
466
  for (const cb of this.listeners)
56
467
  cb(this.entries[i], true);
57
468
  return;
58
469
  }
59
470
  }
60
- this.addEntry(entry);
471
+ this.addEntry(normalized, opts);
61
472
  }
62
473
  /** Get the most recent entry of a given type */
63
474
  getLastEntry(type) {
@@ -75,5 +486,40 @@ export class BridgeTimelineStore {
75
486
  if (idx !== -1)
76
487
  this.listeners.splice(idx, 1);
77
488
  }
489
+ tryMergeTaskEndByTaskId(entry) {
490
+ if (entry.type !== 'task_end' || !entry.taskId)
491
+ return false;
492
+ let idx = -1;
493
+ for (let i = this.entries.length - 1; i >= 0; i--) {
494
+ const e = this.entries[i];
495
+ if (e.type === 'task_end' && e.taskId === entry.taskId) {
496
+ idx = i;
497
+ break;
498
+ }
499
+ }
500
+ if (idx < 0)
501
+ return false;
502
+ const existing = this.entries[idx];
503
+ this.entries[idx] = {
504
+ ...existing,
505
+ raw: entry.raw,
506
+ ...(entry.detail ? { detail: entry.detail } : {}),
507
+ ...(entry.agentType ? { agentType: entry.agentType } : {}),
508
+ ...(entry.projectName ? { projectName: entry.projectName } : {}),
509
+ ...(entry.sessionId ? { sessionId: entry.sessionId } : {}),
510
+ ...(entry.runId ? { runId: entry.runId } : {}),
511
+ ...(entry.startedAt != null ? { startedAt: entry.startedAt } : {}),
512
+ ...(entry.endedAt != null ? { endedAt: entry.endedAt } : {}),
513
+ ...(entry.boundarySignal ? { boundarySignal: entry.boundarySignal } : {}),
514
+ ...(entry.summaryKind ? { summaryKind: entry.summaryKind } : {}),
515
+ ...(entry.taskScore != null ? { taskScore: entry.taskScore } : {}),
516
+ ...(entry.taskOutcome ? { taskOutcome: entry.taskOutcome } : {}),
517
+ ...(entry.taskCategory ? { taskCategory: entry.taskCategory } : {}),
518
+ ...(entry.taskSummary ? { taskSummary: entry.taskSummary } : {}),
519
+ };
520
+ for (const cb of this.listeners)
521
+ cb(this.entries[idx], true);
522
+ return true;
523
+ }
78
524
  }
79
525
  //# sourceMappingURL=timeline-store.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"timeline-store.js","sourceRoot":"","sources":["../src/timeline-store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"timeline-store.js","sourceRoot":"","sources":["../src/timeline-store.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"timeline-summarizer.d.ts","sourceRoot":"","sources":["../src/timeline-summarizer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAiCrD;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAsC5E"}
1
+ {"version":3,"file":"timeline-summarizer.d.ts","sourceRoot":"","sources":["../src/timeline-summarizer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAiCrD;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAoE5E"}
@@ -5,7 +5,7 @@
5
5
  * Tries: local mlx-serve qwen (port 8800) → Ollama → heuristic fallback.
6
6
  * Non-blocking — caller should fire-and-forget, update entry when ready.
7
7
  */
8
- import { debug } from './logger.js';
8
+ import { debug, log } from './logger.js';
9
9
  import { SUMMARY_SYSTEM_PROMPT, cleanLLMOutput, mlxChatUrl, resolveMlxModel } from '@agentdeck/shared';
10
10
  import { fetchMlxModels } from './mlx-probe.js';
11
11
  export { extractTopicHint } from '@agentdeck/shared';
@@ -47,19 +47,26 @@ export async function summarizeResponse(text) {
47
47
  const input = text.length > MAX_INPUT_CHARS
48
48
  ? text.slice(0, MAX_INPUT_CHARS) + '...'
49
49
  : text;
50
+ let mlxJustFailed = false;
51
+ let ollamaJustFailed = false;
50
52
  // Try MLX qwen first (retry after RETRY_INTERVAL_MS)
51
53
  if (mlxAvailable !== false || (Date.now() - mlxFailedAt > RETRY_INTERVAL_MS)) {
52
54
  try {
53
55
  const result = await callMLX(input);
54
56
  if (result) {
57
+ if (mlxAvailable === false) {
58
+ // MLX recovered — note the transition.
59
+ debug('summarizer', 'MLX recovered');
60
+ }
55
61
  mlxAvailable = true;
56
62
  return result;
57
63
  }
58
64
  }
59
- catch {
65
+ catch (err) {
66
+ mlxJustFailed = mlxAvailable !== false; // first time we observe failure
60
67
  mlxAvailable = false;
61
68
  mlxFailedAt = Date.now();
62
- debug('summarizer', 'MLX not available, trying Ollama');
69
+ debug('summarizer', `MLX not available: ${String(err)}`);
63
70
  }
64
71
  }
65
72
  // Try Ollama (retry after RETRY_INTERVAL_MS)
@@ -67,16 +74,33 @@ export async function summarizeResponse(text) {
67
74
  try {
68
75
  const result = await callOllama(input);
69
76
  if (result) {
77
+ if (ollamaAvailable === false) {
78
+ debug('summarizer', 'Ollama recovered');
79
+ }
70
80
  ollamaAvailable = true;
71
81
  return result;
72
82
  }
73
83
  }
74
- catch {
84
+ catch (err) {
85
+ ollamaJustFailed = ollamaAvailable !== false;
75
86
  ollamaAvailable = false;
76
87
  ollamaFailedAt = Date.now();
77
- debug('summarizer', 'Ollama not available, using heuristic');
88
+ debug('summarizer', `Ollama not available: ${String(err)}`);
78
89
  }
79
90
  }
91
+ // Surface backend-down state to the user — but ONLY on the transition
92
+ // (first time we observe both providers failing) and via `log`, NOT
93
+ // `logError`. The summarizer is *optional* — when the user hasn't
94
+ // installed MLX/Ollama, the heuristic row is the intended UX. Routing
95
+ // through `log` means PTY mode (`agentdeck claude`) suppresses it
96
+ // entirely (the message would otherwise bleed into Claude's terminal
97
+ // session and read as a critical error). Daemon/CLI surfaces still see
98
+ // it in stderr as a regular `[agentdeck]` info line.
99
+ if ((mlxJustFailed && ollamaJustFailed)
100
+ || (mlxJustFailed && ollamaAvailable === false)
101
+ || (ollamaJustFailed && mlxAvailable === false)) {
102
+ log('[timeline] LLM summary backend offline (MLX:8800 / Ollama:11434).', 'Timeline rows will use heuristic summaries.', 'Install MLX (`mlx_vlm.server`) or Ollama to get LLM-summarized chat_end rows.');
103
+ }
80
104
  return null;
81
105
  }
82
106
  // extractTopicHint and cleanLLMOutput moved to @agentdeck/shared/timeline-summarizer