aimeat 1.27.0 → 1.28.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 (421) hide show
  1. package/dist/.env.example +2 -0
  2. package/dist/locales/en.json +538 -297
  3. package/dist/locales/fi.json +500 -259
  4. package/dist/public/components/NotificationBell.js +2 -4
  5. package/dist/public/css/views/agents-detail.css +11 -0
  6. package/dist/public/css/views/app-grant.css +35 -3
  7. package/dist/public/css/views/inbox.css +78 -0
  8. package/dist/public/css/views/landing.css +8 -0
  9. package/dist/public/css/views/living.css +187 -0
  10. package/dist/public/css/views/notebook.css +89 -0
  11. package/dist/public/css/views/profile.css +78 -85
  12. package/dist/public/js/app-sandbox.js +18 -59
  13. package/dist/public/js/presence-store.js +7 -1
  14. package/dist/public/js/services/agents.js +10 -3
  15. package/dist/public/js/services/generator-prompts-base.js +40 -3
  16. package/dist/public/js/services/living.js +506 -0
  17. package/dist/public/js/services/memory.js +23 -3
  18. package/dist/public/js/services/nodes.js +1 -1
  19. package/dist/public/js/services/notebook-plan.js +211 -0
  20. package/dist/public/js/services/notebook.js +97 -0
  21. package/dist/public/js/services/organisms.js +41 -2
  22. package/dist/public/js/services/tracked-responses.js +103 -0
  23. package/dist/public/js/utils.js +15 -0
  24. package/dist/public/lib/live-updates.js +231 -94
  25. package/dist/public/spa.html +8 -1
  26. package/dist/public/types/aimeat-globals.d.ts +4 -0
  27. package/dist/public/views/admin/agent-integration-tab.js +2 -5
  28. package/dist/public/views/admin/agent-tasks-tab.js +2 -5
  29. package/dist/public/views/admin/cortex-tab.js +2 -5
  30. package/dist/public/views/admin/federation-tab.js +3 -10
  31. package/dist/public/views/admin/memory-tab.js +2 -5
  32. package/dist/public/views/admin/messages-tab.js +2 -5
  33. package/dist/public/views/admin/packages-tab.js +2 -5
  34. package/dist/public/views/admin/sharing-groups-tab.js +2 -5
  35. package/dist/public/views/app-grant.js +126 -23
  36. package/dist/public/views/landing-node-totals.js +71 -0
  37. package/dist/public/views/landing.js +6 -4
  38. package/dist/public/views/profile/agents/agent-card.js +8 -5
  39. package/dist/public/views/profile/agents/tab-activity.js +2 -3
  40. package/dist/public/views/profile/agents/tab-agent-config.js +2 -3
  41. package/dist/public/views/profile/agents/tab-data-access.js +2 -3
  42. package/dist/public/views/profile/agents/tab-integration.js +2 -3
  43. package/dist/public/views/profile/agents/tab-messages.js +2 -6
  44. package/dist/public/views/profile/agents/tab-quality.js +2 -5
  45. package/dist/public/views/profile/agents/tab-schedules.js +2 -4
  46. package/dist/public/views/profile/agents-activity-subtab.js +2 -5
  47. package/dist/public/views/profile/agents-capabilities-subtab.js +2 -2
  48. package/dist/public/views/profile/agents-messages-subtab.js +2 -5
  49. package/dist/public/views/profile/agents-services-subtab.js +2 -3
  50. package/dist/public/views/profile/agents-tab.js +70 -90
  51. package/dist/public/views/profile/agents-tasks-subtab.js +3 -8
  52. package/dist/public/views/profile/apps-tab.js +17 -0
  53. package/dist/public/views/profile/boards-tab.js +2 -5
  54. package/dist/public/views/profile/chat-sessions-tab.js +2 -5
  55. package/dist/public/views/profile/ecosystem-tab.js +7 -12
  56. package/dist/public/views/profile/extensions-tab.js +2 -5
  57. package/dist/public/views/profile/federation-tab.js +2 -5
  58. package/dist/public/views/profile/inbox-tab.js +280 -14
  59. package/dist/public/views/profile/knowledge-tab.js +2 -5
  60. package/dist/public/views/profile/landing-page.js +260 -184
  61. package/dist/public/views/profile/living-tab.js +480 -0
  62. package/dist/public/views/profile/memory-tab.js +2 -5
  63. package/dist/public/views/profile/notebook-card.js +515 -0
  64. package/dist/public/views/profile/notebook-helpers.js +48 -0
  65. package/dist/public/views/profile/notebook-tab.js +40 -260
  66. package/dist/public/views/profile/organisms/activity-panel.js +3 -2
  67. package/dist/public/views/profile/organisms/home.js +52 -3
  68. package/dist/public/views/profile/organisms/members.js +2 -5
  69. package/dist/public/views/profile/organisms/mindmap.js +194 -0
  70. package/dist/public/views/profile/organisms/panels.js +3 -10
  71. package/dist/public/views/profile/organisms/participants-panel.js +3 -2
  72. package/dist/public/views/profile/organisms/readme-panel.js +97 -0
  73. package/dist/public/views/profile/organisms/sources-panel.js +2 -5
  74. package/dist/public/views/profile/organisms/timeline-panel.js +104 -0
  75. package/dist/public/views/profile/organisms/workspace-comments.js +2 -5
  76. package/dist/public/views/profile/organisms/workspace-list.js +8 -8
  77. package/dist/public/views/profile/organisms/workspace.js +41 -6
  78. package/dist/public/views/profile/organisms-tab.js +3 -6
  79. package/dist/public/views/profile/packages-tab.js +2 -5
  80. package/dist/public/views/profile/scheduler-tab.js +2 -4
  81. package/dist/public/views/profile/track-response-modal.js +211 -0
  82. package/dist/public/views/profile/workflows-tab.js +4 -13
  83. package/dist/public/views/profile.js +10 -9
  84. package/dist/scripts/consent-audit-prune.d.ts +21 -0
  85. package/dist/scripts/consent-audit-prune.d.ts.map +1 -0
  86. package/dist/scripts/consent-audit-prune.js +198 -0
  87. package/dist/scripts/consent-audit-prune.js.map +1 -0
  88. package/dist/scripts/reassign-apps.d.ts +2 -0
  89. package/dist/scripts/reassign-apps.d.ts.map +1 -0
  90. package/dist/scripts/reassign-apps.js +99 -0
  91. package/dist/scripts/reassign-apps.js.map +1 -0
  92. package/dist/scripts/telemetry-prune.d.ts +20 -0
  93. package/dist/scripts/telemetry-prune.d.ts.map +1 -0
  94. package/dist/scripts/telemetry-prune.js +195 -0
  95. package/dist/scripts/telemetry-prune.js.map +1 -0
  96. package/dist/src/auth/jwt.d.ts +1 -0
  97. package/dist/src/auth/jwt.d.ts.map +1 -1
  98. package/dist/src/auth/jwt.js +13 -0
  99. package/dist/src/auth/jwt.js.map +1 -1
  100. package/dist/src/cli/connect/mcp/local-server.d.ts.map +1 -1
  101. package/dist/src/cli/connect/mcp/local-server.js +109 -0
  102. package/dist/src/cli/connect/mcp/local-server.js.map +1 -1
  103. package/dist/src/cli/connect/tool-call.d.ts.map +1 -1
  104. package/dist/src/cli/connect/tool-call.js +9 -0
  105. package/dist/src/cli/connect/tool-call.js.map +1 -1
  106. package/dist/src/cli/connect/tunnel-client.d.ts +16 -0
  107. package/dist/src/cli/connect/tunnel-client.d.ts.map +1 -1
  108. package/dist/src/cli/connect/tunnel-client.js +42 -0
  109. package/dist/src/cli/connect/tunnel-client.js.map +1 -1
  110. package/dist/src/config.d.ts +7 -0
  111. package/dist/src/config.d.ts.map +1 -1
  112. package/dist/src/config.js +4 -0
  113. package/dist/src/config.js.map +1 -1
  114. package/dist/src/generated/api-types.d.ts +1449 -128
  115. package/dist/src/generated/api-types.d.ts.map +1 -1
  116. package/dist/src/generated/prisma-postgres/edge.js +17 -3
  117. package/dist/src/generated/prisma-postgres/index-browser.js +14 -0
  118. package/dist/src/generated/prisma-postgres/index.d.ts +1580 -161
  119. package/dist/src/generated/prisma-postgres/index.js +17 -3
  120. package/dist/src/generated/prisma-postgres/package.json +1 -1
  121. package/dist/src/generated/prisma-postgres/schema.prisma +18 -0
  122. package/dist/src/generated/prisma-postgres/wasm.js +17 -3
  123. package/dist/src/index.js +4 -0
  124. package/dist/src/index.js.map +1 -1
  125. package/dist/src/mcp/agent-telemetry.d.ts +2 -0
  126. package/dist/src/mcp/agent-telemetry.d.ts.map +1 -1
  127. package/dist/src/mcp/agent-telemetry.js +8 -3
  128. package/dist/src/mcp/agent-telemetry.js.map +1 -1
  129. package/dist/src/mcp/annotations.d.ts.map +1 -1
  130. package/dist/src/mcp/annotations.js +1 -0
  131. package/dist/src/mcp/annotations.js.map +1 -1
  132. package/dist/src/mcp/apps.d.ts.map +1 -1
  133. package/dist/src/mcp/apps.js +14 -1
  134. package/dist/src/mcp/apps.js.map +1 -1
  135. package/dist/src/mcp/catalog/definitions.d.ts.map +1 -1
  136. package/dist/src/mcp/catalog/definitions.js +15 -0
  137. package/dist/src/mcp/catalog/definitions.js.map +1 -1
  138. package/dist/src/mcp/organisms.d.ts +2 -0
  139. package/dist/src/mcp/organisms.d.ts.map +1 -1
  140. package/dist/src/mcp/organisms.js +43 -0
  141. package/dist/src/mcp/organisms.js.map +1 -1
  142. package/dist/src/mcp/workspaces.d.ts.map +1 -1
  143. package/dist/src/mcp/workspaces.js +8 -1
  144. package/dist/src/mcp/workspaces.js.map +1 -1
  145. package/dist/src/routes/agent-messages.js +2 -2
  146. package/dist/src/routes/agent-messages.js.map +1 -1
  147. package/dist/src/routes/agent-tasks.js +14 -14
  148. package/dist/src/routes/agent-tasks.js.map +1 -1
  149. package/dist/src/routes/agent-telemetry.d.ts +3 -0
  150. package/dist/src/routes/agent-telemetry.d.ts.map +1 -1
  151. package/dist/src/routes/agent-telemetry.js +11 -6
  152. package/dist/src/routes/agent-telemetry.js.map +1 -1
  153. package/dist/src/routes/agents.d.ts.map +1 -1
  154. package/dist/src/routes/agents.js +41 -3
  155. package/dist/src/routes/agents.js.map +1 -1
  156. package/dist/src/routes/app-grants.d.ts +3 -0
  157. package/dist/src/routes/app-grants.d.ts.map +1 -1
  158. package/dist/src/routes/app-grants.js +120 -7
  159. package/dist/src/routes/app-grants.js.map +1 -1
  160. package/dist/src/routes/apps.d.ts +9 -0
  161. package/dist/src/routes/apps.d.ts.map +1 -1
  162. package/dist/src/routes/apps.js +110 -16
  163. package/dist/src/routes/apps.js.map +1 -1
  164. package/dist/src/routes/boards.d.ts.map +1 -1
  165. package/dist/src/routes/boards.js +4 -2
  166. package/dist/src/routes/boards.js.map +1 -1
  167. package/dist/src/routes/consent.d.ts.map +1 -1
  168. package/dist/src/routes/consent.js +14 -1
  169. package/dist/src/routes/consent.js.map +1 -1
  170. package/dist/src/routes/ghii.d.ts.map +1 -1
  171. package/dist/src/routes/ghii.js +20 -10
  172. package/dist/src/routes/ghii.js.map +1 -1
  173. package/dist/src/routes/librarian.d.ts.map +1 -1
  174. package/dist/src/routes/librarian.js +64 -2
  175. package/dist/src/routes/librarian.js.map +1 -1
  176. package/dist/src/routes/libs.d.ts +9 -0
  177. package/dist/src/routes/libs.d.ts.map +1 -1
  178. package/dist/src/routes/libs.js +261 -2
  179. package/dist/src/routes/libs.js.map +1 -1
  180. package/dist/src/routes/living.d.ts +18 -0
  181. package/dist/src/routes/living.d.ts.map +1 -0
  182. package/dist/src/routes/living.js +63 -0
  183. package/dist/src/routes/living.js.map +1 -0
  184. package/dist/src/routes/matches.d.ts.map +1 -1
  185. package/dist/src/routes/matches.js +1 -3
  186. package/dist/src/routes/matches.js.map +1 -1
  187. package/dist/src/routes/memory.d.ts.map +1 -1
  188. package/dist/src/routes/memory.js +40 -1
  189. package/dist/src/routes/memory.js.map +1 -1
  190. package/dist/src/routes/messages.d.ts +2 -0
  191. package/dist/src/routes/messages.d.ts.map +1 -1
  192. package/dist/src/routes/messages.js +27 -96
  193. package/dist/src/routes/messages.js.map +1 -1
  194. package/dist/src/routes/organisms.d.ts +8 -0
  195. package/dist/src/routes/organisms.d.ts.map +1 -1
  196. package/dist/src/routes/organisms.js +124 -3
  197. package/dist/src/routes/organisms.js.map +1 -1
  198. package/dist/src/routes/owners.d.ts.map +1 -1
  199. package/dist/src/routes/owners.js +2 -0
  200. package/dist/src/routes/owners.js.map +1 -1
  201. package/dist/src/routes/personal.d.ts.map +1 -1
  202. package/dist/src/routes/personal.js +7 -0
  203. package/dist/src/routes/personal.js.map +1 -1
  204. package/dist/src/routes/portal.d.ts +3 -0
  205. package/dist/src/routes/portal.d.ts.map +1 -1
  206. package/dist/src/routes/portal.js +19 -12
  207. package/dist/src/routes/portal.js.map +1 -1
  208. package/dist/src/routes/public-stats.d.ts +3 -0
  209. package/dist/src/routes/public-stats.d.ts.map +1 -1
  210. package/dist/src/routes/public-stats.js +48 -0
  211. package/dist/src/routes/public-stats.js.map +1 -1
  212. package/dist/src/routes/sse.d.ts +3 -0
  213. package/dist/src/routes/sse.d.ts.map +1 -1
  214. package/dist/src/routes/sse.js +27 -15
  215. package/dist/src/routes/sse.js.map +1 -1
  216. package/dist/src/routes/storage-files.d.ts +2 -0
  217. package/dist/src/routes/storage-files.d.ts.map +1 -1
  218. package/dist/src/routes/storage-files.js +14 -17
  219. package/dist/src/routes/storage-files.js.map +1 -1
  220. package/dist/src/routes/subdomains.d.ts +28 -0
  221. package/dist/src/routes/subdomains.d.ts.map +1 -1
  222. package/dist/src/routes/subdomains.js +138 -11
  223. package/dist/src/routes/subdomains.js.map +1 -1
  224. package/dist/src/routes/tracked-responses.d.ts +27 -0
  225. package/dist/src/routes/tracked-responses.d.ts.map +1 -0
  226. package/dist/src/routes/tracked-responses.js +212 -0
  227. package/dist/src/routes/tracked-responses.js.map +1 -0
  228. package/dist/src/routes/upload.js +8 -0
  229. package/dist/src/routes/upload.js.map +1 -1
  230. package/dist/src/server-bootstrap/routes-loader.d.ts.map +1 -1
  231. package/dist/src/server-bootstrap/routes-loader.js +24 -0
  232. package/dist/src/server-bootstrap/routes-loader.js.map +1 -1
  233. package/dist/src/server-bootstrap/service-init.d.ts.map +1 -1
  234. package/dist/src/server-bootstrap/service-init.js +4 -0
  235. package/dist/src/server-bootstrap/service-init.js.map +1 -1
  236. package/dist/src/server-bootstrap/static-files.d.ts +5 -0
  237. package/dist/src/server-bootstrap/static-files.d.ts.map +1 -1
  238. package/dist/src/server-bootstrap/static-files.js +33 -1
  239. package/dist/src/server-bootstrap/static-files.js.map +1 -1
  240. package/dist/src/services/access-guard.d.ts +4 -4
  241. package/dist/src/services/access-guard.d.ts.map +1 -1
  242. package/dist/src/services/access-guard.js +7 -8
  243. package/dist/src/services/access-guard.js.map +1 -1
  244. package/dist/src/services/activity-recorder.d.ts +2 -13
  245. package/dist/src/services/activity-recorder.d.ts.map +1 -1
  246. package/dist/src/services/activity-recorder.js +0 -42
  247. package/dist/src/services/activity-recorder.js.map +1 -1
  248. package/dist/src/services/connect-tunnel.d.ts +56 -3
  249. package/dist/src/services/connect-tunnel.d.ts.map +1 -1
  250. package/dist/src/services/connect-tunnel.js +216 -1
  251. package/dist/src/services/connect-tunnel.js.map +1 -1
  252. package/dist/src/services/consent-audit-buffer.d.ts +45 -0
  253. package/dist/src/services/consent-audit-buffer.d.ts.map +1 -0
  254. package/dist/src/services/consent-audit-buffer.js +85 -0
  255. package/dist/src/services/consent-audit-buffer.js.map +1 -0
  256. package/dist/src/services/consent.d.ts +9 -3
  257. package/dist/src/services/consent.d.ts.map +1 -1
  258. package/dist/src/services/consent.js +13 -5
  259. package/dist/src/services/consent.js.map +1 -1
  260. package/dist/src/services/core-jobs.d.ts.map +1 -1
  261. package/dist/src/services/core-jobs.js +20 -4
  262. package/dist/src/services/core-jobs.js.map +1 -1
  263. package/dist/src/services/event-bus.d.ts +24 -1
  264. package/dist/src/services/event-bus.d.ts.map +1 -1
  265. package/dist/src/services/event-bus.js +17 -2
  266. package/dist/src/services/event-bus.js.map +1 -1
  267. package/dist/src/services/generator-prompts/resolvers.d.ts +2 -0
  268. package/dist/src/services/generator-prompts/resolvers.d.ts.map +1 -1
  269. package/dist/src/services/generator-prompts/resolvers.js +22 -3
  270. package/dist/src/services/generator-prompts/resolvers.js.map +1 -1
  271. package/dist/src/services/job-seeding.d.ts.map +1 -1
  272. package/dist/src/services/job-seeding.js +4 -0
  273. package/dist/src/services/job-seeding.js.map +1 -1
  274. package/dist/src/services/living-author-prompt.d.ts +14 -0
  275. package/dist/src/services/living-author-prompt.d.ts.map +1 -0
  276. package/dist/src/services/living-author-prompt.js +47 -0
  277. package/dist/src/services/living-author-prompt.js.map +1 -0
  278. package/dist/src/services/living-author.d.ts +55 -0
  279. package/dist/src/services/living-author.d.ts.map +1 -0
  280. package/dist/src/services/living-author.js +91 -0
  281. package/dist/src/services/living-author.js.map +1 -0
  282. package/dist/src/services/living-pulse.d.ts +29 -0
  283. package/dist/src/services/living-pulse.d.ts.map +1 -0
  284. package/dist/src/services/living-pulse.js +363 -0
  285. package/dist/src/services/living-pulse.js.map +1 -0
  286. package/dist/src/services/message-delivery.d.ts +1 -1
  287. package/dist/src/services/message-delivery.d.ts.map +1 -1
  288. package/dist/src/services/message-delivery.js +10 -7
  289. package/dist/src/services/message-delivery.js.map +1 -1
  290. package/dist/src/services/message-send.d.ts +24 -0
  291. package/dist/src/services/message-send.d.ts.map +1 -0
  292. package/dist/src/services/message-send.js +122 -0
  293. package/dist/src/services/message-send.js.map +1 -0
  294. package/dist/src/services/notebook-ai.d.ts +36 -0
  295. package/dist/src/services/notebook-ai.d.ts.map +1 -0
  296. package/dist/src/services/notebook-ai.js +51 -0
  297. package/dist/src/services/notebook-ai.js.map +1 -0
  298. package/dist/src/services/notebook-classify.d.ts +32 -5
  299. package/dist/src/services/notebook-classify.d.ts.map +1 -1
  300. package/dist/src/services/notebook-classify.js +59 -43
  301. package/dist/src/services/notebook-classify.js.map +1 -1
  302. package/dist/src/services/notebook-distribute-prompt.d.ts +16 -0
  303. package/dist/src/services/notebook-distribute-prompt.d.ts.map +1 -0
  304. package/dist/src/services/notebook-distribute-prompt.js +40 -0
  305. package/dist/src/services/notebook-distribute-prompt.js.map +1 -0
  306. package/dist/src/services/notebook-plan-prompt.d.ts +19 -0
  307. package/dist/src/services/notebook-plan-prompt.d.ts.map +1 -0
  308. package/dist/src/services/notebook-plan-prompt.js +54 -0
  309. package/dist/src/services/notebook-plan-prompt.js.map +1 -0
  310. package/dist/src/services/notebook-plan.d.ts +70 -0
  311. package/dist/src/services/notebook-plan.d.ts.map +1 -0
  312. package/dist/src/services/notebook-plan.js +118 -0
  313. package/dist/src/services/notebook-plan.js.map +1 -0
  314. package/dist/src/services/onboarding-validator.d.ts.map +1 -1
  315. package/dist/src/services/onboarding-validator.js +13 -3
  316. package/dist/src/services/onboarding-validator.js.map +1 -1
  317. package/dist/src/services/organism-comments.d.ts +5 -1
  318. package/dist/src/services/organism-comments.d.ts.map +1 -1
  319. package/dist/src/services/organism-comments.js +7 -22
  320. package/dist/src/services/organism-comments.js.map +1 -1
  321. package/dist/src/services/organism-readme.d.ts +24 -0
  322. package/dist/src/services/organism-readme.d.ts.map +1 -0
  323. package/dist/src/services/organism-readme.js +37 -0
  324. package/dist/src/services/organism-readme.js.map +1 -0
  325. package/dist/src/services/prompt-defaults.d.ts.map +1 -1
  326. package/dist/src/services/prompt-defaults.js +30 -0
  327. package/dist/src/services/prompt-defaults.js.map +1 -1
  328. package/dist/src/services/readiness-scorer.d.ts.map +1 -1
  329. package/dist/src/services/readiness-scorer.js +11 -6
  330. package/dist/src/services/readiness-scorer.js.map +1 -1
  331. package/dist/src/services/scheduler.d.ts +5 -0
  332. package/dist/src/services/scheduler.d.ts.map +1 -1
  333. package/dist/src/services/scheduler.js +13 -3
  334. package/dist/src/services/scheduler.js.map +1 -1
  335. package/dist/src/services/screenshot-capture.d.ts +28 -0
  336. package/dist/src/services/screenshot-capture.d.ts.map +1 -0
  337. package/dist/src/services/screenshot-capture.js +154 -0
  338. package/dist/src/services/screenshot-capture.js.map +1 -0
  339. package/dist/src/services/structure-graph.d.ts +65 -0
  340. package/dist/src/services/structure-graph.d.ts.map +1 -0
  341. package/dist/src/services/structure-graph.js +53 -0
  342. package/dist/src/services/structure-graph.js.map +1 -0
  343. package/dist/src/services/structure-overview.d.ts +6 -0
  344. package/dist/src/services/structure-overview.d.ts.map +1 -1
  345. package/dist/src/services/structure-overview.js +1 -1
  346. package/dist/src/services/structure-overview.js.map +1 -1
  347. package/dist/src/services/structure-snapshot.d.ts +47 -0
  348. package/dist/src/services/structure-snapshot.d.ts.map +1 -0
  349. package/dist/src/services/structure-snapshot.js +101 -0
  350. package/dist/src/services/structure-snapshot.js.map +1 -0
  351. package/dist/src/services/telemetry-buffer.d.ts +73 -0
  352. package/dist/src/services/telemetry-buffer.d.ts.map +1 -0
  353. package/dist/src/services/telemetry-buffer.js +185 -0
  354. package/dist/src/services/telemetry-buffer.js.map +1 -0
  355. package/dist/src/services/track-registry.d.ts +29 -0
  356. package/dist/src/services/track-registry.d.ts.map +1 -0
  357. package/dist/src/services/track-registry.js +61 -0
  358. package/dist/src/services/track-registry.js.map +1 -0
  359. package/dist/src/services/tracked-classify.d.ts +98 -0
  360. package/dist/src/services/tracked-classify.d.ts.map +1 -0
  361. package/dist/src/services/tracked-classify.js +182 -0
  362. package/dist/src/services/tracked-classify.js.map +1 -0
  363. package/dist/src/services/tracked-response.d.ts +98 -0
  364. package/dist/src/services/tracked-response.d.ts.map +1 -0
  365. package/dist/src/services/tracked-response.js +304 -0
  366. package/dist/src/services/tracked-response.js.map +1 -0
  367. package/dist/src/services/workspace-access.d.ts +36 -0
  368. package/dist/src/services/workspace-access.d.ts.map +1 -0
  369. package/dist/src/services/workspace-access.js +38 -0
  370. package/dist/src/services/workspace-access.js.map +1 -0
  371. package/dist/src/storage/interface.d.ts +6 -1
  372. package/dist/src/storage/interface.d.ts.map +1 -1
  373. package/dist/src/storage/interface.js.map +1 -1
  374. package/dist/src/storage/providers/mongodb/index.d.ts +26 -1
  375. package/dist/src/storage/providers/mongodb/index.d.ts.map +1 -1
  376. package/dist/src/storage/providers/mongodb/index.js +144 -1
  377. package/dist/src/storage/providers/mongodb/index.js.map +1 -1
  378. package/dist/src/storage/providers/sqlite/index.d.ts +26 -1
  379. package/dist/src/storage/providers/sqlite/index.d.ts.map +1 -1
  380. package/dist/src/storage/providers/sqlite/index.js +73 -6
  381. package/dist/src/storage/providers/sqlite/index.js.map +1 -1
  382. package/dist/src/storage/providers/sqlite/repos/agent-message.d.ts +4 -0
  383. package/dist/src/storage/providers/sqlite/repos/agent-message.d.ts.map +1 -1
  384. package/dist/src/storage/providers/sqlite/repos/agent-message.js +14 -0
  385. package/dist/src/storage/providers/sqlite/repos/agent-message.js.map +1 -1
  386. package/dist/src/storage/providers/sqlite/repos/agent-task.d.ts +9 -0
  387. package/dist/src/storage/providers/sqlite/repos/agent-task.d.ts.map +1 -1
  388. package/dist/src/storage/providers/sqlite/repos/agent-task.js +25 -0
  389. package/dist/src/storage/providers/sqlite/repos/agent-task.js.map +1 -1
  390. package/dist/src/storage/providers/sqlite/repos/memory.d.ts +22 -1
  391. package/dist/src/storage/providers/sqlite/repos/memory.d.ts.map +1 -1
  392. package/dist/src/storage/providers/sqlite/repos/memory.js +61 -3
  393. package/dist/src/storage/providers/sqlite/repos/memory.js.map +1 -1
  394. package/dist/src/storage/providers/sqlite/schema.d.ts +16 -3
  395. package/dist/src/storage/providers/sqlite/schema.d.ts.map +1 -1
  396. package/dist/src/storage/providers/sqlite/schema.js +33 -6
  397. package/dist/src/storage/providers/sqlite/schema.js.map +1 -1
  398. package/dist/src/storage/repositories/agent-message.repository.d.ts +10 -0
  399. package/dist/src/storage/repositories/agent-message.repository.d.ts.map +1 -1
  400. package/dist/src/storage/repositories/agent-task.repository.d.ts +15 -0
  401. package/dist/src/storage/repositories/agent-task.repository.d.ts.map +1 -1
  402. package/dist/src/storage/repositories/app.repository.d.ts +9 -0
  403. package/dist/src/storage/repositories/app.repository.d.ts.map +1 -1
  404. package/dist/src/storage/repositories/consent.repository.d.ts +2 -0
  405. package/dist/src/storage/repositories/consent.repository.d.ts.map +1 -1
  406. package/dist/src/storage/repositories/memory.repository.d.ts +31 -0
  407. package/dist/src/storage/repositories/memory.repository.d.ts.map +1 -1
  408. package/dist/src/utils/env-config.d.ts.map +1 -1
  409. package/dist/src/utils/env-config.js +18 -0
  410. package/dist/src/utils/env-config.js.map +1 -1
  411. package/dist/src/utils/messaging.d.ts +5 -0
  412. package/dist/src/utils/messaging.d.ts.map +1 -1
  413. package/dist/src/utils/messaging.js +0 -0
  414. package/dist/src/utils/messaging.js.map +1 -1
  415. package/dist/static/app-catalog.html +452 -34
  416. package/dist/static/app-login.js +67 -0
  417. package/dist/static/app-silent.html +14 -0
  418. package/dist/static/app-silent.js +32 -0
  419. package/package.json +5 -1
  420. package/prisma/schema.postgres.prisma +36 -18
  421. package/prisma/schema.prisma +20 -0
@@ -1,94 +1,231 @@
1
- /**
2
- * SSE Live Updates — singleton connection with reference counting and debounced callbacks.
3
- * Opens an EventSource to /v1/events using a single-use ticket obtained via authenticated POST.
4
- */
5
-
6
- let es = null;
7
- let listeners = new Set();
8
- let debounceTimer = null;
9
- let refCount = 0;
10
- let jwtGetter = null;
11
- let reconnectTimer = null;
12
- let reconnectDelay = 5000;
13
- const MAX_RECONNECT_DELAY = 120000;
14
-
15
- export async function connect(getJwt) {
16
- refCount++;
17
- if (es) return;
18
-
19
- jwtGetter = getJwt;
20
- await _open();
21
- }
22
-
23
- async function _open() {
24
- const jwt = jwtGetter?.();
25
- if (!jwt) return;
26
-
27
- try {
28
- const resp = await fetch('/v1/events/ticket', {
29
- method: 'POST',
30
- headers: { 'Authorization': `Bearer ${jwt}` },
31
- });
32
- if (!resp.ok) {
33
- console.warn('[SSE] Ticket request failed:', resp.status);
34
- reconnectTimer = setTimeout(() => { if (refCount > 0) _open(); }, reconnectDelay);
35
- reconnectDelay = Math.min(reconnectDelay * 2, MAX_RECONNECT_DELAY);
36
- return;
37
- }
38
- const body = await resp.json();
39
- const ticket = body.data.ticket;
40
-
41
- es = new EventSource(`/v1/events?ticket=${encodeURIComponent(ticket)}`);
42
-
43
- es.onopen = () => {
44
- reconnectDelay = 5000; // reset on successful connection
45
- };
46
-
47
- es.onmessage = (event) => {
48
- reconnectDelay = 5000;
49
- clearTimeout(debounceTimer);
50
- debounceTimer = setTimeout(() => {
51
- listeners.forEach(fn => fn());
52
- }, 500);
53
- };
54
-
55
- es.onerror = () => {
56
- if (es) { es.close(); es = null; }
57
- clearTimeout(reconnectTimer);
58
- if (refCount > 0 && jwtGetter) {
59
- reconnectTimer = setTimeout(() => {
60
- if (refCount > 0) _open();
61
- }, reconnectDelay);
62
- reconnectDelay = Math.min(reconnectDelay * 2, MAX_RECONNECT_DELAY);
63
- }
64
- };
65
- } catch {
66
- // Network error fetching ticket — retry with backoff
67
- clearTimeout(reconnectTimer);
68
- if (refCount > 0) {
69
- reconnectTimer = setTimeout(() => {
70
- if (refCount > 0) _open();
71
- }, reconnectDelay);
72
- reconnectDelay = Math.min(reconnectDelay * 2, MAX_RECONNECT_DELAY);
73
- }
74
- }
75
- }
76
-
77
- export function disconnect() {
78
- refCount = Math.max(0, refCount - 1);
79
- if (refCount === 0) {
80
- if (es) { es.close(); es = null; }
81
- clearTimeout(debounceTimer);
82
- clearTimeout(reconnectTimer);
83
- reconnectDelay = 5000;
84
- jwtGetter = null;
85
- }
86
- }
87
-
88
- export function onUpdate(callback) {
89
- listeners.add(callback);
90
- }
91
-
92
- export function offUpdate(callback) {
93
- listeners.delete(callback);
94
- }
1
+ /**
2
+ * SSE Live Updates — ONE EventSource per browser (shared across tabs), domain-aware,
3
+ * debounced, and visibility-gated.
4
+ *
5
+ * Connection sharing (multi-tab): instead of every tab opening its own EventSource (20 tabs =
6
+ * 20 connections, and HTTP/1.1 caps at 6/domain), a single "leader" tab holds the EventSource
7
+ * and relays each event to follower tabs over a BroadcastChannel. Leadership is elected with the
8
+ * Web Locks API: whoever holds the 'aimeat-live-leader' lock is the leader; when the leader tab
9
+ * closes (or crashes) the browser auto-releases the lock and a waiting tab takes over — no
10
+ * heartbeat, no polling. Browsers without BroadcastChannel/Web Locks fall back to a per-tab
11
+ * connection (today's behaviour, no regression).
12
+ *
13
+ * Selective refetch: the server sends `data: {"domains":[...]}` (which domains changed in the
14
+ * last ~1s window). We accumulate domains across a 1000ms debounce (matching the server
15
+ * coalesce) and notify only the subscribers that care. Hidden tabs do NO refetch fan-out (Page
16
+ * Visibility gating) and catch up once when re-shown. A (re)connect forces one "all domains"
17
+ * reconcile so nothing is missed. A legacy/opaque payload is treated as "everything changed".
18
+ */
19
+
20
+ let es = null;
21
+ let subscribers = []; // { domains: Set<string>|null, fn } (null = all domains)
22
+ let debounceTimer = null;
23
+ let refCount = 0;
24
+ let jwtGetter = null;
25
+ let reconnectTimer = null;
26
+ let reconnectDelay = 5000;
27
+ let everOpened = false;
28
+ const MAX_RECONNECT_DELAY = 120000;
29
+ const DEBOUNCE_MS = 1000; // match server COALESCE_MS
30
+
31
+ let pendingDomains = new Set(); // null ⇒ "everything changed" (sticky for the window)
32
+ let hadHiddenUpdate = false;
33
+
34
+ // Multi-tab connection sharing
35
+ let started = false;
36
+ let isLeader = false;
37
+ let bc = null; // BroadcastChannel | null
38
+ let leaderRelease = null; // resolves the Web Lock promise → releases leadership
39
+ let leaderAbort = null; // aborts a still-queued (follower) lock request on disconnect
40
+
41
+ export async function connect(getJwt) {
42
+ refCount++;
43
+ jwtGetter = getJwt;
44
+ if (started) return;
45
+ started = true;
46
+ startShared();
47
+ }
48
+
49
+ function startShared() {
50
+ const canShare = (typeof BroadcastChannel !== 'undefined')
51
+ && (typeof navigator !== 'undefined') && navigator.locks;
52
+ if (!canShare) { becomeLeader(); return; } // legacy: this tab opens its own connection
53
+
54
+ bc = new BroadcastChannel('aimeat-live');
55
+ bc.onmessage = (ev) => {
56
+ if (ev.data && ev.data.type === 'domains') ingestDomains(ev.data.domains);
57
+ };
58
+ // Hold the lock for as long as this tab is connected; whoever holds it is the leader. The
59
+ // request callback resolves only when we release (on disconnect), at which point the next
60
+ // waiting tab becomes leader. If the leader tab closes/crashes the browser auto-releases.
61
+ // The AbortController cancels a still-QUEUED request (a follower that disconnects before ever
62
+ // acquiring the lock) so it can't later become a phantom leader with no active views.
63
+ leaderAbort = new AbortController();
64
+ navigator.locks.request('aimeat-live-leader', { mode: 'exclusive', signal: leaderAbort.signal }, () => new Promise((release) => {
65
+ leaderRelease = release;
66
+ becomeLeader();
67
+ })).catch(() => { /* aborted while queued — fine */ });
68
+ }
69
+
70
+ function becomeLeader() {
71
+ if (isLeader) return;
72
+ isLeader = true;
73
+ _open();
74
+ }
75
+
76
+ /** Relay an event to follower tabs (no-op when not sharing). */
77
+ function relay(domains) {
78
+ if (bc) { try { bc.postMessage({ type: 'domains', domains }); } catch { /* channel closed */ } }
79
+ }
80
+
81
+ async function _open() {
82
+ const jwt = jwtGetter?.();
83
+ if (!jwt) return;
84
+
85
+ try {
86
+ const resp = await fetch('/v1/events/ticket', {
87
+ method: 'POST',
88
+ headers: { 'Authorization': `Bearer ${jwt}` },
89
+ });
90
+ if (!resp.ok) {
91
+ console.warn('[SSE] Ticket request failed:', resp.status);
92
+ scheduleReconnect();
93
+ return;
94
+ }
95
+ const body = await resp.json();
96
+ const ticket = body.data.ticket;
97
+
98
+ es = new EventSource(`/v1/events?ticket=${encodeURIComponent(ticket)}`);
99
+
100
+ es.onopen = () => {
101
+ reconnectDelay = 5000;
102
+ // Reconnect catch-up: after a gap we may have missed events, so force one "all domains"
103
+ // reconcile (locally + relayed). Skip on the very first open (views load on mount).
104
+ if (everOpened) { ingestDomains(null); relay(null); }
105
+ everOpened = true;
106
+ };
107
+
108
+ es.onmessage = (event) => {
109
+ reconnectDelay = 5000;
110
+ let domains = null;
111
+ try {
112
+ const p = JSON.parse(event.data);
113
+ if (Array.isArray(p.domains)) domains = p.domains;
114
+ } catch { /* legacy {"t":"change"} or non-JSON ⇒ treat as "everything" */ }
115
+ ingestDomains(domains);
116
+ relay(domains);
117
+ };
118
+
119
+ es.onerror = () => {
120
+ if (es) { es.close(); es = null; }
121
+ scheduleReconnect();
122
+ };
123
+ } catch {
124
+ scheduleReconnect();
125
+ }
126
+ }
127
+
128
+ /** Accumulate changed domains and (re)arm the debounce. `null` ⇒ everything changed. */
129
+ function ingestDomains(domains) {
130
+ if (domains === null) pendingDomains = null;
131
+ else if (pendingDomains !== null) domains.forEach(d => pendingDomains.add(d));
132
+ clearTimeout(debounceTimer);
133
+ debounceTimer = setTimeout(flushDomains, DEBOUNCE_MS);
134
+ }
135
+
136
+ /** Dispatch accumulated domains to interested subscribers — unless this tab is hidden. */
137
+ function flushDomains() {
138
+ // Page Visibility gating: a hidden tab does NO refetch fan-out; it catches up on re-show.
139
+ if (typeof document !== 'undefined' && document.hidden) { hadHiddenUpdate = true; return; }
140
+ const dset = pendingDomains;
141
+ pendingDomains = new Set();
142
+ dispatch(dset);
143
+ }
144
+
145
+ function dispatch(dset) {
146
+ for (const s of subscribers.slice()) {
147
+ if (dset === null || s.domains === null) { try { s.fn(dset); } catch { /* listener error */ } continue; }
148
+ for (const d of dset) {
149
+ if (s.domains.has(d)) { try { s.fn(dset); } catch { /* listener error */ } break; }
150
+ }
151
+ }
152
+ }
153
+
154
+ function scheduleReconnect() {
155
+ // Only the connection holder (leader / legacy) reconnects.
156
+ clearTimeout(reconnectTimer);
157
+ if (refCount > 0 && jwtGetter && isLeader) {
158
+ reconnectTimer = setTimeout(() => { if (refCount > 0) _open(); }, reconnectDelay);
159
+ reconnectDelay = Math.min(reconnectDelay * 2, MAX_RECONNECT_DELAY);
160
+ }
161
+ }
162
+
163
+ if (typeof document !== 'undefined') {
164
+ document.addEventListener('visibilitychange', () => {
165
+ if (!document.hidden && hadHiddenUpdate) {
166
+ hadHiddenUpdate = false;
167
+ pendingDomains = null; // one catch-up reconcile across all domains
168
+ flushDomains();
169
+ }
170
+ });
171
+ }
172
+
173
+ export function disconnect() {
174
+ refCount = Math.max(0, refCount - 1);
175
+ if (refCount === 0) {
176
+ started = false;
177
+ if (es) { es.close(); es = null; }
178
+ if (leaderAbort) { try { leaderAbort.abort(); } catch { /* noop */ } leaderAbort = null; }
179
+ if (leaderRelease) { try { leaderRelease(); } catch { /* already released */ } leaderRelease = null; }
180
+ isLeader = false;
181
+ if (bc) { try { bc.close(); } catch { /* already closed */ } bc = null; }
182
+ clearTimeout(debounceTimer);
183
+ clearTimeout(reconnectTimer);
184
+ reconnectDelay = 5000;
185
+ jwtGetter = null;
186
+ everOpened = false;
187
+ pendingDomains = new Set();
188
+ hadHiddenUpdate = false;
189
+ }
190
+ }
191
+
192
+ /**
193
+ * Subscribe to live updates for specific domains.
194
+ * @param {string[]|null} domains Domains of interest (e.g. ['agent-tasks']); null = all domains.
195
+ * @param {(domains: Set<string>|null) => void} fn Called when any of those domains change.
196
+ * @returns {() => void} unsubscribe
197
+ */
198
+ export function subscribe(domains, fn) {
199
+ const entry = { domains: domains ? new Set(domains) : null, fn };
200
+ subscribers.push(entry);
201
+ return () => { const i = subscribers.indexOf(entry); if (i >= 0) subscribers.splice(i, 1); };
202
+ }
203
+
204
+ /** Back-compat: subscribe to ALL changes (no domain filter). */
205
+ export function onUpdate(callback) { return subscribe(null, callback); }
206
+
207
+ export function offUpdate(callback) {
208
+ for (let i = subscribers.length - 1; i >= 0; i--) {
209
+ if (subscribers[i].fn === callback) subscribers.splice(i, 1);
210
+ }
211
+ }
212
+
213
+ /**
214
+ * Convenience for views: listen to the window 'aimeat-live-update' event, filtered to the
215
+ * domains a view cares about, and run `fn` only when one of those domains changed (or when the
216
+ * payload is the legacy "everything changed"). Replaces the old per-tab
217
+ * `addEventListener + setInterval(fallback poll)` boilerplate — no steady-state polling.
218
+ * @param {string[]|null} domains Domains of interest; null = fire on any change.
219
+ * @param {() => void} fn
220
+ * @returns {() => void} unsubscribe (use as a useEffect cleanup)
221
+ */
222
+ export function onLiveUpdate(domains, fn) {
223
+ const want = domains ? new Set(domains) : null;
224
+ const handler = (e) => {
225
+ const d = e.detail?.domains; // Set<string> | null
226
+ if (want && d && ![...want].some(x => d.has(x))) return;
227
+ fn();
228
+ };
229
+ window.addEventListener('aimeat-live-update', handler);
230
+ return () => window.removeEventListener('aimeat-live-update', handler);
231
+ }
@@ -77,6 +77,7 @@
77
77
  <link rel="stylesheet" href="/css/views/portal-dev.css">
78
78
  <link rel="stylesheet" href="/css/views/profile.css">
79
79
  <link rel="stylesheet" href="/css/views/notebook.css">
80
+ <link rel="stylesheet" href="/css/views/living.css">
80
81
  <link rel="stylesheet" href="/css/views/offers.css">
81
82
  <link rel="stylesheet" href="/css/views/foundry.css">
82
83
  <link rel="stylesheet" href="/css/views/calibrator.css">
@@ -163,8 +164,10 @@
163
164
  "/js/services/foundry-smoke.js": "/js/services/foundry-smoke.js",
164
165
  "/js/services/foundry-probe-reconcile.js": "/js/services/foundry-probe-reconcile.js",
165
166
  "/js/services/knowledge.js": "/js/services/knowledge.js",
167
+ "/js/services/living.js": "/js/services/living.js",
166
168
  "/js/services/memory.js": "/js/services/memory.js",
167
169
  "/js/services/notebook.js": "/js/services/notebook.js",
170
+ "/js/services/notebook-plan.js": "/js/services/notebook-plan.js",
168
171
  "/js/services/nodes.js": "/js/services/nodes.js",
169
172
  "/js/services/organisms.js": "/js/services/organisms.js",
170
173
  "/js/services/offers.js": "/js/services/offers.js",
@@ -175,6 +178,7 @@
175
178
  "/js/services/wallet.js": "/js/services/wallet.js",
176
179
  "/js/services/work.js": "/js/services/work.js",
177
180
  "/js/services/messages.js": "/js/services/messages.js",
181
+ "/js/services/tracked-responses.js": "/js/services/tracked-responses.js",
178
182
  "/js/services/presence.js": "/js/services/presence.js",
179
183
  "/js/presence-store.js": "/js/presence-store.js",
180
184
  "/js/components/auth-image.js": "/js/components/auth-image.js",
@@ -235,7 +239,10 @@
235
239
  "/views/profile/organisms/workspace-comments.js": "/views/profile/organisms/workspace-comments.js",
236
240
  "/views/profile/organisms/sources-panel.js": "/views/profile/organisms/sources-panel.js",
237
241
  "/views/profile/organisms/schema-form.js": "/views/profile/organisms/schema-form.js",
238
- "/views/profile/organisms/document.js": "/views/profile/organisms/document.js"
242
+ "/views/profile/organisms/document.js": "/views/profile/organisms/document.js",
243
+ "/views/profile/organisms/mindmap.js": "/views/profile/organisms/mindmap.js",
244
+ "/views/profile/organisms/readme-panel.js": "/views/profile/organisms/readme-panel.js",
245
+ "/views/profile/organisms/timeline-panel.js": "/views/profile/organisms/timeline-panel.js"
239
246
  }
240
247
  }
241
248
  </script>
@@ -35,6 +35,10 @@ declare global {
35
35
  /** Preact bundle marker set by the vendored preact build. */
36
36
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
37
37
  __B?: any;
38
+ /** H-2: true when the node serves apps from a separate app origin — set the launchers to
39
+ * open published apps top-level (apex inline URL 301s to apps.<domain>) instead of the
40
+ * opaque-sandbox iframe. Injected into spa.html / app-catalog.html by the server. */
41
+ __APP_ORIGIN_ENABLED?: boolean;
38
42
  }
39
43
 
40
44
  /**
@@ -14,6 +14,7 @@
14
14
  import { h } from 'preact';
15
15
  import { useState, useEffect, useCallback } from 'preact/hooks';
16
16
  import htm from 'htm';
17
+ import { onLiveUpdate } from '/lib/live-updates.js';
17
18
  const html = htm.bind(h);
18
19
  import { t } from '/js/i18n.js';
19
20
  import { useViewCSS } from '/components/useViewCSS.js';
@@ -49,11 +50,7 @@ export default function AgentIntegrationTab({ data, session }) {
49
50
 
50
51
  useEffect(() => { loadData(); }, [loadData]);
51
52
 
52
- useEffect(() => {
53
- const handler = () => { loadData(); };
54
- window.addEventListener('aimeat-live-update', handler);
55
- return () => window.removeEventListener('aimeat-live-update', handler);
56
- }, [loadData]);
53
+ useEffect(() => onLiveUpdate(['agents'], () => loadData()), [loadData]);
57
54
 
58
55
  if (loading) return html`<div class="adm-card">${t('common.loading')}</div>`;
59
56
 
@@ -11,6 +11,7 @@
11
11
  import { h } from 'preact';
12
12
  import { useState, useEffect, useCallback } from 'preact/hooks';
13
13
  import htm from 'htm';
14
+ import { onLiveUpdate } from '/lib/live-updates.js';
14
15
  const html = htm.bind(h);
15
16
  import { t } from '/js/i18n.js';
16
17
  import { escHtml } from '/js/utils.js';
@@ -50,11 +51,7 @@ export default function AgentTasksTab({ data, reload, session }) {
50
51
  useEffect(() => { loadTasks(1); }, [loadTasks]);
51
52
 
52
53
  // Listen for live updates
53
- useEffect(() => {
54
- const handler = () => { loadTasks(page, { showSpinner: false }); }; // silent: no flash
55
- window.addEventListener('aimeat-live-update', handler);
56
- return () => window.removeEventListener('aimeat-live-update', handler);
57
- }, [loadTasks, page]);
54
+ useEffect(() => onLiveUpdate(['agent-tasks'], () => loadTasks(page, { showSpinner: false })), [loadTasks, page]);
58
55
 
59
56
  function handleFilterChange(e) {
60
57
  setStatusFilter(e.target.value);
@@ -14,6 +14,7 @@
14
14
  import { h } from 'preact';
15
15
  import { useState, useEffect, useCallback } from 'preact/hooks';
16
16
  import htm from 'htm';
17
+ import { onLiveUpdate } from '/lib/live-updates.js';
17
18
  const html = htm.bind(h);
18
19
  import { t } from '/js/i18n.js';
19
20
  import { escHtml } from '/js/utils.js';
@@ -41,11 +42,7 @@ export default function CortexTab({ data, reload, session }) {
41
42
  }, []);
42
43
 
43
44
  useEffect(() => { loadData(); }, [loadData]);
44
- useEffect(() => {
45
- const handler = () => { loadData({ showSpinner: false }); }; // silent: no flash
46
- window.addEventListener('aimeat-live-update', handler);
47
- return () => window.removeEventListener('aimeat-live-update', handler);
48
- }, [loadData]);
45
+ useEffect(() => onLiveUpdate(['cortex'], () => loadData({ showSpinner: false })), [loadData]);
49
46
 
50
47
  const handleActivate = async (name) => {
51
48
  try {
@@ -18,6 +18,7 @@
18
18
  import { h } from 'preact';
19
19
  import { useState, useEffect, useCallback, useRef } from 'preact/hooks';
20
20
  import htm from 'htm';
21
+ import { onLiveUpdate } from '/lib/live-updates.js';
21
22
  const html = htm.bind(h);
22
23
  import { t } from '/js/i18n.js';
23
24
  import { escHtml } from '/js/utils.js';
@@ -84,11 +85,7 @@ export default function FederationTab({ data, reload }) {
84
85
  catch { setBook(null); }
85
86
  }, []);
86
87
  useEffect(() => { loadBook(); }, [loadBook]);
87
- useEffect(() => {
88
- const h = () => loadBook();
89
- window.addEventListener('aimeat-live-update', h);
90
- return () => window.removeEventListener('aimeat-live-update', h);
91
- }, [loadBook]);
88
+ useEffect(() => onLiveUpdate(['federation'], () => loadBook()), [loadBook]);
92
89
 
93
90
  const doSaveAuthPolicy = async (policy, scopes) => {
94
91
  const changes = [
@@ -123,11 +120,7 @@ export default function FederationTab({ data, reload }) {
123
120
 
124
121
  useEffect(() => { loadDirectory(''); }, []);
125
122
 
126
- useEffect(() => {
127
- const handler = () => loadDirectory(dirSearch);
128
- window.addEventListener('aimeat-live-update', handler);
129
- return () => window.removeEventListener('aimeat-live-update', handler);
130
- }, [dirSearch]);
123
+ useEffect(() => onLiveUpdate(['federation'], () => loadDirectory(dirSearch)), [dirSearch]);
131
124
 
132
125
  const onDirSearchInput = useCallback((e) => {
133
126
  const val = e.target.value;
@@ -13,6 +13,7 @@
13
13
  import { h } from 'preact';
14
14
  import { useState, useEffect, useCallback } from 'preact/hooks';
15
15
  import htm from 'htm';
16
+ import { onLiveUpdate } from '/lib/live-updates.js';
16
17
  const html = htm.bind(h);
17
18
  import { t } from '/js/i18n.js';
18
19
  import { escHtml } from '/js/utils.js';
@@ -59,11 +60,7 @@ export default function MemoryTab({ data, reload, session }) {
59
60
  useEffect(() => { loadMemory(0); }, [loadMemory]);
60
61
 
61
62
  // Listen for live updates
62
- useEffect(() => {
63
- const handler = () => { loadMemory(offset, { showSpinner: false }); }; // silent: no flash
64
- window.addEventListener('aimeat-live-update', handler);
65
- return () => window.removeEventListener('aimeat-live-update', handler);
66
- }, [loadMemory, offset]);
63
+ useEffect(() => onLiveUpdate(['memory'], () => loadMemory(offset, { showSpinner: false })), [loadMemory, offset]);
67
64
 
68
65
  function toggleExpand(idx) {
69
66
  setExpanded(prev => {
@@ -12,6 +12,7 @@
12
12
  import { h } from 'preact';
13
13
  import { useState, useEffect, useCallback } from 'preact/hooks';
14
14
  import htm from 'htm';
15
+ import { onLiveUpdate } from '/lib/live-updates.js';
15
16
  const html = htm.bind(h);
16
17
  import { t } from '/js/i18n.js';
17
18
  import { escHtml } from '/js/utils.js';
@@ -43,11 +44,7 @@ export default function MessagesTab() {
43
44
  }, []);
44
45
 
45
46
  useEffect(() => { load(); }, [load]);
46
- useEffect(() => {
47
- const hh = () => load();
48
- window.addEventListener('aimeat-live-update', hh);
49
- return () => window.removeEventListener('aimeat-live-update', hh);
50
- }, [load]);
47
+ useEffect(() => onLiveUpdate(['messages', 'agent-messages'], () => load()), [load]);
51
48
 
52
49
  if (err) return html`<div class="adm-section"><div class="adm-error">${escHtml(err)}</div></div>`;
53
50
  if (!data) return html`<div class="adm-section">${t('common.loading') || 'Loading…'}</div>`;
@@ -18,6 +18,7 @@
18
18
  import { h } from 'preact';
19
19
  import { useState, useEffect, useCallback } from 'preact/hooks';
20
20
  import htm from 'htm';
21
+ import { onLiveUpdate } from '/lib/live-updates.js';
21
22
  const html = htm.bind(h);
22
23
  import { t } from '/js/i18n.js';
23
24
  import { escHtml } from '/js/utils.js';
@@ -329,11 +330,7 @@ export default function PackagesAdminTab({ data, reload, session }) {
329
330
  useEffect(() => { loadData(); }, [loadData]);
330
331
 
331
332
  // Live updates
332
- useEffect(() => {
333
- const handler = () => { loadData({ showSpinner: false }); }; // silent: no flash
334
- window.addEventListener('aimeat-live-update', handler);
335
- return () => window.removeEventListener('aimeat-live-update', handler);
336
- }, [loadData]);
333
+ useEffect(() => onLiveUpdate(['packages'], () => loadData({ showSpinner: false })), [loadData]);
337
334
 
338
335
  if (loading) return html`<${Spinner} text=${t('dashboard.loading')} />`;
339
336
 
@@ -8,6 +8,7 @@
8
8
  import { h } from 'preact';
9
9
  import { useState, useEffect, useCallback } from 'preact/hooks';
10
10
  import htm from 'htm';
11
+ import { onLiveUpdate } from '/lib/live-updates.js';
11
12
  const html = htm.bind(h);
12
13
  import { t } from '/js/i18n.js';
13
14
  import { escHtml } from '/js/utils.js';
@@ -36,11 +37,7 @@ export default function SharingGroupsTab({ data, reload, session }) {
36
37
  useEffect(() => { loadGroups(); }, [loadGroups]);
37
38
 
38
39
  // Listen for live updates
39
- useEffect(() => {
40
- const handler = () => { loadGroups({ showSpinner: false }); }; // silent: no flash
41
- window.addEventListener('aimeat-live-update', handler);
42
- return () => window.removeEventListener('aimeat-live-update', handler);
43
- }, [loadGroups]);
40
+ useEffect(() => onLiveUpdate(['groups'], () => loadGroups({ showSpinner: false })), [loadGroups]);
44
41
 
45
42
  return html`
46
43
  <div>