@agentdeck/bridge 0.2.2 → 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 +1021 -93
  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,22 @@
1
+ # Bundled fonts
2
+
3
+ These TTFs are rasterized by resvg-js in the D200H image renderer
4
+ (`bridge/src/d200h/image-renderer.ts`). They are loaded explicitly via
5
+ `fontFiles` (not system-font scanning) so device tile rendering is fast and
6
+ deterministic across macOS/Linux.
7
+
8
+ All fonts are licensed under the **SIL Open Font License 1.1** (OFL-1.1),
9
+ which permits bundling and redistribution.
10
+
11
+ | File | Family | Source |
12
+ |------|--------|--------|
13
+ | `IBMPlexSans-Regular.ttf` | IBM Plex Sans | https://github.com/IBM/plex (OFL-1.1) |
14
+ | `IBMPlexSans-Bold.ttf` | IBM Plex Sans (Bold) | https://github.com/IBM/plex (OFL-1.1) |
15
+ | `JetBrainsMono-Regular.ttf` | JetBrains Mono | https://github.com/JetBrains/JetBrainsMono (OFL-1.1) |
16
+ | `JetBrainsMono-Bold.ttf` | JetBrains Mono (Bold) | https://github.com/JetBrains/JetBrainsMono (OFL-1.1) |
17
+
18
+ IBM Plex Sans + JetBrains Mono are the two canonical AgentDeck design-system
19
+ faces (see `DESIGN.md` §3). `IBM Plex Sans` is the `defaultFontFamily` passed to
20
+ resvg so any unresolved family in the shared SVG renderers (e.g. `Inter`,
21
+ `Arial`, `monospace`) falls back to a design-system face instead of dropping
22
+ text entirely.
@@ -14,6 +14,12 @@ export declare class ClaudeCodeAdapter extends PtyAdapter {
14
14
  protected wireOutputParser(): void;
15
15
  protected feedParser(data: string): void;
16
16
  protected handleAgentCommand(cmd: PluginCommand): boolean;
17
+ /**
18
+ * Pre-seed the bridge-resolved (git-aware) project name so the parser's
19
+ * PROJECT_DIR scrape never fires. The scrape is kept only as a fallback for
20
+ * the rare case the resolver produced nothing meaningful.
21
+ */
22
+ seedProjectName(name: string): void;
17
23
  getProjectName(): string | null;
18
24
  prepareForNavigation(): void;
19
25
  /** Exposed for SSE broadcasting from bridge index (alias for getHookServer) */
@@ -1 +1 @@
1
- {"version":3,"file":"claude-code.d.ts","sourceRoot":"","sources":["../../src/adapters/claude-code.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEpE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C;;;GAGG;AACH,qBAAa,iBAAkB,SAAQ,UAAU;IAC/C,QAAQ,CAAC,YAAY,EAAE,iBAAiB,CAA4B;IAEpE,OAAO,CAAC,YAAY,CAAe;IACnC,2BAA2B;IAC3B,OAAO,CAAC,kBAAkB,CAAK;;IAO/B,SAAS,CAAC,iBAAiB,IAAI,MAAM;IAIrC,SAAS,CAAC,gBAAgB,IAAI,IAAI;IA4ClC,SAAS,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIxC,SAAS,CAAC,kBAAkB,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO;IAgBhD,cAAc,IAAI,MAAM,GAAG,IAAI;IAI/B,oBAAoB,IAAI,IAAI;IAIrC,+EAA+E;IAC/E,mBAAmB;CAGpB"}
1
+ {"version":3,"file":"claude-code.d.ts","sourceRoot":"","sources":["../../src/adapters/claude-code.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEpE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C;;;GAGG;AACH,qBAAa,iBAAkB,SAAQ,UAAU;IAC/C,QAAQ,CAAC,YAAY,EAAE,iBAAiB,CAA4B;IAEpE,OAAO,CAAC,YAAY,CAAe;IACnC,2BAA2B;IAC3B,OAAO,CAAC,kBAAkB,CAAK;;IAO/B,SAAS,CAAC,iBAAiB,IAAI,MAAM;IAIrC,SAAS,CAAC,gBAAgB,IAAI,IAAI;IA4ClC,SAAS,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIxC,SAAS,CAAC,kBAAkB,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO;IAgBzD;;;;OAIG;IACH,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI1B,cAAc,IAAI,MAAM,GAAG,IAAI;IAI/B,oBAAoB,IAAI,IAAI;IAIrC,+EAA+E;IAC/E,mBAAmB;CAGpB"}
@@ -76,6 +76,14 @@ export class ClaudeCodeAdapter extends PtyAdapter {
76
76
  }
77
77
  return false;
78
78
  }
79
+ /**
80
+ * Pre-seed the bridge-resolved (git-aware) project name so the parser's
81
+ * PROJECT_DIR scrape never fires. The scrape is kept only as a fallback for
82
+ * the rare case the resolver produced nothing meaningful.
83
+ */
84
+ seedProjectName(name) {
85
+ this.outputParser.seedProjectName(name);
86
+ }
79
87
  getProjectName() {
80
88
  return this.outputParser.getProjectName();
81
89
  }
@@ -1 +1 @@
1
- {"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../src/adapters/claude-code.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAErC,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C;;;GAGG;AACH,MAAM,OAAO,iBAAkB,SAAQ,UAAU;IACtC,YAAY,GAAsB,wBAAwB,CAAC;IAE5D,YAAY,CAAe;IACnC,2BAA2B;IACnB,kBAAkB,GAAG,CAAC,CAAC;IAE/B;QACE,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,YAAY,GAAG,IAAI,YAAY,EAAE,CAAC;IACzC,CAAC;IAES,iBAAiB;QACzB,OAAO,QAAQ,CAAC;IAClB,CAAC;IAES,gBAAgB;QACxB,gCAAgC;QAChC,MAAM,YAAY,GAAG;YACnB,eAAe;YACf,cAAc;YACd,mBAAmB;YACnB,eAAe;YACf,aAAa;YACb,MAAM;YACN,aAAa;YACb,aAAa;YACb,cAAc;YACd,YAAY;YACZ,aAAa;YACb,kBAAkB;YAClB,YAAY;SACb,CAAC;QACF,KAAK,MAAM,SAAS,IAAI,YAAY,EAAE,CAAC;YACrC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,IAA8B,EAAE,EAAE;gBACjE,IAAI,CAAC,gBAAgB,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACtE,CAAC,CAAC,CAAC;QACL,CAAC;QAED,2BAA2B;QAC3B,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,eAAe,EAAE,CAAC,IAA8B,EAAE,EAAE;YACvE,IAAI,CAAC,gBAAgB,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC;QAC1F,CAAC,CAAC,CAAC;QAEH,wBAAwB;QACxB,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,IAA8B,EAAE,EAAE;YACpE,IAAI,IAAI,EAAE,CAAC;gBACT,IAAI,CAAC,gBAAgB,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;YAC3E,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,yBAAyB;QACzB,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC,IAA8B,EAAE,EAAE;YACrE,MAAM,IAAI,GAAG,IAAI,EAAE,IAA0B,CAAC;YAC9C,IAAI,IAAI,EAAE,CAAC;gBACT,IAAI,CAAC,gBAAgB,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;YACtF,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAES,UAAU,CAAC,IAAY;QAC/B,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAES,kBAAkB,CAAC,GAAkB;QAC7C,IAAI,GAAG,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;YAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACvB,IAAI,GAAG,GAAG,IAAI,CAAC,kBAAkB,GAAG,GAAG,EAAE,CAAC;gBACxC,KAAK,CAAC,gBAAgB,EAAE,2BAA2B,GAAG,GAAG,IAAI,CAAC,kBAAkB,aAAa,CAAC,CAAC;gBAC/F,OAAO,IAAI,CAAC;YACd,CAAC;YACD,IAAI,CAAC,kBAAkB,GAAG,GAAG,CAAC;YAC9B,KAAK,CAAC,gBAAgB,EAAE,gCAAgC,CAAC,CAAC;YAC1D,IAAI,CAAC,YAAY,CAAC,oBAAoB,EAAE,CAAC;YACzC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAChC,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAEQ,cAAc;QACrB,OAAO,IAAI,CAAC,YAAY,CAAC,cAAc,EAAE,CAAC;IAC5C,CAAC;IAEQ,oBAAoB;QAC3B,IAAI,CAAC,YAAY,CAAC,wBAAwB,EAAE,CAAC;IAC/C,CAAC;IAED,+EAA+E;IAC/E,mBAAmB;QACjB,OAAO,IAAI,CAAC,aAAa,EAAE,CAAC;IAC9B,CAAC;CACF"}
1
+ {"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../src/adapters/claude-code.ts"],"names":[],"mappings":"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"}
@@ -45,11 +45,34 @@ export declare class OpenClawAdapter extends EventEmitter implements AgentAdapte
45
45
  private chatIsAutomated;
46
46
  private deviceIdentity;
47
47
  private deviceAuthToken;
48
+ private sharedGatewayToken;
49
+ private disableDeviceAuthForNextConnect;
50
+ private apmeSessionId;
51
+ private apmeTraceId;
52
+ private apmeCwdHint;
53
+ /** Idle-gap timer — fires the `task_boundary` (idle_gap) span when the
54
+ * user hasn't sent a new `chat.send` for OPENCLAW_IDLE_GAP_MS after the
55
+ * last `chat.final`. Reset on every new send, cleared on session end. */
56
+ private apmeIdleTimer;
48
57
  /** Reconnect delay (doubles on each failure, max 30s) */
49
58
  private reconnectDelay;
50
59
  private static readonly MAX_RECONNECT_DELAY;
51
60
  private static readonly RPC_TIMEOUT;
52
61
  constructor(options?: string | OpenClawAdapterOptions);
62
+ /** Bind the adapter to an APME session id so Gateway events can be
63
+ * ingested as TelemetrySpans. No-op when APME isn't initialized. */
64
+ setApmeSession(sessionId: string, cwd?: string): void;
65
+ /** True when this adapter pipes Gateway events into the APME collector
66
+ * itself — the bridge must then NOT also convert its timeline entries to
67
+ * spans, or every turn and tool would be counted twice. */
68
+ hasDirectApmeIngestion(): boolean;
69
+ private buildApmeCtx;
70
+ private ingestApmeSpans;
71
+ /** Reset (or start) the idle-gap timer. Fires
72
+ * `openclawIdleGapTaskBoundary` after OPENCLAW_IDLE_GAP_MS of silence
73
+ * (no new `chat.send`) following the last `chat.final`. */
74
+ private armIdleGapTimer;
75
+ private clearIdleGapTimer;
53
76
  start(options: AdapterStartOptions & {
54
77
  externalServer?: Server;
55
78
  }): Promise<void>;
@@ -64,6 +87,7 @@ export declare class OpenClawAdapter extends EventEmitter implements AgentAdapte
64
87
  onRawData(callback: (data: string) => void): void;
65
88
  shutdown(): Promise<void>;
66
89
  private loadDeviceIdentity;
90
+ private loadSharedGatewayToken;
67
91
  /** Extract raw 32-byte Ed25519 public key from PEM → base64url */
68
92
  private getPublicKeyBase64Url;
69
93
  /** Build signed device auth for connect request */
@@ -1 +1 @@
1
- {"version":3,"file":"openclaw.d.ts","sourceRoot":"","sources":["../../src/adapters/openclaw.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"openclaw.d.ts","sourceRoot":"","sources":["../../src/adapters/openclaw.ts"],"names":[],"mappings":"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"}
@@ -5,11 +5,46 @@ import { join } from 'path';
5
5
  import { homedir } from 'os';
6
6
  import { createPublicKey, createPrivateKey, sign as cryptoSign, randomUUID } from 'crypto';
7
7
  import WebSocket from 'ws';
8
- import { debug } from '../logger.js';
9
- import { summarizeResponse, extractTopicHint } from '../timeline-summarizer.js';
10
- import { cleanDetailText, cleanRawText, cleanNopMarkers, ED25519_SPKI_PREFIX_LEN, GATEWAY_PROTOCOL_VERSION, } from '@agentdeck/shared';
8
+ import { debug, logError } from '../logger.js';
9
+ import { summarizeResponse } from '../timeline-summarizer.js';
10
+ import { extractTopicHint, extractTopicHintWithKind, promptSnippetFallback, prepareMarkdownDetail } from '@agentdeck/shared';
11
+ import { cleanRawText, cleanNopMarkers, isOpenClawCronPrompt, ED25519_SPKI_PREFIX_LEN, GATEWAY_PROTOCOL_VERSION, } from '@agentdeck/shared';
11
12
  import { OPENCLAW_CAPABILITIES, OPENCLAW_GATEWAY_PORT } from '../types.js';
12
13
  import { fetchModelCatalog, getDefaultModelName, invalidateModelCache } from '../model-catalog.js';
14
+ import { getApme } from '../apme/index.js';
15
+ import { openclawChatEventToSpans, openclawChatSendToSpan, openclawIdleGapTaskBoundary, openclawSessionToolToSpans, openclawSessionMessageToSpans, OPENCLAW_IDLE_GAP_MS, } from '../apme/adapters/openclaw-hook.js';
16
+ function extractGatewayTokenFromJson(json) {
17
+ if (!json || typeof json !== 'object')
18
+ return null;
19
+ const readPath = (root, path) => {
20
+ let current = root;
21
+ for (const [index, key] of path.entries()) {
22
+ if (!current || typeof current !== 'object' || Array.isArray(current))
23
+ return null;
24
+ const next = current[key];
25
+ if (next == null)
26
+ return null;
27
+ if (index === path.length - 1) {
28
+ if (typeof next !== 'string')
29
+ return null;
30
+ const trimmed = next.trim();
31
+ return trimmed || null;
32
+ }
33
+ current = next;
34
+ }
35
+ return null;
36
+ };
37
+ for (const path of [
38
+ ['gateway', 'auth', 'token'],
39
+ ['auth', 'token'],
40
+ ['gateway', 'token'],
41
+ ]) {
42
+ const token = readPath(json, path);
43
+ if (token)
44
+ return token;
45
+ }
46
+ return null;
47
+ }
13
48
  export class OpenClawAdapter extends EventEmitter {
14
49
  capabilities = OPENCLAW_CAPABILITIES;
15
50
  gatewayUrl;
@@ -41,6 +76,20 @@ export class OpenClawAdapter extends EventEmitter {
41
76
  // Device identity (loaded once on start)
42
77
  deviceIdentity = null;
43
78
  deviceAuthToken = null;
79
+ sharedGatewayToken = null;
80
+ disableDeviceAuthForNextConnect = false;
81
+ // APME bridge — set by `setApmeSession`. OpenClaw has no hook layer; the
82
+ // Gateway WS stream is the only event source. Without this APME wiring,
83
+ // OpenClaw sessions land in the runs table but fall through to a single
84
+ // `session_end` task boundary per session, collapsing all conversations
85
+ // into one "task" and defeating per-task evaluation.
86
+ apmeSessionId = null;
87
+ apmeTraceId = randomUUID();
88
+ apmeCwdHint;
89
+ /** Idle-gap timer — fires the `task_boundary` (idle_gap) span when the
90
+ * user hasn't sent a new `chat.send` for OPENCLAW_IDLE_GAP_MS after the
91
+ * last `chat.final`. Reset on every new send, cleared on session end. */
92
+ apmeIdleTimer = null;
44
93
  /** Reconnect delay (doubles on each failure, max 30s) */
45
94
  reconnectDelay = 1000;
46
95
  static MAX_RECONNECT_DELAY = 30_000;
@@ -92,6 +141,73 @@ export class OpenClawAdapter extends EventEmitter {
92
141
  res.end(JSON.stringify({ error: 'Not found' }));
93
142
  });
94
143
  }
144
+ /** Bind the adapter to an APME session id so Gateway events can be
145
+ * ingested as TelemetrySpans. No-op when APME isn't initialized. */
146
+ setApmeSession(sessionId, cwd) {
147
+ this.apmeSessionId = sessionId;
148
+ this.apmeCwdHint = cwd;
149
+ }
150
+ /** True when this adapter pipes Gateway events into the APME collector
151
+ * itself — the bridge must then NOT also convert its timeline entries to
152
+ * spans, or every turn and tool would be counted twice. */
153
+ hasDirectApmeIngestion() {
154
+ return this.apmeSessionId != null && getApme() != null;
155
+ }
156
+ buildApmeCtx() {
157
+ if (!this.apmeSessionId || !getApme())
158
+ return null;
159
+ return {
160
+ sessionId: this.apmeSessionId,
161
+ agentType: 'openclaw',
162
+ cwd: this.apmeCwdHint,
163
+ traceId: this.apmeTraceId,
164
+ activeTurnId: undefined,
165
+ };
166
+ }
167
+ ingestApmeSpans(spans) {
168
+ const apme = getApme();
169
+ if (!apme || !this.apmeSessionId || spans.length === 0)
170
+ return;
171
+ for (const span of spans) {
172
+ try {
173
+ apme.collector.ingestSpan(this.apmeSessionId, span);
174
+ }
175
+ catch (err) {
176
+ debug('apme:openclaw', `ingestSpan failed: ${String(err)}`);
177
+ }
178
+ }
179
+ }
180
+ /** Reset (or start) the idle-gap timer. Fires
181
+ * `openclawIdleGapTaskBoundary` after OPENCLAW_IDLE_GAP_MS of silence
182
+ * (no new `chat.send`) following the last `chat.final`. */
183
+ armIdleGapTimer() {
184
+ this.clearIdleGapTimer();
185
+ const ctx = this.buildApmeCtx();
186
+ if (!ctx)
187
+ return;
188
+ this.apmeIdleTimer = setTimeout(() => {
189
+ this.apmeIdleTimer = null;
190
+ const apme = getApme();
191
+ if (!apme || !this.apmeSessionId)
192
+ return;
193
+ const span = openclawIdleGapTaskBoundary(ctx);
194
+ try {
195
+ apme.collector.ingestSpan(this.apmeSessionId, span);
196
+ }
197
+ catch (err) {
198
+ debug('apme:openclaw', `idle_gap ingestSpan failed: ${String(err)}`);
199
+ }
200
+ }, OPENCLAW_IDLE_GAP_MS);
201
+ // Don't keep the event loop alive just for this timer; the adapter is
202
+ // already pinning the loop via WebSocket.
203
+ this.apmeIdleTimer.unref?.();
204
+ }
205
+ clearIdleGapTimer() {
206
+ if (this.apmeIdleTimer) {
207
+ clearTimeout(this.apmeIdleTimer);
208
+ this.apmeIdleTimer = null;
209
+ }
210
+ }
95
211
  async start(options) {
96
212
  if (options.gatewayUrl) {
97
213
  this.gatewayUrl = options.gatewayUrl;
@@ -178,6 +294,14 @@ export class OpenClawAdapter extends EventEmitter {
178
294
  this.emitAdapterEvent({ source: 'parser', event: 'spinner_start' });
179
295
  }
180
296
  if (this.currentSessionKey) {
297
+ // APME: open a turn. The matching `turn_response` lands on
298
+ // `chat.final` below. Cancel any pending idle-gap timer — a new
299
+ // send means the conversation is still active.
300
+ const ctx = this.buildApmeCtx();
301
+ if (ctx) {
302
+ this.clearIdleGapTimer();
303
+ this.ingestApmeSpans([openclawChatSendToSpan(ctx, cmd.text)]);
304
+ }
181
305
  this.rpcCall('chat.send', {
182
306
  sessionKey: this.currentSessionKey,
183
307
  message: cmd.text,
@@ -279,6 +403,8 @@ export class OpenClawAdapter extends EventEmitter {
279
403
  clearTimeout(this.reconnectTimer);
280
404
  this.reconnectTimer = null;
281
405
  }
406
+ // Cancel any pending idle-gap timer so it doesn't fire after shutdown.
407
+ this.clearIdleGapTimer();
282
408
  for (const [id, pending] of this.pendingRpc) {
283
409
  pending.reject(new Error('Adapter shutting down'));
284
410
  this.pendingRpc.delete(id);
@@ -313,10 +439,21 @@ export class OpenClawAdapter extends EventEmitter {
313
439
  scopes: operatorToken.scopes,
314
440
  };
315
441
  }
442
+ this.sharedGatewayToken = this.loadSharedGatewayToken();
316
443
  debug('adapter:openclaw', `Device identity loaded: ${this.deviceIdentity.deviceId.slice(0, 16)}...`);
317
444
  }
318
445
  catch (err) {
319
446
  debug('adapter:openclaw', `Device identity not available: ${err}`);
447
+ this.sharedGatewayToken = this.loadSharedGatewayToken();
448
+ }
449
+ }
450
+ loadSharedGatewayToken() {
451
+ try {
452
+ const json = JSON.parse(readFileSync(join(homedir(), '.openclaw', 'openclaw.json'), 'utf-8'));
453
+ return extractGatewayTokenFromJson(json);
454
+ }
455
+ catch {
456
+ return null;
320
457
  }
321
458
  }
322
459
  /** Extract raw 32-byte Ed25519 public key from PEM → base64url */
@@ -335,9 +472,9 @@ export class OpenClawAdapter extends EventEmitter {
335
472
  }
336
473
  const signedAt = Date.now();
337
474
  const scopes = requestScopes.join(',');
338
- // v2|deviceId|clientId|clientMode|role|scopes|signedAtMs|token|nonce
475
+ // v3|deviceId|clientId|clientMode|role|scopes|signedAtMs|token|nonce|platform|deviceFamily
339
476
  const payload = [
340
- 'v2',
477
+ 'v3',
341
478
  this.deviceIdentity.deviceId,
342
479
  'gateway-client',
343
480
  'backend',
@@ -346,6 +483,8 @@ export class OpenClawAdapter extends EventEmitter {
346
483
  String(signedAt),
347
484
  authToken,
348
485
  nonce,
486
+ 'darwin',
487
+ 'mac',
349
488
  ].join('|');
350
489
  const privateKey = createPrivateKey(this.deviceIdentity.privateKeyPem);
351
490
  const signature = cryptoSign(null, Buffer.from(payload, 'utf8'), privateKey);
@@ -524,7 +663,15 @@ export class OpenClawAdapter extends EventEmitter {
524
663
  if (!this.chatStarted) {
525
664
  // Non-optimistic path: gateway-initiated chat (cron, web, etc.)
526
665
  this.chatStarted = true;
527
- this.chatIsAutomated = !this.lastPrompt;
666
+ // Automated when there's no user prompt (pure gateway-initiated
667
+ // cron/web run) OR when the prompt itself is a `[cron:…]` job
668
+ // injection. The bare `!lastPrompt` heuristic mis-flagged cron
669
+ // turns whose prompt reached the adapter as `[cron:…]` text (a
670
+ // stale lastPrompt left `automated:false`), so recurring cron
671
+ // status polls ("Still translating") escaped the 8h automated
672
+ // repetitive-dedup and stacked as N separate rows instead of one
673
+ // `×count` row.
674
+ this.chatIsAutomated = !this.lastPrompt || isOpenClawCronPrompt(this.lastPrompt);
528
675
  this.chatStartTime = Date.now();
529
676
  this.chatToolCount = 0;
530
677
  this.chatToolNames = [];
@@ -537,6 +684,7 @@ export class OpenClawAdapter extends EventEmitter {
537
684
  ts: Date.now(), type: 'chat_start', raw: promptRaw,
538
685
  ...(promptDetail ? { detail: promptDetail } : {}),
539
686
  ...(this.chatIsAutomated ? { automated: true } : {}),
687
+ startedAt: this.chatStartTime,
540
688
  });
541
689
  }
542
690
  else {
@@ -552,6 +700,7 @@ export class OpenClawAdapter extends EventEmitter {
552
700
  this.emitTimelineUpsert({
553
701
  ts: this.chatStartTime, type: 'chat_start',
554
702
  raw: cleanRawText(topicHint),
703
+ startedAt: this.chatStartTime,
555
704
  });
556
705
  }
557
706
  }
@@ -578,37 +727,75 @@ export class OpenClawAdapter extends EventEmitter {
578
727
  const finalText = this.extractMessageText(payload);
579
728
  const responseContent = (finalText || undefined)
580
729
  || (this.accumulatedResponse || undefined);
581
- // Emit chat_response for APME turn response capture
582
- if (responseContent) {
583
- const respRaw = responseContent.length > 500 ? responseContent.slice(0, 497) + '...' : responseContent;
584
- this.emitTimelineEntry({
585
- ts: Date.now(), type: 'chat_response',
586
- raw: cleanRawText(respRaw),
587
- detail: cleanDetailText(responseContent.slice(0, 3000)),
588
- });
589
- }
590
- const cleanedResponse = responseContent ? cleanNopMarkers(cleanDetailText(responseContent)) : undefined;
730
+ const cleanedResponse = responseContent ? cleanNopMarkers(prepareMarkdownDetail(responseContent)) : undefined;
591
731
  const responseDetail = cleanedResponse
592
732
  ? (cleanedResponse.length > 1000 ? cleanedResponse.slice(0, 997) + '...' : cleanedResponse)
593
733
  : undefined;
594
- // Emit chat_end with heuristic summary, then async LLM enrichment
595
- const heuristicLabel = (responseContent && extractTopicHint(responseContent)) || 'Completed';
734
+ // Pick the turn-close summary label. Same kind-classification rule
735
+ // as wireClaudeCodeTimeline: 'topic' hint \u2192 heuristic, fallback /
736
+ // "Completed" \u2192 'none' so clients can suppress the
737
+ // (likely-redundant) detail pane.
738
+ const respHint = responseContent ? extractTopicHintWithKind(responseContent) : { hint: null, kind: null };
739
+ const promptHint = this.lastPrompt ? extractTopicHintWithKind(this.lastPrompt) : { hint: null, kind: null };
740
+ let heuristicLabel;
741
+ let summaryKind;
742
+ if (respHint.kind === 'topic' && respHint.hint) {
743
+ heuristicLabel = respHint.hint;
744
+ summaryKind = 'heuristic';
745
+ }
746
+ else if (promptHint.kind === 'topic' && promptHint.hint) {
747
+ heuristicLabel = promptHint.hint;
748
+ summaryKind = 'heuristic';
749
+ }
750
+ else if (respHint.hint || promptHint.hint) {
751
+ heuristicLabel = (respHint.hint || promptHint.hint);
752
+ summaryKind = 'none';
753
+ }
754
+ else {
755
+ heuristicLabel = promptSnippetFallback(this.lastPrompt, 60) ?? 'Completed';
756
+ summaryKind = 'none';
757
+ }
596
758
  const parts = [heuristicLabel];
597
759
  if (duration > 0)
598
760
  parts.push(`${duration}s`);
599
761
  if (toolSummary)
600
762
  parts.push(toolSummary);
601
763
  const chatEndTs = Date.now();
602
- this.emitTimelineEntry({
603
- ts: chatEndTs, type: 'chat_end', raw: parts.join(' \u00b7 '),
604
- ...(responseDetail ? { detail: responseDetail } : {}),
605
- ...(this.chatIsAutomated ? { automated: true } : {}),
606
- });
607
- // Async LLM summarization — fire-and-forget, upsert chat_end when ready
608
- if (responseContent && responseContent.length > 30) {
764
+ // Single turn-close row — mirrors wireClaudeCodeTimeline's
765
+ // emitCompletion: `chat_response` when there is response text,
766
+ // `chat_end` only for response-less turns. Emitting both used to
767
+ // put the same response `detail` on two rows milliseconds apart,
768
+ // so every OpenClaw turn rendered twice on the flat surfaces.
769
+ if (responseContent) {
770
+ const respRaw = responseContent.length > 500 ? responseContent.slice(0, 497) + '...' : responseContent;
771
+ this.emitTimelineEntry({
772
+ ts: chatEndTs, type: 'chat_response',
773
+ raw: cleanRawText(respRaw),
774
+ detail: prepareMarkdownDetail(responseContent.slice(0, 3000)),
775
+ ...(this.chatIsAutomated ? { automated: true } : {}),
776
+ startedAt: this.chatStartTime,
777
+ endedAt: chatEndTs,
778
+ });
779
+ }
780
+ else {
781
+ this.emitTimelineEntry({
782
+ ts: chatEndTs, type: 'chat_end', raw: parts.join(' \u00b7 '),
783
+ ...(this.chatIsAutomated ? { automated: true } : {}),
784
+ startedAt: this.chatStartTime,
785
+ endedAt: chatEndTs,
786
+ summaryKind,
787
+ });
788
+ }
789
+ // Async LLM summarization — fire-and-forget, upserts the turn's
790
+ // chat_response raw with "summary · Ns · tools" (detail keeps the
791
+ // full response). Skipped for automated turns: their low-signal
792
+ // polling responses are dropped at storage time, and an upsert
793
+ // that finds no match falls through to addEntry — the enriched
794
+ // label would resurrect the dropped noise row.
795
+ if (responseContent && responseContent.length > 30 && !this.chatIsAutomated) {
609
796
  const savedToolSummary = toolSummary;
610
797
  const savedDuration = duration;
611
- const savedAutomated = this.chatIsAutomated;
798
+ const savedStartedAt = this.chatStartTime;
612
799
  summarizeResponse(responseContent).then((summary) => {
613
800
  if (summary) {
614
801
  const enrichedParts = [summary];
@@ -617,15 +804,38 @@ export class OpenClawAdapter extends EventEmitter {
617
804
  if (savedToolSummary)
618
805
  enrichedParts.push(savedToolSummary);
619
806
  debug('adapter:openclaw', `LLM summary: ${summary}`);
620
- // Upsert chat_end with LLM summary replacing "Completed"
621
807
  this.emitTimelineUpsert({
622
- ts: chatEndTs, type: 'chat_end',
808
+ ts: chatEndTs, type: 'chat_response',
623
809
  raw: enrichedParts.join(' \u00b7 '),
624
810
  ...(responseDetail ? { detail: responseDetail } : {}),
625
- ...(savedAutomated ? { automated: true } : {}),
811
+ startedAt: savedStartedAt,
812
+ endedAt: chatEndTs,
813
+ summaryKind: 'llm',
626
814
  });
627
815
  }
628
- }).catch(() => { });
816
+ }).catch((err) => {
817
+ // `summarizeResponse` itself swallows MLX/Ollama errors;
818
+ // this catches only post-summary upsert/closure throws.
819
+ // Backend-offline messaging is surfaced inside summarizeResponse.
820
+ logError(`[adapter:openclaw] post-summary upsert threw: ${String(err)}`);
821
+ });
822
+ }
823
+ // APME: emit turn_response + tool_result spans, then arm the
824
+ // idle-gap timer. If the user sends a new prompt within
825
+ // OPENCLAW_IDLE_GAP_MS the timer is cancelled (above in
826
+ // `send_prompt`); otherwise it fires `task_boundary` (idle_gap)
827
+ // and closes the task.
828
+ const apmeCtx = this.buildApmeCtx();
829
+ if (apmeCtx) {
830
+ const apmePayload = {
831
+ state: 'final',
832
+ ...(payload.runId ? { runId: payload.runId } : {}),
833
+ ...(payload.sessionKey ? { sessionKey: payload.sessionKey } : {}),
834
+ ...(responseContent ? { response: responseContent } : {}),
835
+ ...(Array.isArray(payload.tools) ? { tools: payload.tools } : {}),
836
+ };
837
+ this.ingestApmeSpans(openclawChatEventToSpans(apmeCtx, apmePayload));
838
+ this.armIdleGapTimer();
629
839
  }
630
840
  this.chatStarted = false;
631
841
  this.lastPrompt = null;
@@ -648,6 +858,18 @@ export class OpenClawAdapter extends EventEmitter {
648
858
  ...(abortDetail ? { detail: abortDetail } : {}),
649
859
  ...(this.chatIsAutomated ? { automated: true } : {}),
650
860
  });
861
+ // APME: emit task_boundary so the abort itself closes the task
862
+ // immediately \u2014 don't wait for the idle timer. The user
863
+ // explicitly stopped this turn.
864
+ const abortCtx = this.buildApmeCtx();
865
+ if (abortCtx) {
866
+ this.clearIdleGapTimer();
867
+ this.ingestApmeSpans(openclawChatEventToSpans(abortCtx, {
868
+ state: 'aborted',
869
+ ...(payload.runId ? { runId: payload.runId } : {}),
870
+ ...(payload.sessionKey ? { sessionKey: payload.sessionKey } : {}),
871
+ }));
872
+ }
651
873
  this.chatStarted = false;
652
874
  this.lastPrompt = null;
653
875
  this.accumulatedResponse = '';
@@ -742,6 +964,24 @@ export class OpenClawAdapter extends EventEmitter {
742
964
  debug('adapter:openclaw', 'Gateway shutdown event');
743
965
  this.emitAdapterEvent({ source: 'hook', event: 'SessionEnd', data: {} });
744
966
  break;
967
+ // ===== Granular session streams (previously dropped) =====
968
+ // `session.tool` carries per-tool input/output; `session.message` carries
969
+ // out-of-band (e.g. cron/automation) prompts & responses. Both were
970
+ // silently swallowed by the old default case, leaving the sample's tool
971
+ // trajectory empty of detail. Route them into the APME normalizer so the
972
+ // SessionSample captures the full tool-use trajectory (req #6).
973
+ case 'session.tool': {
974
+ const apmeCtx = this.buildApmeCtx();
975
+ if (apmeCtx)
976
+ this.ingestApmeSpans(openclawSessionToolToSpans(apmeCtx, payload));
977
+ break;
978
+ }
979
+ case 'session.message': {
980
+ const apmeCtx = this.buildApmeCtx();
981
+ if (apmeCtx)
982
+ this.ingestApmeSpans(openclawSessionMessageToSpans(apmeCtx, payload));
983
+ break;
984
+ }
745
985
  default:
746
986
  debug('adapter:openclaw', `Unhandled event: ${event}`);
747
987
  break;
@@ -758,7 +998,8 @@ export class OpenClawAdapter extends EventEmitter {
758
998
  // reconstructs the payload from request params for signature verification.
759
999
  const scopes = this.deviceAuthToken?.scopes
760
1000
  ?? ['operator.admin', 'operator.approvals', 'operator.read'];
761
- const authToken = this.deviceAuthToken?.token ?? '';
1001
+ const sharedToken = this.sharedGatewayToken ?? '';
1002
+ const deviceToken = this.deviceAuthToken?.token ?? '';
762
1003
  const params = {
763
1004
  minProtocol: GATEWAY_PROTOCOL_VERSION,
764
1005
  maxProtocol: GATEWAY_PROTOCOL_VERSION,
@@ -767,22 +1008,37 @@ export class OpenClawAdapter extends EventEmitter {
767
1008
  displayName: 'AgentDeck',
768
1009
  version: '0.3.0',
769
1010
  platform: process.platform,
1011
+ deviceFamily: 'mac',
770
1012
  mode: 'backend',
771
1013
  },
772
1014
  role: 'operator',
773
1015
  scopes,
774
1016
  caps: ['tool-events'],
775
1017
  };
776
- // Add device auth if identity is available
777
- if (this.deviceIdentity && this.deviceAuthToken) {
1018
+ // Add device auth if identity is available. Fallback mode suppresses all
1019
+ // device-derived credentials so the retry is token-only.
1020
+ if (this.deviceIdentity && this.deviceAuthToken && !this.disableDeviceAuthForNextConnect) {
778
1021
  try {
779
- params.device = this.buildDeviceAuth(nonce, scopes, authToken);
780
- params.auth = { token: authToken };
1022
+ params.device = this.buildDeviceAuth(nonce, scopes, sharedToken);
781
1023
  }
782
1024
  catch (err) {
783
1025
  debug('adapter:openclaw', `Device auth signing failed: ${err}`);
784
1026
  }
785
1027
  }
1028
+ const auth = {};
1029
+ if (sharedToken)
1030
+ auth.token = sharedToken;
1031
+ if (deviceToken && !this.disableDeviceAuthForNextConnect) {
1032
+ auth.deviceToken = deviceToken;
1033
+ }
1034
+ if (Object.keys(auth).length > 0) {
1035
+ params.auth = auth;
1036
+ }
1037
+ debug('adapter:openclaw', `connect.RPC: fallback=${this.disableDeviceAuthForNextConnect}` +
1038
+ ` hasDevice=${params.device != null}` +
1039
+ ` hasSharedToken=${!!auth.token}` +
1040
+ ` hasDeviceToken=${!!auth.deviceToken}` +
1041
+ ` scopes=${scopes.length}`);
786
1042
  const id = 'init-1';
787
1043
  const message = { type: 'req', id, method: 'connect', params };
788
1044
  this.pendingRpc.set(id, {