@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,582 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, interactive-widget=resizes-visual">
6
+ <title>Zero — Login</title>
7
+ <script nonce="{{CSP_NONCE}}">
8
+ (function(){
9
+ // Per-theme bg-effect defaults — mirrors THEME_DEFAULT_* maps in
10
+ // static/js/theme.js so login picks the same default pattern as the
11
+ // main app for users who never explicitly chose one.
12
+ var THEME_DEFAULT_PATTERN = {
13
+ dark:'none', light:'dots', midnight:'rain', paper:'dots',
14
+ cyberpunk:'synapse', retrowave:'embers', forest:'petals',
15
+ ocean:'constellations', terminal:'perlin-flow', organs:'rain',
16
+ ume:'petals', cute:'sparkles'
17
+ };
18
+ var THEME_DEFAULT_EFFECT_COLOR = {
19
+ midnight:'#ffffff', organs:'#451616', cute:'#ff8cb8', ume:'#f5a0c0'
20
+ };
21
+ var THEME_DEFAULT_INTENSITY = { midnight:0.5, terminal:0.8, organs:0.65 };
22
+ try {
23
+ var t = JSON.parse(localStorage.getItem('zero-theme'));
24
+ var s = document.documentElement.style;
25
+ if (t && t.colors) {
26
+ var c = t.colors;
27
+ // Base palette
28
+ s.setProperty('--bg', c.bg);
29
+ s.setProperty('--fg', c.fg);
30
+ s.setProperty('--panel', c.panel);
31
+ s.setProperty('--border', c.border);
32
+ if (c.red) s.setProperty('--red', c.red);
33
+ if (c.green) s.setProperty('--green', c.green);
34
+ // Advanced overrides (sidebar logo color, input bg, send-button bg, etc.)
35
+ // — mirrors ADV_KEYS in static/js/theme.js so the login page picks up
36
+ // every customization the user has on their theme instead of falling
37
+ // back to defaults that didn't match the main app.
38
+ var a = c.advanced || {};
39
+ var ADV = {
40
+ userBubbleBg: '--user-bubble-bg',
41
+ aiBubbleBg: '--ai-bubble-bg',
42
+ bubbleBorder: '--bubble-border',
43
+ sidebarBg: '--sidebar-bg',
44
+ brandColor: '--brand-color',
45
+ hamburgerColor: '--hamburger-color',
46
+ inputBg: '--input-bg',
47
+ inputBorder: '--input-border',
48
+ sendBtnBg: '--send-btn-bg',
49
+ sendBtnHover: '--send-btn-hover',
50
+ codeBg: '--code-bg',
51
+ codeFg: '--code-fg',
52
+ toggleActive: '--toggle-active',
53
+ };
54
+ for (var k in ADV) { if (a[k]) s.setProperty(ADV[k], a[k]); }
55
+ }
56
+ // Background effect — pick ONE at random from the main app's 8
57
+ // patterns each load (matches the old login behavior, but uses the
58
+ // same effect implementations the main theme system exposes so the
59
+ // login feels consistent with the rest of the app). Per-theme
60
+ // bgEffectColor/Intensity defaults still apply so the random
61
+ // pattern picks up theme-appropriate tinting.
62
+ var name = (t && t.name) || '';
63
+ // perlin-flow excluded — too visually intense for a login screen.
64
+ var PATTERNS = ['dots','synapse','rain','constellations','petals','sparkles','embers'];
65
+ var pattern = PATTERNS[Math.floor(Math.random() * PATTERNS.length)];
66
+ var effColor = (t && t.bgEffectColor) || THEME_DEFAULT_EFFECT_COLOR[name] || '';
67
+ var effInt = (t && t.bgEffectIntensity !== undefined)
68
+ ? t.bgEffectIntensity
69
+ : (THEME_DEFAULT_INTENSITY[name] !== undefined ? THEME_DEFAULT_INTENSITY[name] : 1);
70
+ var effSize = (t && t.bgEffectSize !== undefined) ? t.bgEffectSize : 1;
71
+ if (effColor) s.setProperty('--bg-effect-color', effColor);
72
+ s.setProperty('--bg-effect-intensity', String(effInt));
73
+ s.setProperty('--bg-effect-size', String(effSize));
74
+ // Stash so the deferred module knows which canvas effect to start.
75
+ window.__loginBgPattern = pattern;
76
+ // Apply the body class as soon as <body> exists so static-gradient
77
+ // patterns (dots, synapse) paint immediately on first frame.
78
+ var apply = function() { document.body.classList.add('bg-pattern-' + pattern); };
79
+ if (document.body) apply();
80
+ else document.addEventListener('DOMContentLoaded', apply, { once: true });
81
+ } catch(e){}
82
+ })();
83
+ </script>
84
+ <style>
85
+ @font-face { font-family: 'Fira Code'; font-weight: 400; font-style: normal; font-display: swap; src: url('/static/fonts/FiraCode-Regular.woff2') format('woff2'); }
86
+ @font-face { font-family: 'Fira Code'; font-weight: 600; font-style: normal; font-display: swap; src: url('/static/fonts/FiraCode-SemiBold.woff2') format('woff2'); }
87
+ /* Mirror the main app's :root defaults (static/style.css ~line 18) so an
88
+ uncustomized theme — or a fresh browser with no `zero-theme` in
89
+ localStorage — renders the login page in the same palette as the rest
90
+ of the app instead of a different greys+offwhite scheme. */
91
+ :root {
92
+ --bg: #282c34; --fg: #9cdef2; --panel: #111; --border: #355a66;
93
+ --red: #e06c75; --green: #50fa7b;
94
+ --bg-effect-intensity: 1;
95
+ }
96
+ /* Background patterns — mirrors static/style.css "Background Patterns"
97
+ block so the theme's chosen bgPattern renders on login too. The
98
+ canvas-based effects (rain, constellations, perlin-flow, petals,
99
+ sparkles, embers) are spawned by the deferred theme.js import below;
100
+ the static gradient ones (dots, synapse) need these CSS rules. */
101
+ #synapse-canvas, #rain-canvas, #constellations-canvas,
102
+ #perlin-flow-canvas, #petals-canvas, #sparkles-canvas,
103
+ #embers-canvas { opacity: var(--bg-effect-intensity, 1); }
104
+ body.bg-pattern-dots {
105
+ background-image: radial-gradient(color-mix(in srgb, var(--bg-effect-color, var(--fg)) calc(5% * var(--bg-effect-intensity, 1)), transparent) 1px, transparent 1px);
106
+ background-size: 20px 20px; background-attachment: fixed;
107
+ }
108
+ body.bg-pattern-synapse {
109
+ background-image: linear-gradient(color-mix(in srgb, var(--bg-effect-color, var(--fg)) calc(3.5% * var(--bg-effect-intensity, 1)), transparent) 1px, transparent 1px),
110
+ linear-gradient(90deg, color-mix(in srgb, var(--bg-effect-color, var(--fg)) calc(3.5% * var(--bg-effect-intensity, 1)), transparent) 1px, transparent 1px);
111
+ background-size: 24px 24px; background-attachment: fixed;
112
+ }
113
+ * { box-sizing: border-box; margin: 0; padding: 0; }
114
+ body {
115
+ font-family: 'Fira Code', monospace;
116
+ background: var(--bg); color: var(--fg);
117
+ display: flex; justify-content: center; align-items: flex-start;
118
+ min-height: 100vh; min-height: 100dvh;
119
+ padding-top: 15vh;
120
+ transition: padding-top 0.2s ease;
121
+ }
122
+ .card {
123
+ background: var(--panel); border: 1px solid var(--border); border-radius: 12px;
124
+ padding: 2rem; width: 360px; max-width: 90vw;
125
+ /* Sit above the bg-effect canvases (which spawn at z-index:0) so the
126
+ falling rain / drifting petals / etc. don't streak across the
127
+ login form. */
128
+ position: relative; z-index: 1;
129
+ }
130
+ .logo {
131
+ text-align: center; margin-bottom: 1.5rem;
132
+ }
133
+ .logo span {
134
+ font-family: 'Fira Code', monospace;
135
+ font-size: 2rem; font-weight: 600;
136
+ letter-spacing: 0.04em;
137
+ /* Same gradient as the main app's welcome-screen "Zero" title
138
+ (static/style.css #welcome-screen .welcome-name) so the brand
139
+ wordmark is consistent across login + first-launch screens. */
140
+ background: linear-gradient(135deg, var(--brand-color, var(--red)), color-mix(in srgb, var(--brand-color, var(--red)) 60%, var(--fg)));
141
+ -webkit-background-clip: text;
142
+ -webkit-text-fill-color: transparent;
143
+ background-clip: text;
144
+ }
145
+ .setup-note { color: color-mix(in srgb, var(--fg) 60%, transparent); font-size: 0.8rem; margin-bottom: 1rem; text-align: center; }
146
+ label { display: block; font-size: 0.85rem; margin-bottom: 0.3rem; color: color-mix(in srgb, var(--fg) 65%, transparent); }
147
+ input:not(.remember-check) {
148
+ width: 100%; padding: 0.6rem 0.8rem; margin-bottom: 1rem;
149
+ background: var(--bg); border: 1px solid var(--border); border-radius: 6px;
150
+ color: var(--fg); font-size: 0.95rem; font-family: 'Fira Code', monospace;
151
+ }
152
+ input:focus { outline: none; border-color: var(--red); }
153
+ /* On touch devices keep inputs at >=16px so iOS Safari doesn't zoom the whole
154
+ page when a field is focused (it auto-zooms any focused input under 16px).
155
+ This page has its own inline styles, so it doesn't inherit the main app's
156
+ equivalent rule in static/style.css; mirror it here. !important also lifts
157
+ the dynamically-inserted 2FA input, which pins font-size:14px inline. */
158
+ @media (hover: none) and (pointer: coarse) {
159
+ input:not(.remember-check) { font-size: 16px !important; }
160
+ }
161
+ /* Clear, visible focus ring for keyboard users on every focusable control. */
162
+ input:focus-visible, a:focus-visible, button:focus-visible {
163
+ outline: 2px solid var(--red);
164
+ outline-offset: 2px;
165
+ }
166
+ button {
167
+ width: 100%;
168
+ /* Asymmetric vertical padding nudges the label 1px down while keeping
169
+ the button's total height the same as 0.7rem all-around. */
170
+ padding: calc(0.7rem + 1px) 0.7rem calc(0.7rem - 1px);
171
+ border: none; border-radius: 6px;
172
+ /* Darken the brand red slightly so #fff label text clears the WCAG AA
173
+ 4.5:1 contrast threshold (plain --red #e06c75 only reaches ~3.2:1). */
174
+ background: color-mix(in srgb, var(--red) 78%, #000); color: #fff; font-size: 1rem; cursor: pointer;
175
+ font-weight: 600; font-family: 'Fira Code', monospace;
176
+ }
177
+ button:hover { background: color-mix(in srgb, var(--red) 66%, black); }
178
+ button:disabled { opacity: 0.5; cursor: not-allowed; }
179
+ .error { color: #e55; font-size: 0.85rem; margin-bottom: 0.75rem; display: none; }
180
+ .toggle { text-align: center; margin-top: calc(1rem + 4px); font-size: 0.85rem; color: color-mix(in srgb, var(--fg) 50%, transparent); }
181
+ .toggle a { color: var(--red); cursor: pointer; text-decoration: none; }
182
+ .toggle a:hover { text-decoration: underline; }
183
+ .pw-wrapper { position: relative; margin-bottom: 1rem; }
184
+ .pw-wrapper input:not(.remember-check) { padding-right: 2.5rem; margin-bottom: 0; }
185
+ .pw-toggle {
186
+ position: absolute; right: 8px; top: 50%;
187
+ /* +1px on the centering offset nudges the eye icon down 1px so it
188
+ lines up visually with the input text baseline. */
189
+ transform: translateY(calc(-50% + 1px));
190
+ background: none; border: none; padding: 4px; cursor: pointer;
191
+ color: color-mix(in srgb, var(--fg) 40%, transparent); width: auto;
192
+ display: flex; align-items: center; justify-content: center;
193
+ }
194
+ .pw-toggle:hover { color: var(--fg); background: none; }
195
+ .pw-toggle svg { display: block; }
196
+ .remember-toggle {
197
+ position: absolute !important; right: 13px; top: 50%; transform: translateY(-50%);
198
+ background: none; border: none; padding: 2px; cursor: pointer;
199
+ width: 14px !important; height: 14px !important; display: flex !important;
200
+ align-items: center; justify-content: center;
201
+ font-size: 0; margin: 0; color: transparent;
202
+ }
203
+ /* Visually hide the native checkbox but keep it in the accessibility tree
204
+ and keyboard-focusable (display:none would drop it from tab order). It
205
+ overlays the dot so a click/tap still toggles it. */
206
+ .remember-toggle .remember-check {
207
+ position: absolute; top: 0; left: 0;
208
+ width: 100%; height: 100%; margin: 0;
209
+ opacity: 0; cursor: pointer;
210
+ }
211
+ .remember-toggle .remember-check:focus-visible + .remember-dot {
212
+ outline: 2px solid var(--red); outline-offset: 2px;
213
+ }
214
+ .remember-toggle .remember-dot {
215
+ display: block; width: 10px; height: 10px; min-width: 10px; min-height: 10px;
216
+ border-radius: 50%;
217
+ border: 2px solid color-mix(in srgb, var(--fg) 25%, transparent);
218
+ background: transparent;
219
+ transition: all 0.15s;
220
+ }
221
+ .remember-toggle .remember-check:checked + .remember-dot {
222
+ border-color: transparent;
223
+ background: color-mix(in srgb, var(--fg) 40%, transparent);
224
+ }
225
+ .remember-toggle:hover .remember-dot {
226
+ border-color: color-mix(in srgb, var(--fg) 40%, transparent);
227
+ }
228
+ .logo-boat { width: 1.6rem; height: 1.6rem; margin-right: 0.4rem; vertical-align: -0.15em; color: var(--red); }
229
+ .version-label {
230
+ position: fixed; bottom: 12px; right: 16px;
231
+ font-size: 0.7rem; opacity: 0.25;
232
+ font-family: 'Fira Code', monospace;
233
+ pointer-events: none; user-select: none;
234
+ }
235
+ /* Whirlpool-style spinner shown in the submit button while login /
236
+ account-creation work is in flight — replaces the previous "Loading…"
237
+ text. Two-color ring (muted base + accent arc) rotates continuously. */
238
+ .login-spinner {
239
+ display: inline-block;
240
+ width: 16px; height: 16px;
241
+ border: 2px solid color-mix(in srgb, var(--fg, #fff) 22%, transparent);
242
+ border-top-color: var(--accent, var(--red, #e8a830));
243
+ border-radius: 50%;
244
+ animation: login-spin 0.7s linear infinite;
245
+ vertical-align: -3px;
246
+ }
247
+ @keyframes login-spin { to { transform: rotate(360deg); } }
248
+ </style>
249
+ </head>
250
+ <body>
251
+ <main class="card">
252
+ <h1 class="logo">
253
+ <svg class="logo-boat" viewBox="0 0 32 32" aria-hidden="true" focusable="false"><path d="M16 4L16 22L6 22Z" fill="currentColor"/><path d="M16 8L16 22L24 22Z" fill="currentColor" opacity="0.6"/><path d="M4 24Q10 20 16 24Q22 28 28 24" stroke="currentColor" stroke-width="2.5" fill="none" stroke-linecap="round"/></svg><span>Zero</span>
254
+ </h1>
255
+ <p class="setup-note" id="setupNote" style="display:none"></p>
256
+
257
+ <div class="error" id="error" role="alert" aria-live="assertive"></div>
258
+
259
+ <form id="authForm" autocomplete="on">
260
+ <label for="username">Username</label>
261
+ <div class="pw-wrapper">
262
+ <input id="username" name="username" type="text" required autofocus autocomplete="username">
263
+ <label class="remember-toggle" id="rememberToggle" title="Remember me">
264
+ <input type="checkbox" class="remember-check" id="remember" checked aria-label="Remember me">
265
+ <span class="remember-dot" aria-hidden="true"></span>
266
+ </label>
267
+ </div>
268
+
269
+ <label for="password">Password</label>
270
+ <div class="pw-wrapper">
271
+ <input id="password" name="password" type="password" required autocomplete="current-password">
272
+ <button type="button" class="pw-toggle" id="pwToggle" tabindex="-1" aria-label="Show password">
273
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><line x1="8" y1="16" x2="16" y2="8"/><line x1="8" y1="8" x2="16" y2="16"/></svg>
274
+ </button>
275
+ </div>
276
+
277
+ <div id="confirmGroup" style="display:none">
278
+ <label for="confirmPassword">Confirm Password</label>
279
+ <div class="pw-wrapper">
280
+ <input id="confirmPassword" name="confirmPassword" type="password" autocomplete="new-password">
281
+ <button type="button" class="pw-toggle" id="pwToggleConfirm" tabindex="-1" aria-label="Show password">
282
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><line x1="8" y1="16" x2="16" y2="8"/><line x1="8" y1="8" x2="16" y2="16"/></svg>
283
+ </button>
284
+ </div>
285
+ </div>
286
+
287
+ <button type="submit" id="submitBtn">Sign In</button>
288
+ </form>
289
+
290
+ <div class="toggle" id="toggleArea" style="display:none">
291
+ <span id="toggleText">Don't have an account? </span>
292
+ <a id="toggleLink" href="#">Sign up</a>
293
+ </div>
294
+ </main>
295
+
296
+ <footer class="version-label" id="version-label"></footer>
297
+
298
+ <script nonce="{{CSP_NONCE}}">
299
+ (async () => {
300
+ // Load version
301
+ try {
302
+ const vr = await fetch('/api/version');
303
+ if (vr.ok) {
304
+ const vd = await vr.json();
305
+ document.getElementById('version-label').textContent = 'v' + vd.version;
306
+ }
307
+ } catch(e) {}
308
+
309
+ // Prefill last username
310
+ const usernameInput = document.getElementById('username');
311
+ const savedUser = localStorage.getItem('zero-last-user');
312
+ if (savedUser && usernameInput) {
313
+ usernameInput.value = savedUser;
314
+ document.getElementById('password').focus();
315
+ }
316
+
317
+ const form = document.getElementById('authForm');
318
+ const errEl = document.getElementById('error');
319
+ const setupNote = document.getElementById('setupNote');
320
+ const confirmGroup = document.getElementById('confirmGroup');
321
+ const submitBtn = document.getElementById('submitBtn');
322
+ const toggleArea = document.getElementById('toggleArea');
323
+ const toggleLink = document.getElementById('toggleLink');
324
+ const toggleText = document.getElementById('toggleText');
325
+
326
+ let mode = 'login'; // 'login' | 'signup' | 'setup'
327
+ let signupAllowed = false;
328
+
329
+ const rememberToggle = document.getElementById('rememberToggle');
330
+
331
+ function setMode(m) {
332
+ mode = m;
333
+ errEl.style.display = 'none';
334
+ if (m === 'setup') {
335
+ setupNote.textContent = 'First-time setup — create your admin account';
336
+ setupNote.style.display = 'block';
337
+ confirmGroup.style.display = 'block';
338
+ submitBtn.textContent = 'Create Admin Account';
339
+ toggleArea.style.display = 'none';
340
+ rememberToggle.style.display = 'none';
341
+ } else if (m === 'signup') {
342
+ setupNote.style.display = 'none';
343
+ confirmGroup.style.display = 'block';
344
+ submitBtn.innerHTML = '<span style="position:relative;top:1px;">Create Account</span>';
345
+ toggleArea.style.display = 'block';
346
+ toggleText.textContent = 'Already have an account? ';
347
+ toggleLink.textContent = 'Sign in';
348
+ rememberToggle.style.display = 'none';
349
+ } else {
350
+ setupNote.style.display = 'none';
351
+ confirmGroup.style.display = 'none';
352
+ submitBtn.textContent = 'Sign In';
353
+ toggleArea.style.display = signupAllowed ? 'block' : 'none';
354
+ toggleText.textContent = "Don't have an account? ";
355
+ toggleLink.textContent = 'Sign up';
356
+ rememberToggle.style.display = '';
357
+ }
358
+ }
359
+
360
+ // Check auth status
361
+ try {
362
+ const res = await fetch('/api/auth/status', { credentials: 'same-origin' });
363
+ const data = await res.json();
364
+ if (data.authenticated) {
365
+ window.location.replace('/');
366
+ return;
367
+ }
368
+ signupAllowed = !!data.signup_enabled;
369
+ if (!data.configured) {
370
+ setMode('setup');
371
+ } else {
372
+ setMode('login');
373
+ }
374
+ } catch (e) {
375
+ setMode('login');
376
+ }
377
+
378
+ toggleLink.addEventListener('click', (e) => {
379
+ e.preventDefault();
380
+ setMode(mode === 'login' ? 'signup' : 'login');
381
+ });
382
+
383
+ form.addEventListener('submit', async (e) => {
384
+ e.preventDefault();
385
+ errEl.style.display = 'none';
386
+ submitBtn.disabled = true;
387
+
388
+ const username = document.getElementById('username').value.trim();
389
+ const password = document.getElementById('password').value;
390
+
391
+ // If in TOTP mode, handle the code submission directly
392
+ if (form._totpMode) {
393
+ const totpInput = document.getElementById('totp-input');
394
+ const code = totpInput ? totpInput.value.trim() : '';
395
+ if (!code) { totpInput.focus(); submitBtn.disabled = false; return; }
396
+ const remember = document.getElementById('remember').checked;
397
+ try {
398
+ const res = await fetch('/api/auth/login', {
399
+ method: 'POST',
400
+ headers: { 'Content-Type': 'application/json' },
401
+ credentials: 'same-origin',
402
+ body: JSON.stringify({ username, password, remember, totp_code: code })
403
+ });
404
+ const data = await res.json();
405
+ if (!res.ok) throw new Error(data.detail || 'Invalid code');
406
+ if (!data.ok) throw new Error('Login failed');
407
+ form._totpMode = false;
408
+ finishLogin();
409
+ } catch (err) {
410
+ errEl.textContent = err.message;
411
+ errEl.style.display = 'block';
412
+ submitBtn.disabled = false;
413
+ }
414
+ return;
415
+ }
416
+
417
+ // Validate confirm password for setup/signup
418
+ if (mode === 'setup' || mode === 'signup') {
419
+ const confirm = document.getElementById('confirmPassword').value;
420
+ if (password !== confirm) {
421
+ errEl.textContent = 'Passwords do not match';
422
+ errEl.style.display = 'block';
423
+ submitBtn.disabled = false;
424
+ return;
425
+ }
426
+ if (password.length < 8) {
427
+ errEl.textContent = 'Password must be at least 8 characters';
428
+ errEl.style.display = 'block';
429
+ submitBtn.disabled = false;
430
+ return;
431
+ }
432
+ }
433
+
434
+ // Setup or signup first
435
+ if (mode === 'setup' || mode === 'signup') {
436
+ const endpoint = mode === 'setup' ? '/api/auth/setup' : '/api/auth/signup';
437
+ try {
438
+ const res = await fetch(endpoint, {
439
+ method: 'POST',
440
+ headers: { 'Content-Type': 'application/json' },
441
+ credentials: 'same-origin',
442
+ body: JSON.stringify({ username, password })
443
+ });
444
+ const data = await res.json();
445
+ if (!res.ok) throw new Error(data.detail || 'Account creation failed');
446
+ } catch (err) {
447
+ errEl.textContent = err.message;
448
+ errEl.style.display = 'block';
449
+ submitBtn.disabled = false;
450
+ return;
451
+ }
452
+ }
453
+
454
+ // Login (auto-login after setup/signup too)
455
+ const remember = document.getElementById('remember').checked;
456
+ function finishLogin() {
457
+ const _rem = document.getElementById('remember').checked;
458
+ if (_rem) localStorage.setItem('zero-last-user', username);
459
+ else localStorage.removeItem('zero-last-user');
460
+ sessionStorage.removeItem('ody-session-active');
461
+ submitBtn.innerHTML = '<span class="login-spinner" aria-hidden="true"></span>';
462
+ submitBtn.disabled = true;
463
+ Promise.all([
464
+ fetch('/api/sessions', { credentials: 'same-origin' }).then(r => r.json()),
465
+ fetch('/api/auth/features', { credentials: 'same-origin' }).then(r => r.json()),
466
+ fetch('/api/auth/settings', { credentials: 'same-origin' }).then(r => r.json()),
467
+ ]).then(([sess, feat, sett]) => {
468
+ sessionStorage.setItem('ody-prefetch-sessions', JSON.stringify(sess));
469
+ sessionStorage.setItem('ody-prefetch-features', JSON.stringify(feat));
470
+ sessionStorage.setItem('ody-prefetch-settings', JSON.stringify(sett));
471
+ }).catch(() => {}).finally(() => { window.location.replace('/'); });
472
+ }
473
+ async function doLogin(totpCode) {
474
+ const loginBody = { username, password, remember };
475
+ if (totpCode) loginBody.totp_code = totpCode;
476
+ const res = await fetch('/api/auth/login', {
477
+ method: 'POST',
478
+ headers: { 'Content-Type': 'application/json' },
479
+ credentials: 'same-origin',
480
+ body: JSON.stringify(loginBody)
481
+ });
482
+ const data = await res.json();
483
+ if (!res.ok) throw new Error(data.detail || 'Login failed');
484
+ return data;
485
+ }
486
+ try {
487
+ let data = await doLogin();
488
+ // 2FA required — show TOTP input
489
+ if (data.requires_totp) {
490
+ submitBtn.disabled = false;
491
+ // Only add TOTP input once
492
+ if (document.getElementById('totp-input')) return;
493
+ form._totpMode = true;
494
+ const totpWrap = document.createElement('div');
495
+ totpWrap.style.cssText = 'margin-top:12px;';
496
+ totpWrap.innerHTML = '<label for="totp-input" style="font-size:0.85em;opacity:0.7;display:block;margin-bottom:4px;">2FA Code</label><input type="text" id="totp-input" placeholder="Enter 6-digit code" aria-label="Two-factor authentication code" autocomplete="one-time-code" inputmode="numeric" maxlength="8" style="width:100%;padding:10px 12px;background:var(--bg);color:var(--fg);border:1px solid var(--border);border-radius:8px;font-size:14px;box-sizing:border-box;text-align:center;letter-spacing:4px;">';
497
+ const formEl = submitBtn.parentElement;
498
+ formEl.insertBefore(totpWrap, submitBtn);
499
+ const totpInput = document.getElementById('totp-input');
500
+ totpInput.focus();
501
+ submitBtn.textContent = 'Verify';
502
+ return;
503
+ }
504
+ finishLogin();
505
+ } catch (err) {
506
+ errEl.textContent = err.message;
507
+ errEl.style.display = 'block';
508
+ submitBtn.disabled = false;
509
+ return;
510
+ }
511
+ });
512
+
513
+ // Password show/hide toggles
514
+ const eyeOpen = '<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>';
515
+ const eyeClosed = '<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><line x1="8" y1="16" x2="16" y2="8"/><line x1="8" y1="8" x2="16" y2="16"/></svg>';
516
+
517
+ function wireToggle(btnId, inputId) {
518
+ const btn = document.getElementById(btnId);
519
+ const inp = document.getElementById(inputId);
520
+ if (!btn || !inp) return;
521
+ btn.addEventListener('click', (e) => {
522
+ e.preventDefault();
523
+ const show = inp.type === 'password';
524
+ inp.type = show ? 'text' : 'password';
525
+ btn.innerHTML = show ? eyeOpen : eyeClosed;
526
+ btn.setAttribute('aria-label', show ? 'Hide password' : 'Show password');
527
+ inp.focus();
528
+ });
529
+ }
530
+ wireToggle('pwToggle', 'password');
531
+ wireToggle('pwToggleConfirm', 'confirmPassword');
532
+ })();
533
+
534
+ // Prevent login button and eye toggles from stealing focus on mobile (keeps keyboard open)
535
+ document.querySelectorAll('#submitBtn, .pw-toggle').forEach(btn => {
536
+ btn.addEventListener('touchstart', (e) => { e.preventDefault(); }, { passive: false });
537
+ btn.addEventListener('touchend', (e) => {
538
+ e.preventDefault();
539
+ btn.click();
540
+ });
541
+ });
542
+
543
+ // Mobile keyboard: shift card up when virtual keyboard opens
544
+ if (window.visualViewport) {
545
+ const card = document.querySelector('.card');
546
+ window.visualViewport.addEventListener('resize', () => {
547
+ const vvh = window.visualViewport.height;
548
+ const wh = window.innerHeight;
549
+ if (vvh < wh * 0.8) {
550
+ document.body.style.paddingTop = '5vh';
551
+ // Keep the active input visible without jumping the whole card to the top
552
+ if (document.activeElement && document.activeElement.tagName === 'INPUT') {
553
+ document.activeElement.scrollIntoView({ behavior: 'smooth', block: 'center' });
554
+ }
555
+ } else {
556
+ document.body.style.paddingTop = '';
557
+ }
558
+ });
559
+ }
560
+ </script>
561
+ <script type="module" nonce="{{CSP_NONCE}}">
562
+ // Drive the login page's bg effect off the user's saved theme. The
563
+ // sync bootstrap above already set the body class + effect CSS vars so
564
+ // the static-gradient patterns (dots, synapse) paint immediately; this
565
+ // block imports theme.js's canvas implementations for the dynamic
566
+ // patterns (rain, constellations, perlin-flow, petals, sparkles,
567
+ // embers, synapse pulses).
568
+ //
569
+ // IMPORTANT: theme.js's auto-init (`_initWithSync` → `initThemeUI`)
570
+ // early-returns at `#themeGrid` which doesn't exist on this page, so
571
+ // `applyBgPattern` would never fire on its own. We call it directly
572
+ // here against the pattern the bootstrap already chose.
573
+ try {
574
+ const tm = await import('/static/js/theme.js');
575
+ const pattern = window.__loginBgPattern;
576
+ if (pattern && tm.applyBgPattern) tm.applyBgPattern(pattern);
577
+ } catch (e) {
578
+ console.error('[login-bg] failed:', e);
579
+ }
580
+ </script>
581
+ </body>
582
+ </html>
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "Zero",
3
+ "short_name": "Zero",
4
+ "description": "Self-hosted AI chat with memory, documents, and tools",
5
+ "start_url": "/",
6
+ "scope": "/",
7
+ "display": "standalone",
8
+ "orientation": "any",
9
+ "background_color": "#282c34",
10
+ "theme_color": "#282c34",
11
+ "icons": [
12
+ { "src": "/static/icon-192.png", "sizes": "192x192", "type": "image/png", "purpose": "any maskable" },
13
+ { "src": "/static/icon-512.png", "sizes": "512x512", "type": "image/png", "purpose": "any maskable" }
14
+ ]
15
+ }