@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,27 @@
1
+ // static/js/emailLibrary/replyRecipients.js
2
+ //
3
+ // Pure helpers for building reply-all recipient lists. No DOM, no fetch,
4
+ // no shared state — safe to import anywhere and to unit-test under node.
5
+
6
+ // Extract the bare email from "Name <email@x>" or a plain "email@x".
7
+ export function extractEmail(addr) {
8
+ const m = (addr || '').match(/<([^>]+)>/);
9
+ return (m ? m[1] : (addr || '')).trim().toLowerCase();
10
+ }
11
+
12
+ // Reply-all CC = everyone on the original To + Cc, minus ourselves, with the
13
+ // original "Name <email>" form preserved.
14
+ //
15
+ // `mine` is a single address or a list of the user's own addresses (a
16
+ // multi-account user has more than one). Empty/unknown ⇒ no exclusion.
17
+ // Comparing by exact extracted email (not a substring `includes`) is what
18
+ // fixes issue #360: an empty self address made `"...".includes("")` true for
19
+ // every recipient, so reply-all dropped the entire Cc list.
20
+ export function buildReplyAllCc(data, mine) {
21
+ const list = Array.isArray(mine) ? mine : [mine];
22
+ const me = new Set(list.map((a) => (a || '').toLowerCase()).filter(Boolean));
23
+ const split = (s) => (typeof s === 'string' ? s : '').split(',').map((x) => x.trim()).filter(Boolean);
24
+ return [...split(data && data.to), ...split(data && data.cc)]
25
+ .filter((addr) => !me.has(extractEmail(addr)))
26
+ .join(', ');
27
+ }
@@ -0,0 +1,339 @@
1
+ // static/js/emailLibrary/signatureFold.js
2
+ //
3
+ // Heuristics that turn raw HTML email bodies into folded structures —
4
+ // "Earlier reply" details collapsing the quoted history, and "Signature"
5
+ // details collapsing the trailing corporate disclaimer / boilerplate.
6
+ //
7
+ // All pure functions of HTML strings (and one DOM-mutating exception:
8
+ // `_harvestAttribution` peels nodes off a container). No module state,
9
+ // no fetch, no globals. The icons (`_SIG_ICON`, `_QUOTE_ICON`) live here
10
+ // since `_foldSummary` is the only caller and other modules pass them in
11
+ // via that helper.
12
+
13
+ import {
14
+ _TALON_WROTE, _TALON_FROM, _TALON_SENT, _TALON_ORIG_RE,
15
+ _SIG_BLOAT_MIN_CHARS,
16
+ } from './utils.js';
17
+
18
+ // No leading icon on the signature fold — the user explicitly does not
19
+ // want a star/emoji-style glyph in this header.
20
+ export const _SIG_ICON = '';
21
+ export const _QUOTE_ICON = '<svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 17 4 12 9 7"/><path d="M20 18v-2a4 4 0 0 0-4-4H4"/></svg>';
22
+
23
+ // HTML-escape used by `_extractQuoteMeta`. Inlined here (rather than
24
+ // imported from utils) so this module remains free of cross-file links.
25
+ function _esc(text) {
26
+ const div = document.createElement('div');
27
+ div.textContent = text || '';
28
+ return div.innerHTML;
29
+ }
30
+
31
+ // Looks like a signature / corporate disclaimer rather than a quoted email.
32
+ // Heuristic: scores known "this is a disclaimer" tells against
33
+ // "this is a real email" tells. 3+ disclaimer hits with ≤1 conversational
34
+ // hit → signature.
35
+ export function _looksLikeSignature(html) {
36
+ if (!html) return false;
37
+ const txt = String(html).replace(/<[^>]+>/g, ' ').replace(/\s+/g, ' ').trim();
38
+ if (!txt) return false;
39
+ let score = 0;
40
+ const SIG_TELLS = [
41
+ /\bregistered\s+in\b/i,
42
+ /\blimited\s+liability\s+partnership\b/i,
43
+ /\b(Pte\.?\s*Ltd|GmbH|S\.A\.|S\.A\.S|LLC|LLP|Inc\.?)\b/,
44
+ /\bintended\s+solely\s+for\b/i,
45
+ /\bconfidential(?:ity)?\s+(?:notice|information)\b/i,
46
+ /\b(?:disclaimer|please\s+(?:notify|delete))\b/i,
47
+ /\bunsubscribe\b/i,
48
+ /\bUEN\b\s*\w/i,
49
+ /\b\+\d[\d\s().-]{6,}\b/, // phone number
50
+ ];
51
+ for (const re of SIG_TELLS) if (re.test(txt)) score++;
52
+ const PRIOR_TELLS = [
53
+ /\bHi\s+[A-Z][a-z]+\b/,
54
+ /\bDear\s+[A-Z][a-z]+\b/,
55
+ /\bRegards\b/i,
56
+ /\?\s*$/,
57
+ ];
58
+ let priorScore = 0;
59
+ for (const re of PRIOR_TELLS) if (re.test(txt)) priorScore++;
60
+ return score >= 3 && priorScore <= 1;
61
+ }
62
+
63
+ // Look for an "On <date>, <addr> wrote:" line at the END of a fragment
64
+ // and remove it (returning the captured meta string, or null). Also
65
+ // handles Outlook-style "From: ... Sent: ... Subject: ..." blocks.
66
+ export function _harvestAttribution(container) {
67
+ const text = container.textContent || '';
68
+ const wroteLineRe = new RegExp(`${_TALON_WROTE}\\s*:\\s*$|${_TALON_WROTE}\\s*:\\s*<`, 'i');
69
+ const lastLines = text.trim().split('\n').slice(-3).join('\n');
70
+ if (!wroteLineRe.test(lastLines)) {
71
+ const outlookHeadRe = new RegExp(`${_TALON_FROM}\\s*:.*?${_TALON_SENT}\\s*:`, 'is');
72
+ if (!outlookHeadRe.test(text.split('\n').slice(-12).join('\n'))) {
73
+ if (!_TALON_ORIG_RE.test(text)) return null;
74
+ }
75
+ }
76
+ const trailing = [];
77
+ for (let i = container.childNodes.length - 1; i >= 0; i--) {
78
+ const node = container.childNodes[i];
79
+ const t = (node.textContent || '').trim();
80
+ if (!t) { trailing.unshift(node); continue; }
81
+ trailing.unshift(node);
82
+ if (trailing.map(n => n.textContent || '').join('\n').length > 600) break;
83
+ }
84
+ const meta = _extractQuoteMeta(trailing.map(n => n.outerHTML || n.textContent || '').join(''));
85
+ for (const n of trailing) {
86
+ try { container.removeChild(n); } catch {}
87
+ }
88
+ return meta || null;
89
+ }
90
+
91
+ export function _extractTurnMetaFromBlockquote(bq) {
92
+ const html = bq.innerHTML.slice(0, 2000);
93
+ const meta = _extractQuoteMeta(html);
94
+ return meta || null;
95
+ }
96
+
97
+ // "Earlier reply" / "Signature" summary header — caller supplies the
98
+ // label string + icon SVG. `meta`, when present, is split on " · " to
99
+ // promote the sender's name to the headline.
100
+ export function _foldSummary(label, iconSvg, meta) {
101
+ let primary = label;
102
+ let subMeta = meta || '';
103
+ if (meta) {
104
+ const idx = meta.indexOf(' · ');
105
+ if (idx > 0) {
106
+ primary = meta.slice(0, idx);
107
+ subMeta = meta.slice(idx + 3);
108
+ } else if (meta.length <= 80 && !/^\d/.test(meta)) {
109
+ primary = meta;
110
+ subMeta = '';
111
+ }
112
+ }
113
+ // `meta` is derived from _extractQuoteMeta, which strips tags but then
114
+ // un-escapes entities (to recover `<foo@bar.com>` for bubble alignment) —
115
+ // so it can carry attacker-controlled angle brackets from a quoted block.
116
+ // This summary is built into innerHTML, so escape both parts to stop a
117
+ // crafted quote (e.g. `From: <img src=x onerror=...>`) from running script.
118
+ const metaSpan = subMeta
119
+ ? `<span class="email-fold-summary-meta">${_esc(subMeta)}</span>`
120
+ : '';
121
+ return (
122
+ '<summary class="email-fold-summary">'
123
+ + iconSvg
124
+ + `<span class="email-fold-summary-name">${_esc(primary)}</span>`
125
+ + metaSpan
126
+ + '<svg class="email-summary-chevron" width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" style="margin-left:auto;transition:transform .15s ease;"><polyline points="6 9 12 15 18 9"/></svg>'
127
+ + '</summary>'
128
+ );
129
+ }
130
+
131
+ // Extract sender + date from a quoted email block. Tries Outlook-style
132
+ // "From: X · Sent: Y" header first, falls back to Gmail-style
133
+ // "On <date>, <addr> wrote:". Returns a display string like
134
+ // "Jane Doe · Mon, Apr 18, 2026 at 9:31 AM" or `''`.
135
+ export function _extractQuoteMeta(html) {
136
+ if (typeof html !== 'string' || !html) return '';
137
+ const txt = html
138
+ .replace(/<style[\s\S]*?<\/style>/gi, '')
139
+ .replace(/<[^>]+>/g, ' ')
140
+ .replace(/&nbsp;/gi, ' ')
141
+ .replace(/&amp;/gi, '&')
142
+ .replace(/&lt;/gi, '<')
143
+ .replace(/&gt;/gi, '>')
144
+ .replace(/&quot;/gi, '"')
145
+ .replace(/\s+/g, ' ')
146
+ .slice(0, 1500);
147
+
148
+ const FROM = '(?:From|Från|Von|De|Da|От|Od|Van)';
149
+ const SENT = '(?:Sent|Skickat|Gesendet|Envoyé|Inviato|Enviado|Verzonden|Отправлено|Wysłane|Date)';
150
+ const STOP = `(?=\\s+(?:To|Cc|Bcc|Subject|Ämne|Betreff|Objet|Oggetto|Asunto|Onderwerp|Тема|Temat|${SENT})\\s*:)`;
151
+ const fromMatch = txt.match(new RegExp(`${FROM}\\s*:\\s*(.+?)${STOP}`, 'i'));
152
+ const sentMatch = txt.match(new RegExp(`${SENT}\\s*:\\s*([^\\n]+?)(?=\\s+(?:To|Cc|Bcc|Subject|Ämne|Betreff|Objet|Oggetto|Asunto|Onderwerp|Тема|Temat)\\s*:)`, 'i'));
153
+ let from = fromMatch ? fromMatch[1].trim() : '';
154
+ let date = sentMatch ? sentMatch[1].trim() : '';
155
+
156
+ if (!from && !date) {
157
+ // The date may carry up to three commas before the year: the standard
158
+ // US Gmail attribution is "On Mon, Apr 18, 2026 at 9:31 AM, Jane wrote:"
159
+ // (weekday and day-of-month each add one). A single-comma pattern never
160
+ // reached the year there, so the fold lost its sender/date headline.
161
+ const gmail = txt.match(/On\s+((?:[^,]*,){0,3}?[^,]*?\d{4}[^,]*),?\s+(.+?)\s+wrote\s*:/i);
162
+ if (gmail) { date = gmail[1].trim(); from = gmail[2].trim(); }
163
+ }
164
+
165
+ from = from.replace(/[<>]/g, '').replace(/\s+/g, ' ').trim();
166
+ date = date.replace(/\s+/g, ' ').trim();
167
+ if (from.length > 60) from = from.slice(0, 57) + '…';
168
+ if (date.length > 28) date = date.slice(0, 25) + '…';
169
+
170
+ // Return the raw sender/date text; `_foldSummary` is the single sink that
171
+ // builds these into HTML, so it owns escaping. Escaping here too would
172
+ // double-encode (e.g. "Ben & Jerry" -> "Ben &amp;amp; Jerry").
173
+ if (from && date) return `${from} · ${date}`;
174
+ if (from) return from;
175
+ if (date) return date;
176
+ return '';
177
+ }
178
+
179
+ // Peel the first non-empty line off the signature tail. That line is
180
+ // usually the signer's name — keep it inline so "Kind regards, / Bob"
181
+ // reads naturally. Returns `{ preBloat, bloat }` — `bloat` is what
182
+ // should go into the fold; `preBloat` stays visible above it.
183
+ export function _peelSigNameLine(htmlAfterClosing) {
184
+ if (!htmlAfterClosing) return { preBloat: '', bloat: '' };
185
+ const breakRe = /<br\s*\/?>|<\/p>|<\/div>|\n/gi;
186
+ let cursor = 0;
187
+ let nameConsumed = false;
188
+ let mm;
189
+ while ((mm = breakRe.exec(htmlAfterClosing)) !== null) {
190
+ const seg = htmlAfterClosing.slice(cursor, mm.index)
191
+ .replace(/<[^>]+>/g, '').replace(/&nbsp;/gi, ' ').trim();
192
+ if (seg.length > 0) {
193
+ const looksBloat = /[@]|tel\.?:|mobile:|phone:|www\.|https?:\/\/|sent from|^\+?\d[\d \-().]{6,}$/i.test(seg);
194
+ if (looksBloat) {
195
+ return {
196
+ preBloat: htmlAfterClosing.slice(0, cursor),
197
+ bloat: htmlAfterClosing.slice(cursor),
198
+ };
199
+ }
200
+ if (!nameConsumed) {
201
+ nameConsumed = true;
202
+ const off = mm.index + mm[0].length;
203
+ return {
204
+ preBloat: htmlAfterClosing.slice(0, off),
205
+ bloat: htmlAfterClosing.slice(off),
206
+ };
207
+ }
208
+ }
209
+ cursor = mm.index + mm[0].length;
210
+ }
211
+ return { preBloat: htmlAfterClosing, bloat: '' };
212
+ }
213
+
214
+ export function _isBloatedSig(htmlFragment) {
215
+ if (!htmlFragment) return false;
216
+ const plain = htmlFragment
217
+ .replace(/<style[\s\S]*?<\/style>/gi, '')
218
+ .replace(/<script[\s\S]*?<\/script>/gi, '')
219
+ .replace(/<[^>]+>/g, ' ')
220
+ .replace(/&nbsp;/gi, ' ')
221
+ .replace(/&amp;/g, '&').replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&quot;/g, '"')
222
+ .replace(/\s+/g, ' ')
223
+ .trim();
224
+ return plain.length >= _SIG_BLOAT_MIN_CHARS;
225
+ }
226
+
227
+ // Try folding using a per-sender cached signature (built by the
228
+ // `learn_sender_signatures` action). When the cached text is found near
229
+ // the end of `html`, slice there and wrap the tail in a details fold.
230
+ // Returns the wrapped HTML or null when the hint doesn't apply.
231
+ export function _tryFoldHintSig(html, hintSig) {
232
+ if (!html || !hintSig || typeof hintSig !== 'string') return null;
233
+ if (hintSig.length < 20) return null;
234
+ const lines = hintSig.split(/\r?\n/).map(s => s.trim()).filter(Boolean);
235
+ const closingsRe = /^(?:Best regards|Best wishes|Kind regards|Yours (?:truly|sincerely|faithfully)|Sincerely|Cheers|Thanks|Thank you|Regards|Warm regards|Many thanks|Take care)[,!.\s]*$/i;
236
+ const anchor = (lines.find(l => l.length >= 8 && !closingsRe.test(l)) || lines[0] || '').trim();
237
+ if (anchor.length < 8) return null;
238
+ const plain = [];
239
+ const map = [];
240
+ let i = 0;
241
+ while (i < html.length) {
242
+ if (html[i] === '<') {
243
+ if (/^<br\s*\/?\s*>/i.test(html.slice(i, i + 6))) {
244
+ plain.push('\n'); map.push(i);
245
+ const e = html.indexOf('>', i);
246
+ i = e + 1;
247
+ continue;
248
+ }
249
+ const e = html.indexOf('>', i);
250
+ if (e < 0) break;
251
+ i = e + 1;
252
+ continue;
253
+ }
254
+ if (html[i] === '&') {
255
+ const semi = html.indexOf(';', i);
256
+ if (semi > 0 && semi - i < 8) {
257
+ const ent = html.slice(i + 1, semi);
258
+ const dec = ({nbsp: ' ', amp: '&', lt: '<', gt: '>', quot: '"', apos: "'"})[ent];
259
+ if (dec !== undefined) {
260
+ plain.push(dec); map.push(i);
261
+ i = semi + 1;
262
+ continue;
263
+ }
264
+ }
265
+ }
266
+ plain.push(html[i]); map.push(i);
267
+ i++;
268
+ }
269
+ const plainStr = plain.join('');
270
+ const idx = plainStr.lastIndexOf(anchor);
271
+ if (idx < 0) return null;
272
+ const htmlStart = map[idx];
273
+ if (htmlStart == null) return null;
274
+ const before = html.slice(0, htmlStart);
275
+ const sigSection = html.slice(htmlStart);
276
+ if (!_isBloatedSig(sigSection)) return null;
277
+ return before + '<details class="email-sig-fold">'
278
+ + _foldSummary('Signature', _SIG_ICON)
279
+ + sigSection + '</details>';
280
+ }
281
+
282
+ // Top-level signature fold — runs through several detection strategies
283
+ // in priority order. Returns the original html unchanged when no
284
+ // strategy fires.
285
+ export function _foldSignature(html, hintSig) {
286
+ if (!html || typeof html !== 'string') return html;
287
+ if (html.length > 80000) return html;
288
+ if (hintSig) {
289
+ const wrapped = _tryFoldHintSig(html, hintSig);
290
+ if (wrapped !== null) return wrapped;
291
+ }
292
+ const wrap = (before, marker, rest) => {
293
+ if (!_isBloatedSig(rest)) return html;
294
+ return before + (marker || '') + '<details class="email-sig-fold">'
295
+ + _foldSummary('Signature', _SIG_ICON) + rest + '</details>';
296
+ };
297
+
298
+ let m = html.match(/<div[^>]*class=["'][^"']*\bgmail_signature\b[^"']*["'][\s\S]*$/i);
299
+ if (m) return wrap(html.slice(0, html.length - m[0].length), '', m[0]);
300
+ m = html.match(/<div[^>]*data-smartmail=["']gmail_signature["'][\s\S]*$/i);
301
+ if (m) return wrap(html.slice(0, html.length - m[0].length), '', m[0]);
302
+ m = html.match(/<div[^>]*id=["'](?:Signature|signature|divRplyFwdMsg)["'][\s\S]*$/i);
303
+ if (m) return wrap(html.slice(0, html.length - m[0].length), '', m[0]);
304
+
305
+ m = html.match(/(<br\s*\/?>|\n)\s*--\s*(<br\s*\/?>|\n)([\s\S]*)$/i);
306
+ if (m) {
307
+ const idx = html.lastIndexOf(m[0]);
308
+ return wrap(html.slice(0, idx), m[1], m[3]);
309
+ }
310
+
311
+ const blockBoundary = '(?:<br\\s*/?>|<\\/p>|<\\/div>|<\\/li>|<p[^>]*>|<div[^>]*>|<span[^>]*>|\\n)';
312
+ const closings = '(?:Best regards|Best wishes|Kind regards|Yours truly|Yours sincerely|Yours faithfully|Best,|Best\\s|Cheers,|Cheers\\s|Thanks,|Thanks\\s|Thank you,|Regards,|Regards\\s|Sincerely[, ]|Warm regards|Many thanks|Talk soon|Take care)';
313
+ m = html.match(new RegExp(`(${blockBoundary})\\s*(${closings})([\\s\\S]+)$`, 'i'));
314
+ if (m) {
315
+ const idx = html.lastIndexOf(m[0]);
316
+ const boundary = m[1];
317
+ const closing = m[2];
318
+ const after = m[3];
319
+ const { preBloat, bloat } = _peelSigNameLine(after);
320
+ if (!_isBloatedSig(bloat)) return html;
321
+ return html.slice(0, idx) + boundary + closing + preBloat
322
+ + '<details class="email-sig-fold">' + _foldSummary('Signature', _SIG_ICON)
323
+ + bloat + '</details>';
324
+ }
325
+
326
+ m = html.match(new RegExp(`(${blockBoundary})\\s*((?:Sent from my (?:iPhone|iPad|Android|Galaxy|Pixel|phone|mobile)|Get Outlook for (?:iOS|Android))[\\s\\S]*)$`, 'i'));
327
+ if (m) {
328
+ const idx = html.lastIndexOf(m[0]);
329
+ return wrap(html.slice(0, idx), m[1], m[2]);
330
+ }
331
+
332
+ m = html.match(new RegExp(`(${blockBoundary})\\s*((?:CONFIDENTIALITY NOTICE|DISCLAIMER|This e-?mail (?:is confidential|may contain confidential)|The information (?:contained )?in this e-?mail|This message and any attachments)[\\s\\S]*)$`, 'i'));
333
+ if (m) {
334
+ const idx = html.lastIndexOf(m[0]);
335
+ return wrap(html.slice(0, idx), m[1], m[2]);
336
+ }
337
+
338
+ return html;
339
+ }
@@ -0,0 +1,34 @@
1
+ // static/js/emailLibrary/state.js
2
+ //
3
+ // Shared mutable state for the email-library popup. Keeping these on a
4
+ // single exported object lets sibling modules (utils, signatureFold,
5
+ // future render/menu/composer splits) read and write the same values
6
+ // without each one importing 19 `let` bindings — which ES modules
7
+ // don't allow from outside the defining module anyway.
8
+ //
9
+ // Writes look like `state._libOpen = true` everywhere; reads look like
10
+ // `state._libOpen`. The names match the originals so the refactor is a
11
+ // pure rename, not a semantic change.
12
+
13
+ export const state = {
14
+ _libOpen: false,
15
+ _libJustOpened: false,
16
+ _libEmails: [],
17
+ _libTotal: 0,
18
+ _libOffset: 0,
19
+ _libFolder: 'INBOX',
20
+ _libFolders: [],
21
+ _libAccountId: null, // null = backend default account
22
+ _libAccounts: [], // list of accounts for the chip strip
23
+ _libPendingExpandUid: null,
24
+ _libSearch: '',
25
+ _libFilter: 'all', // all, unread, unanswered
26
+ _libSort: 'recent', // recent, unread, favorites
27
+ _libHasAttachments: false,
28
+ _libLoading: false,
29
+ _docModule: null,
30
+ _onEmailClick: null,
31
+ _libEscHandler: null,
32
+ _selectMode: false,
33
+ _selectedUids: new Set(),
34
+ };
@@ -0,0 +1,202 @@
1
+ // static/js/emailLibrary/utils.js
2
+ //
3
+ // Pure helpers extracted from emailLibrary.js. No DOM state, no fetch,
4
+ // no shared mutable references — safe to import anywhere.
5
+
6
+ // ── Talon-inspired multilingual quote-detection regexes ───────────
7
+ // Borrowed (loosely) from Mailgun's `talon` library. These are partial
8
+ // regex source strings — combined with surrounding patterns by callers.
9
+ // Multilingual on purpose: a typed "wrote:" line is locale-bound, and
10
+ // people forward / reply across language settings all the time.
11
+
12
+ export const _TALON_WROTE = '(?:wrote|écrit|escribió|scrisse|schrieb|skrev|schreef|napisał|написал|napsal|написа|έγραψε|katselivat|napisao|написав|napisała|napisali|hat geschrieben|kirjoitti|написала|escreveu|napisao|написа|написала)';
13
+
14
+ export const _TALON_FROM = '(?:From|Från|Von|De|Da|От|Od|Van|差出人|发件人|寄件人|Ut|Frá|Lähettäjä|Avsender|Pošiljatelj|Од|Від|Posiljatelj|Frå)';
15
+ export const _TALON_SENT = '(?:Sent|Skickat|Gesendet|Envoy[ée]|Inviato|Enviado|Verzonden|Отправлено|Wysłane|Date|送信日時|发送时间|寄件日期|Sendt|Lähetetty|Tarih|Datum|Data|Datum)';
16
+ export const _TALON_SUBJ = '(?:Subject|Ämne|Betreff|Objet|Oggetto|Asunto|Onderwerp|Тема|Temat|件名|主题|主旨|Emne|Aihe|Onderwerp|Konu)';
17
+ export const _TALON_TO = '(?:To|Till|An|À|A|Voor|Para|Naar|Кому|Do|宛先|收件人|Emri|Komu)';
18
+ export const _TALON_ORIG_RE = /(?:^|\n)[\s>]*[-_=]{3,}\s*(?:Original\s+Message|Forwarded\s+message|Ursprüngliche\s+Nachricht|Mensaje\s+original|Messaggio\s+originale|Message\s+d['’]origine|Oorspronkelijk\s+bericht|Original\s+meddelande|Vor[ ]asal[a]\s+meddelande|原文|原始邮件|転送)\s*[-_=]{3,}/i;
19
+
20
+ // Minimum plain-text length of a "signature" before we bother folding it.
21
+ // Short closings ("Cheers, John") stay inline — folding them would add
22
+ // a click for two bytes of saving.
23
+ export const _SIG_BLOAT_MIN_CHARS = 200;
24
+
25
+ // HTML-escape a string by round-tripping through a detached div. Cheap
26
+ // and correct (handles all the entities that matter for innerHTML).
27
+ export function _esc(text) {
28
+ const div = document.createElement('div');
29
+ div.textContent = text || '';
30
+ return div.innerHTML;
31
+ }
32
+
33
+ // Escape + linkify URLs and email addresses. Returns innerHTML-safe markup.
34
+ export function _escLinkify(text) {
35
+ const escaped = _esc(text);
36
+ // URLs: http(s)://... or www....
37
+ const urlRe = /\b((?:https?:\/\/|www\.)[^\s<>"']+[^\s<>"'.,;:!?)\]])/g;
38
+ const mailRe = /\b([A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,})\b/g;
39
+ return escaped
40
+ .replace(urlRe, (m) => {
41
+ const href = m.startsWith('www.') ? `https://${m}` : m;
42
+ return `<a href="${href}" target="_blank" rel="noopener noreferrer">${m}</a>`;
43
+ })
44
+ .replace(mailRe, (m) => `<a href="mailto:${m}">${m}</a>`);
45
+ }
46
+
47
+ // Pull display name out of "Name <email@x>"; fallback to local-part of
48
+ // the email; final fallback to the input string.
49
+ export function _extractName(addr) {
50
+ const m = addr.match(/^"?([^"<]+?)"?\s*<([^>]+)>\s*$/);
51
+ if (m) return m[1].trim();
52
+ const localPart = addr.split('@')[0];
53
+ return localPart || addr;
54
+ }
55
+
56
+ // Parse the "Author <email> · Date" metadata string emitted by the
57
+ // server-side thread parser.
58
+ export function _parseTurnMeta(meta) {
59
+ if (!meta) return { author: '', email: '', date: '' };
60
+ const m = String(meta);
61
+ const eMatch = m.match(/<([^<>\s]+@[^<>\s]+)>/) ||
62
+ m.match(/\b([\w.+-]+@[\w.-]+\.[A-Za-z]{2,})\b/);
63
+ const email = eMatch ? eMatch[1].toLowerCase().trim() : '';
64
+ const parts = m.split(/\s+[·•]\s+/);
65
+ let author = '', date = '';
66
+ if (parts.length >= 2) {
67
+ author = parts[0].replace(/<[^>]+>/g, '').trim();
68
+ date = parts.slice(1).join(' · ').trim();
69
+ } else {
70
+ author = m.replace(/<[^>]+>/g, '').trim();
71
+ }
72
+ return { author, email, date };
73
+ }
74
+
75
+ // Short, locale-aware display string for a chat-bubble timestamp.
76
+ // Returns '' for invalid / empty input.
77
+ export function _formatBubbleDate(iso) {
78
+ if (!iso) return '';
79
+ const d = new Date(iso);
80
+ if (!d || isNaN(d.getTime())) return '';
81
+ try {
82
+ return d.toLocaleString(undefined, {
83
+ month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit',
84
+ });
85
+ } catch (_) { return ''; }
86
+ }
87
+
88
+ // Format a raw "to" address string ("Foo <foo@x.com>, bar@y.com") into a
89
+ // short, readable list — display names when present, just the local part
90
+ // of the email otherwise, and ", +N" once there are more than 2 recipients.
91
+ export function _formatRecipients(raw) {
92
+ if (!raw) return '';
93
+ const addrs = String(raw).split(',').map(s => s.trim()).filter(Boolean);
94
+ if (!addrs.length) return '';
95
+ const friendly = addrs.map(a => {
96
+ const m = a.match(/^\s*"?([^"<]+?)"?\s*<[^>]+>\s*$/);
97
+ if (m && m[1].trim()) return m[1].trim();
98
+ const em = a.replace(/[<>]/g, '').trim();
99
+ return em.split('@')[0] || em;
100
+ });
101
+ if (friendly.length === 1) return friendly[0];
102
+ if (friendly.length === 2) return friendly.join(', ');
103
+ return friendly.slice(0, 2).join(', ') + ' +' + (friendly.length - 2);
104
+ }
105
+
106
+ // Deterministic per-sender colour. Same hashing as
107
+ // emailInbox.js#_senderColor so a sender's avatar / name colour matches
108
+ // across the list view and the bubble reader.
109
+ export function _senderColor(name) {
110
+ if (!name) return 'hsl(220, 55%, 65%)';
111
+ const key = String(name).toLowerCase();
112
+ let hash = 0;
113
+ for (let i = 0; i < key.length; i++) {
114
+ hash = ((hash << 5) - hash + key.charCodeAt(i)) | 0;
115
+ }
116
+ const hue = ((hash % 360) + 360) % 360;
117
+ return `hsl(${hue}, 55%, 65%)`;
118
+ }
119
+
120
+ // 1- or 2-letter initials for an avatar bubble. Unicode-friendly.
121
+ export function _initials(s) {
122
+ if (!s) return '?';
123
+ const clean = String(s).replace(/<[^>]+>/g, '').replace(/[^\p{L}\s]/gu, ' ').trim();
124
+ const parts = clean.split(/\s+/).filter(Boolean);
125
+ if (!parts.length) return '?';
126
+ const first = parts[0][0] || '';
127
+ const last = parts.length > 1 ? parts[parts.length - 1][0] : '';
128
+ return (first + last).toUpperCase();
129
+ }
130
+
131
+ // HTML sanitizer for rendering remote email bodies. Strips script/iframe/
132
+ // form/style/etc., kills `on*` handlers, blocks `javascript:`/`vbscript:`/
133
+ // `data:` URLs on every known URL attribute, scrubs inline colour/font/
134
+ // position styles so the theme can take over, and wraps highlight-bearing
135
+ // inline tags in <mark> so they render legibly across themes.
136
+ export function _sanitizeHtml(html) {
137
+ const doc = new DOMParser().parseFromString(html, 'text/html');
138
+ doc.querySelectorAll(
139
+ 'script, iframe, object, embed, form, style, link, ' +
140
+ 'svg, math, base, meta, noscript, frame, frameset, applet, portal'
141
+ ).forEach(el => el.remove());
142
+
143
+ const URL_ATTRS = ['href', 'src', 'srcset', 'action', 'formaction', 'background', 'poster', 'data'];
144
+ const isDangerousUrl = (val) => {
145
+ if (!val) return false;
146
+ const v = val.trim().toLowerCase();
147
+ return v.startsWith('javascript:') || v.startsWith('vbscript:') || v.startsWith('data:');
148
+ };
149
+
150
+ const STRIP_CSS_PROPS = ['color', 'background', 'background-color',
151
+ 'font-family', 'font', '-webkit-text-fill-color',
152
+ 'position', 'z-index'];
153
+ const HIGHLIGHT_INLINE_TAGS = new Set(['SPAN', 'FONT', 'EM', 'B', 'I',
154
+ 'STRONG', 'SMALL', 'U']);
155
+ const HAS_BG_COLOR = /background(?:-color)?\s*:\s*(?!\s*(?:transparent|none|inherit|initial)\b)[^;]+/i;
156
+ const _markedForHighlight = [];
157
+
158
+ doc.querySelectorAll('*').forEach(el => {
159
+ for (const attr of [...el.attributes]) {
160
+ const name = attr.name.toLowerCase();
161
+ if (name.startsWith('on')) { el.removeAttribute(attr.name); continue; }
162
+ if (name === 'srcdoc') { el.removeAttribute(attr.name); continue; }
163
+ if (URL_ATTRS.includes(name) && isDangerousUrl(attr.value)) {
164
+ el.removeAttribute(attr.name);
165
+ continue;
166
+ }
167
+ }
168
+ el.removeAttribute('color');
169
+ const bgcolor = el.getAttribute('bgcolor');
170
+ el.removeAttribute('bgcolor');
171
+ el.removeAttribute('face');
172
+ const style = el.getAttribute('style');
173
+ const hadHighlight =
174
+ HIGHLIGHT_INLINE_TAGS.has(el.tagName) &&
175
+ ((style && HAS_BG_COLOR.test(style)) || (bgcolor && bgcolor !== 'transparent'));
176
+ if (hadHighlight) _markedForHighlight.push(el);
177
+ if (style) {
178
+ const kept = style.split(';').map(s => s.trim()).filter(decl => {
179
+ if (!decl) return false;
180
+ const lower = decl.toLowerCase();
181
+ if (lower.includes('javascript:') || lower.includes('expression(')) return false;
182
+ const prop = decl.split(':', 1)[0].trim().toLowerCase();
183
+ return !STRIP_CSS_PROPS.includes(prop);
184
+ });
185
+ if (kept.length) el.setAttribute('style', kept.join('; '));
186
+ else el.removeAttribute('style');
187
+ }
188
+ if (el.tagName === 'A') {
189
+ el.setAttribute('target', '_blank');
190
+ el.setAttribute('rel', 'noopener noreferrer');
191
+ }
192
+ });
193
+
194
+ _markedForHighlight.forEach(el => {
195
+ if (el.tagName === 'MARK' || !el.firstChild) return;
196
+ const mark = doc.createElement('mark');
197
+ while (el.firstChild) mark.appendChild(el.firstChild);
198
+ el.appendChild(mark);
199
+ });
200
+
201
+ return doc.body.innerHTML;
202
+ }