aimeat 2.0.0 → 2.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 (722) hide show
  1. package/dist/.env.example +9 -4
  2. package/dist/locales/en.json +63 -1
  3. package/dist/locales/fi.json +63 -1
  4. package/dist/public/components/LinkPreview.js +101 -0
  5. package/dist/public/components/NotificationBell.js +18 -1
  6. package/dist/public/cortex-bundled/aimeat-charts.js +158 -10
  7. package/dist/public/cortex-bundled/aimeat-charts.yaml +1 -1
  8. package/dist/public/cortex-bundled/aimeat-dag.js +515 -173
  9. package/dist/public/cortex-bundled/aimeat-dag.yaml +1 -1
  10. package/dist/public/cortex-bundled/aimeat-i18n.js +6 -1
  11. package/dist/public/cortex-bundled/aimeat-i18n.yaml +1 -1
  12. package/dist/public/cortex-bundled/aimeat-surface.js +577 -0
  13. package/dist/public/cortex-bundled/aimeat-surface.yaml +107 -0
  14. package/dist/public/cortex-bundled/aimeat-viewport.js +405 -0
  15. package/dist/public/cortex-bundled/aimeat-viewport.yaml +100 -0
  16. package/dist/public/css/theme.css +57 -7
  17. package/dist/public/css/views/admin.css +8 -1
  18. package/dist/public/css/views/app-grant.css +18 -0
  19. package/dist/public/css/views/inbox.css +47 -1
  20. package/dist/public/css/views/portfolio.css +46 -0
  21. package/dist/public/css/views/profile.css +38 -4
  22. package/dist/public/js/services/apps.js +19 -3
  23. package/dist/public/js/services/messages-ai-prompts.js +38 -0
  24. package/dist/public/js/services/messages.js +26 -4
  25. package/dist/public/js/services/notebook.js +76 -0
  26. package/dist/public/js/services/unfurl.js +43 -0
  27. package/dist/public/lib/VENDORED.md +6 -3
  28. package/dist/public/lib/aimeat-daisyui-bridge.css +39 -2
  29. package/dist/public/lib/aimeat-theme.css +538 -0
  30. package/dist/public/lib/fonts/LICENSE.md +11 -4
  31. package/dist/public/lib/fonts/fraunces-var-latin-ext.woff2 +0 -0
  32. package/dist/public/lib/fonts/fraunces-var-latin.woff2 +0 -0
  33. package/dist/public/lib/fonts/inter-var-latin-ext.woff2 +0 -0
  34. package/dist/public/lib/fonts/inter-var-latin.woff2 +0 -0
  35. package/dist/public/lib/fonts/jetbrains-mono-var-latin-ext.woff2 +0 -0
  36. package/dist/public/lib/fonts/jetbrains-mono-var-latin.woff2 +0 -0
  37. package/dist/public/lib/fonts/space-grotesk-var-latin-ext.woff2 +0 -0
  38. package/dist/public/lib/fonts/space-grotesk-var-latin.woff2 +0 -0
  39. package/dist/public/lib/samples/LICENSE.md +11 -0
  40. package/dist/public/lib/samples/bass/A1.mp3 +0 -0
  41. package/dist/public/lib/samples/bass/B2.mp3 +0 -0
  42. package/dist/public/lib/samples/bass/D2.mp3 +0 -0
  43. package/dist/public/lib/samples/bass/E1.mp3 +0 -0
  44. package/dist/public/lib/samples/bass/E3.mp3 +0 -0
  45. package/dist/public/lib/samples/bass/G2.mp3 +0 -0
  46. package/dist/public/lib/samples/epiano/C2.mp3 +0 -0
  47. package/dist/public/lib/samples/epiano/C3.mp3 +0 -0
  48. package/dist/public/lib/samples/epiano/C4.mp3 +0 -0
  49. package/dist/public/lib/samples/epiano/C5.mp3 +0 -0
  50. package/dist/public/lib/samples/epiano/C6.mp3 +0 -0
  51. package/dist/public/lib/samples/epiano/G2.mp3 +0 -0
  52. package/dist/public/lib/samples/epiano/G3.mp3 +0 -0
  53. package/dist/public/lib/samples/epiano/G4.mp3 +0 -0
  54. package/dist/public/lib/samples/epiano/G5.mp3 +0 -0
  55. package/dist/public/lib/samples/guitar-steel/A2.mp3 +0 -0
  56. package/dist/public/lib/samples/guitar-steel/A4.mp3 +0 -0
  57. package/dist/public/lib/samples/guitar-steel/B3.mp3 +0 -0
  58. package/dist/public/lib/samples/guitar-steel/D3.mp3 +0 -0
  59. package/dist/public/lib/samples/guitar-steel/E2.mp3 +0 -0
  60. package/dist/public/lib/samples/guitar-steel/E4.mp3 +0 -0
  61. package/dist/public/lib/samples/guitar-steel/E5.mp3 +0 -0
  62. package/dist/public/lib/samples/guitar-steel/G3.mp3 +0 -0
  63. package/dist/public/lib/samples/organ/C2.mp3 +0 -0
  64. package/dist/public/lib/samples/organ/C3.mp3 +0 -0
  65. package/dist/public/lib/samples/organ/C4.mp3 +0 -0
  66. package/dist/public/lib/samples/organ/C5.mp3 +0 -0
  67. package/dist/public/lib/samples/organ/C6.mp3 +0 -0
  68. package/dist/public/lib/samples/organ/G2.mp3 +0 -0
  69. package/dist/public/lib/samples/organ/G3.mp3 +0 -0
  70. package/dist/public/lib/samples/organ/G4.mp3 +0 -0
  71. package/dist/public/lib/samples/organ/G5.mp3 +0 -0
  72. package/dist/public/lib/samples/strings/C2.mp3 +0 -0
  73. package/dist/public/lib/samples/strings/C3.mp3 +0 -0
  74. package/dist/public/lib/samples/strings/C4.mp3 +0 -0
  75. package/dist/public/lib/samples/strings/C5.mp3 +0 -0
  76. package/dist/public/lib/samples/strings/C6.mp3 +0 -0
  77. package/dist/public/lib/samples/strings/G2.mp3 +0 -0
  78. package/dist/public/lib/samples/strings/G3.mp3 +0 -0
  79. package/dist/public/lib/samples/strings/G4.mp3 +0 -0
  80. package/dist/public/lib/samples/strings/G5.mp3 +0 -0
  81. package/dist/public/lib/samples/theme-check.html +92 -0
  82. package/dist/public/lib/samples/themes-boot.js +20 -0
  83. package/dist/public/lib/samples/themes.html +154 -0
  84. package/dist/public/lib/samples/themes.js +60 -0
  85. package/dist/public/lib/samples/trumpet/A3.mp3 +0 -0
  86. package/dist/public/lib/samples/trumpet/A4.mp3 +0 -0
  87. package/dist/public/lib/samples/trumpet/A5.mp3 +0 -0
  88. package/dist/public/lib/samples/trumpet/C4.mp3 +0 -0
  89. package/dist/public/lib/samples/trumpet/C5.mp3 +0 -0
  90. package/dist/public/lib/samples/trumpet/E3.mp3 +0 -0
  91. package/dist/public/lib/samples/trumpet/E4.mp3 +0 -0
  92. package/dist/public/lib/samples/trumpet/E5.mp3 +0 -0
  93. package/dist/public/spa.html +2 -0
  94. package/dist/public/views/app-grant.js +24 -4
  95. package/dist/public/views/portfolio.js +61 -6
  96. package/dist/public/views/profile/access-tab/connected-apps.js +81 -5
  97. package/dist/public/views/profile/apps-tab.js +18 -1
  98. package/dist/public/views/profile/extensions-tab.maturity.js +4 -1
  99. package/dist/public/views/profile/inbox-tab/ai-actions.js +86 -0
  100. package/dist/public/views/profile/inbox-tab/components.js +141 -10
  101. package/dist/public/views/profile/inbox-tab/helpers.js +26 -0
  102. package/dist/public/views/profile/inbox-tab/panels.js +18 -3
  103. package/dist/public/views/profile/inbox-tab/use-thread-ux.js +47 -3
  104. package/dist/public/views/profile/inbox-tab.js +46 -49
  105. package/dist/public/views/profile/landing-page.cards.js +7 -0
  106. package/dist/public/views/profile/landing-page.js +12 -1
  107. package/dist/public/views/profile/libraries-tab.js +10 -2
  108. package/dist/public/views/profile/skills-tab.js +1 -1
  109. package/dist/public/views/profile/wallet-tab.js +64 -0
  110. package/dist/public/views/public-workspace-viewer.js +1 -1
  111. package/dist/public/views/start.js +2 -1
  112. package/dist/scripts/build-sdk-libs.d.ts +16 -0
  113. package/dist/scripts/build-sdk-libs.d.ts.map +1 -0
  114. package/dist/scripts/build-sdk-libs.js +112 -0
  115. package/dist/scripts/build-sdk-libs.js.map +1 -0
  116. package/dist/scripts/check-openapi.d.ts +2 -0
  117. package/dist/scripts/check-openapi.d.ts.map +1 -0
  118. package/dist/scripts/check-openapi.js +139 -0
  119. package/dist/scripts/check-openapi.js.map +1 -0
  120. package/dist/scripts/embed-viewport.d.ts +23 -0
  121. package/dist/scripts/embed-viewport.d.ts.map +1 -0
  122. package/dist/scripts/embed-viewport.js +116 -0
  123. package/dist/scripts/embed-viewport.js.map +1 -0
  124. package/dist/src/auth/sse-domain-scopes.d.ts +50 -0
  125. package/dist/src/auth/sse-domain-scopes.d.ts.map +1 -0
  126. package/dist/src/auth/sse-domain-scopes.js +111 -0
  127. package/dist/src/auth/sse-domain-scopes.js.map +1 -0
  128. package/dist/src/cli/connect/auth.d.ts +15 -0
  129. package/dist/src/cli/connect/auth.d.ts.map +1 -1
  130. package/dist/src/cli/connect/auth.js +25 -6
  131. package/dist/src/cli/connect/auth.js.map +1 -1
  132. package/dist/src/cli/connect/keychain.d.ts +9 -0
  133. package/dist/src/cli/connect/keychain.d.ts.map +1 -1
  134. package/dist/src/cli/connect/keychain.js +21 -8
  135. package/dist/src/cli/connect/keychain.js.map +1 -1
  136. package/dist/src/cli/connect/mcp/tools/agent-tasks.d.ts.map +1 -1
  137. package/dist/src/cli/connect/mcp/tools/agent-tasks.js +4 -1
  138. package/dist/src/cli/connect/mcp/tools/agent-tasks.js.map +1 -1
  139. package/dist/src/cli/connect/mcp/tools/core.d.ts.map +1 -1
  140. package/dist/src/cli/connect/mcp/tools/core.js +14 -3
  141. package/dist/src/cli/connect/mcp/tools/core.js.map +1 -1
  142. package/dist/src/cli/connect/mcp/tools/exchange.d.ts +18 -0
  143. package/dist/src/cli/connect/mcp/tools/exchange.d.ts.map +1 -0
  144. package/dist/src/cli/connect/mcp/tools/exchange.js +170 -0
  145. package/dist/src/cli/connect/mcp/tools/exchange.js.map +1 -0
  146. package/dist/src/cli/connect/mcp/tools/index.d.ts.map +1 -1
  147. package/dist/src/cli/connect/mcp/tools/index.js +2 -0
  148. package/dist/src/cli/connect/mcp/tools/index.js.map +1 -1
  149. package/dist/src/cli/connect/mcp/tools/workspaces.d.ts +3 -0
  150. package/dist/src/cli/connect/mcp/tools/workspaces.d.ts.map +1 -1
  151. package/dist/src/cli/connect/mcp/tools/workspaces.js +4 -2
  152. package/dist/src/cli/connect/mcp/tools/workspaces.js.map +1 -1
  153. package/dist/src/cli/connect/tool-call-defs-core.d.ts.map +1 -1
  154. package/dist/src/cli/connect/tool-call-defs-core.js +13 -1
  155. package/dist/src/cli/connect/tool-call-defs-core.js.map +1 -1
  156. package/dist/src/cli/connect/tool-call-defs-exchange.d.ts +3 -0
  157. package/dist/src/cli/connect/tool-call-defs-exchange.d.ts.map +1 -0
  158. package/dist/src/cli/connect/tool-call-defs-exchange.js +146 -0
  159. package/dist/src/cli/connect/tool-call-defs-exchange.js.map +1 -0
  160. package/dist/src/cli/connect/tool-call.d.ts.map +1 -1
  161. package/dist/src/cli/connect/tool-call.js +2 -0
  162. package/dist/src/cli/connect/tool-call.js.map +1 -1
  163. package/dist/src/commerce/__tests__/x402-registry.test.d.ts +2 -0
  164. package/dist/src/commerce/__tests__/x402-registry.test.d.ts.map +1 -0
  165. package/dist/src/commerce/__tests__/x402-registry.test.js +105 -0
  166. package/dist/src/commerce/__tests__/x402-registry.test.js.map +1 -0
  167. package/dist/src/commerce/evm-address.d.ts +21 -0
  168. package/dist/src/commerce/evm-address.d.ts.map +1 -0
  169. package/dist/src/commerce/evm-address.js +94 -0
  170. package/dist/src/commerce/evm-address.js.map +1 -0
  171. package/dist/src/commerce/money.d.ts +18 -5
  172. package/dist/src/commerce/money.d.ts.map +1 -1
  173. package/dist/src/commerce/money.js +27 -6
  174. package/dist/src/commerce/money.js.map +1 -1
  175. package/dist/src/commerce/session-service.d.ts +14 -0
  176. package/dist/src/commerce/session-service.d.ts.map +1 -1
  177. package/dist/src/commerce/session-service.js +1 -1
  178. package/dist/src/commerce/session-service.js.map +1 -1
  179. package/dist/src/commerce/x402-facilitator.d.ts +64 -13
  180. package/dist/src/commerce/x402-facilitator.d.ts.map +1 -1
  181. package/dist/src/commerce/x402-facilitator.js +71 -19
  182. package/dist/src/commerce/x402-facilitator.js.map +1 -1
  183. package/dist/src/commerce/x402-handler.d.ts +13 -7
  184. package/dist/src/commerce/x402-handler.d.ts.map +1 -1
  185. package/dist/src/commerce/x402-handler.js +23 -10
  186. package/dist/src/commerce/x402-handler.js.map +1 -1
  187. package/dist/src/commerce/x402.d.ts +11 -6
  188. package/dist/src/commerce/x402.d.ts.map +1 -1
  189. package/dist/src/commerce/x402.js +10 -7
  190. package/dist/src/commerce/x402.js.map +1 -1
  191. package/dist/src/config-types.d.ts +12 -0
  192. package/dist/src/config-types.d.ts.map +1 -1
  193. package/dist/src/config.d.ts.map +1 -1
  194. package/dist/src/config.js +8 -0
  195. package/dist/src/config.js.map +1 -1
  196. package/dist/src/data/app-templates/shells.d.ts +15 -3
  197. package/dist/src/data/app-templates/shells.d.ts.map +1 -1
  198. package/dist/src/data/app-templates/shells.js +97 -12
  199. package/dist/src/data/app-templates/shells.js.map +1 -1
  200. package/dist/src/data/app-templates.js +2 -2
  201. package/dist/src/data/app-templates.js.map +1 -1
  202. package/dist/src/data/appdev-pitfalls.d.ts +2 -0
  203. package/dist/src/data/appdev-pitfalls.d.ts.map +1 -1
  204. package/dist/src/data/appdev-pitfalls.js +24 -1
  205. package/dist/src/data/appdev-pitfalls.js.map +1 -1
  206. package/dist/src/data/library-packs/cortex.d.ts.map +1 -1
  207. package/dist/src/data/library-packs/cortex.js +108 -5
  208. package/dist/src/data/library-packs/cortex.js.map +1 -1
  209. package/dist/src/data/library-packs/sdk.d.ts.map +1 -1
  210. package/dist/src/data/library-packs/sdk.js +32 -8
  211. package/dist/src/data/library-packs/sdk.js.map +1 -1
  212. package/dist/src/data/library-packs/vendored.d.ts.map +1 -1
  213. package/dist/src/data/library-packs/vendored.js +83 -6
  214. package/dist/src/data/library-packs/vendored.js.map +1 -1
  215. package/dist/src/generated/api-types.d.ts +2039 -24
  216. package/dist/src/generated/api-types.d.ts.map +1 -1
  217. package/dist/src/mcp/agent-tasks.d.ts +4 -0
  218. package/dist/src/mcp/agent-tasks.d.ts.map +1 -1
  219. package/dist/src/mcp/agent-tasks.js +20 -2
  220. package/dist/src/mcp/agent-tasks.js.map +1 -1
  221. package/dist/src/mcp/annotations.d.ts.map +1 -1
  222. package/dist/src/mcp/annotations.js +20 -0
  223. package/dist/src/mcp/annotations.js.map +1 -1
  224. package/dist/src/mcp/apps.d.ts.map +1 -1
  225. package/dist/src/mcp/apps.js +8 -4
  226. package/dist/src/mcp/apps.js.map +1 -1
  227. package/dist/src/mcp/capabilities.d.ts +7 -1
  228. package/dist/src/mcp/capabilities.d.ts.map +1 -1
  229. package/dist/src/mcp/capabilities.js +5 -2
  230. package/dist/src/mcp/capabilities.js.map +1 -1
  231. package/dist/src/mcp/catalog/definitions/commerce.d.ts.map +1 -1
  232. package/dist/src/mcp/catalog/definitions/commerce.js +4 -2
  233. package/dist/src/mcp/catalog/definitions/commerce.js.map +1 -1
  234. package/dist/src/mcp/catalog/definitions/discovery-work-boards.d.ts.map +1 -1
  235. package/dist/src/mcp/catalog/definitions/discovery-work-boards.js +4 -3
  236. package/dist/src/mcp/catalog/definitions/discovery-work-boards.js.map +1 -1
  237. package/dist/src/mcp/catalog/definitions/exchange.d.ts +18 -0
  238. package/dist/src/mcp/catalog/definitions/exchange.d.ts.map +1 -0
  239. package/dist/src/mcp/catalog/definitions/exchange.js +182 -0
  240. package/dist/src/mcp/catalog/definitions/exchange.js.map +1 -0
  241. package/dist/src/mcp/catalog/definitions/organisms-workspaces-apps.js +1 -1
  242. package/dist/src/mcp/catalog/definitions/organisms-workspaces-apps.js.map +1 -1
  243. package/dist/src/mcp/catalog/definitions/schedules-tasks-memory.d.ts.map +1 -1
  244. package/dist/src/mcp/catalog/definitions/schedules-tasks-memory.js +3 -2
  245. package/dist/src/mcp/catalog/definitions/schedules-tasks-memory.js.map +1 -1
  246. package/dist/src/mcp/catalog/definitions.d.ts.map +1 -1
  247. package/dist/src/mcp/catalog/definitions.js +2 -0
  248. package/dist/src/mcp/catalog/definitions.js.map +1 -1
  249. package/dist/src/mcp/catalog/output-schemas.d.ts +6 -1
  250. package/dist/src/mcp/catalog/output-schemas.d.ts.map +1 -1
  251. package/dist/src/mcp/catalog/output-schemas.js +6 -1
  252. package/dist/src/mcp/catalog/output-schemas.js.map +1 -1
  253. package/dist/src/mcp/catalog/scopes.d.ts.map +1 -1
  254. package/dist/src/mcp/catalog/scopes.js +22 -0
  255. package/dist/src/mcp/catalog/scopes.js.map +1 -1
  256. package/dist/src/mcp/catalog/surfaces.d.ts.map +1 -1
  257. package/dist/src/mcp/catalog/surfaces.js +14 -0
  258. package/dist/src/mcp/catalog/surfaces.js.map +1 -1
  259. package/dist/src/mcp/commerce.d.ts.map +1 -1
  260. package/dist/src/mcp/commerce.js +15 -3
  261. package/dist/src/mcp/commerce.js.map +1 -1
  262. package/dist/src/mcp/core-storage.d.ts +23 -0
  263. package/dist/src/mcp/core-storage.d.ts.map +1 -0
  264. package/dist/src/mcp/core-storage.js +157 -0
  265. package/dist/src/mcp/core-storage.js.map +1 -0
  266. package/dist/src/mcp/core.d.ts +16 -0
  267. package/dist/src/mcp/core.d.ts.map +1 -1
  268. package/dist/src/mcp/core.js +75 -119
  269. package/dist/src/mcp/core.js.map +1 -1
  270. package/dist/src/mcp/dm-messages.d.ts +4 -0
  271. package/dist/src/mcp/dm-messages.d.ts.map +1 -1
  272. package/dist/src/mcp/dm-messages.js +43 -2
  273. package/dist/src/mcp/dm-messages.js.map +1 -1
  274. package/dist/src/mcp/exchange-run.d.ts +5 -0
  275. package/dist/src/mcp/exchange-run.d.ts.map +1 -0
  276. package/dist/src/mcp/exchange-run.js +226 -0
  277. package/dist/src/mcp/exchange-run.js.map +1 -0
  278. package/dist/src/mcp/exchange.d.ts +5 -0
  279. package/dist/src/mcp/exchange.d.ts.map +1 -0
  280. package/dist/src/mcp/exchange.js +352 -0
  281. package/dist/src/mcp/exchange.js.map +1 -0
  282. package/dist/src/mcp/extensions.d.ts.map +1 -1
  283. package/dist/src/mcp/extensions.js +17 -2
  284. package/dist/src/mcp/extensions.js.map +1 -1
  285. package/dist/src/mcp/index.d.ts +5 -0
  286. package/dist/src/mcp/index.d.ts.map +1 -1
  287. package/dist/src/mcp/index.js +26 -3
  288. package/dist/src/mcp/index.js.map +1 -1
  289. package/dist/src/mcp/memory-namespace-hints.d.ts +33 -0
  290. package/dist/src/mcp/memory-namespace-hints.d.ts.map +1 -0
  291. package/dist/src/mcp/memory-namespace-hints.js +60 -0
  292. package/dist/src/mcp/memory-namespace-hints.js.map +1 -0
  293. package/dist/src/mcp/workspaces.d.ts +5 -0
  294. package/dist/src/mcp/workspaces.d.ts.map +1 -1
  295. package/dist/src/mcp/workspaces.js +5 -3
  296. package/dist/src/mcp/workspaces.js.map +1 -1
  297. package/dist/src/models/agent-task-schemas.d.ts +25 -3
  298. package/dist/src/models/agent-task-schemas.d.ts.map +1 -1
  299. package/dist/src/models/agent-task-schemas.js +16 -0
  300. package/dist/src/models/agent-task-schemas.js.map +1 -1
  301. package/dist/src/models/app-tool-schemas.d.ts +573 -2
  302. package/dist/src/models/app-tool-schemas.d.ts.map +1 -1
  303. package/dist/src/models/app-tool-schemas.js +73 -2
  304. package/dist/src/models/app-tool-schemas.js.map +1 -1
  305. package/dist/src/models/odps-schemas.d.ts +305 -0
  306. package/dist/src/models/odps-schemas.d.ts.map +1 -0
  307. package/dist/src/models/odps-schemas.js +182 -0
  308. package/dist/src/models/odps-schemas.js.map +1 -0
  309. package/dist/src/models/offer-schemas.d.ts +359 -4
  310. package/dist/src/models/offer-schemas.d.ts.map +1 -1
  311. package/dist/src/models/offer-schemas.js +37 -0
  312. package/dist/src/models/offer-schemas.js.map +1 -1
  313. package/dist/src/models/schemas.d.ts +7 -3
  314. package/dist/src/models/schemas.d.ts.map +1 -1
  315. package/dist/src/models/schemas.js +13 -1
  316. package/dist/src/models/schemas.js.map +1 -1
  317. package/dist/src/models/webhook-schemas.d.ts +8 -8
  318. package/dist/src/routes/agent-tasks/create-read.d.ts +4 -0
  319. package/dist/src/routes/agent-tasks/create-read.d.ts.map +1 -1
  320. package/dist/src/routes/agent-tasks/create-read.js +20 -1
  321. package/dist/src/routes/agent-tasks/create-read.js.map +1 -1
  322. package/dist/src/routes/agent-tasks/lifecycle.d.ts.map +1 -1
  323. package/dist/src/routes/agent-tasks/lifecycle.js +10 -0
  324. package/dist/src/routes/agent-tasks/lifecycle.js.map +1 -1
  325. package/dist/src/routes/agents/device-auth.d.ts +4 -0
  326. package/dist/src/routes/agents/device-auth.d.ts.map +1 -1
  327. package/dist/src/routes/agents/device-auth.js +19 -4
  328. package/dist/src/routes/agents/device-auth.js.map +1 -1
  329. package/dist/src/routes/agents/offers.d.ts +2 -0
  330. package/dist/src/routes/agents/offers.d.ts.map +1 -1
  331. package/dist/src/routes/agents/offers.js +0 -0
  332. package/dist/src/routes/agents/offers.js.map +1 -1
  333. package/dist/src/routes/app-grants.d.ts +12 -0
  334. package/dist/src/routes/app-grants.d.ts.map +1 -1
  335. package/dist/src/routes/app-grants.js +90 -27
  336. package/dist/src/routes/app-grants.js.map +1 -1
  337. package/dist/src/routes/apps/drafts.d.ts +3 -0
  338. package/dist/src/routes/apps/drafts.d.ts.map +1 -1
  339. package/dist/src/routes/apps/drafts.js +63 -1
  340. package/dist/src/routes/apps/drafts.js.map +1 -1
  341. package/dist/src/routes/apps/fork-manage.d.ts.map +1 -1
  342. package/dist/src/routes/apps/fork-manage.js +24 -1
  343. package/dist/src/routes/apps/fork-manage.js.map +1 -1
  344. package/dist/src/routes/apps/publish.d.ts +4 -0
  345. package/dist/src/routes/apps/publish.d.ts.map +1 -1
  346. package/dist/src/routes/apps/publish.js +44 -3
  347. package/dist/src/routes/apps/publish.js.map +1 -1
  348. package/dist/src/routes/apps-cost.d.ts +25 -0
  349. package/dist/src/routes/apps-cost.d.ts.map +1 -0
  350. package/dist/src/routes/apps-cost.js +107 -0
  351. package/dist/src/routes/apps-cost.js.map +1 -0
  352. package/dist/src/routes/commerce.d.ts.map +1 -1
  353. package/dist/src/routes/commerce.js +122 -2
  354. package/dist/src/routes/commerce.js.map +1 -1
  355. package/dist/src/routes/exchange-market.d.ts +32 -0
  356. package/dist/src/routes/exchange-market.d.ts.map +1 -0
  357. package/dist/src/routes/exchange-market.js +580 -0
  358. package/dist/src/routes/exchange-market.js.map +1 -0
  359. package/dist/src/routes/exchange.d.ts +33 -0
  360. package/dist/src/routes/exchange.d.ts.map +1 -0
  361. package/dist/src/routes/exchange.js +398 -0
  362. package/dist/src/routes/exchange.js.map +1 -0
  363. package/dist/src/routes/extensions/actions.d.ts.map +1 -1
  364. package/dist/src/routes/extensions/actions.js +18 -0
  365. package/dist/src/routes/extensions/actions.js.map +1 -1
  366. package/dist/src/routes/extensions/crud.d.ts.map +1 -1
  367. package/dist/src/routes/extensions/crud.js +36 -3
  368. package/dist/src/routes/extensions/crud.js.map +1 -1
  369. package/dist/src/routes/extensions/entitlement-gate.d.ts +33 -0
  370. package/dist/src/routes/extensions/entitlement-gate.d.ts.map +1 -0
  371. package/dist/src/routes/extensions/entitlement-gate.js +156 -0
  372. package/dist/src/routes/extensions/entitlement-gate.js.map +1 -0
  373. package/dist/src/routes/extensions/manifest.d.ts +15 -0
  374. package/dist/src/routes/extensions/manifest.d.ts.map +1 -1
  375. package/dist/src/routes/extensions/manifest.js +101 -2
  376. package/dist/src/routes/extensions/manifest.js.map +1 -1
  377. package/dist/src/routes/extensions/pacing.d.ts +31 -0
  378. package/dist/src/routes/extensions/pacing.d.ts.map +1 -0
  379. package/dist/src/routes/extensions/pacing.js +73 -0
  380. package/dist/src/routes/extensions/pacing.js.map +1 -0
  381. package/dist/src/routes/extensions/paywall.d.ts.map +1 -1
  382. package/dist/src/routes/extensions/paywall.js +20 -11
  383. package/dist/src/routes/extensions/paywall.js.map +1 -1
  384. package/dist/src/routes/federation-sync/messaging.d.ts.map +1 -1
  385. package/dist/src/routes/federation-sync/messaging.js +3 -1
  386. package/dist/src/routes/federation-sync/messaging.js.map +1 -1
  387. package/dist/src/routes/ghii/recovery.d.ts +2 -0
  388. package/dist/src/routes/ghii/recovery.d.ts.map +1 -1
  389. package/dist/src/routes/ghii/recovery.js +7 -0
  390. package/dist/src/routes/ghii/recovery.js.map +1 -1
  391. package/dist/src/routes/ghii/register-login.d.ts +4 -0
  392. package/dist/src/routes/ghii/register-login.d.ts.map +1 -1
  393. package/dist/src/routes/ghii/register-login.js +45 -22
  394. package/dist/src/routes/ghii/register-login.js.map +1 -1
  395. package/dist/src/routes/ghii/web-verify.d.ts +5 -0
  396. package/dist/src/routes/ghii/web-verify.d.ts.map +1 -1
  397. package/dist/src/routes/ghii/web-verify.js +24 -3
  398. package/dist/src/routes/ghii/web-verify.js.map +1 -1
  399. package/dist/src/routes/libs/sdk-serve.d.ts +11 -0
  400. package/dist/src/routes/libs/sdk-serve.d.ts.map +1 -0
  401. package/dist/src/routes/libs/sdk-serve.js +53 -0
  402. package/dist/src/routes/libs/sdk-serve.js.map +1 -0
  403. package/dist/src/routes/libs.d.ts +7 -1
  404. package/dist/src/routes/libs.d.ts.map +1 -1
  405. package/dist/src/routes/libs.js +65 -146
  406. package/dist/src/routes/libs.js.map +1 -1
  407. package/dist/src/routes/memory/crud.d.ts.map +1 -1
  408. package/dist/src/routes/memory/crud.js +10 -0
  409. package/dist/src/routes/memory/crud.js.map +1 -1
  410. package/dist/src/routes/messages.d.ts +3 -0
  411. package/dist/src/routes/messages.d.ts.map +1 -1
  412. package/dist/src/routes/messages.js +9 -0
  413. package/dist/src/routes/messages.js.map +1 -1
  414. package/dist/src/routes/notifications.d.ts +6 -3
  415. package/dist/src/routes/notifications.d.ts.map +1 -1
  416. package/dist/src/routes/notifications.js +32 -3
  417. package/dist/src/routes/notifications.js.map +1 -1
  418. package/dist/src/routes/organisms/crud.d.ts +3 -0
  419. package/dist/src/routes/organisms/crud.d.ts.map +1 -1
  420. package/dist/src/routes/organisms/crud.js +5 -2
  421. package/dist/src/routes/organisms/crud.js.map +1 -1
  422. package/dist/src/routes/organisms/workspace-access.d.ts.map +1 -1
  423. package/dist/src/routes/organisms/workspace-access.js +38 -20
  424. package/dist/src/routes/organisms/workspace-access.js.map +1 -1
  425. package/dist/src/routes/organisms/workspace-read.d.ts.map +1 -1
  426. package/dist/src/routes/organisms/workspace-read.js +7 -2
  427. package/dist/src/routes/organisms/workspace-read.js.map +1 -1
  428. package/dist/src/routes/public-stats.d.ts +7 -0
  429. package/dist/src/routes/public-stats.d.ts.map +1 -1
  430. package/dist/src/routes/public-stats.js +28 -7
  431. package/dist/src/routes/public-stats.js.map +1 -1
  432. package/dist/src/routes/sse.d.ts +7 -0
  433. package/dist/src/routes/sse.d.ts.map +1 -1
  434. package/dist/src/routes/sse.js +36 -6
  435. package/dist/src/routes/sse.js.map +1 -1
  436. package/dist/src/routes/storage-files.d.ts +11 -0
  437. package/dist/src/routes/storage-files.d.ts.map +1 -1
  438. package/dist/src/routes/storage-files.js +58 -51
  439. package/dist/src/routes/storage-files.js.map +1 -1
  440. package/dist/src/routes/subdomains.d.ts +4 -0
  441. package/dist/src/routes/subdomains.d.ts.map +1 -1
  442. package/dist/src/routes/subdomains.js +42 -5
  443. package/dist/src/routes/subdomains.js.map +1 -1
  444. package/dist/src/routes/unfurl.d.ts +27 -0
  445. package/dist/src/routes/unfurl.d.ts.map +1 -0
  446. package/dist/src/routes/unfurl.js +180 -0
  447. package/dist/src/routes/unfurl.js.map +1 -0
  448. package/dist/src/routes/upload.d.ts +13 -0
  449. package/dist/src/routes/upload.d.ts.map +1 -1
  450. package/dist/src/routes/upload.js +115 -28
  451. package/dist/src/routes/upload.js.map +1 -1
  452. package/dist/src/routes/webmcp.d.ts +3 -0
  453. package/dist/src/routes/webmcp.d.ts.map +1 -1
  454. package/dist/src/routes/webmcp.js +59 -0
  455. package/dist/src/routes/webmcp.js.map +1 -1
  456. package/dist/src/schemas/knowledge-package.d.ts +1 -1
  457. package/dist/src/server-bootstrap/routes-loader.d.ts +1 -0
  458. package/dist/src/server-bootstrap/routes-loader.d.ts.map +1 -1
  459. package/dist/src/server-bootstrap/routes-loader.js +8 -0
  460. package/dist/src/server-bootstrap/routes-loader.js.map +1 -1
  461. package/dist/src/server-bootstrap/static-files.d.ts +4 -0
  462. package/dist/src/server-bootstrap/static-files.d.ts.map +1 -1
  463. package/dist/src/server-bootstrap/static-files.js +11 -0
  464. package/dist/src/server-bootstrap/static-files.js.map +1 -1
  465. package/dist/src/services/agent-face.d.ts +10 -2
  466. package/dist/src/services/agent-face.d.ts.map +1 -1
  467. package/dist/src/services/agent-face.js +10 -4
  468. package/dist/src/services/agent-face.js.map +1 -1
  469. package/dist/src/services/app-tool-interfaces.d.ts +37 -0
  470. package/dist/src/services/app-tool-interfaces.d.ts.map +1 -0
  471. package/dist/src/services/app-tool-interfaces.js +101 -0
  472. package/dist/src/services/app-tool-interfaces.js.map +1 -0
  473. package/dist/src/services/build-app-prompt.d.ts +22 -0
  474. package/dist/src/services/build-app-prompt.d.ts.map +1 -1
  475. package/dist/src/services/build-app-prompt.js +108 -11
  476. package/dist/src/services/build-app-prompt.js.map +1 -1
  477. package/dist/src/services/call-timing.d.ts +51 -0
  478. package/dist/src/services/call-timing.d.ts.map +1 -0
  479. package/dist/src/services/call-timing.js +91 -0
  480. package/dist/src/services/call-timing.js.map +1 -0
  481. package/dist/src/services/capability-invoke.d.ts +2 -0
  482. package/dist/src/services/capability-invoke.d.ts.map +1 -1
  483. package/dist/src/services/capability-invoke.js +10 -0
  484. package/dist/src/services/capability-invoke.js.map +1 -1
  485. package/dist/src/services/config-schema.d.ts.map +1 -1
  486. package/dist/src/services/config-schema.js +6 -0
  487. package/dist/src/services/config-schema.js.map +1 -1
  488. package/dist/src/services/contacts.d.ts +25 -1
  489. package/dist/src/services/contacts.d.ts.map +1 -1
  490. package/dist/src/services/contacts.js +30 -0
  491. package/dist/src/services/contacts.js.map +1 -1
  492. package/dist/src/services/draft-token.d.ts +22 -2
  493. package/dist/src/services/draft-token.d.ts.map +1 -1
  494. package/dist/src/services/draft-token.js +52 -3
  495. package/dist/src/services/draft-token.js.map +1 -1
  496. package/dist/src/services/entitlement-money.d.ts +55 -0
  497. package/dist/src/services/entitlement-money.d.ts.map +1 -0
  498. package/dist/src/services/entitlement-money.js +68 -0
  499. package/dist/src/services/entitlement-money.js.map +1 -0
  500. package/dist/src/services/exchange-market.d.ts +280 -0
  501. package/dist/src/services/exchange-market.d.ts.map +1 -0
  502. package/dist/src/services/exchange-market.js +276 -0
  503. package/dist/src/services/exchange-market.js.map +1 -0
  504. package/dist/src/services/exchange-odps.d.ts +58 -0
  505. package/dist/src/services/exchange-odps.d.ts.map +1 -0
  506. package/dist/src/services/exchange-odps.js +400 -0
  507. package/dist/src/services/exchange-odps.js.map +1 -0
  508. package/dist/src/services/exchange-projection.d.ts +61 -0
  509. package/dist/src/services/exchange-projection.d.ts.map +1 -0
  510. package/dist/src/services/exchange-projection.js +504 -0
  511. package/dist/src/services/exchange-projection.js.map +1 -0
  512. package/dist/src/services/exchange-proposals.d.ts +47 -0
  513. package/dist/src/services/exchange-proposals.d.ts.map +1 -0
  514. package/dist/src/services/exchange-proposals.js +73 -0
  515. package/dist/src/services/exchange-proposals.js.map +1 -0
  516. package/dist/src/services/exchange-work.d.ts +30 -0
  517. package/dist/src/services/exchange-work.d.ts.map +1 -0
  518. package/dist/src/services/exchange-work.js +43 -0
  519. package/dist/src/services/exchange-work.js.map +1 -0
  520. package/dist/src/services/extension-files.d.ts +64 -0
  521. package/dist/src/services/extension-files.d.ts.map +1 -0
  522. package/dist/src/services/extension-files.js +88 -0
  523. package/dist/src/services/extension-files.js.map +1 -0
  524. package/dist/src/services/extension-runtime.d.ts +33 -0
  525. package/dist/src/services/extension-runtime.d.ts.map +1 -1
  526. package/dist/src/services/extension-runtime.js +52 -0
  527. package/dist/src/services/extension-runtime.js.map +1 -1
  528. package/dist/src/services/file-refs.d.ts +105 -0
  529. package/dist/src/services/file-refs.d.ts.map +1 -0
  530. package/dist/src/services/file-refs.js +106 -0
  531. package/dist/src/services/file-refs.js.map +1 -0
  532. package/dist/src/services/message-send.d.ts.map +1 -1
  533. package/dist/src/services/message-send.js +4 -1
  534. package/dist/src/services/message-send.js.map +1 -1
  535. package/dist/src/services/metered-entitlements.d.ts +210 -0
  536. package/dist/src/services/metered-entitlements.d.ts.map +1 -0
  537. package/dist/src/services/metered-entitlements.js +268 -0
  538. package/dist/src/services/metered-entitlements.js.map +1 -0
  539. package/dist/src/services/notify.d.ts +7 -0
  540. package/dist/src/services/notify.d.ts.map +1 -1
  541. package/dist/src/services/notify.js +35 -0
  542. package/dist/src/services/notify.js.map +1 -1
  543. package/dist/src/services/owner-memory.d.ts +30 -1
  544. package/dist/src/services/owner-memory.d.ts.map +1 -1
  545. package/dist/src/services/owner-memory.js +31 -14
  546. package/dist/src/services/owner-memory.js.map +1 -1
  547. package/dist/src/services/owner-provisioning.d.ts +5 -0
  548. package/dist/src/services/owner-provisioning.d.ts.map +1 -1
  549. package/dist/src/services/owner-provisioning.js +20 -2
  550. package/dist/src/services/owner-provisioning.js.map +1 -1
  551. package/dist/src/services/task-files.d.ts +51 -0
  552. package/dist/src/services/task-files.d.ts.map +1 -0
  553. package/dist/src/services/task-files.js +58 -0
  554. package/dist/src/services/task-files.js.map +1 -0
  555. package/dist/src/services/upload-token.d.ts +29 -0
  556. package/dist/src/services/upload-token.d.ts.map +1 -1
  557. package/dist/src/services/upload-token.js +37 -0
  558. package/dist/src/services/upload-token.js.map +1 -1
  559. package/dist/src/services/upload-zip.d.ts +2 -0
  560. package/dist/src/services/upload-zip.d.ts.map +1 -1
  561. package/dist/src/services/upload-zip.js +5 -1
  562. package/dist/src/services/upload-zip.js.map +1 -1
  563. package/dist/src/services/workspace-meta.d.ts +15 -0
  564. package/dist/src/services/workspace-meta.d.ts.map +1 -1
  565. package/dist/src/services/workspace-meta.js +17 -0
  566. package/dist/src/services/workspace-meta.js.map +1 -1
  567. package/dist/src/services/workspace-provision.d.ts +3 -0
  568. package/dist/src/services/workspace-provision.d.ts.map +1 -1
  569. package/dist/src/services/workspace-provision.js +5 -3
  570. package/dist/src/services/workspace-provision.js.map +1 -1
  571. package/dist/src/storage/providers/postgres-kysely/methods/app-grants.d.ts +1 -0
  572. package/dist/src/storage/providers/postgres-kysely/methods/app-grants.d.ts.map +1 -1
  573. package/dist/src/storage/providers/postgres-kysely/methods/app-grants.js +10 -0
  574. package/dist/src/storage/providers/postgres-kysely/methods/app-grants.js.map +1 -1
  575. package/dist/src/storage/providers/postgres-kysely/methods/apps.d.ts +1 -0
  576. package/dist/src/storage/providers/postgres-kysely/methods/apps.d.ts.map +1 -1
  577. package/dist/src/storage/providers/postgres-kysely/methods/apps.js +2 -0
  578. package/dist/src/storage/providers/postgres-kysely/methods/apps.js.map +1 -1
  579. package/dist/src/storage/providers/postgres-kysely/methods/identity.d.ts +1 -0
  580. package/dist/src/storage/providers/postgres-kysely/methods/identity.d.ts.map +1 -1
  581. package/dist/src/storage/providers/postgres-kysely/methods/identity.js +4 -0
  582. package/dist/src/storage/providers/postgres-kysely/methods/identity.js.map +1 -1
  583. package/dist/src/storage/providers/postgres-kysely/methods/memory.d.ts +2 -0
  584. package/dist/src/storage/providers/postgres-kysely/methods/memory.d.ts.map +1 -1
  585. package/dist/src/storage/providers/postgres-kysely/methods/memory.js +12 -1
  586. package/dist/src/storage/providers/postgres-kysely/methods/memory.js.map +1 -1
  587. package/dist/src/storage/providers/postgres-kysely/methods/organisms.d.ts.map +1 -1
  588. package/dist/src/storage/providers/postgres-kysely/methods/organisms.js +5 -1
  589. package/dist/src/storage/providers/postgres-kysely/methods/organisms.js.map +1 -1
  590. package/dist/src/storage/providers/postgres-kysely/migrations/0011_unique_verified_email.sql +25 -0
  591. package/dist/src/storage/providers/postgres-kysely/migrations/0012_unique_live_app_grant.sql +29 -0
  592. package/dist/src/storage/providers/sqlite/methods/apps.d.ts +4 -0
  593. package/dist/src/storage/providers/sqlite/methods/apps.d.ts.map +1 -1
  594. package/dist/src/storage/providers/sqlite/methods/apps.js +9 -0
  595. package/dist/src/storage/providers/sqlite/methods/apps.js.map +1 -1
  596. package/dist/src/storage/providers/sqlite/methods/governance.d.ts +1 -0
  597. package/dist/src/storage/providers/sqlite/methods/governance.d.ts.map +1 -1
  598. package/dist/src/storage/providers/sqlite/methods/governance.js +4 -1
  599. package/dist/src/storage/providers/sqlite/methods/governance.js.map +1 -1
  600. package/dist/src/storage/providers/sqlite/methods/identity-nodes.d.ts +1 -0
  601. package/dist/src/storage/providers/sqlite/methods/identity-nodes.d.ts.map +1 -1
  602. package/dist/src/storage/providers/sqlite/methods/identity-nodes.js +4 -0
  603. package/dist/src/storage/providers/sqlite/methods/identity-nodes.js.map +1 -1
  604. package/dist/src/storage/providers/sqlite/methods/owner.d.ts +5 -0
  605. package/dist/src/storage/providers/sqlite/methods/owner.d.ts.map +1 -1
  606. package/dist/src/storage/providers/sqlite/methods/owner.js +8 -0
  607. package/dist/src/storage/providers/sqlite/methods/owner.js.map +1 -1
  608. package/dist/src/storage/providers/sqlite/schema.d.ts +3 -0
  609. package/dist/src/storage/providers/sqlite/schema.d.ts.map +1 -1
  610. package/dist/src/storage/providers/sqlite/schema.js +40 -0
  611. package/dist/src/storage/providers/sqlite/schema.js.map +1 -1
  612. package/dist/src/storage/repositories/app-grant.repository.d.ts +9 -1
  613. package/dist/src/storage/repositories/app-grant.repository.d.ts.map +1 -1
  614. package/dist/src/storage/repositories/app.repository.d.ts +0 -0
  615. package/dist/src/storage/repositories/app.repository.d.ts.map +1 -1
  616. package/dist/src/storage/repositories/identity.repository.d.ts +6 -0
  617. package/dist/src/storage/repositories/identity.repository.d.ts.map +1 -1
  618. package/dist/src/storage/repositories/memory.repository.d.ts +14 -0
  619. package/dist/src/storage/repositories/memory.repository.d.ts.map +1 -1
  620. package/dist/src/storage/repositories-impl/memory-repository.d.ts +8 -1
  621. package/dist/src/storage/repositories-impl/memory-repository.d.ts.map +1 -1
  622. package/dist/src/storage/repositories-impl/memory-repository.js +15 -4
  623. package/dist/src/storage/repositories-impl/memory-repository.js.map +1 -1
  624. package/dist/src/storage/types/agents-messaging.d.ts +19 -0
  625. package/dist/src/storage/types/agents-messaging.d.ts.map +1 -1
  626. package/dist/src/storage/types/agents-messaging.js.map +1 -1
  627. package/dist/src/storage/types/apps.d.ts +1 -0
  628. package/dist/src/storage/types/apps.d.ts.map +1 -1
  629. package/dist/src/storage/types/organisms-federation.d.ts +50 -0
  630. package/dist/src/storage/types/organisms-federation.d.ts.map +1 -1
  631. package/dist/src/utils/app-badge.d.ts.map +1 -1
  632. package/dist/src/utils/app-badge.js +7 -3
  633. package/dist/src/utils/app-badge.js.map +1 -1
  634. package/dist/src/utils/app-mobile-lint.d.ts +17 -0
  635. package/dist/src/utils/app-mobile-lint.d.ts.map +1 -0
  636. package/dist/src/utils/app-mobile-lint.js +40 -0
  637. package/dist/src/utils/app-mobile-lint.js.map +1 -0
  638. package/dist/static/app-catalog/_template.html +18 -82
  639. package/dist/static/app-catalog/js/apps-io.js +51 -165
  640. package/dist/static/app-catalog/js/cortex.js +3 -1
  641. package/dist/static/app-catalog/js/cost.js +100 -0
  642. package/dist/static/app-catalog/js/db.js +23 -93
  643. package/dist/static/app-catalog/js/detail.js +568 -59
  644. package/dist/static/app-catalog/js/favorites.js +71 -0
  645. package/dist/static/app-catalog/js/i18n-data.js +369 -19
  646. package/dist/static/app-catalog/js/main.js +50 -139
  647. package/dist/static/app-catalog/js/migrate.js +88 -0
  648. package/dist/static/app-catalog/js/monetize.js +205 -17
  649. package/dist/static/app-catalog/js/odps.js +489 -0
  650. package/dist/static/app-catalog/js/promote.js +70 -0
  651. package/dist/static/app-catalog/js/render.js +29 -139
  652. package/dist/static/app-catalog/js/server-io.js +126 -223
  653. package/dist/static/app-catalog/js/settings.js +11 -204
  654. package/dist/static/app-catalog/js/workcopy.js +198 -0
  655. package/dist/static/app-catalog/styles/app-catalog.css +100 -0
  656. package/dist/static/app-catalog.html +2220 -1029
  657. package/dist/static/sdk-libs/_core/config.js +52 -0
  658. package/dist/static/sdk-libs/_core/http.js +52 -0
  659. package/dist/static/sdk-libs/_core/namespace.js +33 -0
  660. package/dist/static/sdk-libs/_core/sdk-globals.d.ts +50 -0
  661. package/dist/static/sdk-libs/_core/session.js +66 -0
  662. package/dist/static/sdk-libs/agentface/index.js +102 -0
  663. package/dist/static/sdk-libs/agents/index.js +305 -0
  664. package/dist/static/sdk-libs/ai/index.js +153 -0
  665. package/dist/static/sdk-libs/audio/core.js +111 -0
  666. package/dist/static/sdk-libs/audio/index.js +380 -0
  667. package/dist/static/sdk-libs/audio/instruments.js +369 -0
  668. package/dist/static/sdk-libs/auth/cluster.js +97 -0
  669. package/dist/static/sdk-libs/auth/config.js +46 -0
  670. package/dist/static/sdk-libs/auth/crypto.js +166 -0
  671. package/dist/static/sdk-libs/auth/events.js +27 -0
  672. package/dist/static/sdk-libs/auth/i18n.js +64 -0
  673. package/dist/static/sdk-libs/auth/index.js +61 -0
  674. package/dist/static/sdk-libs/auth/locale.js +151 -0
  675. package/dist/static/sdk-libs/auth/modal.js +554 -0
  676. package/dist/static/sdk-libs/auth/palette.js +172 -0
  677. package/dist/static/sdk-libs/auth/pill.js +198 -0
  678. package/dist/static/sdk-libs/auth/session.js +792 -0
  679. package/dist/static/sdk-libs/auth/signup.js +232 -0
  680. package/dist/static/sdk-libs/auth/theme.js +137 -0
  681. package/dist/static/sdk-libs/capabilities/index.js +179 -0
  682. package/dist/static/sdk-libs/commerce/index.js +243 -0
  683. package/dist/static/sdk-libs/data/index.js +250 -0
  684. package/dist/static/sdk-libs/dist/aimeat-agentface.js +91 -0
  685. package/dist/static/sdk-libs/dist/aimeat-agents.js +348 -0
  686. package/dist/static/sdk-libs/dist/aimeat-ai.js +168 -0
  687. package/dist/static/sdk-libs/dist/aimeat-audio.js +979 -0
  688. package/dist/static/sdk-libs/dist/aimeat-auth.js +2232 -0
  689. package/dist/static/sdk-libs/dist/aimeat-capabilities.js +177 -0
  690. package/dist/static/sdk-libs/dist/aimeat-commerce.js +265 -0
  691. package/dist/static/sdk-libs/dist/aimeat-data.js +247 -0
  692. package/dist/static/sdk-libs/dist/aimeat-editor.js +299 -0
  693. package/dist/static/sdk-libs/dist/aimeat-header.js +270 -0
  694. package/dist/static/sdk-libs/dist/aimeat-intake.js +94 -0
  695. package/dist/static/sdk-libs/dist/aimeat-live.js +317 -0
  696. package/dist/static/sdk-libs/dist/aimeat-markdown.js +633 -0
  697. package/dist/static/sdk-libs/dist/aimeat-organism.js +394 -0
  698. package/dist/static/sdk-libs/dist/aimeat-portfolio-standalone.js +90 -0
  699. package/dist/static/sdk-libs/dist/aimeat-social.js +157 -0
  700. package/dist/static/sdk-libs/dist/aimeat-speech.js +300 -0
  701. package/dist/static/sdk-libs/dist/aimeat-storage.js +210 -0
  702. package/dist/static/sdk-libs/dist/aimeat-tunnel.js +383 -0
  703. package/dist/static/sdk-libs/dist/aimeat-wallet.js +118 -0
  704. package/dist/static/sdk-libs/dist/aimeat-webmcp.js +187 -0
  705. package/dist/static/sdk-libs/dist/aimeat-work.js +213 -0
  706. package/dist/static/sdk-libs/dist/aimeat-workflows.js +147 -0
  707. package/dist/static/sdk-libs/editor/index.js +229 -0
  708. package/dist/static/sdk-libs/header/index.js +249 -0
  709. package/dist/static/sdk-libs/intake/index.js +75 -0
  710. package/dist/static/sdk-libs/live/index.js +223 -0
  711. package/dist/static/sdk-libs/markdown/index.js +570 -0
  712. package/dist/static/sdk-libs/organism/index.js +381 -0
  713. package/dist/static/sdk-libs/portfolio-standalone/index.js +78 -0
  714. package/dist/static/sdk-libs/social/index.js +140 -0
  715. package/dist/static/sdk-libs/speech/index.js +321 -0
  716. package/dist/static/sdk-libs/storage/index.js +189 -0
  717. package/dist/static/sdk-libs/tunnel/index.js +428 -0
  718. package/dist/static/sdk-libs/wallet/index.js +115 -0
  719. package/dist/static/sdk-libs/webmcp/index.js +185 -0
  720. package/dist/static/sdk-libs/work/index.js +191 -0
  721. package/dist/static/sdk-libs/workflows/index.js +113 -0
  722. package/package.json +10 -3
@@ -0,0 +1,2232 @@
1
+ // GENERATED FILE — do not edit directly. Source: src/static/sdk-libs/auth/ (+ _core/).
2
+ // Rebuild: pnpm build:sdk · Served at /v1/libs/aimeat-auth.js (with a per-node config prelude).
3
+ "use strict";
4
+ (() => {
5
+ // src/static/sdk-libs/auth/crypto.js
6
+ async function importEd25519Key(privateKeyBase64) {
7
+ const privBytes = Uint8Array.from(atob(privateKeyBase64), (c) => c.charCodeAt(0));
8
+ const pkcs8Prefix = new Uint8Array([48, 46, 2, 1, 0, 48, 5, 6, 3, 43, 101, 112, 4, 34, 4, 32]);
9
+ const pkcs8 = new Uint8Array(pkcs8Prefix.length + privBytes.length);
10
+ pkcs8.set(pkcs8Prefix);
11
+ pkcs8.set(privBytes, pkcs8Prefix.length);
12
+ const cryptoKey = await crypto.subtle.importKey("pkcs8", pkcs8, "Ed25519", false, ["sign"]);
13
+ privBytes.fill(0);
14
+ pkcs8.fill(0);
15
+ return cryptoKey;
16
+ }
17
+ function isCryptoKey(value) {
18
+ if (!value || typeof value !== "object") return false;
19
+ if (typeof CryptoKey !== "undefined" && value instanceof CryptoKey) return true;
20
+ return Object.prototype.toString.call(value) === "[object CryptoKey]";
21
+ }
22
+ async function sign(keyOrB64, message) {
23
+ let key = keyOrB64;
24
+ if (typeof keyOrB64 === "string") {
25
+ key = await importEd25519Key(keyOrB64);
26
+ }
27
+ if (!isCryptoKey(key)) {
28
+ throw new Error("AIMEAT signing key is missing or invalid. Please sign in again.");
29
+ }
30
+ const msgBytes = new TextEncoder().encode(message);
31
+ const sigBytes = await crypto.subtle.sign("Ed25519", key, msgBytes);
32
+ return btoa(String.fromCharCode(...new Uint8Array(sigBytes)));
33
+ }
34
+ var KEY_DB_NAME = "aimeat_keys";
35
+ var KEY_STORE_NAME = "cryptokeys";
36
+ function openKeyDB() {
37
+ return new Promise((resolve, reject) => {
38
+ const req = indexedDB.open(KEY_DB_NAME, 1);
39
+ req.onupgradeneeded = () => req.result.createObjectStore(KEY_STORE_NAME);
40
+ req.onsuccess = () => resolve(req.result);
41
+ req.onerror = () => reject(req.error);
42
+ });
43
+ }
44
+ async function storeKey(name, cryptoKey) {
45
+ const db = (
46
+ /** @type {IDBDatabase} */
47
+ await openKeyDB()
48
+ );
49
+ return new Promise((resolve, reject) => {
50
+ const tx = db.transaction(KEY_STORE_NAME, "readwrite");
51
+ tx.objectStore(KEY_STORE_NAME).put(cryptoKey, name);
52
+ tx.oncomplete = () => {
53
+ db.close();
54
+ resolve(void 0);
55
+ };
56
+ tx.onerror = () => {
57
+ db.close();
58
+ reject(tx.error);
59
+ };
60
+ });
61
+ }
62
+ async function loadKey(name) {
63
+ const db = (
64
+ /** @type {IDBDatabase} */
65
+ await openKeyDB()
66
+ );
67
+ return new Promise((resolve) => {
68
+ const tx = db.transaction(KEY_STORE_NAME, "readonly");
69
+ const req = tx.objectStore(KEY_STORE_NAME).get(name);
70
+ req.onsuccess = () => {
71
+ db.close();
72
+ resolve(req.result || null);
73
+ };
74
+ req.onerror = () => {
75
+ db.close();
76
+ resolve(null);
77
+ };
78
+ });
79
+ }
80
+ async function deleteKey(name) {
81
+ try {
82
+ const db = (
83
+ /** @type {IDBDatabase} */
84
+ await openKeyDB()
85
+ );
86
+ return new Promise((resolve) => {
87
+ const tx = db.transaction(KEY_STORE_NAME, "readwrite");
88
+ tx.objectStore(KEY_STORE_NAME).delete(name);
89
+ tx.oncomplete = () => {
90
+ db.close();
91
+ resolve(void 0);
92
+ };
93
+ tx.onerror = () => {
94
+ db.close();
95
+ resolve(void 0);
96
+ };
97
+ });
98
+ } catch {
99
+ }
100
+ }
101
+ async function migrateKeysToIndexedDB() {
102
+ try {
103
+ const session = load("session");
104
+ if (session && session.privateKey) {
105
+ const cryptoKey = await importEd25519Key(session.privateKey);
106
+ await storeKey("agent_key", cryptoKey);
107
+ delete session.privateKey;
108
+ save("session", session);
109
+ }
110
+ const ownerKey = load("owner_key");
111
+ if (typeof ownerKey === "string" && ownerKey.length > 0) {
112
+ const cryptoKey = await importEd25519Key(ownerKey);
113
+ await storeKey("owner_key", cryptoKey);
114
+ remove("owner_key");
115
+ }
116
+ } catch (e) {
117
+ console.warn("AIMEAT: Key migration to IndexedDB failed, falling back to localStorage", e);
118
+ }
119
+ }
120
+ var STORAGE_PREFIX = "aimeat_";
121
+ function save(key, value) {
122
+ try {
123
+ localStorage.setItem(STORAGE_PREFIX + key, JSON.stringify(value));
124
+ } catch {
125
+ }
126
+ }
127
+ function load(key) {
128
+ try {
129
+ const v = localStorage.getItem(STORAGE_PREFIX + key);
130
+ return v ? JSON.parse(v) : null;
131
+ } catch {
132
+ return null;
133
+ }
134
+ }
135
+ function remove(key) {
136
+ try {
137
+ localStorage.removeItem(STORAGE_PREFIX + key);
138
+ } catch {
139
+ }
140
+ }
141
+ function parseJwt(token) {
142
+ try {
143
+ const parts = token.split(".");
144
+ if (parts.length !== 3) return null;
145
+ const payload = JSON.parse(atob(parts[1].replace(/-/g, "+").replace(/_/g, "/")));
146
+ return payload;
147
+ } catch {
148
+ return null;
149
+ }
150
+ }
151
+ function isExpired(jwt) {
152
+ const payload = parseJwt(jwt);
153
+ if (!payload || !payload.exp) return true;
154
+ return Date.now() / 1e3 > payload.exp - 60;
155
+ }
156
+
157
+ // src/static/sdk-libs/_core/config.js
158
+ function cfg() {
159
+ return window.__AIMEAT_SDK_CFG__ || { nodeId: "", baseUrl: "" };
160
+ }
161
+ function resolveNodeUrl() {
162
+ const meta = document.querySelector('meta[name="aimeat-node"]');
163
+ if (meta) return (meta.getAttribute("content") || "").replace(/\/$/, "");
164
+ if (location.protocol === "http:" || location.protocol === "https:") return location.origin;
165
+ return cfg().baseUrl;
166
+ }
167
+ var NODE_URL = resolveNodeUrl();
168
+ var APEX_URL = cfg().baseUrl;
169
+ var NODE_ID = cfg().nodeId;
170
+ var HEARTBEAT_MS = cfg().heartbeatMs || 3e4;
171
+
172
+ // src/static/sdk-libs/auth/config.js
173
+ var APP_DEFAULT_SCOPES = "memory:read memory:write storage:read storage:write";
174
+ function appDeclaredScopes() {
175
+ try {
176
+ var m = document.querySelector('meta[name="aimeat-scopes"]');
177
+ var c = m && m.getAttribute("content");
178
+ if (c && c.trim()) return c.trim().replace(/\s+/g, " ");
179
+ } catch {
180
+ }
181
+ return APP_DEFAULT_SCOPES;
182
+ }
183
+ var AUTH_PROVIDERS = window.__AIMEAT_AUTH_CFG__ && window.__AIMEAT_AUTH_CFG__.providers || [];
184
+ var PROVIDER_ICONS = {
185
+ google: '<svg width="18" height="18" viewBox="0 0 18 18" aria-hidden="true"><path fill="#4285F4" d="M17.64 9.2c0-.64-.06-1.25-.16-1.84H9v3.48h4.84a4.14 4.14 0 0 1-1.8 2.72v2.26h2.92c1.7-1.57 2.68-3.88 2.68-6.62z"/><path fill="#34A853" d="M9 18c2.43 0 4.47-.8 5.96-2.18l-2.92-2.26c-.8.54-1.84.86-3.04.86-2.34 0-4.32-1.58-5.03-3.7H.96v2.33A9 9 0 0 0 9 18z"/><path fill="#FBBC05" d="M3.97 10.72a5.4 5.4 0 0 1 0-3.44V4.95H.96a9 9 0 0 0 0 8.1l3.01-2.33z"/><path fill="#EA4335" d="M9 3.58c1.32 0 2.5.45 3.44 1.35l2.58-2.58A9 9 0 0 0 .96 4.95l3.01 2.33C4.68 5.16 6.66 3.58 9 3.58z"/></svg>',
186
+ entra: '<svg width="18" height="18" viewBox="0 0 21 21" aria-hidden="true"><rect x="1" y="1" width="9" height="9" fill="#F25022"/><rect x="11" y="1" width="9" height="9" fill="#7FBA00"/><rect x="1" y="11" width="9" height="9" fill="#00A4EF"/><rect x="11" y="11" width="9" height="9" fill="#FFB900"/></svg>',
187
+ casdoor: '<svg width="18" height="18" viewBox="0 0 24 24" aria-hidden="true"><rect x="4" y="3" width="16" height="18" rx="2" fill="#4757F6"/><circle cx="14" cy="11" r="1.6" fill="#fff"/><rect x="13.2" y="11.5" width="1.6" height="4" fill="#fff"/></svg>'
188
+ };
189
+
190
+ // src/static/sdk-libs/auth/events.js
191
+ var listeners = {};
192
+ function emit(event, data) {
193
+ (listeners[event] || []).forEach((fn) => fn(data));
194
+ }
195
+ function on(event, fn) {
196
+ if (!listeners[event]) listeners[event] = [];
197
+ listeners[event].push(fn);
198
+ }
199
+ function off(event, fn) {
200
+ if (!listeners[event]) return;
201
+ listeners[event] = listeners[event].filter((f) => f !== fn);
202
+ }
203
+
204
+ // src/static/sdk-libs/auth/theme.js
205
+ function escHtml(s) {
206
+ const d = document.createElement("div");
207
+ d.textContent = s;
208
+ return d.innerHTML;
209
+ }
210
+ var AIMEAT_THEME_KEY = "aimeat-theme";
211
+ function aimeatReadTheme() {
212
+ try {
213
+ var u = new URLSearchParams(location.search).get("mode");
214
+ if (u === "light" || u === "dark") return u;
215
+ } catch {
216
+ }
217
+ try {
218
+ var s = localStorage.getItem(AIMEAT_THEME_KEY);
219
+ if (s === "light" || s === "dark") return s;
220
+ } catch {
221
+ }
222
+ var attr = document.documentElement.dataset.theme;
223
+ if (attr === "light" || attr === "dark") return attr;
224
+ return window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
225
+ }
226
+ function aimeatApplyTheme(t) {
227
+ document.documentElement.dataset.theme = t;
228
+ try {
229
+ localStorage.setItem(AIMEAT_THEME_KEY, t);
230
+ } catch {
231
+ }
232
+ try {
233
+ window.dispatchEvent(new CustomEvent("aimeat-theme-change", { detail: { theme: t } }));
234
+ } catch {
235
+ }
236
+ }
237
+ function aimeatRestoreMode() {
238
+ try {
239
+ var u = new URLSearchParams(location.search).get("mode");
240
+ if (u === "light" || u === "dark") document.documentElement.dataset.theme = u;
241
+ } catch {
242
+ }
243
+ }
244
+ function modeSwitchHtml(i) {
245
+ var cur = aimeatReadTheme();
246
+ var light = i.lightMode || "Light mode";
247
+ var dark = i.darkMode || "Dark mode";
248
+ return '<span id="aimeat-mode-switch" class="aimeat-seg" role="group" aria-label="' + escHtml(i.themeLabel || "Theme") + '"><button type="button" data-mode="light" aria-pressed="' + (cur === "light") + '" title="' + escHtml(light) + '" aria-label="' + escHtml(light) + '"><span class="seg-ico" aria-hidden="true">☀</span></button><button type="button" data-mode="dark" aria-pressed="' + (cur === "dark") + '" title="' + escHtml(dark) + '" aria-label="' + escHtml(dark) + '"><span class="seg-ico" aria-hidden="true">☾</span></button></span>';
249
+ }
250
+ function wireModeSwitch(container) {
251
+ var root = container.querySelector("#aimeat-mode-switch");
252
+ if (!root) return;
253
+ function sync(cur) {
254
+ root.querySelectorAll("button[data-mode]").forEach(function(b) {
255
+ b.setAttribute("aria-pressed", String(b.getAttribute("data-mode") === cur));
256
+ });
257
+ }
258
+ root.querySelectorAll("button[data-mode]").forEach(function(b) {
259
+ b.addEventListener("click", function() {
260
+ var m = b.getAttribute("data-mode");
261
+ aimeatApplyTheme(m);
262
+ sync(m);
263
+ });
264
+ });
265
+ window.addEventListener("aimeat-theme-change", function(ev) {
266
+ var e = (
267
+ /** @type {CustomEvent} */
268
+ ev
269
+ );
270
+ if (e && e.detail && e.detail.theme) sync(e.detail.theme);
271
+ });
272
+ }
273
+ function ensureAuthPillStyles() {
274
+ if (document.getElementById("aimeat-auth-pill-css")) return;
275
+ var st = document.createElement("style");
276
+ st.id = "aimeat-auth-pill-css";
277
+ st.textContent = [
278
+ ".aimeat-auth-wrap{position:relative;display:inline-flex;align-items:center}",
279
+ ".aimeat-auth-compact{display:none;align-items:center;gap:7px;padding:5px 11px 5px 9px;cursor:pointer;",
280
+ "background:linear-gradient(160deg,#3d2e1a 0%,#6b4c2a 15%,#c9a84c 30%,#f5e6a3 45%,#c9a84c 55%,#8b6914 70%,#4a3520 100%);",
281
+ "border:1px solid rgba(201,168,76,.6);border-top-color:rgba(245,230,163,.5);border-bottom-color:rgba(75,53,32,.8);",
282
+ "border-radius:10px;box-shadow:0 1px 0 rgba(245,230,163,.3) inset,0 -1px 0 rgba(75,53,32,.5) inset,0 3px 10px rgba(0,0,0,.4);",
283
+ "font-family:system-ui;font-size:13px;color:#2a1800;text-shadow:0 1px 0 rgba(245,230,163,.5)}",
284
+ ".aimeat-auth-compact .cdot{width:8px;height:8px;border-radius:50%;flex:0 0 auto;",
285
+ "background:radial-gradient(circle at 35% 35%,#b0ffc8,#00c853 40%,#00802e 80%,#003d15);box-shadow:0 0 5px rgba(0,200,83,.6)}",
286
+ ".aimeat-auth-compact .cini{font-weight:800;letter-spacing:.3px;max-width:96px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}",
287
+ ".aimeat-auth-compact .ccar{font-size:9px;opacity:.75;transition:transform .18s}",
288
+ ".aimeat-auth-wrap.aimeat-open .aimeat-auth-compact .ccar{transform:rotate(180deg)}",
289
+ "@media (max-width:600px){",
290
+ ".aimeat-auth-compact{display:inline-flex}",
291
+ ".aimeat-auth-wrap>.aimeat-auth-pill{position:absolute;top:calc(100% + 8px);right:0;z-index:1000;",
292
+ "display:none!important;flex-wrap:wrap!important;justify-content:flex-start;row-gap:9px;",
293
+ "min-width:210px;max-width:calc(100vw - 24px)}",
294
+ ".aimeat-auth-wrap.aimeat-open>.aimeat-auth-pill{display:flex!important}",
295
+ "}"
296
+ ].join("");
297
+ (document.head || document.documentElement).appendChild(st);
298
+ }
299
+ function pillInitials(s) {
300
+ s = (s || "").trim();
301
+ if (!s) return "•";
302
+ s = s.split("@")[0].split("#")[0].trim();
303
+ var parts = s.split(/\s+/).filter(Boolean);
304
+ if (parts.length >= 2) return (parts[0].charAt(0) + parts[1].charAt(0)).toUpperCase();
305
+ return s.slice(0, 2).toUpperCase();
306
+ }
307
+
308
+ // src/static/sdk-libs/auth/i18n.js
309
+ var MODAL_LANG_KEY = "aimeat-lang";
310
+ function currentModalLang() {
311
+ try {
312
+ var u = new URLSearchParams(location.search).get("lang");
313
+ if (u === "en" || u === "fi") return u;
314
+ var s = localStorage.getItem(MODAL_LANG_KEY);
315
+ if (s === "en" || s === "fi") return s;
316
+ } catch {
317
+ }
318
+ return (navigator.language || "en").slice(0, 2).toLowerCase() === "fi" ? "fi" : "en";
319
+ }
320
+ function flattenModalI18n(obj, prefix, out) {
321
+ out = out || {};
322
+ prefix = prefix || "";
323
+ for (var k in obj) {
324
+ if (!Object.prototype.hasOwnProperty.call(obj, k)) continue;
325
+ var key = prefix ? prefix + "." + k : k;
326
+ var v = obj[k];
327
+ if (v && typeof v === "object" && !Array.isArray(v)) flattenModalI18n(v, key, out);
328
+ else out[key] = v;
329
+ }
330
+ return out;
331
+ }
332
+ async function loadModalI18n(lang) {
333
+ var v = Date.now();
334
+ var t = {};
335
+ try {
336
+ var enRes = await fetch(NODE_URL + "/locales/en.json?v=" + v);
337
+ if (enRes.ok) t = flattenModalI18n(await enRes.json());
338
+ } catch {
339
+ }
340
+ if (lang !== "en") {
341
+ try {
342
+ var locRes = await fetch(NODE_URL + "/locales/" + lang + ".json?v=" + v);
343
+ if (locRes.ok) {
344
+ var loc = flattenModalI18n(await locRes.json());
345
+ for (var lk in loc) if (Object.prototype.hasOwnProperty.call(loc, lk)) t[lk] = loc[lk];
346
+ }
347
+ } catch {
348
+ }
349
+ }
350
+ var out = {};
351
+ for (var k in t) {
352
+ if (Object.prototype.hasOwnProperty.call(t, k) && k.indexOf("modal.") === 0) out[k.slice(6)] = t[k];
353
+ }
354
+ return out;
355
+ }
356
+
357
+ // src/static/sdk-libs/auth/modal.js
358
+ function showLoginModal(opts, renderBtn) {
359
+ var i = opts.i18n || {};
360
+ var lang = currentModalLang();
361
+ const old = document.getElementById("aimeat-modal");
362
+ if (old) old.remove();
363
+ const modal = document.createElement("div");
364
+ modal.id = "aimeat-modal";
365
+ function captureInputs() {
366
+ var g = function(id) {
367
+ var el = (
368
+ /** @type {any} */
369
+ document.getElementById(id)
370
+ );
371
+ return el ? el.value : "";
372
+ };
373
+ return { u: g("aimeat-username"), p: g("aimeat-password"), d: g("aimeat-displayname") };
374
+ }
375
+ function restoreInputs(vals) {
376
+ var s = function(id, val) {
377
+ var el = (
378
+ /** @type {any} */
379
+ document.getElementById(id)
380
+ );
381
+ if (el && val) el.value = val;
382
+ };
383
+ s("aimeat-username", vals.u);
384
+ s("aimeat-password", vals.p);
385
+ s("aimeat-displayname", vals.d);
386
+ }
387
+ function switchLang(next) {
388
+ if (next === lang) return;
389
+ try {
390
+ localStorage.setItem(MODAL_LANG_KEY, next);
391
+ document.cookie = "aimeat-lang=" + next + ";path=/;max-age=31536000;SameSite=Lax";
392
+ } catch {
393
+ }
394
+ var vals = captureInputs();
395
+ loadModalI18n(next).then(function(fresh) {
396
+ lang = next;
397
+ if (fresh && Object.keys(fresh).length) i = fresh;
398
+ render(false);
399
+ restoreInputs(vals);
400
+ });
401
+ }
402
+ function render(anim) {
403
+ modal.innerHTML = buildModalInner(i, lang, anim);
404
+ wireModal();
405
+ }
406
+ document.body.appendChild(modal);
407
+ render(true);
408
+ loadModalI18n(lang).then(function(fresh) {
409
+ if (!fresh || !Object.keys(fresh).length) return;
410
+ var differs = false;
411
+ for (var k in fresh) {
412
+ if (Object.prototype.hasOwnProperty.call(fresh, k) && fresh[k] !== i[k]) {
413
+ differs = true;
414
+ break;
415
+ }
416
+ }
417
+ if (!differs) return;
418
+ var vals = captureInputs();
419
+ i = fresh;
420
+ render(false);
421
+ restoreInputs(vals);
422
+ });
423
+ function buildModalInner(i2, lang2, anim) {
424
+ return '<style>.aimeat-inp{width:100%;padding:11px 14px;border:1.5px solid #E5E7EB;border-radius:10px;font-family:DM Sans,system-ui,sans-serif;font-size:15px;color:#1A1A2E;background:#FAFAF8;box-sizing:border-box;transition:all .15s;outline:none}.aimeat-inp:focus{border-color:#E8564A;box-shadow:0 0 0 3px rgba(232,86,74,.1)}.aimeat-inp::placeholder{color:#9CA3AF}.aimeat-go{flex:1;padding:12px;background:linear-gradient(135deg,#E8564A,#D4493F);color:#fff;border:none;border-radius:10px;cursor:pointer;font-weight:700;font-size:15px;font-family:DM Sans,system-ui,sans-serif;box-shadow:0 2px 8px rgba(232,86,74,.25);transition:transform .15s,box-shadow .15s}.aimeat-go:hover{transform:translateY(-1px);box-shadow:0 4px 14px rgba(232,86,74,.35)}.aimeat-label{display:block;margin-bottom:5px;font-size:12px;font-weight:600;letter-spacing:.5px;text-transform:uppercase;color:#6B7280}.aimeat-cancel{padding:12px 20px;background:none;color:#1A1A2E;border:1px solid #E5E7EB;border-radius:10px;cursor:pointer;font-size:15px;font-weight:500;font-family:DM Sans,system-ui,sans-serif;transition:background .15s}.aimeat-cancel:hover{background:#F3F4F6}.aimeat-fi{width:20px;height:20px;border-radius:5px;display:inline-flex;align-items:center;justify-content:center;font-size:11px;flex-shrink:0;margin-top:1px}.aimeat-langsw{position:absolute;top:24px;right:28px;display:flex;gap:5px}.aimeat-lang{padding:4px 9px;border:1px solid #E5E7EB;background:#fff;color:#6B7280;border-radius:7px;cursor:pointer;font-size:11px;font-weight:700;letter-spacing:.4px;line-height:1;font-family:DM Sans,system-ui,sans-serif;transition:all .15s}.aimeat-lang:hover{border-color:#E8564A;color:#E8564A}.aimeat-lang.active{background:#E8564A;color:#fff;border-color:#E8564A;cursor:default}@keyframes aimeatModalIn{from{opacity:0;transform:translateY(12px) scale(.97)}to{opacity:1;transform:translateY(0) scale(1)}}</style><div style="position:fixed;inset:0;background:rgba(26,26,46,.4);backdrop-filter:blur(8px);display:flex;align-items:flex-start;justify-content:center;overflow-y:auto;z-index:99999;font-family:DM Sans,system-ui,sans-serif;padding:24px"><div style="background:#FFFFFF;border-radius:16px;max-width:420px;width:100%;margin:auto;overflow:hidden;box-shadow:0 20px 60px rgba(0,0,0,.15),0 0 0 1px rgba(0,0,0,.05);' + (anim ? "animation:aimeatModalIn .3s ease" : "") + '"><div style="padding:28px 32px 0;position:relative"><div class="aimeat-langsw"><button type="button" class="aimeat-lang' + (lang2 === "en" ? " active" : "") + '" data-lang="en">EN</button><button type="button" class="aimeat-lang' + (lang2 === "fi" ? " active" : "") + '" data-lang="fi">FI</button></div><h2 style="margin:0;font-size:22px;font-weight:800;display:flex;align-items:center;gap:8px;color:#1A1A2E">AIME <span style="width:28px;height:28px;border-radius:7px;background:linear-gradient(135deg,#E8564A,#D4493F);display:inline-flex;align-items:center;justify-content:center;color:#fff;font-size:14px">♥</span> AT Sign In</h2><p style="margin:8px 0 0;font-size:14px;color:#6B7280;line-height:1.5">' + escHtml(i2.descNew || "New? Pick a username and password to create an account.") + " " + escHtml(i2.descReturning || "Already have an account? Enter your username and password.") + '</p></div><div id="aimeat-modal-body" style="padding:24px 32px"><div style="margin-bottom:14px"><label class="aimeat-label">' + escHtml(i2.usernameLabel || "Username") + '</label><input id="aimeat-username" class="aimeat-inp" placeholder="' + escHtml(i2.usernamePlaceholder || "Username") + '"></div><div style="margin-bottom:14px"><label class="aimeat-label">' + escHtml(i2.passwordLabel || "Password") + '</label><input id="aimeat-password" type="password" class="aimeat-inp" placeholder="' + escHtml(i2.passwordPlaceholder || "Password (min 4 chars)") + '"></div><div style="margin-bottom:14px"><label class="aimeat-label">' + escHtml(i2.displayNameLabel || "Display Name") + ' <span style="font-weight:400;text-transform:none;letter-spacing:0">(' + escHtml(i2.displayNameHint || "optional, for new accounts") + ')</span></label><input id="aimeat-displayname" class="aimeat-inp" placeholder="' + escHtml(i2.displayNamePlaceholder || "Display Name") + '"></div><div style="display:flex;gap:10px;margin-top:20px"><button id="aimeat-go-btn" class="aimeat-go">' + escHtml(i2.signInBtn || "Sign In / Register") + '</button><button id="aimeat-cancel-btn" class="aimeat-cancel">' + escHtml(i2.cancelBtn || "Cancel") + '</button></div><p id="aimeat-error" style="margin:8px 0 0;font-size:13px;color:#ef4444;display:none"></p>' + (AUTH_PROVIDERS.length ? '<div style="display:flex;align-items:center;gap:12px;margin:18px 0 14px;color:#9CA3AF;font-size:12px;font-weight:600;letter-spacing:.5px"><span style="flex:1;height:1px;background:#E5E7EB"></span>' + escHtml(i2.orLabel || "OR") + '<span style="flex:1;height:1px;background:#E5E7EB"></span></div>' + AUTH_PROVIDERS.map(function(p) {
425
+ return '<button type="button" class="aimeat-oauth-btn" data-provider="' + escHtml(p.id) + '" style="width:100%;display:flex;align-items:center;justify-content:center;gap:10px;padding:11px;margin-bottom:8px;background:#fff;color:#1A1A2E;border:1.5px solid #E5E7EB;border-radius:10px;cursor:pointer;font-weight:600;font-size:15px;font-family:DM Sans,system-ui,sans-serif;transition:background .15s,border-color .15s">' + (PROVIDER_ICONS[p.id] || "") + escHtml(i2[p.i18nKey] || p.label) + "</button>";
426
+ }).join("") : "") + '<div style="margin-top:14px;display:flex;gap:16px"><a href="#" id="aimeat-forgot-pw" style="font-size:13px;color:#6B7280;cursor:pointer;text-decoration:underline">' + escHtml(i2.forgotPassword || "Forgot password?") + '</a><a href="#" id="aimeat-forgot-user" style="font-size:13px;color:#6B7280;cursor:pointer;text-decoration:underline">' + escHtml(i2.forgotUsername || "Forgot username?") + '</a></div></div><div id="aimeat-forgot-pw-view" style="padding:24px 32px;display:none"><div id="aimeat-fpw-step1"><h3 style="margin:0 0 8px;font-size:17px;font-weight:700;color:#1A1A2E">' + escHtml(i2.resetPasswordTitle || "Reset Password") + '</h3><p style="font-size:13px;color:#6B7280;margin-bottom:14px">' + escHtml(i2.resetPasswordDesc || "Enter your username to receive a reset code by email.") + '</p><div style="margin-bottom:14px"><label class="aimeat-label">' + escHtml(i2.usernameLabel || "Username") + '</label><input id="aimeat-fpw-username" class="aimeat-inp" placeholder="' + escHtml(i2.usernamePlaceholder || "Username") + '"></div><div style="display:flex;gap:10px"><button id="aimeat-fpw-send" class="aimeat-go">' + escHtml(i2.sendResetCode || "Send Reset Code") + '</button><button id="aimeat-fpw-back" class="aimeat-cancel">' + escHtml(i2.backToLogin || "Back to Login") + '</button></div><p id="aimeat-fpw-msg" style="margin:8px 0 0;font-size:13px;color:#22C55E;display:none"></p><p id="aimeat-fpw-err" style="margin:8px 0 0;font-size:13px;color:#ef4444;display:none"></p></div><div id="aimeat-fpw-step2" style="display:none"><h3 style="margin:0 0 8px;font-size:17px;font-weight:700;color:#1A1A2E">' + escHtml(i2.enterNewPasswordTitle || "Enter New Password") + '</h3><p style="font-size:13px;color:#6B7280;margin-bottom:14px">' + escHtml(i2.resetCodeSent || "A reset code was sent to your email. Enter it below with your new password.") + '</p><div style="margin-bottom:14px"><label class="aimeat-label">' + escHtml(i2.codeLabel || "Reset Code") + '</label><input id="aimeat-fpw-code" class="aimeat-inp" placeholder="123456" maxlength="6"></div><div style="margin-bottom:14px"><label class="aimeat-label">' + escHtml(i2.newPasswordLabel || "New Password") + '</label><input id="aimeat-fpw-newpass" type="password" class="aimeat-inp" placeholder="' + escHtml(i2.newPasswordPlaceholder || "New password (min 8 chars)") + '"></div><div style="display:flex;gap:10px"><button id="aimeat-fpw-reset" class="aimeat-go">' + escHtml(i2.resetPassword || "Reset Password") + '</button><button id="aimeat-fpw-back2" class="aimeat-cancel">' + escHtml(i2.backToLogin || "Back to Login") + '</button></div><p id="aimeat-fpw-msg2" style="margin:8px 0 0;font-size:13px;color:#22C55E;display:none"></p><p id="aimeat-fpw-err2" style="margin:8px 0 0;font-size:13px;color:#ef4444;display:none"></p></div></div><div id="aimeat-forgot-user-view" style="padding:24px 32px;display:none"><h3 style="margin:0 0 8px;font-size:17px;font-weight:700;color:#1A1A2E">' + escHtml(i2.recoverUsernameTitle || "Recover Username") + '</h3><p style="font-size:13px;color:#6B7280;margin-bottom:14px">' + escHtml(i2.recoverUsernameDesc || "Enter the email address associated with your account.") + '</p><div style="margin-bottom:14px"><label class="aimeat-label">' + escHtml(i2.emailLabel || "Email") + '</label><input id="aimeat-fu-email" class="aimeat-inp" type="email" placeholder="you@example.com"></div><div style="display:flex;gap:10px"><button id="aimeat-fu-send" class="aimeat-go">' + escHtml(i2.sendUsername || "Send My Username") + '</button><button id="aimeat-fu-back" class="aimeat-cancel">' + escHtml(i2.backToLogin || "Back to Login") + '</button></div><p id="aimeat-fu-msg" style="margin:8px 0 0;font-size:13px;color:#22C55E;display:none"></p></div><div id="aimeat-email-view" style="padding:24px 32px;display:none"><div id="aimeat-em-step1"><h3 style="margin:0 0 8px;font-size:17px;font-weight:700;color:#1A1A2E">' + escHtml(i2.completeAccountTitle || "One last step") + '</h3><p style="font-size:13px;color:#6B7280;margin-bottom:14px">' + escHtml(i2.completeAccountDesc || "Add an email to finish setting up your account. We’ll send a verification code to confirm it.") + '</p><div style="margin-bottom:14px"><label class="aimeat-label">' + escHtml(i2.emailLabel || "Email") + '</label><input id="aimeat-em-email" class="aimeat-inp" type="email" placeholder="you@example.com"></div><div style="display:flex;gap:10px"><button id="aimeat-em-send" class="aimeat-go">' + escHtml(i2.sendVerificationCode || "Send Verification Code") + '</button><button id="aimeat-em-back" class="aimeat-cancel">' + escHtml(i2.backToLogin || "Back to Login") + '</button></div><p id="aimeat-em-err" style="margin:8px 0 0;font-size:13px;color:#ef4444;display:none"></p></div><div id="aimeat-em-step2" style="display:none"><h3 style="margin:0 0 8px;font-size:17px;font-weight:700;color:#1A1A2E">' + escHtml(i2.enterCodeTitle || "Enter Verification Code") + '</h3><p style="font-size:13px;color:#6B7280;margin-bottom:14px">' + escHtml(i2.enterCodeDesc || "We sent a 6-digit code to your email. Enter it below to finish and sign in.") + '</p><div style="margin-bottom:14px"><label class="aimeat-label">' + escHtml(i2.codeLabel || "Verification Code") + '</label><input id="aimeat-em-code" class="aimeat-inp" placeholder="123456" maxlength="6" inputmode="numeric"></div><div style="display:flex;gap:10px"><button id="aimeat-em-confirm" class="aimeat-go">' + escHtml(i2.confirmAndSignIn || "Confirm & Sign In") + '</button><button id="aimeat-em-back2" class="aimeat-cancel">' + escHtml(i2.backToLogin || "Back to Login") + '</button></div><p id="aimeat-em-msg2" style="margin:8px 0 0;font-size:13px;color:#22C55E;display:none"></p><p id="aimeat-em-err2" style="margin:8px 0 0;font-size:13px;color:#ef4444;display:none"></p></div></div><div style="padding:20px 32px 28px;background:#F9FAFB;border-top:1px solid #E5E7EB"><h4 style="margin:0 0 12px;font-size:13px;font-weight:700;color:#1A1A2E;display:flex;align-items:center;gap:6px">✨ ' + escHtml(i2.whyTitle || "What do you get?") + '</h4><div style="display:flex;align-items:flex-start;gap:10px;font-size:13.5px;color:#6B7280;margin-bottom:8px;line-height:1.45"><div class="aimeat-fi" style="background:#FFF1F0;color:#E8564A">♥</div><span>' + escHtml(i2.whyGhii || "A free GHII (Global Human Intelligence Identifier), your personal AI identity") + '</span></div><div style="display:flex;align-items:flex-start;gap:10px;font-size:13.5px;color:#6B7280;margin-bottom:8px;line-height:1.45"><div class="aimeat-fi" style="background:#EFF6FF;color:#3B82F6">🔒</div><span>' + escHtml(i2.whyPrivacy || "Your own private memory space, protected by your password") + '</span></div><div style="display:flex;align-items:flex-start;gap:10px;font-size:13.5px;color:#6B7280;margin-bottom:8px;line-height:1.45"><div class="aimeat-fi" style="background:#F0FDF4;color:#22C55E">🤖</div><span>' + escHtml(i2.whyAgents || "Connect AI agents that remember you and work on your behalf") + '</span></div><div style="display:flex;align-items:flex-start;gap:10px;font-size:13.5px;color:#6B7280;line-height:1.45"><div class="aimeat-fi" style="background:#FFF1F0;color:#E8564A">♥</div><span><strong>' + escHtml(i2.whyMorsels || "Your own AI-built apps and agents work for you — a digital agency under your own roof.") + "</strong></span></div></div></div></div>";
427
+ }
428
+ function wireModal() {
429
+ modal.querySelectorAll(".aimeat-lang").forEach(function(b) {
430
+ b.addEventListener("click", function() {
431
+ switchLang(b.getAttribute("data-lang"));
432
+ });
433
+ });
434
+ document.getElementById("aimeat-cancel-btn").addEventListener("click", () => modal.remove());
435
+ modal.querySelectorAll(".aimeat-oauth-btn").forEach(function(btn) {
436
+ btn.addEventListener("click", function() {
437
+ var id = btn.getAttribute("data-provider");
438
+ var back = encodeURIComponent(location.pathname + location.search + location.hash);
439
+ location.href = NODE_URL + "/v1/ghii/login/" + id + "?redirect=" + back;
440
+ });
441
+ });
442
+ function showView(view) {
443
+ document.getElementById("aimeat-modal-body").style.display = view === "login" ? "" : "none";
444
+ document.getElementById("aimeat-forgot-pw-view").style.display = view === "forgot-pw" ? "" : "none";
445
+ document.getElementById("aimeat-forgot-user-view").style.display = view === "forgot-user" ? "" : "none";
446
+ document.getElementById("aimeat-email-view").style.display = view === "email" ? "" : "none";
447
+ }
448
+ var pendingEmailLogin = null;
449
+ function openEmailCompletion(user, pass, hasEmail, mode, displayName) {
450
+ pendingEmailLogin = { username: user, password: pass, mode: mode || "attach", displayName: displayName || user };
451
+ showView("email");
452
+ document.getElementById("aimeat-em-step1").style.display = "";
453
+ document.getElementById("aimeat-em-step2").style.display = "none";
454
+ var emailInput = (
455
+ /** @type {any} */
456
+ document.getElementById("aimeat-em-email")
457
+ );
458
+ emailInput.value = "";
459
+ var titleEl = document.querySelector("#aimeat-em-step1 h3");
460
+ var desc = document.querySelector("#aimeat-em-step1 p");
461
+ if (pendingEmailLogin.mode === "register") {
462
+ if (titleEl) titleEl.textContent = i.registerEmailTitle || "Add your email";
463
+ if (desc) desc.textContent = i.registerEmailDesc || "Enter your email to create your account. We’ll send a verification code to confirm it.";
464
+ } else {
465
+ if (titleEl) titleEl.textContent = i.completeAccountTitle || "One last step";
466
+ if (desc) {
467
+ desc.textContent = hasEmail ? i.completeAccountDescResend || "Confirm your email to finish signing in. We’ll send a verification code — edit the address if it’s wrong." : i.completeAccountDesc || "Add an email to finish setting up your account. We’ll send a verification code to confirm it.";
468
+ }
469
+ }
470
+ document.getElementById("aimeat-em-err").style.display = "none";
471
+ setTimeout(function() {
472
+ emailInput.focus();
473
+ }, 50);
474
+ }
475
+ document.getElementById("aimeat-forgot-pw").addEventListener("click", function(e) {
476
+ e.preventDefault();
477
+ showView("forgot-pw");
478
+ document.getElementById("aimeat-fpw-step1").style.display = "";
479
+ document.getElementById("aimeat-fpw-step2").style.display = "none";
480
+ });
481
+ document.getElementById("aimeat-forgot-user").addEventListener("click", function(e) {
482
+ e.preventDefault();
483
+ showView("forgot-user");
484
+ });
485
+ ["aimeat-fpw-back", "aimeat-fpw-back2", "aimeat-fu-back", "aimeat-em-back", "aimeat-em-back2"].forEach(function(id) {
486
+ document.getElementById(id).addEventListener("click", function() {
487
+ showView("login");
488
+ });
489
+ });
490
+ document.getElementById("aimeat-em-send").addEventListener("click", async function() {
491
+ var email = (
492
+ /** @type {any} */
493
+ document.getElementById("aimeat-em-email").value.trim()
494
+ );
495
+ var errEl = document.getElementById("aimeat-em-err");
496
+ errEl.style.display = "none";
497
+ if (!email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
498
+ errEl.textContent = i.errEmailInvalid || "Please enter a valid email address.";
499
+ errEl.style.display = "block";
500
+ return;
501
+ }
502
+ if (!pendingEmailLogin) {
503
+ showView("login");
504
+ return;
505
+ }
506
+ var btn = (
507
+ /** @type {any} */
508
+ document.getElementById("aimeat-em-send")
509
+ );
510
+ btn.textContent = i.working || "Working...";
511
+ btn.disabled = true;
512
+ try {
513
+ var res;
514
+ if (pendingEmailLogin.mode === "register") {
515
+ res = await api("/v1/ghii", {
516
+ method: "POST",
517
+ credentials: "include",
518
+ body: JSON.stringify({
519
+ username: pendingEmailLogin.username,
520
+ display_name: pendingEmailLogin.displayName,
521
+ password: pendingEmailLogin.password,
522
+ email
523
+ })
524
+ });
525
+ } else {
526
+ res = await api("/v1/ghii/login/attach-email", {
527
+ method: "POST",
528
+ body: JSON.stringify({ username: pendingEmailLogin.username, password: pendingEmailLogin.password, email })
529
+ });
530
+ }
531
+ pendingEmailLogin.verificationId = res.data && res.data.verification_id;
532
+ document.getElementById("aimeat-em-step1").style.display = "none";
533
+ document.getElementById("aimeat-em-step2").style.display = "";
534
+ setTimeout(function() {
535
+ document.getElementById("aimeat-em-code").focus();
536
+ }, 50);
537
+ } catch (e) {
538
+ errEl.textContent = e.message;
539
+ errEl.style.display = "block";
540
+ } finally {
541
+ btn.textContent = i.sendVerificationCode || "Send Verification Code";
542
+ btn.disabled = false;
543
+ }
544
+ });
545
+ document.getElementById("aimeat-em-confirm").addEventListener("click", async function() {
546
+ var code = (
547
+ /** @type {any} */
548
+ document.getElementById("aimeat-em-code").value.trim()
549
+ );
550
+ var msgEl = document.getElementById("aimeat-em-msg2");
551
+ var errEl = document.getElementById("aimeat-em-err2");
552
+ msgEl.style.display = "none";
553
+ errEl.style.display = "none";
554
+ if (!code) {
555
+ errEl.textContent = i.errCodeRequired || "Enter the verification code.";
556
+ errEl.style.display = "block";
557
+ return;
558
+ }
559
+ if (!pendingEmailLogin) {
560
+ showView("login");
561
+ return;
562
+ }
563
+ var btn = (
564
+ /** @type {any} */
565
+ document.getElementById("aimeat-em-confirm")
566
+ );
567
+ btn.textContent = i.working || "Working...";
568
+ btn.disabled = true;
569
+ try {
570
+ await api("/v1/ghii/verify-email", {
571
+ method: "POST",
572
+ body: JSON.stringify({ verification_id: pendingEmailLogin.verificationId, code })
573
+ });
574
+ msgEl.textContent = i.emailVerifiedSigningIn || "Verified! Signing you in...";
575
+ msgEl.style.display = "block";
576
+ var session = await auth.loginWithPassword(pendingEmailLogin.username, pendingEmailLogin.password);
577
+ pendingEmailLogin = null;
578
+ modal.remove();
579
+ renderBtn();
580
+ if (opts.onLogin) opts.onLogin(session);
581
+ } catch (e) {
582
+ errEl.textContent = e.message;
583
+ errEl.style.display = "block";
584
+ btn.textContent = i.confirmAndSignIn || "Confirm & Sign In";
585
+ btn.disabled = false;
586
+ }
587
+ });
588
+ document.getElementById("aimeat-fpw-send").addEventListener("click", async function() {
589
+ var username = (
590
+ /** @type {any} */
591
+ document.getElementById("aimeat-fpw-username").value.trim().toLowerCase()
592
+ );
593
+ var msgEl = document.getElementById("aimeat-fpw-msg");
594
+ var errEl = document.getElementById("aimeat-fpw-err");
595
+ msgEl.style.display = "none";
596
+ errEl.style.display = "none";
597
+ if (!username) {
598
+ errEl.textContent = i.errUserShort || "Username is required";
599
+ errEl.style.display = "block";
600
+ return;
601
+ }
602
+ try {
603
+ await api("/v1/ghii/password/reset-request", { method: "POST", body: JSON.stringify({ username }) });
604
+ msgEl.textContent = i.resetCodeSent || "If your account has a verified email, a reset code was sent.";
605
+ msgEl.style.display = "block";
606
+ document.getElementById("aimeat-fpw-step1").style.display = "none";
607
+ document.getElementById("aimeat-fpw-step2").style.display = "";
608
+ window.__aimeatResetUser = username;
609
+ } catch (e) {
610
+ errEl.textContent = e.message;
611
+ errEl.style.display = "block";
612
+ }
613
+ });
614
+ document.getElementById("aimeat-fpw-reset").addEventListener("click", async function() {
615
+ var code = (
616
+ /** @type {any} */
617
+ document.getElementById("aimeat-fpw-code").value.trim()
618
+ );
619
+ var newPass = (
620
+ /** @type {any} */
621
+ document.getElementById("aimeat-fpw-newpass").value
622
+ );
623
+ var msgEl = document.getElementById("aimeat-fpw-msg2");
624
+ var errEl = document.getElementById("aimeat-fpw-err2");
625
+ msgEl.style.display = "none";
626
+ errEl.style.display = "none";
627
+ if (!code) {
628
+ errEl.textContent = "Code is required";
629
+ errEl.style.display = "block";
630
+ return;
631
+ }
632
+ if (!newPass || newPass.length < 8) {
633
+ errEl.textContent = i.errPassWeak || "Password must be at least 8 characters";
634
+ errEl.style.display = "block";
635
+ return;
636
+ }
637
+ try {
638
+ await api("/v1/ghii/password/reset", { method: "POST", body: JSON.stringify({
639
+ username: window.__aimeatResetUser || "",
640
+ code,
641
+ newPassword: newPass
642
+ }) });
643
+ msgEl.textContent = i.resetSuccess || "Password reset successful! You can now sign in.";
644
+ msgEl.style.display = "block";
645
+ setTimeout(function() {
646
+ showView("login");
647
+ }, 2e3);
648
+ } catch (e) {
649
+ errEl.textContent = e.message;
650
+ errEl.style.display = "block";
651
+ }
652
+ });
653
+ document.getElementById("aimeat-fu-send").addEventListener("click", async function() {
654
+ var email = (
655
+ /** @type {any} */
656
+ document.getElementById("aimeat-fu-email").value.trim()
657
+ );
658
+ var msgEl = document.getElementById("aimeat-fu-msg");
659
+ msgEl.style.display = "none";
660
+ if (!email) return;
661
+ try {
662
+ await api("/v1/ghii/account/recover", { method: "POST", body: JSON.stringify({ email }) });
663
+ } catch {
664
+ }
665
+ msgEl.textContent = i.usernameSent || "If an account with that email exists, your username was sent.";
666
+ msgEl.style.display = "block";
667
+ });
668
+ ["aimeat-username", "aimeat-password", "aimeat-displayname"].forEach(function(id) {
669
+ var el = document.getElementById(id);
670
+ if (!el) return;
671
+ el.addEventListener("keydown", function(e) {
672
+ if (e.key !== "Enter") return;
673
+ e.preventDefault();
674
+ var btn = (
675
+ /** @type {any} */
676
+ document.getElementById("aimeat-go-btn")
677
+ );
678
+ if (btn && !btn.disabled) btn.click();
679
+ });
680
+ });
681
+ document.getElementById("aimeat-go-btn").addEventListener("click", async () => {
682
+ let username = (
683
+ /** @type {any} */
684
+ document.getElementById("aimeat-username").value.trim().toLowerCase()
685
+ );
686
+ const password = (
687
+ /** @type {any} */
688
+ document.getElementById("aimeat-password").value
689
+ );
690
+ const errEl = document.getElementById("aimeat-error");
691
+ let isGhii = false;
692
+ let isFederated = false;
693
+ let fullUsername = username;
694
+ if (username.includes("@")) {
695
+ const atIdx = username.indexOf("@");
696
+ const nodePart = username.substring(atIdx + 1);
697
+ if (nodePart && nodePart !== NODE_ID) {
698
+ isFederated = true;
699
+ isGhii = true;
700
+ } else {
701
+ username = username.substring(0, atIdx);
702
+ isGhii = true;
703
+ }
704
+ }
705
+ const displayName = (
706
+ /** @type {any} */
707
+ document.getElementById("aimeat-displayname").value.trim() || username
708
+ );
709
+ if (!username || username.length < 3) {
710
+ errEl.textContent = i.errUserShort || "Username must be at least 3 characters";
711
+ errEl.style.display = "block";
712
+ return;
713
+ }
714
+ if (!password || password.length < 4) {
715
+ errEl.textContent = i.errPassShort || "Password must be at least 4 characters";
716
+ errEl.style.display = "block";
717
+ return;
718
+ }
719
+ const btn = (
720
+ /** @type {any} */
721
+ document.getElementById("aimeat-go-btn")
722
+ );
723
+ btn.textContent = i.working || "Working...";
724
+ btn.disabled = true;
725
+ if (isGhii) {
726
+ try {
727
+ if (isFederated) {
728
+ btn.textContent = i.connectingHome || "Connecting to home node...";
729
+ }
730
+ const loginUser = isFederated ? fullUsername : username;
731
+ const session = await auth.loginWithPassword(loginUser, password);
732
+ modal.remove();
733
+ renderBtn();
734
+ if (opts.onLogin) opts.onLogin(session);
735
+ } catch (e2) {
736
+ if (e2.code === "EMAIL_NOT_VERIFIED" && !isFederated) {
737
+ btn.textContent = i.signInBtn || "Sign In / Register";
738
+ btn.disabled = false;
739
+ openEmailCompletion(username, password, !!(e2.details && e2.details.has_email));
740
+ return;
741
+ }
742
+ errEl.textContent = e2.message.includes("Invalid username or password") ? i.errWrongPass || "Wrong password for that username." : e2.message;
743
+ errEl.style.display = "block";
744
+ btn.textContent = i.signInBtn || "Sign In / Register";
745
+ btn.disabled = false;
746
+ }
747
+ return;
748
+ }
749
+ try {
750
+ const session = await auth.register(username, displayName, { password });
751
+ modal.remove();
752
+ renderBtn();
753
+ if (opts.onLogin) opts.onLogin(session);
754
+ } catch (e) {
755
+ if (e.code === "EMAIL_REQUIRED") {
756
+ btn.textContent = i.signInBtn || "Sign In / Register";
757
+ btn.disabled = false;
758
+ openEmailCompletion(username, password, false, "register", displayName);
759
+ return;
760
+ }
761
+ if (e.message.includes("already registered") || e.message.includes("NAME_TAKEN")) {
762
+ try {
763
+ const session = await auth.loginWithPassword(username, password);
764
+ modal.remove();
765
+ renderBtn();
766
+ if (opts.onLogin) opts.onLogin(session);
767
+ } catch (e2) {
768
+ if (e2.code === "EMAIL_NOT_VERIFIED") {
769
+ btn.textContent = i.signInBtn || "Sign In / Register";
770
+ btn.disabled = false;
771
+ openEmailCompletion(username, password, !!(e2.details && e2.details.has_email));
772
+ return;
773
+ }
774
+ errEl.textContent = e2.message.includes("Invalid username or password") ? i.errWrongPass || "Wrong password for that username." : e2.message;
775
+ errEl.style.display = "block";
776
+ btn.textContent = i.signInBtn || "Sign In";
777
+ btn.disabled = false;
778
+ }
779
+ } else {
780
+ errEl.textContent = e.message;
781
+ errEl.style.display = "block";
782
+ btn.textContent = i.signInBtn || "Sign In / Register";
783
+ btn.disabled = false;
784
+ }
785
+ }
786
+ });
787
+ }
788
+ }
789
+
790
+ // src/static/sdk-libs/auth/cluster.js
791
+ function ensureClusterStyles() {
792
+ if (document.getElementById("aimeat-cluster-css")) return;
793
+ var st = document.createElement("style");
794
+ st.id = "aimeat-cluster-css";
795
+ st.textContent = [
796
+ /* The cluster row. Inherits text colour from its host (gold pill or page header). */
797
+ ".aimeat-ctl{display:inline-flex;align-items:center;gap:6px}",
798
+ /* Segmented group: one bordered pill, every option a button. */
799
+ ".aimeat-seg{display:inline-flex;align-items:stretch;height:30px;flex:0 0 auto;",
800
+ "border:1px solid color-mix(in oklab,currentColor 38%,transparent);border-radius:999px;",
801
+ "overflow:hidden;background:color-mix(in oklab,currentColor 5%,transparent)}",
802
+ ".aimeat-seg button{appearance:none;border:0;background:transparent;color:currentColor;",
803
+ 'opacity:.6;font:700 11px/1 "Inter","Segoe UI",system-ui,sans-serif;letter-spacing:.4px;',
804
+ "padding:0 10px;margin:0;cursor:pointer;display:inline-flex;align-items:center;gap:4px;",
805
+ "transition:opacity var(--motion-fast,120ms) ease,background var(--motion-fast,120ms) ease}",
806
+ ".aimeat-seg button:hover{opacity:.9}",
807
+ ".aimeat-seg button:focus-visible{outline:2px solid currentColor;outline-offset:-2px;opacity:1}",
808
+ '.aimeat-seg button[aria-pressed="true"]{opacity:1;',
809
+ "background:color-mix(in oklab,currentColor 16%,transparent)}",
810
+ ".aimeat-seg button+button{border-left:1px solid color-mix(in oklab,currentColor 22%,transparent)}",
811
+ ".aimeat-seg .seg-ico{font-size:13px;line-height:1}",
812
+ /* Popover trigger (palette picker; language picker when 4+ languages). */
813
+ ".aimeat-pop-wrap{position:relative;display:inline-flex;flex:0 0 auto}",
814
+ ".aimeat-pop-btn{appearance:none;display:inline-flex;align-items:center;justify-content:center;",
815
+ "gap:5px;height:30px;min-width:30px;padding:0 7px;background:color-mix(in oklab,currentColor 5%,transparent);",
816
+ "border:1px solid color-mix(in oklab,currentColor 38%,transparent);border-radius:999px;",
817
+ 'cursor:pointer;color:currentColor;font:700 11px/1 "Inter","Segoe UI",system-ui,sans-serif;letter-spacing:.4px;',
818
+ "transition:background var(--motion-fast,120ms) ease}",
819
+ ".aimeat-pop-btn:hover{background:color-mix(in oklab,currentColor 12%,transparent)}",
820
+ ".aimeat-pop-btn:focus-visible{outline:2px solid currentColor;outline-offset:-2px}",
821
+ /* The popover panel: a real themed surface (not the host pill), so swatches read true. */
822
+ ".aimeat-pop{position:absolute;top:calc(100% + 8px);right:0;z-index:1200;display:none;",
823
+ "background:var(--color-base-200,#ffffff);color:var(--color-base-content,#1a1a2e);",
824
+ "border:1px solid var(--color-base-300,#d9dbe1);border-radius:var(--radius-box,14px);",
825
+ "box-shadow:var(--elev-pop,0 4px 10px rgb(15 18 25 / .1),0 18px 44px rgb(15 18 25 / .16));",
826
+ "padding:8px;width:max-content;max-width:calc(100vw - 24px)}",
827
+ ".aimeat-pop-wrap.aimeat-open .aimeat-pop{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:4px}",
828
+ ".aimeat-pop.aimeat-pop-list{grid-template-columns:minmax(0,1fr)}",
829
+ ".aimeat-pop button{appearance:none;display:flex;align-items:center;gap:8px;padding:7px 9px;margin:0;",
830
+ "background:transparent;border:1px solid transparent;border-radius:calc(var(--radius-box,14px) - 6px);",
831
+ 'cursor:pointer;color:inherit;font:600 12px/1.1 "Inter","Segoe UI",system-ui,sans-serif;text-align:left;',
832
+ "transition:background var(--motion-fast,120ms) ease}",
833
+ ".aimeat-pop button:hover{background:color-mix(in oklab,currentColor 8%,transparent)}",
834
+ ".aimeat-pop button:focus-visible{outline:2px solid var(--color-primary,#e8564a);outline-offset:-2px}",
835
+ '.aimeat-pop button[aria-pressed="true"]{border-color:var(--color-primary,#e8564a)}',
836
+ /* Palette swatch chips: page/card/accent of the palette IN THE CURRENT MODE. The three
837
+ colours are data (they vary per palette), so they arrive as inline background values on
838
+ these spans — layout and everything else stays here. */
839
+ ".aimeat-pal-chip{position:relative;flex:0 0 auto;width:26px;height:20px;border-radius:5px;",
840
+ "border:1px solid color-mix(in oklab,currentColor 25%,transparent);overflow:hidden}",
841
+ ".aimeat-pal-chip .pc-card{position:absolute;inset:5px 5px 3px 5px;border-radius:3px}",
842
+ ".aimeat-pal-chip .pc-acc{position:absolute;right:3px;bottom:3px;width:7px;height:7px;border-radius:50%}",
843
+ /* The trigger's miniature: the active palette's accent as a dot. */
844
+ ".aimeat-pal-dot{width:12px;height:12px;border-radius:50%;flex:0 0 auto;",
845
+ "border:1px solid color-mix(in oklab,currentColor 30%,transparent)}"
846
+ ].join("");
847
+ (document.head || document.documentElement).appendChild(st);
848
+ }
849
+ function clampPopover(pop) {
850
+ pop.style.transform = "";
851
+ var r = pop.getBoundingClientRect();
852
+ var pad = 12;
853
+ var shift = 0;
854
+ if (r.left < pad) shift = pad - r.left;
855
+ else if (r.right > window.innerWidth - pad) shift = window.innerWidth - pad - r.right;
856
+ if (shift) pop.style.transform = "translateX(" + Math.round(shift) + "px)";
857
+ }
858
+
859
+ // src/static/sdk-libs/auth/locale.js
860
+ var AIMEAT_LANG_KEY = "aimeat-lang";
861
+ function readLocales(opts) {
862
+ var list = opts && Array.isArray(opts.locales) ? opts.locales : null;
863
+ if (!list) {
864
+ try {
865
+ var m = (
866
+ /** @type {HTMLMetaElement|null} */
867
+ document.querySelector('meta[name="aimeat-locales"]')
868
+ );
869
+ if (m && m.content) list = m.content.split(/[\s,]+/);
870
+ } catch {
871
+ }
872
+ }
873
+ if (!list) return [];
874
+ var seen = {}, out = [];
875
+ for (var i = 0; i < list.length; i++) {
876
+ var c = String(list[i] || "").trim().toLowerCase();
877
+ if (/^[a-z]{2}$/.test(c) && !seen[c]) {
878
+ seen[c] = 1;
879
+ out.push(c);
880
+ }
881
+ }
882
+ return out.length > 1 ? out : [];
883
+ }
884
+ function aimeatReadLang(locales) {
885
+ var ok = function(v) {
886
+ return v && locales.indexOf(v) >= 0 ? v : null;
887
+ };
888
+ try {
889
+ var u = ok(new URLSearchParams(location.search).get("lang"));
890
+ if (u) return u;
891
+ var s = ok(localStorage.getItem(AIMEAT_LANG_KEY));
892
+ if (s) return s;
893
+ var c = document.cookie.match(/(?:^|;\s*)aimeat-lang=([a-z]{2})(?:;|$)/);
894
+ if (c && ok(c[1])) return c[1];
895
+ } catch {
896
+ }
897
+ var nav = ok((navigator.language || "").slice(0, 2).toLowerCase());
898
+ return nav || locales[0];
899
+ }
900
+ function aimeatApplyLang(lang) {
901
+ try {
902
+ localStorage.setItem(AIMEAT_LANG_KEY, lang);
903
+ document.cookie = "aimeat-lang=" + lang + ";path=/;max-age=31536000;SameSite=Lax";
904
+ } catch {
905
+ }
906
+ try {
907
+ document.documentElement.setAttribute("lang", lang);
908
+ } catch {
909
+ }
910
+ try {
911
+ window.dispatchEvent(new CustomEvent("aimeat-lang-change", { detail: { lang } }));
912
+ } catch {
913
+ }
914
+ }
915
+ function langName(code) {
916
+ try {
917
+ var dn = new Intl.DisplayNames([code], { type: "language" });
918
+ var n = dn.of(code);
919
+ if (n && n !== code) return n.charAt(0).toUpperCase() + n.slice(1);
920
+ } catch {
921
+ }
922
+ return code.toUpperCase();
923
+ }
924
+ var SEGMENT_MAX = 3;
925
+ function langSwitchHtml(i, locales) {
926
+ if (!locales.length) return "";
927
+ var cur = aimeatReadLang(locales);
928
+ var group = i && i.switchLanguage ? i.switchLanguage : "Language";
929
+ if (locales.length <= SEGMENT_MAX) {
930
+ return '<span id="aimeat-lang-switch" class="aimeat-seg" role="group" aria-label="' + escHtml(group) + '">' + locales.map(function(c) {
931
+ return '<button type="button" data-lang="' + escHtml(c) + '" aria-pressed="' + (c === cur) + '" title="' + escHtml(langName(c)) + '" aria-label="' + escHtml(langName(c)) + '">' + escHtml(c.toUpperCase()) + "</button>";
932
+ }).join("") + "</span>";
933
+ }
934
+ return '<span id="aimeat-lang-switch" class="aimeat-pop-wrap"><button type="button" class="aimeat-pop-btn" aria-haspopup="listbox" aria-expanded="false" title="' + escHtml(group) + '" aria-label="' + escHtml(group) + '">' + escHtml(cur.toUpperCase()) + ' <span aria-hidden="true">▾</span></button><span class="aimeat-pop aimeat-pop-list" role="listbox">' + locales.map(function(c) {
935
+ return '<button type="button" role="option" data-lang="' + escHtml(c) + '" aria-pressed="' + (c === cur) + '">' + escHtml(c.toUpperCase()) + " · " + escHtml(langName(c)) + "</button>";
936
+ }).join("") + "</span></span>";
937
+ }
938
+ function wireLangSwitch(container, i, locales) {
939
+ var root = container.querySelector("#aimeat-lang-switch");
940
+ if (!root || !locales.length) return;
941
+ var trigger = root.querySelector(".aimeat-pop-btn");
942
+ function sync(cur) {
943
+ root.querySelectorAll("button[data-lang]").forEach(function(b) {
944
+ b.setAttribute("aria-pressed", String(b.getAttribute("data-lang") === cur));
945
+ });
946
+ if (trigger) trigger.childNodes[0].textContent = cur.toUpperCase() + " ";
947
+ }
948
+ root.querySelectorAll("button[data-lang]").forEach(function(b) {
949
+ b.addEventListener("click", function() {
950
+ aimeatApplyLang(b.getAttribute("data-lang"));
951
+ sync(b.getAttribute("data-lang"));
952
+ root.classList.remove("aimeat-open");
953
+ if (trigger) trigger.setAttribute("aria-expanded", "false");
954
+ });
955
+ });
956
+ if (trigger) trigger.addEventListener("click", function(ev) {
957
+ ev.stopPropagation();
958
+ var open = root.classList.toggle("aimeat-open");
959
+ trigger.setAttribute("aria-expanded", String(open));
960
+ if (open) clampPopover(root.querySelector(".aimeat-pop"));
961
+ });
962
+ window.addEventListener("aimeat-lang-change", function(ev) {
963
+ var e = (
964
+ /** @type {CustomEvent} */
965
+ ev
966
+ );
967
+ var lang = e && e.detail && e.detail.lang;
968
+ if (lang && locales.indexOf(lang) >= 0) sync(lang);
969
+ });
970
+ }
971
+
972
+ // src/static/sdk-libs/auth/palette.js
973
+ var AIMEAT_PALETTE_KEY = "aimeat-palette";
974
+ var PALETTES = [
975
+ { id: "aimeat", label: "AIMEAT", swatch: {
976
+ light: { bg: "#efeee8", card: "#ffffff", accent: "#e8564a" },
977
+ dark: { bg: "#14151a", card: "#21232e", accent: "#ff6f62" }
978
+ } },
979
+ { id: "paper", label: "Paper", swatch: {
980
+ light: { bg: "#eae2cf", card: "#fdfaf1", accent: "#a03040" },
981
+ dark: { bg: "#151110", card: "#282017", accent: "#e08590" }
982
+ } },
983
+ { id: "circuit", label: "Circuit", swatch: {
984
+ light: { bg: "#e9edf1", card: "#ffffff", accent: "#0e7290" },
985
+ dark: { bg: "#0a0f14", card: "#18202b", accent: "#4fd2f2" }
986
+ } },
987
+ { id: "contrast", label: "Contrast", swatch: {
988
+ light: { bg: "#e9e9e9", card: "#ffffff", accent: "#1d4ed8" },
989
+ dark: { bg: "#000000", card: "#17171c", accent: "#99c2ff" }
990
+ } },
991
+ { id: "mist", label: "Mist", swatch: {
992
+ light: { bg: "#e6eae4", card: "#fbfcfa", accent: "#47695a" },
993
+ dark: { bg: "#141715", card: "#252b27", accent: "#9cc0ae" }
994
+ } }
995
+ ];
996
+ function aimeatReadPalette() {
997
+ var ids = PALETTES.map(function(p) {
998
+ return p.id;
999
+ });
1000
+ try {
1001
+ var u = new URLSearchParams(location.search).get("palette");
1002
+ if (u && ids.indexOf(u) >= 0) return u;
1003
+ } catch {
1004
+ }
1005
+ try {
1006
+ var s = localStorage.getItem(AIMEAT_PALETTE_KEY);
1007
+ if (s && ids.indexOf(s) >= 0) return s;
1008
+ } catch {
1009
+ }
1010
+ var attr = document.documentElement.getAttribute("data-palette");
1011
+ return attr && ids.indexOf(attr) >= 0 ? attr : PALETTES[0].id;
1012
+ }
1013
+ function aimeatApplyPalette(id) {
1014
+ if (id === PALETTES[0].id) document.documentElement.removeAttribute("data-palette");
1015
+ else document.documentElement.setAttribute("data-palette", id);
1016
+ try {
1017
+ localStorage.setItem(AIMEAT_PALETTE_KEY, id);
1018
+ } catch {
1019
+ }
1020
+ try {
1021
+ window.dispatchEvent(new CustomEvent("aimeat-palette-change", { detail: { palette: id } }));
1022
+ } catch {
1023
+ }
1024
+ }
1025
+ function aimeatRestorePalette() {
1026
+ var cur = aimeatReadPalette();
1027
+ if (cur !== PALETTES[0].id) document.documentElement.setAttribute("data-palette", cur);
1028
+ else document.documentElement.removeAttribute("data-palette");
1029
+ try {
1030
+ window.addEventListener("storage", function(e) {
1031
+ if (e.key === AIMEAT_PALETTE_KEY && e.newValue) aimeatApplyPalette(e.newValue);
1032
+ });
1033
+ } catch {
1034
+ }
1035
+ }
1036
+ function paletteControlHtml(i) {
1037
+ var cur = aimeatReadPalette();
1038
+ var mode = document.documentElement.getAttribute("data-theme") === "dark" ? "dark" : "light";
1039
+ var curAcc = (PALETTES.find(function(p) {
1040
+ return p.id === cur;
1041
+ }) || PALETTES[0]).swatch[mode].accent;
1042
+ var label = i && i.chooseLook || "Choose look";
1043
+ return '<span id="aimeat-palette-switch" class="aimeat-pop-wrap"><button type="button" class="aimeat-pop-btn" aria-haspopup="listbox" aria-expanded="false" title="' + esc(label) + '" aria-label="' + esc(label) + '"><span class="aimeat-pal-dot" style="background:' + esc(curAcc) + '"></span></button><span class="aimeat-pop" role="listbox">' + PALETTES.map(function(p) {
1044
+ var s = p.swatch[mode];
1045
+ return '<button type="button" role="option" data-palette="' + esc(p.id) + '" aria-pressed="' + (p.id === cur) + '"><span class="aimeat-pal-chip" style="background:' + esc(s.bg) + '"><span class="pc-card" style="background:' + esc(s.card) + '"></span><span class="pc-acc" style="background:' + esc(s.accent) + '"></span></span>' + esc(p.label) + "</button>";
1046
+ }).join("") + "</span></span>";
1047
+ }
1048
+ function wirePaletteControl(container, clampPopover2) {
1049
+ var root = container.querySelector("#aimeat-palette-switch");
1050
+ if (!root) return;
1051
+ var trigger = (
1052
+ /** @type {HTMLElement} */
1053
+ root.querySelector(".aimeat-pop-btn")
1054
+ );
1055
+ function syncDot() {
1056
+ var cur = aimeatReadPalette();
1057
+ var mode = document.documentElement.getAttribute("data-theme") === "dark" ? "dark" : "light";
1058
+ var p = PALETTES.find(function(x) {
1059
+ return x.id === cur;
1060
+ }) || PALETTES[0];
1061
+ var dot = (
1062
+ /** @type {HTMLElement|null} */
1063
+ root.querySelector(".aimeat-pal-dot")
1064
+ );
1065
+ if (dot) dot.style.background = p.swatch[mode].accent;
1066
+ root.querySelectorAll("button[data-palette]").forEach(function(b) {
1067
+ b.setAttribute("aria-pressed", String(b.getAttribute("data-palette") === cur));
1068
+ var pp = PALETTES.find(function(x) {
1069
+ return x.id === b.getAttribute("data-palette");
1070
+ });
1071
+ if (!pp) return;
1072
+ var s = pp.swatch[mode];
1073
+ var chip = (
1074
+ /** @type {HTMLElement|null} */
1075
+ b.querySelector(".aimeat-pal-chip")
1076
+ );
1077
+ var card = (
1078
+ /** @type {HTMLElement|null} */
1079
+ b.querySelector(".pc-card")
1080
+ );
1081
+ var acc = (
1082
+ /** @type {HTMLElement|null} */
1083
+ b.querySelector(".pc-acc")
1084
+ );
1085
+ if (chip) chip.style.background = s.bg;
1086
+ if (card) card.style.background = s.card;
1087
+ if (acc) acc.style.background = s.accent;
1088
+ });
1089
+ }
1090
+ root.querySelectorAll("button[data-palette]").forEach(function(b) {
1091
+ b.addEventListener("click", function() {
1092
+ aimeatApplyPalette(b.getAttribute("data-palette") || PALETTES[0].id);
1093
+ syncDot();
1094
+ root.classList.remove("aimeat-open");
1095
+ trigger.setAttribute("aria-expanded", "false");
1096
+ });
1097
+ });
1098
+ trigger.addEventListener("click", function(ev) {
1099
+ ev.stopPropagation();
1100
+ var open = root.classList.toggle("aimeat-open");
1101
+ trigger.setAttribute("aria-expanded", String(open));
1102
+ if (open) clampPopover2(
1103
+ /** @type {HTMLElement} */
1104
+ root.querySelector(".aimeat-pop")
1105
+ );
1106
+ });
1107
+ window.addEventListener("aimeat-palette-change", syncDot);
1108
+ window.addEventListener("aimeat-theme-change", syncDot);
1109
+ }
1110
+ function esc(s) {
1111
+ var d = document.createElement("div");
1112
+ d.textContent = s;
1113
+ return d.innerHTML;
1114
+ }
1115
+
1116
+ // src/static/sdk-libs/auth/pill.js
1117
+ function mountPill(auth2, selector, opts = {}) {
1118
+ let container;
1119
+ if (selector && typeof selector === "object" && selector.nodeType === 1) {
1120
+ container = selector;
1121
+ } else if (selector && typeof selector === "object") {
1122
+ opts = selector;
1123
+ container = document.getElementById("aimeat-auth-bar");
1124
+ if (!container) {
1125
+ container = document.createElement("div");
1126
+ container.id = "aimeat-auth-bar";
1127
+ document.body.appendChild(container);
1128
+ }
1129
+ } else {
1130
+ container = document.querySelector(selector);
1131
+ if (!container) {
1132
+ console.error("AIMEAT: mountLoginButton container not found for selector:", selector, "— pass a CSS selector string, a DOM element, or an options object.");
1133
+ return;
1134
+ }
1135
+ }
1136
+ const i = opts.i18n || {};
1137
+ const locales = readLocales(opts);
1138
+ const useCompact = opts.compact !== void 0 ? !!opts.compact : isAppOrigin();
1139
+ function render() {
1140
+ const stored = auth2.getSession() || load("session");
1141
+ if (stored) {
1142
+ var pillHtml = '<div class="aimeat-auth-pill" style="display:inline-flex;align-items:center;gap:10px;padding:8px 18px;background:linear-gradient(160deg,#3d2e1a 0%,#6b4c2a 15%,#c9a84c 30%,#f5e6a3 45%,#c9a84c 55%,#8b6914 70%,#4a3520 100%);border:1px solid rgba(201,168,76,.6);border-top-color:rgba(245,230,163,.5);border-bottom-color:rgba(75,53,32,.8);border-radius:10px;box-shadow:0 1px 0 rgba(245,230,163,.3) inset,0 -1px 0 rgba(75,53,32,.5) inset,0 3px 10px rgba(0,0,0,.4),0 0 20px rgba(201,168,76,.15);font-family:system-ui;font-size:14px"><span class="aimeat-auth-dot" style="display:inline-block;flex:0 0 auto;width:9px;height:9px;border-radius:50%;background:radial-gradient(circle at 35% 35%,#b0ffc8,#00c853 40%,#00802e 80%,#003d15);box-shadow:0 0 5px rgba(0,200,83,.7),0 0 12px rgba(0,200,83,.3),inset 0 -1px 2px rgba(0,0,0,.3)"></span><span class="aimeat-auth-label" style="display:inline-flex;align-items:center;font-size:12px;font-weight:600;letter-spacing:.5px;color:#a0ffb8;text-shadow:0 0 4px rgba(0,210,80,.6),0 0 10px rgba(0,180,70,.3)">' + escHtml(i.loggedIn || "logged in") + '</span><span class="aimeat-auth-ghii" style="color:rgba(90,65,20,.7);font-weight:700;letter-spacing:.5px;font-size:13px;text-shadow:0 1px 0 rgba(245,230,163,.6),0 -1px 0 rgba(50,35,10,.3);-webkit-text-stroke:.2px rgba(120,85,20,.3)">' + escHtml(stored.displayName || stored.ghii || stored.owner) + "</span>" + (stored.federated ? '<span style="display:inline-flex;align-items:center;gap:3px;font-size:10px;font-weight:700;letter-spacing:.5px;color:#7dd3fc;background:rgba(56,189,248,.15);padding:2px 6px;border-radius:4px;border:1px solid rgba(56,189,248,.3)">🌐 ' + escHtml(i.federated || "Federated") + "</span>" : "") + (stored._appOrigin && stored._app && !stored._own ? '<button id="aimeat-grant-gear" title="' + escHtml(i.manageAccess || "Manage permissions") + '" aria-label="' + escHtml(i.manageAccess || "Manage permissions") + '" style="background:rgba(90,65,20,.18);color:#5a4114;border:1px solid rgba(120,85,20,.35);border-radius:6px;padding:3px 8px;cursor:pointer;font-size:13px;line-height:1">⚙️</button>' : "") + '<span class="aimeat-ctl">' + langSwitchHtml(i, locales) + modeSwitchHtml(i) + paletteControlHtml(i) + '</span><button id="aimeat-logout-btn" class="aimeat-auth-logout" style="background:radial-gradient(ellipse at 50% 30%,#ff6b6b 0%,#dc2626 35%,#991b1b 70%,#7f1d1d 100%);color:#ffd7d7;border:1px solid rgba(220,38,38,.6);border-top-color:rgba(255,130,130,.4);border-bottom-color:rgba(100,20,20,.8);border-radius:6px;padding:3px 10px;cursor:pointer;font-size:11px;font-weight:700;letter-spacing:.3px;box-shadow:0 1px 0 rgba(255,140,140,.25) inset,0 -1px 0 rgba(80,10,10,.4) inset,0 2px 6px rgba(153,27,27,.5);text-shadow:0 1px 1px rgba(0,0,0,.4)">' + escHtml(i.logoutBtn || "Logout") + "</button></div>";
1143
+ if (useCompact) {
1144
+ ensureAuthPillStyles();
1145
+ var ini = pillInitials(stored.displayName || stored.ghii || stored.owner);
1146
+ container.innerHTML = '<div class="aimeat-auth-wrap"><button class="aimeat-auth-compact" id="aimeat-auth-compact" aria-haspopup="true" aria-expanded="false" aria-label="' + escHtml(i.account || "Account") + '"><span class="cdot" aria-hidden="true"></span><span class="cini">' + escHtml(ini) + '</span><span class="ccar" aria-hidden="true">▾</span></button>' + pillHtml + "</div>";
1147
+ } else {
1148
+ container.innerHTML = pillHtml;
1149
+ }
1150
+ document.getElementById("aimeat-logout-btn").addEventListener("click", () => {
1151
+ auth2.logout();
1152
+ render();
1153
+ if (opts.onLogout) opts.onLogout();
1154
+ });
1155
+ var gearBtn = document.getElementById("aimeat-grant-gear");
1156
+ if (gearBtn) gearBtn.addEventListener("click", () => {
1157
+ auth2.manageGrant().then((res) => {
1158
+ render();
1159
+ if (res && res.revoked && opts.onLogout) opts.onLogout();
1160
+ }).catch(() => {
1161
+ });
1162
+ });
1163
+ var compactBtn = document.getElementById("aimeat-auth-compact");
1164
+ if (compactBtn) compactBtn.addEventListener("click", (ev) => {
1165
+ ev.stopPropagation();
1166
+ var w = container.querySelector(".aimeat-auth-wrap");
1167
+ if (!w) return;
1168
+ var open = w.classList.toggle("aimeat-open");
1169
+ compactBtn.setAttribute("aria-expanded", open ? "true" : "false");
1170
+ });
1171
+ } else {
1172
+ container.innerHTML = '<style>.aimeat-sign-btn{padding:8px 18px;background:linear-gradient(160deg,#3d2e1a 0%,#6b4c2a 15%,#c9a84c 30%,#f5e6a3 45%,#c9a84c 55%,#8b6914 70%,#4a3520 100%);color:#2a1800;border:1px solid rgba(201,168,76,.6);border-top-color:rgba(245,230,163,.5);border-bottom-color:rgba(75,53,32,.8);border-radius:10px;cursor:pointer;font-weight:800;font-family:system-ui;font-size:14px;letter-spacing:.3px;box-shadow:0 1px 0 rgba(245,230,163,.3) inset,0 -1px 0 rgba(75,53,32,.5) inset,0 3px 10px rgba(0,0,0,.4),0 0 20px rgba(201,168,76,.15);text-shadow:0 1px 0 rgba(245,230,163,.5);transition:transform .15s,box-shadow .15s}.aimeat-sign-btn:hover{transform:translateY(-1px);box-shadow:0 1px 0 rgba(245,230,163,.3) inset,0 -1px 0 rgba(75,53,32,.5) inset,0 5px 16px rgba(0,0,0,.5),0 0 30px rgba(201,168,76,.3)}</style><span style="display:inline-flex;align-items:center;gap:10px"><span class="aimeat-ctl">' + langSwitchHtml(i, locales) + modeSwitchHtml(i) + paletteControlHtml(i) + '</span><button id="aimeat-login-btn" class="aimeat-sign-btn">' + (opts.buttonText || i.signInBtn || "❤️ Sign In") + "</button></span>";
1173
+ document.getElementById("aimeat-login-btn").addEventListener("click", () => {
1174
+ if (isAppOrigin()) {
1175
+ restoreSessionFromAppOrigin(true).then((s) => {
1176
+ if (s) render();
1177
+ }).catch(() => {
1178
+ });
1179
+ } else {
1180
+ showLoginModal(opts, render);
1181
+ }
1182
+ });
1183
+ }
1184
+ wireModeSwitch(container);
1185
+ wireLangSwitch(container, i, locales);
1186
+ wirePaletteControl(container, clampPopover);
1187
+ }
1188
+ ensureClusterStyles();
1189
+ render();
1190
+ document.addEventListener("click", (ev) => {
1191
+ container.querySelectorAll(".aimeat-pop-wrap.aimeat-open").forEach((w) => {
1192
+ if (!w.contains(
1193
+ /** @type {Node} */
1194
+ ev.target
1195
+ )) {
1196
+ w.classList.remove("aimeat-open");
1197
+ var b = w.querySelector(".aimeat-pop-btn");
1198
+ if (b) b.setAttribute("aria-expanded", "false");
1199
+ }
1200
+ });
1201
+ });
1202
+ document.addEventListener("keydown", (ev) => {
1203
+ if (ev.key !== "Escape") return;
1204
+ container.querySelectorAll(".aimeat-pop-wrap.aimeat-open").forEach((w) => {
1205
+ w.classList.remove("aimeat-open");
1206
+ var b = w.querySelector(".aimeat-pop-btn");
1207
+ if (b) b.setAttribute("aria-expanded", "false");
1208
+ });
1209
+ });
1210
+ if (useCompact) {
1211
+ var closeCompact = () => {
1212
+ var w = container.querySelector(".aimeat-auth-wrap.aimeat-open");
1213
+ if (!w) return;
1214
+ w.classList.remove("aimeat-open");
1215
+ var cb = w.querySelector(".aimeat-auth-compact");
1216
+ if (cb) cb.setAttribute("aria-expanded", "false");
1217
+ };
1218
+ document.addEventListener("click", (ev) => {
1219
+ var w = container.querySelector(".aimeat-auth-wrap.aimeat-open");
1220
+ if (w && !w.contains(ev.target)) closeCompact();
1221
+ });
1222
+ document.addEventListener("keydown", (ev) => {
1223
+ if (ev.key === "Escape") closeCompact();
1224
+ });
1225
+ }
1226
+ auth2.on("login", render);
1227
+ auth2.on("logout", render);
1228
+ auth2.on("session-updated", render);
1229
+ if (isAppOrigin() && !auth2.getSession()) {
1230
+ restoreSessionFromAppOrigin(false).then((s) => {
1231
+ if (!s && load("session")) {
1232
+ remove("session");
1233
+ emit("logout");
1234
+ }
1235
+ }).catch(() => {
1236
+ });
1237
+ }
1238
+ }
1239
+
1240
+ // src/static/sdk-libs/auth/session.js
1241
+ var currentSession = null;
1242
+ var refreshTimer = null;
1243
+ var ownerRefreshInFlight = null;
1244
+ var _appOriginLoginInFlight = null;
1245
+ var focusRefreshInFlight = null;
1246
+ async function api(path, opts = {}) {
1247
+ const url = NODE_URL + path;
1248
+ const headers = { "Content-Type": "application/json", ...opts.headers };
1249
+ const resp = await fetch(url, { ...opts, headers });
1250
+ const data = await resp.json();
1251
+ if (!data.ok) {
1252
+ const err = (
1253
+ /** @type {Error & { code?: string, details?: unknown }} */
1254
+ new Error(data.error?.message || "API error")
1255
+ );
1256
+ err.code = data.error?.code;
1257
+ err.details = data.error?.details;
1258
+ throw err;
1259
+ }
1260
+ return data;
1261
+ }
1262
+ function persistSession(session) {
1263
+ save("session", {
1264
+ owner: session.owner,
1265
+ gaii: session.gaii,
1266
+ ghii: session.ghii,
1267
+ jwt: session.jwt,
1268
+ publicKey: session.publicKey,
1269
+ roles: session.roles,
1270
+ displayName: session.displayName || "",
1271
+ federated: session.federated || false,
1272
+ homeNode: session.homeNode || "",
1273
+ homeUrl: session.homeUrl || "",
1274
+ // H-2 app-origin grant session metadata (drives the consent gear on the login pill).
1275
+ _appOrigin: session._appOrigin || false,
1276
+ _app: session._app || null,
1277
+ _own: session._own || false
1278
+ });
1279
+ }
1280
+ async function restoreSessionFromCookie() {
1281
+ try {
1282
+ const data = await api("/v1/auth/refresh", {
1283
+ method: "POST",
1284
+ credentials: "include",
1285
+ headers: { "X-AIMEAT-Refresh": "1" }
1286
+ });
1287
+ const token = data && data.data && data.data.token;
1288
+ if (!token) return null;
1289
+ const payload = parseJwt(token) || {};
1290
+ const ownerName = payload.owner || payload.sub;
1291
+ if (!ownerName) return null;
1292
+ const session = createSession({
1293
+ owner: ownerName,
1294
+ ghii: String(ownerName).indexOf("@") >= 0 ? ownerName : ownerName + "@" + NODE_ID,
1295
+ gaii: null,
1296
+ jwt: token,
1297
+ roles: payload.roles || [],
1298
+ displayName: ""
1299
+ });
1300
+ persistSession(session);
1301
+ currentSession = session;
1302
+ scheduleAutoRefresh(session);
1303
+ emit("login", session);
1304
+ return session;
1305
+ } catch {
1306
+ return null;
1307
+ }
1308
+ }
1309
+ function isAppOrigin() {
1310
+ try {
1311
+ return location.origin !== new URL(APEX_URL).origin;
1312
+ } catch {
1313
+ return false;
1314
+ }
1315
+ }
1316
+ function appScopeDrift(session) {
1317
+ if (!session || !session._appOrigin || !session.jwt) return [];
1318
+ var have = (parseJwt(session.jwt) || {}).scopes || [];
1319
+ return appDeclaredScopes().split(" ").filter(function(s) {
1320
+ return s && have.indexOf(s) < 0;
1321
+ });
1322
+ }
1323
+ function silentAppToken() {
1324
+ return new Promise(function(resolve) {
1325
+ var apexOrigin;
1326
+ try {
1327
+ apexOrigin = new URL(APEX_URL).origin;
1328
+ } catch {
1329
+ resolve(null);
1330
+ return;
1331
+ }
1332
+ if (location.origin === apexOrigin) {
1333
+ resolve(null);
1334
+ return;
1335
+ }
1336
+ var settled = false, iframe = null, timer = null;
1337
+ function finish(v) {
1338
+ if (settled) return;
1339
+ settled = true;
1340
+ window.removeEventListener("message", onMsg);
1341
+ if (timer) clearTimeout(timer);
1342
+ if (iframe && iframe.parentNode) iframe.parentNode.removeChild(iframe);
1343
+ resolve(v);
1344
+ }
1345
+ function onMsg(e) {
1346
+ if (e.origin !== apexOrigin) return;
1347
+ var d = e.data || {};
1348
+ if (d.type !== "aimeat_app_login") return;
1349
+ finish(d.result || null);
1350
+ }
1351
+ window.addEventListener("message", onMsg);
1352
+ iframe = document.createElement("iframe");
1353
+ iframe.style.display = "none";
1354
+ iframe.setAttribute("aria-hidden", "true");
1355
+ iframe.src = apexOrigin + "/app-silent.html?scope=" + encodeURIComponent(appDeclaredScopes());
1356
+ (document.body || document.documentElement).appendChild(iframe);
1357
+ timer = setTimeout(function() {
1358
+ finish(null);
1359
+ }, 8e3);
1360
+ });
1361
+ }
1362
+ function apexLogout() {
1363
+ return new Promise(function(resolve) {
1364
+ var apexOrigin;
1365
+ try {
1366
+ apexOrigin = new URL(APEX_URL).origin;
1367
+ } catch {
1368
+ resolve(false);
1369
+ return;
1370
+ }
1371
+ if (location.origin === apexOrigin) {
1372
+ resolve(false);
1373
+ return;
1374
+ }
1375
+ var settled = false, iframe = null, timer = null;
1376
+ function finish(v) {
1377
+ if (settled) return;
1378
+ settled = true;
1379
+ window.removeEventListener("message", onMsg);
1380
+ if (timer) clearTimeout(timer);
1381
+ if (iframe && iframe.parentNode) iframe.parentNode.removeChild(iframe);
1382
+ resolve(v);
1383
+ }
1384
+ function onMsg(e) {
1385
+ if (e.origin !== apexOrigin) return;
1386
+ var d = e.data || {};
1387
+ if (d.type !== "aimeat_app_logout") return;
1388
+ finish(!!(d.result && d.result.ok));
1389
+ }
1390
+ window.addEventListener("message", onMsg);
1391
+ iframe = document.createElement("iframe");
1392
+ iframe.style.display = "none";
1393
+ iframe.setAttribute("aria-hidden", "true");
1394
+ iframe.src = apexOrigin + "/app-silent.html?mode=logout";
1395
+ (document.body || document.documentElement).appendChild(iframe);
1396
+ timer = setTimeout(function() {
1397
+ finish(false);
1398
+ }, 8e3);
1399
+ });
1400
+ }
1401
+ function _b64url(buf) {
1402
+ var bytes = new Uint8Array(buf), s = "";
1403
+ for (var i = 0; i < bytes.length; i++) s += String.fromCharCode(bytes[i]);
1404
+ return btoa(s).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
1405
+ }
1406
+ async function _pkce() {
1407
+ var verifier = _b64url(crypto.getRandomValues(new Uint8Array(32)).buffer);
1408
+ if (crypto.subtle && crypto.subtle.digest) {
1409
+ var digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(verifier));
1410
+ return { verifier, challenge: _b64url(digest), method: "S256" };
1411
+ }
1412
+ return { verifier, challenge: verifier, method: "plain" };
1413
+ }
1414
+ async function requestConsentPopup(app, scopeStr, manage) {
1415
+ var apexOrigin;
1416
+ try {
1417
+ apexOrigin = new URL(APEX_URL).origin;
1418
+ } catch {
1419
+ return null;
1420
+ }
1421
+ var p = await _pkce();
1422
+ var state = _b64url(crypto.getRandomValues(new Uint8Array(16)).buffer);
1423
+ var redirectUri = location.origin + "/";
1424
+ var scope = scopeStr || appDeclaredScopes();
1425
+ var url = apexOrigin + "/v1/app-grants/authorize?response_type=code&response_mode=web_message" + (manage ? "&manage=1" : "") + "&app=" + encodeURIComponent(app) + "&scope=" + encodeURIComponent(scope) + "&redirect_uri=" + encodeURIComponent(redirectUri) + "&code_challenge=" + encodeURIComponent(p.challenge) + "&code_challenge_method=" + encodeURIComponent(p.method) + "&state=" + encodeURIComponent(state);
1426
+ var w = 460, h = 660;
1427
+ var left = window.screen && window.screen.width ? (window.screen.width - w) / 2 : 0;
1428
+ var top = window.screen && window.screen.height ? (window.screen.height - h) / 2 : 0;
1429
+ var popup = window.open(url, "aimeat_consent", "width=" + w + ",height=" + h + ",left=" + left + ",top=" + top);
1430
+ if (!popup) {
1431
+ try {
1432
+ console.warn("[aimeat-auth] consent popup blocked — app-origin sign-in needs a real user click (user activation). Synthetic/automated clicks cannot open the consent window.");
1433
+ } catch {
1434
+ }
1435
+ emit("popup-blocked", { app });
1436
+ return null;
1437
+ }
1438
+ var msg = await new Promise(function(resolve) {
1439
+ var done = false, iv = null;
1440
+ function onMsg(e) {
1441
+ if (e.origin !== apexOrigin) return;
1442
+ var d = e.data || {};
1443
+ if (d.type !== "aimeat_app_grant" || d.state !== state) return;
1444
+ done = true;
1445
+ cleanup();
1446
+ resolve(d);
1447
+ }
1448
+ function cleanup() {
1449
+ window.removeEventListener("message", onMsg);
1450
+ if (iv) clearInterval(iv);
1451
+ }
1452
+ window.addEventListener("message", onMsg);
1453
+ iv = setInterval(function() {
1454
+ if (popup.closed && !done) {
1455
+ cleanup();
1456
+ resolve(null);
1457
+ }
1458
+ }, 500);
1459
+ });
1460
+ if (msg && msg.revoked) return { revoked: true };
1461
+ if (!msg || !msg.code) return null;
1462
+ try {
1463
+ var resp = await fetch(apexOrigin + "/v1/app-grants/token", {
1464
+ method: "POST",
1465
+ headers: { "Content-Type": "application/json" },
1466
+ body: JSON.stringify({ grant_type: "authorization_code", code: msg.code, code_verifier: p.verifier, redirect_uri: redirectUri })
1467
+ });
1468
+ var j = await resp.json();
1469
+ return j && j.ok && j.data && j.data.access_token ? j.data : null;
1470
+ } catch {
1471
+ return null;
1472
+ }
1473
+ }
1474
+ function _buildAppSession(accessToken, appId, own, displayName) {
1475
+ var payload = parseJwt(accessToken) || {};
1476
+ var ownerName = payload.owner || payload.sub;
1477
+ if (!ownerName) return null;
1478
+ var session = createSession({
1479
+ owner: ownerName,
1480
+ ghii: String(ownerName).indexOf("@") >= 0 ? ownerName : ownerName + "@" + NODE_ID,
1481
+ gaii: null,
1482
+ jwt: accessToken,
1483
+ roles: payload.roles || [],
1484
+ displayName: displayName || ""
1485
+ });
1486
+ session._appOrigin = true;
1487
+ session._app = appId || null;
1488
+ session._own = !!own;
1489
+ persistSession(session);
1490
+ currentSession = session;
1491
+ scheduleAutoRefresh(session);
1492
+ emit("login", session);
1493
+ return session;
1494
+ }
1495
+ function restoreSessionFromAppOrigin(interactive) {
1496
+ if (currentSession) return Promise.resolve(currentSession);
1497
+ if (_appOriginLoginInFlight) return _appOriginLoginInFlight;
1498
+ _appOriginLoginInFlight = (async function() {
1499
+ var r = await silentAppToken();
1500
+ var grant = r && r.ok && r.access_token ? r : null;
1501
+ var appId = r && r.app || null;
1502
+ var own = !!(r && r.own);
1503
+ if (!grant && interactive && r && (r.error === "consent_required" || r.error === "login_required") && r.app) {
1504
+ appId = r.app;
1505
+ grant = await requestConsentPopup(r.app, r.scope);
1506
+ own = !!(grant && grant.own);
1507
+ if (grant && grant.app) appId = grant.app;
1508
+ }
1509
+ if (!grant || !grant.access_token) return null;
1510
+ return _buildAppSession(grant.access_token, appId, own, grant.display_name);
1511
+ })();
1512
+ _appOriginLoginInFlight.finally(function() {
1513
+ _appOriginLoginInFlight = null;
1514
+ });
1515
+ return _appOriginLoginInFlight;
1516
+ }
1517
+ function scheduleAutoRefresh(session) {
1518
+ if (refreshTimer) clearTimeout(refreshTimer);
1519
+ if (!session?.jwt) return;
1520
+ try {
1521
+ const payload = JSON.parse(atob(session.jwt.split(".")[1].replace(/-/g, "+").replace(/_/g, "/")));
1522
+ if (!payload.exp) return;
1523
+ const msUntilExpiry = payload.exp * 1e3 - Date.now();
1524
+ const refreshIn = Math.max(msUntilExpiry - 5 * 60 * 1e3, 1e4);
1525
+ refreshTimer = setTimeout(async () => {
1526
+ try {
1527
+ await session.refresh();
1528
+ emit("refreshed", session);
1529
+ scheduleAutoRefresh(session);
1530
+ } catch (e) {
1531
+ console.warn("[aimeat-auth] Auto-refresh failed:", e.message);
1532
+ emit("expired", { reason: "refresh_failed", error: e.message });
1533
+ }
1534
+ }, refreshIn);
1535
+ } catch {
1536
+ }
1537
+ }
1538
+ function createSession(data) {
1539
+ const jwtPayload = data.jwt ? parseJwt(data.jwt) : null;
1540
+ let ownerVal = data.owner;
1541
+ if (ownerVal != null && typeof ownerVal !== "string") {
1542
+ ownerVal = typeof ownerVal === "object" && typeof ownerVal.name === "string" ? ownerVal.name : String(ownerVal);
1543
+ }
1544
+ let ghiiVal = data.ghii;
1545
+ if (ghiiVal != null && typeof ghiiVal !== "string") {
1546
+ ghiiVal = typeof ghiiVal === "object" && typeof ghiiVal.ghii === "string" ? ghiiVal.ghii : String(ghiiVal);
1547
+ }
1548
+ const session = (
1549
+ /** @type {Record<string, any>} */
1550
+ {
1551
+ ghii: ghiiVal || null,
1552
+ owner: ownerVal,
1553
+ gaii: data.gaii || null,
1554
+ identity: data.gaii || ghiiVal || null,
1555
+ jwt: data.jwt,
1556
+ roles: jwtPayload?.roles || data.roles || [],
1557
+ displayName: data.displayName || "",
1558
+ // SECURITY: Private keys are non-extractable CryptoKeys in IndexedDB, NOT here. _cryptoKey = in-memory ref only.
1559
+ _cryptoKey: data._cryptoKey || null,
1560
+ publicKey: data.publicKey,
1561
+ nodeUrl: NODE_URL,
1562
+ federated: data.federated || false,
1563
+ homeNode: data.homeNode || "",
1564
+ homeUrl: data.homeUrl || "",
1565
+ // Authenticated fetch wrapper — returns parsed JSON without throwing on error so callers
1566
+ // (e.g. AIMEAT.data.get) can inspect res.ok / res.error themselves.
1567
+ async fetch(path, opts = {}) {
1568
+ if (isExpired(session.jwt)) {
1569
+ await session.refresh();
1570
+ }
1571
+ const url = NODE_URL + path;
1572
+ const headers = { "Content-Type": "application/json", "Authorization": "Bearer " + session.jwt, ...opts.headers || {} };
1573
+ const resp = await fetch(url, { ...opts, headers });
1574
+ if (resp.status === 403 && session._appOrigin && !session._scopeHealTried) {
1575
+ var missing = appScopeDrift(session);
1576
+ if (missing.length) {
1577
+ session._scopeHealTried = true;
1578
+ var t = await silentAppToken();
1579
+ if (t && t.ok && t.access_token && !appScopeDrift({ _appOrigin: true, jwt: t.access_token })) {
1580
+ session.jwt = t.access_token;
1581
+ persistSession(session);
1582
+ scheduleAutoRefresh(session);
1583
+ var retry = await fetch(url, { ...opts, headers: { ...headers, "Authorization": "Bearer " + session.jwt } });
1584
+ return retry.json();
1585
+ }
1586
+ emit("scopes-stale", { app: session._app || null, missing });
1587
+ }
1588
+ }
1589
+ return resp.json();
1590
+ },
1591
+ // Notify the signed-in owner (header bell + browser push if subscribed).
1592
+ async notify(title, opts = {}) {
1593
+ return session.fetch("/v1/notifications", {
1594
+ method: "POST",
1595
+ body: JSON.stringify({ title, body: opts.body, link: opts.link, type: opts.type })
1596
+ });
1597
+ },
1598
+ // Get a fresh access token. Owner sessions use the httpOnly refresh cookie; agent sessions
1599
+ // re-sign with their IndexedDB key. Concurrent owner refreshes share one in-flight request.
1600
+ async refresh() {
1601
+ if (session._appOrigin) {
1602
+ var t = await silentAppToken();
1603
+ if (!t || !t.access_token) throw new Error("App session expired — the owner is not logged in on the node.");
1604
+ session.jwt = t.access_token;
1605
+ session.roles = (parseJwt(session.jwt) || {}).roles || session.roles || [];
1606
+ persistSession(session);
1607
+ scheduleAutoRefresh(session);
1608
+ return session;
1609
+ }
1610
+ if (session.federated) {
1611
+ throw new Error("Federated session expired. Please log in again.");
1612
+ }
1613
+ if (session.gaii) {
1614
+ const key = session._cryptoKey || await loadKey("agent_key");
1615
+ if (!key) throw new Error("Cannot refresh — no signing key found in IndexedDB");
1616
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
1617
+ const signature = await sign(key, session.gaii + timestamp);
1618
+ const d2 = await api("/v1/auth/token", {
1619
+ method: "POST",
1620
+ body: JSON.stringify({ gaii: session.gaii, timestamp, signature })
1621
+ });
1622
+ session.jwt = d2.data.token;
1623
+ session.roles = (parseJwt(session.jwt) || {}).roles || session.roles || [];
1624
+ persistSession(session);
1625
+ scheduleAutoRefresh(session);
1626
+ return session;
1627
+ }
1628
+ if (ownerRefreshInFlight) return ownerRefreshInFlight;
1629
+ ownerRefreshInFlight = (async () => {
1630
+ const resp = await fetch(NODE_URL + "/v1/auth/refresh", {
1631
+ method: "POST",
1632
+ credentials: "include",
1633
+ headers: { "Content-Type": "application/json", "X-AIMEAT-Refresh": "1" }
1634
+ });
1635
+ let data2 = null;
1636
+ try {
1637
+ data2 = await resp.json();
1638
+ } catch {
1639
+ }
1640
+ if (!resp.ok || !data2 || data2.ok === false) {
1641
+ throw new Error(data2?.error?.message || "Session refresh failed");
1642
+ }
1643
+ session.jwt = data2.data.token;
1644
+ session.roles = (parseJwt(session.jwt) || {}).roles || session.roles || [];
1645
+ var freshClaims = parseJwt(session.jwt) || {};
1646
+ if (freshClaims.owner && freshClaims.owner !== session.owner) {
1647
+ session.owner = freshClaims.owner;
1648
+ if (freshClaims.node) session.ghii = freshClaims.owner + "@" + freshClaims.node;
1649
+ session.identity = session.gaii || session.ghii || null;
1650
+ }
1651
+ if (typeof data2.data.display_name === "string") session.displayName = data2.data.display_name;
1652
+ persistSession(session);
1653
+ scheduleAutoRefresh(session);
1654
+ return session;
1655
+ })();
1656
+ try {
1657
+ return await ownerRefreshInFlight;
1658
+ } finally {
1659
+ ownerRefreshInFlight = null;
1660
+ }
1661
+ },
1662
+ // Check if session is valid
1663
+ get valid() {
1664
+ return session.jwt && !isExpired(session.jwt);
1665
+ }
1666
+ }
1667
+ );
1668
+ return session;
1669
+ }
1670
+ function refreshOnFocus() {
1671
+ const session = currentSession;
1672
+ if (!session || !session.jwt || session.federated) return;
1673
+ const payload = parseJwt(session.jwt);
1674
+ if (!payload || !payload.exp) return;
1675
+ const msUntilExpiry = payload.exp * 1e3 - Date.now();
1676
+ if (msUntilExpiry > 5 * 60 * 1e3) return;
1677
+ if (focusRefreshInFlight) return;
1678
+ const wasExpired = msUntilExpiry <= 0;
1679
+ focusRefreshInFlight = session.refresh().then(() => {
1680
+ emit("refreshed", session);
1681
+ }).catch((e) => {
1682
+ console.warn("[aimeat-auth] Focus refresh failed:", e.message);
1683
+ if (wasExpired) emit("expired", { reason: "refresh_failed", error: e.message });
1684
+ }).finally(() => {
1685
+ focusRefreshInFlight = null;
1686
+ });
1687
+ }
1688
+ var auth = {
1689
+ nodeUrl: NODE_URL,
1690
+ nodeId: NODE_ID,
1691
+ /**
1692
+ * Register a new human identity (GHII) and get an authenticated session.
1693
+ * @returns {Promise<object>} Session object with .fetch(), .refresh(), .jwt, .ghii
1694
+ */
1695
+ async register(username, displayName, opts = {}) {
1696
+ const regData = await api("/v1/ghii", {
1697
+ method: "POST",
1698
+ credentials: "include",
1699
+ body: JSON.stringify({
1700
+ username,
1701
+ display_name: displayName,
1702
+ bio: opts.bio,
1703
+ avatar: opts.avatar,
1704
+ locale: opts.locale,
1705
+ password: opts.password || void 0
1706
+ })
1707
+ });
1708
+ if (opts.password) {
1709
+ return this.loginWithPassword(username, opts.password);
1710
+ }
1711
+ const ownerName = regData.data.owner.name;
1712
+ const ghii = regData.data.ghii.ghii;
1713
+ const serverPrivateKey = regData.data.private_key || regData.data.owner_private_key;
1714
+ const serverPublicKey = regData.data.public_key || regData.data.owner_public_key || "";
1715
+ if (!serverPrivateKey) {
1716
+ throw new Error("Server did not return an owner signing key. Please try signing in again.");
1717
+ }
1718
+ let ownerToken = regData.data.token || null;
1719
+ if (!ownerToken) {
1720
+ const ownerTimestamp = (/* @__PURE__ */ new Date()).toISOString();
1721
+ const ownerMessage = ownerName + NODE_ID + ownerTimestamp;
1722
+ const ownerSig = await sign(serverPrivateKey, ownerMessage);
1723
+ const ownerTokenData = await api("/v1/auth/token", {
1724
+ method: "POST",
1725
+ body: JSON.stringify({ owner: ownerName, timestamp: ownerTimestamp, signature: ownerSig })
1726
+ });
1727
+ ownerToken = ownerTokenData.data.token;
1728
+ }
1729
+ const ownerCryptoKey = await importEd25519Key(serverPrivateKey);
1730
+ await storeKey("owner_key", ownerCryptoKey);
1731
+ const session = createSession({
1732
+ ghii,
1733
+ owner: ownerName,
1734
+ gaii: null,
1735
+ jwt: ownerToken,
1736
+ _cryptoKey: ownerCryptoKey,
1737
+ publicKey: serverPublicKey,
1738
+ displayName: regData.data.ghii.display_name || ""
1739
+ });
1740
+ save("session", {
1741
+ owner: ownerName,
1742
+ gaii: null,
1743
+ ghii,
1744
+ jwt: session.jwt,
1745
+ publicKey: serverPublicKey,
1746
+ roles: session.roles,
1747
+ displayName: session.displayName || ""
1748
+ });
1749
+ currentSession = session;
1750
+ scheduleAutoRefresh(session);
1751
+ emit("login", session);
1752
+ return session;
1753
+ },
1754
+ /**
1755
+ * Login with stored credentials (auto-refreshes JWT if expired).
1756
+ * @returns {Promise<object|null>} Session or null if no stored credentials
1757
+ */
1758
+ async login(username) {
1759
+ if (isAppOrigin()) return await restoreSessionFromAppOrigin(false);
1760
+ const stored = load("session");
1761
+ if (!stored) return await restoreSessionFromCookie();
1762
+ if (username && stored.owner !== username) return null;
1763
+ await migrateKeysToIndexedDB();
1764
+ if (stored.gaii) {
1765
+ stored.gaii = null;
1766
+ }
1767
+ const cryptoKey = stored.gaii ? await loadKey("agent_key") : await loadKey("owner_key");
1768
+ const session = createSession({ ...stored, _cryptoKey: cryptoKey });
1769
+ const isOwnerLocal = !session.federated && !session.gaii;
1770
+ if (isOwnerLocal || isExpired(session.jwt)) {
1771
+ try {
1772
+ await session.refresh();
1773
+ } catch {
1774
+ remove("session");
1775
+ emit("expired");
1776
+ return null;
1777
+ }
1778
+ }
1779
+ currentSession = session;
1780
+ scheduleAutoRefresh(session);
1781
+ emit("login", session);
1782
+ return session;
1783
+ },
1784
+ /**
1785
+ * Login with username + password (works from any device).
1786
+ * @returns {Promise<object>} Session object
1787
+ */
1788
+ async loginWithPassword(username, password) {
1789
+ const data = await api("/v1/ghii/login", {
1790
+ method: "POST",
1791
+ credentials: "include",
1792
+ body: JSON.stringify({ username, password })
1793
+ });
1794
+ const d = data.data;
1795
+ let ownerCryptoKey = null;
1796
+ if (d.owner_private_key) {
1797
+ ownerCryptoKey = await importEd25519Key(d.owner_private_key);
1798
+ await storeKey("owner_key", ownerCryptoKey);
1799
+ }
1800
+ const session = createSession({
1801
+ ghii: d.ghii.ghii,
1802
+ owner: d.owner.name,
1803
+ gaii: null,
1804
+ jwt: d.token,
1805
+ _cryptoKey: ownerCryptoKey,
1806
+ publicKey: d.owner_public_key || "",
1807
+ displayName: d.ghii.display_name || "",
1808
+ federated: d.federated || false,
1809
+ homeNode: d.home_node || "",
1810
+ homeUrl: d.home_url || ""
1811
+ });
1812
+ if (d.key_credentials) session._keyCredentials = d.key_credentials;
1813
+ persistSession(session);
1814
+ currentSession = session;
1815
+ scheduleAutoRefresh(session);
1816
+ emit("login", session);
1817
+ return session;
1818
+ },
1819
+ /** Get the current session (or null if not logged in) */
1820
+ getSession() {
1821
+ return currentSession;
1822
+ },
1823
+ /**
1824
+ * Patch mutable, non-secret session metadata in place (e.g. displayName after a profile edit),
1825
+ * persist it, and notify the login pill so it re-renders live — no page reload.
1826
+ */
1827
+ updateSessionMeta(patch) {
1828
+ if (!currentSession || !patch) return;
1829
+ Object.assign(currentSession, patch);
1830
+ persistSession(currentSession);
1831
+ emit("session-updated", currentSession);
1832
+ },
1833
+ /** Logout — clear stored credentials from localStorage and IndexedDB */
1834
+ async logout() {
1835
+ if (refreshTimer) {
1836
+ clearTimeout(refreshTimer);
1837
+ refreshTimer = null;
1838
+ }
1839
+ ownerRefreshInFlight = null;
1840
+ try {
1841
+ await fetch(NODE_URL + "/v1/auth/revoke", {
1842
+ method: "POST",
1843
+ credentials: "include",
1844
+ headers: {
1845
+ "Content-Type": "application/json",
1846
+ ...currentSession?.jwt ? { "Authorization": "Bearer " + currentSession.jwt } : {}
1847
+ }
1848
+ });
1849
+ } catch {
1850
+ }
1851
+ if (isAppOrigin()) {
1852
+ try {
1853
+ await apexLogout();
1854
+ } catch {
1855
+ }
1856
+ }
1857
+ currentSession = null;
1858
+ remove("session");
1859
+ remove("owner_key");
1860
+ await deleteKey("agent_key");
1861
+ await deleteKey("owner_key");
1862
+ emit("logout");
1863
+ },
1864
+ /**
1865
+ * Re-open the consent screen for the current app (H-2 in-app grant management).
1866
+ */
1867
+ async manageGrant() {
1868
+ const s = currentSession || load("session");
1869
+ if (!s || !s._app) return null;
1870
+ const res = await requestConsentPopup(s._app, appDeclaredScopes(), true);
1871
+ if (res && res.revoked) {
1872
+ await auth.logout();
1873
+ return { revoked: true };
1874
+ }
1875
+ if (res && res.access_token) return _buildAppSession(res.access_token, res.app || s._app, res.own != null ? !!res.own : s._own);
1876
+ return null;
1877
+ },
1878
+ /** True when running inside a published app on its isolated origin (not the apex). */
1879
+ isAppOrigin() {
1880
+ return isAppOrigin();
1881
+ },
1882
+ /** Open the sign-in modal (password + Google if configured). */
1883
+ showLoginModal(opts) {
1884
+ showLoginModal(opts || {}, function() {
1885
+ });
1886
+ },
1887
+ /** Check if there are stored credentials */
1888
+ get hasSession() {
1889
+ return !!load("session");
1890
+ },
1891
+ /** Get stored GHII without authenticating */
1892
+ get storedGhii() {
1893
+ const s = load("session");
1894
+ return s?.ghii || null;
1895
+ },
1896
+ /** Register an event listener */
1897
+ on(event, fn) {
1898
+ on(event, fn);
1899
+ },
1900
+ /** Remove an event listener */
1901
+ off(event, fn) {
1902
+ off(event, fn);
1903
+ },
1904
+ /** Check if running inside a sandboxed iframe (no localStorage access) */
1905
+ get inSandbox() {
1906
+ try {
1907
+ localStorage.getItem("_test");
1908
+ return false;
1909
+ } catch {
1910
+ return true;
1911
+ }
1912
+ },
1913
+ /**
1914
+ * Request auth credentials from the parent window via postMessage (sandboxed-iframe fallback).
1915
+ * @returns {Promise<object|null>} Session-like object with .jwt and .fetch(), or null
1916
+ */
1917
+ requestParentAuth(timeout = 3e3) {
1918
+ return new Promise((resolve) => {
1919
+ if (window === window.parent) {
1920
+ resolve(null);
1921
+ return;
1922
+ }
1923
+ let resolved = false;
1924
+ const timer = setTimeout(() => {
1925
+ if (!resolved) {
1926
+ resolved = true;
1927
+ resolve(null);
1928
+ }
1929
+ }, timeout);
1930
+ function handler(e) {
1931
+ if (resolved) return;
1932
+ if (!e.data || e.data.type !== "aimeat-auth") return;
1933
+ resolved = true;
1934
+ clearTimeout(timer);
1935
+ window.removeEventListener("message", handler);
1936
+ const jwt = e.data.jwt;
1937
+ const parentNodeUrl = e.data.nodeUrl;
1938
+ if (!jwt) {
1939
+ resolve(null);
1940
+ return;
1941
+ }
1942
+ const effectiveNodeUrl = parentNodeUrl || NODE_URL;
1943
+ const session = (
1944
+ /** @type {Record<string, any>} */
1945
+ {
1946
+ jwt,
1947
+ nodeUrl: effectiveNodeUrl,
1948
+ owner: null,
1949
+ gaii: null,
1950
+ ghii: null,
1951
+ identity: null,
1952
+ get valid() {
1953
+ return jwt && !isExpired(jwt);
1954
+ },
1955
+ async fetch(path, opts = {}) {
1956
+ const url = effectiveNodeUrl + path;
1957
+ const headers = { "Content-Type": "application/json", "Authorization": "Bearer " + jwt, ...opts.headers || {} };
1958
+ const resp = await fetch(url, { ...opts, headers });
1959
+ return resp.json();
1960
+ },
1961
+ async notify(title, opts = {}) {
1962
+ return session.fetch("/v1/notifications", {
1963
+ method: "POST",
1964
+ body: JSON.stringify({ title, body: opts.body, link: opts.link, type: opts.type })
1965
+ });
1966
+ }
1967
+ }
1968
+ );
1969
+ const payload = parseJwt(jwt);
1970
+ if (payload) {
1971
+ session.gaii = payload.sub || null;
1972
+ session.owner = payload.owner || null;
1973
+ session.identity = session.gaii || session.ghii || null;
1974
+ }
1975
+ currentSession = session;
1976
+ emit("login", session);
1977
+ resolve(session);
1978
+ }
1979
+ window.addEventListener("message", handler);
1980
+ window.parent.postMessage({ type: "aimeat-request-auth" }, "*");
1981
+ });
1982
+ },
1983
+ // Capability flag so an embedding app can feature-detect the compact login pill.
1984
+ compactPill: true,
1985
+ /**
1986
+ * Mount a login/register button that handles the full flow. Delegates the render to pill.js.
1987
+ * @param {string|Element|object} selector - CSS selector, DOM element, OR (options-first) the opts.
1988
+ * @param {object} [opts] - { onLogin, onLogout, buttonText, compact }.
1989
+ */
1990
+ mountLoginButton(selector, opts = {}) {
1991
+ return mountPill(auth, selector, opts);
1992
+ }
1993
+ };
1994
+
1995
+ // src/static/sdk-libs/auth/signup.js
1996
+ var USERNAME_RE = new RegExp("^[a-z0-9][a-z0-9-]{1,62}[a-z0-9]$");
1997
+ function fillTemplate(str, vars) {
1998
+ return String(str || "").replace(/\{(\w+)\}/g, function(_, k) {
1999
+ return vars[k] != null ? vars[k] : "";
2000
+ });
2001
+ }
2002
+ function cleanSignupParam() {
2003
+ try {
2004
+ var url = new URL(location.href);
2005
+ if (!url.searchParams.has("aimeat_signup")) return;
2006
+ url.searchParams.delete("aimeat_signup");
2007
+ history.replaceState(null, "", url.pathname + (url.search ? url.search : "") + url.hash);
2008
+ } catch {
2009
+ }
2010
+ }
2011
+ function showSignupNoticeModal(i, opts) {
2012
+ var old = document.getElementById("aimeat-modal");
2013
+ if (old) old.remove();
2014
+ var modal = document.createElement("div");
2015
+ modal.id = "aimeat-modal";
2016
+ document.body.appendChild(modal);
2017
+ modal.innerHTML = '<style>.aimeat-go{flex:1;padding:12px;background:linear-gradient(135deg,#E8564A,#D4493F);color:#fff;border:none;border-radius:10px;cursor:pointer;font-weight:700;font-size:15px;font-family:DM Sans,system-ui,sans-serif;box-shadow:0 2px 8px rgba(232,86,74,.25);transition:transform .15s,box-shadow .15s}.aimeat-cancel{padding:12px 20px;background:none;color:#1A1A2E;border:1px solid #E5E7EB;border-radius:10px;cursor:pointer;font-size:15px;font-weight:500;font-family:DM Sans,system-ui,sans-serif;transition:background .15s}.aimeat-cancel:hover{background:#F3F4F6}</style><div style="position:fixed;inset:0;background:rgba(26,26,46,.4);backdrop-filter:blur(8px);display:flex;align-items:flex-start;justify-content:center;overflow-y:auto;z-index:99999;font-family:DM Sans,system-ui,sans-serif;padding:24px"><div style="background:#FFFFFF;border-radius:16px;max-width:440px;width:100%;margin:auto;overflow:hidden;box-shadow:0 20px 60px rgba(0,0,0,.15),0 0 0 1px rgba(0,0,0,.05)"><div style="padding:28px 32px 24px"><h2 style="margin:0 0 8px;font-size:21px;font-weight:800;color:#1A1A2E">' + escHtml(opts.title || "") + '</h2><p style="margin:0 0 18px;font-size:14px;color:#6B7280;line-height:1.55">' + escHtml(opts.body || "") + '</p><div style="display:flex;gap:10px"><button id="aimeat-sn-primary" class="aimeat-go">' + escHtml(opts.primaryLabel || "OK") + "</button>" + (opts.showCancel ? '<button id="aimeat-sn-cancel" class="aimeat-cancel">' + escHtml(i.signupCancelBtn || "Cancel") + "</button>" : "") + "</div></div></div></div>";
2018
+ function close() {
2019
+ modal.remove();
2020
+ cleanSignupParam();
2021
+ }
2022
+ document.getElementById("aimeat-sn-primary").addEventListener("click", function() {
2023
+ close();
2024
+ if (opts.onPrimary) opts.onPrimary();
2025
+ });
2026
+ var cancelEl = document.getElementById("aimeat-sn-cancel");
2027
+ if (cancelEl) cancelEl.addEventListener("click", close);
2028
+ }
2029
+ function showGoogleSignupModal(pending, i) {
2030
+ i = i || {};
2031
+ if (pending && pending.mode === "link_existing") {
2032
+ var hint = pending.existing_hint ? " " + fillTemplate(i.signupLinkHint || "(Username hint: {hint}.)", { hint: pending.existing_hint }) : "";
2033
+ showSignupNoticeModal(i, {
2034
+ title: i.signupLinkTitle || "This email already has an account",
2035
+ body: fillTemplate(i.signupLinkIntro || "An AIMEAT account already uses {email}, but its email has not been verified yet. Sign in with your username and password once — that verifies your email, and after that this sign-in connects to your account automatically.", { email: pending.email || "" }) + hint,
2036
+ primaryLabel: i.signupLinkSignInBtn || "Sign in with password",
2037
+ showCancel: true,
2038
+ onPrimary: function() {
2039
+ showLoginModal({ i18n: i }, function() {
2040
+ });
2041
+ }
2042
+ });
2043
+ return;
2044
+ }
2045
+ var old = document.getElementById("aimeat-modal");
2046
+ if (old) old.remove();
2047
+ var modal = document.createElement("div");
2048
+ modal.id = "aimeat-modal";
2049
+ document.body.appendChild(modal);
2050
+ var emailNote = pending.email ? '<p style="margin:0 0 14px;font-size:13px;color:#6B7280">' + escHtml(fillTemplate(i.signupEmailNote || "Signing up as {email}", { email: pending.email })) + "</p>" : "";
2051
+ modal.innerHTML = '<style>.aimeat-inp{width:100%;padding:11px 14px;border:1.5px solid #E5E7EB;border-radius:10px;font-family:DM Sans,system-ui,sans-serif;font-size:15px;color:#1A1A2E;background:#FAFAF8;box-sizing:border-box;transition:all .15s;outline:none}.aimeat-inp:focus{border-color:#E8564A;box-shadow:0 0 0 3px rgba(232,86,74,.1)}.aimeat-go{flex:1;padding:12px;background:linear-gradient(135deg,#E8564A,#D4493F);color:#fff;border:none;border-radius:10px;cursor:pointer;font-weight:700;font-size:15px;font-family:DM Sans,system-ui,sans-serif;box-shadow:0 2px 8px rgba(232,86,74,.25);transition:transform .15s,box-shadow .15s}.aimeat-go:disabled{opacity:.55;cursor:not-allowed;box-shadow:none}.aimeat-label{display:block;margin-bottom:5px;font-size:12px;font-weight:600;letter-spacing:.5px;text-transform:uppercase;color:#6B7280}.aimeat-cancel{padding:12px 20px;background:none;color:#1A1A2E;border:1px solid #E5E7EB;border-radius:10px;cursor:pointer;font-size:15px;font-weight:500;font-family:DM Sans,system-ui,sans-serif;transition:background .15s}.aimeat-cancel:hover{background:#F3F4F6}</style><div style="position:fixed;inset:0;background:rgba(26,26,46,.4);backdrop-filter:blur(8px);display:flex;align-items:flex-start;justify-content:center;overflow-y:auto;z-index:99999;font-family:DM Sans,system-ui,sans-serif;padding:24px"><div style="background:#FFFFFF;border-radius:16px;max-width:440px;width:100%;margin:auto;overflow:hidden;box-shadow:0 20px 60px rgba(0,0,0,.15),0 0 0 1px rgba(0,0,0,.05)"><div style="padding:28px 32px 24px"><h2 style="margin:0 0 8px;font-size:21px;font-weight:800;color:#1A1A2E">' + escHtml(i.signupTitle || "Choose your username") + '</h2><p style="margin:0 0 6px;font-size:14px;color:#6B7280;line-height:1.5">' + escHtml(i.signupIntro || "You're signing in for the first time. Pick the username for your AIMEAT account.") + "</p>" + emailNote + '<label class="aimeat-label" for="aimeat-su-name">' + escHtml(i.signupUsernameLabel || "Username") + '</label><input id="aimeat-su-name" class="aimeat-inp" autocomplete="off" autocapitalize="none" spellcheck="false" value="' + escHtml(pending.suggested || "") + '"><p id="aimeat-su-status" style="margin:6px 0 0;font-size:13px;min-height:18px"></p><p style="margin:8px 0 0;font-size:12px;color:#9CA3AF;line-height:1.45">' + escHtml(i.signupSuggestedHint || "We suggested one from your account — change it to anything you like.") + '</p><div style="margin:16px 0 0;padding:12px 14px;background:#FFF7ED;border:1px solid #FED7AA;border-radius:10px;font-size:13px;color:#9A3412;line-height:1.5">' + escHtml(i.signupPermanentWarning || "This username is permanent. It identifies you across AIMEAT and cannot be changed later — the only way to change it is to delete your account and create a new one.") + '</div><label class="aimeat-label" for="aimeat-su-display" style="margin-top:16px">' + escHtml(i.signupDisplayNameLabel || "Display name") + '</label><input id="aimeat-su-display" class="aimeat-inp" autocomplete="off" maxlength="80" value="' + escHtml(pending.displayName || "") + '"><p style="margin:6px 0 0;font-size:12px;color:#9CA3AF;line-height:1.45">' + escHtml(i.signupDisplayNameHint || "Shown to others — not permanent, you can change it anytime later.") + '</p><div style="display:flex;gap:10px;margin-top:20px"><button id="aimeat-su-create" class="aimeat-go">' + escHtml(i.signupCreateBtn || "Create my account") + '</button><button id="aimeat-su-cancel" class="aimeat-cancel">' + escHtml(i.signupCancelBtn || "Cancel") + '</button></div><p id="aimeat-su-err" style="margin:10px 0 0;font-size:13px;color:#ef4444;display:none"></p></div></div></div>';
2052
+ var input = (
2053
+ /** @type {any} */
2054
+ document.getElementById("aimeat-su-name")
2055
+ );
2056
+ var statusEl = document.getElementById("aimeat-su-status");
2057
+ var createBtn = (
2058
+ /** @type {any} */
2059
+ document.getElementById("aimeat-su-create")
2060
+ );
2061
+ var cancelBtn = document.getElementById("aimeat-su-cancel");
2062
+ var errEl = document.getElementById("aimeat-su-err");
2063
+ var checkTimer = null;
2064
+ var lastChecked = "";
2065
+ function setStatus(text, color) {
2066
+ statusEl.textContent = text || "";
2067
+ statusEl.style.color = color || "#6B7280";
2068
+ }
2069
+ function evaluate() {
2070
+ errEl.style.display = "none";
2071
+ var name = (input.value || "").trim().toLowerCase();
2072
+ if (!USERNAME_RE.test(name)) {
2073
+ createBtn.disabled = true;
2074
+ setStatus(i.signupInvalid || "Username must be 3–64 characters: lowercase letters, numbers and hyphens.", "#ef4444");
2075
+ return;
2076
+ }
2077
+ createBtn.disabled = true;
2078
+ setStatus("…", "#9CA3AF");
2079
+ if (checkTimer) clearTimeout(checkTimer);
2080
+ checkTimer = setTimeout(function() {
2081
+ lastChecked = name;
2082
+ api("/v1/ghii/username-available?name=" + encodeURIComponent(name)).then(function(res) {
2083
+ var d = res && res.data;
2084
+ if (!d || (input.value || "").trim().toLowerCase() !== lastChecked) return;
2085
+ if (d.valid && d.available) {
2086
+ createBtn.disabled = false;
2087
+ setStatus(i.signupAvailable || "✓ Available", "#16a34a");
2088
+ } else if (!d.valid) {
2089
+ createBtn.disabled = true;
2090
+ setStatus(i.signupInvalid || d.reason || "Invalid username", "#ef4444");
2091
+ } else {
2092
+ createBtn.disabled = true;
2093
+ setStatus(i.signupTaken || "That username is already taken — pick another.", "#ef4444");
2094
+ }
2095
+ }).catch(function() {
2096
+ createBtn.disabled = false;
2097
+ setStatus("", "#6B7280");
2098
+ });
2099
+ }, 350);
2100
+ }
2101
+ input.addEventListener("input", evaluate);
2102
+ input.addEventListener("keydown", function(e) {
2103
+ if (e.key === "Enter" && !createBtn.disabled) {
2104
+ e.preventDefault();
2105
+ createBtn.click();
2106
+ }
2107
+ });
2108
+ function close() {
2109
+ if (checkTimer) clearTimeout(checkTimer);
2110
+ modal.remove();
2111
+ cleanSignupParam();
2112
+ }
2113
+ cancelBtn.addEventListener("click", close);
2114
+ createBtn.addEventListener("click", async function() {
2115
+ var name = (input.value || "").trim().toLowerCase();
2116
+ if (!USERNAME_RE.test(name)) {
2117
+ evaluate();
2118
+ return;
2119
+ }
2120
+ var displayEl = (
2121
+ /** @type {any} */
2122
+ document.getElementById("aimeat-su-display")
2123
+ );
2124
+ var displayName = displayEl ? (displayEl.value || "").trim() : "";
2125
+ createBtn.disabled = true;
2126
+ createBtn.textContent = i.signupCreating || "Creating account...";
2127
+ errEl.style.display = "none";
2128
+ try {
2129
+ var res = await api("/v1/ghii/login/" + (pending.provider || "google") + "/finalize", {
2130
+ method: "POST",
2131
+ credentials: "include",
2132
+ body: JSON.stringify({ username: name, displayName })
2133
+ });
2134
+ cleanSignupParam();
2135
+ var redirect = res && res.data && res.data.redirect || pending.redirect || "/";
2136
+ location.href = NODE_URL + redirect;
2137
+ } catch (e) {
2138
+ var msg = e && e.message ? e.message : "Could not create account";
2139
+ if (msg.indexOf("already registered") >= 0 || msg.indexOf("NAME_TAKEN") >= 0) msg = i.signupTaken || msg;
2140
+ errEl.textContent = msg;
2141
+ errEl.style.display = "block";
2142
+ createBtn.textContent = i.signupCreateBtn || "Create my account";
2143
+ evaluate();
2144
+ }
2145
+ });
2146
+ evaluate();
2147
+ }
2148
+ function maybeShowGoogleSignup() {
2149
+ var params;
2150
+ try {
2151
+ params = new URLSearchParams(location.search);
2152
+ } catch {
2153
+ return;
2154
+ }
2155
+ if (params.get("aimeat_signup") !== "1") return;
2156
+ function showExpired() {
2157
+ function open(i) {
2158
+ showSignupNoticeModal(i || {}, {
2159
+ title: i && i.signupExpiredTitle || "Sign-in session expired",
2160
+ body: i && i.signupExpiredBody || "Your sign-in session expired or was interrupted. No password is needed — just click “Continue with Google” again to restart.",
2161
+ primaryLabel: i && i.signupExpiredOkBtn || "OK",
2162
+ showCancel: false
2163
+ });
2164
+ }
2165
+ loadModalI18n(currentModalLang()).then(open).catch(function() {
2166
+ open({});
2167
+ });
2168
+ }
2169
+ api("/v1/ghii/login/pending", { credentials: "include" }).then(function(res) {
2170
+ var pending = res && res.data;
2171
+ if (!pending) {
2172
+ showExpired();
2173
+ return;
2174
+ }
2175
+ loadModalI18n(currentModalLang()).then(function(i) {
2176
+ showGoogleSignupModal(pending, i || {});
2177
+ }).catch(function() {
2178
+ showGoogleSignupModal(pending, {});
2179
+ });
2180
+ }).catch(function() {
2181
+ showExpired();
2182
+ });
2183
+ }
2184
+
2185
+ // src/static/sdk-libs/_core/namespace.js
2186
+ function namespace() {
2187
+ if (!window.AIMEAT) window.AIMEAT = {};
2188
+ return window.AIMEAT;
2189
+ }
2190
+ function attach(key, value) {
2191
+ const ns2 = namespace();
2192
+ ns2[key] = value;
2193
+ return ns2;
2194
+ }
2195
+
2196
+ // src/static/sdk-libs/auth/index.js
2197
+ if (typeof document !== "undefined" && document.addEventListener) {
2198
+ if (document.readyState === "loading") document.addEventListener("DOMContentLoaded", maybeShowGoogleSignup);
2199
+ else maybeShowGoogleSignup();
2200
+ }
2201
+ if (typeof document !== "undefined" && document.addEventListener) {
2202
+ document.addEventListener("visibilitychange", () => {
2203
+ if (document.visibilityState === "visible") refreshOnFocus();
2204
+ });
2205
+ }
2206
+ if (typeof window !== "undefined" && window.addEventListener) {
2207
+ window.addEventListener("focus", refreshOnFocus);
2208
+ }
2209
+ auth.getLang = function(locales) {
2210
+ return aimeatReadLang(readLocales({ locales }));
2211
+ };
2212
+ auth.setLang = function(lang) {
2213
+ aimeatApplyLang(String(lang).toLowerCase());
2214
+ };
2215
+ auth.getPalette = function() {
2216
+ return aimeatReadPalette();
2217
+ };
2218
+ auth.setPalette = function(id) {
2219
+ aimeatApplyPalette(String(id).toLowerCase());
2220
+ };
2221
+ auth.getPalettes = function() {
2222
+ return PALETTES.map(function(p) {
2223
+ return { id: p.id, label: p.label, swatch: p.swatch };
2224
+ });
2225
+ };
2226
+ if (typeof document !== "undefined") {
2227
+ aimeatRestorePalette();
2228
+ aimeatRestoreMode();
2229
+ }
2230
+ var ns = attach("auth", auth);
2231
+ ns.version = "2026-07-25-002";
2232
+ })();