@agentdeck/bridge 0.1.0 → 0.2.1

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 (384) hide show
  1. package/LICENSE +21 -0
  2. package/dist/adapters/claude-code.d.ts +11 -27
  3. package/dist/adapters/claude-code.d.ts.map +1 -1
  4. package/dist/adapters/claude-code.js +29 -123
  5. package/dist/adapters/claude-code.js.map +1 -1
  6. package/dist/adapters/codex-cli.d.ts +21 -0
  7. package/dist/adapters/codex-cli.d.ts.map +1 -0
  8. package/dist/adapters/codex-cli.js +53 -0
  9. package/dist/adapters/codex-cli.js.map +1 -0
  10. package/dist/adapters/index.d.ts +4 -0
  11. package/dist/adapters/index.d.ts.map +1 -1
  12. package/dist/adapters/index.js +13 -0
  13. package/dist/adapters/index.js.map +1 -1
  14. package/dist/adapters/monitor.d.ts +34 -0
  15. package/dist/adapters/monitor.d.ts.map +1 -0
  16. package/dist/adapters/monitor.js +86 -0
  17. package/dist/adapters/monitor.js.map +1 -0
  18. package/dist/adapters/openclaw.d.ts +36 -2
  19. package/dist/adapters/openclaw.d.ts.map +1 -1
  20. package/dist/adapters/openclaw.js +329 -59
  21. package/dist/adapters/openclaw.js.map +1 -1
  22. package/dist/adapters/opencode-adapter.d.ts +48 -0
  23. package/dist/adapters/opencode-adapter.d.ts.map +1 -0
  24. package/dist/adapters/opencode-adapter.js +345 -0
  25. package/dist/adapters/opencode-adapter.js.map +1 -0
  26. package/dist/adapters/pty-adapter.d.ts +56 -0
  27. package/dist/adapters/pty-adapter.d.ts.map +1 -0
  28. package/dist/adapters/pty-adapter.js +143 -0
  29. package/dist/adapters/pty-adapter.js.map +1 -0
  30. package/dist/adb-reverse.d.ts +25 -0
  31. package/dist/adb-reverse.d.ts.map +1 -0
  32. package/dist/adb-reverse.js +129 -0
  33. package/dist/adb-reverse.js.map +1 -0
  34. package/dist/antigravity-local.d.ts +7 -0
  35. package/dist/antigravity-local.d.ts.map +1 -0
  36. package/dist/antigravity-local.js +153 -0
  37. package/dist/antigravity-local.js.map +1 -0
  38. package/dist/apme/adapters/claude-hook.d.ts +15 -0
  39. package/dist/apme/adapters/claude-hook.d.ts.map +1 -0
  40. package/dist/apme/adapters/claude-hook.js +85 -0
  41. package/dist/apme/adapters/claude-hook.js.map +1 -0
  42. package/dist/apme/adapters/claude-pty.d.ts +28 -0
  43. package/dist/apme/adapters/claude-pty.d.ts.map +1 -0
  44. package/dist/apme/adapters/claude-pty.js +88 -0
  45. package/dist/apme/adapters/claude-pty.js.map +1 -0
  46. package/dist/apme/adapters/timeline.d.ts +16 -0
  47. package/dist/apme/adapters/timeline.d.ts.map +1 -0
  48. package/dist/apme/adapters/timeline.js +66 -0
  49. package/dist/apme/adapters/timeline.js.map +1 -0
  50. package/dist/apme/classifier.d.ts +53 -0
  51. package/dist/apme/classifier.d.ts.map +1 -0
  52. package/dist/apme/classifier.js +266 -0
  53. package/dist/apme/classifier.js.map +1 -0
  54. package/dist/apme/claude-transcript-reader.d.ts +38 -0
  55. package/dist/apme/claude-transcript-reader.d.ts.map +1 -0
  56. package/dist/apme/claude-transcript-reader.js +127 -0
  57. package/dist/apme/claude-transcript-reader.js.map +1 -0
  58. package/dist/apme/collector.d.ts +108 -0
  59. package/dist/apme/collector.d.ts.map +1 -0
  60. package/dist/apme/collector.js +659 -0
  61. package/dist/apme/collector.js.map +1 -0
  62. package/dist/apme/dashboard-html.d.ts +9 -0
  63. package/dist/apme/dashboard-html.d.ts.map +1 -0
  64. package/dist/apme/dashboard-html.js +416 -0
  65. package/dist/apme/dashboard-html.js.map +1 -0
  66. package/dist/apme/http.d.ts +19 -0
  67. package/dist/apme/http.d.ts.map +1 -0
  68. package/dist/apme/http.js +210 -0
  69. package/dist/apme/http.js.map +1 -0
  70. package/dist/apme/hw-sampler.d.ts +30 -0
  71. package/dist/apme/hw-sampler.d.ts.map +1 -0
  72. package/dist/apme/hw-sampler.js +106 -0
  73. package/dist/apme/hw-sampler.js.map +1 -0
  74. package/dist/apme/index.d.ts +43 -0
  75. package/dist/apme/index.d.ts.map +1 -0
  76. package/dist/apme/index.js +75 -0
  77. package/dist/apme/index.js.map +1 -0
  78. package/dist/apme/outcome.d.ts +48 -0
  79. package/dist/apme/outcome.d.ts.map +1 -0
  80. package/dist/apme/outcome.js +232 -0
  81. package/dist/apme/outcome.js.map +1 -0
  82. package/dist/apme/recommend.d.ts +32 -0
  83. package/dist/apme/recommend.d.ts.map +1 -0
  84. package/dist/apme/recommend.js +41 -0
  85. package/dist/apme/recommend.js.map +1 -0
  86. package/dist/apme/runner.d.ts +94 -0
  87. package/dist/apme/runner.d.ts.map +1 -0
  88. package/dist/apme/runner.js +812 -0
  89. package/dist/apme/runner.js.map +1 -0
  90. package/dist/apme/settings.d.ts +65 -0
  91. package/dist/apme/settings.d.ts.map +1 -0
  92. package/dist/apme/settings.js +97 -0
  93. package/dist/apme/settings.js.map +1 -0
  94. package/dist/apme/store.d.ts +99 -0
  95. package/dist/apme/store.d.ts.map +1 -0
  96. package/dist/apme/store.js +911 -0
  97. package/dist/apme/store.js.map +1 -0
  98. package/dist/apme/tuner.d.ts +64 -0
  99. package/dist/apme/tuner.d.ts.map +1 -0
  100. package/dist/apme/tuner.js +297 -0
  101. package/dist/apme/tuner.js.map +1 -0
  102. package/dist/apme/types.d.ts +11 -0
  103. package/dist/apme/types.d.ts.map +1 -0
  104. package/dist/apme/types.js +10 -0
  105. package/dist/apme/types.js.map +1 -0
  106. package/dist/auth.d.ts +1 -1
  107. package/dist/auth.d.ts.map +1 -1
  108. package/dist/auth.js +15 -5
  109. package/dist/auth.js.map +1 -1
  110. package/dist/bridge-core.d.ts +162 -0
  111. package/dist/bridge-core.d.ts.map +1 -0
  112. package/dist/bridge-core.js +627 -0
  113. package/dist/bridge-core.js.map +1 -0
  114. package/dist/check-deps.d.ts +3 -1
  115. package/dist/check-deps.d.ts.map +1 -1
  116. package/dist/check-deps.js +34 -13
  117. package/dist/check-deps.js.map +1 -1
  118. package/dist/cli.d.ts +3 -0
  119. package/dist/cli.d.ts.map +1 -0
  120. package/dist/cli.js +1235 -0
  121. package/dist/cli.js.map +1 -0
  122. package/dist/codex-auth.d.ts +10 -0
  123. package/dist/codex-auth.d.ts.map +1 -0
  124. package/dist/codex-auth.js +63 -0
  125. package/dist/codex-auth.js.map +1 -0
  126. package/dist/codex-output-parser.d.ts +21 -0
  127. package/dist/codex-output-parser.d.ts.map +1 -0
  128. package/dist/codex-output-parser.js +253 -0
  129. package/dist/codex-output-parser.js.map +1 -0
  130. package/dist/d200h/hid-protocol.d.ts +62 -0
  131. package/dist/d200h/hid-protocol.d.ts.map +1 -0
  132. package/dist/d200h/hid-protocol.js +124 -0
  133. package/dist/d200h/hid-protocol.js.map +1 -0
  134. package/dist/d200h/image-renderer.d.ts +36 -0
  135. package/dist/d200h/image-renderer.d.ts.map +1 -0
  136. package/dist/d200h/image-renderer.js +487 -0
  137. package/dist/d200h/image-renderer.js.map +1 -0
  138. package/dist/daemon-server.d.ts +19 -0
  139. package/dist/daemon-server.d.ts.map +1 -0
  140. package/dist/daemon-server.js +1168 -0
  141. package/dist/daemon-server.js.map +1 -0
  142. package/dist/daemon-ws-client.d.ts +82 -0
  143. package/dist/daemon-ws-client.d.ts.map +1 -0
  144. package/dist/daemon-ws-client.js +179 -0
  145. package/dist/daemon-ws-client.js.map +1 -0
  146. package/dist/daemon.d.ts +10 -0
  147. package/dist/daemon.d.ts.map +1 -0
  148. package/dist/daemon.js +56 -0
  149. package/dist/daemon.js.map +1 -0
  150. package/dist/display-monitor.d.ts +25 -0
  151. package/dist/display-monitor.d.ts.map +1 -0
  152. package/dist/display-monitor.js +143 -0
  153. package/dist/display-monitor.js.map +1 -0
  154. package/dist/esp32-serial.d.ts +112 -0
  155. package/dist/esp32-serial.d.ts.map +1 -0
  156. package/dist/esp32-serial.js +502 -0
  157. package/dist/esp32-serial.js.map +1 -0
  158. package/dist/gateway-probe.d.ts +12 -0
  159. package/dist/gateway-probe.d.ts.map +1 -0
  160. package/dist/gateway-probe.js +39 -0
  161. package/dist/gateway-probe.js.map +1 -0
  162. package/dist/hook-migration.d.ts +2 -0
  163. package/dist/hook-migration.d.ts.map +1 -0
  164. package/dist/hook-migration.js +104 -0
  165. package/dist/hook-migration.js.map +1 -0
  166. package/dist/hook-server.d.ts +29 -0
  167. package/dist/hook-server.d.ts.map +1 -1
  168. package/dist/hook-server.js +366 -8
  169. package/dist/hook-server.js.map +1 -1
  170. package/dist/index.d.ts +20 -2
  171. package/dist/index.d.ts.map +1 -1
  172. package/dist/index.js +1304 -562
  173. package/dist/index.js.map +1 -1
  174. package/dist/log-stream.d.ts +26 -0
  175. package/dist/log-stream.d.ts.map +1 -0
  176. package/dist/log-stream.js +111 -0
  177. package/dist/log-stream.js.map +1 -0
  178. package/dist/logger.d.ts +9 -2
  179. package/dist/logger.d.ts.map +1 -1
  180. package/dist/logger.js +36 -5
  181. package/dist/logger.js.map +1 -1
  182. package/dist/mdns.d.ts +15 -1
  183. package/dist/mdns.d.ts.map +1 -1
  184. package/dist/mdns.js +143 -28
  185. package/dist/mdns.js.map +1 -1
  186. package/dist/mlx-probe.d.ts +14 -0
  187. package/dist/mlx-probe.d.ts.map +1 -0
  188. package/dist/mlx-probe.js +44 -0
  189. package/dist/mlx-probe.js.map +1 -0
  190. package/dist/model-catalog.d.ts +5 -3
  191. package/dist/model-catalog.d.ts.map +1 -1
  192. package/dist/model-catalog.js +45 -29
  193. package/dist/model-catalog.js.map +1 -1
  194. package/dist/modules/adb-module.d.ts +14 -0
  195. package/dist/modules/adb-module.d.ts.map +1 -0
  196. package/dist/modules/adb-module.js +36 -0
  197. package/dist/modules/adb-module.js.map +1 -0
  198. package/dist/modules/d200h-module.d.ts +43 -0
  199. package/dist/modules/d200h-module.d.ts.map +1 -0
  200. package/dist/modules/d200h-module.js +360 -0
  201. package/dist/modules/d200h-module.js.map +1 -0
  202. package/dist/modules/d200h-renderer.d.ts +7 -0
  203. package/dist/modules/d200h-renderer.d.ts.map +1 -0
  204. package/dist/modules/d200h-renderer.js +321 -0
  205. package/dist/modules/d200h-renderer.js.map +1 -0
  206. package/dist/modules/index.d.ts +23 -0
  207. package/dist/modules/index.d.ts.map +1 -0
  208. package/dist/modules/index.js +65 -0
  209. package/dist/modules/index.js.map +1 -0
  210. package/dist/modules/mdns-module.d.ts +12 -0
  211. package/dist/modules/mdns-module.d.ts.map +1 -0
  212. package/dist/modules/mdns-module.js +21 -0
  213. package/dist/modules/mdns-module.js.map +1 -0
  214. package/dist/modules/pixoo-module.d.ts +8 -0
  215. package/dist/modules/pixoo-module.d.ts.map +1 -0
  216. package/dist/modules/pixoo-module.js +24 -0
  217. package/dist/modules/pixoo-module.js.map +1 -0
  218. package/dist/modules/serial-module.d.ts +18 -0
  219. package/dist/modules/serial-module.d.ts.map +1 -0
  220. package/dist/modules/serial-module.js +47 -0
  221. package/dist/modules/serial-module.js.map +1 -0
  222. package/dist/modules/types.d.ts +39 -0
  223. package/dist/modules/types.d.ts.map +1 -0
  224. package/dist/modules/types.js +2 -0
  225. package/dist/modules/types.js.map +1 -0
  226. package/dist/ollama-probe.d.ts +13 -0
  227. package/dist/ollama-probe.d.ts.map +1 -0
  228. package/dist/ollama-probe.js +46 -0
  229. package/dist/ollama-probe.js.map +1 -0
  230. package/dist/opencode-client.d.ts +126 -0
  231. package/dist/opencode-client.d.ts.map +1 -0
  232. package/dist/opencode-client.js +181 -0
  233. package/dist/opencode-client.js.map +1 -0
  234. package/dist/output-parser.d.ts +3 -0
  235. package/dist/output-parser.d.ts.map +1 -1
  236. package/dist/output-parser.js +29 -3
  237. package/dist/output-parser.js.map +1 -1
  238. package/dist/passive-observer.d.ts +38 -0
  239. package/dist/passive-observer.d.ts.map +1 -0
  240. package/dist/passive-observer.js +632 -0
  241. package/dist/passive-observer.js.map +1 -0
  242. package/dist/pixoo/pixoo-bridge.d.ts +50 -0
  243. package/dist/pixoo/pixoo-bridge.d.ts.map +1 -0
  244. package/dist/pixoo/pixoo-bridge.js +280 -0
  245. package/dist/pixoo/pixoo-bridge.js.map +1 -0
  246. package/dist/pixoo/pixoo-camera.d.ts +80 -0
  247. package/dist/pixoo/pixoo-camera.d.ts.map +1 -0
  248. package/dist/pixoo/pixoo-camera.js +271 -0
  249. package/dist/pixoo/pixoo-camera.js.map +1 -0
  250. package/dist/pixoo/pixoo-client.d.ts +67 -0
  251. package/dist/pixoo/pixoo-client.d.ts.map +1 -0
  252. package/dist/pixoo/pixoo-client.js +335 -0
  253. package/dist/pixoo/pixoo-client.js.map +1 -0
  254. package/dist/pixoo/pixoo-font.d.ts +24 -0
  255. package/dist/pixoo/pixoo-font.d.ts.map +1 -0
  256. package/dist/pixoo/pixoo-font.js +121 -0
  257. package/dist/pixoo/pixoo-font.js.map +1 -0
  258. package/dist/pixoo/pixoo-renderer.d.ts +32 -0
  259. package/dist/pixoo/pixoo-renderer.d.ts.map +1 -0
  260. package/dist/pixoo/pixoo-renderer.js +696 -0
  261. package/dist/pixoo/pixoo-renderer.js.map +1 -0
  262. package/dist/pixoo/pixoo-settings.d.ts +10 -0
  263. package/dist/pixoo/pixoo-settings.d.ts.map +1 -0
  264. package/dist/pixoo/pixoo-settings.js +47 -0
  265. package/dist/pixoo/pixoo-settings.js.map +1 -0
  266. package/dist/pixoo/pixoo-sprites.d.ts +187 -0
  267. package/dist/pixoo/pixoo-sprites.d.ts.map +1 -0
  268. package/dist/pixoo/pixoo-sprites.js +926 -0
  269. package/dist/pixoo/pixoo-sprites.js.map +1 -0
  270. package/dist/pty-manager.d.ts +1 -1
  271. package/dist/pty-manager.d.ts.map +1 -1
  272. package/dist/pty-manager.js +36 -15
  273. package/dist/pty-manager.js.map +1 -1
  274. package/dist/session-aggregator.d.ts +41 -0
  275. package/dist/session-aggregator.d.ts.map +1 -0
  276. package/dist/session-aggregator.js +76 -0
  277. package/dist/session-aggregator.js.map +1 -0
  278. package/dist/session-focus-relay.d.ts +35 -0
  279. package/dist/session-focus-relay.d.ts.map +1 -0
  280. package/dist/session-focus-relay.js +127 -0
  281. package/dist/session-focus-relay.js.map +1 -0
  282. package/dist/session-registry.d.ts +88 -1
  283. package/dist/session-registry.d.ts.map +1 -1
  284. package/dist/session-registry.js +222 -15
  285. package/dist/session-registry.js.map +1 -1
  286. package/dist/session-timeline-relay.d.ts +27 -0
  287. package/dist/session-timeline-relay.d.ts.map +1 -0
  288. package/dist/session-timeline-relay.js +124 -0
  289. package/dist/session-timeline-relay.js.map +1 -0
  290. package/dist/state-machine.d.ts +1 -0
  291. package/dist/state-machine.d.ts.map +1 -1
  292. package/dist/state-machine.js +14 -0
  293. package/dist/state-machine.js.map +1 -1
  294. package/dist/terminal-status.d.ts +28 -0
  295. package/dist/terminal-status.d.ts.map +1 -0
  296. package/dist/terminal-status.js +152 -0
  297. package/dist/terminal-status.js.map +1 -0
  298. package/dist/timeline-store.d.ts +22 -0
  299. package/dist/timeline-store.d.ts.map +1 -0
  300. package/dist/timeline-store.js +79 -0
  301. package/dist/timeline-store.js.map +1 -0
  302. package/dist/timeline-summarizer.d.ts +14 -0
  303. package/dist/timeline-summarizer.d.ts.map +1 -0
  304. package/dist/timeline-summarizer.js +154 -0
  305. package/dist/timeline-summarizer.js.map +1 -0
  306. package/dist/tts.d.ts +25 -0
  307. package/dist/tts.d.ts.map +1 -0
  308. package/dist/tts.js +99 -0
  309. package/dist/tts.js.map +1 -0
  310. package/dist/tui/ansi.d.ts +92 -0
  311. package/dist/tui/ansi.d.ts.map +1 -0
  312. package/dist/tui/ansi.js +181 -0
  313. package/dist/tui/ansi.js.map +1 -0
  314. package/dist/tui/dashboard.d.ts +35 -0
  315. package/dist/tui/dashboard.d.ts.map +1 -0
  316. package/dist/tui/dashboard.js +436 -0
  317. package/dist/tui/dashboard.js.map +1 -0
  318. package/dist/tui/gauge.d.ts +15 -0
  319. package/dist/tui/gauge.d.ts.map +1 -0
  320. package/dist/tui/gauge.js +82 -0
  321. package/dist/tui/gauge.js.map +1 -0
  322. package/dist/tui/renderer.d.ts +15 -0
  323. package/dist/tui/renderer.d.ts.map +1 -0
  324. package/dist/tui/renderer.js +758 -0
  325. package/dist/tui/renderer.js.map +1 -0
  326. package/dist/tui/screen.d.ts +27 -0
  327. package/dist/tui/screen.d.ts.map +1 -0
  328. package/dist/tui/screen.js +109 -0
  329. package/dist/tui/screen.js.map +1 -0
  330. package/dist/tui/terrarium.d.ts +96 -0
  331. package/dist/tui/terrarium.d.ts.map +1 -0
  332. package/dist/tui/terrarium.js +912 -0
  333. package/dist/tui/terrarium.js.map +1 -0
  334. package/dist/types.d.ts +4 -2
  335. package/dist/types.d.ts.map +1 -1
  336. package/dist/types.js +3 -2
  337. package/dist/types.js.map +1 -1
  338. package/dist/usage-api.d.ts +9 -2
  339. package/dist/usage-api.d.ts.map +1 -1
  340. package/dist/usage-api.js +224 -42
  341. package/dist/usage-api.js.map +1 -1
  342. package/dist/usage-event.d.ts +12 -0
  343. package/dist/usage-event.d.ts.map +1 -0
  344. package/dist/usage-event.js +78 -0
  345. package/dist/usage-event.js.map +1 -0
  346. package/dist/usage-tracker.d.ts +4 -0
  347. package/dist/usage-tracker.d.ts.map +1 -1
  348. package/dist/usage-tracker.js +17 -0
  349. package/dist/usage-tracker.js.map +1 -1
  350. package/dist/utility-proxy.d.ts +30 -0
  351. package/dist/utility-proxy.d.ts.map +1 -0
  352. package/dist/utility-proxy.js +217 -0
  353. package/dist/utility-proxy.js.map +1 -0
  354. package/dist/utils/project-name.d.ts +22 -0
  355. package/dist/utils/project-name.d.ts.map +1 -0
  356. package/dist/utils/project-name.js +72 -0
  357. package/dist/utils/project-name.js.map +1 -0
  358. package/dist/version-check.d.ts +26 -0
  359. package/dist/version-check.d.ts.map +1 -0
  360. package/dist/version-check.js +225 -0
  361. package/dist/version-check.js.map +1 -0
  362. package/dist/voice-assistant.d.ts +63 -0
  363. package/dist/voice-assistant.d.ts.map +1 -0
  364. package/dist/voice-assistant.js +406 -0
  365. package/dist/voice-assistant.js.map +1 -0
  366. package/dist/voice.d.ts +2 -0
  367. package/dist/voice.d.ts.map +1 -1
  368. package/dist/voice.js +26 -1
  369. package/dist/voice.js.map +1 -1
  370. package/dist/wake-word.d.ts +35 -0
  371. package/dist/wake-word.d.ts.map +1 -0
  372. package/dist/wake-word.js +225 -0
  373. package/dist/wake-word.js.map +1 -0
  374. package/dist/whisper-server-manager.d.ts +1 -1
  375. package/dist/whisper-server-manager.js +1 -1
  376. package/dist/wifi-config.d.ts +24 -0
  377. package/dist/wifi-config.d.ts.map +1 -0
  378. package/dist/wifi-config.js +84 -0
  379. package/dist/wifi-config.js.map +1 -0
  380. package/dist/ws-server.d.ts +12 -0
  381. package/dist/ws-server.d.ts.map +1 -1
  382. package/dist/ws-server.js +81 -3
  383. package/dist/ws-server.js.map +1 -1
  384. package/package.json +21 -13
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Terminal Status — lightweight terminal context display.
3
+ *
4
+ * Layer 1: Tab title (OSC 1) — "{project} · {model}"
5
+ * Layer 2: iTerm2 badge (OSC 1337 SetBadgeFormat) — post-it style, 2 lines
6
+ * Layer 3: iTerm2 user variables (OSC 1337 SetUserVar) — agentdeck_project/_model
7
+ *
8
+ * Badge sizing is pinned via a Dynamic Profile that inherits from the user's
9
+ * current profile; color adapts to macOS dark/light mode.
10
+ */
11
+ import type { StateSnapshot } from './types.js';
12
+ export declare class TerminalStatus {
13
+ private stdout;
14
+ private debounceTimer;
15
+ private inTmux;
16
+ private originalProfile;
17
+ private profileInstalled;
18
+ constructor(stdout: NodeJS.WritableStream);
19
+ update(snapshot: StateSnapshot): void;
20
+ cleanup(): void;
21
+ private installDynamicProfile;
22
+ private uninstallDynamicProfile;
23
+ private render;
24
+ private buildBadge;
25
+ private writeOsc;
26
+ private writeIterm;
27
+ }
28
+ //# sourceMappingURL=terminal-status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal-status.d.ts","sourceRoot":"","sources":["../src/terminal-status.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAiBhD,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAwB;IACtC,OAAO,CAAC,aAAa,CAA8C;IACnE,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,gBAAgB,CAAS;gBAErB,MAAM,EAAE,MAAM,CAAC,cAAc;IAMzC,MAAM,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI;IAKrC,OAAO,IAAI,IAAI;IAcf,OAAO,CAAC,qBAAqB;IA8C7B,OAAO,CAAC,uBAAuB;IAiB/B,OAAO,CAAC,MAAM;IAad,OAAO,CAAC,UAAU;IAQlB,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,UAAU;CAOnB"}
@@ -0,0 +1,152 @@
1
+ /**
2
+ * Terminal Status — lightweight terminal context display.
3
+ *
4
+ * Layer 1: Tab title (OSC 1) — "{project} · {model}"
5
+ * Layer 2: iTerm2 badge (OSC 1337 SetBadgeFormat) — post-it style, 2 lines
6
+ * Layer 3: iTerm2 user variables (OSC 1337 SetUserVar) — agentdeck_project/_model
7
+ *
8
+ * Badge sizing is pinned via a Dynamic Profile that inherits from the user's
9
+ * current profile; color adapts to macOS dark/light mode.
10
+ */
11
+ import { debug } from './logger.js';
12
+ import { writeFileSync, unlinkSync, mkdirSync } from 'node:fs';
13
+ import { join } from 'node:path';
14
+ import { homedir } from 'node:os';
15
+ import { execSync } from 'node:child_process';
16
+ const DYNAMIC_PROFILE_NAME = 'AgentDeck Postit';
17
+ const DYNAMIC_PROFILE_DIR = join(homedir(), 'Library', 'Application Support', 'iTerm2', 'DynamicProfiles');
18
+ const DYNAMIC_PROFILE_PATH = join(DYNAMIC_PROFILE_DIR, 'agentdeck.json');
19
+ const BADGE_MAX_WIDTH_FRACTION = 0.5;
20
+ const BADGE_MAX_HEIGHT_FRACTION = 0.1;
21
+ export class TerminalStatus {
22
+ stdout;
23
+ debounceTimer = null;
24
+ inTmux;
25
+ originalProfile = null;
26
+ profileInstalled = false;
27
+ constructor(stdout) {
28
+ this.stdout = stdout;
29
+ this.inTmux = !!process.env.TMUX;
30
+ this.installDynamicProfile();
31
+ }
32
+ update(snapshot) {
33
+ if (this.debounceTimer)
34
+ clearTimeout(this.debounceTimer);
35
+ this.debounceTimer = setTimeout(() => this.render(snapshot), 200);
36
+ }
37
+ cleanup() {
38
+ if (this.debounceTimer) {
39
+ clearTimeout(this.debounceTimer);
40
+ this.debounceTimer = null;
41
+ }
42
+ this.writeOsc('\x1b]1;\x07');
43
+ this.writeIterm('\x1b]1337;SetBadgeFormat=\x07');
44
+ this.writeIterm(`\x1b]1337;SetUserVar=agentdeck_project=${b64('')}\x07`);
45
+ this.writeIterm(`\x1b]1337;SetUserVar=agentdeck_model=${b64('')}\x07`);
46
+ this.uninstallDynamicProfile();
47
+ }
48
+ // ===== Dynamic Profile =====
49
+ installDynamicProfile() {
50
+ this.originalProfile = process.env.ITERM_PROFILE || null;
51
+ const parentName = this.originalProfile || 'Default';
52
+ const isDark = detectDarkMode();
53
+ const badgeColor = isDark
54
+ ? {
55
+ 'Red Component': 1.0,
56
+ 'Green Component': 0.8,
57
+ 'Blue Component': 0.3,
58
+ 'Alpha Component': 0.7,
59
+ }
60
+ : {
61
+ 'Red Component': 0.2,
62
+ 'Green Component': 0.25,
63
+ 'Blue Component': 0.35,
64
+ 'Alpha Component': 0.7,
65
+ };
66
+ const profile = {
67
+ Name: DYNAMIC_PROFILE_NAME,
68
+ Guid: 'agentdeck-postit-dynamic-profile',
69
+ 'Dynamic Profile Parent Name': parentName,
70
+ 'Badge Max Width': BADGE_MAX_WIDTH_FRACTION,
71
+ 'Badge Max Height': BADGE_MAX_HEIGHT_FRACTION,
72
+ 'Badge Top Margin': 10,
73
+ 'Badge Right Margin': 10,
74
+ 'Badge Color': { ...badgeColor, 'Color Space': 'sRGB' },
75
+ };
76
+ try {
77
+ mkdirSync(DYNAMIC_PROFILE_DIR, { recursive: true });
78
+ writeFileSync(DYNAMIC_PROFILE_PATH, JSON.stringify({ Profiles: [profile] }, null, 2));
79
+ setTimeout(() => {
80
+ this.writeIterm(`\x1b]1337;SetProfile=${DYNAMIC_PROFILE_NAME}\x07`);
81
+ }, 300);
82
+ this.profileInstalled = true;
83
+ debug('postit', `Dynamic profile installed, parent="${parentName}", dark=${isDark}`);
84
+ }
85
+ catch (err) {
86
+ debug('postit', `Failed to install dynamic profile: ${err}`);
87
+ }
88
+ }
89
+ uninstallDynamicProfile() {
90
+ if (this.originalProfile) {
91
+ this.writeIterm(`\x1b]1337;SetProfile=${this.originalProfile}\x07`);
92
+ }
93
+ if (this.profileInstalled) {
94
+ try {
95
+ unlinkSync(DYNAMIC_PROFILE_PATH);
96
+ debug('postit', 'Dynamic profile removed');
97
+ }
98
+ catch {
99
+ // File may already be gone
100
+ }
101
+ this.profileInstalled = false;
102
+ }
103
+ }
104
+ // ===== Render =====
105
+ render(snapshot) {
106
+ const project = snapshot.projectName ?? 'AgentDeck';
107
+ const model = snapshot.modelName ?? '';
108
+ const title = model ? `${project} · ${model}` : project;
109
+ this.writeOsc(`\x1b]1;${title}\x07`);
110
+ this.writeIterm(`\x1b]1337;SetBadgeFormat=${b64(this.buildBadge(project, model))}\x07`);
111
+ this.writeIterm(`\x1b]1337;SetUserVar=agentdeck_project=${b64(project)}\x07`);
112
+ this.writeIterm(`\x1b]1337;SetUserVar=agentdeck_model=${b64(model)}\x07`);
113
+ }
114
+ buildBadge(project, model) {
115
+ const lines = [`📂 ${project}`];
116
+ if (model)
117
+ lines.push(model);
118
+ // Pad to 3 lines with braille blank — keeps badge height stable when model is absent.
119
+ while (lines.length < 3)
120
+ lines.push('\u2800');
121
+ return lines.join('\n');
122
+ }
123
+ writeOsc(seq) {
124
+ this.stdout.write(seq);
125
+ }
126
+ writeIterm(seq) {
127
+ if (this.inTmux) {
128
+ this.stdout.write(`\x1bPtmux;\x1b${seq}\x1b\\`);
129
+ }
130
+ else {
131
+ this.stdout.write(seq);
132
+ }
133
+ }
134
+ }
135
+ function b64(s) {
136
+ return Buffer.from(s, 'utf-8').toString('base64');
137
+ }
138
+ function detectDarkMode() {
139
+ try {
140
+ const result = execSync('defaults read -g AppleInterfaceStyle', {
141
+ encoding: 'utf-8',
142
+ timeout: 1000,
143
+ stdio: ['pipe', 'pipe', 'pipe'],
144
+ }).trim();
145
+ return result === 'Dark';
146
+ }
147
+ catch {
148
+ // Command fails when in light mode (key doesn't exist) — default to dark
149
+ return true;
150
+ }
151
+ }
152
+ //# sourceMappingURL=terminal-status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal-status.js","sourceRoot":"","sources":["../src/terminal-status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Bridge-side timeline store — minimal server-side event buffer.
3
+ * Stores recent timeline entries for relay to Android/plugin clients.
4
+ * No scroll/grouping logic (that's client-side).
5
+ */
6
+ import type { TimelineEntry } from './types.js';
7
+ type EntryListener = (entry: TimelineEntry, upsert?: boolean) => void;
8
+ export declare class BridgeTimelineStore {
9
+ private entries;
10
+ private listeners;
11
+ addEntry(entry: TimelineEntry): void;
12
+ getHistory(since?: number): TimelineEntry[];
13
+ updateEntryStatus(approvalId: string, status: 'approved' | 'denied'): void;
14
+ /** Update existing entry with same ts+type (1s tolerance), or add new */
15
+ upsertEntry(entry: TimelineEntry): void;
16
+ /** Get the most recent entry of a given type */
17
+ getLastEntry(type: string): TimelineEntry | null;
18
+ onEntry(cb: EntryListener): void;
19
+ removeListener(cb: EntryListener): void;
20
+ }
21
+ export {};
22
+ //# sourceMappingURL=timeline-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timeline-store.d.ts","sourceRoot":"","sources":["../src/timeline-store.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGhD,KAAK,aAAa,GAAG,CAAC,KAAK,EAAE,aAAa,EAAE,MAAM,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;AAItE,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,SAAS,CAAuB;IAExC,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAwBpC,UAAU,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,aAAa,EAAE;IAO3C,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,QAAQ,GAAG,IAAI;IAS1E,yEAAyE;IACzE,WAAW,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAavC,gDAAgD;IAChD,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI;IAOhD,OAAO,CAAC,EAAE,EAAE,aAAa,GAAG,IAAI;IAIhC,cAAc,CAAC,EAAE,EAAE,aAAa,GAAG,IAAI;CAIxC"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Bridge-side timeline store — minimal server-side event buffer.
3
+ * Stores recent timeline entries for relay to Android/plugin clients.
4
+ * No scroll/grouping logic (that's client-side).
5
+ */
6
+ import { deduplicateEntry } from '@agentdeck/shared';
7
+ const MAX_ENTRIES = 200;
8
+ export class BridgeTimelineStore {
9
+ entries = [];
10
+ listeners = [];
11
+ addEntry(entry) {
12
+ const result = deduplicateEntry(entry, this.entries);
13
+ if (result.action === 'skip')
14
+ return;
15
+ if (result.action === 'merge') {
16
+ const existing = this.entries[result.index];
17
+ existing.repeatCount = (existing.repeatCount || 1) + 1;
18
+ existing.ts = entry.ts;
19
+ if (result.removeChatStartIndex != null) {
20
+ this.entries.splice(result.removeChatStartIndex, 1);
21
+ }
22
+ for (const cb of this.listeners)
23
+ cb(existing, true);
24
+ return;
25
+ }
26
+ // action === 'add'
27
+ this.entries.push(result.entry);
28
+ if (this.entries.length > MAX_ENTRIES) {
29
+ this.entries.shift();
30
+ }
31
+ for (const cb of this.listeners)
32
+ cb(result.entry);
33
+ }
34
+ getHistory(since) {
35
+ if (since) {
36
+ return this.entries.filter((e) => e.ts > since);
37
+ }
38
+ return [...this.entries];
39
+ }
40
+ updateEntryStatus(approvalId, status) {
41
+ for (let i = this.entries.length - 1; i >= 0; i--) {
42
+ if (this.entries[i].approvalId === approvalId) {
43
+ this.entries[i] = { ...this.entries[i], status };
44
+ return;
45
+ }
46
+ }
47
+ }
48
+ /** Update existing entry with same ts+type (1s tolerance), or add new */
49
+ upsertEntry(entry) {
50
+ const tolerance = 1000;
51
+ for (let i = this.entries.length - 1; i >= 0; i--) {
52
+ 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 } : {}) };
55
+ for (const cb of this.listeners)
56
+ cb(this.entries[i], true);
57
+ return;
58
+ }
59
+ }
60
+ this.addEntry(entry);
61
+ }
62
+ /** Get the most recent entry of a given type */
63
+ getLastEntry(type) {
64
+ for (let i = this.entries.length - 1; i >= 0; i--) {
65
+ if (this.entries[i].type === type)
66
+ return this.entries[i];
67
+ }
68
+ return null;
69
+ }
70
+ onEntry(cb) {
71
+ this.listeners.push(cb);
72
+ }
73
+ removeListener(cb) {
74
+ const idx = this.listeners.indexOf(cb);
75
+ if (idx !== -1)
76
+ this.listeners.splice(idx, 1);
77
+ }
78
+ }
79
+ //# sourceMappingURL=timeline-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timeline-store.js","sourceRoot":"","sources":["../src/timeline-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Timeline summarizer — uses local LLM to create concise 1-line summaries
3
+ * of OpenClaw chat responses for timeline display.
4
+ *
5
+ * Tries: local mlx-serve qwen (port 8800) → Ollama → heuristic fallback.
6
+ * Non-blocking — caller should fire-and-forget, update entry when ready.
7
+ */
8
+ export { extractTopicHint } from '@agentdeck/shared';
9
+ /**
10
+ * Summarize a chat response into a concise 1-line Korean summary.
11
+ * Returns null if summarization fails (caller should use fallback).
12
+ */
13
+ export declare function summarizeResponse(text: string): Promise<string | null>;
14
+ //# sourceMappingURL=timeline-summarizer.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,154 @@
1
+ /**
2
+ * Timeline summarizer — uses local LLM to create concise 1-line summaries
3
+ * of OpenClaw chat responses for timeline display.
4
+ *
5
+ * Tries: local mlx-serve qwen (port 8800) → Ollama → heuristic fallback.
6
+ * Non-blocking — caller should fire-and-forget, update entry when ready.
7
+ */
8
+ import { debug } from './logger.js';
9
+ import { SUMMARY_SYSTEM_PROMPT, cleanLLMOutput, mlxChatUrl, resolveMlxModel } from '@agentdeck/shared';
10
+ import { fetchMlxModels } from './mlx-probe.js';
11
+ export { extractTopicHint } from '@agentdeck/shared';
12
+ const MLX_URL = mlxChatUrl();
13
+ // In-memory cache of the probe's first result, so summarizers don't hit
14
+ // /v1/models on every call. Refreshed lazily when the model call fails.
15
+ let probedFirstModel = null;
16
+ let probedAt = 0;
17
+ const PROBE_CACHE_TTL_MS = 60_000;
18
+ async function resolveModelForCall() {
19
+ const now = Date.now();
20
+ if (!probedFirstModel || now - probedAt > PROBE_CACHE_TTL_MS) {
21
+ try {
22
+ const models = await fetchMlxModels();
23
+ probedFirstModel = models && models.length > 0 ? models[0] : null;
24
+ probedAt = now;
25
+ }
26
+ catch {
27
+ probedFirstModel = null;
28
+ }
29
+ }
30
+ return resolveMlxModel(probedFirstModel);
31
+ }
32
+ const OLLAMA_URL = 'http://localhost:11434/api/chat';
33
+ const TIMEOUT_MS = 30_000; // 30s — first inference needs model load time
34
+ const MAX_INPUT_CHARS = 2000;
35
+ let mlxAvailable = null;
36
+ let ollamaAvailable = null;
37
+ let mlxFailedAt = 0;
38
+ let ollamaFailedAt = 0;
39
+ const RETRY_INTERVAL_MS = 60_000; // retry failed providers after 60s
40
+ /**
41
+ * Summarize a chat response into a concise 1-line Korean summary.
42
+ * Returns null if summarization fails (caller should use fallback).
43
+ */
44
+ export async function summarizeResponse(text) {
45
+ if (!text || text.length < 20)
46
+ return null;
47
+ const input = text.length > MAX_INPUT_CHARS
48
+ ? text.slice(0, MAX_INPUT_CHARS) + '...'
49
+ : text;
50
+ // Try MLX qwen first (retry after RETRY_INTERVAL_MS)
51
+ if (mlxAvailable !== false || (Date.now() - mlxFailedAt > RETRY_INTERVAL_MS)) {
52
+ try {
53
+ const result = await callMLX(input);
54
+ if (result) {
55
+ mlxAvailable = true;
56
+ return result;
57
+ }
58
+ }
59
+ catch {
60
+ mlxAvailable = false;
61
+ mlxFailedAt = Date.now();
62
+ debug('summarizer', 'MLX not available, trying Ollama');
63
+ }
64
+ }
65
+ // Try Ollama (retry after RETRY_INTERVAL_MS)
66
+ if (ollamaAvailable !== false || (Date.now() - ollamaFailedAt > RETRY_INTERVAL_MS)) {
67
+ try {
68
+ const result = await callOllama(input);
69
+ if (result) {
70
+ ollamaAvailable = true;
71
+ return result;
72
+ }
73
+ }
74
+ catch {
75
+ ollamaAvailable = false;
76
+ ollamaFailedAt = Date.now();
77
+ debug('summarizer', 'Ollama not available, using heuristic');
78
+ }
79
+ }
80
+ return null;
81
+ }
82
+ // extractTopicHint and cleanLLMOutput moved to @agentdeck/shared/timeline-summarizer
83
+ async function callMLX(input) {
84
+ const controller = new AbortController();
85
+ const timer = setTimeout(() => controller.abort(), TIMEOUT_MS);
86
+ const model = await resolveModelForCall();
87
+ try {
88
+ const resp = await fetch(MLX_URL, {
89
+ method: 'POST',
90
+ headers: { 'Content-Type': 'application/json' },
91
+ body: JSON.stringify({
92
+ model,
93
+ enable_thinking: false,
94
+ messages: [
95
+ { role: 'system', content: SUMMARY_SYSTEM_PROMPT },
96
+ { role: 'user', content: input },
97
+ ],
98
+ max_tokens: 100,
99
+ temperature: 0.3,
100
+ }),
101
+ signal: controller.signal,
102
+ });
103
+ clearTimeout(timer);
104
+ if (!resp.ok)
105
+ throw new Error(`MLX ${resp.status}`);
106
+ const data = await resp.json();
107
+ const content = data.choices?.[0]?.message?.content?.trim();
108
+ if (!content)
109
+ return null;
110
+ const result = cleanLLMOutput(content);
111
+ if (result)
112
+ debug('summarizer', `MLX summary: ${result}`);
113
+ return result;
114
+ }
115
+ catch (err) {
116
+ clearTimeout(timer);
117
+ throw err;
118
+ }
119
+ }
120
+ async function callOllama(input) {
121
+ const controller = new AbortController();
122
+ const timer = setTimeout(() => controller.abort(), TIMEOUT_MS);
123
+ try {
124
+ const resp = await fetch(OLLAMA_URL, {
125
+ method: 'POST',
126
+ headers: { 'Content-Type': 'application/json' },
127
+ body: JSON.stringify({
128
+ model: 'qwen2.5:7b',
129
+ messages: [
130
+ { role: 'system', content: SUMMARY_SYSTEM_PROMPT },
131
+ { role: 'user', content: input },
132
+ ],
133
+ stream: false,
134
+ }),
135
+ signal: controller.signal,
136
+ });
137
+ clearTimeout(timer);
138
+ if (!resp.ok)
139
+ throw new Error(`Ollama ${resp.status}`);
140
+ const data = await resp.json();
141
+ const content = data.message?.content?.trim();
142
+ if (!content)
143
+ return null;
144
+ const result = cleanLLMOutput(content);
145
+ if (result)
146
+ debug('summarizer', `Ollama summary: ${result}`);
147
+ return result;
148
+ }
149
+ catch (err) {
150
+ clearTimeout(timer);
151
+ throw err;
152
+ }
153
+ }
154
+ //# sourceMappingURL=timeline-summarizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timeline-summarizer.js","sourceRoot":"","sources":["../src/timeline-summarizer.ts"],"names":[],"mappings":"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"}
package/dist/tts.d.ts ADDED
@@ -0,0 +1,25 @@
1
+ /**
2
+ * TTS Engine — macOS `say` with Neural Korean voice.
3
+ *
4
+ * Uses macOS built-in Neural TTS (Yuna / Sandy / etc.) — pre-installed,
5
+ * fast (~1s for a sentence), high quality Korean, no GPU competition.
6
+ *
7
+ * Supports sentence-level streaming: splits text into sentences,
8
+ * speaks each sequentially for lower perceived latency.
9
+ */
10
+ export declare class TtsEngine {
11
+ private voice;
12
+ private currentPlayback;
13
+ constructor();
14
+ isAvailable(): boolean;
15
+ /** Speak text directly (no temp file) */
16
+ speak(text: string): Promise<void>;
17
+ /**
18
+ * Streaming speak: split text into sentences, speak sequentially.
19
+ * Each sentence starts as soon as the previous one finishes.
20
+ */
21
+ speakStreaming(text: string): Promise<void>;
22
+ stopPlayback(): void;
23
+ cleanup(): void;
24
+ }
25
+ //# sourceMappingURL=tts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tts.d.ts","sourceRoot":"","sources":["../src/tts.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA8BH,qBAAa,SAAS;IACpB,OAAO,CAAC,KAAK,CAAgB;IAC7B,OAAO,CAAC,eAAe,CAA6B;;IAWpD,WAAW,IAAI,OAAO;IAItB,yCAAyC;IACnC,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBxC;;;OAGG;IACG,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASjD,YAAY,IAAI,IAAI;IAOpB,OAAO,IAAI,IAAI;CAGhB"}
package/dist/tts.js ADDED
@@ -0,0 +1,99 @@
1
+ /**
2
+ * TTS Engine — macOS `say` with Neural Korean voice.
3
+ *
4
+ * Uses macOS built-in Neural TTS (Yuna / Sandy / etc.) — pre-installed,
5
+ * fast (~1s for a sentence), high quality Korean, no GPU competition.
6
+ *
7
+ * Supports sentence-level streaming: splits text into sentences,
8
+ * speaks each sequentially for lower perceived latency.
9
+ */
10
+ import { spawn, execSync } from 'child_process';
11
+ import { platform } from 'os';
12
+ import { debug } from './logger.js';
13
+ const TAG = 'TTS';
14
+ /** Preferred Korean voices in quality order */
15
+ const PREFERRED_KO_VOICES = ['Yuna', 'Sandy', 'Shelley', 'Reed', 'Flo', 'Eddy'];
16
+ function findMacOsKoreanVoice() {
17
+ if (platform() !== 'darwin')
18
+ return null;
19
+ try {
20
+ const voices = execSync('say -v "?"', { encoding: 'utf-8' });
21
+ const koVoices = voices.split('\n').filter(l => l.includes('ko_KR'));
22
+ if (koVoices.length === 0)
23
+ return null;
24
+ for (const name of PREFERRED_KO_VOICES) {
25
+ if (koVoices.some(v => v.startsWith(name + ' ') || v.includes(`(${name})`))) {
26
+ return name;
27
+ }
28
+ }
29
+ const match = koVoices[0].match(/^(\S+)/);
30
+ return match?.[1] ?? null;
31
+ }
32
+ catch {
33
+ return null;
34
+ }
35
+ }
36
+ export class TtsEngine {
37
+ voice;
38
+ currentPlayback = null;
39
+ constructor() {
40
+ this.voice = findMacOsKoreanVoice();
41
+ if (this.voice) {
42
+ debug(TAG, `macOS say voice: ${this.voice}`);
43
+ }
44
+ else {
45
+ debug(TAG, 'No Korean TTS voice available');
46
+ }
47
+ }
48
+ isAvailable() {
49
+ return this.voice !== null;
50
+ }
51
+ /** Speak text directly (no temp file) */
52
+ async speak(text) {
53
+ if (!this.voice)
54
+ throw new Error('No TTS voice available');
55
+ return new Promise((resolve, reject) => {
56
+ debug(TAG, `say -v ${this.voice}: "${text.slice(0, 60)}"`);
57
+ const proc = spawn('say', ['-v', this.voice, text], { stdio: 'ignore' });
58
+ this.currentPlayback = proc;
59
+ proc.on('error', (err) => {
60
+ this.currentPlayback = null;
61
+ reject(new Error(`say error: ${err.message}`));
62
+ });
63
+ proc.on('close', (code) => {
64
+ this.currentPlayback = null;
65
+ if (code !== 0)
66
+ reject(new Error(`say exited with code ${code}`));
67
+ else
68
+ resolve();
69
+ });
70
+ });
71
+ }
72
+ /**
73
+ * Streaming speak: split text into sentences, speak sequentially.
74
+ * Each sentence starts as soon as the previous one finishes.
75
+ */
76
+ async speakStreaming(text) {
77
+ const sentences = splitSentences(text);
78
+ if (sentences.length === 0)
79
+ return;
80
+ for (const sentence of sentences) {
81
+ await this.speak(sentence);
82
+ }
83
+ }
84
+ stopPlayback() {
85
+ if (this.currentPlayback) {
86
+ this.currentPlayback.kill('SIGTERM');
87
+ this.currentPlayback = null;
88
+ }
89
+ }
90
+ cleanup() {
91
+ this.stopPlayback();
92
+ }
93
+ }
94
+ /** Split text into sentences for streaming TTS */
95
+ function splitSentences(text) {
96
+ const raw = text.split(/(?<=[.!?。?!])\s+/);
97
+ return raw.map(s => s.trim()).filter(s => s.length > 0);
98
+ }
99
+ //# sourceMappingURL=tts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tts.js","sourceRoot":"","sources":["../src/tts.ts"],"names":[],"mappings":"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"}