aimeat 1.2.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 (1366) hide show
  1. package/dist/.env.example +300 -0
  2. package/dist/bin/aimeat.d.ts +3 -0
  3. package/dist/bin/aimeat.d.ts.map +1 -0
  4. package/dist/bin/aimeat.js +22 -0
  5. package/dist/bin/aimeat.js.map +1 -0
  6. package/dist/locales/en.json +4566 -0
  7. package/dist/locales/fi.json +4566 -0
  8. package/dist/public/BingSiteAuth.xml +4 -0
  9. package/dist/public/agent-consent.html +521 -0
  10. package/dist/public/aimeat-developers.html +679 -0
  11. package/dist/public/assets/mcp_1_add_custom_connector.png +0 -0
  12. package/dist/public/assets/mcp_2_connect_disconnect_connector.png +0 -0
  13. package/dist/public/components/Alert.js +18 -0
  14. package/dist/public/components/Card.js +19 -0
  15. package/dist/public/components/CopyButton.js +24 -0
  16. package/dist/public/components/FormField.js +16 -0
  17. package/dist/public/components/Modal.js +121 -0
  18. package/dist/public/components/Spinner.js +11 -0
  19. package/dist/public/components/Toast.js +26 -0
  20. package/dist/public/components/index.js +8 -0
  21. package/dist/public/components/useViewCSS.js +12 -0
  22. package/dist/public/cortex-bundled/aimeat-canvas.js +1408 -0
  23. package/dist/public/cortex-bundled/aimeat-canvas.yaml +241 -0
  24. package/dist/public/cortex-bundled/aimeat-charts.js +455 -0
  25. package/dist/public/cortex-bundled/aimeat-charts.yaml +178 -0
  26. package/dist/public/cortex-bundled/aimeat-ui-dialogs.js +667 -0
  27. package/dist/public/cortex-bundled/aimeat-ui-dialogs.yaml +66 -0
  28. package/dist/public/cortex-bundled/aimeat-ui-forms.js +1106 -0
  29. package/dist/public/cortex-bundled/aimeat-ui-forms.yaml +90 -0
  30. package/dist/public/cortex-bundled/aimeat-ui-layout.js +436 -0
  31. package/dist/public/cortex-bundled/aimeat-ui-layout.yaml +87 -0
  32. package/dist/public/cortex-bundled/aimeat-ui-nav.js +722 -0
  33. package/dist/public/cortex-bundled/aimeat-ui-nav.yaml +73 -0
  34. package/dist/public/cortex-bundled/aimeat-ui-viewers.js +602 -0
  35. package/dist/public/cortex-bundled/aimeat-ui-viewers.yaml +73 -0
  36. package/dist/public/css/components/tags.css +67 -0
  37. package/dist/public/css/theme.css +716 -0
  38. package/dist/public/css/views/admin.css +576 -0
  39. package/dist/public/css/views/aimeat-os.css +153 -0
  40. package/dist/public/css/views/calibrator.css +480 -0
  41. package/dist/public/css/views/foundry.css +1334 -0
  42. package/dist/public/css/views/help.css +136 -0
  43. package/dist/public/css/views/hobbies.css +73 -0
  44. package/dist/public/css/views/marketplace.css +134 -0
  45. package/dist/public/css/views/openclaw.css +33 -0
  46. package/dist/public/css/views/portal-classic.css +484 -0
  47. package/dist/public/css/views/portal-dev.css +139 -0
  48. package/dist/public/css/views/portal.css +365 -0
  49. package/dist/public/css/views/portfolio.css +322 -0
  50. package/dist/public/css/views/profile.css +1799 -0
  51. package/dist/public/echat.html +442 -0
  52. package/dist/public/img/genesis-001-badge.png +0 -0
  53. package/dist/public/img/platforms/chatgpt.png +0 -0
  54. package/dist/public/img/platforms/claude.png +0 -0
  55. package/dist/public/img/platforms/copilot.png +0 -0
  56. package/dist/public/img/platforms/deepseek.png +0 -0
  57. package/dist/public/img/platforms/gemini.png +0 -0
  58. package/dist/public/img/platforms/grok.png +0 -0
  59. package/dist/public/img/platforms/lmstudio.png +0 -0
  60. package/dist/public/img/platforms/m365copilot.png +0 -0
  61. package/dist/public/img/platforms/openclaw.png +0 -0
  62. package/dist/public/img/platforms/other.png +0 -0
  63. package/dist/public/js/api.js +123 -0
  64. package/dist/public/js/components/auth-image.js +59 -0
  65. package/dist/public/js/components/tag-cloud.js +31 -0
  66. package/dist/public/js/components/tag-editor.js +46 -0
  67. package/dist/public/js/hooks.js +63 -0
  68. package/dist/public/js/i18n.js +76 -0
  69. package/dist/public/js/services/admin.js +239 -0
  70. package/dist/public/js/services/agents.js +57 -0
  71. package/dist/public/js/services/apps.js +35 -0
  72. package/dist/public/js/services/auth.js +40 -0
  73. package/dist/public/js/services/boards.js +79 -0
  74. package/dist/public/js/services/calibrator.js +97 -0
  75. package/dist/public/js/services/catalogue.js +39 -0
  76. package/dist/public/js/services/consent.js +57 -0
  77. package/dist/public/js/services/cortex.js +95 -0
  78. package/dist/public/js/services/extensions.js +61 -0
  79. package/dist/public/js/services/federation.js +11 -0
  80. package/dist/public/js/services/foundry-context-bundle.js +128 -0
  81. package/dist/public/js/services/foundry-contract.js +117 -0
  82. package/dist/public/js/services/foundry-packaging.js +762 -0
  83. package/dist/public/js/services/foundry-probe-reconcile.js +52 -0
  84. package/dist/public/js/services/foundry-prompts-base.js +1886 -0
  85. package/dist/public/js/services/foundry-prompts-build.js +2187 -0
  86. package/dist/public/js/services/foundry-prompts-cortex-app.js +154 -0
  87. package/dist/public/js/services/foundry-prompts-cortex-data.js +241 -0
  88. package/dist/public/js/services/foundry-prompts-cortex-feature.js +281 -0
  89. package/dist/public/js/services/foundry-prompts-fix.js +408 -0
  90. package/dist/public/js/services/foundry-prompts-test.js +520 -0
  91. package/dist/public/js/services/foundry-prompts.js +31 -0
  92. package/dist/public/js/services/foundry-smoke.js +65 -0
  93. package/dist/public/js/services/foundry-testing.js +64 -0
  94. package/dist/public/js/services/foundry-validate.js +1082 -0
  95. package/dist/public/js/services/foundry.js +1194 -0
  96. package/dist/public/js/services/generator-context-bundle.js +134 -0
  97. package/dist/public/js/services/generator-contract.js +117 -0
  98. package/dist/public/js/services/generator-packaging.js +762 -0
  99. package/dist/public/js/services/generator-probe-reconcile.js +52 -0
  100. package/dist/public/js/services/generator-prompts-base.js +1890 -0
  101. package/dist/public/js/services/generator-prompts-build.js +1126 -0
  102. package/dist/public/js/services/generator-prompts-cortex-app.js +155 -0
  103. package/dist/public/js/services/generator-prompts-cortex-data.js +199 -0
  104. package/dist/public/js/services/generator-prompts-cortex-feature.js +276 -0
  105. package/dist/public/js/services/generator-prompts-fix.js +316 -0
  106. package/dist/public/js/services/generator-prompts-test.js +402 -0
  107. package/dist/public/js/services/generator-prompts.js +31 -0
  108. package/dist/public/js/services/generator-smoke.js +65 -0
  109. package/dist/public/js/services/generator-spec-tests.js +280 -0
  110. package/dist/public/js/services/generator-spec-validate.js +192 -0
  111. package/dist/public/js/services/generator-specs.js +369 -0
  112. package/dist/public/js/services/generator-testing.js +64 -0
  113. package/dist/public/js/services/generator-validate.js +916 -0
  114. package/dist/public/js/services/generator.js +952 -0
  115. package/dist/public/js/services/knowledge.js +120 -0
  116. package/dist/public/js/services/memory.js +112 -0
  117. package/dist/public/js/services/nodes.js +55 -0
  118. package/dist/public/js/services/organisms.js +74 -0
  119. package/dist/public/js/services/packages.js +97 -0
  120. package/dist/public/js/services/security.js +67 -0
  121. package/dist/public/js/services/stats.js +11 -0
  122. package/dist/public/js/services/wallet.js +24 -0
  123. package/dist/public/js/services/work.js +51 -0
  124. package/dist/public/js/utils.js +184 -0
  125. package/dist/public/lib/htm.mjs +4 -0
  126. package/dist/public/lib/live-updates.js +89 -0
  127. package/dist/public/lib/minidenticons.min.js +1 -0
  128. package/dist/public/lib/preact-hooks.mjs +3 -0
  129. package/dist/public/lib/preact.mjs +3 -0
  130. package/dist/public/lib/realtime.js +549 -0
  131. package/dist/public/lib/three.min.js +6 -0
  132. package/dist/public/lib/yaml.mjs +141 -0
  133. package/dist/public/llms-template.txt +1043 -0
  134. package/dist/public/oauth-consent.html +388 -0
  135. package/dist/public/og-image.png +0 -0
  136. package/dist/public/robots.txt +52 -0
  137. package/dist/public/spa.html +533 -0
  138. package/dist/public/sw.js +34 -0
  139. package/dist/public/tmp-paste.txt +223 -0
  140. package/dist/public/views/_template.js +85 -0
  141. package/dist/public/views/admin/actions-tab.js +41 -0
  142. package/dist/public/views/admin/agents-tab.js +84 -0
  143. package/dist/public/views/admin/boards-tab.js +154 -0
  144. package/dist/public/views/admin/chat-instances-tab.js +207 -0
  145. package/dist/public/views/admin/config-tab.js +151 -0
  146. package/dist/public/views/admin/consul-tab.js +77 -0
  147. package/dist/public/views/admin/cors-tab.js +240 -0
  148. package/dist/public/views/admin/cortex-tab.js +171 -0
  149. package/dist/public/views/admin/csm-tab.js +261 -0
  150. package/dist/public/views/admin/directory-tab.js +44 -0
  151. package/dist/public/views/admin/economy-tab.js +80 -0
  152. package/dist/public/views/admin/email-tab.js +460 -0
  153. package/dist/public/views/admin/federation-tab.js +412 -0
  154. package/dist/public/views/admin/generator-debug-tab.js +238 -0
  155. package/dist/public/views/admin/genesis-tab.js +70 -0
  156. package/dist/public/views/admin/ghii-tab.js +101 -0
  157. package/dist/public/views/admin/hooks-tab.js +69 -0
  158. package/dist/public/views/admin/knowledge-tab.js +297 -0
  159. package/dist/public/views/admin/maintenance-tab.js +98 -0
  160. package/dist/public/views/admin/matching-tab.js +44 -0
  161. package/dist/public/views/admin/memory-tab.js +222 -0
  162. package/dist/public/views/admin/msm-tab.js +342 -0
  163. package/dist/public/views/admin/overview-tab.js +90 -0
  164. package/dist/public/views/admin/owners-tab.js +55 -0
  165. package/dist/public/views/admin/packages-tab.js +510 -0
  166. package/dist/public/views/admin/portal-tab.js +211 -0
  167. package/dist/public/views/admin/prompts-tab.js +287 -0
  168. package/dist/public/views/admin/push-tab.js +291 -0
  169. package/dist/public/views/admin/realtime-tab.js +68 -0
  170. package/dist/public/views/admin/scheduler-tab.js +156 -0
  171. package/dist/public/views/admin/services-tab.js +981 -0
  172. package/dist/public/views/admin/shared.js +148 -0
  173. package/dist/public/views/admin/stats-tab.js +187 -0
  174. package/dist/public/views/admin/work-tab.js +45 -0
  175. package/dist/public/views/admin.js +400 -0
  176. package/dist/public/views/aimeat-os.js +259 -0
  177. package/dist/public/views/guides.js +402 -0
  178. package/dist/public/views/help.js +79 -0
  179. package/dist/public/views/hobbies.js +697 -0
  180. package/dist/public/views/marketplace.js +647 -0
  181. package/dist/public/views/openclaw.js +223 -0
  182. package/dist/public/views/portal-classic.js +519 -0
  183. package/dist/public/views/portal-dev.js +816 -0
  184. package/dist/public/views/portal.js +1354 -0
  185. package/dist/public/views/portfolio.js +795 -0
  186. package/dist/public/views/profile/access-tab.js +58 -0
  187. package/dist/public/views/profile/agents-tab.js +689 -0
  188. package/dist/public/views/profile/apps-tab.js +197 -0
  189. package/dist/public/views/profile/boards-tab.js +323 -0
  190. package/dist/public/views/profile/calibrator-batch.js +926 -0
  191. package/dist/public/views/profile/calibrator-chart.js +135 -0
  192. package/dist/public/views/profile/calibrator-llm-editor.js +205 -0
  193. package/dist/public/views/profile/calibrator-tab.js +535 -0
  194. package/dist/public/views/profile/chat-sessions-tab.js +184 -0
  195. package/dist/public/views/profile/data-wallet-tab.js +313 -0
  196. package/dist/public/views/profile/email-tab.js +157 -0
  197. package/dist/public/views/profile/extensions-tab.js +711 -0
  198. package/dist/public/views/profile/federation-tab.js +63 -0
  199. package/dist/public/views/profile/foundry-dashboard/DebugPanel.js +193 -0
  200. package/dist/public/views/profile/foundry-dashboard/DiagnosticsPanel.js +69 -0
  201. package/dist/public/views/profile/foundry-dashboard/EditModePanel.js +141 -0
  202. package/dist/public/views/profile/foundry-dashboard/PackageDialog.js +96 -0
  203. package/dist/public/views/profile/foundry-dashboard/RemovePanel.js +53 -0
  204. package/dist/public/views/profile/foundry-dashboard/use-autopilot-state.js +53 -0
  205. package/dist/public/views/profile/foundry-dashboard/use-autopilot.js +1016 -0
  206. package/dist/public/views/profile/foundry-dashboard/use-dashboard-core.js +154 -0
  207. package/dist/public/views/profile/foundry-dashboard/use-edit-mode.js +294 -0
  208. package/dist/public/views/profile/foundry-dashboard/use-lifecycle.js +101 -0
  209. package/dist/public/views/profile/foundry-dashboard/use-packaging.js +97 -0
  210. package/dist/public/views/profile/foundry-dashboard/use-test-execution.js +275 -0
  211. package/dist/public/views/profile/foundry-dashboard.js +395 -0
  212. package/dist/public/views/profile/foundry-detail.js +1178 -0
  213. package/dist/public/views/profile/foundry-settings.js +377 -0
  214. package/dist/public/views/profile/foundry-tab.js +546 -0
  215. package/dist/public/views/profile/generator-dashboard/DebugPanel.js +193 -0
  216. package/dist/public/views/profile/generator-dashboard/DiagnosticsPanel.js +69 -0
  217. package/dist/public/views/profile/generator-dashboard/EditModePanel.js +141 -0
  218. package/dist/public/views/profile/generator-dashboard/PackageDialog.js +96 -0
  219. package/dist/public/views/profile/generator-dashboard/RemovePanel.js +53 -0
  220. package/dist/public/views/profile/generator-dashboard/use-autopilot-state.js +53 -0
  221. package/dist/public/views/profile/generator-dashboard/use-autopilot.js +136 -0
  222. package/dist/public/views/profile/generator-dashboard/use-dashboard-core.js +143 -0
  223. package/dist/public/views/profile/generator-dashboard/use-edit-mode.js +296 -0
  224. package/dist/public/views/profile/generator-dashboard/use-lifecycle.js +101 -0
  225. package/dist/public/views/profile/generator-dashboard/use-packaging.js +97 -0
  226. package/dist/public/views/profile/generator-dashboard/use-test-execution.js +275 -0
  227. package/dist/public/views/profile/generator-dashboard.js +377 -0
  228. package/dist/public/views/profile/generator-detail.js +1007 -0
  229. package/dist/public/views/profile/generator-settings.js +417 -0
  230. package/dist/public/views/profile/generator-tab.js +544 -0
  231. package/dist/public/views/profile/inline-panels.js +277 -0
  232. package/dist/public/views/profile/knowledge-tab.js +735 -0
  233. package/dist/public/views/profile/landing-page.js +539 -0
  234. package/dist/public/views/profile/mcp-tab.js +140 -0
  235. package/dist/public/views/profile/memory-tab.js +599 -0
  236. package/dist/public/views/profile/node-stats-tab.js +132 -0
  237. package/dist/public/views/profile/nodes-tab.js +195 -0
  238. package/dist/public/views/profile/notifications-tab.js +274 -0
  239. package/dist/public/views/profile/organisms-tab.js +402 -0
  240. package/dist/public/views/profile/packages-tab.js +393 -0
  241. package/dist/public/views/profile/portfolio-tab.js +31 -0
  242. package/dist/public/views/profile/security-tab.js +219 -0
  243. package/dist/public/views/profile/services-tab.js +281 -0
  244. package/dist/public/views/profile/shared.js +58 -0
  245. package/dist/public/views/profile/wallet-tab.js +272 -0
  246. package/dist/public/views/profile/work-tab.js +220 -0
  247. package/dist/public/views/profile.js +271 -0
  248. package/dist/public/wizard.html +1320 -0
  249. package/dist/scripts/db-init.d.ts +19 -0
  250. package/dist/scripts/db-init.d.ts.map +1 -0
  251. package/dist/scripts/db-init.js +168 -0
  252. package/dist/scripts/db-init.js.map +1 -0
  253. package/dist/scripts/db-reset.d.ts +15 -0
  254. package/dist/scripts/db-reset.d.ts.map +1 -0
  255. package/dist/scripts/db-reset.js +162 -0
  256. package/dist/scripts/db-reset.js.map +1 -0
  257. package/dist/scripts/indexnow.d.ts +18 -0
  258. package/dist/scripts/indexnow.d.ts.map +1 -0
  259. package/dist/scripts/indexnow.js +104 -0
  260. package/dist/scripts/indexnow.js.map +1 -0
  261. package/dist/scripts/kill-port.d.ts +3 -0
  262. package/dist/scripts/kill-port.d.ts.map +1 -0
  263. package/dist/scripts/kill-port.js +89 -0
  264. package/dist/scripts/kill-port.js.map +1 -0
  265. package/dist/scripts/seed-digital-signage.d.ts +13 -0
  266. package/dist/scripts/seed-digital-signage.d.ts.map +1 -0
  267. package/dist/scripts/seed-digital-signage.js +85 -0
  268. package/dist/scripts/seed-digital-signage.js.map +1 -0
  269. package/dist/src/auth/jwt.d.ts +40 -0
  270. package/dist/src/auth/jwt.d.ts.map +1 -0
  271. package/dist/src/auth/jwt.js +139 -0
  272. package/dist/src/auth/jwt.js.map +1 -0
  273. package/dist/src/auth/keypair.d.ts +8 -0
  274. package/dist/src/auth/keypair.d.ts.map +1 -0
  275. package/dist/src/auth/keypair.js +35 -0
  276. package/dist/src/auth/keypair.js.map +1 -0
  277. package/dist/src/auth/middleware.d.ts +50 -0
  278. package/dist/src/auth/middleware.d.ts.map +1 -0
  279. package/dist/src/auth/middleware.js +241 -0
  280. package/dist/src/auth/middleware.js.map +1 -0
  281. package/dist/src/auth/node-keys.d.ts +7 -0
  282. package/dist/src/auth/node-keys.d.ts.map +1 -0
  283. package/dist/src/auth/node-keys.js +116 -0
  284. package/dist/src/auth/node-keys.js.map +1 -0
  285. package/dist/src/cli/config-export.d.ts +9 -0
  286. package/dist/src/cli/config-export.d.ts.map +1 -0
  287. package/dist/src/cli/config-export.js +90 -0
  288. package/dist/src/cli/config-export.js.map +1 -0
  289. package/dist/src/cli/config-import.d.ts +10 -0
  290. package/dist/src/cli/config-import.d.ts.map +1 -0
  291. package/dist/src/cli/config-import.js +124 -0
  292. package/dist/src/cli/config-import.js.map +1 -0
  293. package/dist/src/cli/federation-join.d.ts +13 -0
  294. package/dist/src/cli/federation-join.d.ts.map +1 -0
  295. package/dist/src/cli/federation-join.js +395 -0
  296. package/dist/src/cli/federation-join.js.map +1 -0
  297. package/dist/src/cli/init-wizard.d.ts +8 -0
  298. package/dist/src/cli/init-wizard.d.ts.map +1 -0
  299. package/dist/src/cli/init-wizard.js +1489 -0
  300. package/dist/src/cli/init-wizard.js.map +1 -0
  301. package/dist/src/cli/scaffold.d.ts +33 -0
  302. package/dist/src/cli/scaffold.d.ts.map +1 -0
  303. package/dist/src/cli/scaffold.js +142 -0
  304. package/dist/src/cli/scaffold.js.map +1 -0
  305. package/dist/src/config.d.ts +272 -0
  306. package/dist/src/config.d.ts.map +1 -0
  307. package/dist/src/config.js +362 -0
  308. package/dist/src/config.js.map +1 -0
  309. package/dist/src/data/example-packages.d.ts +49 -0
  310. package/dist/src/data/example-packages.d.ts.map +1 -0
  311. package/dist/src/data/example-packages.js +814 -0
  312. package/dist/src/data/example-packages.js.map +1 -0
  313. package/dist/src/i18n.d.ts +19 -0
  314. package/dist/src/i18n.d.ts.map +1 -0
  315. package/dist/src/i18n.js +126 -0
  316. package/dist/src/i18n.js.map +1 -0
  317. package/dist/src/index.d.ts +3 -0
  318. package/dist/src/index.d.ts.map +1 -0
  319. package/dist/src/index.js +608 -0
  320. package/dist/src/index.js.map +1 -0
  321. package/dist/src/mcp/boards.d.ts +18 -0
  322. package/dist/src/mcp/boards.d.ts.map +1 -0
  323. package/dist/src/mcp/boards.js +279 -0
  324. package/dist/src/mcp/boards.js.map +1 -0
  325. package/dist/src/mcp/catalogue.d.ts +17 -0
  326. package/dist/src/mcp/catalogue.d.ts.map +1 -0
  327. package/dist/src/mcp/catalogue.js +114 -0
  328. package/dist/src/mcp/catalogue.js.map +1 -0
  329. package/dist/src/mcp/chat-instances.d.ts +18 -0
  330. package/dist/src/mcp/chat-instances.d.ts.map +1 -0
  331. package/dist/src/mcp/chat-instances.js +161 -0
  332. package/dist/src/mcp/chat-instances.js.map +1 -0
  333. package/dist/src/mcp/consent.d.ts +18 -0
  334. package/dist/src/mcp/consent.d.ts.map +1 -0
  335. package/dist/src/mcp/consent.js +158 -0
  336. package/dist/src/mcp/consent.js.map +1 -0
  337. package/dist/src/mcp/core.d.ts +18 -0
  338. package/dist/src/mcp/core.d.ts.map +1 -0
  339. package/dist/src/mcp/core.js +489 -0
  340. package/dist/src/mcp/core.js.map +1 -0
  341. package/dist/src/mcp/extensions.d.ts +18 -0
  342. package/dist/src/mcp/extensions.d.ts.map +1 -0
  343. package/dist/src/mcp/extensions.js +299 -0
  344. package/dist/src/mcp/extensions.js.map +1 -0
  345. package/dist/src/mcp/flags.d.ts +18 -0
  346. package/dist/src/mcp/flags.d.ts.map +1 -0
  347. package/dist/src/mcp/flags.js +59 -0
  348. package/dist/src/mcp/flags.js.map +1 -0
  349. package/dist/src/mcp/index.d.ts +31 -0
  350. package/dist/src/mcp/index.d.ts.map +1 -0
  351. package/dist/src/mcp/index.js +694 -0
  352. package/dist/src/mcp/index.js.map +1 -0
  353. package/dist/src/mcp/knowledge.d.ts +18 -0
  354. package/dist/src/mcp/knowledge.d.ts.map +1 -0
  355. package/dist/src/mcp/knowledge.js +214 -0
  356. package/dist/src/mcp/knowledge.js.map +1 -0
  357. package/dist/src/mcp/memory-extended.d.ts +18 -0
  358. package/dist/src/mcp/memory-extended.d.ts.map +1 -0
  359. package/dist/src/mcp/memory-extended.js +73 -0
  360. package/dist/src/mcp/memory-extended.js.map +1 -0
  361. package/dist/src/mcp/organisms.d.ts +18 -0
  362. package/dist/src/mcp/organisms.d.ts.map +1 -0
  363. package/dist/src/mcp/organisms.js +291 -0
  364. package/dist/src/mcp/organisms.js.map +1 -0
  365. package/dist/src/mcp/prompts.d.ts +17 -0
  366. package/dist/src/mcp/prompts.d.ts.map +1 -0
  367. package/dist/src/mcp/prompts.js +65 -0
  368. package/dist/src/mcp/prompts.js.map +1 -0
  369. package/dist/src/mcp/wallet-extended.d.ts +17 -0
  370. package/dist/src/mcp/wallet-extended.d.ts.map +1 -0
  371. package/dist/src/mcp/wallet-extended.js +42 -0
  372. package/dist/src/mcp/wallet-extended.js.map +1 -0
  373. package/dist/src/middleware/__tests__/cookie-consent.test.d.ts +2 -0
  374. package/dist/src/middleware/__tests__/cookie-consent.test.d.ts.map +1 -0
  375. package/dist/src/middleware/__tests__/cookie-consent.test.js +432 -0
  376. package/dist/src/middleware/__tests__/cookie-consent.test.js.map +1 -0
  377. package/dist/src/middleware/cookie-consent.d.ts +19 -0
  378. package/dist/src/middleware/cookie-consent.d.ts.map +1 -0
  379. package/dist/src/middleware/cookie-consent.js +127 -0
  380. package/dist/src/middleware/cookie-consent.js.map +1 -0
  381. package/dist/src/middleware/cors.d.ts +12 -0
  382. package/dist/src/middleware/cors.d.ts.map +1 -0
  383. package/dist/src/middleware/cors.js +112 -0
  384. package/dist/src/middleware/cors.js.map +1 -0
  385. package/dist/src/middleware/envelope.d.ts +33 -0
  386. package/dist/src/middleware/envelope.d.ts.map +1 -0
  387. package/dist/src/middleware/envelope.js +32 -0
  388. package/dist/src/middleware/envelope.js.map +1 -0
  389. package/dist/src/middleware/idempotency.d.ts +3 -0
  390. package/dist/src/middleware/idempotency.d.ts.map +1 -0
  391. package/dist/src/middleware/idempotency.js +64 -0
  392. package/dist/src/middleware/idempotency.js.map +1 -0
  393. package/dist/src/middleware/metrics.d.ts +8 -0
  394. package/dist/src/middleware/metrics.d.ts.map +1 -0
  395. package/dist/src/middleware/metrics.js +25 -0
  396. package/dist/src/middleware/metrics.js.map +1 -0
  397. package/dist/src/middleware/rate-limit.d.ts +4 -0
  398. package/dist/src/middleware/rate-limit.d.ts.map +1 -0
  399. package/dist/src/middleware/rate-limit.js +73 -0
  400. package/dist/src/middleware/rate-limit.js.map +1 -0
  401. package/dist/src/middleware/request-id.d.ts +18 -0
  402. package/dist/src/middleware/request-id.d.ts.map +1 -0
  403. package/dist/src/middleware/request-id.js +23 -0
  404. package/dist/src/middleware/request-id.js.map +1 -0
  405. package/dist/src/middleware/stats.d.ts +4 -0
  406. package/dist/src/middleware/stats.d.ts.map +1 -0
  407. package/dist/src/middleware/stats.js +11 -0
  408. package/dist/src/middleware/stats.js.map +1 -0
  409. package/dist/src/middleware/workspace-access.d.ts +16 -0
  410. package/dist/src/middleware/workspace-access.d.ts.map +1 -0
  411. package/dist/src/middleware/workspace-access.js +115 -0
  412. package/dist/src/middleware/workspace-access.js.map +1 -0
  413. package/dist/src/models/schemas.d.ts +311 -0
  414. package/dist/src/models/schemas.d.ts.map +1 -0
  415. package/dist/src/models/schemas.js +281 -0
  416. package/dist/src/models/schemas.js.map +1 -0
  417. package/dist/src/routes/actions.d.ts +5 -0
  418. package/dist/src/routes/actions.d.ts.map +1 -0
  419. package/dist/src/routes/actions.js +199 -0
  420. package/dist/src/routes/actions.js.map +1 -0
  421. package/dist/src/routes/admin-agents.d.ts +5 -0
  422. package/dist/src/routes/admin-agents.d.ts.map +1 -0
  423. package/dist/src/routes/admin-agents.js +60 -0
  424. package/dist/src/routes/admin-agents.js.map +1 -0
  425. package/dist/src/routes/admin-config.d.ts +7 -0
  426. package/dist/src/routes/admin-config.d.ts.map +1 -0
  427. package/dist/src/routes/admin-config.js +209 -0
  428. package/dist/src/routes/admin-config.js.map +1 -0
  429. package/dist/src/routes/admin-economy.d.ts +5 -0
  430. package/dist/src/routes/admin-economy.d.ts.map +1 -0
  431. package/dist/src/routes/admin-economy.js +57 -0
  432. package/dist/src/routes/admin-economy.js.map +1 -0
  433. package/dist/src/routes/admin-extensions.d.ts +6 -0
  434. package/dist/src/routes/admin-extensions.d.ts.map +1 -0
  435. package/dist/src/routes/admin-extensions.js +619 -0
  436. package/dist/src/routes/admin-extensions.js.map +1 -0
  437. package/dist/src/routes/admin-features.d.ts +16 -0
  438. package/dist/src/routes/admin-features.d.ts.map +1 -0
  439. package/dist/src/routes/admin-features.js +672 -0
  440. package/dist/src/routes/admin-features.js.map +1 -0
  441. package/dist/src/routes/admin-maintenance.d.ts +8 -0
  442. package/dist/src/routes/admin-maintenance.d.ts.map +1 -0
  443. package/dist/src/routes/admin-maintenance.js +86 -0
  444. package/dist/src/routes/admin-maintenance.js.map +1 -0
  445. package/dist/src/routes/admin-memory.d.ts +12 -0
  446. package/dist/src/routes/admin-memory.d.ts.map +1 -0
  447. package/dist/src/routes/admin-memory.js +64 -0
  448. package/dist/src/routes/admin-memory.js.map +1 -0
  449. package/dist/src/routes/admin-monitoring.d.ts +5 -0
  450. package/dist/src/routes/admin-monitoring.d.ts.map +1 -0
  451. package/dist/src/routes/admin-monitoring.js +343 -0
  452. package/dist/src/routes/admin-monitoring.js.map +1 -0
  453. package/dist/src/routes/admin-prompts.d.ts +5 -0
  454. package/dist/src/routes/admin-prompts.d.ts.map +1 -0
  455. package/dist/src/routes/admin-prompts.js +198 -0
  456. package/dist/src/routes/admin-prompts.js.map +1 -0
  457. package/dist/src/routes/admin-scheduler.d.ts +6 -0
  458. package/dist/src/routes/admin-scheduler.d.ts.map +1 -0
  459. package/dist/src/routes/admin-scheduler.js +153 -0
  460. package/dist/src/routes/admin-scheduler.js.map +1 -0
  461. package/dist/src/routes/admin.d.ts +10 -0
  462. package/dist/src/routes/admin.d.ts.map +1 -0
  463. package/dist/src/routes/admin.js +847 -0
  464. package/dist/src/routes/admin.js.map +1 -0
  465. package/dist/src/routes/agents.d.ts +5 -0
  466. package/dist/src/routes/agents.d.ts.map +1 -0
  467. package/dist/src/routes/agents.js +946 -0
  468. package/dist/src/routes/agents.js.map +1 -0
  469. package/dist/src/routes/app-store.d.ts +25 -0
  470. package/dist/src/routes/app-store.d.ts.map +1 -0
  471. package/dist/src/routes/app-store.js +269 -0
  472. package/dist/src/routes/app-store.js.map +1 -0
  473. package/dist/src/routes/appeals.d.ts +5 -0
  474. package/dist/src/routes/appeals.d.ts.map +1 -0
  475. package/dist/src/routes/appeals.js +241 -0
  476. package/dist/src/routes/appeals.js.map +1 -0
  477. package/dist/src/routes/apps.d.ts +14 -0
  478. package/dist/src/routes/apps.d.ts.map +1 -0
  479. package/dist/src/routes/apps.js +395 -0
  480. package/dist/src/routes/apps.js.map +1 -0
  481. package/dist/src/routes/auth.d.ts +13 -0
  482. package/dist/src/routes/auth.d.ts.map +1 -0
  483. package/dist/src/routes/auth.js +517 -0
  484. package/dist/src/routes/auth.js.map +1 -0
  485. package/dist/src/routes/boards.d.ts +5 -0
  486. package/dist/src/routes/boards.d.ts.map +1 -0
  487. package/dist/src/routes/boards.js +614 -0
  488. package/dist/src/routes/boards.js.map +1 -0
  489. package/dist/src/routes/bootstrap.d.ts +6 -0
  490. package/dist/src/routes/bootstrap.d.ts.map +1 -0
  491. package/dist/src/routes/bootstrap.js +360 -0
  492. package/dist/src/routes/bootstrap.js.map +1 -0
  493. package/dist/src/routes/calibrator.d.ts +28 -0
  494. package/dist/src/routes/calibrator.d.ts.map +1 -0
  495. package/dist/src/routes/calibrator.js +556 -0
  496. package/dist/src/routes/calibrator.js.map +1 -0
  497. package/dist/src/routes/catalogue.d.ts +7 -0
  498. package/dist/src/routes/catalogue.d.ts.map +1 -0
  499. package/dist/src/routes/catalogue.js +377 -0
  500. package/dist/src/routes/catalogue.js.map +1 -0
  501. package/dist/src/routes/chat-instances.d.ts +5 -0
  502. package/dist/src/routes/chat-instances.d.ts.map +1 -0
  503. package/dist/src/routes/chat-instances.js +131 -0
  504. package/dist/src/routes/chat-instances.js.map +1 -0
  505. package/dist/src/routes/consent.d.ts +6 -0
  506. package/dist/src/routes/consent.d.ts.map +1 -0
  507. package/dist/src/routes/consent.js +188 -0
  508. package/dist/src/routes/consent.js.map +1 -0
  509. package/dist/src/routes/cortex.d.ts +5 -0
  510. package/dist/src/routes/cortex.d.ts.map +1 -0
  511. package/dist/src/routes/cortex.js +617 -0
  512. package/dist/src/routes/cortex.js.map +1 -0
  513. package/dist/src/routes/csm.d.ts +5 -0
  514. package/dist/src/routes/csm.d.ts.map +1 -0
  515. package/dist/src/routes/csm.js +258 -0
  516. package/dist/src/routes/csm.js.map +1 -0
  517. package/dist/src/routes/disputes.d.ts +5 -0
  518. package/dist/src/routes/disputes.d.ts.map +1 -0
  519. package/dist/src/routes/disputes.js +528 -0
  520. package/dist/src/routes/disputes.js.map +1 -0
  521. package/dist/src/routes/extensions.d.ts +6 -0
  522. package/dist/src/routes/extensions.d.ts.map +1 -0
  523. package/dist/src/routes/extensions.js +1149 -0
  524. package/dist/src/routes/extensions.js.map +1 -0
  525. package/dist/src/routes/federation-genesis.d.ts +11 -0
  526. package/dist/src/routes/federation-genesis.d.ts.map +1 -0
  527. package/dist/src/routes/federation-genesis.js +638 -0
  528. package/dist/src/routes/federation-genesis.js.map +1 -0
  529. package/dist/src/routes/federation-peer.d.ts +10 -0
  530. package/dist/src/routes/federation-peer.d.ts.map +1 -0
  531. package/dist/src/routes/federation-peer.js +613 -0
  532. package/dist/src/routes/federation-peer.js.map +1 -0
  533. package/dist/src/routes/federation-settlements.d.ts +10 -0
  534. package/dist/src/routes/federation-settlements.d.ts.map +1 -0
  535. package/dist/src/routes/federation-settlements.js +231 -0
  536. package/dist/src/routes/federation-settlements.js.map +1 -0
  537. package/dist/src/routes/federation-sync.d.ts +15 -0
  538. package/dist/src/routes/federation-sync.d.ts.map +1 -0
  539. package/dist/src/routes/federation-sync.js +629 -0
  540. package/dist/src/routes/federation-sync.js.map +1 -0
  541. package/dist/src/routes/federation.d.ts +15 -0
  542. package/dist/src/routes/federation.d.ts.map +1 -0
  543. package/dist/src/routes/federation.js +23 -0
  544. package/dist/src/routes/federation.js.map +1 -0
  545. package/dist/src/routes/flags.d.ts +5 -0
  546. package/dist/src/routes/flags.d.ts.map +1 -0
  547. package/dist/src/routes/flags.js +194 -0
  548. package/dist/src/routes/flags.js.map +1 -0
  549. package/dist/src/routes/foundry.d.ts +5 -0
  550. package/dist/src/routes/foundry.d.ts.map +1 -0
  551. package/dist/src/routes/foundry.js +955 -0
  552. package/dist/src/routes/foundry.js.map +1 -0
  553. package/dist/src/routes/generator-autopilot.d.ts +12 -0
  554. package/dist/src/routes/generator-autopilot.d.ts.map +1 -0
  555. package/dist/src/routes/generator-autopilot.js +71 -0
  556. package/dist/src/routes/generator-autopilot.js.map +1 -0
  557. package/dist/src/routes/generator.d.ts +5 -0
  558. package/dist/src/routes/generator.d.ts.map +1 -0
  559. package/dist/src/routes/generator.js +1313 -0
  560. package/dist/src/routes/generator.js.map +1 -0
  561. package/dist/src/routes/ghii.d.ts +16 -0
  562. package/dist/src/routes/ghii.d.ts.map +1 -0
  563. package/dist/src/routes/ghii.js +1115 -0
  564. package/dist/src/routes/ghii.js.map +1 -0
  565. package/dist/src/routes/instances.d.ts +31 -0
  566. package/dist/src/routes/instances.d.ts.map +1 -0
  567. package/dist/src/routes/instances.js +722 -0
  568. package/dist/src/routes/instances.js.map +1 -0
  569. package/dist/src/routes/knowledge.d.ts +33 -0
  570. package/dist/src/routes/knowledge.d.ts.map +1 -0
  571. package/dist/src/routes/knowledge.js +1108 -0
  572. package/dist/src/routes/knowledge.js.map +1 -0
  573. package/dist/src/routes/lib-data.d.ts +7 -0
  574. package/dist/src/routes/lib-data.d.ts.map +1 -0
  575. package/dist/src/routes/lib-data.js +189 -0
  576. package/dist/src/routes/lib-data.js.map +1 -0
  577. package/dist/src/routes/lib-social.d.ts +7 -0
  578. package/dist/src/routes/lib-social.d.ts.map +1 -0
  579. package/dist/src/routes/lib-social.js +159 -0
  580. package/dist/src/routes/lib-social.js.map +1 -0
  581. package/dist/src/routes/lib-storage.d.ts +7 -0
  582. package/dist/src/routes/lib-storage.d.ts.map +1 -0
  583. package/dist/src/routes/lib-storage.js +202 -0
  584. package/dist/src/routes/lib-storage.js.map +1 -0
  585. package/dist/src/routes/lib-tunnel.d.ts +8 -0
  586. package/dist/src/routes/lib-tunnel.d.ts.map +1 -0
  587. package/dist/src/routes/lib-tunnel.js +442 -0
  588. package/dist/src/routes/lib-tunnel.js.map +1 -0
  589. package/dist/src/routes/lib-wallet.d.ts +7 -0
  590. package/dist/src/routes/lib-wallet.d.ts.map +1 -0
  591. package/dist/src/routes/lib-wallet.js +129 -0
  592. package/dist/src/routes/lib-wallet.js.map +1 -0
  593. package/dist/src/routes/lib-work.d.ts +7 -0
  594. package/dist/src/routes/lib-work.d.ts.map +1 -0
  595. package/dist/src/routes/lib-work.js +210 -0
  596. package/dist/src/routes/lib-work.js.map +1 -0
  597. package/dist/src/routes/libs.d.ts +10 -0
  598. package/dist/src/routes/libs.d.ts.map +1 -0
  599. package/dist/src/routes/libs.js +989 -0
  600. package/dist/src/routes/libs.js.map +1 -0
  601. package/dist/src/routes/matches.d.ts +10 -0
  602. package/dist/src/routes/matches.d.ts.map +1 -0
  603. package/dist/src/routes/matches.js +218 -0
  604. package/dist/src/routes/matches.js.map +1 -0
  605. package/dist/src/routes/memory.d.ts +6 -0
  606. package/dist/src/routes/memory.d.ts.map +1 -0
  607. package/dist/src/routes/memory.js +796 -0
  608. package/dist/src/routes/memory.js.map +1 -0
  609. package/dist/src/routes/micro-memory.d.ts +5 -0
  610. package/dist/src/routes/micro-memory.d.ts.map +1 -0
  611. package/dist/src/routes/micro-memory.js +488 -0
  612. package/dist/src/routes/micro-memory.js.map +1 -0
  613. package/dist/src/routes/msm.d.ts +5 -0
  614. package/dist/src/routes/msm.d.ts.map +1 -0
  615. package/dist/src/routes/msm.js +242 -0
  616. package/dist/src/routes/msm.js.map +1 -0
  617. package/dist/src/routes/openrouter.d.ts +23 -0
  618. package/dist/src/routes/openrouter.d.ts.map +1 -0
  619. package/dist/src/routes/openrouter.js +337 -0
  620. package/dist/src/routes/openrouter.js.map +1 -0
  621. package/dist/src/routes/organisms.d.ts +5 -0
  622. package/dist/src/routes/organisms.d.ts.map +1 -0
  623. package/dist/src/routes/organisms.js +415 -0
  624. package/dist/src/routes/organisms.js.map +1 -0
  625. package/dist/src/routes/owners.d.ts +5 -0
  626. package/dist/src/routes/owners.d.ts.map +1 -0
  627. package/dist/src/routes/owners.js +637 -0
  628. package/dist/src/routes/owners.js.map +1 -0
  629. package/dist/src/routes/packages.d.ts +35 -0
  630. package/dist/src/routes/packages.d.ts.map +1 -0
  631. package/dist/src/routes/packages.js +600 -0
  632. package/dist/src/routes/packages.js.map +1 -0
  633. package/dist/src/routes/permissions.d.ts +5 -0
  634. package/dist/src/routes/permissions.d.ts.map +1 -0
  635. package/dist/src/routes/permissions.js +85 -0
  636. package/dist/src/routes/permissions.js.map +1 -0
  637. package/dist/src/routes/personal.d.ts +7 -0
  638. package/dist/src/routes/personal.d.ts.map +1 -0
  639. package/dist/src/routes/personal.js +594 -0
  640. package/dist/src/routes/personal.js.map +1 -0
  641. package/dist/src/routes/portal-api.d.ts +9 -0
  642. package/dist/src/routes/portal-api.d.ts.map +1 -0
  643. package/dist/src/routes/portal-api.js +49 -0
  644. package/dist/src/routes/portal-api.js.map +1 -0
  645. package/dist/src/routes/portal-human.d.ts +12 -0
  646. package/dist/src/routes/portal-human.d.ts.map +1 -0
  647. package/dist/src/routes/portal-human.js +2652 -0
  648. package/dist/src/routes/portal-human.js.map +1 -0
  649. package/dist/src/routes/portal.d.ts +24 -0
  650. package/dist/src/routes/portal.d.ts.map +1 -0
  651. package/dist/src/routes/portal.js +372 -0
  652. package/dist/src/routes/portal.js.map +1 -0
  653. package/dist/src/routes/portfolio.d.ts +5 -0
  654. package/dist/src/routes/portfolio.d.ts.map +1 -0
  655. package/dist/src/routes/portfolio.js +231 -0
  656. package/dist/src/routes/portfolio.js.map +1 -0
  657. package/dist/src/routes/profile.d.ts +5 -0
  658. package/dist/src/routes/profile.d.ts.map +1 -0
  659. package/dist/src/routes/profile.js +2042 -0
  660. package/dist/src/routes/profile.js.map +1 -0
  661. package/dist/src/routes/prompts.d.ts +5 -0
  662. package/dist/src/routes/prompts.d.ts.map +1 -0
  663. package/dist/src/routes/prompts.js +318 -0
  664. package/dist/src/routes/prompts.js.map +1 -0
  665. package/dist/src/routes/push.d.ts +6 -0
  666. package/dist/src/routes/push.d.ts.map +1 -0
  667. package/dist/src/routes/push.js +75 -0
  668. package/dist/src/routes/push.js.map +1 -0
  669. package/dist/src/routes/realtime.d.ts +7 -0
  670. package/dist/src/routes/realtime.d.ts.map +1 -0
  671. package/dist/src/routes/realtime.js +289 -0
  672. package/dist/src/routes/realtime.js.map +1 -0
  673. package/dist/src/routes/schemas.d.ts +5 -0
  674. package/dist/src/routes/schemas.d.ts.map +1 -0
  675. package/dist/src/routes/schemas.js +130 -0
  676. package/dist/src/routes/schemas.js.map +1 -0
  677. package/dist/src/routes/setup.d.ts +7 -0
  678. package/dist/src/routes/setup.d.ts.map +1 -0
  679. package/dist/src/routes/setup.js +243 -0
  680. package/dist/src/routes/setup.js.map +1 -0
  681. package/dist/src/routes/site.d.ts +6 -0
  682. package/dist/src/routes/site.d.ts.map +1 -0
  683. package/dist/src/routes/site.js +201 -0
  684. package/dist/src/routes/site.js.map +1 -0
  685. package/dist/src/routes/spec.d.ts +3 -0
  686. package/dist/src/routes/spec.d.ts.map +1 -0
  687. package/dist/src/routes/spec.js +47 -0
  688. package/dist/src/routes/spec.js.map +1 -0
  689. package/dist/src/routes/sse.d.ts +5 -0
  690. package/dist/src/routes/sse.d.ts.map +1 -0
  691. package/dist/src/routes/sse.js +66 -0
  692. package/dist/src/routes/sse.js.map +1 -0
  693. package/dist/src/routes/stats.d.ts +7 -0
  694. package/dist/src/routes/stats.d.ts.map +1 -0
  695. package/dist/src/routes/stats.js +98 -0
  696. package/dist/src/routes/stats.js.map +1 -0
  697. package/dist/src/routes/storage-files.d.ts +5 -0
  698. package/dist/src/routes/storage-files.d.ts.map +1 -0
  699. package/dist/src/routes/storage-files.js +460 -0
  700. package/dist/src/routes/storage-files.js.map +1 -0
  701. package/dist/src/routes/templates.d.ts +30 -0
  702. package/dist/src/routes/templates.d.ts.map +1 -0
  703. package/dist/src/routes/templates.js +511 -0
  704. package/dist/src/routes/templates.js.map +1 -0
  705. package/dist/src/routes/totp.d.ts +5 -0
  706. package/dist/src/routes/totp.d.ts.map +1 -0
  707. package/dist/src/routes/totp.js +166 -0
  708. package/dist/src/routes/totp.js.map +1 -0
  709. package/dist/src/routes/validate.d.ts +4 -0
  710. package/dist/src/routes/validate.d.ts.map +1 -0
  711. package/dist/src/routes/validate.js +71 -0
  712. package/dist/src/routes/validate.js.map +1 -0
  713. package/dist/src/routes/verification.d.ts +8 -0
  714. package/dist/src/routes/verification.d.ts.map +1 -0
  715. package/dist/src/routes/verification.js +259 -0
  716. package/dist/src/routes/verification.js.map +1 -0
  717. package/dist/src/routes/wallet.d.ts +18 -0
  718. package/dist/src/routes/wallet.d.ts.map +1 -0
  719. package/dist/src/routes/wallet.js +164 -0
  720. package/dist/src/routes/wallet.js.map +1 -0
  721. package/dist/src/routes/wellknown.d.ts +5 -0
  722. package/dist/src/routes/wellknown.d.ts.map +1 -0
  723. package/dist/src/routes/wellknown.js +57 -0
  724. package/dist/src/routes/wellknown.js.map +1 -0
  725. package/dist/src/routes/work.d.ts +21 -0
  726. package/dist/src/routes/work.d.ts.map +1 -0
  727. package/dist/src/routes/work.js +654 -0
  728. package/dist/src/routes/work.js.map +1 -0
  729. package/dist/src/schemas/knowledge-package.d.ts +203 -0
  730. package/dist/src/schemas/knowledge-package.d.ts.map +1 -0
  731. package/dist/src/schemas/knowledge-package.js +233 -0
  732. package/dist/src/schemas/knowledge-package.js.map +1 -0
  733. package/dist/src/server-bootstrap/config-init.d.ts +16 -0
  734. package/dist/src/server-bootstrap/config-init.d.ts.map +1 -0
  735. package/dist/src/server-bootstrap/config-init.js +113 -0
  736. package/dist/src/server-bootstrap/config-init.js.map +1 -0
  737. package/dist/src/server-bootstrap/middleware-guards.d.ts +15 -0
  738. package/dist/src/server-bootstrap/middleware-guards.d.ts.map +1 -0
  739. package/dist/src/server-bootstrap/middleware-guards.js +244 -0
  740. package/dist/src/server-bootstrap/middleware-guards.js.map +1 -0
  741. package/dist/src/server-bootstrap/routes-loader.d.ts +35 -0
  742. package/dist/src/server-bootstrap/routes-loader.d.ts.map +1 -0
  743. package/dist/src/server-bootstrap/routes-loader.js +290 -0
  744. package/dist/src/server-bootstrap/routes-loader.js.map +1 -0
  745. package/dist/src/server-bootstrap/service-init.d.ts +24 -0
  746. package/dist/src/server-bootstrap/service-init.d.ts.map +1 -0
  747. package/dist/src/server-bootstrap/service-init.js +195 -0
  748. package/dist/src/server-bootstrap/service-init.js.map +1 -0
  749. package/dist/src/server-bootstrap/static-files.d.ts +7 -0
  750. package/dist/src/server-bootstrap/static-files.d.ts.map +1 -0
  751. package/dist/src/server-bootstrap/static-files.js +119 -0
  752. package/dist/src/server-bootstrap/static-files.js.map +1 -0
  753. package/dist/src/server.d.ts +22 -0
  754. package/dist/src/server.d.ts.map +1 -0
  755. package/dist/src/server.js +133 -0
  756. package/dist/src/server.js.map +1 -0
  757. package/dist/src/services/cache-cleanup.d.ts +31 -0
  758. package/dist/src/services/cache-cleanup.d.ts.map +1 -0
  759. package/dist/src/services/cache-cleanup.js +123 -0
  760. package/dist/src/services/cache-cleanup.js.map +1 -0
  761. package/dist/src/services/catalogue-sync.d.ts +45 -0
  762. package/dist/src/services/catalogue-sync.d.ts.map +1 -0
  763. package/dist/src/services/catalogue-sync.js +196 -0
  764. package/dist/src/services/catalogue-sync.js.map +1 -0
  765. package/dist/src/services/component-registrar.d.ts +46 -0
  766. package/dist/src/services/component-registrar.d.ts.map +1 -0
  767. package/dist/src/services/component-registrar.js +389 -0
  768. package/dist/src/services/component-registrar.js.map +1 -0
  769. package/dist/src/services/config-loader.d.ts +42 -0
  770. package/dist/src/services/config-loader.d.ts.map +1 -0
  771. package/dist/src/services/config-loader.js +187 -0
  772. package/dist/src/services/config-loader.js.map +1 -0
  773. package/dist/src/services/config-provenance.d.ts +32 -0
  774. package/dist/src/services/config-provenance.d.ts.map +1 -0
  775. package/dist/src/services/config-provenance.js +59 -0
  776. package/dist/src/services/config-provenance.js.map +1 -0
  777. package/dist/src/services/config-schema.d.ts +52 -0
  778. package/dist/src/services/config-schema.d.ts.map +1 -0
  779. package/dist/src/services/config-schema.js +288 -0
  780. package/dist/src/services/config-schema.js.map +1 -0
  781. package/dist/src/services/consent.d.ts +43 -0
  782. package/dist/src/services/consent.d.ts.map +1 -0
  783. package/dist/src/services/consent.js +137 -0
  784. package/dist/src/services/consent.js.map +1 -0
  785. package/dist/src/services/consul-config.d.ts +30 -0
  786. package/dist/src/services/consul-config.d.ts.map +1 -0
  787. package/dist/src/services/consul-config.js +110 -0
  788. package/dist/src/services/consul-config.js.map +1 -0
  789. package/dist/src/services/core-jobs.d.ts +8 -0
  790. package/dist/src/services/core-jobs.d.ts.map +1 -0
  791. package/dist/src/services/core-jobs.js +161 -0
  792. package/dist/src/services/core-jobs.js.map +1 -0
  793. package/dist/src/services/cortex-manifest.d.ts +17 -0
  794. package/dist/src/services/cortex-manifest.d.ts.map +1 -0
  795. package/dist/src/services/cortex-manifest.js +343 -0
  796. package/dist/src/services/cortex-manifest.js.map +1 -0
  797. package/dist/src/services/cortex-seeder.d.ts +18 -0
  798. package/dist/src/services/cortex-seeder.d.ts.map +1 -0
  799. package/dist/src/services/cortex-seeder.js +86 -0
  800. package/dist/src/services/cortex-seeder.js.map +1 -0
  801. package/dist/src/services/cross-node-matching.d.ts +23 -0
  802. package/dist/src/services/cross-node-matching.d.ts.map +1 -0
  803. package/dist/src/services/cross-node-matching.js +62 -0
  804. package/dist/src/services/cross-node-matching.js.map +1 -0
  805. package/dist/src/services/csm-parser.d.ts +57 -0
  806. package/dist/src/services/csm-parser.d.ts.map +1 -0
  807. package/dist/src/services/csm-parser.js +161 -0
  808. package/dist/src/services/csm-parser.js.map +1 -0
  809. package/dist/src/services/csm-seed.d.ts +15 -0
  810. package/dist/src/services/csm-seed.d.ts.map +1 -0
  811. package/dist/src/services/csm-seed.js +89 -0
  812. package/dist/src/services/csm-seed.js.map +1 -0
  813. package/dist/src/services/directory.d.ts +86 -0
  814. package/dist/src/services/directory.d.ts.map +1 -0
  815. package/dist/src/services/directory.js +307 -0
  816. package/dist/src/services/directory.js.map +1 -0
  817. package/dist/src/services/email-templates.d.ts +29 -0
  818. package/dist/src/services/email-templates.d.ts.map +1 -0
  819. package/dist/src/services/email-templates.js +204 -0
  820. package/dist/src/services/email-templates.js.map +1 -0
  821. package/dist/src/services/email.d.ts +18 -0
  822. package/dist/src/services/email.d.ts.map +1 -0
  823. package/dist/src/services/email.js +102 -0
  824. package/dist/src/services/email.js.map +1 -0
  825. package/dist/src/services/encryption.d.ts +31 -0
  826. package/dist/src/services/encryption.d.ts.map +1 -0
  827. package/dist/src/services/encryption.js +51 -0
  828. package/dist/src/services/encryption.js.map +1 -0
  829. package/dist/src/services/eudiw.d.ts +15 -0
  830. package/dist/src/services/eudiw.d.ts.map +1 -0
  831. package/dist/src/services/eudiw.js +89 -0
  832. package/dist/src/services/eudiw.js.map +1 -0
  833. package/dist/src/services/event-bus.d.ts +8 -0
  834. package/dist/src/services/event-bus.d.ts.map +1 -0
  835. package/dist/src/services/event-bus.js +13 -0
  836. package/dist/src/services/event-bus.js.map +1 -0
  837. package/dist/src/services/extension-runtime.d.ts +72 -0
  838. package/dist/src/services/extension-runtime.d.ts.map +1 -0
  839. package/dist/src/services/extension-runtime.js +282 -0
  840. package/dist/src/services/extension-runtime.js.map +1 -0
  841. package/dist/src/services/federation-helpers.d.ts +37 -0
  842. package/dist/src/services/federation-helpers.d.ts.map +1 -0
  843. package/dist/src/services/federation-helpers.js +100 -0
  844. package/dist/src/services/federation-helpers.js.map +1 -0
  845. package/dist/src/services/federation.d.ts +32 -0
  846. package/dist/src/services/federation.d.ts.map +1 -0
  847. package/dist/src/services/federation.js +201 -0
  848. package/dist/src/services/federation.js.map +1 -0
  849. package/dist/src/services/foundry-debug.d.ts +77 -0
  850. package/dist/src/services/foundry-debug.d.ts.map +1 -0
  851. package/dist/src/services/foundry-debug.js +214 -0
  852. package/dist/src/services/foundry-debug.js.map +1 -0
  853. package/dist/src/services/foundry-registration.d.ts +42 -0
  854. package/dist/src/services/foundry-registration.d.ts.map +1 -0
  855. package/dist/src/services/foundry-registration.js +330 -0
  856. package/dist/src/services/foundry-registration.js.map +1 -0
  857. package/dist/src/services/foundry-testing.d.ts +90 -0
  858. package/dist/src/services/foundry-testing.d.ts.map +1 -0
  859. package/dist/src/services/foundry-testing.js +253 -0
  860. package/dist/src/services/foundry-testing.js.map +1 -0
  861. package/dist/src/services/foundry-validate.d.ts +115 -0
  862. package/dist/src/services/foundry-validate.d.ts.map +1 -0
  863. package/dist/src/services/foundry-validate.js +781 -0
  864. package/dist/src/services/foundry-validate.js.map +1 -0
  865. package/dist/src/services/generator-autopilot.d.ts +37 -0
  866. package/dist/src/services/generator-autopilot.d.ts.map +1 -0
  867. package/dist/src/services/generator-autopilot.js +1076 -0
  868. package/dist/src/services/generator-autopilot.js.map +1 -0
  869. package/dist/src/services/generator-debug.d.ts +79 -0
  870. package/dist/src/services/generator-debug.d.ts.map +1 -0
  871. package/dist/src/services/generator-debug.js +218 -0
  872. package/dist/src/services/generator-debug.js.map +1 -0
  873. package/dist/src/services/generator-prompt-seeds.d.ts +13 -0
  874. package/dist/src/services/generator-prompt-seeds.d.ts.map +1 -0
  875. package/dist/src/services/generator-prompt-seeds.js +2694 -0
  876. package/dist/src/services/generator-prompt-seeds.js.map +1 -0
  877. package/dist/src/services/generator-prompts/bundle.d.ts +17 -0
  878. package/dist/src/services/generator-prompts/bundle.d.ts.map +1 -0
  879. package/dist/src/services/generator-prompts/bundle.js +95 -0
  880. package/dist/src/services/generator-prompts/bundle.js.map +1 -0
  881. package/dist/src/services/generator-prompts/index.d.ts +48 -0
  882. package/dist/src/services/generator-prompts/index.d.ts.map +1 -0
  883. package/dist/src/services/generator-prompts/index.js +97 -0
  884. package/dist/src/services/generator-prompts/index.js.map +1 -0
  885. package/dist/src/services/generator-prompts/resolvers.d.ts +21 -0
  886. package/dist/src/services/generator-prompts/resolvers.d.ts.map +1 -0
  887. package/dist/src/services/generator-prompts/resolvers.js +1553 -0
  888. package/dist/src/services/generator-prompts/resolvers.js.map +1 -0
  889. package/dist/src/services/generator-prompts/spec-validate.d.ts +29 -0
  890. package/dist/src/services/generator-prompts/spec-validate.d.ts.map +1 -0
  891. package/dist/src/services/generator-prompts/spec-validate.js +190 -0
  892. package/dist/src/services/generator-prompts/spec-validate.js.map +1 -0
  893. package/dist/src/services/generator-prompts/strip.d.ts +13 -0
  894. package/dist/src/services/generator-prompts/strip.d.ts.map +1 -0
  895. package/dist/src/services/generator-prompts/strip.js +60 -0
  896. package/dist/src/services/generator-prompts/strip.js.map +1 -0
  897. package/dist/src/services/generator-prompts/types.d.ts +229 -0
  898. package/dist/src/services/generator-prompts/types.d.ts.map +1 -0
  899. package/dist/src/services/generator-prompts/types.js +8 -0
  900. package/dist/src/services/generator-prompts/types.js.map +1 -0
  901. package/dist/src/services/generator-prompts/validate.d.ts +48 -0
  902. package/dist/src/services/generator-prompts/validate.d.ts.map +1 -0
  903. package/dist/src/services/generator-prompts/validate.js +927 -0
  904. package/dist/src/services/generator-prompts/validate.js.map +1 -0
  905. package/dist/src/services/generator-registration.d.ts +43 -0
  906. package/dist/src/services/generator-registration.d.ts.map +1 -0
  907. package/dist/src/services/generator-registration.js +343 -0
  908. package/dist/src/services/generator-registration.js.map +1 -0
  909. package/dist/src/services/generator-testing.d.ts +93 -0
  910. package/dist/src/services/generator-testing.d.ts.map +1 -0
  911. package/dist/src/services/generator-testing.js +300 -0
  912. package/dist/src/services/generator-testing.js.map +1 -0
  913. package/dist/src/services/generator-validate.d.ts +117 -0
  914. package/dist/src/services/generator-validate.d.ts.map +1 -0
  915. package/dist/src/services/generator-validate.js +790 -0
  916. package/dist/src/services/generator-validate.js.map +1 -0
  917. package/dist/src/services/genesis-peering.d.ts +12 -0
  918. package/dist/src/services/genesis-peering.d.ts.map +1 -0
  919. package/dist/src/services/genesis-peering.js +91 -0
  920. package/dist/src/services/genesis-peering.js.map +1 -0
  921. package/dist/src/services/genesis-sync.d.ts +29 -0
  922. package/dist/src/services/genesis-sync.d.ts.map +1 -0
  923. package/dist/src/services/genesis-sync.js +370 -0
  924. package/dist/src/services/genesis-sync.js.map +1 -0
  925. package/dist/src/services/hooks.d.ts +21 -0
  926. package/dist/src/services/hooks.d.ts.map +1 -0
  927. package/dist/src/services/hooks.js +85 -0
  928. package/dist/src/services/hooks.js.map +1 -0
  929. package/dist/src/services/job-seeding.d.ts +7 -0
  930. package/dist/src/services/job-seeding.d.ts.map +1 -0
  931. package/dist/src/services/job-seeding.js +39 -0
  932. package/dist/src/services/job-seeding.js.map +1 -0
  933. package/dist/src/services/knowledge.d.ts +13 -0
  934. package/dist/src/services/knowledge.d.ts.map +1 -0
  935. package/dist/src/services/knowledge.js +15 -0
  936. package/dist/src/services/knowledge.js.map +1 -0
  937. package/dist/src/services/mailbox-notification.d.ts +37 -0
  938. package/dist/src/services/mailbox-notification.d.ts.map +1 -0
  939. package/dist/src/services/mailbox-notification.js +249 -0
  940. package/dist/src/services/mailbox-notification.js.map +1 -0
  941. package/dist/src/services/mailbox.d.ts +16 -0
  942. package/dist/src/services/mailbox.d.ts.map +1 -0
  943. package/dist/src/services/mailbox.js +77 -0
  944. package/dist/src/services/mailbox.js.map +1 -0
  945. package/dist/src/services/match-notification.d.ts +12 -0
  946. package/dist/src/services/match-notification.d.ts.map +1 -0
  947. package/dist/src/services/match-notification.js +121 -0
  948. package/dist/src/services/match-notification.js.map +1 -0
  949. package/dist/src/services/matching.d.ts +54 -0
  950. package/dist/src/services/matching.d.ts.map +1 -0
  951. package/dist/src/services/matching.js +293 -0
  952. package/dist/src/services/matching.js.map +1 -0
  953. package/dist/src/services/memory-replication.d.ts +43 -0
  954. package/dist/src/services/memory-replication.d.ts.map +1 -0
  955. package/dist/src/services/memory-replication.js +213 -0
  956. package/dist/src/services/memory-replication.js.map +1 -0
  957. package/dist/src/services/morsel.d.ts +49 -0
  958. package/dist/src/services/morsel.d.ts.map +1 -0
  959. package/dist/src/services/morsel.js +174 -0
  960. package/dist/src/services/morsel.js.map +1 -0
  961. package/dist/src/services/msm-parser.d.ts +55 -0
  962. package/dist/src/services/msm-parser.d.ts.map +1 -0
  963. package/dist/src/services/msm-parser.js +186 -0
  964. package/dist/src/services/msm-parser.js.map +1 -0
  965. package/dist/src/services/mydata-receipt.d.ts +29 -0
  966. package/dist/src/services/mydata-receipt.d.ts.map +1 -0
  967. package/dist/src/services/mydata-receipt.js +31 -0
  968. package/dist/src/services/mydata-receipt.js.map +1 -0
  969. package/dist/src/services/notification-templates.d.ts +40 -0
  970. package/dist/src/services/notification-templates.d.ts.map +1 -0
  971. package/dist/src/services/notification-templates.js +109 -0
  972. package/dist/src/services/notification-templates.js.map +1 -0
  973. package/dist/src/services/openrouter.d.ts +30 -0
  974. package/dist/src/services/openrouter.d.ts.map +1 -0
  975. package/dist/src/services/openrouter.js +95 -0
  976. package/dist/src/services/openrouter.js.map +1 -0
  977. package/dist/src/services/organism-reputation.d.ts +7 -0
  978. package/dist/src/services/organism-reputation.d.ts.map +1 -0
  979. package/dist/src/services/organism-reputation.js +107 -0
  980. package/dist/src/services/organism-reputation.js.map +1 -0
  981. package/dist/src/services/package-hash.d.ts +19 -0
  982. package/dist/src/services/package-hash.d.ts.map +1 -0
  983. package/dist/src/services/package-hash.js +22 -0
  984. package/dist/src/services/package-hash.js.map +1 -0
  985. package/dist/src/services/package-zip.d.ts +60 -0
  986. package/dist/src/services/package-zip.d.ts.map +1 -0
  987. package/dist/src/services/package-zip.js +267 -0
  988. package/dist/src/services/package-zip.js.map +1 -0
  989. package/dist/src/services/password.d.ts +9 -0
  990. package/dist/src/services/password.d.ts.map +1 -0
  991. package/dist/src/services/password.js +32 -0
  992. package/dist/src/services/password.js.map +1 -0
  993. package/dist/src/services/personal-routing.d.ts +21 -0
  994. package/dist/src/services/personal-routing.d.ts.map +1 -0
  995. package/dist/src/services/personal-routing.js +77 -0
  996. package/dist/src/services/personal-routing.js.map +1 -0
  997. package/dist/src/services/personal-tunnel.d.ts +39 -0
  998. package/dist/src/services/personal-tunnel.d.ts.map +1 -0
  999. package/dist/src/services/personal-tunnel.js +371 -0
  1000. package/dist/src/services/personal-tunnel.js.map +1 -0
  1001. package/dist/src/services/profile-schemas.d.ts +12 -0
  1002. package/dist/src/services/profile-schemas.d.ts.map +1 -0
  1003. package/dist/src/services/profile-schemas.js +100 -0
  1004. package/dist/src/services/profile-schemas.js.map +1 -0
  1005. package/dist/src/services/prometheus.d.ts +32 -0
  1006. package/dist/src/services/prometheus.d.ts.map +1 -0
  1007. package/dist/src/services/prometheus.js +162 -0
  1008. package/dist/src/services/prometheus.js.map +1 -0
  1009. package/dist/src/services/prompt-defaults.d.ts +33 -0
  1010. package/dist/src/services/prompt-defaults.d.ts.map +1 -0
  1011. package/dist/src/services/prompt-defaults.js +1675 -0
  1012. package/dist/src/services/prompt-defaults.js.map +1 -0
  1013. package/dist/src/services/prompt-seeder.d.ts +8 -0
  1014. package/dist/src/services/prompt-seeder.d.ts.map +1 -0
  1015. package/dist/src/services/prompt-seeder.js +65 -0
  1016. package/dist/src/services/prompt-seeder.js.map +1 -0
  1017. package/dist/src/services/prompt-variables.d.ts +15 -0
  1018. package/dist/src/services/prompt-variables.d.ts.map +1 -0
  1019. package/dist/src/services/prompt-variables.js +34 -0
  1020. package/dist/src/services/prompt-variables.js.map +1 -0
  1021. package/dist/src/services/push.d.ts +26 -0
  1022. package/dist/src/services/push.d.ts.map +1 -0
  1023. package/dist/src/services/push.js +70 -0
  1024. package/dist/src/services/push.js.map +1 -0
  1025. package/dist/src/services/quota.d.ts +45 -0
  1026. package/dist/src/services/quota.d.ts.map +1 -0
  1027. package/dist/src/services/quota.js +129 -0
  1028. package/dist/src/services/quota.js.map +1 -0
  1029. package/dist/src/services/realtime-manager.d.ts +144 -0
  1030. package/dist/src/services/realtime-manager.d.ts.map +1 -0
  1031. package/dist/src/services/realtime-manager.js +640 -0
  1032. package/dist/src/services/realtime-manager.js.map +1 -0
  1033. package/dist/src/services/scheduler.d.ts +55 -0
  1034. package/dist/src/services/scheduler.d.ts.map +1 -0
  1035. package/dist/src/services/scheduler.js +420 -0
  1036. package/dist/src/services/scheduler.js.map +1 -0
  1037. package/dist/src/services/schema-validator.d.ts +20 -0
  1038. package/dist/src/services/schema-validator.d.ts.map +1 -0
  1039. package/dist/src/services/schema-validator.js +68 -0
  1040. package/dist/src/services/schema-validator.js.map +1 -0
  1041. package/dist/src/services/site-sync.d.ts +15 -0
  1042. package/dist/src/services/site-sync.d.ts.map +1 -0
  1043. package/dist/src/services/site-sync.js +99 -0
  1044. package/dist/src/services/site-sync.js.map +1 -0
  1045. package/dist/src/services/site.d.ts +65 -0
  1046. package/dist/src/services/site.d.ts.map +1 -0
  1047. package/dist/src/services/site.js +378 -0
  1048. package/dist/src/services/site.js.map +1 -0
  1049. package/dist/src/services/stats.d.ts +75 -0
  1050. package/dist/src/services/stats.d.ts.map +1 -0
  1051. package/dist/src/services/stats.js +124 -0
  1052. package/dist/src/services/stats.js.map +1 -0
  1053. package/dist/src/services/sync-health.d.ts +53 -0
  1054. package/dist/src/services/sync-health.d.ts.map +1 -0
  1055. package/dist/src/services/sync-health.js +122 -0
  1056. package/dist/src/services/sync-health.js.map +1 -0
  1057. package/dist/src/services/sync-scheduler.d.ts +25 -0
  1058. package/dist/src/services/sync-scheduler.d.ts.map +1 -0
  1059. package/dist/src/services/sync-scheduler.js +211 -0
  1060. package/dist/src/services/sync-scheduler.js.map +1 -0
  1061. package/dist/src/services/totp.d.ts +31 -0
  1062. package/dist/src/services/totp.d.ts.map +1 -0
  1063. package/dist/src/services/totp.js +96 -0
  1064. package/dist/src/services/totp.js.map +1 -0
  1065. package/dist/src/services/trust-broadcast.d.ts +37 -0
  1066. package/dist/src/services/trust-broadcast.d.ts.map +1 -0
  1067. package/dist/src/services/trust-broadcast.js +107 -0
  1068. package/dist/src/services/trust-broadcast.js.map +1 -0
  1069. package/dist/src/services/trust.d.ts +16 -0
  1070. package/dist/src/services/trust.d.ts.map +1 -0
  1071. package/dist/src/services/trust.js +109 -0
  1072. package/dist/src/services/trust.js.map +1 -0
  1073. package/dist/src/services/vc-issuer.d.ts +14 -0
  1074. package/dist/src/services/vc-issuer.d.ts.map +1 -0
  1075. package/dist/src/services/vc-issuer.js +24 -0
  1076. package/dist/src/services/vc-issuer.js.map +1 -0
  1077. package/dist/src/storage/interface.d.ts +1161 -0
  1078. package/dist/src/storage/interface.d.ts.map +1 -0
  1079. package/dist/src/storage/interface.js +2 -0
  1080. package/dist/src/storage/interface.js.map +1 -0
  1081. package/dist/src/storage/pattern-utils.d.ts +20 -0
  1082. package/dist/src/storage/pattern-utils.d.ts.map +1 -0
  1083. package/dist/src/storage/pattern-utils.js +57 -0
  1084. package/dist/src/storage/pattern-utils.js.map +1 -0
  1085. package/dist/src/storage/providers/mongodb/index.d.ts +608 -0
  1086. package/dist/src/storage/providers/mongodb/index.d.ts.map +1 -0
  1087. package/dist/src/storage/providers/mongodb/index.js +4931 -0
  1088. package/dist/src/storage/providers/mongodb/index.js.map +1 -0
  1089. package/dist/src/storage/providers/sqlite/index.d.ts +602 -0
  1090. package/dist/src/storage/providers/sqlite/index.d.ts.map +1 -0
  1091. package/dist/src/storage/providers/sqlite/index.js +4156 -0
  1092. package/dist/src/storage/providers/sqlite/index.js.map +1 -0
  1093. package/dist/src/storage/providers/sqlite/repos/action.d.ts +13 -0
  1094. package/dist/src/storage/providers/sqlite/repos/action.d.ts.map +1 -0
  1095. package/dist/src/storage/providers/sqlite/repos/action.js +79 -0
  1096. package/dist/src/storage/providers/sqlite/repos/action.js.map +1 -0
  1097. package/dist/src/storage/providers/sqlite/repos/agent.d.ts +13 -0
  1098. package/dist/src/storage/providers/sqlite/repos/agent.d.ts.map +1 -0
  1099. package/dist/src/storage/providers/sqlite/repos/agent.js +103 -0
  1100. package/dist/src/storage/providers/sqlite/repos/agent.js.map +1 -0
  1101. package/dist/src/storage/providers/sqlite/repos/auth.d.ts +56 -0
  1102. package/dist/src/storage/providers/sqlite/repos/auth.d.ts.map +1 -0
  1103. package/dist/src/storage/providers/sqlite/repos/auth.js +282 -0
  1104. package/dist/src/storage/providers/sqlite/repos/auth.js.map +1 -0
  1105. package/dist/src/storage/providers/sqlite/repos/board.d.ts +24 -0
  1106. package/dist/src/storage/providers/sqlite/repos/board.d.ts.map +1 -0
  1107. package/dist/src/storage/providers/sqlite/repos/board.js +154 -0
  1108. package/dist/src/storage/providers/sqlite/repos/board.js.map +1 -0
  1109. package/dist/src/storage/providers/sqlite/repos/community.d.ts +33 -0
  1110. package/dist/src/storage/providers/sqlite/repos/community.d.ts.map +1 -0
  1111. package/dist/src/storage/providers/sqlite/repos/community.js +202 -0
  1112. package/dist/src/storage/providers/sqlite/repos/community.js.map +1 -0
  1113. package/dist/src/storage/providers/sqlite/repos/consent.d.ts +23 -0
  1114. package/dist/src/storage/providers/sqlite/repos/consent.d.ts.map +1 -0
  1115. package/dist/src/storage/providers/sqlite/repos/consent.js +187 -0
  1116. package/dist/src/storage/providers/sqlite/repos/consent.js.map +1 -0
  1117. package/dist/src/storage/providers/sqlite/repos/dispute.d.ts +20 -0
  1118. package/dist/src/storage/providers/sqlite/repos/dispute.d.ts.map +1 -0
  1119. package/dist/src/storage/providers/sqlite/repos/dispute.js +118 -0
  1120. package/dist/src/storage/providers/sqlite/repos/dispute.js.map +1 -0
  1121. package/dist/src/storage/providers/sqlite/repos/flag.d.ts +26 -0
  1122. package/dist/src/storage/providers/sqlite/repos/flag.d.ts.map +1 -0
  1123. package/dist/src/storage/providers/sqlite/repos/flag.js +147 -0
  1124. package/dist/src/storage/providers/sqlite/repos/flag.js.map +1 -0
  1125. package/dist/src/storage/providers/sqlite/repos/identity.d.ts +36 -0
  1126. package/dist/src/storage/providers/sqlite/repos/identity.d.ts.map +1 -0
  1127. package/dist/src/storage/providers/sqlite/repos/identity.js +297 -0
  1128. package/dist/src/storage/providers/sqlite/repos/identity.js.map +1 -0
  1129. package/dist/src/storage/providers/sqlite/repos/mailbox.d.ts +18 -0
  1130. package/dist/src/storage/providers/sqlite/repos/mailbox.d.ts.map +1 -0
  1131. package/dist/src/storage/providers/sqlite/repos/mailbox.js +91 -0
  1132. package/dist/src/storage/providers/sqlite/repos/mailbox.js.map +1 -0
  1133. package/dist/src/storage/providers/sqlite/repos/memory.d.ts +28 -0
  1134. package/dist/src/storage/providers/sqlite/repos/memory.d.ts.map +1 -0
  1135. package/dist/src/storage/providers/sqlite/repos/memory.js +152 -0
  1136. package/dist/src/storage/providers/sqlite/repos/memory.js.map +1 -0
  1137. package/dist/src/storage/providers/sqlite/repos/owner.d.ts +14 -0
  1138. package/dist/src/storage/providers/sqlite/repos/owner.d.ts.map +1 -0
  1139. package/dist/src/storage/providers/sqlite/repos/owner.js +124 -0
  1140. package/dist/src/storage/providers/sqlite/repos/owner.js.map +1 -0
  1141. package/dist/src/storage/providers/sqlite/repos/service-manifest.d.ts +17 -0
  1142. package/dist/src/storage/providers/sqlite/repos/service-manifest.d.ts.map +1 -0
  1143. package/dist/src/storage/providers/sqlite/repos/service-manifest.js +114 -0
  1144. package/dist/src/storage/providers/sqlite/repos/service-manifest.js.map +1 -0
  1145. package/dist/src/storage/providers/sqlite/repos/storage-file.d.ts +19 -0
  1146. package/dist/src/storage/providers/sqlite/repos/storage-file.d.ts.map +1 -0
  1147. package/dist/src/storage/providers/sqlite/repos/storage-file.js +128 -0
  1148. package/dist/src/storage/providers/sqlite/repos/storage-file.js.map +1 -0
  1149. package/dist/src/storage/providers/sqlite/repos/work.d.ts +13 -0
  1150. package/dist/src/storage/providers/sqlite/repos/work.d.ts.map +1 -0
  1151. package/dist/src/storage/providers/sqlite/repos/work.js +86 -0
  1152. package/dist/src/storage/providers/sqlite/repos/work.js.map +1 -0
  1153. package/dist/src/storage/providers/sqlite/schema.d.ts +7 -0
  1154. package/dist/src/storage/providers/sqlite/schema.d.ts.map +1 -0
  1155. package/dist/src/storage/providers/sqlite/schema.js +1090 -0
  1156. package/dist/src/storage/providers/sqlite/schema.js.map +1 -0
  1157. package/dist/src/storage/repositories/action.repository.d.ts +14 -0
  1158. package/dist/src/storage/repositories/action.repository.d.ts.map +1 -0
  1159. package/dist/src/storage/repositories/action.repository.js +2 -0
  1160. package/dist/src/storage/repositories/action.repository.js.map +1 -0
  1161. package/dist/src/storage/repositories/agent.repository.d.ts +18 -0
  1162. package/dist/src/storage/repositories/agent.repository.d.ts.map +1 -0
  1163. package/dist/src/storage/repositories/agent.repository.js +2 -0
  1164. package/dist/src/storage/repositories/agent.repository.js.map +1 -0
  1165. package/dist/src/storage/repositories/app-marketplace.repository.d.ts +9 -0
  1166. package/dist/src/storage/repositories/app-marketplace.repository.d.ts.map +1 -0
  1167. package/dist/src/storage/repositories/app-marketplace.repository.js +2 -0
  1168. package/dist/src/storage/repositories/app-marketplace.repository.js.map +1 -0
  1169. package/dist/src/storage/repositories/app.repository.d.ts +17 -0
  1170. package/dist/src/storage/repositories/app.repository.d.ts.map +1 -0
  1171. package/dist/src/storage/repositories/app.repository.js +2 -0
  1172. package/dist/src/storage/repositories/app.repository.js.map +1 -0
  1173. package/dist/src/storage/repositories/auth.repository.d.ts +6 -0
  1174. package/dist/src/storage/repositories/auth.repository.d.ts.map +1 -0
  1175. package/dist/src/storage/repositories/auth.repository.js +2 -0
  1176. package/dist/src/storage/repositories/auth.repository.js.map +1 -0
  1177. package/dist/src/storage/repositories/board.repository.d.ts +27 -0
  1178. package/dist/src/storage/repositories/board.repository.d.ts.map +1 -0
  1179. package/dist/src/storage/repositories/board.repository.js +2 -0
  1180. package/dist/src/storage/repositories/board.repository.js.map +1 -0
  1181. package/dist/src/storage/repositories/catalogue.repository.d.ts +18 -0
  1182. package/dist/src/storage/repositories/catalogue.repository.d.ts.map +1 -0
  1183. package/dist/src/storage/repositories/catalogue.repository.js +2 -0
  1184. package/dist/src/storage/repositories/catalogue.repository.js.map +1 -0
  1185. package/dist/src/storage/repositories/config.repository.d.ts +17 -0
  1186. package/dist/src/storage/repositories/config.repository.d.ts.map +1 -0
  1187. package/dist/src/storage/repositories/config.repository.js +2 -0
  1188. package/dist/src/storage/repositories/config.repository.js.map +1 -0
  1189. package/dist/src/storage/repositories/consent.repository.d.ts +19 -0
  1190. package/dist/src/storage/repositories/consent.repository.d.ts.map +1 -0
  1191. package/dist/src/storage/repositories/consent.repository.js +2 -0
  1192. package/dist/src/storage/repositories/consent.repository.js.map +1 -0
  1193. package/dist/src/storage/repositories/device-auth.repository.d.ts +11 -0
  1194. package/dist/src/storage/repositories/device-auth.repository.d.ts.map +1 -0
  1195. package/dist/src/storage/repositories/device-auth.repository.js +2 -0
  1196. package/dist/src/storage/repositories/device-auth.repository.js.map +1 -0
  1197. package/dist/src/storage/repositories/dispute.repository.d.ts +12 -0
  1198. package/dist/src/storage/repositories/dispute.repository.d.ts.map +1 -0
  1199. package/dist/src/storage/repositories/dispute.repository.js +2 -0
  1200. package/dist/src/storage/repositories/dispute.repository.js.map +1 -0
  1201. package/dist/src/storage/repositories/extension-instance.repository.d.ts +9 -0
  1202. package/dist/src/storage/repositories/extension-instance.repository.d.ts.map +1 -0
  1203. package/dist/src/storage/repositories/extension-instance.repository.js +2 -0
  1204. package/dist/src/storage/repositories/extension-instance.repository.js.map +1 -0
  1205. package/dist/src/storage/repositories/federation.repository.d.ts +37 -0
  1206. package/dist/src/storage/repositories/federation.repository.d.ts.map +1 -0
  1207. package/dist/src/storage/repositories/federation.repository.js +2 -0
  1208. package/dist/src/storage/repositories/federation.repository.js.map +1 -0
  1209. package/dist/src/storage/repositories/file.repository.d.ts +14 -0
  1210. package/dist/src/storage/repositories/file.repository.d.ts.map +1 -0
  1211. package/dist/src/storage/repositories/file.repository.js +2 -0
  1212. package/dist/src/storage/repositories/file.repository.js.map +1 -0
  1213. package/dist/src/storage/repositories/identity.repository.d.ts +29 -0
  1214. package/dist/src/storage/repositories/identity.repository.d.ts.map +1 -0
  1215. package/dist/src/storage/repositories/identity.repository.js +2 -0
  1216. package/dist/src/storage/repositories/identity.repository.js.map +1 -0
  1217. package/dist/src/storage/repositories/index.d.ts +34 -0
  1218. package/dist/src/storage/repositories/index.d.ts.map +1 -0
  1219. package/dist/src/storage/repositories/index.js +2 -0
  1220. package/dist/src/storage/repositories/index.js.map +1 -0
  1221. package/dist/src/storage/repositories/knowledge.repository.d.ts +18 -0
  1222. package/dist/src/storage/repositories/knowledge.repository.d.ts.map +1 -0
  1223. package/dist/src/storage/repositories/knowledge.repository.js +2 -0
  1224. package/dist/src/storage/repositories/knowledge.repository.js.map +1 -0
  1225. package/dist/src/storage/repositories/marketplace.repository.d.ts +23 -0
  1226. package/dist/src/storage/repositories/marketplace.repository.d.ts.map +1 -0
  1227. package/dist/src/storage/repositories/marketplace.repository.js +2 -0
  1228. package/dist/src/storage/repositories/marketplace.repository.js.map +1 -0
  1229. package/dist/src/storage/repositories/memory.repository.d.ts +32 -0
  1230. package/dist/src/storage/repositories/memory.repository.d.ts.map +1 -0
  1231. package/dist/src/storage/repositories/memory.repository.js +2 -0
  1232. package/dist/src/storage/repositories/memory.repository.js.map +1 -0
  1233. package/dist/src/storage/repositories/micro-memory.repository.d.ts +10 -0
  1234. package/dist/src/storage/repositories/micro-memory.repository.d.ts.map +1 -0
  1235. package/dist/src/storage/repositories/micro-memory.repository.js +2 -0
  1236. package/dist/src/storage/repositories/micro-memory.repository.js.map +1 -0
  1237. package/dist/src/storage/repositories/moderation.repository.d.ts +36 -0
  1238. package/dist/src/storage/repositories/moderation.repository.d.ts.map +1 -0
  1239. package/dist/src/storage/repositories/moderation.repository.js +2 -0
  1240. package/dist/src/storage/repositories/moderation.repository.js.map +1 -0
  1241. package/dist/src/storage/repositories/node.repository.d.ts +59 -0
  1242. package/dist/src/storage/repositories/node.repository.d.ts.map +1 -0
  1243. package/dist/src/storage/repositories/node.repository.js +2 -0
  1244. package/dist/src/storage/repositories/node.repository.js.map +1 -0
  1245. package/dist/src/storage/repositories/notification-template.repository.d.ts +8 -0
  1246. package/dist/src/storage/repositories/notification-template.repository.d.ts.map +1 -0
  1247. package/dist/src/storage/repositories/notification-template.repository.js +2 -0
  1248. package/dist/src/storage/repositories/notification-template.repository.js.map +1 -0
  1249. package/dist/src/storage/repositories/notification.repository.d.ts +14 -0
  1250. package/dist/src/storage/repositories/notification.repository.d.ts.map +1 -0
  1251. package/dist/src/storage/repositories/notification.repository.js +2 -0
  1252. package/dist/src/storage/repositories/notification.repository.js.map +1 -0
  1253. package/dist/src/storage/repositories/oauth.repository.d.ts +19 -0
  1254. package/dist/src/storage/repositories/oauth.repository.d.ts.map +1 -0
  1255. package/dist/src/storage/repositories/oauth.repository.js +2 -0
  1256. package/dist/src/storage/repositories/oauth.repository.js.map +1 -0
  1257. package/dist/src/storage/repositories/organism.repository.d.ts +34 -0
  1258. package/dist/src/storage/repositories/organism.repository.d.ts.map +1 -0
  1259. package/dist/src/storage/repositories/organism.repository.js +2 -0
  1260. package/dist/src/storage/repositories/organism.repository.js.map +1 -0
  1261. package/dist/src/storage/repositories/otk.repository.d.ts +9 -0
  1262. package/dist/src/storage/repositories/otk.repository.d.ts.map +1 -0
  1263. package/dist/src/storage/repositories/otk.repository.js +2 -0
  1264. package/dist/src/storage/repositories/otk.repository.js.map +1 -0
  1265. package/dist/src/storage/repositories/owner.repository.d.ts +9 -0
  1266. package/dist/src/storage/repositories/owner.repository.d.ts.map +1 -0
  1267. package/dist/src/storage/repositories/owner.repository.js +2 -0
  1268. package/dist/src/storage/repositories/owner.repository.js.map +1 -0
  1269. package/dist/src/storage/repositories/package-instance.repository.d.ts +26 -0
  1270. package/dist/src/storage/repositories/package-instance.repository.d.ts.map +1 -0
  1271. package/dist/src/storage/repositories/package-instance.repository.js +12 -0
  1272. package/dist/src/storage/repositories/package-instance.repository.js.map +1 -0
  1273. package/dist/src/storage/repositories/package.repository.d.ts +28 -0
  1274. package/dist/src/storage/repositories/package.repository.d.ts.map +1 -0
  1275. package/dist/src/storage/repositories/package.repository.js +12 -0
  1276. package/dist/src/storage/repositories/package.repository.js.map +1 -0
  1277. package/dist/src/storage/repositories/replication-queue.repository.d.ts +10 -0
  1278. package/dist/src/storage/repositories/replication-queue.repository.d.ts.map +1 -0
  1279. package/dist/src/storage/repositories/replication-queue.repository.js +2 -0
  1280. package/dist/src/storage/repositories/replication-queue.repository.js.map +1 -0
  1281. package/dist/src/storage/repositories/scheduler.repository.d.ts +30 -0
  1282. package/dist/src/storage/repositories/scheduler.repository.d.ts.map +1 -0
  1283. package/dist/src/storage/repositories/scheduler.repository.js +2 -0
  1284. package/dist/src/storage/repositories/scheduler.repository.js.map +1 -0
  1285. package/dist/src/storage/repositories/schema.repository.d.ts +9 -0
  1286. package/dist/src/storage/repositories/schema.repository.d.ts.map +1 -0
  1287. package/dist/src/storage/repositories/schema.repository.js +2 -0
  1288. package/dist/src/storage/repositories/schema.repository.js.map +1 -0
  1289. package/dist/src/storage/repositories/session.repository.d.ts +22 -0
  1290. package/dist/src/storage/repositories/session.repository.d.ts.map +1 -0
  1291. package/dist/src/storage/repositories/session.repository.js +2 -0
  1292. package/dist/src/storage/repositories/session.repository.js.map +1 -0
  1293. package/dist/src/storage/repositories/system-prompt.repository.d.ts +14 -0
  1294. package/dist/src/storage/repositories/system-prompt.repository.d.ts.map +1 -0
  1295. package/dist/src/storage/repositories/system-prompt.repository.js +2 -0
  1296. package/dist/src/storage/repositories/system-prompt.repository.js.map +1 -0
  1297. package/dist/src/storage/repositories/template-listing.repository.d.ts +44 -0
  1298. package/dist/src/storage/repositories/template-listing.repository.d.ts.map +1 -0
  1299. package/dist/src/storage/repositories/template-listing.repository.js +13 -0
  1300. package/dist/src/storage/repositories/template-listing.repository.js.map +1 -0
  1301. package/dist/src/storage/repositories/wallet.repository.d.ts +8 -0
  1302. package/dist/src/storage/repositories/wallet.repository.d.ts.map +1 -0
  1303. package/dist/src/storage/repositories/wallet.repository.js +2 -0
  1304. package/dist/src/storage/repositories/wallet.repository.js.map +1 -0
  1305. package/dist/src/storage/repositories/work.repository.d.ts +10 -0
  1306. package/dist/src/storage/repositories/work.repository.d.ts.map +1 -0
  1307. package/dist/src/storage/repositories/work.repository.js +2 -0
  1308. package/dist/src/storage/repositories/work.repository.js.map +1 -0
  1309. package/dist/src/storage/storage-factory.d.ts +9 -0
  1310. package/dist/src/storage/storage-factory.d.ts.map +1 -0
  1311. package/dist/src/storage/storage-factory.js +20 -0
  1312. package/dist/src/storage/storage-factory.js.map +1 -0
  1313. package/dist/src/types/route-manifest.d.ts +53 -0
  1314. package/dist/src/types/route-manifest.d.ts.map +1 -0
  1315. package/dist/src/types/route-manifest.js +44 -0
  1316. package/dist/src/types/route-manifest.js.map +1 -0
  1317. package/dist/src/utils/catalogue-hash.d.ts +10 -0
  1318. package/dist/src/utils/catalogue-hash.d.ts.map +1 -0
  1319. package/dist/src/utils/catalogue-hash.js +23 -0
  1320. package/dist/src/utils/catalogue-hash.js.map +1 -0
  1321. package/dist/src/utils/env-config.d.ts +8 -0
  1322. package/dist/src/utils/env-config.d.ts.map +1 -0
  1323. package/dist/src/utils/env-config.js +1264 -0
  1324. package/dist/src/utils/env-config.js.map +1 -0
  1325. package/dist/src/utils/env-validator.d.ts +14 -0
  1326. package/dist/src/utils/env-validator.d.ts.map +1 -0
  1327. package/dist/src/utils/env-validator.js +338 -0
  1328. package/dist/src/utils/env-validator.js.map +1 -0
  1329. package/dist/src/utils/fire-hook.d.ts +9 -0
  1330. package/dist/src/utils/fire-hook.d.ts.map +1 -0
  1331. package/dist/src/utils/fire-hook.js +12 -0
  1332. package/dist/src/utils/fire-hook.js.map +1 -0
  1333. package/dist/src/utils/gaii.d.ts +57 -0
  1334. package/dist/src/utils/gaii.d.ts.map +1 -0
  1335. package/dist/src/utils/gaii.js +148 -0
  1336. package/dist/src/utils/gaii.js.map +1 -0
  1337. package/dist/src/utils/ghii-resolver.d.ts +14 -0
  1338. package/dist/src/utils/ghii-resolver.d.ts.map +1 -0
  1339. package/dist/src/utils/ghii-resolver.js +21 -0
  1340. package/dist/src/utils/ghii-resolver.js.map +1 -0
  1341. package/dist/src/utils/logger.d.ts +9 -0
  1342. package/dist/src/utils/logger.d.ts.map +1 -0
  1343. package/dist/src/utils/logger.js +36 -0
  1344. package/dist/src/utils/logger.js.map +1 -0
  1345. package/dist/src/utils/otk.d.ts +2 -0
  1346. package/dist/src/utils/otk.d.ts.map +1 -0
  1347. package/dist/src/utils/otk.js +5 -0
  1348. package/dist/src/utils/otk.js.map +1 -0
  1349. package/dist/src/utils/tracking-code.d.ts +9 -0
  1350. package/dist/src/utils/tracking-code.d.ts.map +1 -0
  1351. package/dist/src/utils/tracking-code.js +16 -0
  1352. package/dist/src/utils/tracking-code.js.map +1 -0
  1353. package/dist/src/utils/url-validator.d.ts +5 -0
  1354. package/dist/src/utils/url-validator.d.ts.map +1 -0
  1355. package/dist/src/utils/url-validator.js +56 -0
  1356. package/dist/src/utils/url-validator.js.map +1 -0
  1357. package/dist/static/app-catalog.html +4401 -0
  1358. package/dist/static/cookieconsent.css +1 -0
  1359. package/dist/static/cookieconsent.umd.js +7 -0
  1360. package/dist/static/icons/icon-maskable.svg +27 -0
  1361. package/dist/static/icons/icon.svg +27 -0
  1362. package/dist/static/manifest.json +17 -0
  1363. package/dist/static/offline.html +167 -0
  1364. package/dist/static/sw.js +260 -0
  1365. package/package.json +182 -0
  1366. package/prisma/schema.prisma +1086 -0
@@ -0,0 +1,2042 @@
1
+ import { Router } from 'express';
2
+ import { resolveFlat, resolveLocale } from '../i18n.js';
3
+ function sanitize(s) {
4
+ return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
5
+ }
6
+ function buildProfileTranslations(locale) {
7
+ return { ...resolveFlat(locale, 'profile'), ...resolveFlat(locale, 'modal') };
8
+ }
9
+ function profileHtml(config, locale, translations) {
10
+ return `<!DOCTYPE html>
11
+ <html lang="${sanitize(locale)}">
12
+ <head>
13
+ <meta charset="UTF-8">
14
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
15
+ <meta name="aimeat-node" content="${sanitize(config.baseUrl)}">
16
+ <title>${sanitize(translations['profile.title'] || 'My Profile')} \u2014 AIMEAT ${sanitize(config.nodeId)}</title>
17
+ <link rel="icon" href="/favicon.svg" type="image/svg+xml">
18
+ <script>var T = ${JSON.stringify(translations)};</script>
19
+ <script src="${sanitize(config.baseUrl)}/v1/libs/aimeat-auth.js"></script>
20
+ <style>
21
+ *{margin:0;padding:0;box-sizing:border-box}
22
+ :root{--bg:#0f0a14;--card:rgba(30,20,40,.85);--card2:rgba(60,30,60,.7);--text:#f0e6f6;--muted:#c4a6d0;--accent:#ff6b9d;--accent2:#c44569;--border:rgba(255,107,157,.25);--success:#22c55e;--warn:#f59e0b;--danger:#ef4444;--radius:12px;--love1:#ff6b9d;--love2:#c44569;--love3:#ff8a80;--love4:#f48fb1;--love5:#880e4f}
23
+ body{font-family:system-ui,-apple-system,sans-serif;background:var(--bg);color:var(--text);line-height:1.6;min-height:100vh;overflow-x:hidden}
24
+ a{color:var(--love1);text-decoration:none}
25
+ a:hover{text-decoration:underline;color:var(--love3)}
26
+
27
+ /* Background */
28
+ .bg-layer{position:fixed;top:0;left:0;width:100%;height:100%;z-index:0;pointer-events:none}
29
+ .bg-aurora .aurora-wave{position:absolute;width:200%;height:60%;left:-50%;border-radius:50%;filter:blur(80px);opacity:.25;animation:auroraShift 8s ease-in-out infinite alternate}
30
+ .bg-aurora .aurora-wave:nth-child(1){top:10%;background:linear-gradient(90deg,#ff6b9d,#c44569,#ff8a80,#f48fb1);animation-duration:8s}
31
+ .bg-aurora .aurora-wave:nth-child(2){top:35%;background:linear-gradient(90deg,#f48fb1,#880e4f,#ff6b9d,#e91e63);animation-duration:12s;animation-delay:-4s}
32
+ .bg-aurora .aurora-wave:nth-child(3){top:60%;background:linear-gradient(90deg,#ad1457,#ff6b9d,#f06292,#880e4f);animation-duration:10s;animation-delay:-2s}
33
+ @keyframes auroraShift{0%{transform:translateX(-20%) scaleY(1)}50%{transform:translateX(10%) scaleY(1.3)}100%{transform:translateX(-10%) scaleY(.8)}}
34
+
35
+ /* Layout */
36
+ .topbar{background:rgba(30,20,40,.9);backdrop-filter:blur(12px);border-bottom:1px solid var(--border);padding:.6rem 1.5rem;display:flex;align-items:center;justify-content:space-between;position:sticky;top:0;z-index:100}
37
+ .topbar-left{display:flex;align-items:center;gap:.75rem;font-weight:700;font-size:1rem}
38
+ .topbar-left a{color:var(--text);text-decoration:none}
39
+ .topbar-right{display:flex;align-items:center;gap:.75rem}
40
+ #auth-container{display:inline-flex;align-items:center}
41
+
42
+ .container{max-width:1000px;margin:0 auto;padding:2rem 1.5rem;position:relative;z-index:1}
43
+
44
+ /* Login prompt */
45
+ .login-prompt{text-align:center;padding:4rem 2rem}
46
+ .login-prompt h1{font-size:2rem;margin-bottom:1rem}
47
+ .login-prompt p{color:var(--muted);margin-bottom:2rem;font-size:1.1rem}
48
+ #login-area{display:flex;justify-content:center}
49
+
50
+ /* Profile header */
51
+ .profile-header{display:flex;align-items:center;gap:1.5rem;margin-bottom:2rem;flex-wrap:wrap}
52
+ .avatar{width:80px;height:80px;border-radius:50%;background:linear-gradient(135deg,var(--love1),var(--love2));display:flex;align-items:center;justify-content:center;font-size:2.2rem;flex-shrink:0;box-shadow:0 0 24px rgba(255,107,157,.3)}
53
+ .profile-info h1{font-size:1.6rem;font-weight:700;margin-bottom:.2rem}
54
+ .profile-info .ghii{color:var(--love1);font-family:monospace;font-size:.9rem}
55
+ .profile-info .meta{color:var(--muted);font-size:.85rem;margin-top:.3rem}
56
+
57
+ /* Stats bar */
58
+ .stats-bar{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:.75rem;margin-bottom:2rem}
59
+ .stat-card{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);padding:1rem;text-align:center}
60
+ .stat-card .num{font-size:1.6rem;font-weight:700;color:var(--love1)}
61
+ .stat-card .label{font-size:.75rem;color:var(--muted);text-transform:uppercase;letter-spacing:.05em;margin-top:.2rem}
62
+
63
+ /* Tabs */
64
+ .tabs{display:flex;gap:.25rem;border-bottom:2px solid var(--border);margin-bottom:1.5rem;flex-wrap:wrap}
65
+ .tab{padding:.6rem 1.2rem;cursor:pointer;color:var(--muted);font-weight:600;font-size:.9rem;border-bottom:2px solid transparent;margin-bottom:-2px;transition:all .2s;background:none;border-top:none;border-left:none;border-right:none}
66
+ .tab:hover{color:var(--text)}
67
+ .tab.active{color:var(--love1);border-bottom-color:var(--love1)}
68
+ .tab-panel{display:none}
69
+ .tab-panel.active{display:block}
70
+
71
+ /* Cards */
72
+ .section-title{font-size:1.15rem;font-weight:600;margin-bottom:.4rem;color:var(--love1)}
73
+ .section-desc{color:var(--muted);font-size:.85rem;margin-bottom:1.25rem;line-height:1.5;max-width:700px}
74
+ .card{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);padding:1.25rem;margin-bottom:.75rem;transition:border-color .2s}
75
+ .card:hover{border-color:var(--love1)}
76
+ .card-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:.5rem}
77
+ .card-title{font-weight:600;font-size:1rem}
78
+ .card-subtitle{color:var(--muted);font-size:.8rem}
79
+ .badge{display:inline-block;padding:.15rem .5rem;border-radius:6px;font-size:.7rem;font-weight:700;letter-spacing:.03em}
80
+ .badge-success{background:rgba(34,197,94,.15);color:var(--success)}
81
+ .badge-warn{background:rgba(245,158,11,.15);color:var(--warn)}
82
+ .badge-info{background:rgba(255,107,157,.15);color:var(--love1)}
83
+ .badge-danger{background:rgba(239,68,68,.15);color:var(--danger)}
84
+ .badge-muted{background:rgba(196,166,208,.1);color:var(--muted)}
85
+
86
+ /* Agent card specifics */
87
+ .agent-card .gaii{font-family:monospace;font-size:.8rem;color:var(--muted)}
88
+ .agent-card .caps{display:flex;gap:.4rem;flex-wrap:wrap;margin-top:.5rem}
89
+ .agent-card .caps .cap{font-size:.7rem;background:rgba(255,107,157,.1);color:var(--love4);padding:.15rem .4rem;border-radius:4px}
90
+
91
+ /* Wallet */
92
+ .wallet-overview{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:.75rem;margin-bottom:1.5rem}
93
+ .wallet-card{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);padding:1rem;text-align:center}
94
+ .wallet-card .amount{font-size:1.4rem;font-weight:700}
95
+ .wallet-card .amount.positive{color:var(--success)}
96
+ .wallet-card .amount.neutral{color:var(--love1)}
97
+ .wallet-card .wlabel{font-size:.75rem;color:var(--muted);text-transform:uppercase;margin-top:.2rem}
98
+ .tx-list{max-height:400px;overflow-y:auto}
99
+ .tx-item{display:flex;justify-content:space-between;align-items:center;padding:.6rem .8rem;border-bottom:1px solid rgba(255,107,157,.08);font-size:.85rem}
100
+ .tx-item:last-child{border-bottom:none}
101
+ .tx-amount{font-weight:600;font-family:monospace}
102
+ .tx-amount.credit{color:var(--success)}
103
+ .tx-amount.debit{color:var(--danger)}
104
+ .tx-type{font-size:.75rem;color:var(--muted)}
105
+ .tx-date{font-size:.75rem;color:var(--muted)}
106
+
107
+ /* Memory list */
108
+ .mem-item{display:flex;justify-content:space-between;align-items:center;padding:.5rem 0;border-bottom:1px solid rgba(255,107,157,.08);font-size:.85rem;cursor:pointer}
109
+ .mem-item:hover{background:rgba(255,107,157,.05)}
110
+ .mem-key{font-family:monospace;color:var(--love3);font-weight:500}
111
+ .mem-vis{font-size:.7rem}
112
+
113
+ /* Memory expanded view */
114
+ .mem-detail{background:rgba(15,10,20,.6);border:1px solid rgba(255,107,157,.1);border-radius:8px;padding:1rem;margin-top:.5rem;font-size:.85rem}
115
+ .mem-detail pre{white-space:pre-wrap;word-break:break-all;font-family:monospace;color:var(--text);font-size:.8rem}
116
+ .mem-detail .mem-actions{display:flex;gap:.5rem;margin-top:.75rem}
117
+
118
+ /* Work items */
119
+ .work-status{display:flex;gap:.4rem;align-items:center}
120
+
121
+ /* OTK list */
122
+ .otk-item{font-size:.85rem;padding:.5rem 0;border-bottom:1px solid rgba(255,107,157,.08)}
123
+ .otk-key{font-family:monospace;font-size:.8rem;color:var(--love3);word-break:break-all}
124
+ .otk-meta{color:var(--muted);font-size:.75rem;margin-top:.2rem}
125
+
126
+ /* Federation */
127
+ .peer-card{display:flex;justify-content:space-between;align-items:center}
128
+ .peer-status{display:flex;align-items:center;gap:.4rem}
129
+ .peer-dot{width:8px;height:8px;border-radius:50%}
130
+ .peer-dot.alive{background:var(--success)}
131
+ .peer-dot.dead{background:var(--danger)}
132
+
133
+ /* Personal Node cards */
134
+ .pn-card{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);margin-bottom:.75rem;transition:border-color .2s;overflow:hidden}
135
+ .pn-card:hover{border-color:var(--love1)}
136
+ .pn-header{display:flex;justify-content:space-between;align-items:center;padding:1rem 1.25rem;cursor:pointer;user-select:none}
137
+ .pn-header-left{display:flex;align-items:center;gap:.75rem}
138
+ .pn-status-dot{width:10px;height:10px;border-radius:50%;flex-shrink:0}
139
+ .pn-status-dot.online{background:var(--success);box-shadow:0 0 6px rgba(34,197,94,.4)}
140
+ .pn-status-dot.offline{background:var(--danger)}
141
+ .pn-status-dot.degraded{background:var(--warn)}
142
+ .pn-status-dot.detached{background:var(--muted)}
143
+ .pn-name{font-weight:600;font-family:monospace;font-size:.9rem}
144
+ .pn-badges{display:flex;gap:.4rem;align-items:center}
145
+ .pn-quick{font-size:.8rem;color:var(--muted);padding:0 1.25rem .75rem}
146
+ .pn-arrow{color:var(--muted);font-size:.8rem;transition:transform .2s}
147
+ .pn-arrow.open{transform:rotate(180deg)}
148
+ .pn-details{display:none;padding:0 1.25rem 1.25rem;border-top:1px solid rgba(255,107,157,.08)}
149
+ .pn-details.open{display:block}
150
+ .pn-detail-row{display:flex;justify-content:space-between;align-items:center;padding:.5rem 0;border-bottom:1px solid rgba(255,107,157,.06);font-size:.85rem}
151
+ .pn-detail-row:last-child{border-bottom:none}
152
+ .pn-detail-label{color:var(--muted);font-size:.8rem}
153
+ .pn-detail-value{font-family:monospace;font-size:.8rem;color:var(--text);word-break:break-all}
154
+ .pn-agent-list{display:flex;flex-direction:column;gap:.3rem;margin:.5rem 0}
155
+ .pn-agent-item{font-family:monospace;font-size:.8rem;color:var(--love3);padding:.2rem .5rem;background:rgba(255,107,157,.08);border-radius:4px}
156
+ .pn-vis-toggle{display:flex;gap:2px;border-radius:6px;overflow:hidden;border:1px solid var(--border)}
157
+ .pn-vis-btn{padding:4px 12px;border:none;cursor:pointer;font-size:.75rem;font-weight:600;background:transparent;color:var(--muted);transition:all .2s}
158
+ .pn-vis-btn.active{background:var(--love1);color:#fff}
159
+ .pn-vis-btn:hover:not(.active){color:var(--text)}
160
+ .pn-setup{display:none;margin-top:.75rem;background:rgba(15,10,20,.6);border:1px solid rgba(255,107,157,.1);border-radius:8px;padding:1rem;font-size:.85rem;line-height:1.7}
161
+ .pn-setup.open{display:block}
162
+ .pn-setup ol{margin-left:1.5rem;margin-bottom:.5rem}
163
+ .pn-setup li{margin-bottom:.3rem;color:var(--muted)}
164
+ .pn-detach-btn{margin-top:.75rem;padding:6px 16px;background:transparent;color:var(--danger);border:1px solid var(--danger);border-radius:6px;cursor:pointer;font-size:.8rem;font-weight:600;transition:all .2s}
165
+ .pn-detach-btn:hover{background:rgba(239,68,68,.15)}
166
+
167
+ /* Agent CTA */
168
+ .agent-cta{background:linear-gradient(135deg,rgba(30,20,40,.95),rgba(50,20,50,.9));border:1px solid var(--border);border-radius:var(--radius);padding:1.5rem;margin-bottom:1.5rem}
169
+ .agent-cta h3{color:var(--love1);margin-bottom:.5rem;font-size:1.05rem}
170
+ .agent-cta p{font-size:.9rem;color:var(--muted);margin-bottom:.75rem}
171
+ .agent-prompt-box{position:relative;background:rgba(15,10,20,.8);border:1px solid rgba(255,107,157,.15);border-radius:8px;padding:1rem;font-family:monospace;font-size:.8rem;color:var(--text);white-space:pre-wrap;word-break:break-all;line-height:1.5;margin-bottom:1rem;max-height:300px;overflow-y:auto}
172
+ .copy-prompt-btn{background:var(--love2);color:#fff;border:none;border-radius:6px;padding:6px 14px;cursor:pointer;font-size:.8rem;font-weight:600;transition:all .2s}
173
+ .copy-prompt-btn:hover{background:var(--love1)}
174
+ .expand-btn{background:none;border:1px solid var(--border);color:var(--love4);border-radius:8px;padding:8px 16px;cursor:pointer;font-size:.85rem;font-weight:600;transition:all .2s;display:inline-flex;align-items:center;gap:6px}
175
+ .expand-btn:hover{border-color:var(--love1);color:var(--love1)}
176
+ .platform-instructions{display:none;margin-top:1rem}
177
+ .platform-instructions.expanded{display:block}
178
+ .platform-tabs{display:flex;gap:.25rem;flex-wrap:wrap;margin-bottom:1rem}
179
+ .platform-tab{padding:.5rem 1rem;background:var(--card);border:1px solid var(--border);border-radius:8px;cursor:pointer;color:var(--muted);font-size:.8rem;font-weight:600;transition:all .2s}
180
+ .platform-tab:hover{color:var(--text);border-color:var(--love4)}
181
+ .platform-tab.active{color:var(--love1);border-color:var(--love1);background:rgba(255,107,157,.1)}
182
+ .platform-content{background:rgba(15,10,20,.6);border:1px solid rgba(255,107,157,.1);border-radius:8px;padding:1.25rem;font-size:.85rem;line-height:1.7}
183
+ .platform-content ol{margin-left:1.5rem;margin-bottom:.75rem}
184
+ .platform-content li{margin-bottom:.4rem}
185
+ .platform-content code{background:rgba(255,107,157,.1);padding:1px 5px;border-radius:3px;font-size:.8rem;color:var(--love3)}
186
+ .platform-panel{display:none}
187
+ .platform-panel.active{display:block}
188
+
189
+ /* Empty state */
190
+ .empty{text-align:center;padding:2rem;color:var(--muted);font-size:.9rem}
191
+
192
+ /* Spinner */
193
+ .spinner{display:inline-block;width:18px;height:18px;border:2px solid var(--border);border-top-color:var(--love1);border-radius:50%;animation:spin .6s linear infinite;margin-right:.5rem;vertical-align:middle}
194
+ @keyframes spin{to{transform:rotate(360deg)}}
195
+ .loading-text{color:var(--muted);font-size:.9rem}
196
+
197
+ /* Language toggle */
198
+ .lang-toggle{display:flex;gap:2px;margin-right:.5rem}
199
+ .lang-btn{padding:4px 10px;border:1px solid var(--border);background:transparent;color:var(--muted);cursor:pointer;font-size:.75rem;font-weight:700;border-radius:4px;transition:all .2s}
200
+ .lang-btn:first-child{border-radius:4px 0 0 4px}
201
+ .lang-btn:last-child{border-radius:0 4px 4px 0}
202
+ .lang-btn.active{background:var(--love1);color:#fff;border-color:var(--love1)}
203
+ .lang-btn:hover{color:var(--text)}
204
+
205
+ /* Sub-tabs */
206
+ .sub-tabs{display:flex;gap:.25rem;margin-bottom:1rem}
207
+ .sub-tab{padding:.4rem .8rem;cursor:pointer;color:var(--muted);font-weight:600;font-size:.8rem;background:var(--card);border:1px solid var(--border);border-radius:6px;transition:all .2s}
208
+ .sub-tab:hover{color:var(--text)}
209
+ .sub-tab.active{color:var(--love1);border-color:var(--love1);background:rgba(255,107,157,.1)}
210
+ .sub-panel{display:none}
211
+ .sub-panel.active{display:block}
212
+
213
+ /* Action bar */
214
+ .action-bar{display:flex;justify-content:space-between;align-items:center;gap:.75rem;margin-bottom:1rem;flex-wrap:wrap}
215
+ .search-bar{display:flex;gap:.5rem;flex:1;max-width:500px}
216
+
217
+ /* Form elements */
218
+ .input-field{width:100%;padding:8px 12px;background:rgba(15,10,20,.8);border:1px solid var(--border);border-radius:6px;color:var(--text);font-size:.85rem;font-family:inherit}
219
+ .input-field:focus{outline:none;border-color:var(--love1)}
220
+ select.input-field{cursor:pointer}
221
+ textarea.input-field{resize:vertical;min-height:60px}
222
+
223
+ /* Create forms */
224
+ .create-form{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);padding:1.25rem;margin-bottom:1rem}
225
+ .form-row{margin-bottom:.75rem}
226
+ .form-row label{display:block;font-size:.8rem;color:var(--muted);margin-bottom:.3rem;font-weight:600}
227
+ .form-actions{display:flex;gap:.5rem;margin-top:1rem}
228
+
229
+ /* Buttons */
230
+ .btn-primary{background:linear-gradient(135deg,var(--love1),var(--love2));color:#fff;border:none;border-radius:6px;padding:8px 16px;cursor:pointer;font-size:.85rem;font-weight:600;transition:all .2s}
231
+ .btn-primary:hover{transform:translateY(-1px);box-shadow:0 4px 12px rgba(255,107,157,.3)}
232
+ .btn-sm{padding:6px 12px;border-radius:6px;cursor:pointer;font-size:.8rem;font-weight:600;background:var(--love2);color:#fff;border:none;transition:all .2s}
233
+ .btn-sm:hover{background:var(--love1)}
234
+ .btn-outline{padding:6px 12px;border-radius:6px;cursor:pointer;font-size:.8rem;font-weight:600;background:transparent;color:var(--muted);border:1px solid var(--border);transition:all .2s}
235
+ .btn-outline:hover{color:var(--text);border-color:var(--love4)}
236
+ .btn-danger{background:var(--danger);color:#fff;border:none;border-radius:6px;padding:6px 12px;cursor:pointer;font-size:.8rem;font-weight:600}
237
+ .btn-danger:hover{opacity:.8}
238
+ .btn-icon{background:none;border:none;cursor:pointer;font-size:1rem;padding:4px 6px;border-radius:4px;transition:all .2s}
239
+ .btn-icon:hover{background:rgba(255,107,157,.1)}
240
+
241
+ /* App gallery */
242
+ .app-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:1rem}
243
+ .app-card{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);overflow:hidden;transition:all .2s}
244
+ .app-card:hover{border-color:var(--love1);transform:translateY(-2px)}
245
+ .app-screenshot{width:100%;height:180px;object-fit:cover;background:rgba(15,10,20,.6);display:flex;align-items:center;justify-content:center}
246
+ .app-screenshot img{width:100%;height:100%;object-fit:cover}
247
+ .app-screenshot .placeholder{color:var(--muted);font-size:2rem}
248
+ .app-info{padding:1rem}
249
+ .app-info .app-name{font-weight:600;font-size:.95rem;margin-bottom:.3rem}
250
+ .app-info .app-meta{font-size:.75rem;color:var(--muted)}
251
+
252
+ /* Upload form */
253
+ .file-input-wrap{position:relative;display:inline-flex}
254
+ .file-input-wrap input[type=file]{position:absolute;inset:0;opacity:0;cursor:pointer}
255
+ .file-label{display:inline-flex;align-items:center;gap:.5rem;padding:8px 16px;background:var(--card);border:1px dashed var(--border);border-radius:8px;color:var(--muted);font-size:.85rem;cursor:pointer;transition:all .2s}
256
+ .file-label:hover{border-color:var(--love1);color:var(--text)}
257
+
258
+ /* File storage grid */
259
+ .file-grid{display:flex;flex-direction:column;gap:.5rem}
260
+ .file-card{display:flex;align-items:center;gap:1rem;padding:.75rem 1rem;background:var(--card);border:1px solid var(--border);border-radius:var(--radius);transition:all .2s}
261
+ .file-card:hover{border-color:var(--love1)}
262
+ .file-icon{font-size:1.5rem;min-width:2rem;text-align:center}
263
+ .file-info{flex:1;min-width:0}
264
+ .file-name{font-weight:600;font-size:.9rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
265
+ .file-meta{font-size:.75rem;color:var(--muted)}
266
+ .file-actions{display:flex;gap:.25rem;flex-shrink:0}
267
+
268
+ /* Board post */
269
+ .post-card{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);padding:1rem;margin-bottom:.75rem}
270
+ .post-content{font-size:.9rem;margin-bottom:.5rem;line-height:1.5}
271
+ .post-meta{font-size:.75rem;color:var(--muted);display:flex;justify-content:space-between;align-items:center}
272
+ .post-reactions{display:flex;gap:.4rem;margin-top:.5rem}
273
+ .reaction-btn{padding:2px 8px;border-radius:12px;border:1px solid var(--border);background:transparent;cursor:pointer;font-size:.8rem;transition:all .2s}
274
+ .reaction-btn:hover{border-color:var(--love1);background:rgba(255,107,157,.1)}
275
+ .reaction-btn.active{border-color:var(--love1);background:rgba(255,107,157,.15)}
276
+
277
+ /* Modal */
278
+ .modal-overlay{position:fixed;inset:0;background:rgba(0,0,0,.7);display:flex;align-items:center;justify-content:center;z-index:1000;backdrop-filter:blur(4px)}
279
+ .modal{background:var(--bg);border:1px solid var(--border);border-radius:var(--radius);padding:2rem;max-width:500px;width:90%;max-height:80vh;overflow-y:auto}
280
+ .modal h3{color:var(--love1);margin-bottom:1rem}
281
+
282
+ /* Toast notification */
283
+ .toast{position:fixed;bottom:2rem;left:50%;transform:translateX(-50%);background:var(--success);color:#fff;padding:.75rem 1.5rem;border-radius:8px;font-weight:600;font-size:.85rem;z-index:2000;animation:toastIn .3s ease,toastOut .3s ease 2.5s forwards}
284
+ .toast.error{background:var(--danger)}
285
+ @keyframes toastIn{from{opacity:0;transform:translateX(-50%) translateY(20px)}to{opacity:1;transform:translateX(-50%) translateY(0)}}
286
+ @keyframes toastOut{from{opacity:1}to{opacity:0}}
287
+
288
+ /* Pagination */
289
+ .pagination{display:flex;justify-content:center;gap:.5rem;margin-top:1rem}
290
+ .page-btn{padding:4px 12px;border-radius:6px;border:1px solid var(--border);background:transparent;color:var(--muted);cursor:pointer;font-size:.8rem}
291
+ .page-btn.active{background:var(--love1);color:#fff;border-color:var(--love1)}
292
+ .page-btn:hover{border-color:var(--love4)}
293
+
294
+ /* Star rating */
295
+ .star-rating{display:flex;gap:.25rem}
296
+ .star{font-size:1.5rem;cursor:pointer;color:var(--muted);transition:color .15s}
297
+ .star:hover,.star.active{color:var(--warn)}
298
+
299
+ /* Responsive */
300
+ @media(max-width:600px){
301
+ .profile-header{flex-direction:column;text-align:center}
302
+ .stats-bar{grid-template-columns:repeat(2,1fr)}
303
+ .wallet-overview{grid-template-columns:repeat(2,1fr)}
304
+ .topbar{flex-direction:column;gap:.5rem;text-align:center}
305
+ .action-bar{flex-direction:column;align-items:stretch}
306
+ .search-bar{max-width:100%}
307
+ .app-grid{grid-template-columns:1fr}
308
+ }
309
+ </style>
310
+ </head>
311
+ <body>
312
+
313
+ <!-- Background -->
314
+ <div class="bg-layer bg-aurora">
315
+ <div class="aurora-wave"></div>
316
+ <div class="aurora-wave"></div>
317
+ <div class="aurora-wave"></div>
318
+ </div>
319
+
320
+ <!-- Top bar -->
321
+ <div class="topbar">
322
+ <div class="topbar-left">
323
+ <a href="/v1/portal">\u{1F496} AIMEAT</a>
324
+ <span style="color:var(--muted);font-weight:400;font-size:.85rem">/&nbsp;${sanitize(translations['profile.subtitle'] || 'Profile')}</span>
325
+ </div>
326
+ <div class="topbar-right">
327
+ <div class="lang-toggle">
328
+ <button class="lang-btn ${locale === 'fi' ? 'active' : ''}" onclick="switchLang('fi')">FI</button>
329
+ <button class="lang-btn ${locale === 'en' ? 'active' : ''}" onclick="switchLang('en')">EN</button>
330
+ </div>
331
+ <div id="auth-container"></div>
332
+ </div>
333
+ </div>
334
+
335
+ <!-- Not logged in state -->
336
+ <div class="container" id="login-screen">
337
+ <div class="login-prompt">
338
+ <h1>\u{1F496} <span id="login-title">${sanitize(translations['profile.signInTitle'] || 'Your AIMEAT Profile')}</span></h1>
339
+ <p id="login-desc">${sanitize(translations['profile.signInDesc'] || 'Sign in to see your agents, wallet, memory, work history, and more.')}</p>
340
+ <div id="login-area"></div>
341
+ </div>
342
+ </div>
343
+
344
+ <!-- Logged in profile -->
345
+ <div class="container" id="profile-screen" style="display:none">
346
+ <!-- Profile header -->
347
+ <div class="profile-header">
348
+ <div class="avatar" id="avatar">\u{1F9D1}</div>
349
+ <div class="profile-info">
350
+ <h1 id="display-name">${sanitize(translations['profile.loading'] || 'Loading...')}</h1>
351
+ <div class="ghii" id="ghii-label"></div>
352
+ <div class="meta" id="profile-meta"></div>
353
+ </div>
354
+ </div>
355
+
356
+ <!-- Stats bar -->
357
+ <div class="stats-bar" id="stats-bar">
358
+ <div class="stat-card"><div class="num" id="stat-agents">-</div><div class="label">${sanitize(translations['profile.stats.agents'] || 'Agents')}</div></div>
359
+ <div class="stat-card"><div class="num" id="stat-chatsessions">-</div><div class="label">${sanitize(translations['profile.stats.chatSessions'] || 'Chat Sessions')}</div></div>
360
+ <div class="stat-card"><div class="num" id="stat-balance">-</div><div class="label">${sanitize(translations['profile.stats.morsels'] || 'Morsels')}</div></div>
361
+ <div class="stat-card"><div class="num" id="stat-memory">-</div><div class="label">${sanitize(translations['profile.stats.memories'] || 'Memories')}</div></div>
362
+ <div class="stat-card"><div class="num" id="stat-actions">-</div><div class="label">${sanitize(translations['profile.stats.services'] || 'Services')}</div></div>
363
+ <div class="stat-card"><div class="num" id="stat-work">-</div><div class="label">${sanitize(translations['profile.stats.tasks'] || 'Tasks')}</div></div>
364
+ <div class="stat-card"><div class="num" id="stat-apps">-</div><div class="label">${sanitize(translations['profile.stats.apps'] || 'Apps')}</div></div>
365
+ <div class="stat-card"><div class="num" id="stat-files">-</div><div class="label">${sanitize(translations['profile.stats.files'] || 'Files')}</div></div>
366
+ <div class="stat-card"><div class="num" id="stat-nodes">-</div><div class="label">${sanitize(translations['profile.stats.nodes'] || 'Nodes')}</div></div>
367
+ </div>
368
+
369
+ <!-- Tabs -->
370
+ <div class="tabs" id="tabs">
371
+ <button class="tab active" data-tab="agents">${sanitize(translations['profile.tabs.agents'] || 'Agents')}</button>
372
+ <button class="tab" data-tab="chatsessions">${sanitize(translations['profile.tabs.chatSessions'] || 'Chat Sessions')}</button>
373
+ <button class="tab" data-tab="wallet">${sanitize(translations['profile.tabs.wallet'] || 'Wallet')}</button>
374
+ <button class="tab" data-tab="memory">${sanitize(translations['profile.tabs.memory'] || 'Memory')}</button>
375
+ <button class="tab" data-tab="work">${sanitize(translations['profile.tabs.work'] || 'Work')}</button>
376
+ <button class="tab" data-tab="actions">${sanitize(translations['profile.tabs.services'] || 'Services')}</button>
377
+ <button class="tab" data-tab="boards">${sanitize(translations['profile.tabs.boards'] || 'Boards')}</button>
378
+ <button class="tab" data-tab="apps">${sanitize(translations['profile.tabs.apps'] || 'Apps')}</button>
379
+ <button class="tab" data-tab="federation">${sanitize(translations['profile.tabs.federation'] || 'Federation')}</button>
380
+ <button class="tab" data-tab="nodes">${sanitize(translations['profile.tabs.nodes'] || 'Nodes')}</button>
381
+ <button class="tab" data-tab="access">${sanitize(translations['profile.tabs.access'] || 'Access')}</button>
382
+ </div>
383
+
384
+ <!-- Tab panels -->
385
+
386
+ <!-- ═══ AGENTS ═══ -->
387
+ <div class="tab-panel active" id="panel-agents">
388
+ <div class="section-title">${sanitize(translations['profile.agents.title'] || 'Your Agents')}</div>
389
+ <div class="section-desc">${sanitize(translations['profile.agents.desc'] || '')}</div>
390
+
391
+ <!-- Agent CTA -->
392
+ <div class="agent-cta" id="agent-cta">
393
+ <h3>${sanitize(translations['profile.agents.connect'] || 'Connect an Automation Agent')}</h3>
394
+ <p>${sanitize(translations['profile.agents.connectDesc'] || '')}</p>
395
+ <div class="agent-prompt-box" id="agent-connect-prompt">${sanitize(translations['profile.agents.loadingPrompt'] || 'Loading prompt...')}</div>
396
+ <button class="copy-prompt-btn" onclick="copyAgentPrompt()">${sanitize(translations['profile.agents.copyPrompt'] || 'Copy Prompt')}</button>
397
+
398
+ <div style="margin-top:1.25rem;border-top:1px solid var(--border);padding-top:1.25rem">
399
+ <p style="margin-bottom:.75rem">${sanitize(translations['profile.agents.noAgent'] || 'Don\'t have an automation agent yet?')}</p>
400
+ <button class="expand-btn" onclick="toggleInstructions(this)">${sanitize(translations['profile.agents.seeHow'] || 'See how to get one')} <span style="transition:transform .2s">\u25BC</span></button>
401
+ <div class="platform-instructions" id="platform-instructions">
402
+ <div class="platform-tabs" id="platform-tabs">
403
+ <button class="platform-tab active" data-platform="windows">${sanitize(translations['profile.platforms.windows'] || 'Windows')}</button>
404
+ <button class="platform-tab" data-platform="mac">${sanitize(translations['profile.platforms.mac'] || 'macOS')}</button>
405
+ <button class="platform-tab" data-platform="linux">${sanitize(translations['profile.platforms.linux'] || 'Linux')}</button>
406
+ <button class="platform-tab" data-platform="wsl2">${sanitize(translations['profile.platforms.wsl2'] || 'WSL2')}</button>
407
+ <button class="platform-tab" data-platform="android">${sanitize(translations['profile.platforms.android'] || 'Android')}</button>
408
+ <button class="platform-tab" data-platform="aws">${sanitize(translations['profile.platforms.aws'] || 'AWS / Cloud')}</button>
409
+ </div>
410
+ <div id="platform-panels"></div>
411
+ </div>
412
+ </div>
413
+ </div>
414
+
415
+ <div id="agents-list"><span class="spinner"></span><span class="loading-text">${sanitize(translations['profile.agents.loadingAgents'] || 'Loading agents...')}</span></div>
416
+ </div>
417
+
418
+ <!-- ═══ CHAT SESSIONS ═══ -->
419
+ <div class="tab-panel" id="panel-chatsessions">
420
+ <div class="section-title">${sanitize(translations['profile.chatSessions.title'] || 'Chat Sessions')}</div>
421
+ <div class="section-desc">${sanitize(translations['profile.chatSessions.desc'] || '')}</div>
422
+ <div id="chatsessions-list"><span class="spinner"></span><span class="loading-text">${sanitize(translations['profile.chatSessions.loading'] || 'Loading chat sessions...')}</span></div>
423
+ </div>
424
+
425
+ <!-- ═══ WALLET ═══ -->
426
+ <div class="tab-panel" id="panel-wallet">
427
+ <div class="section-title">${sanitize(translations['profile.wallet.title'] || 'Wallet')}</div>
428
+ <div class="section-desc">${sanitize(translations['profile.wallet.desc'] || '')}</div>
429
+ <div id="wallet-area"><span class="spinner"></span><span class="loading-text">${sanitize(translations['profile.wallet.loading'] || 'Loading wallet...')}</span></div>
430
+ </div>
431
+
432
+ <!-- ═══ MEMORY ═══ -->
433
+ <div class="tab-panel" id="panel-memory">
434
+ <div class="section-title">${sanitize(translations['profile.memory.title'] || 'Memory')}</div>
435
+ <div class="section-desc">${sanitize(translations['profile.memory.desc'] || '')}</div>
436
+ <div class="sub-tabs" id="memory-sub-tabs">
437
+ <button class="sub-tab active" data-subtab="memory-entries">${sanitize(translations['profile.memory.entries'] || 'Entries')}</button>
438
+ <button class="sub-tab" data-subtab="memory-files">${sanitize(translations['profile.memory.files'] || 'Files')}</button>
439
+ </div>
440
+ <div class="sub-panel active" id="subpanel-memory-entries">
441
+ <div class="action-bar">
442
+ <div class="search-bar">
443
+ <input type="text" id="memory-search" placeholder="${sanitize(translations['profile.memory.search'] || 'Search memories...')}" class="input-field">
444
+ <button class="btn-sm" onclick="searchMemory()">${sanitize(translations['profile.memory.searchBtn'] || 'Search')}</button>
445
+ <button class="btn-sm btn-outline" onclick="loadMemory()">${sanitize(translations['profile.memory.clearBtn'] || 'Clear')}</button>
446
+ </div>
447
+ <button class="btn-primary" onclick="toggleMemoryForm()">${sanitize(translations['profile.memory.newBtn'] || '+ New Memory')}</button>
448
+ </div>
449
+ <div class="create-form" id="memory-form" style="display:none">
450
+ <div class="form-row"><label>${sanitize(translations['profile.memory.keyLabel'] || 'Key')}</label><input type="text" id="mem-key" class="input-field" placeholder="${sanitize(translations['profile.memory.keyPlaceholder'] || 'my-preference')}"></div>
451
+ <div class="form-row"><label>${sanitize(translations['profile.memory.valueLabel'] || 'Value')}</label><textarea id="mem-value" class="input-field" rows="3" placeholder="${sanitize(translations['profile.memory.valuePlaceholder'] || 'The value to store...')}"></textarea></div>
452
+ <div class="form-row"><label>${sanitize(translations['profile.memory.visLabel'] || 'Visibility')}</label><select id="mem-vis" class="input-field"><option value="private">${sanitize(translations['profile.memory.visPrivate'] || 'Private')}</option><option value="shared">${sanitize(translations['profile.memory.visShared'] || 'Shared')}</option><option value="public">${sanitize(translations['profile.memory.visPublic'] || 'Public')}</option></select></div>
453
+ <div class="form-row"><label>${sanitize(translations['profile.memory.tagsLabel'] || 'Tags')}</label><input type="text" id="mem-tags" class="input-field" placeholder="${sanitize(translations['profile.memory.tagsPlaceholder'] || 'tag1, tag2 (optional)')}"></div>
454
+ <div class="form-actions"><button class="btn-primary" onclick="createMemory()">${sanitize(translations['profile.memory.saveBtn'] || 'Save')}</button><button class="btn-outline" onclick="toggleMemoryForm()">${sanitize(translations['profile.memory.cancelBtn'] || 'Cancel')}</button></div>
455
+ </div>
456
+ <div id="memory-list"><span class="spinner"></span><span class="loading-text">${sanitize(translations['profile.memory.loading'] || 'Loading memories...')}</span></div>
457
+ </div>
458
+ <div class="sub-panel" id="subpanel-memory-files">
459
+ <div class="action-bar">
460
+ <button class="btn-primary" onclick="toggleFileForm()">${sanitize(translations['profile.files.uploadBtn'] || '+ Upload File')}</button>
461
+ <span class="muted-text" style="font-size:.75rem;color:var(--muted)">${sanitize(translations['profile.files.sizeLimit'] || 'Max 10MB per file')}</span>
462
+ </div>
463
+ <div class="create-form" id="file-form" style="display:none">
464
+ <div class="form-row"><label>${sanitize(translations['profile.files.keyLabel'] || 'File Name')} <span style="font-weight:normal;font-size:.75rem;color:var(--muted)">${sanitize(translations['profile.files.nameNote'] || '(must be unique per user)')}</span></label><input type="text" id="file-key" class="input-field" placeholder="${sanitize(translations['profile.files.keyPlaceholder'] || 'document.pdf')}"></div>
465
+ <div class="form-row"><label>${sanitize(translations['profile.files.fileLabel'] || 'File')}</label><input type="file" id="file-input" class="input-field" onchange="if(this.files[0]&&!document.getElementById('file-key').value){document.getElementById('file-key').value=this.files[0].name}"></div>
466
+ <div class="form-row"><label>${sanitize(translations['profile.files.visLabel'] || 'Visibility')}</label><select id="file-vis" class="input-field"><option value="private">${sanitize(translations['profile.files.visPrivate'] || 'Private')}</option><option value="owner">${sanitize(translations['profile.files.visOwner'] || 'Owner')}</option><option value="public">${sanitize(translations['profile.files.visPublic'] || 'Public')}</option></select></div>
467
+ <div class="form-actions"><button class="btn-primary" onclick="uploadFile()">${sanitize(translations['profile.files.uploadSaveBtn'] || 'Upload')}</button><button class="btn-outline" onclick="toggleFileForm()">${sanitize(translations['profile.files.cancelBtn'] || 'Cancel')}</button></div>
468
+ </div>
469
+ <div id="files-list"><span class="spinner"></span><span class="loading-text">${sanitize(translations['profile.files.loading'] || 'Loading files...')}</span></div>
470
+ </div>
471
+ </div>
472
+
473
+ <!-- ═══ WORK ═══ -->
474
+ <div class="tab-panel" id="panel-work">
475
+ <div class="section-title">${sanitize(translations['profile.work.title'] || 'Work History')}</div>
476
+ <div class="section-desc">${sanitize(translations['profile.work.desc'] || '')}</div>
477
+ <div class="sub-tabs" id="work-sub-tabs">
478
+ <button class="sub-tab active" data-subtab="work-inbox">${sanitize(translations['profile.work.inbox'] || 'Inbox')}</button>
479
+ <button class="sub-tab" data-subtab="work-sent">${sanitize(translations['profile.work.sent'] || 'Sent')}</button>
480
+ </div>
481
+ <div class="sub-panel active" id="subpanel-work-inbox">
482
+ <div id="work-list"><span class="spinner"></span><span class="loading-text">${sanitize(translations['profile.work.loading'] || 'Loading work items...')}</span></div>
483
+ </div>
484
+ <div class="sub-panel" id="subpanel-work-sent">
485
+ <div id="work-sent-list"><span class="spinner"></span><span class="loading-text">${sanitize(translations['profile.work.loading'] || 'Loading work items...')}</span></div>
486
+ </div>
487
+ </div>
488
+
489
+ <!-- ═══ SERVICES ═══ -->
490
+ <div class="tab-panel" id="panel-actions">
491
+ <div class="section-title">${sanitize(translations['profile.services.title'] || 'Services')}</div>
492
+ <div class="section-desc">${sanitize(translations['profile.services.desc'] || '')}</div>
493
+ <div class="sub-tabs" id="services-sub-tabs">
494
+ <button class="sub-tab active" data-subtab="services-mine">${sanitize(translations['profile.services.mine'] || 'My Services')}</button>
495
+ <button class="sub-tab" data-subtab="services-catalogue">${sanitize(translations['profile.services.catalogue'] || 'Catalogue')}</button>
496
+ </div>
497
+ <div class="sub-panel active" id="subpanel-services-mine">
498
+ <button class="btn-primary" onclick="togglePublishForm()" style="margin-bottom:1rem">${sanitize(translations['profile.services.publishBtn'] || '+ Publish Service')}</button>
499
+ <div class="create-form" id="publish-form" style="display:none">
500
+ <div class="form-row"><label>${sanitize(translations['profile.services.nameLabel'] || 'Display Name')}</label><input type="text" id="svc-name" class="input-field" placeholder="${sanitize(translations['profile.services.namePlaceholder'] || 'My Translation Service')}"></div>
501
+ <div class="form-row"><label>${sanitize(translations['profile.services.descLabel'] || 'Description')}</label><textarea id="svc-desc" class="input-field" rows="3" placeholder="${sanitize(translations['profile.services.descPlaceholder'] || 'What this service does...')}"></textarea></div>
502
+ <div class="form-row"><label>${sanitize(translations['profile.services.categoryLabel'] || 'Category')}</label><select id="svc-category" class="input-field"><option value="language">Language</option><option value="translation">Translation</option><option value="analysis">Analysis</option><option value="generation">Generation</option><option value="coding">Coding</option><option value="data">Data</option><option value="image">Image</option><option value="audio">Audio</option><option value="video">Video</option><option value="search">Search</option><option value="utility">Utility</option><option value="other">Other</option></select></div>
503
+ <div class="form-row"><label>${sanitize(translations['profile.services.priceLabel'] || 'Price (morsels)')}</label><input type="number" id="svc-price" class="input-field" value="0" min="0"></div>
504
+ <div class="form-row"><label>${sanitize(translations['profile.services.unitLabel'] || 'Unit')}</label><select id="svc-unit" class="input-field"><option value="call">Per call</option><option value="minute">Per minute</option><option value="token">Per token</option><option value="task">Per task</option></select></div>
505
+ <div class="form-row"><label>${sanitize(translations['profile.services.webhookLabel'] || 'Webhook URL (optional)')}</label><input type="text" id="svc-webhook" class="input-field" placeholder="${sanitize(translations['profile.services.webhookPlaceholder'] || 'https://...')}"></div>
506
+ <div class="form-actions"><button class="btn-primary" onclick="publishService()">${sanitize(translations['profile.services.publishSaveBtn'] || 'Publish')}</button><button class="btn-outline" onclick="togglePublishForm()">${sanitize(translations['profile.cancel'] || 'Cancel')}</button></div>
507
+ </div>
508
+ <div id="actions-list"><span class="spinner"></span><span class="loading-text">${sanitize(translations['profile.services.loading'] || 'Loading services...')}</span></div>
509
+ </div>
510
+ <div class="sub-panel" id="subpanel-services-catalogue">
511
+ <div class="action-bar"><select id="cat-filter" class="input-field" style="max-width:200px" onchange="loadCatalogue()"><option value="">${sanitize(translations['profile.services.allCategories'] || 'All Categories')}</option><option value="language">Language</option><option value="translation">Translation</option><option value="analysis">Analysis</option><option value="generation">Generation</option><option value="coding">Coding</option><option value="data">Data</option><option value="image">Image</option><option value="audio">Audio</option><option value="video">Video</option><option value="search">Search</option><option value="utility">Utility</option><option value="other">Other</option></select></div>
512
+ <div id="catalogue-list"><span class="spinner"></span><span class="loading-text">${sanitize(translations['profile.services.loading'] || 'Loading services...')}</span></div>
513
+ </div>
514
+ </div>
515
+
516
+ <!-- ═══ BOARDS ═══ -->
517
+ <div class="tab-panel" id="panel-boards">
518
+ <div class="section-title">${sanitize(translations['profile.boards.title'] || 'Boards')}</div>
519
+ <div class="section-desc">${sanitize(translations['profile.boards.desc'] || '')}</div>
520
+ <div class="sub-tabs" id="boards-sub-tabs">
521
+ <button class="sub-tab active" data-subtab="boards-mine">${sanitize(translations['profile.boards.mine'] || 'My Boards')}</button>
522
+ <button class="sub-tab" data-subtab="boards-browse">${sanitize(translations['profile.boards.browse'] || 'Browse All')}</button>
523
+ </div>
524
+ <div class="sub-panel active" id="subpanel-boards-mine">
525
+ <button class="btn-primary" onclick="toggleBoardForm()" style="margin-bottom:1rem">${sanitize(translations['profile.boards.createBtn'] || '+ Create Board')}</button>
526
+ <div class="create-form" id="board-create-form" style="display:none">
527
+ <div class="form-row"><label>${sanitize(translations['profile.boards.nameLabel'] || 'Board Name')}</label><input type="text" id="board-name" class="input-field" placeholder="${sanitize(translations['profile.boards.namePlaceholder'] || 'My Discussion Board')}"></div>
528
+ <div class="form-row"><label>${sanitize(translations['profile.boards.descLabel'] || 'Description')}</label><input type="text" id="board-desc" class="input-field" placeholder="${sanitize(translations['profile.boards.descPlaceholder'] || 'What this board is about...')}"></div>
529
+ <div class="form-row"><label>${sanitize(translations['profile.boards.visLabel'] || 'Visibility')}</label><select id="board-vis" class="input-field"><option value="private">${sanitize(translations['profile.boards.visPrivate'] || 'Private')}</option><option value="public">${sanitize(translations['profile.boards.visPublic'] || 'Public (operators only)')}</option></select></div>
530
+ <div class="form-actions"><button class="btn-primary" onclick="createBoard()">${sanitize(translations['profile.boards.createSaveBtn'] || 'Create')}</button><button class="btn-outline" onclick="toggleBoardForm()">${sanitize(translations['profile.cancel'] || 'Cancel')}</button></div>
531
+ </div>
532
+ <div id="boards-list"><span class="spinner"></span><span class="loading-text">${sanitize(translations['profile.boards.loading'] || 'Loading boards...')}</span></div>
533
+ </div>
534
+ <div class="sub-panel" id="subpanel-boards-browse">
535
+ <div id="boards-browse-list"><span class="spinner"></span><span class="loading-text">${sanitize(translations['profile.boards.browseLoading'] || 'Loading boards...')}</span></div>
536
+ </div>
537
+ </div>
538
+
539
+ <!-- ═══ APPS ═══ -->
540
+ <div class="tab-panel" id="panel-apps">
541
+ <div class="section-title">${sanitize(translations['profile.apps.title'] || 'Apps')}</div>
542
+ <div class="section-desc">${sanitize(translations['profile.apps.desc'] || '')}</div>
543
+ <div class="sub-tabs" id="apps-sub-tabs">
544
+ <button class="sub-tab active" data-subtab="apps-mine">${sanitize(translations['profile.apps.mine'] || 'My Apps')}</button>
545
+ <button class="sub-tab" data-subtab="apps-gallery">${sanitize(translations['profile.apps.gallery'] || 'All Apps')}</button>
546
+ </div>
547
+ <div class="sub-panel active" id="subpanel-apps-mine">
548
+ <div style="background:linear-gradient(135deg, rgba(251,191,36,.1), rgba(245,158,11,.05));border:1px solid rgba(251,191,36,.3);border-radius:var(--radius);padding:1.25rem;margin-bottom:1.25rem">
549
+ <div style="display:flex;align-items:center;gap:.6rem;margin-bottom:.5rem">
550
+ <span style="font-size:1.3rem">\ud83d\ude80</span>
551
+ <span style="font-weight:700;font-size:1rem;color:#fbbf24">${sanitize(translations['profile.apps.launcherTitle'] || 'App Launcher')}</span>
552
+ </div>
553
+ <div style="font-size:.85rem;color:var(--muted);margin-bottom:1rem">${sanitize(translations['profile.apps.launcherDesc'] || 'Manage all your apps in one place. Pin favorites, search by tags, publish to your node.')}</div>
554
+ <a href="/app-catalog.html" class="btn-primary" style="text-decoration:none;display:inline-flex;align-items:center;gap:.4rem;background:linear-gradient(135deg,#f59e0b,#d97706)">\ud83d\ude80 ${sanitize(translations['profile.apps.launcherOpen'] || 'Open App Catalog')}</a>
555
+ </div>
556
+ <div class="app-create-guide" style="background:var(--card);border:1px solid var(--border);border-radius:var(--radius);padding:1.25rem;margin-bottom:1.25rem">
557
+ <div style="font-weight:700;font-size:1rem;margin-bottom:.5rem;color:var(--love1)">${sanitize(translations['profile.apps.createGuide'] || 'Create a New App')}</div>
558
+ <div style="font-size:.85rem;color:var(--muted);margin-bottom:1rem">${sanitize(translations['profile.apps.createGuideDesc'] || '')}</div>
559
+ <div style="display:flex;gap:.75rem;flex-wrap:wrap;align-items:center;margin-bottom:1rem">
560
+ <a href="/v1/aimeat-os.md" download class="btn-primary" style="text-decoration:none;display:inline-flex;align-items:center;gap:.4rem">\ud83d\udcd6 ${sanitize(translations['profile.apps.downloadGuide'] || 'Download AIMEAT-OS.md')}</a>
561
+ <button class="btn-outline" onclick="copyAppPrompt()">\ud83d\udccb ${sanitize(translations['profile.apps.copyPrompt'] || 'Copy App Creation Prompt')}</button>
562
+ </div>
563
+ <div style="font-size:.75rem;color:var(--muted)">${sanitize(translations['profile.apps.guideDesc'] || '')}</div>
564
+ </div>
565
+ <button class="btn-primary" onclick="toggleUploadForm()" style="margin-bottom:1rem">${sanitize(translations['profile.apps.uploadBtn'] || '+ Add New App')}</button>
566
+ <div class="create-form" id="upload-form" style="display:none">
567
+ <div class="form-row"><label>${sanitize(translations['profile.apps.fileLabel'] || 'HTML File')}</label><div class="file-input-wrap"><label class="file-label" id="app-file-label">${sanitize(translations['profile.apps.filePlaceholder'] || 'Choose HTML file...')}<input type="file" id="app-file" accept=".html,.htm" onchange="this.parentElement.querySelector('.file-label')&&(document.getElementById('app-file-label').textContent=this.files[0]?this.files[0].name:'${sanitize(translations['profile.apps.filePlaceholder'] || 'Choose HTML file...')}')"></label></div></div>
568
+ <div class="form-row"><label>${sanitize(translations['profile.apps.screenshotLabel'] || 'Screenshot (optional)')}</label><div class="file-input-wrap"><label class="file-label" id="app-ss-label">${sanitize(translations['profile.apps.screenshotPlaceholder'] || 'Choose screenshot...')}<input type="file" id="app-screenshot" accept="image/*" onchange="document.getElementById('app-ss-label').textContent=this.files[0]?this.files[0].name:'${sanitize(translations['profile.apps.screenshotPlaceholder'] || 'Choose screenshot...')}'"></label></div></div>
569
+ <div class="form-row"><label>${sanitize(translations['profile.apps.accessCodeLabel'] || 'Access Code (optional)')}</label><input type="text" id="app-access-code" class="input-field" placeholder="${sanitize(translations['profile.apps.accessCodePlaceholder'] || 'Leave empty for public')}"></div>
570
+ <div class="form-actions"><button class="btn-primary" onclick="uploadApp()">${sanitize(translations['profile.apps.uploadSaveBtn'] || 'Send')}</button><button class="btn-outline" onclick="toggleUploadForm()">${sanitize(translations['profile.cancel'] || 'Cancel')}</button></div>
571
+ </div>
572
+ <div id="apps-list"><span class="spinner"></span><span class="loading-text">${sanitize(translations['profile.apps.loading'] || 'Loading apps...')}</span></div>
573
+ </div>
574
+ <div class="sub-panel" id="subpanel-apps-gallery">
575
+ <div id="apps-gallery-list"><span class="spinner"></span><span class="loading-text">${sanitize(translations['profile.apps.galleryLoading'] || 'Loading apps...')}</span></div>
576
+ </div>
577
+ </div>
578
+
579
+ <!-- ═══ FEDERATION ═══ -->
580
+ <div class="tab-panel" id="panel-federation">
581
+ <div class="section-title">${sanitize(translations['profile.federation.title'] || 'Federation & Peers')}</div>
582
+ <div class="section-desc">${sanitize(translations['profile.federation.desc'] || '')}</div>
583
+ <div id="federation-area"><span class="spinner"></span><span class="loading-text">${sanitize(translations['profile.federation.loading'] || 'Loading federation info...')}</span></div>
584
+ </div>
585
+
586
+ <!-- ═══ PERSONAL NODES ═══ -->
587
+ <div class="tab-panel" id="panel-nodes">
588
+ <div class="section-title">${sanitize(translations['profile.nodes.title'] || 'Personal Nodes')}</div>
589
+ <div class="section-desc">${sanitize(translations['profile.nodes.desc'] || '')}</div>
590
+
591
+ <!-- Add Node button -->
592
+ <button class="expand-btn" id="add-node-btn" onclick="toggleAddNodeForm()" style="margin-bottom:1.25rem">${sanitize(translations['profile.nodes.addBtn'] || '+ Add Node')}</button>
593
+
594
+ <!-- Add Node form (hidden) -->
595
+ <div id="add-node-form" style="display:none">
596
+ <div class="card" style="border-color:var(--love1);margin-bottom:1.5rem">
597
+ <h3 style="color:var(--love1);margin-bottom:1rem;font-size:1rem">${sanitize(translations['profile.nodes.addTitle'] || 'Register a Personal Node')}</h3>
598
+ <div style="margin-bottom:.75rem">
599
+ <label style="font-size:.8rem;color:var(--muted);display:block;margin-bottom:.3rem">${sanitize(translations['profile.nodes.nodeIdLabel'] || 'Node ID')}</label>
600
+ <input id="node-id-input" type="text" placeholder="${sanitize(translations['profile.nodes.nodeIdPlaceholder'] || 'personal-my-laptop')}" style="width:100%;padding:8px 12px;background:rgba(15,10,20,.8);border:1px solid var(--border);border-radius:8px;color:var(--text);font-family:monospace;font-size:.85rem">
601
+ </div>
602
+ <div style="margin-bottom:.75rem">
603
+ <label style="font-size:.8rem;color:var(--muted);display:block;margin-bottom:.3rem">${sanitize(translations['profile.nodes.visLabel'] || 'Visibility')}</label>
604
+ <div style="display:flex;gap:1rem">
605
+ <label style="display:flex;align-items:center;gap:.4rem;cursor:pointer;font-size:.85rem">
606
+ <input type="radio" name="node-vis" value="private" checked style="accent-color:var(--love1)"> ${sanitize(translations['profile.nodes.private'] || 'Private')}
607
+ <span style="font-size:.75rem;color:var(--muted)">\u2014 ${sanitize(translations['profile.nodes.privateDesc'] || 'Hidden from federation')}</span>
608
+ </label>
609
+ <label style="display:flex;align-items:center;gap:.4rem;cursor:pointer;font-size:.85rem">
610
+ <input type="radio" name="node-vis" value="public" style="accent-color:var(--love1)"> ${sanitize(translations['profile.nodes.public'] || 'Public')}
611
+ <span style="font-size:.75rem;color:var(--muted)">\u2014 ${sanitize(translations['profile.nodes.publicDesc'] || 'Discoverable')}</span>
612
+ </label>
613
+ </div>
614
+ </div>
615
+ <div style="margin-bottom:1rem">
616
+ <label style="font-size:.8rem;color:var(--muted);display:block;margin-bottom:.3rem">${sanitize(translations['profile.nodes.agentGaiisLabel'] || 'Agent GAIIs')}</label>
617
+ <input id="node-gaiis-input" type="text" placeholder="${sanitize(translations['profile.nodes.agentGaiisPlaceholder'] || 'bot1#owner, bot2#owner')}" style="width:100%;padding:8px 12px;background:rgba(15,10,20,.8);border:1px solid var(--border);border-radius:8px;color:var(--text);font-size:.85rem">
618
+ </div>
619
+ <div style="display:flex;gap:.75rem">
620
+ <button onclick="registerNode()" style="padding:8px 20px;background:linear-gradient(135deg,var(--love1),var(--love2));color:#fff;border:none;border-radius:8px;cursor:pointer;font-weight:600;font-size:.85rem">${sanitize(translations['profile.nodes.registerBtn'] || 'Register')}</button>
621
+ <button onclick="toggleAddNodeForm()" style="padding:8px 20px;background:transparent;color:var(--muted);border:1px solid var(--border);border-radius:8px;cursor:pointer;font-size:.85rem">${sanitize(translations['profile.nodes.cancelBtn'] || 'Cancel')}</button>
622
+ </div>
623
+ </div>
624
+ </div>
625
+
626
+ <div id="nodes-list"><span class="spinner"></span><span class="loading-text">${sanitize(translations['profile.nodes.loading'] || 'Loading...')}</span></div>
627
+ </div>
628
+
629
+ <!-- ═══ ACCESS ═══ -->
630
+ <div class="tab-panel" id="panel-access">
631
+ <div class="section-title">${sanitize(translations['profile.access.title'] || 'Access Codes & Tokens')}</div>
632
+ <div class="section-desc">${sanitize(translations['profile.access.desc'] || '')}</div>
633
+ <div id="access-area"><span class="spinner"></span><span class="loading-text">${sanitize(translations['profile.access.loading'] || 'Loading access info...')}</span></div>
634
+ </div>
635
+ </div>
636
+
637
+ <script>
638
+ var NODE_URL = ${JSON.stringify(config.baseUrl)};
639
+ var session = null;
640
+
641
+ // ── Clipboard helper (fallback for HTTP) ──
642
+ function copyToClipboard(text) {
643
+ if (navigator.clipboard && navigator.clipboard.writeText) {
644
+ return navigator.clipboard.writeText(text).catch(function() { return fallbackCopy(text); });
645
+ }
646
+ return fallbackCopy(text);
647
+ }
648
+ function fallbackCopy(text) {
649
+ var ta = document.createElement('textarea');
650
+ ta.value = text;
651
+ ta.style.position = 'fixed';
652
+ ta.style.left = '-9999px';
653
+ document.body.appendChild(ta);
654
+ ta.select();
655
+ try { document.execCommand('copy'); } catch(e) {}
656
+ document.body.removeChild(ta);
657
+ return Promise.resolve();
658
+ }
659
+
660
+ // ── i18n helper ──
661
+ function t(key) { return T[key] || key; }
662
+
663
+ function switchLang(lang) {
664
+ var url = new URL(window.location.href);
665
+ url.searchParams.set('lang', lang);
666
+ localStorage.setItem('aimeat-lang', lang);
667
+ document.cookie = 'aimeat-lang=' + lang + ';path=/;max-age=31536000;SameSite=Lax';
668
+ window.location.href = url.toString();
669
+ }
670
+
671
+ // ── Auth setup ──
672
+ console.log('[AIMEAT Profile] Starting auth...', { AIMEAT: !!window.AIMEAT, auth: !!(window.AIMEAT && window.AIMEAT.auth) });
673
+ var storedRaw = localStorage.getItem('aimeat_session');
674
+ console.log('[AIMEAT Profile] Stored session:', storedRaw ? 'exists (' + storedRaw.substring(0,60) + '...)' : 'NONE');
675
+
676
+ var auth = window.AIMEAT && window.AIMEAT.auth;
677
+ if (auth) {
678
+ auth.mountLoginButton('#auth-container', {
679
+ i18n: (function() {
680
+ var m = {};
681
+ for (var k in T) { if (k.indexOf('modal.') === 0) m[k.slice(6)] = T[k]; }
682
+ return m;
683
+ })(),
684
+ onLogin: function(s) { console.log('[AIMEAT Profile] onLogin callback', s); session = s; showProfile(); },
685
+ onLogout: function() { console.log('[AIMEAT Profile] onLogout callback'); session = null; hideProfile(); },
686
+ });
687
+ auth.login().then(function(s) {
688
+ console.log('[AIMEAT Profile] auth.login() result:', s ? 'session OK (gaii=' + s.gaii + ')' : 'null');
689
+ if (s) { session = s; showProfile(); }
690
+ else {
691
+ console.log('[AIMEAT Profile] No session after login, stored now:', localStorage.getItem('aimeat_session') ? 'still exists' : 'DELETED');
692
+ renderLoginSplash();
693
+ }
694
+ }).catch(function(e) {
695
+ console.error('[AIMEAT Profile] auth.login() THREW:', e);
696
+ renderLoginSplash();
697
+ });
698
+ } else {
699
+ console.error('[AIMEAT Profile] window.AIMEAT.auth not found! Script may have failed to load.');
700
+ renderLoginSplash();
701
+ }
702
+
703
+ function renderLoginSplash() {
704
+ var area = document.getElementById('login-area');
705
+ area.innerHTML = '<button onclick="document.querySelector(\\'#auth-container button\\').click()" '
706
+ + 'style="padding:12px 28px;background:linear-gradient(135deg,var(--love1),var(--love2));color:#fff;border:none;border-radius:10px;cursor:pointer;font-weight:700;font-size:1rem;box-shadow:0 0 20px rgba(255,107,157,.3)">'
707
+ + '\\u{1F496} ' + t('profile.signInBtn') + '</button>';
708
+ }
709
+
710
+ function showProfile() {
711
+ document.getElementById('login-screen').style.display = 'none';
712
+ document.getElementById('profile-screen').style.display = 'block';
713
+ updateAgentPrompt();
714
+ loadAll();
715
+ }
716
+ function hideProfile() {
717
+ document.getElementById('login-screen').style.display = 'block';
718
+ document.getElementById('profile-screen').style.display = 'none';
719
+ }
720
+
721
+ function escHtml(s) { if (s == null) return ''; var d = document.createElement('div'); d.textContent = String(s); return d.innerHTML; }
722
+
723
+ // ── Toast notifications ──
724
+ function showToast(msg, isError) {
725
+ var existing = document.querySelector('.toast');
726
+ if (existing) existing.remove();
727
+ var el = document.createElement('div');
728
+ el.className = 'toast' + (isError ? ' error' : '');
729
+ el.textContent = msg;
730
+ document.body.appendChild(el);
731
+ setTimeout(function(){ el.remove(); }, 3000);
732
+ }
733
+
734
+ // ── Tabs ──
735
+ document.getElementById('tabs').addEventListener('click', function(e) {
736
+ var btn = e.target.closest('.tab');
737
+ if (!btn) return;
738
+ var tab = btn.dataset.tab;
739
+ document.querySelectorAll('.tab').forEach(function(t){ t.classList.toggle('active', t.dataset.tab === tab); });
740
+ document.querySelectorAll('.tab-panel').forEach(function(p){ p.classList.toggle('active', p.id === 'panel-' + tab); });
741
+ });
742
+
743
+ // ── Sub-tab handling (generic) ──
744
+ document.addEventListener('click', function(e) {
745
+ var btn = e.target.closest('.sub-tab');
746
+ if (!btn) return;
747
+ var container = btn.closest('.tab-panel');
748
+ if (!container) return;
749
+ container.querySelectorAll('.sub-tab').forEach(function(t){ t.classList.toggle('active', t === btn); });
750
+ var target = btn.dataset.subtab;
751
+ container.querySelectorAll('.sub-panel').forEach(function(p){ p.classList.toggle('active', p.id === 'subpanel-' + target); });
752
+ // Lazy-load content
753
+ if (target === 'memory-files') loadFiles();
754
+ if (target === 'services-catalogue') loadCatalogue();
755
+ if (target === 'boards-browse') loadAllBoards();
756
+ if (target === 'apps-gallery') loadAllApps();
757
+ if (target === 'work-sent') loadSentWork();
758
+ });
759
+
760
+ // ── Data loading ──
761
+ async function loadAll() {
762
+ if (!session) return;
763
+ var dn = session.ghii || session.owner;
764
+ document.getElementById('display-name').textContent = dn;
765
+ document.getElementById('ghii-label').textContent = session.ghii || '';
766
+ document.getElementById('profile-meta').textContent = t('profile.node') + ': ' + NODE_URL;
767
+
768
+ // Load everything in parallel
769
+ loadAgents();
770
+ loadChatSessions();
771
+ loadWallet();
772
+ loadMemory();
773
+ loadFiles();
774
+ loadWork();
775
+ loadActions();
776
+ loadBoards();
777
+ loadApps();
778
+ loadFederation();
779
+ loadAccess();
780
+ loadNodes();
781
+ }
782
+
783
+ // Helper to do authenticated fetch
784
+ async function apiFetch(path) {
785
+ try {
786
+ var resp = await session.fetch(path);
787
+ if (resp && resp.ok !== undefined) return resp;
788
+ return resp;
789
+ } catch(e) {
790
+ return null;
791
+ }
792
+ }
793
+
794
+ // ── Agents ──
795
+ async function loadAgents() {
796
+ var el = document.getElementById('agents-list');
797
+ try {
798
+ var data = await apiFetch('/v1/agents');
799
+ var agents = data && data.data && data.data.agents ? data.data.agents : (Array.isArray(data) ? data : []);
800
+ document.getElementById('stat-agents').textContent = agents.length;
801
+
802
+ if (agents.length === 0) { el.innerHTML = '<div class="empty">' + t('profile.agents.empty') + '</div>'; return; }
803
+ var html = '';
804
+ agents.forEach(function(a) {
805
+ var trustPct = Math.round((a.trust_score || 0) * 100);
806
+ var trustClass = trustPct >= 80 ? 'badge-success' : trustPct >= 50 ? 'badge-warn' : 'badge-danger';
807
+ html += '<div class="card agent-card">'
808
+ + '<div class="card-header"><div><div class="card-title">' + escHtml(a.display_name || a.name) + '</div>'
809
+ + '<div class="gaii">' + escHtml(a.gaii) + '</div></div>'
810
+ + '<span class="badge ' + trustClass + '">' + t('profile.agents.trust') + ': ' + trustPct + '%</span></div>'
811
+ + '<div class="card-subtitle">' + escHtml(a.description || '') + '</div>';
812
+ if (a.capabilities && a.capabilities.length) {
813
+ html += '<div class="caps">';
814
+ a.capabilities.forEach(function(c) { html += '<span class="cap">' + escHtml(c) + '</span>'; });
815
+ html += '</div>';
816
+ }
817
+ html += '<div class="card-subtitle" style="margin-top:.5rem">' + t('profile.agents.balance') + ': <strong>' + (a.morsel_balance || 0) + '</strong> ' + t('profile.stats.morsels').toLowerCase()
818
+ + (a.last_seen ? ' &bull; ' + t('profile.agents.lastSeen') + ': ' + new Date(a.last_seen).toLocaleString() : '') + '</div>';
819
+ html += '</div>';
820
+ });
821
+ el.innerHTML = html;
822
+ } catch(e) { el.innerHTML = '<div class="empty">' + t('profile.agents.loadError') + '</div>'; }
823
+ }
824
+
825
+ // ── Chat Sessions ──
826
+ async function loadChatSessions() {
827
+ var el = document.getElementById('chatsessions-list');
828
+ try {
829
+ var csData = await apiFetch('/v1/chat-instances');
830
+ var csList = (csData && csData.data && csData.data.chat_instances) ? csData.data.chat_instances : [];
831
+ document.getElementById('stat-chatsessions').textContent = csList.length;
832
+ var csHtml = '';
833
+ if (csList.length === 0) {
834
+ csHtml = '<div class="empty">' + t('profile.chatSessions.empty') + '</div>';
835
+ } else {
836
+ csList.forEach(function(c) {
837
+ csHtml += '<div class="card">';
838
+ csHtml += '<div class="card-header"><div><span class="card-title">' + escHtml(c.platform) + '</span>';
839
+ csHtml += '<div class="card-subtitle">' + escHtml(c.app_name) + '</div></div>';
840
+ csHtml += '<span class="badge badge-info">' + (c.is_anonymous ? t('profile.chatSessions.anonymous') : escHtml(c.platform)) + '</span></div>';
841
+ csHtml += '<div style="font-size:.8rem;color:var(--muted);margin-top:.4rem">' + t('profile.chatSessions.lastSeen') + ': ' + new Date(c.last_seen).toLocaleString() + '</div>';
842
+ csHtml += '</div>';
843
+ });
844
+ }
845
+ el.innerHTML = csHtml;
846
+ } catch(e) {
847
+ el.innerHTML = '<div class="empty">' + t('profile.chatSessions.error') + '</div>';
848
+ }
849
+ }
850
+
851
+ // ── Wallet ──
852
+ async function loadWallet() {
853
+ var el = document.getElementById('wallet-area');
854
+ try {
855
+ var data = await apiFetch('/v1/wallet');
856
+ var w = data && data.data ? data.data : null;
857
+ if (!w) { el.innerHTML = '<div class="empty">' + t('profile.wallet.empty') + '</div>'; return; }
858
+ document.getElementById('stat-balance').textContent = w.balance || 0;
859
+
860
+ var html = '<div class="wallet-overview">'
861
+ + '<div class="wallet-card"><div class="amount neutral">' + (w.balance || 0) + '</div><div class="wlabel">' + t('profile.wallet.balance') + '</div></div>'
862
+ + '<div class="wallet-card"><div class="amount" style="color:var(--warn)">' + (w.in_escrow || 0) + '</div><div class="wlabel">' + t('profile.wallet.inEscrow') + '</div></div>'
863
+ + '<div class="wallet-card"><div class="amount positive">' + (w.available || 0) + '</div><div class="wlabel">' + t('profile.wallet.available') + '</div></div>'
864
+ + '<div class="wallet-card"><div class="amount" style="color:var(--muted)">' + (w.daily_allowance ? w.daily_allowance.amount : '-') + '</div><div class="wlabel">' + t('profile.wallet.dailyAllowance') + '</div></div>'
865
+ + '</div>';
866
+
867
+ // Try loading transactions
868
+ try {
869
+ var txData = await apiFetch('/v1/wallet/transactions');
870
+ var txs = txData && txData.data && txData.data.transactions ? txData.data.transactions : [];
871
+ if (txs.length > 0) {
872
+ html += '<h3 style="color:var(--love1);margin-bottom:.75rem">' + t('profile.wallet.recentTx') + '</h3>';
873
+ html += '<div class="card"><div class="tx-list">';
874
+ txs.slice(0, 50).forEach(function(tx) {
875
+ var isCredit = tx.amount > 0;
876
+ html += '<div class="tx-item">'
877
+ + '<div><div class="tx-type">' + escHtml(tx.type || 'transfer') + '</div>'
878
+ + (tx.counterparty_gaii ? '<div class="tx-date">' + escHtml(tx.counterparty_gaii) + '</div>' : '')
879
+ + '</div>'
880
+ + '<div class="tx-amount ' + (isCredit ? 'credit' : 'debit') + '">' + (isCredit ? '+' : '') + tx.amount + '</div>'
881
+ + '</div>';
882
+ });
883
+ html += '</div></div>';
884
+ }
885
+ } catch(e) {}
886
+
887
+ if (w.lifetime) {
888
+ html += '<div style="margin-top:1rem;display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:.5rem">'
889
+ + '<div class="card" style="text-align:center;padding:.75rem"><div style="font-size:1.1rem;font-weight:700;color:var(--success)">' + (w.lifetime.earned || 0) + '</div><div style="font-size:.7rem;color:var(--muted)">' + t('profile.wallet.earned') + '</div></div>'
890
+ + '<div class="card" style="text-align:center;padding:.75rem"><div style="font-size:1.1rem;font-weight:700;color:var(--love1)">' + (w.lifetime.spent || 0) + '</div><div style="font-size:.7rem;color:var(--muted)">' + t('profile.wallet.shared') + '</div></div>'
891
+ + '<div class="card" style="text-align:center;padding:.75rem"><div style="font-size:1.1rem;font-weight:700;color:var(--love1)">' + (w.lifetime.welcome_bonus || 0) + '</div><div style="font-size:.7rem;color:var(--muted)">' + t('profile.wallet.welcomeBonus') + '</div></div>'
892
+ + '</div>';
893
+ }
894
+
895
+ el.innerHTML = html;
896
+ } catch(e) { el.innerHTML = '<div class="empty">' + t('profile.wallet.error') + '</div>'; }
897
+ }
898
+
899
+ // ── Memory ──
900
+ function renderMemoryList(entries, el) {
901
+ document.getElementById('stat-memory').textContent = entries.length;
902
+ if (entries.length === 0) { el.innerHTML = '<div class="empty">' + t('profile.memory.noResults') + '</div>'; return; }
903
+ var html = '<div class="card">';
904
+ entries.forEach(function(m) {
905
+ var visBadge = m.visibility === 'public' ? 'badge-success' : m.visibility === 'shared' ? 'badge-warn' : 'badge-muted';
906
+ html += '<div class="mem-item" data-memkey="' + escHtml(m.key) + '" onclick="viewMemory(\\'' + escHtml(m.key).replace(/'/g, "\\\\'") + '\\')">'
907
+ + '<div class="mem-key">' + escHtml(m.key) + '</div>'
908
+ + '<div><span class="badge mem-vis ' + visBadge + '">' + escHtml(m.visibility || 'private') + '</span>'
909
+ + (m.tags && m.tags.length ? ' <span style="font-size:.7rem;color:var(--muted)">' + m.tags.map(escHtml).join(', ') + '</span>' : '')
910
+ + '</div></div>';
911
+ });
912
+ html += '</div>';
913
+ el.innerHTML = html;
914
+ }
915
+
916
+ async function loadMemory() {
917
+ var el = document.getElementById('memory-list');
918
+ try {
919
+ var data = await apiFetch('/v1/memory');
920
+ var entries = data && data.data && data.data.entries ? data.data.entries : [];
921
+ renderMemoryList(entries, el);
922
+ } catch(e) { el.innerHTML = '<div class="empty">' + t('profile.memory.error') + '</div>'; }
923
+ }
924
+
925
+ function toggleMemoryForm() {
926
+ var el = document.getElementById('memory-form');
927
+ el.style.display = el.style.display === 'none' ? 'block' : 'none';
928
+ }
929
+
930
+ async function createMemory() {
931
+ var key = document.getElementById('mem-key').value.trim();
932
+ var value = document.getElementById('mem-value').value;
933
+ var vis = document.getElementById('mem-vis').value;
934
+ var tagsStr = document.getElementById('mem-tags').value.trim();
935
+ var tags = tagsStr ? tagsStr.split(',').map(function(t){ return t.trim(); }).filter(Boolean) : [];
936
+
937
+ if (!key || !value) { showToast(t('profile.memory.keyRequired'), true); return; }
938
+
939
+ try {
940
+ var resp = await session.fetch('/v1/memory', {
941
+ method: 'POST',
942
+ headers: { 'Content-Type': 'application/json' },
943
+ body: JSON.stringify({ key: key, value: value, visibility: vis, tags: tags })
944
+ });
945
+ if (resp && resp.ok !== false) {
946
+ showToast(t('profile.memory.saved'));
947
+ toggleMemoryForm();
948
+ document.getElementById('mem-key').value = '';
949
+ document.getElementById('mem-value').value = '';
950
+ document.getElementById('mem-tags').value = '';
951
+ loadMemory();
952
+ } else {
953
+ showToast(t('profile.memory.saveFailed') + ': ' + (resp && resp.error ? resp.error.message : t('profile.unknownError')), true);
954
+ }
955
+ } catch(e) { showToast(t('profile.memory.saveFailed'), true); }
956
+ }
957
+
958
+ async function viewMemory(key) {
959
+ var existingEl = document.getElementById('mem-detail-' + key);
960
+ if (existingEl) { existingEl.remove(); return; }
961
+
962
+ try {
963
+ var data = await apiFetch('/v1/memory/' + encodeURIComponent(key));
964
+ var entry = data && data.data ? data.data : null;
965
+ if (!entry) return;
966
+
967
+ var containers = document.querySelectorAll('[data-memkey]');
968
+ var container = null;
969
+ for (var i = 0; i < containers.length; i++) {
970
+ if (containers[i].getAttribute('data-memkey') === key) { container = containers[i]; break; }
971
+ }
972
+ if (!container) return;
973
+
974
+ var detail = document.createElement('div');
975
+ detail.className = 'mem-detail';
976
+ detail.id = 'mem-detail-' + key;
977
+ var valueStr = typeof entry.value === 'string' ? entry.value : JSON.stringify(entry.value, null, 2);
978
+ detail.innerHTML = '<pre>' + escHtml(valueStr) + '</pre>'
979
+ + '<div class="mem-actions">'
980
+ + '<button class="btn-sm" onclick="editMemoryPrompt(\\'' + escHtml(key).replace(/'/g, "\\\\'") + '\\')">' + t('profile.memory.editBtn') + '</button>'
981
+ + '<button class="btn-danger" onclick="deleteMemory(\\'' + escHtml(key).replace(/'/g, "\\\\'") + '\\')">' + t('profile.memory.deleteBtn') + '</button>'
982
+ + '</div>';
983
+ container.after(detail);
984
+ } catch(e) {}
985
+ }
986
+
987
+ async function deleteMemory(key) {
988
+ if (!confirm(t('profile.memory.deleteConfirm') + ' "' + key + '"?')) return;
989
+ try {
990
+ await session.fetch('/v1/memory/' + encodeURIComponent(key), { method: 'DELETE' });
991
+ showToast(t('profile.memory.deleted'));
992
+ loadMemory();
993
+ } catch(e) { showToast(t('profile.error'), true); }
994
+ }
995
+
996
+ async function editMemoryPrompt(key) {
997
+ try {
998
+ var data = await apiFetch('/v1/memory/' + encodeURIComponent(key));
999
+ var entry = data && data.data ? data.data : null;
1000
+ if (!entry) return;
1001
+
1002
+ var valueStr = typeof entry.value === 'string' ? entry.value : JSON.stringify(entry.value);
1003
+ var overlay = document.createElement('div');
1004
+ overlay.className = 'modal-overlay';
1005
+ overlay.onclick = function(e) { if (e.target === overlay) overlay.remove(); };
1006
+ overlay.innerHTML = '<div class="modal"><h3>' + t('profile.memory.editTitle') + ': ' + escHtml(key) + '</h3>'
1007
+ + '<div class="form-row"><label>' + t('profile.memory.valueLabel') + '</label><textarea id="edit-mem-value" class="input-field" rows="5">' + escHtml(valueStr) + '</textarea></div>'
1008
+ + '<div class="form-row"><label>' + t('profile.memory.visLabel') + '</label><select id="edit-mem-vis" class="input-field">'
1009
+ + '<option value="private"' + (entry.visibility === 'private' ? ' selected' : '') + '>' + t('profile.memory.visPrivate') + '</option>'
1010
+ + '<option value="shared"' + (entry.visibility === 'shared' ? ' selected' : '') + '>' + t('profile.memory.visShared') + '</option>'
1011
+ + '<option value="public"' + (entry.visibility === 'public' ? ' selected' : '') + '>' + t('profile.memory.visPublic') + '</option></select></div>'
1012
+ + '<div class="form-row"><label>' + t('profile.memory.tagsLabel') + '</label><input type="text" id="edit-mem-tags" class="input-field" value="' + escHtml((entry.tags || []).join(', ')) + '"></div>'
1013
+ + '<div class="form-actions"><button class="btn-primary" onclick="saveMemoryEdit(\\'' + escHtml(key).replace(/'/g, "\\\\'") + '\\')">' + t('profile.save') + '</button><button class="btn-outline" onclick="this.closest(\\'.modal-overlay\\').remove()">' + t('profile.cancel') + '</button></div></div>';
1014
+ document.body.appendChild(overlay);
1015
+ } catch(e) { showToast(t('profile.error'), true); }
1016
+ }
1017
+
1018
+ async function saveMemoryEdit(key) {
1019
+ var value = document.getElementById('edit-mem-value').value;
1020
+ var vis = document.getElementById('edit-mem-vis').value;
1021
+ var tagsStr = document.getElementById('edit-mem-tags').value.trim();
1022
+ var tags = tagsStr ? tagsStr.split(',').map(function(t){ return t.trim(); }).filter(Boolean) : [];
1023
+
1024
+ try {
1025
+ await session.fetch('/v1/memory/' + encodeURIComponent(key), {
1026
+ method: 'PUT',
1027
+ headers: { 'Content-Type': 'application/json' },
1028
+ body: JSON.stringify({ value: value, visibility: vis, tags: tags })
1029
+ });
1030
+ showToast(t('profile.memory.updated'));
1031
+ document.querySelector('.modal-overlay').remove();
1032
+ loadMemory();
1033
+ } catch(e) { showToast(t('profile.error'), true); }
1034
+ }
1035
+
1036
+ async function searchMemory() {
1037
+ var q = document.getElementById('memory-search').value.trim();
1038
+ if (!q) { loadMemory(); return; }
1039
+ var el = document.getElementById('memory-list');
1040
+ el.innerHTML = '<span class="spinner"></span> ' + t('profile.memory.searchBtn') + '...';
1041
+ try {
1042
+ var data = await apiFetch('/v1/memory/search?q=' + encodeURIComponent(q));
1043
+ var entries = data && data.data && data.data.entries ? data.data.entries : [];
1044
+ renderMemoryList(entries, el);
1045
+ } catch(e) { el.innerHTML = '<div class="empty">' + t('profile.memory.searchFailed') + '</div>'; }
1046
+ }
1047
+
1048
+ // ── Files (Storage) ──
1049
+ function formatFileSize(bytes) {
1050
+ if (bytes === 0) return '0 B';
1051
+ var units = ['B', 'KB', 'MB', 'GB'];
1052
+ var i = Math.floor(Math.log(bytes) / Math.log(1024));
1053
+ return (bytes / Math.pow(1024, i)).toFixed(i > 0 ? 1 : 0) + ' ' + units[i];
1054
+ }
1055
+
1056
+ async function loadFiles() {
1057
+ var el = document.getElementById('files-list');
1058
+ try {
1059
+ var data = await apiFetch('/v1/storage');
1060
+ var files = data && data.data && data.data.files ? data.data.files : [];
1061
+ document.getElementById('stat-files').textContent = files.length;
1062
+
1063
+ if (files.length === 0) { el.innerHTML = '<div class="empty">' + t('profile.files.empty') + '</div>'; return; }
1064
+ var html = '<div class="file-grid">';
1065
+ files.forEach(function(f) {
1066
+ var isImage = f.mime_type && f.mime_type.startsWith('image/');
1067
+ var icon = isImage ? '\ud83d\uddbc\ufe0f' : f.mime_type && f.mime_type.includes('pdf') ? '\ud83d\udcc4' : f.mime_type && f.mime_type.includes('text') ? '\ud83d\udcdd' : '\ud83d\udcc1';
1068
+ var safeKey = escHtml(f.key).replace(/'/g, '&#39;');
1069
+ html += '<div class="file-card">'
1070
+ + '<div class="file-icon">' + icon + '</div>'
1071
+ + '<div class="file-info">'
1072
+ + '<div class="file-name" title="' + escHtml(f.key) + '">' + escHtml(f.key) + '</div>'
1073
+ + '<div class="file-meta">' + formatFileSize(f.size) + ' &bull; ' + escHtml(f.mime_type || 'unknown') + '</div>'
1074
+ + '<div class="file-meta">' + escHtml(f.visibility) + (f.created_at ? ' &bull; ' + new Date(f.created_at).toLocaleDateString() : '') + '</div>'
1075
+ + '</div>'
1076
+ + '<div class="file-actions">'
1077
+ + '<button class="btn-sm" onclick="downloadFile(decodeURIComponent(\\'' + encodeURIComponent(f.key) + '\\'))" title="' + t('profile.files.download') + '">\u2b07\ufe0f</button>'
1078
+ + '<button class="btn-sm btn-danger" onclick="deleteFile(decodeURIComponent(\\'' + encodeURIComponent(f.key) + '\\'))" title="' + t('profile.files.delete') + '">\u2716</button>'
1079
+ + '</div></div>';
1080
+ });
1081
+ html += '</div>';
1082
+ el.innerHTML = html;
1083
+ } catch(e) { el.innerHTML = '<div class="empty">' + t('profile.files.error') + '</div>'; }
1084
+ }
1085
+
1086
+ function toggleFileForm() {
1087
+ var form = document.getElementById('file-form');
1088
+ form.style.display = form.style.display === 'none' ? 'block' : 'none';
1089
+ }
1090
+
1091
+ async function uploadFile() {
1092
+ var fileInput = document.getElementById('file-input');
1093
+ var keyInput = document.getElementById('file-key');
1094
+ var vis = document.getElementById('file-vis').value;
1095
+
1096
+ if (!fileInput.files || !fileInput.files.length) {
1097
+ showToast(t('profile.files.selectFile'), true); return;
1098
+ }
1099
+ var file = fileInput.files[0];
1100
+ var key = keyInput.value.trim() || file.name;
1101
+
1102
+ // Read file as base64
1103
+ var reader = new FileReader();
1104
+ reader.onload = async function() {
1105
+ var base64 = reader.result.split(',')[1];
1106
+ try {
1107
+ var resp = await session.fetch('/v1/storage', {
1108
+ method: 'POST',
1109
+ headers: { 'Content-Type': 'application/json' },
1110
+ body: JSON.stringify({
1111
+ key: key,
1112
+ visibility: vis,
1113
+ data: base64,
1114
+ mime_type: file.type || 'application/octet-stream'
1115
+ })
1116
+ });
1117
+ if (resp && resp.data) {
1118
+ showToast(t('profile.files.uploaded'));
1119
+ toggleFileForm();
1120
+ fileInput.value = '';
1121
+ keyInput.value = '';
1122
+ loadFiles();
1123
+ } else {
1124
+ showToast(t('profile.files.uploadFailed') + (resp && resp.error ? ': ' + resp.error.message : ''), true);
1125
+ }
1126
+ } catch(e) {
1127
+ showToast(t('profile.files.uploadFailed'), true);
1128
+ }
1129
+ };
1130
+ reader.readAsDataURL(file);
1131
+ }
1132
+
1133
+ async function downloadFile(key) {
1134
+ try {
1135
+ // Use raw fetch with JWT since session.fetch() auto-parses as JSON
1136
+ var resp = await fetch(NODE_URL + '/v1/storage/' + encodeURIComponent(key), {
1137
+ headers: { 'Authorization': 'Bearer ' + session.jwt }
1138
+ });
1139
+ if (!resp || !resp.ok) { showToast(t('profile.files.error'), true); return; }
1140
+ var blob = await resp.blob();
1141
+ var url = URL.createObjectURL(blob);
1142
+ var a = document.createElement('a');
1143
+ a.href = url;
1144
+ a.download = key;
1145
+ document.body.appendChild(a);
1146
+ a.click();
1147
+ document.body.removeChild(a);
1148
+ URL.revokeObjectURL(url);
1149
+ } catch(e) { showToast(t('profile.files.error'), true); }
1150
+ }
1151
+
1152
+ async function deleteFile(key) {
1153
+ if (!confirm(t('profile.files.deleteConfirm') + ': ' + key)) return;
1154
+ try {
1155
+ var resp = await session.fetch('/v1/storage/' + encodeURIComponent(key), { method: 'DELETE' });
1156
+ if (resp && resp.data && resp.data.deleted) {
1157
+ showToast(t('profile.files.deleted'));
1158
+ loadFiles();
1159
+ } else {
1160
+ showToast(t('profile.files.error'), true);
1161
+ }
1162
+ } catch(e) { showToast(t('profile.files.error'), true); }
1163
+ }
1164
+
1165
+ // ── Board creation ──
1166
+ function toggleBoardForm() {
1167
+ var form = document.getElementById('board-create-form');
1168
+ form.style.display = form.style.display === 'none' ? 'block' : 'none';
1169
+ }
1170
+
1171
+ async function createBoard() {
1172
+ var name = document.getElementById('board-name').value.trim();
1173
+ var desc = document.getElementById('board-desc').value.trim();
1174
+ var vis = document.getElementById('board-vis').value;
1175
+ if (!name) { showToast(t('profile.boards.createFailed'), true); return; }
1176
+ try {
1177
+ var resp = await session.fetch('/v1/boards', {
1178
+ method: 'POST',
1179
+ headers: { 'Content-Type': 'application/json' },
1180
+ body: JSON.stringify({ name: name, description: desc, visibility: vis })
1181
+ });
1182
+ if (resp && resp.data) {
1183
+ showToast(t('profile.boards.created'));
1184
+ toggleBoardForm();
1185
+ document.getElementById('board-name').value = '';
1186
+ document.getElementById('board-desc').value = '';
1187
+ loadBoards();
1188
+ } else {
1189
+ showToast(t('profile.boards.createFailed') + (resp && resp.error ? ': ' + resp.error.message : ''), true);
1190
+ }
1191
+ } catch(e) { showToast(t('profile.boards.createFailed'), true); }
1192
+ }
1193
+
1194
+ async function subscribeBoard(boardId) {
1195
+ try {
1196
+ var resp = await session.fetch('/v1/boards/' + encodeURIComponent(boardId) + '/subscribe', {
1197
+ method: 'POST',
1198
+ headers: { 'Content-Type': 'application/json' },
1199
+ body: JSON.stringify({})
1200
+ });
1201
+ if (resp && resp.data) {
1202
+ showToast(t('profile.boards.subscribed'));
1203
+ loadBoards();
1204
+ } else {
1205
+ showToast(t('profile.boards.subscribeFailed') + (resp && resp.error ? ': ' + resp.error.message : ''), true);
1206
+ }
1207
+ } catch(e) { showToast(t('profile.boards.subscribeFailed'), true); }
1208
+ }
1209
+
1210
+ // ── App creation prompt ──
1211
+ function copyAppPrompt() {
1212
+ var prompt = 'I want to create a self-contained HTML application that connects to an AIMEAT node. '
1213
+ + 'The node is at: ' + NODE_URL + '\\n\\n'
1214
+ + 'Please read the attached AIMEAT-OS.md file for the complete API reference and guidelines. '
1215
+ + 'The app should be a single HTML file with embedded CSS and JavaScript that I can upload and share. '
1216
+ + 'Start by asking me what kind of app I want to build, then help me design and implement it step by step.';
1217
+ copyToClipboard(prompt).then(function() {
1218
+ showToast(t('profile.apps.promptCopied'));
1219
+ });
1220
+ }
1221
+
1222
+ // ── Work ──
1223
+ async function loadWork() {
1224
+ var el = document.getElementById('work-list');
1225
+ try {
1226
+ var data = await apiFetch('/v1/work/inbox');
1227
+ var items = data && data.data && data.data.items ? data.data.items : [];
1228
+ document.getElementById('stat-work').textContent = items.length;
1229
+ if (items.length === 0) { el.innerHTML = '<div class="empty">' + t('profile.work.empty') + '</div>'; return; }
1230
+ var html = '';
1231
+ items.forEach(function(w) {
1232
+ var statusClass = w.status === 'completed' ? 'badge-success' : w.status === 'delivered' ? 'badge-info' : w.status === 'accepted' ? 'badge-warn' : w.status === 'in_progress' ? 'badge-info' : w.status === 'failed' ? 'badge-danger' : w.status === 'disputed' ? 'badge-danger' : 'badge-muted';
1233
+ html += '<div class="card">'
1234
+ + '<div class="card-header"><div><div class="card-title">' + escHtml(w.action_id || w.tracking_code) + '</div>'
1235
+ + '<div class="card-subtitle">' + escHtml(w.tracking_code) + '</div></div>'
1236
+ + '<div class="work-status"><span class="badge ' + statusClass + '">' + escHtml(w.status) + '</span></div></div>'
1237
+ + '<div class="card-subtitle">'
1238
+ + (w.requester_gaii ? t('profile.work.from') + ': ' + escHtml(w.requester_gaii) : '')
1239
+ + (w.cost ? ' &bull; ' + t('profile.work.cost') + ': ' + w.cost + ' ' + t('profile.stats.morsels').toLowerCase() : '') + '</div>'
1240
+ + '</div>';
1241
+ });
1242
+ el.innerHTML = html;
1243
+ } catch(e) { el.innerHTML = '<div class="empty">' + t('profile.work.error') + '</div>'; }
1244
+ }
1245
+
1246
+ async function loadSentWork() {
1247
+ var el = document.getElementById('work-sent-list');
1248
+ try {
1249
+ var data = await apiFetch('/v1/work/inbox');
1250
+ var items = data && data.data && data.data.items ? data.data.items : [];
1251
+ if (items.length === 0) { el.innerHTML = '<div class="empty">' + t('profile.work.sentEmpty') + '</div>'; return; }
1252
+ var html = '';
1253
+ items.forEach(function(w) {
1254
+ var statusClass = w.status === 'completed' ? 'badge-success' : w.status === 'delivered' ? 'badge-info' : w.status === 'accepted' ? 'badge-warn' : w.status === 'disputed' ? 'badge-danger' : 'badge-muted';
1255
+ html += '<div class="card">'
1256
+ + '<div class="card-header"><div><div class="card-title">' + escHtml(w.action_id || w.tracking_code) + '</div>'
1257
+ + '<div class="card-subtitle">' + escHtml(w.tracking_code) + '</div></div>'
1258
+ + '<div class="work-status"><span class="badge ' + statusClass + '">' + escHtml(w.status) + '</span></div></div>'
1259
+ + '<div class="card-subtitle">'
1260
+ + (w.provider_gaii ? t('profile.work.provider') + ': ' + escHtml(w.provider_gaii) : '')
1261
+ + (w.cost ? ' &bull; ' + t('profile.work.cost') + ': ' + w.cost + ' ' + t('profile.stats.morsels').toLowerCase() : '') + '</div>';
1262
+
1263
+ // Rate button for delivered items
1264
+ if (w.status === 'delivered') {
1265
+ html += '<div style="margin-top:.5rem"><button class="btn-sm" onclick="showRateModal(\\'' + escHtml(w.tracking_code) + '\\')">' + t('profile.work.rateBtn') + '</button></div>';
1266
+ }
1267
+ html += '</div>';
1268
+ });
1269
+ el.innerHTML = html;
1270
+ } catch(e) { el.innerHTML = '<div class="empty">' + t('profile.work.sentError') + '</div>'; }
1271
+ }
1272
+
1273
+ function showRateModal(tc) {
1274
+ var overlay = document.createElement('div');
1275
+ overlay.className = 'modal-overlay';
1276
+ overlay.onclick = function(e) { if (e.target === overlay) overlay.remove(); };
1277
+ overlay.innerHTML = '<div class="modal"><h3>' + t('profile.work.rateTitle') + '</h3>'
1278
+ + '<p style="color:var(--muted);font-size:.85rem">' + t('profile.work.rateDesc') + ' ' + escHtml(tc) + '</p>'
1279
+ + '<div class="star-rating" id="rate-stars">'
1280
+ + [1,2,3,4,5].map(function(n) { return '<span class="star" data-rating="' + n + '" onclick="selectRating(' + n + ')">&#9734;</span>'; }).join('')
1281
+ + '</div>'
1282
+ + '<div class="form-row" style="margin-top:1rem"><label>' + t('profile.work.commentLabel') + '</label><textarea id="rate-comment" class="input-field" rows="2"></textarea></div>'
1283
+ + '<div class="form-actions"><button class="btn-primary" onclick="submitRating(\\'' + escHtml(tc) + '\\')">' + t('profile.work.submitRating') + '</button><button class="btn-outline" onclick="this.closest(\\'.modal-overlay\\').remove()">' + t('profile.cancel') + '</button></div></div>';
1284
+ document.body.appendChild(overlay);
1285
+ }
1286
+
1287
+ var currentRating = 0;
1288
+ function selectRating(n) {
1289
+ currentRating = n;
1290
+ document.querySelectorAll('#rate-stars .star').forEach(function(s) {
1291
+ var r = parseInt(s.dataset.rating);
1292
+ s.innerHTML = r <= n ? '&#9733;' : '&#9734;';
1293
+ s.classList.toggle('active', r <= n);
1294
+ });
1295
+ }
1296
+
1297
+ async function submitRating(tc) {
1298
+ if (currentRating === 0) { showToast(t('profile.work.selectRating'), true); return; }
1299
+ try {
1300
+ await session.fetch('/v1/work/' + tc + '/rate', {
1301
+ method: 'POST',
1302
+ headers: { 'Content-Type': 'application/json' },
1303
+ body: JSON.stringify({ rating: currentRating, comment: document.getElementById('rate-comment').value })
1304
+ });
1305
+ showToast(t('profile.work.ratingSubmitted'));
1306
+ document.querySelector('.modal-overlay').remove();
1307
+ currentRating = 0;
1308
+ loadSentWork();
1309
+ } catch(e) { showToast(t('profile.error'), true); }
1310
+ }
1311
+
1312
+ // ── Actions (published services) ──
1313
+ async function loadActions() {
1314
+ var el = document.getElementById('actions-list');
1315
+ try {
1316
+ var data = await apiFetch('/v1/actions');
1317
+ var actions = data && data.data && data.data.actions ? data.data.actions : [];
1318
+ // Filter to own actions
1319
+ var mine = actions.filter(function(a) { return a.provider_gaii === session.gaii; });
1320
+ document.getElementById('stat-actions').textContent = mine.length;
1321
+ if (mine.length === 0) { el.innerHTML = '<div class="empty">' + t('profile.services.empty') + '</div>'; return; }
1322
+ var html = '';
1323
+ mine.forEach(function(a) {
1324
+ html += '<div class="card">'
1325
+ + '<div class="card-header"><div class="card-title">' + escHtml(a.display_name || a.id) + '</div>'
1326
+ + '<div><span class="badge badge-info">' + escHtml(a.category || 'general') + '</span>'
1327
+ + ' <button class="btn-icon" title="' + t('profile.delete') + '" onclick="deleteAction(\\'' + escHtml(a.id) + '\\')">\\u{1F5D1}\\u{FE0F}</button></div></div>'
1328
+ + '<div class="card-subtitle">' + escHtml(a.description || '') + '</div>'
1329
+ + (a.pricing && a.pricing.amount ? '<div class="card-subtitle" style="margin-top:.3rem">' + t('profile.services.price') + ': <strong>' + a.pricing.amount + '</strong> ' + t('profile.stats.morsels').toLowerCase() + '/' + (a.pricing.unit || 'call') + '</div>' : '')
1330
+ + '</div>';
1331
+ });
1332
+ el.innerHTML = html;
1333
+ } catch(e) { el.innerHTML = '<div class="empty">' + t('profile.services.error') + '</div>'; }
1334
+ }
1335
+
1336
+ function togglePublishForm() {
1337
+ var el = document.getElementById('publish-form');
1338
+ el.style.display = el.style.display === 'none' ? 'block' : 'none';
1339
+ }
1340
+
1341
+ async function publishService() {
1342
+ var name = document.getElementById('svc-name').value.trim();
1343
+ var desc = document.getElementById('svc-desc').value.trim();
1344
+ var cat = document.getElementById('svc-category').value;
1345
+ var amount = parseInt(document.getElementById('svc-price').value) || 0;
1346
+ var unit = document.getElementById('svc-unit').value || 'call';
1347
+ var webhook = document.getElementById('svc-webhook').value.trim();
1348
+
1349
+ if (!name || !desc) { showToast(t('profile.memory.keyRequired'), true); return; }
1350
+
1351
+ try {
1352
+ var body = {
1353
+ display_name: name,
1354
+ description: desc,
1355
+ category: cat,
1356
+ pricing: { amount: amount, unit: unit },
1357
+ };
1358
+ if (webhook) body.webhook_url = webhook;
1359
+
1360
+ await session.fetch('/v1/actions', {
1361
+ method: 'POST',
1362
+ headers: { 'Content-Type': 'application/json' },
1363
+ body: JSON.stringify(body)
1364
+ });
1365
+ showToast(t('profile.services.published'));
1366
+ togglePublishForm();
1367
+ document.getElementById('svc-name').value = '';
1368
+ document.getElementById('svc-desc').value = '';
1369
+ document.getElementById('svc-webhook').value = '';
1370
+ document.getElementById('svc-price').value = '0';
1371
+ loadActions();
1372
+ } catch(e) { showToast(t('profile.error'), true); }
1373
+ }
1374
+
1375
+ async function deleteAction(id) {
1376
+ if (!confirm(t('profile.services.unpublishConfirm'))) return;
1377
+ try {
1378
+ await session.fetch('/v1/actions/' + encodeURIComponent(id), { method: 'DELETE' });
1379
+ showToast(t('profile.services.unpublished'));
1380
+ loadActions();
1381
+ } catch(e) { showToast(t('profile.error'), true); }
1382
+ }
1383
+
1384
+ var cataloguePage = 1;
1385
+ async function loadCatalogue(page) {
1386
+ page = page || 1;
1387
+ cataloguePage = page;
1388
+ var el = document.getElementById('catalogue-list');
1389
+ el.innerHTML = '<span class="spinner"></span> ' + t('profile.services.loading');
1390
+ var catFilter = document.getElementById('cat-filter').value;
1391
+ var url = '/v1/catalogue/actions?page=' + page + '&per_page=20';
1392
+ if (catFilter) url += '&category=' + catFilter;
1393
+ try {
1394
+ var resp = await fetch(NODE_URL + url);
1395
+ var data = await resp.json();
1396
+ var actions = data && data.data && data.data.actions ? data.data.actions : (data && data.data ? [data.data].flat() : []);
1397
+ if (actions.length === 0) { el.innerHTML = '<div class="empty">' + t('profile.services.catalogueEmpty') + '</div>'; return; }
1398
+ var html = '';
1399
+ actions.forEach(function(a) {
1400
+ html += '<div class="card">'
1401
+ + '<div class="card-header"><div class="card-title">' + escHtml(a.display_name || a.id) + '</div>'
1402
+ + '<span class="badge badge-info">' + escHtml(a.category || 'general') + '</span></div>'
1403
+ + '<div class="card-subtitle">' + escHtml(a.description || '') + '</div>'
1404
+ + '<div class="card-subtitle" style="margin-top:.3rem">'
1405
+ + t('profile.work.provider') + ': ' + escHtml(a.provider_gaii || 'unknown')
1406
+ + (a.pricing && a.pricing.amount ? ' &bull; ' + t('profile.services.price') + ': <strong>' + a.pricing.amount + '</strong> ' + t('profile.stats.morsels').toLowerCase() + '/' + (a.pricing.unit || 'call') : ' &bull; ' + t('profile.services.free'))
1407
+ + '</div></div>';
1408
+ });
1409
+ el.innerHTML = html;
1410
+ } catch(e) { el.innerHTML = '<div class="empty">' + t('profile.services.catalogueError') + '</div>'; }
1411
+ }
1412
+
1413
+ // ── Boards ──
1414
+ async function loadBoards() {
1415
+ var el = document.getElementById('boards-list');
1416
+ try {
1417
+ var data = await apiFetch('/v1/boards/subscriptions');
1418
+ var subs = data && data.data && data.data.subscriptions ? data.data.subscriptions : [];
1419
+ if (subs.length === 0) { el.innerHTML = '<div class="empty">' + t('profile.boards.empty') + '</div>'; return; }
1420
+ var html = '';
1421
+ subs.forEach(function(s) {
1422
+ html += '<div class="card">'
1423
+ + '<div class="card-header"><div class="card-title">' + escHtml(s.board_id || s.boardId) + '</div>'
1424
+ + '<span class="badge badge-success">' + t('profile.boards.mine') + '</span></div>'
1425
+ + (s.filters ? '<div class="card-subtitle">Filters: ' + escHtml(JSON.stringify(s.filters)) + '</div>' : '')
1426
+ + '</div>';
1427
+ });
1428
+ el.innerHTML = html;
1429
+ } catch(e) { el.innerHTML = '<div class="empty">' + t('profile.boards.error') + '</div>'; }
1430
+ }
1431
+
1432
+ async function loadAllBoards() {
1433
+ var el = document.getElementById('boards-browse-list');
1434
+ if (!el) return;
1435
+ el.innerHTML = '<span class="spinner"></span> ' + t('profile.boards.browseLoading');
1436
+ try {
1437
+ var resp = await fetch(NODE_URL + '/v1/catalogue/boards');
1438
+ var data = await resp.json();
1439
+ var boards = data && data.data && data.data.boards ? data.data.boards : [];
1440
+ if (boards.length === 0) { el.innerHTML = '<div class="empty">' + t('profile.boards.browseEmpty') + '</div>'; return; }
1441
+ var html = '';
1442
+ boards.forEach(function(b) {
1443
+ html += '<div class="card" style="cursor:pointer" onclick="viewBoard(\\'' + escHtml(b.id) + '\\', \\'' + escHtml(b.name || b.id).replace(/'/g, "\\\\'") + '\\')">'
1444
+ + '<div class="card-header"><div class="card-title">' + escHtml(b.name || b.id) + '</div>'
1445
+ + '<span class="badge ' + (b.visibility === 'public' ? 'badge-success' : 'badge-warn') + '">' + escHtml(b.visibility || 'public') + '</span></div>'
1446
+ + (b.description ? '<div class="card-subtitle">' + escHtml(b.description) + '</div>' : '')
1447
+ + '<div style="margin-top:.5rem"><button class="btn-sm" onclick="event.stopPropagation();subscribeBoard(\\'' + escHtml(b.id) + '\\')">' + t('profile.boards.subscribe') + '</button></div>'
1448
+ + '</div>';
1449
+ });
1450
+ el.innerHTML = html;
1451
+ } catch(e) { el.innerHTML = '<div class="empty">' + t('profile.boards.browseError') + '</div>'; }
1452
+ }
1453
+
1454
+ async function viewBoard(boardId, boardName) {
1455
+ var el = document.getElementById('boards-browse-list');
1456
+ el.innerHTML = '<div style="margin-bottom:1rem"><button class="btn-outline" onclick="loadAllBoards()">&larr; ' + t('profile.boards.backToBoards') + '</button> <strong>' + escHtml(boardName) + '</strong></div>'
1457
+ + '<div class="create-form" style="margin-bottom:1rem"><div class="form-row"><label>' + t('profile.boards.newPost') + '</label><textarea id="board-post-content" class="input-field" rows="2" placeholder="' + t('profile.boards.postPlaceholder') + '"></textarea></div>'
1458
+ + '<div class="form-actions"><button class="btn-primary" onclick="createPost(\\'' + escHtml(boardId) + '\\')">' + t('profile.boards.postBtn') + '</button></div></div>'
1459
+ + '<div id="board-posts"><span class="spinner"></span> ' + t('profile.boards.postsLoading') + '</div>';
1460
+
1461
+ try {
1462
+ var resp = await fetch(NODE_URL + '/v1/boards/' + encodeURIComponent(boardId) + '/posts');
1463
+ var data = await resp.json();
1464
+ var posts = data && data.data && data.data.posts ? data.data.posts : [];
1465
+ var postsEl = document.getElementById('board-posts');
1466
+ if (posts.length === 0) { postsEl.innerHTML = '<div class="empty">' + t('profile.boards.postsEmpty') + '</div>'; return; }
1467
+ var html = '';
1468
+ posts.forEach(function(p) {
1469
+ html += '<div class="post-card">'
1470
+ + '<div class="post-content">' + escHtml(p.content || p.body || '') + '</div>'
1471
+ + '<div class="post-meta"><span>' + escHtml(p.author_gaii || p.gaii || 'anonymous') + '</span>'
1472
+ + '<span>' + (p.created_at ? new Date(p.created_at).toLocaleString() : '') + '</span></div>'
1473
+ + '<div class="post-reactions">';
1474
+ var emojis = ['\\u{1F44D}', '\\u{2764}\\u{FE0F}', '\\u{1F525}', '\\u{2B50}', '\\u{1F602}'];
1475
+ emojis.forEach(function(emoji) {
1476
+ var count = p.reactions && p.reactions[emoji] ? p.reactions[emoji].length : 0;
1477
+ html += '<button class="reaction-btn" onclick="reactToPost(\\'' + escHtml(boardId) + '\\', \\'' + escHtml(p.id || p.postId) + '\\', \\'' + emoji + '\\')">' + emoji + (count > 0 ? ' ' + count : '') + '</button>';
1478
+ });
1479
+ html += '</div></div>';
1480
+ });
1481
+ postsEl.innerHTML = html;
1482
+ } catch(e) { document.getElementById('board-posts').innerHTML = '<div class="empty">' + t('profile.boards.postsError') + '</div>'; }
1483
+ }
1484
+
1485
+ async function createPost(boardId) {
1486
+ var content = document.getElementById('board-post-content').value.trim();
1487
+ if (!content) { showToast(t('profile.boards.writeFirst'), true); return; }
1488
+ try {
1489
+ await session.fetch('/v1/boards/' + encodeURIComponent(boardId) + '/posts', {
1490
+ method: 'POST',
1491
+ headers: { 'Content-Type': 'application/json' },
1492
+ body: JSON.stringify({ content: content })
1493
+ });
1494
+ showToast(t('profile.boards.posted'));
1495
+ document.getElementById('board-post-content').value = '';
1496
+ viewBoard(boardId, boardId);
1497
+ } catch(e) { showToast(t('profile.error'), true); }
1498
+ }
1499
+
1500
+ async function reactToPost(boardId, postId, emoji) {
1501
+ try {
1502
+ await session.fetch('/v1/boards/' + encodeURIComponent(boardId) + '/posts/' + encodeURIComponent(postId) + '/react', {
1503
+ method: 'POST',
1504
+ headers: { 'Content-Type': 'application/json' },
1505
+ body: JSON.stringify({ emoji: emoji })
1506
+ });
1507
+ viewBoard(boardId, boardId);
1508
+ } catch(e) { showToast(t('profile.error'), true); }
1509
+ }
1510
+
1511
+ // ── Apps ──
1512
+ async function loadApps() {
1513
+ var el = document.getElementById('apps-list');
1514
+ try {
1515
+ var resp = await fetch(NODE_URL + '/v1/apps');
1516
+ var data = await resp.json();
1517
+ var apps = data && data.data && data.data.apps ? data.data.apps : [];
1518
+ // Filter to own apps
1519
+ var mine = apps.filter(function(a) { return a.owner === session.owner; });
1520
+ document.getElementById('stat-apps').textContent = mine.length;
1521
+ if (mine.length === 0) { el.innerHTML = '<div class="empty">' + t('profile.apps.empty') + '</div>'; return; }
1522
+ var html = '';
1523
+ mine.forEach(function(a) {
1524
+ html += '<div class="card">'
1525
+ + '<div class="card-header"><div class="card-title">' + escHtml(a.filename || a.name) + '</div>'
1526
+ + '<span class="badge badge-info">' + escHtml(a.content_type || 'html') + '</span></div>'
1527
+ + '<div class="card-subtitle"><a href="' + escHtml(NODE_URL + '/v1/apps/' + (a.owner || session.owner) + '/' + (a.filename || a.name)) + '" target="_blank">' + t('profile.apps.download') + ' / Open</a>'
1528
+ + (a.size ? ' &bull; ' + Math.round(a.size/1024) + ' KB' : '')
1529
+ + '</div></div>';
1530
+ });
1531
+ el.innerHTML = html;
1532
+ } catch(e) { el.innerHTML = '<div class="empty">' + t('profile.apps.error') + '</div>'; }
1533
+ }
1534
+
1535
+ function toggleUploadForm() {
1536
+ var el = document.getElementById('upload-form');
1537
+ el.style.display = el.style.display === 'none' ? 'block' : 'none';
1538
+ }
1539
+
1540
+ async function loadAllApps() {
1541
+ var el = document.getElementById('apps-gallery-list');
1542
+ if (!el) return;
1543
+ el.innerHTML = '<span class="spinner"></span> ' + t('profile.apps.galleryLoading');
1544
+ try {
1545
+ var resp = await fetch(NODE_URL + '/v1/apps');
1546
+ var data = await resp.json();
1547
+ var apps = data && data.data && data.data.apps ? data.data.apps : [];
1548
+ if (apps.length === 0) { el.innerHTML = '<div class="empty">' + t('profile.apps.galleryEmpty') + '</div>'; return; }
1549
+ var html = '<div class="app-grid">';
1550
+ apps.forEach(function(a) {
1551
+ var screenshotUrl = a.screenshot_url ? (NODE_URL + a.screenshot_url) : null;
1552
+ html += '<div class="app-card">'
1553
+ + '<div class="app-screenshot">'
1554
+ + (screenshotUrl
1555
+ ? '<img src="' + escHtml(screenshotUrl) + '" alt="' + escHtml(a.filename) + '" onerror="this.parentElement.innerHTML=\\'<div class=placeholder>\\u{1F4F1}</div>\\'">'
1556
+ : '<div class="placeholder">\\u{1F4F1}</div>')
1557
+ + '</div>'
1558
+ + '<div class="app-info"><div class="app-name">' + escHtml(a.filename) + '</div>'
1559
+ + '<div class="app-meta">' + escHtml(a.owner) + ' &bull; ' + Math.round((a.size || 0) / 1024) + ' KB'
1560
+ + (a.protected ? ' &bull; \\u{1F512} ' + t('profile.apps.protected') : '') + '</div>'
1561
+ + '<div style="margin-top:.5rem"><a href="' + escHtml(NODE_URL + (a.download_url || '/v1/apps/' + a.owner + '/' + a.filename)) + '" class="btn-sm" style="text-decoration:none;display:inline-block">' + t('profile.apps.download') + '</a></div>'
1562
+ + '</div></div>';
1563
+ });
1564
+ html += '</div>';
1565
+ el.innerHTML = html;
1566
+ } catch(e) { el.innerHTML = '<div class="empty">' + t('profile.apps.galleryError') + '</div>'; }
1567
+ }
1568
+
1569
+ async function uploadApp() {
1570
+ var fileInput = document.getElementById('app-file');
1571
+ var ssInput = document.getElementById('app-screenshot');
1572
+ var codeInput = document.getElementById('app-access-code');
1573
+
1574
+ if (!fileInput.files.length) { showToast(t('profile.apps.selectFile'), true); return; }
1575
+ var file = fileInput.files[0];
1576
+
1577
+ var reader = new FileReader();
1578
+ reader.onload = async function() {
1579
+ var base64 = reader.result.split(',')[1];
1580
+ var body = {
1581
+ filename: file.name,
1582
+ content: base64,
1583
+ mime_type: file.type || 'text/html',
1584
+ };
1585
+ var code = codeInput.value.trim();
1586
+ if (code) body.access_code = code;
1587
+
1588
+ // Handle screenshot
1589
+ if (ssInput.files.length) {
1590
+ var ssReader = new FileReader();
1591
+ ssReader.onload = async function() {
1592
+ body.screenshot = ssReader.result.split(',')[1];
1593
+ body.screenshot_mime_type = ssInput.files[0].type || 'image/png';
1594
+ await doUpload(body);
1595
+ };
1596
+ ssReader.readAsDataURL(ssInput.files[0]);
1597
+ } else {
1598
+ await doUpload(body);
1599
+ }
1600
+ };
1601
+ reader.readAsDataURL(file);
1602
+ }
1603
+
1604
+ async function doUpload(body) {
1605
+ try {
1606
+ var resp = await session.fetch('/v1/apps', {
1607
+ method: 'POST',
1608
+ headers: { 'Content-Type': 'application/json' },
1609
+ body: JSON.stringify(body)
1610
+ });
1611
+ if (resp && resp.ok !== false) {
1612
+ showToast(t('profile.apps.uploaded'));
1613
+ document.getElementById('app-file').value = '';
1614
+ document.getElementById('app-screenshot').value = '';
1615
+ document.getElementById('app-access-code').value = '';
1616
+ document.getElementById('upload-form').style.display = 'none';
1617
+ loadApps();
1618
+ } else {
1619
+ showToast(t('profile.apps.uploadFailed') + ': ' + (resp && resp.error ? resp.error.message : t('profile.unknownError')), true);
1620
+ }
1621
+ } catch(e) { showToast(t('profile.apps.uploadFailed'), true); }
1622
+ }
1623
+
1624
+ // ── Federation ──
1625
+ async function loadFederation() {
1626
+ var el = document.getElementById('federation-area');
1627
+ try {
1628
+ var resp = await fetch(NODE_URL + '/v1/federation/directory');
1629
+ var data = await resp.json();
1630
+ var peers = data && data.data && data.data.peers ? data.data.peers : [];
1631
+ if (peers.length === 0) {
1632
+ el.innerHTML = '<div class="empty">' + t('profile.federation.empty') + '</div>';
1633
+ return;
1634
+ }
1635
+ var html = '<div class="section-title" style="margin-top:0">' + t('profile.federation.peers') + '</div>';
1636
+ peers.forEach(function(p) {
1637
+ var alive = p.status === 'active' || p.alive;
1638
+ html += '<div class="card"><div class="peer-card">'
1639
+ + '<div><div class="card-title">' + escHtml(p.node_id || p.nodeId || p.url) + '</div>'
1640
+ + '<div class="card-subtitle">' + escHtml(p.url || '') + '</div></div>'
1641
+ + '<div class="peer-status"><span class="peer-dot ' + (alive ? 'alive' : 'dead') + '"></span>'
1642
+ + '<span style="font-size:.8rem;color:' + (alive ? 'var(--success)' : 'var(--danger)') + '">' + (alive ? t('profile.federation.online') : t('profile.federation.offline')) + '</span>'
1643
+ + '</div></div></div>';
1644
+ });
1645
+ el.innerHTML = html;
1646
+ } catch(e) { el.innerHTML = '<div class="empty">' + t('profile.federation.error') + '</div>'; }
1647
+ }
1648
+
1649
+ // ── Agent CTA ──
1650
+ function updateAgentPrompt() {
1651
+ var el = document.getElementById('agent-connect-prompt');
1652
+ if (!el || !session) return;
1653
+ var ownerName = session.owner || 'unknown';
1654
+ var ghii = session.ghii || (ownerName + '@' + (window.AIMEAT && window.AIMEAT.auth ? window.AIMEAT.auth.nodeId : 'unknown'));
1655
+ var nodeUrl = NODE_URL;
1656
+ el.textContent = 'I want you to register a new automation agent on my AIMEAT node.\\n\\n'
1657
+ + 'IMPORTANT: I already have an account. Do NOT create a new owner. Use my existing identity.\\n\\n'
1658
+ + 'My GHII: ' + ghii + '\\n'
1659
+ + 'My owner name (for API calls): ' + ownerName + '\\n'
1660
+ + 'Node URL: ' + nodeUrl + '\\n\\n'
1661
+ + 'Steps:\\n'
1662
+ + '1. First, authenticate as my owner:\\n'
1663
+ + ' POST ' + nodeUrl + '/v1/auth/token\\n'
1664
+ + ' You need my owner private key to sign (ownerName + nodeId + timestamp) with Ed25519.\\n'
1665
+ + ' My owner key is stored in my browser (I will provide it if needed).\\n\\n'
1666
+ + '2. Register a new agent under my account:\\n'
1667
+ + ' POST ' + nodeUrl + '/v1/agents\\n'
1668
+ + ' Header: Authorization: Bearer <owner_jwt>\\n'
1669
+ + ' Body: {"name": "<choose-a-name>", "owner": "' + ownerName + '", "display_name": "<Your Agent Name>", "description": "<What this agent does>"}\\n'
1670
+ + ' The new agent will get a GAII in the format: <name>#' + ghii + '\\n'
1671
+ + ' SAVE the private_key from the response!\\n\\n'
1672
+ + '3. Authenticate as the new agent:\\n'
1673
+ + ' Sign (gaii + timestamp) with the agent\\'s Ed25519 private key\\n'
1674
+ + ' POST ' + nodeUrl + '/v1/auth/token with {"gaii": "<agent-gaii>", "timestamp": "<iso>", "signature": "<sig>"}\\n\\n'
1675
+ + '4. You\\'re connected! Use the JWT to access:\\n'
1676
+ + ' GET ' + nodeUrl + '/v1/catalogue \\u2014 Browse services\\n'
1677
+ + ' POST ' + nodeUrl + '/v1/memory \\u2014 Store/retrieve memories\\n'
1678
+ + ' GET ' + nodeUrl + '/v1/wallet \\u2014 Check balance\\n'
1679
+ + ' Full API spec: ' + nodeUrl + '/v1/spec\\n'
1680
+ + ' Operating instructions: ' + nodeUrl + '/v1/prompts/tier1';
1681
+ }
1682
+
1683
+ function copyAgentPrompt() {
1684
+ var el = document.getElementById('agent-connect-prompt');
1685
+ if (!el) return;
1686
+ copyToClipboard(el.textContent).then(function() {
1687
+ var btn = document.querySelector('.copy-prompt-btn');
1688
+ btn.textContent = '\\u{2705} ' + t('profile.agents.copied');
1689
+ setTimeout(function(){ btn.textContent = t('profile.agents.copyPrompt'); }, 2000);
1690
+ });
1691
+ }
1692
+
1693
+ function toggleInstructions(btn) {
1694
+ var el = document.getElementById('platform-instructions');
1695
+ var expanded = el.classList.toggle('expanded');
1696
+ var arrow = btn.querySelector('span');
1697
+ arrow.style.transform = expanded ? 'rotate(180deg)' : '';
1698
+ if (expanded && !el.dataset.loaded) {
1699
+ el.dataset.loaded = '1';
1700
+ renderPlatformPanels();
1701
+ }
1702
+ }
1703
+
1704
+ function renderPlatformPanels() {
1705
+ var panels = {
1706
+ windows: '<h4>OpenClaw (Recommended)</h4>'
1707
+ + '<p><a href="https://openclaw.ai" target="_blank">OpenClaw</a> is an open-source AI automation agent \\u2014 perfect for AIMEAT.</p>'
1708
+ + '<p>Windows requires WSL2. Open PowerShell as Admin:</p>'
1709
+ + '<ol><li>Install WSL2: <code>wsl --install</code> (restart if prompted)</li>'
1710
+ + '<li>In WSL2 terminal, install Node.js 22+: <code>curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash - && sudo apt-get install -y nodejs</code></li>'
1711
+ + '<li>Install OpenClaw: <code>npm install -g openclaw@latest</code></li>'
1712
+ + '<li>Run: <code>openclaw onboard</code> to configure your LLM API key</li>'
1713
+ + '<li>Paste the agent prompt above into the OpenClaw session</li></ol>',
1714
+ mac: '<h4>OpenClaw (Recommended)</h4>'
1715
+ + '<p><a href="https://openclaw.ai" target="_blank">OpenClaw</a> is an open-source AI automation agent \\u2014 perfect for AIMEAT.</p>'
1716
+ + '<ol><li>Install Node.js 22+: <code>brew install node</code></li>'
1717
+ + '<li>Install OpenClaw: <code>npm install -g openclaw@latest</code></li>'
1718
+ + '<li>Run: <code>openclaw onboard</code> to configure your LLM API key</li>'
1719
+ + '<li>Paste the agent prompt above into the OpenClaw session</li></ol>'
1720
+ + '<h4>Alternative: one-liner install</h4>'
1721
+ + '<pre><code>curl -fsSL https://openclaw.ai/install.sh | bash</code></pre>',
1722
+ linux: '<h4>OpenClaw (Recommended)</h4>'
1723
+ + '<p><a href="https://openclaw.ai" target="_blank">OpenClaw</a> is an open-source AI automation agent \\u2014 perfect for AIMEAT.</p>'
1724
+ + '<ol><li>Install Node.js 22+: <code>curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash - && sudo apt-get install -y nodejs</code></li>'
1725
+ + '<li>Install OpenClaw: <code>npm install -g openclaw@latest</code></li>'
1726
+ + '<li>Run: <code>openclaw onboard</code> to configure your LLM API key</li>'
1727
+ + '<li>Paste the agent prompt above into the OpenClaw session</li></ol>'
1728
+ + '<h4>Alternative: one-liner install</h4>'
1729
+ + '<pre><code>curl -fsSL https://openclaw.ai/install.sh | bash</code></pre>',
1730
+ wsl2: '<h4>Setup WSL2 (if not already)</h4>'
1731
+ + '<ol><li>Open PowerShell as Admin: <code>wsl --install</code></li>'
1732
+ + '<li>Restart and set up your Linux username/password</li></ol>'
1733
+ + '<h4>Install OpenClaw</h4>'
1734
+ + '<ol><li>In WSL2 terminal, install Node.js 22+: <code>curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash - && sudo apt-get install -y nodejs</code></li>'
1735
+ + '<li>Install OpenClaw: <code>npm install -g openclaw@latest</code></li>'
1736
+ + '<li>Run: <code>openclaw onboard</code> to configure your LLM API key</li>'
1737
+ + '<li>Paste the agent prompt above into the OpenClaw session</li></ol>',
1738
+ android: '<h4>Option A: Termux (CLI only)</h4>'
1739
+ + '<ol><li>Install <a href="https://f-droid.org/packages/com.termux/" target="_blank">Termux from F-Droid</a> (not Play Store)</li>'
1740
+ + '<li>Run: <code>pkg update && pkg install nodejs</code></li>'
1741
+ + '<li>Install OpenClaw: <code>npm install -g openclaw@latest</code></li>'
1742
+ + '<li>Run: <code>openclaw onboard</code> to configure your LLM API key</li>'
1743
+ + '<li>Paste the agent prompt above into the OpenClaw session</li></ol>'
1744
+ + '<h4>Option B: andClaw (on-device with camera/mic)</h4>'
1745
+ + '<p><a href="https://play.google.com/store/apps/details?id=com.coderred.andclaw" target="_blank">andClaw</a> runs the OpenClaw gateway directly on your phone \\u2014 no server needed. '
1746
+ + 'It gives the agent access to your camera, microphone, screen, and sensors.</p>'
1747
+ + '<p><strong>\\u26A0\\u{FE0F} Heads up:</strong> This means an AI agent can see through your camera and hear your mic. '
1748
+ + 'Only use this if you understand the privacy implications and trust your LLM provider.</p>'
1749
+ + '<h4>Alternative: Use a cloud server</h4>'
1750
+ + '<p>Run OpenClaw on a remote server (see AWS/Cloud tab) and connect via WhatsApp or Telegram.</p>',
1751
+ aws: '<h4>Quick EC2 Setup</h4>'
1752
+ + '<ol><li>Launch an EC2 instance (Amazon Linux 2023 or Ubuntu, t3.micro is fine)</li>'
1753
+ + '<li>SSH in: <code>ssh -i key.pem ec2-user@your-ip</code></li>'
1754
+ + '<li>Install Node.js 22+: <code>curl -fsSL https://deb.nodesource.com/setup_22.x | sudo bash - && sudo yum install -y nodejs</code></li>'
1755
+ + '<li>Install OpenClaw: <code>npm install -g openclaw@latest</code></li>'
1756
+ + '<li>Run: <code>openclaw onboard</code> to configure your LLM API key</li>'
1757
+ + '<li>Paste the agent prompt above into the OpenClaw session</li></ol>'
1758
+ + '<h4>For a persistent agent</h4>'
1759
+ + '<ol><li>Use <code>tmux</code> or <code>screen</code> to keep the session alive</li>'
1760
+ + '<li>Or set up a systemd service for always-on operation</li></ol>'
1761
+ };
1762
+
1763
+ var html = '';
1764
+ Object.keys(panels).forEach(function(key) {
1765
+ html += '<div class="platform-panel' + (key === 'windows' ? ' active' : '') + '" id="platform-' + key + '">'
1766
+ + '<div class="platform-content">' + panels[key] + '</div></div>';
1767
+ });
1768
+ document.getElementById('platform-panels').innerHTML = html;
1769
+ }
1770
+
1771
+ // Platform tab clicks
1772
+ document.getElementById('platform-tabs').addEventListener('click', function(e) {
1773
+ var btn = e.target.closest('.platform-tab');
1774
+ if (!btn) return;
1775
+ var platform = btn.dataset.platform;
1776
+ document.querySelectorAll('.platform-tab').forEach(function(t){ t.classList.toggle('active', t.dataset.platform === platform); });
1777
+ document.querySelectorAll('.platform-panel').forEach(function(p){ p.classList.toggle('active', p.id === 'platform-' + platform); });
1778
+ });
1779
+
1780
+ // ── Access Codes ──
1781
+ async function loadAccess() {
1782
+ var el = document.getElementById('access-area');
1783
+ var html = '';
1784
+
1785
+ // Session info
1786
+ html += '<h3 style="color:var(--love1);margin-bottom:.75rem">\\u{1F4BB} ' + t('profile.access.session') + '</h3>';
1787
+ html += '<div class="card">'
1788
+ + '<div class="mem-item"><span class="mem-key">' + t('profile.access.owner') + '</span><span>' + escHtml(session.owner || '-') + '</span></div>'
1789
+ + '<div class="mem-item"><span class="mem-key">' + t('profile.access.ghii') + '</span><span>' + escHtml(session.ghii || '-') + '</span></div>'
1790
+ + '<div class="mem-item"><span class="mem-key">' + t('profile.access.agentGaii') + '</span><span>' + escHtml(session.gaii || '-') + '</span></div>'
1791
+ + '<div class="mem-item"><span class="mem-key">' + t('profile.access.node') + '</span><span>' + escHtml(NODE_URL) + '</span></div>'
1792
+ + '<div class="mem-item"><span class="mem-key">' + t('profile.access.jwtValid') + '</span><span>' + (session.valid ? '<span class="badge badge-success">' + t('profile.access.yes') + '</span>' : '<span class="badge badge-danger">' + t('profile.access.expired') + '</span>') + '</span></div>'
1793
+ + '</div>';
1794
+
1795
+ // Public key
1796
+ html += '<h3 style="color:var(--love1);margin:1.5rem 0 .75rem">\\u{1F510} ' + t('profile.access.publicKey') + '</h3>';
1797
+ html += '<div class="card"><div style="font-family:monospace;font-size:.75rem;word-break:break-all;color:var(--muted)">' + escHtml(session.publicKey || 'N/A') + '</div></div>';
1798
+
1799
+ // Owner key info
1800
+ var ownerKey = localStorage.getItem('aimeat_owner_key');
1801
+ if (ownerKey) {
1802
+ html += '<h3 style="color:var(--love1);margin:1.5rem 0 .75rem">\\u{1F5DD}\\u{FE0F} ' + t('profile.access.ownerKey') + '</h3>';
1803
+ html += '<div class="card" style="border-color:var(--warn);cursor:pointer" onclick="copyToClipboard(localStorage.getItem(&quot;aimeat_owner_key&quot;)).then(function(){showToast(&quot;' + t('profile.access.keyCopied').replace(/"/g, '&quot;') + '&quot;)})">'
1804
+ + '<div style="display:flex;justify-content:space-between;align-items:center">'
1805
+ + '<div style="font-family:monospace;font-size:.75rem;word-break:break-all;color:var(--muted);filter:blur(4px);transition:filter .2s" '
1806
+ + 'onmouseenter="this.style.filter=&quot;none&quot;" onmouseleave="this.style.filter=&quot;blur(4px)&quot;">'
1807
+ + escHtml(ownerKey)
1808
+ + '</div><span class="badge badge-warn">' + t('profile.access.hoverReveal') + '</span></div>'
1809
+ + '<div style="font-size:.75rem;color:var(--warn);margin-top:.5rem">\\u26A0 ' + t('profile.access.keepSafe') + '</div>'
1810
+ + '</div>';
1811
+ }
1812
+
1813
+ // MCP endpoint
1814
+ html += '<h3 style="color:var(--love1);margin:1.5rem 0 .75rem">\\u{1F517} ' + t('profile.access.mcpEndpoint') + '</h3>';
1815
+ html += '<div class="card"><div style="font-family:monospace;font-size:.85rem;color:var(--love3)">' + escHtml(NODE_URL + '/v1/mcp') + '</div>'
1816
+ + '<div style="font-size:.75rem;color:var(--muted);margin-top:.3rem">' + t('profile.access.mcpDesc') + '</div></div>';
1817
+
1818
+ el.innerHTML = html;
1819
+ }
1820
+
1821
+ // ── Personal Nodes ──
1822
+ var nodesData = [];
1823
+
1824
+ async function loadNodes() {
1825
+ var el = document.getElementById('nodes-list');
1826
+ try {
1827
+ var data = await apiFetch('/v1/personal/status');
1828
+ var nodes = [];
1829
+ if (data && data.data && data.data.node_id) {
1830
+ nodes.push(data.data);
1831
+ }
1832
+ if (nodes.length === 0 && data && data.error && data.error.code === 'NOT_FOUND') {
1833
+ nodes = [];
1834
+ }
1835
+ nodesData = nodes;
1836
+ document.getElementById('stat-nodes').textContent = nodes.length;
1837
+
1838
+ if (nodes.length === 0) {
1839
+ el.innerHTML = '<div class="empty">' + t('profile.nodes.empty') + '</div>';
1840
+ return;
1841
+ }
1842
+
1843
+ var html = '';
1844
+ nodes.forEach(function(node, idx) {
1845
+ var statusClass = node.status || 'offline';
1846
+ var statusLabel = t('profile.nodes.' + statusClass) || statusClass;
1847
+ var visBadge = node.visibility === 'public'
1848
+ ? '<span class="badge badge-success">' + t('profile.nodes.public') + '</span>'
1849
+ : '<span class="badge badge-muted">' + t('profile.nodes.private') + '</span>';
1850
+ var agentCount = node.agent_gaiis ? node.agent_gaiis.length : 0;
1851
+ var agentWord = agentCount === 1 ? t('profile.nodes.agent') : t('profile.nodes.agents');
1852
+ var mailboxCount = node.mailbox ? node.mailbox.items : 0;
1853
+ var tunnelUrl = NODE_URL.replace(/^http/, 'ws') + '/v1/personal/tunnel';
1854
+
1855
+ html += '<div class="pn-card" id="pn-' + idx + '">'
1856
+ + '<div class="pn-header" onclick="toggleNodeCard(' + idx + ')">'
1857
+ + '<div class="pn-header-left">'
1858
+ + '<div class="pn-status-dot ' + statusClass + '"></div>'
1859
+ + '<span class="pn-name">' + escHtml(node.node_id) + '</span>'
1860
+ + '</div>'
1861
+ + '<div class="pn-badges">'
1862
+ + visBadge
1863
+ + ' <span class="badge badge-' + (statusClass === 'online' ? 'success' : statusClass === 'degraded' ? 'warn' : 'danger') + '">' + statusLabel + '</span>'
1864
+ + ' <span class="pn-arrow" id="pn-arrow-' + idx + '">\\u25BC</span>'
1865
+ + '</div></div>'
1866
+ + '<div class="pn-quick">' + agentCount + ' ' + agentWord + ' \\u2502 ' + t('profile.nodes.mailboxItems') + ': ' + mailboxCount + ' ' + t('profile.nodes.items') + '</div>'
1867
+ + '<div class="pn-details" id="pn-details-' + idx + '">';
1868
+
1869
+ // Tunnel URL
1870
+ html += '<div class="pn-detail-row"><span class="pn-detail-label">' + t('profile.nodes.tunnelUrl') + '</span>'
1871
+ + '<span class="pn-detail-value" style="display:flex;align-items:center;gap:.5rem"><code style="font-size:.75rem">' + escHtml(tunnelUrl) + '</code>'
1872
+ + '<button onclick="copyTunnelUrl()" style="padding:2px 8px;background:var(--card2);border:1px solid var(--border);border-radius:4px;color:var(--love4);cursor:pointer;font-size:.7rem">' + t('profile.nodes.copyUrl') + '</button></span></div>';
1873
+
1874
+ // Agents
1875
+ html += '<div style="padding:.5rem 0"><span class="pn-detail-label">' + t('profile.nodes.agentList') + '</span>';
1876
+ if (node.agent_gaiis && node.agent_gaiis.length > 0) {
1877
+ html += '<div class="pn-agent-list">';
1878
+ node.agent_gaiis.forEach(function(g) { html += '<div class="pn-agent-item">' + escHtml(g) + '</div>'; });
1879
+ html += '</div>';
1880
+ } else {
1881
+ html += '<div style="font-size:.8rem;color:var(--muted);margin-top:.3rem">' + t('profile.nodes.noAgents') + '</div>';
1882
+ }
1883
+ html += '</div>';
1884
+
1885
+ // Mailbox
1886
+ var mbUsed = node.mailbox ? node.mailbox.used_bytes : 0;
1887
+ var mbQuota = node.mailbox ? node.mailbox.quota_bytes : 0;
1888
+ var mbUsedMB = (mbUsed / 1024 / 1024).toFixed(1);
1889
+ var mbQuotaMB = (mbQuota / 1024 / 1024).toFixed(0);
1890
+ html += '<div class="pn-detail-row"><span class="pn-detail-label">' + t('profile.nodes.mailbox') + '</span>'
1891
+ + '<span class="pn-detail-value">' + mailboxCount + ' ' + t('profile.nodes.items') + ' (' + mbUsedMB + ' ' + t('profile.nodes.mailboxOf') + ' ' + mbQuotaMB + ' MB)</span></div>';
1892
+
1893
+ // Last seen
1894
+ html += '<div class="pn-detail-row"><span class="pn-detail-label">' + t('profile.nodes.lastSeen') + '</span>'
1895
+ + '<span class="pn-detail-value">' + escHtml(node.last_seen ? timeAgo(node.last_seen) : '-') + '</span></div>';
1896
+
1897
+ // Visibility toggle
1898
+ html += '<div class="pn-detail-row"><span class="pn-detail-label">' + t('profile.nodes.visibility') + '</span>'
1899
+ + '<div class="pn-vis-toggle">'
1900
+ + '<button class="pn-vis-btn ' + (node.visibility !== 'public' ? 'active' : '') + '" onclick="setNodeVis(\\'' + escHtml(node.node_id) + '\\',\\'private\\')">' + t('profile.nodes.private') + '</button>'
1901
+ + '<button class="pn-vis-btn ' + (node.visibility === 'public' ? 'active' : '') + '" onclick="setNodeVis(\\'' + escHtml(node.node_id) + '\\',\\'public\\')">' + t('profile.nodes.public') + '</button>'
1902
+ + '</div></div>';
1903
+
1904
+ // Setup instructions
1905
+ html += '<div style="margin-top:.75rem"><button class="expand-btn" onclick="toggleSetup(' + idx + ')" style="font-size:.8rem;padding:6px 12px">' + t('profile.nodes.setupTitle') + ' <span style="transition:transform .2s">\\u25BC</span></button>'
1906
+ + '<div class="pn-setup" id="pn-setup-' + idx + '">'
1907
+ + '<ol>'
1908
+ + '<li>' + t('profile.nodes.setupStep1') + '</li>'
1909
+ + '<li>' + t('profile.nodes.setupStep2') + '</li>'
1910
+ + '<li>' + t('profile.nodes.setupStep3') + '</li>'
1911
+ + '<li>' + t('profile.nodes.setupStep4') + '</li>'
1912
+ + '</ol>'
1913
+ + '<a href="/docs/personal-node-setup-guide.md" target="_blank" style="color:var(--love1);font-size:.8rem">' + t('profile.nodes.setupDocs') + ' \\u2192</a>'
1914
+ + '</div></div>';
1915
+
1916
+ // Detach button
1917
+ html += '<button class="pn-detach-btn" onclick="detachNode(\\'' + escHtml(node.node_id) + '\\')">' + t('profile.nodes.detachBtn') + '</button>';
1918
+
1919
+ html += '</div></div>';
1920
+ });
1921
+
1922
+ el.innerHTML = html;
1923
+ } catch(e) {
1924
+ document.getElementById('stat-nodes').textContent = '0';
1925
+ if (e && e.message && e.message.includes('NOT_FOUND')) {
1926
+ el.innerHTML = '<div class="empty">' + t('profile.nodes.empty') + '</div>';
1927
+ } else {
1928
+ el.innerHTML = '<div class="empty">' + t('profile.nodes.error') + '</div>';
1929
+ }
1930
+ }
1931
+ }
1932
+
1933
+ function copyTunnelUrl() {
1934
+ var url = NODE_URL.replace(/^http/, 'ws') + '/v1/personal/tunnel';
1935
+ copyToClipboard(url).then(function() { showToast(t('profile.nodes.copied')); });
1936
+ }
1937
+
1938
+ function toggleNodeCard(idx) {
1939
+ var details = document.getElementById('pn-details-' + idx);
1940
+ var arrow = document.getElementById('pn-arrow-' + idx);
1941
+ if (!details) return;
1942
+ details.classList.toggle('open');
1943
+ if (arrow) arrow.classList.toggle('open');
1944
+ }
1945
+
1946
+ function toggleSetup(idx) {
1947
+ var el = document.getElementById('pn-setup-' + idx);
1948
+ if (el) el.classList.toggle('open');
1949
+ }
1950
+
1951
+ function toggleAddNodeForm() {
1952
+ var form = document.getElementById('add-node-form');
1953
+ form.style.display = form.style.display === 'none' ? 'block' : 'none';
1954
+ }
1955
+
1956
+ function timeAgo(iso) {
1957
+ var ms = Date.now() - new Date(iso).getTime();
1958
+ if (ms < 60000) return 'just now';
1959
+ if (ms < 3600000) return Math.floor(ms / 60000) + ' min ago';
1960
+ if (ms < 86400000) return Math.floor(ms / 3600000) + 'h ago';
1961
+ return Math.floor(ms / 86400000) + 'd ago';
1962
+ }
1963
+
1964
+ async function setNodeVis(nodeId, vis) {
1965
+ try {
1966
+ await session.fetch('/v1/personal/anchor/' + encodeURIComponent(nodeId), {
1967
+ method: 'PATCH',
1968
+ headers: { 'Content-Type': 'application/json' },
1969
+ body: JSON.stringify({ visibility: vis }),
1970
+ });
1971
+ showToast(t('profile.nodes.visUpdated'));
1972
+ loadNodes();
1973
+ } catch(e) {
1974
+ showToast(t('profile.error'), true);
1975
+ }
1976
+ }
1977
+
1978
+ async function registerNode() {
1979
+ var nodeId = document.getElementById('node-id-input').value.trim();
1980
+ if (!nodeId) { showToast(t('profile.nodes.registerFailed'), true); return; }
1981
+ if (!nodeId.startsWith('personal-')) nodeId = 'personal-' + nodeId;
1982
+
1983
+ var visRadio = document.querySelector('input[name="node-vis"]:checked');
1984
+ var visibility = visRadio ? visRadio.value : 'private';
1985
+
1986
+ var gaiisRaw = document.getElementById('node-gaiis-input').value.trim();
1987
+ var agentGaiis = gaiisRaw ? gaiisRaw.split(',').map(function(s) { return s.trim(); }).filter(Boolean) : [];
1988
+
1989
+ try {
1990
+ var resp = await session.fetch('/v1/personal/anchor', {
1991
+ method: 'POST',
1992
+ headers: { 'Content-Type': 'application/json' },
1993
+ body: JSON.stringify({
1994
+ node_id: nodeId,
1995
+ owner_name: session.owner,
1996
+ public_key: session.publicKey || 'placeholder',
1997
+ agent_gaiis: agentGaiis,
1998
+ visibility: visibility,
1999
+ }),
2000
+ });
2001
+ if (resp && resp.ok !== false) {
2002
+ showToast(t('profile.nodes.registered'));
2003
+ toggleAddNodeForm();
2004
+ document.getElementById('node-id-input').value = '';
2005
+ document.getElementById('node-gaiis-input').value = '';
2006
+ loadNodes();
2007
+ } else {
2008
+ showToast((resp && resp.error && resp.error.message) || t('profile.nodes.registerFailed'), true);
2009
+ }
2010
+ } catch(e) {
2011
+ showToast(t('profile.nodes.registerFailed'), true);
2012
+ }
2013
+ }
2014
+
2015
+ async function detachNode(nodeId) {
2016
+ if (!confirm(t('profile.nodes.detachConfirm'))) return;
2017
+ try {
2018
+ await session.fetch('/v1/personal/anchor/' + encodeURIComponent(nodeId), { method: 'DELETE' });
2019
+ showToast(t('profile.nodes.detached.toast'));
2020
+ loadNodes();
2021
+ } catch(e) {
2022
+ showToast(t('profile.error'), true);
2023
+ }
2024
+ }
2025
+
2026
+ </script>
2027
+ </body>
2028
+ </html>`;
2029
+ }
2030
+ export function profileRouter(config, _storage) {
2031
+ const router = Router();
2032
+ router.get('/v1/profile', (req, res) => {
2033
+ const langParam = req.query.lang;
2034
+ const locale = resolveLocale(langParam, req.headers.cookie, req.headers['accept-language']);
2035
+ if (langParam)
2036
+ res.cookie('aimeat-lang', locale, { maxAge: 365 * 24 * 60 * 60 * 1000, path: '/', sameSite: 'lax' });
2037
+ const translations = buildProfileTranslations(locale);
2038
+ res.type('text/html').send(profileHtml(config, locale, translations));
2039
+ });
2040
+ return router;
2041
+ }
2042
+ //# sourceMappingURL=profile.js.map