@fraziym/axoniz 0.1.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 (512) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +76 -0
  3. package/dist/agents/definition.d.ts +15 -0
  4. package/dist/agents/definition.d.ts.map +1 -0
  5. package/dist/agents/definition.js +41 -0
  6. package/dist/agents/definition.js.map +1 -0
  7. package/dist/agents/index.d.ts +12 -0
  8. package/dist/agents/index.d.ts.map +1 -0
  9. package/dist/agents/index.js +11 -0
  10. package/dist/agents/index.js.map +1 -0
  11. package/dist/agents/registry.d.ts +17 -0
  12. package/dist/agents/registry.d.ts.map +1 -0
  13. package/dist/agents/registry.js +23 -0
  14. package/dist/agents/registry.js.map +1 -0
  15. package/dist/agents/specialized.d.ts +31 -0
  16. package/dist/agents/specialized.d.ts.map +1 -0
  17. package/dist/agents/specialized.js +75 -0
  18. package/dist/agents/specialized.js.map +1 -0
  19. package/dist/awareness/index.d.ts +14 -0
  20. package/dist/awareness/index.d.ts.map +1 -0
  21. package/dist/awareness/index.js +22 -0
  22. package/dist/awareness/index.js.map +1 -0
  23. package/dist/awareness/service.d.ts +180 -0
  24. package/dist/awareness/service.d.ts.map +1 -0
  25. package/dist/awareness/service.js +789 -0
  26. package/dist/awareness/service.js.map +1 -0
  27. package/dist/cli/entry.d.ts +13 -0
  28. package/dist/cli/entry.d.ts.map +1 -0
  29. package/dist/cli/entry.js +35 -0
  30. package/dist/cli/entry.js.map +1 -0
  31. package/dist/comms/telegram.d.ts +41 -0
  32. package/dist/comms/telegram.d.ts.map +1 -0
  33. package/dist/comms/telegram.js +332 -0
  34. package/dist/comms/telegram.js.map +1 -0
  35. package/dist/core/agent.d.ts +252 -0
  36. package/dist/core/agent.d.ts.map +1 -0
  37. package/dist/core/agent.js +1399 -0
  38. package/dist/core/agent.js.map +1 -0
  39. package/dist/core/auth.d.ts +23 -0
  40. package/dist/core/auth.d.ts.map +1 -0
  41. package/dist/core/auth.js +113 -0
  42. package/dist/core/auth.js.map +1 -0
  43. package/dist/core/authority.d.ts +118 -0
  44. package/dist/core/authority.d.ts.map +1 -0
  45. package/dist/core/authority.js +402 -0
  46. package/dist/core/authority.js.map +1 -0
  47. package/dist/core/backend/async_queue.d.ts +17 -0
  48. package/dist/core/backend/async_queue.d.ts.map +1 -0
  49. package/dist/core/backend/async_queue.js +66 -0
  50. package/dist/core/backend/async_queue.js.map +1 -0
  51. package/dist/core/backend/index.d.ts +24 -0
  52. package/dist/core/backend/index.d.ts.map +1 -0
  53. package/dist/core/backend/index.js +128 -0
  54. package/dist/core/backend/index.js.map +1 -0
  55. package/dist/core/backend/llama_server.d.ts +39 -0
  56. package/dist/core/backend/llama_server.d.ts.map +1 -0
  57. package/dist/core/backend/llama_server.js +182 -0
  58. package/dist/core/backend/llama_server.js.map +1 -0
  59. package/dist/core/backend/llamacpp.d.ts +40 -0
  60. package/dist/core/backend/llamacpp.d.ts.map +1 -0
  61. package/dist/core/backend/llamacpp.js +200 -0
  62. package/dist/core/backend/llamacpp.js.map +1 -0
  63. package/dist/core/backend/lmstudio.d.ts +53 -0
  64. package/dist/core/backend/lmstudio.d.ts.map +1 -0
  65. package/dist/core/backend/lmstudio.js +274 -0
  66. package/dist/core/backend/lmstudio.js.map +1 -0
  67. package/dist/core/backend/ollama.d.ts +25 -0
  68. package/dist/core/backend/ollama.d.ts.map +1 -0
  69. package/dist/core/backend/ollama.js +86 -0
  70. package/dist/core/backend/ollama.js.map +1 -0
  71. package/dist/core/backend/openai.d.ts +27 -0
  72. package/dist/core/backend/openai.d.ts.map +1 -0
  73. package/dist/core/backend/openai.js +84 -0
  74. package/dist/core/backend/openai.js.map +1 -0
  75. package/dist/core/backend/types.d.ts +73 -0
  76. package/dist/core/backend/types.d.ts.map +1 -0
  77. package/dist/core/backend/types.js +137 -0
  78. package/dist/core/backend/types.js.map +1 -0
  79. package/dist/core/chat_store.d.ts +77 -0
  80. package/dist/core/chat_store.d.ts.map +1 -0
  81. package/dist/core/chat_store.js +332 -0
  82. package/dist/core/chat_store.js.map +1 -0
  83. package/dist/core/cli.d.ts +82 -0
  84. package/dist/core/cli.d.ts.map +1 -0
  85. package/dist/core/cli.js +602 -0
  86. package/dist/core/cli.js.map +1 -0
  87. package/dist/core/config.d.ts +127 -0
  88. package/dist/core/config.d.ts.map +1 -0
  89. package/dist/core/config.js +295 -0
  90. package/dist/core/config.js.map +1 -0
  91. package/dist/core/debug.d.ts +8 -0
  92. package/dist/core/debug.d.ts.map +1 -0
  93. package/dist/core/debug.js +8 -0
  94. package/dist/core/debug.js.map +1 -0
  95. package/dist/core/downloader.d.ts +31 -0
  96. package/dist/core/downloader.d.ts.map +1 -0
  97. package/dist/core/downloader.js +180 -0
  98. package/dist/core/downloader.js.map +1 -0
  99. package/dist/core/errors.d.ts +80 -0
  100. package/dist/core/errors.d.ts.map +1 -0
  101. package/dist/core/errors.js +134 -0
  102. package/dist/core/errors.js.map +1 -0
  103. package/dist/core/extras.d.ts +160 -0
  104. package/dist/core/extras.d.ts.map +1 -0
  105. package/dist/core/extras.js +553 -0
  106. package/dist/core/extras.js.map +1 -0
  107. package/dist/core/health.d.ts +27 -0
  108. package/dist/core/health.d.ts.map +1 -0
  109. package/dist/core/health.js +96 -0
  110. package/dist/core/health.js.map +1 -0
  111. package/dist/core/history.d.ts +50 -0
  112. package/dist/core/history.d.ts.map +1 -0
  113. package/dist/core/history.js +276 -0
  114. package/dist/core/history.js.map +1 -0
  115. package/dist/core/index.d.ts +6 -0
  116. package/dist/core/index.d.ts.map +1 -0
  117. package/dist/core/index.js +6 -0
  118. package/dist/core/index.js.map +1 -0
  119. package/dist/core/intelligence/ast_index.d.ts +255 -0
  120. package/dist/core/intelligence/ast_index.d.ts.map +1 -0
  121. package/dist/core/intelligence/ast_index.js +1369 -0
  122. package/dist/core/intelligence/ast_index.js.map +1 -0
  123. package/dist/core/intelligence/confidence.d.ts +113 -0
  124. package/dist/core/intelligence/confidence.d.ts.map +1 -0
  125. package/dist/core/intelligence/confidence.js +298 -0
  126. package/dist/core/intelligence/confidence.js.map +1 -0
  127. package/dist/core/intelligence/context_compressor.d.ts +80 -0
  128. package/dist/core/intelligence/context_compressor.d.ts.map +1 -0
  129. package/dist/core/intelligence/context_compressor.js +245 -0
  130. package/dist/core/intelligence/context_compressor.js.map +1 -0
  131. package/dist/core/intelligence/daemon.d.ts +247 -0
  132. package/dist/core/intelligence/daemon.d.ts.map +1 -0
  133. package/dist/core/intelligence/daemon.js +842 -0
  134. package/dist/core/intelligence/daemon.js.map +1 -0
  135. package/dist/core/intelligence/index.d.ts +60 -0
  136. package/dist/core/intelligence/index.d.ts.map +1 -0
  137. package/dist/core/intelligence/index.js +101 -0
  138. package/dist/core/intelligence/index.js.map +1 -0
  139. package/dist/core/intelligence/predictor.d.ts +246 -0
  140. package/dist/core/intelligence/predictor.d.ts.map +1 -0
  141. package/dist/core/intelligence/predictor.js +590 -0
  142. package/dist/core/intelligence/predictor.js.map +1 -0
  143. package/dist/core/intelligence/reflex.d.ts +84 -0
  144. package/dist/core/intelligence/reflex.d.ts.map +1 -0
  145. package/dist/core/intelligence/reflex.js +344 -0
  146. package/dist/core/intelligence/reflex.js.map +1 -0
  147. package/dist/core/intelligence/self_correction.d.ts +121 -0
  148. package/dist/core/intelligence/self_correction.d.ts.map +1 -0
  149. package/dist/core/intelligence/self_correction.js +327 -0
  150. package/dist/core/intelligence/self_correction.js.map +1 -0
  151. package/dist/core/intelligence/skill_distiller.d.ts +100 -0
  152. package/dist/core/intelligence/skill_distiller.d.ts.map +1 -0
  153. package/dist/core/intelligence/skill_distiller.js +246 -0
  154. package/dist/core/intelligence/skill_distiller.js.map +1 -0
  155. package/dist/core/intelligence/swarm.d.ts +330 -0
  156. package/dist/core/intelligence/swarm.d.ts.map +1 -0
  157. package/dist/core/intelligence/swarm.js +1064 -0
  158. package/dist/core/intelligence/swarm.js.map +1 -0
  159. package/dist/core/intelligence/trajectory.d.ts +107 -0
  160. package/dist/core/intelligence/trajectory.d.ts.map +1 -0
  161. package/dist/core/intelligence/trajectory.js +330 -0
  162. package/dist/core/intelligence/trajectory.js.map +1 -0
  163. package/dist/core/logger.d.ts +111 -0
  164. package/dist/core/logger.d.ts.map +1 -0
  165. package/dist/core/logger.js +640 -0
  166. package/dist/core/logger.js.map +1 -0
  167. package/dist/core/loop.d.ts +123 -0
  168. package/dist/core/loop.d.ts.map +1 -0
  169. package/dist/core/loop.js +423 -0
  170. package/dist/core/loop.js.map +1 -0
  171. package/dist/core/memory.d.ts +81 -0
  172. package/dist/core/memory.d.ts.map +1 -0
  173. package/dist/core/memory.js +328 -0
  174. package/dist/core/memory.js.map +1 -0
  175. package/dist/core/metrics.d.ts +29 -0
  176. package/dist/core/metrics.d.ts.map +1 -0
  177. package/dist/core/metrics.js +109 -0
  178. package/dist/core/metrics.js.map +1 -0
  179. package/dist/core/models.d.ts +51 -0
  180. package/dist/core/models.d.ts.map +1 -0
  181. package/dist/core/models.js +146 -0
  182. package/dist/core/models.js.map +1 -0
  183. package/dist/core/optimizer.d.ts +34 -0
  184. package/dist/core/optimizer.d.ts.map +1 -0
  185. package/dist/core/optimizer.js +131 -0
  186. package/dist/core/optimizer.js.map +1 -0
  187. package/dist/core/persona.d.ts +35 -0
  188. package/dist/core/persona.d.ts.map +1 -0
  189. package/dist/core/persona.js +126 -0
  190. package/dist/core/persona.js.map +1 -0
  191. package/dist/core/rate_limit.d.ts +23 -0
  192. package/dist/core/rate_limit.d.ts.map +1 -0
  193. package/dist/core/rate_limit.js +62 -0
  194. package/dist/core/rate_limit.js.map +1 -0
  195. package/dist/core/runner.d.ts +63 -0
  196. package/dist/core/runner.d.ts.map +1 -0
  197. package/dist/core/runner.js +671 -0
  198. package/dist/core/runner.js.map +1 -0
  199. package/dist/core/stream_parser.d.ts +43 -0
  200. package/dist/core/stream_parser.d.ts.map +1 -0
  201. package/dist/core/stream_parser.js +140 -0
  202. package/dist/core/stream_parser.js.map +1 -0
  203. package/dist/core/tool_schemas.d.ts +26 -0
  204. package/dist/core/tool_schemas.d.ts.map +1 -0
  205. package/dist/core/tool_schemas.js +124 -0
  206. package/dist/core/tool_schemas.js.map +1 -0
  207. package/dist/core/which.d.ts +2 -0
  208. package/dist/core/which.d.ts.map +1 -0
  209. package/dist/core/which.js +35 -0
  210. package/dist/core/which.js.map +1 -0
  211. package/dist/goals/index.d.ts +9 -0
  212. package/dist/goals/index.d.ts.map +1 -0
  213. package/dist/goals/index.js +17 -0
  214. package/dist/goals/index.js.map +1 -0
  215. package/dist/goals/service.d.ts +115 -0
  216. package/dist/goals/service.d.ts.map +1 -0
  217. package/dist/goals/service.js +415 -0
  218. package/dist/goals/service.js.map +1 -0
  219. package/dist/goals/types.d.ts +47 -0
  220. package/dist/goals/types.d.ts.map +1 -0
  221. package/dist/goals/types.js +66 -0
  222. package/dist/goals/types.js.map +1 -0
  223. package/dist/index.d.ts +22 -0
  224. package/dist/index.d.ts.map +1 -0
  225. package/dist/index.js +22 -0
  226. package/dist/index.js.map +1 -0
  227. package/dist/integrations/autonomous_startup.d.ts +51 -0
  228. package/dist/integrations/autonomous_startup.d.ts.map +1 -0
  229. package/dist/integrations/autonomous_startup.js +419 -0
  230. package/dist/integrations/autonomous_startup.js.map +1 -0
  231. package/dist/integrations/goose.d.ts +105 -0
  232. package/dist/integrations/goose.d.ts.map +1 -0
  233. package/dist/integrations/goose.js +408 -0
  234. package/dist/integrations/goose.js.map +1 -0
  235. package/dist/integrations/index.d.ts +21 -0
  236. package/dist/integrations/index.d.ts.map +1 -0
  237. package/dist/integrations/index.js +17 -0
  238. package/dist/integrations/index.js.map +1 -0
  239. package/dist/integrations/mcp.d.ts +73 -0
  240. package/dist/integrations/mcp.d.ts.map +1 -0
  241. package/dist/integrations/mcp.js +307 -0
  242. package/dist/integrations/mcp.js.map +1 -0
  243. package/dist/integrations/mempalace.d.ts +18 -0
  244. package/dist/integrations/mempalace.d.ts.map +1 -0
  245. package/dist/integrations/mempalace.js +25 -0
  246. package/dist/integrations/mempalace.js.map +1 -0
  247. package/dist/integrations/multi_agent.d.ts +82 -0
  248. package/dist/integrations/multi_agent.d.ts.map +1 -0
  249. package/dist/integrations/multi_agent.js +280 -0
  250. package/dist/integrations/multi_agent.js.map +1 -0
  251. package/dist/integrations/unified_memory.d.ts +415 -0
  252. package/dist/integrations/unified_memory.d.ts.map +1 -0
  253. package/dist/integrations/unified_memory.js +1489 -0
  254. package/dist/integrations/unified_memory.js.map +1 -0
  255. package/dist/roles/beru.yaml +48 -0
  256. package/dist/sidecar/client.d.ts +63 -0
  257. package/dist/sidecar/client.d.ts.map +1 -0
  258. package/dist/sidecar/client.js +222 -0
  259. package/dist/sidecar/client.js.map +1 -0
  260. package/dist/sidecar/index.d.ts +7 -0
  261. package/dist/sidecar/index.d.ts.map +1 -0
  262. package/dist/sidecar/index.js +6 -0
  263. package/dist/sidecar/index.js.map +1 -0
  264. package/dist/startup.d.ts +22 -0
  265. package/dist/startup.d.ts.map +1 -0
  266. package/dist/startup.js +194 -0
  267. package/dist/startup.js.map +1 -0
  268. package/dist/tools/_internal.d.ts +90 -0
  269. package/dist/tools/_internal.d.ts.map +1 -0
  270. package/dist/tools/_internal.js +375 -0
  271. package/dist/tools/_internal.js.map +1 -0
  272. package/dist/tools/_smoke.d.ts +2 -0
  273. package/dist/tools/_smoke.d.ts.map +1 -0
  274. package/dist/tools/_smoke.js +203 -0
  275. package/dist/tools/_smoke.js.map +1 -0
  276. package/dist/tools/axodex_tools.d.ts +51 -0
  277. package/dist/tools/axodex_tools.d.ts.map +1 -0
  278. package/dist/tools/axodex_tools.js +181 -0
  279. package/dist/tools/axodex_tools.js.map +1 -0
  280. package/dist/tools/code_tools.d.ts +33 -0
  281. package/dist/tools/code_tools.d.ts.map +1 -0
  282. package/dist/tools/code_tools.js +191 -0
  283. package/dist/tools/code_tools.js.map +1 -0
  284. package/dist/tools/computer_tools.d.ts +59 -0
  285. package/dist/tools/computer_tools.d.ts.map +1 -0
  286. package/dist/tools/computer_tools.js +348 -0
  287. package/dist/tools/computer_tools.js.map +1 -0
  288. package/dist/tools/file_tools.d.ts +51 -0
  289. package/dist/tools/file_tools.d.ts.map +1 -0
  290. package/dist/tools/file_tools.js +424 -0
  291. package/dist/tools/file_tools.js.map +1 -0
  292. package/dist/tools/index.d.ts +13 -0
  293. package/dist/tools/index.d.ts.map +1 -0
  294. package/dist/tools/index.js +13 -0
  295. package/dist/tools/index.js.map +1 -0
  296. package/dist/tools/shell_tools.d.ts +39 -0
  297. package/dist/tools/shell_tools.d.ts.map +1 -0
  298. package/dist/tools/shell_tools.js +163 -0
  299. package/dist/tools/shell_tools.js.map +1 -0
  300. package/dist/tools/web_tools.d.ts +31 -0
  301. package/dist/tools/web_tools.d.ts.map +1 -0
  302. package/dist/tools/web_tools.js +117 -0
  303. package/dist/tools/web_tools.js.map +1 -0
  304. package/dist/voice/index.d.ts +41 -0
  305. package/dist/voice/index.d.ts.map +1 -0
  306. package/dist/voice/index.js +58 -0
  307. package/dist/voice/index.js.map +1 -0
  308. package/dist/voice/light_daemon.d.ts +197 -0
  309. package/dist/voice/light_daemon.d.ts.map +1 -0
  310. package/dist/voice/light_daemon.js +746 -0
  311. package/dist/voice/light_daemon.js.map +1 -0
  312. package/dist/voice/setup.d.ts +63 -0
  313. package/dist/voice/setup.d.ts.map +1 -0
  314. package/dist/voice/setup.js +443 -0
  315. package/dist/voice/setup.js.map +1 -0
  316. package/dist/voice/stt.d.ts +148 -0
  317. package/dist/voice/stt.d.ts.map +1 -0
  318. package/dist/voice/stt.js +361 -0
  319. package/dist/voice/stt.js.map +1 -0
  320. package/dist/voice/tts.d.ts +168 -0
  321. package/dist/voice/tts.d.ts.map +1 -0
  322. package/dist/voice/tts.js +698 -0
  323. package/dist/voice/tts.js.map +1 -0
  324. package/dist/voice/voice_loop.d.ts +101 -0
  325. package/dist/voice/voice_loop.d.ts.map +1 -0
  326. package/dist/voice/voice_loop.js +463 -0
  327. package/dist/voice/voice_loop.js.map +1 -0
  328. package/dist/voice/wake_word.d.ts +153 -0
  329. package/dist/voice/wake_word.d.ts.map +1 -0
  330. package/dist/voice/wake_word.js +458 -0
  331. package/dist/voice/wake_word.js.map +1 -0
  332. package/dist/voice/wav.d.ts +99 -0
  333. package/dist/voice/wav.d.ts.map +1 -0
  334. package/dist/voice/wav.js +306 -0
  335. package/dist/voice/wav.js.map +1 -0
  336. package/dist/web/broker.d.ts +33 -0
  337. package/dist/web/broker.d.ts.map +1 -0
  338. package/dist/web/broker.js +58 -0
  339. package/dist/web/broker.js.map +1 -0
  340. package/dist/web/open_browser.d.ts +2 -0
  341. package/dist/web/open_browser.d.ts.map +1 -0
  342. package/dist/web/open_browser.js +42 -0
  343. package/dist/web/open_browser.js.map +1 -0
  344. package/dist/web/server.d.ts +54 -0
  345. package/dist/web/server.d.ts.map +1 -0
  346. package/dist/web/server.js +831 -0
  347. package/dist/web/server.js.map +1 -0
  348. package/dist/web/static/app.js +4121 -0
  349. package/dist/web/static/index.html +2281 -0
  350. package/dist/web/static/js/MODULE_SUMMARY.md +124 -0
  351. package/dist/web/static/js/a11y.js +165 -0
  352. package/dist/web/static/js/admin.js +2145 -0
  353. package/dist/web/static/js/assistant.js +475 -0
  354. package/dist/web/static/js/calendar/reminders.js +114 -0
  355. package/dist/web/static/js/calendar/utils.js +166 -0
  356. package/dist/web/static/js/calendar.js +3348 -0
  357. package/dist/web/static/js/censor.js +356 -0
  358. package/dist/web/static/js/chat.js +4546 -0
  359. package/dist/web/static/js/chatRenderer.js +2294 -0
  360. package/dist/web/static/js/chatStream.js +276 -0
  361. package/dist/web/static/js/codeRunner.js +398 -0
  362. package/dist/web/static/js/color/hex.js +14 -0
  363. package/dist/web/static/js/colorPicker.js +453 -0
  364. package/dist/web/static/js/compare/icons.js +77 -0
  365. package/dist/web/static/js/compare/index.js +1482 -0
  366. package/dist/web/static/js/compare/models.js +104 -0
  367. package/dist/web/static/js/compare/panes.js +817 -0
  368. package/dist/web/static/js/compare/probe.js +78 -0
  369. package/dist/web/static/js/compare/scoreboard.js +223 -0
  370. package/dist/web/static/js/compare/selector.js +1335 -0
  371. package/dist/web/static/js/compare/state.js +58 -0
  372. package/dist/web/static/js/compare/stream.js +695 -0
  373. package/dist/web/static/js/compare/vote.js +254 -0
  374. package/dist/web/static/js/cookbook-diagnosis.js +694 -0
  375. package/dist/web/static/js/cookbook-hwfit.js +1888 -0
  376. package/dist/web/static/js/cookbook.js +2093 -0
  377. package/dist/web/static/js/cookbookDownload.js +633 -0
  378. package/dist/web/static/js/cookbookProgressSignal.js +29 -0
  379. package/dist/web/static/js/cookbookRunning.js +3506 -0
  380. package/dist/web/static/js/cookbookServe.js +2128 -0
  381. package/dist/web/static/js/document.js +9731 -0
  382. package/dist/web/static/js/documentLibrary.js +3376 -0
  383. package/dist/web/static/js/dragSort.js +265 -0
  384. package/dist/web/static/js/editor/ai-inpaint.js +374 -0
  385. package/dist/web/static/js/editor/ai-models.js +273 -0
  386. package/dist/web/static/js/editor/ai-rembg.js +230 -0
  387. package/dist/web/static/js/editor/ai-tool-runner.js +147 -0
  388. package/dist/web/static/js/editor/ai-tools-misc.js +216 -0
  389. package/dist/web/static/js/editor/build/controls.js +366 -0
  390. package/dist/web/static/js/editor/build/popups.js +112 -0
  391. package/dist/web/static/js/editor/build/right-panel.js +200 -0
  392. package/dist/web/static/js/editor/build/toolbar.js +73 -0
  393. package/dist/web/static/js/editor/build/topbar.js +131 -0
  394. package/dist/web/static/js/editor/build/transform-popup.js +109 -0
  395. package/dist/web/static/js/editor/canvas-coords.js +21 -0
  396. package/dist/web/static/js/editor/canvas-events.js +197 -0
  397. package/dist/web/static/js/editor/canvas-transforms.js +132 -0
  398. package/dist/web/static/js/editor/checkerboard.js +24 -0
  399. package/dist/web/static/js/editor/clipboard-and-drop.js +133 -0
  400. package/dist/web/static/js/editor/composite-helpers.js +83 -0
  401. package/dist/web/static/js/editor/filters/blur.js +118 -0
  402. package/dist/web/static/js/editor/filters/edge-feather.js +70 -0
  403. package/dist/web/static/js/editor/fx/adj-popup.js +677 -0
  404. package/dist/web/static/js/editor/fx/filter-string.js +38 -0
  405. package/dist/web/static/js/editor/fx/histogram.js +67 -0
  406. package/dist/web/static/js/editor/fx/pixel-pass.js +249 -0
  407. package/dist/web/static/js/editor/harmonize-masks.js +116 -0
  408. package/dist/web/static/js/editor/history-panel.js +176 -0
  409. package/dist/web/static/js/editor/keyboard-shortcuts.js +271 -0
  410. package/dist/web/static/js/editor/layer-helpers.js +131 -0
  411. package/dist/web/static/js/editor/layer-panel.js +600 -0
  412. package/dist/web/static/js/editor/mask-utils.js +91 -0
  413. package/dist/web/static/js/editor/shortcuts-popover.js +149 -0
  414. package/dist/web/static/js/editor/slider-ux.js +191 -0
  415. package/dist/web/static/js/editor/snap.js +107 -0
  416. package/dist/web/static/js/editor/state.js +257 -0
  417. package/dist/web/static/js/editor/stroke-pipeline.js +162 -0
  418. package/dist/web/static/js/editor/stroke-tool-sliders.js +64 -0
  419. package/dist/web/static/js/editor/tools/clone.js +81 -0
  420. package/dist/web/static/js/editor/tools/crop.js +137 -0
  421. package/dist/web/static/js/editor/tools/flood-fill.js +72 -0
  422. package/dist/web/static/js/editor/tools/lasso-mask.js +171 -0
  423. package/dist/web/static/js/editor/tools/lasso.js +65 -0
  424. package/dist/web/static/js/editor/tools/move.js +79 -0
  425. package/dist/web/static/js/editor/tools/stroke.js +123 -0
  426. package/dist/web/static/js/editor/tools/transform-drag.js +174 -0
  427. package/dist/web/static/js/editor/tools/transform-handles.js +271 -0
  428. package/dist/web/static/js/editor/tools/transform-session.js +381 -0
  429. package/dist/web/static/js/editor/tools/wand.js +46 -0
  430. package/dist/web/static/js/editor/wire-import.js +148 -0
  431. package/dist/web/static/js/editor/wire-inpaint-controls.js +164 -0
  432. package/dist/web/static/js/editor/wire-merge-buttons.js +103 -0
  433. package/dist/web/static/js/editor/wire-selection-controls.js +170 -0
  434. package/dist/web/static/js/editor/wire-topbar-menus.js +174 -0
  435. package/dist/web/static/js/editor/wire-topbar-overflow.js +49 -0
  436. package/dist/web/static/js/editor/wire-topbar.js +188 -0
  437. package/dist/web/static/js/emailInbox.js +1245 -0
  438. package/dist/web/static/js/emailLibrary/replyRecipients.js +27 -0
  439. package/dist/web/static/js/emailLibrary/signatureFold.js +339 -0
  440. package/dist/web/static/js/emailLibrary/state.js +34 -0
  441. package/dist/web/static/js/emailLibrary/utils.js +202 -0
  442. package/dist/web/static/js/emailLibrary.js +5217 -0
  443. package/dist/web/static/js/emojiPicker.js +311 -0
  444. package/dist/web/static/js/escMenuStack.js +102 -0
  445. package/dist/web/static/js/fileHandler.js +295 -0
  446. package/dist/web/static/js/gallery.js +2835 -0
  447. package/dist/web/static/js/galleryEditor.js +3798 -0
  448. package/dist/web/static/js/group.js +955 -0
  449. package/dist/web/static/js/init.js +405 -0
  450. package/dist/web/static/js/keyboard-shortcuts.js +292 -0
  451. package/dist/web/static/js/langIcons.js +187 -0
  452. package/dist/web/static/js/markdown/tableRow.js +19 -0
  453. package/dist/web/static/js/markdown.js +806 -0
  454. package/dist/web/static/js/memory.js +1418 -0
  455. package/dist/web/static/js/modalManager.js +1552 -0
  456. package/dist/web/static/js/modalSnap.js +782 -0
  457. package/dist/web/static/js/model/matchKey.js +19 -0
  458. package/dist/web/static/js/modelPicker.js +695 -0
  459. package/dist/web/static/js/modelSort.js +33 -0
  460. package/dist/web/static/js/models.js +642 -0
  461. package/dist/web/static/js/notes.js +5054 -0
  462. package/dist/web/static/js/package.json +1 -0
  463. package/dist/web/static/js/platform.js +47 -0
  464. package/dist/web/static/js/presets.js +1110 -0
  465. package/dist/web/static/js/providers.js +93 -0
  466. package/dist/web/static/js/rag.js +177 -0
  467. package/dist/web/static/js/research/jobs.js +335 -0
  468. package/dist/web/static/js/research/panel.js +1233 -0
  469. package/dist/web/static/js/researchSynapse.js +225 -0
  470. package/dist/web/static/js/search-chat.js +201 -0
  471. package/dist/web/static/js/search.js +52 -0
  472. package/dist/web/static/js/section-management.js +260 -0
  473. package/dist/web/static/js/sessions.js +3108 -0
  474. package/dist/web/static/js/settings.js +4991 -0
  475. package/dist/web/static/js/sidebar-layout.js +573 -0
  476. package/dist/web/static/js/signature.js +504 -0
  477. package/dist/web/static/js/skills.js +1908 -0
  478. package/dist/web/static/js/slashAutocomplete.js +267 -0
  479. package/dist/web/static/js/slashCommands.js +6099 -0
  480. package/dist/web/static/js/spinner.js +406 -0
  481. package/dist/web/static/js/storage.js +123 -0
  482. package/dist/web/static/js/tasks.js +2699 -0
  483. package/dist/web/static/js/theme.js +2086 -0
  484. package/dist/web/static/js/tileManager.js +386 -0
  485. package/dist/web/static/js/tourAutoplay.js +133 -0
  486. package/dist/web/static/js/tourHints.js +179 -0
  487. package/dist/web/static/js/tts-ai.js +521 -0
  488. package/dist/web/static/js/ui.js +1288 -0
  489. package/dist/web/static/js/util/ordinal.js +13 -0
  490. package/dist/web/static/js/voiceRecorder.js +283 -0
  491. package/dist/web/static/js/windowDrag.js +326 -0
  492. package/dist/web/static/js/windowResize.js +233 -0
  493. package/dist/web/static/landing.html +824 -0
  494. package/dist/web/static/lib/docx.umd.min.js +20116 -0
  495. package/dist/web/static/lib/highlight.min.js +1213 -0
  496. package/dist/web/static/lib/html2pdf.bundle.min.js +3 -0
  497. package/dist/web/static/lib/mammoth.browser.min.js +21 -0
  498. package/dist/web/static/lib/qrcode.min.js +8 -0
  499. package/dist/web/static/lib/xlsx.full.min.js +24 -0
  500. package/dist/web/static/login.html +582 -0
  501. package/dist/web/static/manifest.json +15 -0
  502. package/dist/web/static/style.css +35733 -0
  503. package/dist/web/static/sw.js +144 -0
  504. package/dist/workflows/engine.d.ts +162 -0
  505. package/dist/workflows/engine.d.ts.map +1 -0
  506. package/dist/workflows/engine.js +625 -0
  507. package/dist/workflows/engine.js.map +1 -0
  508. package/dist/workflows/index.d.ts +8 -0
  509. package/dist/workflows/index.d.ts.map +1 -0
  510. package/dist/workflows/index.js +14 -0
  511. package/dist/workflows/index.js.map +1 -0
  512. package/package.json +112 -0
@@ -0,0 +1,179 @@
1
+ // tourHints.js — secret continuation of /tour. The first time the user opens
2
+ // a tool modal (after the welcome experience), surface a single "pro tip"
3
+ // hint pointing out that modals can be snapped to the screen edge or
4
+ // fullscreened by dragging the title bar. Shown once globally — once the
5
+ // user has dismissed it (or it auto-hides), it never returns.
6
+
7
+ const HINT_SEEN_KEY = 'zero-hint-drag-to-snap-seen';
8
+
9
+ // Allow-list of modals where the snap/fullscreen hint makes sense.
10
+ // These are the full-window "tool" modals where users commonly want to
11
+ // reposition or fullscreen the pane (email, calendar, cookbook, gallery,
12
+ // library, brain memories, tasks, theme, compare). Transient modals
13
+ // like settings, prompts, rename dialogs, custom-preset picker, etc.
14
+ // are excluded — opening those is task-focused and the snap tip would
15
+ // be noise.
16
+ const SHOW_MODALS = new Set([
17
+ 'email-lib-modal',
18
+ 'calendar-modal',
19
+ 'compare-modal', // not currently a real id, defensive
20
+ 'cookbook-modal',
21
+ 'gallery-modal',
22
+ 'doclib-modal',
23
+ 'library-modal', // chat-history library (sessions.js)
24
+ 'memory-modal', // brain / memories
25
+ 'tasks-modal',
26
+ 'theme-modal',
27
+ ]);
28
+
29
+ // Some modals have dynamic per-instance IDs (e.g. one window per opened
30
+ // email). Match by prefix so any window from the same family qualifies.
31
+ const SHOW_MODAL_PREFIXES = ['email-window-'];
32
+
33
+ function _modalShouldShowHint(id) {
34
+ if (!id) return false;
35
+ if (SHOW_MODALS.has(id)) return true;
36
+ return SHOW_MODAL_PREFIXES.some(p => id.startsWith(p));
37
+ }
38
+
39
+ let _shown = false;
40
+ let _initialized = false;
41
+
42
+ function _hasSeen() { return localStorage.getItem(HINT_SEEN_KEY) === '1'; }
43
+ function _markSeen() { try { localStorage.setItem(HINT_SEEN_KEY, '1'); } catch {} }
44
+
45
+ function _isVisible(el) {
46
+ if (!el || el.classList.contains('hidden')) return false;
47
+ // Some modals set inline display:none rather than .hidden
48
+ if (el.style.display === 'none') return false;
49
+ const r = el.getBoundingClientRect();
50
+ return r.width > 0 && r.height > 0;
51
+ }
52
+
53
+ function _onModalOpened(modal) {
54
+ if (_shown || _hasSeen()) return;
55
+ const id = modal.id;
56
+ if (!_modalShouldShowHint(id)) return;
57
+ // Don't interrupt the welcome / tour itself
58
+ if (document.body.classList.contains('tour-active')) return;
59
+ if (document.getElementById('tour-tooltip')) return;
60
+ // Mobile: skip — snapping isn't a desktop-only feature there
61
+ if (window.innerWidth <= 768) return;
62
+
63
+ _shown = true;
64
+ // Give the modal a moment to settle (some open with their own animation).
65
+ setTimeout(() => _show(modal), 380);
66
+ }
67
+
68
+ function _show(modal) {
69
+ if (_hasSeen()) return;
70
+ const content = modal.querySelector('.modal-content') || modal;
71
+ const r = content.getBoundingClientRect();
72
+
73
+ const pop = document.createElement('div');
74
+ pop.className = 'tour-hint';
75
+ pop.innerHTML = `
76
+ <div class="tour-hint-visual" aria-hidden="true">
77
+ <svg viewBox="0 0 100 60" width="160" height="96">
78
+ <!-- ambient frame -->
79
+ <rect x="0.5" y="0.5" width="99" height="59" rx="3" fill="none" stroke="currentColor" stroke-opacity="0.18" />
80
+ <!-- snap-zone preview (right half) -->
81
+ <rect class="th-zone" x="51" y="2" width="47" height="56" rx="2" fill="currentColor" opacity="0" />
82
+ <!-- the modal being dragged -->
83
+ <g class="th-modal-group">
84
+ <rect x="22" y="20" width="34" height="22" rx="2.5" fill="var(--bg)" stroke="currentColor" stroke-width="1.2" />
85
+ <rect x="22" y="20" width="34" height="5" rx="2.5" fill="currentColor" opacity="0.35" />
86
+ </g>
87
+ <!-- cursor -->
88
+ <path class="th-cursor" d="M0 0 L0 9 L2.5 7 L4.5 10 L6 9 L4 6 L7 6 Z" fill="currentColor" />
89
+ </svg>
90
+ </div>
91
+ <div class="tour-hint-text"><b>Pro tip:</b> drag any window's title bar to a screen edge to snap it. Drag to the top for fullscreen.</div>
92
+ <button class="tour-hint-dismiss" type="button">Got it</button>
93
+ `;
94
+ document.body.appendChild(pop);
95
+
96
+ // Prefer placing to the right of the modal; fall back to left, then below.
97
+ pop.style.opacity = '0';
98
+ requestAnimationFrame(() => {
99
+ const pw = pop.offsetWidth || 260;
100
+ const ph = pop.offsetHeight || 200;
101
+ let left = r.right + 14;
102
+ let top = r.top;
103
+ if (left + pw > window.innerWidth - 8) {
104
+ left = r.left - pw - 14;
105
+ if (left < 8) {
106
+ left = Math.max(8, r.left + (r.width - pw) / 2);
107
+ top = r.bottom + 14;
108
+ if (top + ph > window.innerHeight - 8) top = Math.max(8, r.top - ph - 14);
109
+ }
110
+ }
111
+ pop.style.left = left + 'px';
112
+ pop.style.top = top + 'px';
113
+ pop.style.opacity = '';
114
+ pop.classList.add('tour-hint-in');
115
+ });
116
+
117
+ const dismiss = () => {
118
+ pop.classList.add('tour-hint-out');
119
+ setTimeout(() => pop.remove(), 280);
120
+ _markSeen();
121
+ };
122
+ pop.querySelector('.tour-hint-dismiss').addEventListener('click', dismiss);
123
+ // Auto-dismiss after 14s so it doesn't linger forever.
124
+ setTimeout(() => { if (pop.isConnected) dismiss(); }, 14000);
125
+ }
126
+
127
+ function _watchModals() {
128
+ const observeModal = (modal) => {
129
+ if (!modal || modal.dataset.tourHintObserved === '1') return;
130
+ modal.dataset.tourHintObserved = '1';
131
+ observer.observe(modal, {
132
+ attributes: true,
133
+ attributeOldValue: true,
134
+ attributeFilter: ['class', 'style'],
135
+ });
136
+ if (_isVisible(modal)) _onModalOpened(modal);
137
+ };
138
+ const observer = new MutationObserver((muts) => {
139
+ if (_hasSeen() || _shown) return;
140
+ for (const m of muts) {
141
+ if (m.attributeName !== 'class' && m.attributeName !== 'style') continue;
142
+ const el = m.target;
143
+ if (!(el instanceof HTMLElement)) continue;
144
+ if (!el.classList.contains('modal')) continue;
145
+ const wasHidden = !m.oldValue || /\bhidden\b/.test(m.oldValue) || /display:\s*none/.test(m.oldValue);
146
+ if (wasHidden && _isVisible(el)) _onModalOpened(el);
147
+ }
148
+ });
149
+ document.querySelectorAll('.modal').forEach(observeModal);
150
+ const addObserver = new MutationObserver((muts) => {
151
+ if (_hasSeen() || _shown) return;
152
+ for (const m of muts) {
153
+ m.addedNodes.forEach(node => {
154
+ if (!(node instanceof HTMLElement)) return;
155
+ if (node.classList.contains('modal')) observeModal(node);
156
+ node.querySelectorAll?.('.modal').forEach(observeModal);
157
+ });
158
+ }
159
+ });
160
+ addObserver.observe(document.body, { childList: true, subtree: true });
161
+ }
162
+
163
+ export function init() {
164
+ if (_initialized) return;
165
+ _initialized = true;
166
+ if (_hasSeen()) return; // nothing to do
167
+ // Defer one tick so the rest of the app has a chance to mount its modals.
168
+ setTimeout(_watchModals, 50);
169
+ }
170
+
171
+ if (typeof window !== 'undefined') {
172
+ if (document.readyState === 'loading') {
173
+ document.addEventListener('DOMContentLoaded', init);
174
+ } else {
175
+ init();
176
+ }
177
+ }
178
+
179
+ export default { init };
@@ -0,0 +1,521 @@
1
+ // static/js/tts-ai.js
2
+ // AI Text-to-Speech Module — supports server TTS and browser Web Speech API
3
+
4
+ class AITTSManager {
5
+ constructor() {
6
+ this.currentAudio = null;
7
+ this.isPlaying = false;
8
+ this.available = false;
9
+ this.useBrowserTTS = false;
10
+ this.browserVoice = '';
11
+ this.playbackSpeed = 1;
12
+ this._provider = 'disabled';
13
+ this.autoPlay = false;
14
+ this.cache = new Map(); // Client-side audio cache
15
+
16
+ // Queue for sequential auto-play
17
+ this._queue = []; // Array of { text, button, resetFn }
18
+ this._processing = false;
19
+
20
+ // Streaming sentence-by-sentence TTS state
21
+ this._streamSentencesSent = 0; // chars of plain text already queued
22
+ this._streamActive = false;
23
+ this._streamButton = null;
24
+ this._streamResetFn = null;
25
+ this._streamDebounceTimer = null;
26
+
27
+ // Check if TTS service is available
28
+ this.checkAvailability();
29
+ }
30
+
31
+ async checkAvailability() {
32
+ try {
33
+ // Check user setting first — if TTS is disabled in settings, don't show buttons
34
+ try {
35
+ const settingsRes = await fetch('/api/auth/settings', { credentials: 'same-origin' });
36
+ const settings = await settingsRes.json();
37
+ if (settings.tts_enabled === false) {
38
+ this.available = false;
39
+ this._provider = 'disabled';
40
+ return;
41
+ }
42
+ } catch {}
43
+
44
+ const response = await fetch('/api/tts/stats');
45
+ const stats = await response.json();
46
+ this.available = stats.available && stats.ready;
47
+ this.playbackSpeed = stats.speed || 1;
48
+ this._provider = stats.provider || 'disabled';
49
+
50
+ if (stats.provider === 'browser') {
51
+ this.useBrowserTTS = true;
52
+ this.browserVoice = stats.voice || '';
53
+ this.available = 'speechSynthesis' in window;
54
+ if (!this.available) {
55
+ console.warn('TTS: browser mode selected but speechSynthesis not supported');
56
+ }
57
+ } else if (this.available) {
58
+ this.useBrowserTTS = false;
59
+ } else {
60
+ console.warn('TTS: not available');
61
+ }
62
+ } catch (error) {
63
+ console.error('Failed to check TTS availability:', error);
64
+ this.available = false;
65
+ }
66
+ }
67
+
68
+ extractPlainText(content) {
69
+ // Strip <think>/<thinking> blocks (model reasoning)
70
+ let cleaned = content.replace(/<think(?:ing)?>[\s\S]*?<\/think(?:ing)?>/gi, '');
71
+
72
+ // Create a temporary div to parse HTML/markdown
73
+ const temp = document.createElement('div');
74
+ temp.innerHTML = cleaned;
75
+
76
+ // Remove code blocks
77
+ temp.querySelectorAll('pre, code').forEach(el => el.remove());
78
+
79
+ // Get text content
80
+ let text = temp.textContent || temp.innerText || '';
81
+
82
+ // Clean up markdown syntax
83
+ text = text
84
+ .replace(/#{1,6}\s/g, '') // Remove headers
85
+ .replace(/\*\*(.+?)\*\*/g, '$1') // Remove bold
86
+ .replace(/\*(.+?)\*/g, '$1') // Remove italic
87
+ .replace(/\[(.+?)\]\(.+?\)/g, '$1') // Remove links
88
+ .replace(/`(.+?)`/g, '$1') // Remove inline code
89
+ .replace(/\n{3,}/g, '\n\n') // Normalize line breaks
90
+ .trim();
91
+
92
+ return text;
93
+ }
94
+
95
+ getCacheKey(text) {
96
+ // Simple hash function for cache key
97
+ let hash = 0;
98
+ for (let i = 0; i < text.length; i++) {
99
+ const char = text.charCodeAt(i);
100
+ hash = ((hash << 5) - hash) + char;
101
+ hash = hash & hash;
102
+ }
103
+ return hash.toString(36);
104
+ }
105
+
106
+ async synthesize(text, onProgress = null) {
107
+ if (!this.available) {
108
+ throw new Error('AI TTS service not available');
109
+ }
110
+
111
+ const plainText = this.extractPlainText(text);
112
+
113
+ if (!plainText) {
114
+ throw new Error('No text to synthesize');
115
+ }
116
+
117
+ // Browser TTS doesn't use synthesize — handled directly in play()
118
+ if (this.useBrowserTTS) {
119
+ return '__browser_tts__';
120
+ }
121
+
122
+ const cacheKey = this.getCacheKey(plainText);
123
+
124
+ // Check cache first
125
+ if (this.cache.has(cacheKey)) {
126
+ return this.cache.get(cacheKey);
127
+ }
128
+
129
+ try {
130
+ if (onProgress) onProgress('synthesizing');
131
+
132
+ const response = await fetch('/api/tts/synthesize', {
133
+ method: 'POST',
134
+ headers: {
135
+ 'Content-Type': 'application/json',
136
+ },
137
+ body: JSON.stringify({
138
+ text: plainText,
139
+ format: 'audio'
140
+ })
141
+ });
142
+
143
+ if (!response.ok) {
144
+ const error = await response.json();
145
+ throw new Error(error.detail?.message || 'Synthesis failed');
146
+ }
147
+
148
+ const audioBlob = await response.blob();
149
+ const audioUrl = URL.createObjectURL(audioBlob);
150
+
151
+ // Cache the result
152
+ this.cache.set(cacheKey, audioUrl);
153
+
154
+ if (onProgress) onProgress('complete');
155
+
156
+ return audioUrl;
157
+
158
+ } catch (error) {
159
+ if (onProgress) onProgress('error');
160
+ throw error;
161
+ }
162
+ }
163
+
164
+ _findBrowserVoice() {
165
+ if (!this.browserVoice) return null;
166
+ const voices = window.speechSynthesis.getVoices();
167
+ const target = this.browserVoice.toLowerCase();
168
+ // Try exact match first, then partial
169
+ return voices.find(v => v.name.toLowerCase() === target) ||
170
+ voices.find(v => v.name.toLowerCase().includes(target)) ||
171
+ null;
172
+ }
173
+
174
+ async play(text) {
175
+ // Stop current audio if playing
176
+ this.stop();
177
+
178
+ const plainText = this.extractPlainText(text);
179
+ if (!plainText) return;
180
+
181
+ if (this.useBrowserTTS) {
182
+ return this._playBrowser(plainText);
183
+ }
184
+
185
+ try {
186
+ const audioUrl = await this.synthesize(text);
187
+
188
+ this.currentAudio = new Audio(audioUrl);
189
+ await this.currentAudio.play();
190
+ this.isPlaying = true;
191
+ // Note: onended should be set by the caller (addAITTSButton)
192
+ // to reset button state when audio finishes
193
+
194
+ } catch (error) {
195
+ console.error('Failed to play audio:', error);
196
+ throw error;
197
+ }
198
+ }
199
+
200
+ _playBrowser(plainText) {
201
+ return new Promise((resolve, reject) => {
202
+ const utterance = new SpeechSynthesisUtterance(plainText);
203
+ const voice = this._findBrowserVoice();
204
+ if (voice) utterance.voice = voice;
205
+ utterance.rate = this.playbackSpeed;
206
+
207
+ utterance.onend = () => {
208
+ this.isPlaying = false;
209
+ resolve();
210
+ };
211
+ utterance.onerror = (e) => {
212
+ this.isPlaying = false;
213
+ reject(new Error('Browser TTS error: ' + e.error));
214
+ };
215
+
216
+ window.speechSynthesis.speak(utterance);
217
+ this.isPlaying = true;
218
+ });
219
+ }
220
+
221
+ stop() {
222
+ // Cancel streaming TTS
223
+ this._streamActive = false;
224
+ if (this._streamDebounceTimer) {
225
+ clearTimeout(this._streamDebounceTimer);
226
+ this._streamDebounceTimer = null;
227
+ }
228
+ this._streamSentencesSent = 0;
229
+
230
+ // Clear the entire queue and reset all queued buttons
231
+ for (const item of this._queue) {
232
+ if (item.resetFn) item.resetFn();
233
+ }
234
+ this._queue = [];
235
+ this._processing = false;
236
+
237
+ if (this.useBrowserTTS) {
238
+ window.speechSynthesis.cancel();
239
+ this.isPlaying = false;
240
+ }
241
+ if (this.currentAudio) {
242
+ this.currentAudio.pause();
243
+ this.currentAudio.currentTime = 0;
244
+ this.currentAudio = null;
245
+ this.isPlaying = false;
246
+ }
247
+ }
248
+
249
+ /**
250
+ * Enqueue a message for auto-play. Plays sequentially — each message
251
+ * finishes before the next starts. Stopping any message clears the queue.
252
+ */
253
+ enqueue(text, button, resetFn) {
254
+ this._queue.push({ text, button, resetFn });
255
+ if (!this._processing) {
256
+ this._processQueue();
257
+ }
258
+ }
259
+
260
+ async _processQueue() {
261
+ if (this._processing) return;
262
+ this._processing = true;
263
+
264
+ while (this._queue.length > 0) {
265
+ const item = this._queue[0];
266
+ try {
267
+ await this._playQueueItem(item);
268
+ } catch (err) {
269
+ console.error('TTS queue item error:', err);
270
+ }
271
+ if (this._queue.length > 0 && this._queue[0] === item) {
272
+ this._queue.shift();
273
+ }
274
+ if (!this._processing) return;
275
+ }
276
+
277
+ this._processing = false;
278
+ }
279
+
280
+ async _playQueueItem(item) {
281
+ const { text, button, resetFn } = item;
282
+ const ICON_LOADING = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><circle cx="12" cy="12" r="9" stroke-dasharray="42" stroke-dashoffset="12" stroke-linecap="round"><animateTransform attributeName="transform" type="rotate" from="0 12 12" to="360 12 12" dur="0.8s" repeatCount="indefinite"/></circle></svg>';
283
+ var ICON_STOP = '<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="none"><rect x="5" y="5" width="14" height="14" rx="2"/></svg>';
284
+
285
+ button.innerHTML = ICON_LOADING;
286
+ button.classList.add('loading');
287
+ button.style.color = '#ccc';
288
+ button.title = 'Loading...';
289
+
290
+ try {
291
+ if (!this._processing) return;
292
+
293
+ const audioUrl = await this.synthesize(text);
294
+
295
+ if (!this._processing) return;
296
+
297
+ button.innerHTML = ICON_STOP;
298
+ button.classList.remove('loading');
299
+ button.classList.add('playing');
300
+ button.title = 'Stop';
301
+
302
+ if (this.useBrowserTTS) {
303
+ const plainText = this.extractPlainText(text);
304
+ await this._playBrowser(plainText);
305
+ } else {
306
+ if (this.currentAudio) {
307
+ this.currentAudio.pause();
308
+ this.currentAudio = null;
309
+ }
310
+
311
+ await new Promise((resolve, reject) => {
312
+ const audio = new Audio(audioUrl);
313
+ if (this._provider === 'local' && this.playbackSpeed !== 1) {
314
+ audio.playbackRate = this.playbackSpeed;
315
+ }
316
+ this.currentAudio = audio;
317
+ audio.onended = () => {
318
+ this.isPlaying = false;
319
+ if (this.currentAudio === audio) this.currentAudio = null;
320
+ resolve();
321
+ };
322
+ audio.onerror = (e) => {
323
+ this.isPlaying = false;
324
+ if (this.currentAudio === audio) this.currentAudio = null;
325
+ reject(new Error('Audio playback error'));
326
+ };
327
+ audio.onpause = () => {
328
+ if (this.currentAudio !== audio) {
329
+ resolve();
330
+ }
331
+ };
332
+ audio.play().then(() => {
333
+ this.isPlaying = true;
334
+ }).catch(reject);
335
+ });
336
+ }
337
+ } finally {
338
+ if (resetFn) resetFn();
339
+ }
340
+ }
341
+
342
+ // ── Streaming TTS (sentence-by-sentence) ──
343
+
344
+ streamingStart() {
345
+ this._streamSentencesSent = 0;
346
+ this._streamActive = true;
347
+ this._streamButton = null;
348
+ this._streamResetFn = null;
349
+ }
350
+
351
+ streamingUpdate(accumulatedText) {
352
+ if (!this._streamActive || !this.available || !this.autoPlay) return;
353
+ if (this._streamDebounceTimer) return;
354
+ this._streamDebounceTimer = setTimeout(() => {
355
+ this._streamDebounceTimer = null;
356
+ this._processStreamingSentences(accumulatedText);
357
+ }, 150);
358
+ }
359
+
360
+ _processStreamingSentences(accumulatedText) {
361
+ if (!this._streamActive) return;
362
+
363
+ var text = accumulatedText
364
+ .replace(/```[\s\S]*?```/g, '')
365
+ .replace(/```[\s\S]*$/g, '');
366
+
367
+ var plainText = this.extractPlainText(text);
368
+ if (!plainText || plainText.length <= this._streamSentencesSent) return;
369
+
370
+ var newRegion = plainText.substring(this._streamSentencesSent);
371
+
372
+ var sentences = [];
373
+ var current = '';
374
+ for (var i = 0; i < newRegion.length; i++) {
375
+ current += newRegion[i];
376
+ var ch = newRegion[i];
377
+ var next = newRegion[i + 1];
378
+ if ((ch === '.' || ch === '!' || ch === '?') && next && /\s/.test(next)) {
379
+ var lastWord = current.trim().split(/\s/).pop() || '';
380
+ if (/^\d+\.$/.test(lastWord)) continue;
381
+ if (/^[A-Z][a-z]?\.$/.test(lastWord)) continue;
382
+ sentences.push(current.trim());
383
+ current = '';
384
+ }
385
+ }
386
+
387
+ if (sentences.length === 0) return;
388
+
389
+ var advancedChars = 0;
390
+ for (var j = 0; j < sentences.length; j++) {
391
+ var sentence = sentences[j];
392
+ if (sentence.length < 15) {
393
+ advancedChars += sentence.length + 1;
394
+ continue;
395
+ }
396
+ var btn = this._streamButton || this._createPlaceholderButton();
397
+ var resetFn = this._streamResetFn || function() {};
398
+ this.enqueue(sentence, btn, resetFn);
399
+ advancedChars += sentence.length + 1;
400
+ }
401
+
402
+ this._streamSentencesSent += advancedChars;
403
+ }
404
+
405
+ _createPlaceholderButton() {
406
+ var btn = document.createElement('button');
407
+ btn.style.display = 'none';
408
+ btn.className = 'ai-tts-button streaming-placeholder';
409
+ return btn;
410
+ }
411
+
412
+ streamingAttachButton(button, resetFn) {
413
+ this._streamButton = button;
414
+ this._streamResetFn = resetFn;
415
+ for (var i = 0; i < this._queue.length; i++) {
416
+ if (this._queue[i].button && this._queue[i].button.classList.contains('streaming-placeholder')) {
417
+ this._queue[i].button = button;
418
+ this._queue[i].resetFn = resetFn;
419
+ }
420
+ }
421
+ }
422
+
423
+ streamingEnd(finalText) {
424
+ if (!this._streamActive) return;
425
+ this._streamActive = false;
426
+ if (this._streamDebounceTimer) {
427
+ clearTimeout(this._streamDebounceTimer);
428
+ this._streamDebounceTimer = null;
429
+ }
430
+
431
+ var text = finalText
432
+ .replace(/```[\s\S]*?```/g, '')
433
+ .replace(/```[\s\S]*$/g, '');
434
+
435
+ var plainText = this.extractPlainText(text);
436
+ if (!plainText) return;
437
+
438
+ var remaining = plainText.substring(this._streamSentencesSent).trim();
439
+ if (remaining.length >= 15) {
440
+ var btn = this._streamButton || this._createPlaceholderButton();
441
+ var resetFn = this._streamResetFn || function() {};
442
+ this.enqueue(remaining, btn, resetFn);
443
+ }
444
+ this._streamSentencesSent = 0;
445
+ }
446
+
447
+ clearCache() {
448
+ for (const url of this.cache.values()) {
449
+ URL.revokeObjectURL(url);
450
+ }
451
+ this.cache.clear();
452
+ }
453
+ }
454
+
455
+ // Create global AI TTS manager instance
456
+ window.aiTTSManager = new AITTSManager();
457
+
458
+ // Function to add AI TTS button to a message element's action bar
459
+ export function addAITTSButton(messageElement, text) {
460
+ if (!window.aiTTSManager.available || window.aiTTSManager._provider === 'disabled') {
461
+ return;
462
+ }
463
+
464
+ if (messageElement.querySelector('.ai-tts-button')) {
465
+ return;
466
+ }
467
+
468
+ // Find the msg-actions container in the footer
469
+ const actions = messageElement.querySelector('.msg-actions');
470
+ if (!actions) return;
471
+
472
+ var ICON_PLAY = '<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="none"><polygon points="6 3 20 12 6 21 6 3"/></svg>';
473
+ var ICON_STOP = '<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="none"><rect x="5" y="5" width="14" height="14" rx="2"/></svg>';
474
+ var ICON_LOADING = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><circle cx="12" cy="12" r="9" stroke-dasharray="42" stroke-dashoffset="12" stroke-linecap="round"><animateTransform attributeName="transform" type="rotate" from="0 12 12" to="360 12 12" dur="0.8s" repeatCount="indefinite"/></circle></svg>';
475
+
476
+ const playButton = document.createElement('button');
477
+ playButton.className = 'ai-tts-button';
478
+ playButton.type = 'button';
479
+ playButton.title = 'Read aloud';
480
+ playButton.innerHTML = ICON_PLAY;
481
+ playButton.style.cssText = 'background:none;border:none;color:#6b7280;cursor:pointer;padding:2px 6px;border-radius:4px;transition:color .15s;line-height:1;display:inline-flex;align-items:center;';
482
+
483
+ playButton.addEventListener('mouseenter', () => { playButton.style.color = '#ccc'; });
484
+ playButton.addEventListener('mouseleave', () => {
485
+ if (!playButton.classList.contains('playing') && !playButton.classList.contains('loading')) playButton.style.color = '#6b7280';
486
+ });
487
+
488
+ function resetButton() {
489
+ playButton.innerHTML = ICON_PLAY;
490
+ playButton.classList.remove('playing', 'loading');
491
+ playButton.style.color = '#6b7280';
492
+ playButton.title = 'Read aloud';
493
+ }
494
+
495
+ playButton.addEventListener('click', async (e) => {
496
+ e.stopPropagation();
497
+ const mgr = window.aiTTSManager;
498
+
499
+ if (mgr.isPlaying || mgr._processing) {
500
+ mgr.stop();
501
+ resetButton();
502
+ return;
503
+ }
504
+
505
+ mgr.enqueue(text, playButton, resetButton);
506
+ });
507
+
508
+ actions.appendChild(playButton);
509
+ }
510
+
511
+ // Stop audio when navigating away
512
+ window.addEventListener('beforeunload', () => {
513
+ if (window.aiTTSManager) {
514
+ window.aiTTSManager.stop();
515
+ }
516
+ });
517
+
518
+ export { AITTSManager };
519
+
520
+ const ttsModule = { AITTSManager, addAITTSButton };
521
+ export default ttsModule;